diff --git a/admin/README.clang-tidy b/admin/README.clang-tidy new file mode 100644 index 000000000..5a159e3bd --- /dev/null +++ b/admin/README.clang-tidy @@ -0,0 +1,25 @@ +http://clang.llvm.org/extra/clang-tidy/ + +To use clang-tidy: +* add -DCMAKE_EXPORT_COMPILE_COMMANDS=ON to cmake (for example in compile-clang) +* cd src && ln -s ../build-clang/compile_commands.json compile_commands.json +* execute clang-tidy + + +To list all available checks: +* clang-tidy --list-checks -checks='*' | grep "modernize" + +E.g., use override for virtual funcsion: +* clang-tidy my_file.cpp -checks='modernize-use-override' + +clan-tidy can also execute clang-analyzer checks, e.g. +* clang-tidy my_file.cpp -checks=-*,clang-analyzer-*,-clang-analyzer-cplusplus* + +To apply the fixes direcly on the file, add 'fix' parameter: +* clang-tidy.py my_file.cpp -header-filter='.*' -checks='-*,modernize-use-nullptr' -fix + +run-clang-tidy.py -header-filter='.*' -checks='-*,modernize-use-nullptr' -fix +run-clang-tidy.py -header-filter='.*' -checks='-*,modernize-use-override' -fix + + +https://github.com/llvm-mirror/clang-tools-extra/blob/master/clang-tidy/tool/run-clang-tidy.py diff --git a/admin/run-clang-tidy.py b/admin/run-clang-tidy.py new file mode 100755 index 000000000..1cb5d23b2 --- /dev/null +++ b/admin/run-clang-tidy.py @@ -0,0 +1,297 @@ +#!/usr/bin/env python +# +#===- run-clang-tidy.py - Parallel clang-tidy runner ---------*- python -*--===# +# +# The LLVM Compiler Infrastructure +# +# This file is distributed under the University of Illinois Open Source +# License. See LICENSE.TXT for details. +# +#===------------------------------------------------------------------------===# +# FIXME: Integrate with clang-tidy-diff.py + +""" +Parallel clang-tidy runner +========================== + +Runs clang-tidy over all files in a compilation database. Requires clang-tidy +and clang-apply-replacements in $PATH. + +Example invocations. +- Run clang-tidy on all files in the current working directory with a default + set of checks and show warnings in the cpp files and all project headers. + run-clang-tidy.py $PWD + +- Fix all header guards. + run-clang-tidy.py -fix -checks=-*,llvm-header-guard + +- Fix all header guards included from clang-tidy and header guards + for clang-tidy headers. + run-clang-tidy.py -fix -checks=-*,llvm-header-guard extra/clang-tidy \ + -header-filter=extra/clang-tidy + +Compilation database setup: +http://clang.llvm.org/docs/HowToSetupToolingForLLVM.html +""" + +from __future__ import print_function + +import argparse +import glob +import json +import multiprocessing +import os +import re +import shutil +import subprocess +import sys +import tempfile +import threading +import traceback +import yaml + +is_py2 = sys.version[0] == '2' + +if is_py2: + import Queue as queue +else: + import queue as queue + +def find_compilation_database(path): + """Adjusts the directory until a compilation database is found.""" + result = './' + while not os.path.isfile(os.path.join(result, path)): + if os.path.realpath(result) == '/': + print('Error: could not find compilation database.') + sys.exit(1) + result += '../' + return os.path.realpath(result) + + +def make_absolute(f, directory): + if os.path.isabs(f): + return f + return os.path.normpath(os.path.join(directory, f)) + + +def get_tidy_invocation(f, clang_tidy_binary, checks, tmpdir, build_path, + header_filter, extra_arg, extra_arg_before, quiet): + """Gets a command line for clang-tidy.""" + start = [clang_tidy_binary] + if header_filter is not None: + start.append('-header-filter=' + header_filter) + else: + # Show warnings in all in-project headers by default. + start.append('-header-filter=^' + build_path + '/.*') + if checks: + start.append('-checks=' + checks) + if tmpdir is not None: + start.append('-export-fixes') + # Get a temporary file. We immediately close the handle so clang-tidy can + # overwrite it. + (handle, name) = tempfile.mkstemp(suffix='.yaml', dir=tmpdir) + os.close(handle) + start.append(name) + for arg in extra_arg: + start.append('-extra-arg=%s' % arg) + for arg in extra_arg_before: + start.append('-extra-arg-before=%s' % arg) + start.append('-p=' + build_path) + if quiet: + start.append('-quiet') + start.append(f) + return start + + +def merge_replacement_files(tmpdir, mergefile): + """Merge all replacement files in a directory into a single file""" + # The fixes suggested by clang-tidy >= 4.0.0 are given under + # the top level key 'Diagnostics' in the output yaml files + mergekey="Diagnostics" + merged=[] + for replacefile in glob.iglob(os.path.join(tmpdir, '*.yaml')): + content = yaml.safe_load(open(replacefile, 'r')) + if not content: + continue # Skip empty files. + merged.extend(content.get(mergekey, [])) + + if merged: + # MainSourceFile: The key is required by the definition inside + # include/clang/Tooling/ReplacementsYaml.h, but the value + # is actually never used inside clang-apply-replacements, + # so we set it to '' here. + output = { 'MainSourceFile': '', mergekey: merged } + with open(mergefile, 'w') as out: + yaml.safe_dump(output, out) + else: + # Empty the file: + open(mergefile, 'w').close() + + +def check_clang_apply_replacements_binary(args): + """Checks if invoking supplied clang-apply-replacements binary works.""" + try: + subprocess.check_call([args.clang_apply_replacements_binary, '--version']) + except: + print('Unable to run clang-apply-replacements. Is clang-apply-replacements ' + 'binary correctly specified?', file=sys.stderr) + traceback.print_exc() + sys.exit(1) + + +def apply_fixes(args, tmpdir): + """Calls clang-apply-fixes on a given directory.""" + invocation = [args.clang_apply_replacements_binary] + if args.format: + invocation.append('-format') + if args.style: + invocation.append('-style=' + args.style) + invocation.append(tmpdir) + subprocess.call(invocation) + + +def run_tidy(args, tmpdir, build_path, queue): + """Takes filenames out of queue and runs clang-tidy on them.""" + while True: + name = queue.get() + invocation = get_tidy_invocation(name, args.clang_tidy_binary, args.checks, + tmpdir, build_path, args.header_filter, + args.extra_arg, args.extra_arg_before, + args.quiet) + sys.stdout.write(' '.join(invocation) + '\n') + subprocess.call(invocation) + queue.task_done() + + +def main(): + parser = argparse.ArgumentParser(description='Runs clang-tidy over all files ' + 'in a compilation database. Requires ' + 'clang-tidy and clang-apply-replacements in ' + '$PATH.') + parser.add_argument('-clang-tidy-binary', metavar='PATH', + default='clang-tidy', + help='path to clang-tidy binary') + parser.add_argument('-clang-apply-replacements-binary', metavar='PATH', + default='clang-apply-replacements', + help='path to clang-apply-replacements binary') + parser.add_argument('-checks', default=None, + help='checks filter, when not specified, use clang-tidy ' + 'default') + parser.add_argument('-header-filter', default=None, + help='regular expression matching the names of the ' + 'headers to output diagnostics from. Diagnostics from ' + 'the main file of each translation unit are always ' + 'displayed.') + parser.add_argument('-export-fixes', metavar='filename', dest='export_fixes', + help='Create a yaml file to store suggested fixes in, ' + 'which can be applied with clang-apply-replacements.') + parser.add_argument('-j', type=int, default=0, + help='number of tidy instances to be run in parallel.') + parser.add_argument('files', nargs='*', default=['.*'], + help='files to be processed (regex on path)') + parser.add_argument('-fix', action='store_true', help='apply fix-its') + parser.add_argument('-format', action='store_true', help='Reformat code ' + 'after applying fixes') + parser.add_argument('-style', default='file', help='The style of reformat ' + 'code after applying fixes') + parser.add_argument('-p', dest='build_path', + help='Path used to read a compile command database.') + parser.add_argument('-extra-arg', dest='extra_arg', + action='append', default=[], + help='Additional argument to append to the compiler ' + 'command line.') + parser.add_argument('-extra-arg-before', dest='extra_arg_before', + action='append', default=[], + help='Additional argument to prepend to the compiler ' + 'command line.') + parser.add_argument('-quiet', action='store_true', + help='Run clang-tidy in quiet mode') + args = parser.parse_args() + + db_path = 'compile_commands.json' + + if args.build_path is not None: + build_path = args.build_path + else: + # Find our database + build_path = find_compilation_database(db_path) + + try: + invocation = [args.clang_tidy_binary, '-list-checks'] + invocation.append('-p=' + build_path) + if args.checks: + invocation.append('-checks=' + args.checks) + invocation.append('-') + print(subprocess.check_output(invocation)) + except: + print("Unable to run clang-tidy.", file=sys.stderr) + sys.exit(1) + + # Load the database and extract all files. + database = json.load(open(os.path.join(build_path, db_path))) + files = [make_absolute(entry['file'], entry['directory']) + for entry in database] + + max_task = args.j + if max_task == 0: + max_task = multiprocessing.cpu_count() + + tmpdir = None + if args.fix or args.export_fixes: + check_clang_apply_replacements_binary(args) + tmpdir = tempfile.mkdtemp() + + # Build up a big regexy filter from all command line arguments. + file_name_re = re.compile('|'.join(args.files)) + + try: + # Spin up a bunch of tidy-launching threads. + task_queue = queue.Queue(max_task) + for _ in range(max_task): + t = threading.Thread(target=run_tidy, + args=(args, tmpdir, build_path, task_queue)) + t.daemon = True + t.start() + + # Fill the queue with files. + for name in files: + if file_name_re.search(name): + task_queue.put(name) + + # Wait for all threads to be done. + task_queue.join() + + except KeyboardInterrupt: + # This is a sad hack. Unfortunately subprocess goes + # bonkers with ctrl-c and we start forking merrily. + print('\nCtrl-C detected, goodbye.') + if tmpdir: + shutil.rmtree(tmpdir) + os.kill(0, 9) + + return_code = 0 + if args.export_fixes: + print('Writing fixes to ' + args.export_fixes + ' ...') + try: + merge_replacement_files(tmpdir, args.export_fixes) + except: + print('Error exporting fixes.\n', file=sys.stderr) + traceback.print_exc() + return_code=1 + + if args.fix: + print('Applying fixes ...') + try: + apply_fixes(args, tmpdir) + except: + print('Error applying fixes.\n', file=sys.stderr) + traceback.print_exc() + return_code=1 + + if tmpdir: + shutil.rmtree(tmpdir) + sys.exit(return_code) + +if __name__ == '__main__': + main() + diff --git a/src/backend/cantorWorksheet/CantorWorksheet.h b/src/backend/cantorWorksheet/CantorWorksheet.h index 591663d05..b61d819ef 100644 --- a/src/backend/cantorWorksheet/CantorWorksheet.h +++ b/src/backend/cantorWorksheet/CantorWorksheet.h @@ -1,90 +1,90 @@ /*************************************************************************** File : CantorWorksheet.h Project : LabPlot Description : Aspect providing a Cantor Worksheets for Multiple backends -------------------------------------------------------------------- Copyright : (C) 2015 Garvit Khatri (garvitdelhi@gmail.com) Copyright : (C) 2016 by Alexander Semke (alexander.semke@web.de) ***************************************************************************/ /*************************************************************************** * * * 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 CANTORWORKSHEET_H #define CANTORWORKSHEET_H #include #include "backend/core/AbstractScriptingEngine.h" #include namespace Cantor { class PanelPlugin; class WorksheetAccessInterface; } namespace KParts { class ReadWritePart; } class QAbstractItemModel; class Column; class CantorWorksheet : public AbstractPart, public scripted { Q_OBJECT public: CantorWorksheet(AbstractScriptingEngine* engine, const QString& name, bool loading = false); - virtual QWidget* view() const override; - virtual QMenu* createContextMenu() override; - virtual QIcon icon() const override; + QWidget* view() const override; + QMenu* createContextMenu() override; + QIcon icon() const override; - virtual bool exportView() const override; - virtual bool printView() override; - virtual bool printPreview() const override; + bool exportView() const override; + bool printView() override; + bool printPreview() const override; - virtual void save(QXmlStreamWriter*) const override; - virtual bool load(XmlStreamReader*, bool preview) override; + void save(QXmlStreamWriter*) const override; + bool load(XmlStreamReader*, bool preview) override; QString backendName(); KParts::ReadWritePart* part(); QList getPlugins(); private: QString m_backendName; Cantor::Session* m_session; KParts::ReadWritePart* m_part; QList m_plugins; QAbstractItemModel* m_variableModel; Cantor::WorksheetAccessInterface* m_worksheetAccess; bool init(QByteArray* content = NULL); private slots: void rowsInserted(const QModelIndex & parent, int first, int last); void rowsAboutToBeRemoved(const QModelIndex & parent, int first, int last); void modelReset(); void sessionChanged(); signals: void requestProjectContextMenu(QMenu*); void statusChanged(Cantor::Session::Status); }; #endif // CANTORWORKSHEET_H diff --git a/src/backend/core/AbstractAspect.h b/src/backend/core/AbstractAspect.h index caec6380d..a0bcd1eea 100644 --- a/src/backend/core/AbstractAspect.h +++ b/src/backend/core/AbstractAspect.h @@ -1,222 +1,222 @@ /*************************************************************************** File : AbstractAspect.h Project : LabPlot -------------------------------------------------------------------- Copyright : (C) 2007-2009 by Tilman Benkert (thzs@gmx.net) Copyright : (C) 2007-2010 by Knut Franke (knut.franke@gmx.de) Copyright : (C) 2011-2015 by Alexander Semke (alexander.semke@web.de) Description : Base class for all objects in a Project. ***************************************************************************/ /*************************************************************************** * * * 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 ABSTRACT_ASPECT_H #define ABSTRACT_ASPECT_H #include #include class AbstractAspectPrivate; class Project; class QUndoStack; class QDateTime; class QUndoCommand; class QIcon; class QMenu; class Folder; class XmlStreamReader; class QXmlStreamWriter; class AbstractAspect : public QObject { Q_OBJECT public: enum ChildIndexFlag { IncludeHidden = 0x01, Recursive = 0x02, Compress = 0x04 }; Q_DECLARE_FLAGS(ChildIndexFlags, ChildIndexFlag) friend class AspectChildAddCmd; friend class AspectChildRemoveCmd; friend class AbstractAspectPrivate; explicit AbstractAspect(const QString& name); - virtual ~AbstractAspect(); + ~AbstractAspect() override; QString name() const; QString comment() const; void setCreationTime(const QDateTime&); QDateTime creationTime() const; virtual Project* project(); virtual QString path() const; void setHidden(bool); bool hidden() const; void setSelected(bool); void setIsLoading(bool); bool isLoading() const; virtual QIcon icon() const; virtual QMenu* createContextMenu(); //functions related to the handling of the tree-like project structure AbstractAspect* parentAspect() const; void setParentAspect(AbstractAspect*); Folder* folder(); bool isDescendantOf(AbstractAspect* other); void addChild(AbstractAspect*); void addChildFast(AbstractAspect*); QVector children(const char* className, const ChildIndexFlags& flags=0); void insertChildBefore(AbstractAspect* child, AbstractAspect* before); void insertChildBeforeFast(AbstractAspect* child, AbstractAspect* before); void reparent(AbstractAspect* newParent, int newIndex = -1); void removeChild(AbstractAspect*); void removeAllChildren(); virtual QVector dependsOn() const; template T* ancestor() const { AbstractAspect* parent = parentAspect(); while (parent) { T* ancestorAspect = qobject_cast(parent); if (ancestorAspect) return ancestorAspect; parent = parent->parentAspect(); } return nullptr; } template QVector children(const ChildIndexFlags& flags = 0) const { QVector result; for (auto* child: children()) { if (flags & IncludeHidden || !child->hidden()) { T* i = qobject_cast(child); if (i) result << i; if (flags & Recursive) result << child->template children(flags); } } return result; } template T* child(int index, const ChildIndexFlags& flags=0) const { int i = 0; for (auto* child: children()) { T* c = qobject_cast(child); if (c && (flags & IncludeHidden || !child->hidden()) && index == i++) return c; } return nullptr; } template T* child(const QString& name) const { for (auto* child: children()) { T* c = qobject_cast(child); if (c && child->name() == name) return c; } return nullptr; } template int childCount(const ChildIndexFlags& flags = 0) const { int result = 0; for (auto* child: children()) { T* i = qobject_cast(child); if (i && (flags & IncludeHidden || !child->hidden())) result++; } return result; } template int indexOfChild(const AbstractAspect* child, const ChildIndexFlags& flags = 0) const { int index = 0; for (auto* c: children()) { if (child == c) return index; T* i = qobject_cast(c); if (i && (flags & IncludeHidden || !c->hidden())) index++; } return -1; } //undo/redo related functions void setUndoAware(bool); virtual QUndoStack* undoStack() const; void exec(QUndoCommand*); void exec(QUndoCommand* command, const char* preChangeSignal, const char* postChangeSignal, QGenericArgument val0 = QGenericArgument(), QGenericArgument val1 = QGenericArgument(), QGenericArgument val2 = QGenericArgument(), QGenericArgument val3 = QGenericArgument()); void beginMacro(const QString& text); void endMacro(); //save/load virtual void save(QXmlStreamWriter*) const = 0; virtual bool load(XmlStreamReader*, bool preview) = 0; protected: void info(const QString& text) { emit statusInfo(text); } //serialization/deserialization bool readBasicAttributes(XmlStreamReader*); void writeBasicAttributes(QXmlStreamWriter*) const; void writeCommentElement(QXmlStreamWriter*) const; bool readCommentElement(XmlStreamReader*); private: AbstractAspectPrivate* d; QString uniqueNameFor(const QString&) const; const QVector children() const; void connectChild(AbstractAspect*); public slots: void setName(const QString&); void setComment(const QString&); void remove(); protected slots: virtual void childSelected(const AbstractAspect*); virtual void childDeselected(const AbstractAspect*); signals: void aspectDescriptionAboutToChange(const AbstractAspect*); void aspectDescriptionChanged(const AbstractAspect*); void aspectAboutToBeAdded(const AbstractAspect* parent, const AbstractAspect* before, const AbstractAspect* child); void aspectAdded(const AbstractAspect*); void aspectAboutToBeRemoved(const AbstractAspect*); void aspectRemoved(const AbstractAspect* parent, const AbstractAspect* before, const AbstractAspect* child); void aspectHiddenAboutToChange(const AbstractAspect*); void aspectHiddenChanged(const AbstractAspect*); void statusInfo(const QString&); void renameRequested(); //selection/deselection in model (project explorer) void selected(const AbstractAspect*); void deselected(const AbstractAspect*); //selection/deselection in view void childAspectSelectedInView(const AbstractAspect*); void childAspectDeselectedInView(const AbstractAspect*); }; Q_DECLARE_OPERATORS_FOR_FLAGS(AbstractAspect::ChildIndexFlags) #endif // ifndef ABSTRACT_ASPECT_H diff --git a/src/backend/core/AbstractColumn.h b/src/backend/core/AbstractColumn.h index 121bfa19b..74857f823 100644 --- a/src/backend/core/AbstractColumn.h +++ b/src/backend/core/AbstractColumn.h @@ -1,220 +1,220 @@ /*************************************************************************** File : AbstractColumn.h Project : LabPlot Description : Interface definition for data with column logic -------------------------------------------------------------------- Copyright : (C) 2007,2008 Tilman Benkert (thzs@gmx.net) Copyright : (C) 2013 Alexander Semke (alexander.semke@web.de) Copyright : (C) 2017 Stefan Gerlach (stefan.gerlach@uni.kn) ***************************************************************************/ /*************************************************************************** * * * 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 ABSTRACTCOLUMN_H #define ABSTRACTCOLUMN_H #include "backend/core/AbstractAspect.h" #include // NAN class AbstractColumnPrivate; class AbstractSimpleFilter; class QStringList; class QString; class QDateTime; class QDate; class QTime; template class QList; template class Interval; class AbstractColumn : public AbstractAspect { Q_OBJECT Q_ENUMS(PlotDesignation) Q_ENUMS(ColumnMode) public: enum PlotDesignation {NoDesignation, X, Y, Z, XError, XErrorPlus, XErrorMinus, YError, YErrorMinus, YErrorPlus}; enum ColumnMode { // BASIC FORMATS Numeric = 0, // double Text = 1, // QString // Time = 2 and Date = 3 are skipped to avoid problems with old obsolete values Month = 4, // month of year: numeric or "Jan", etc. Day = 5, // day of week: numeric or "Mon", etc. DateTime = 6, // any date-time format // Bool = 7, // bool // FLOATING POINT // 10 = Half precision // Float = 11, // float // 12 = Long double // 13 = Quad precision // 14 = decimal 32 // 15 = decimal 64 // 16 = decimal 128 // COMPLEX // 17 = complex // 18 = complex // 19 = complex // INTEGER // Int8 = 20, // qint8 (char) // UInt8 = 21, // quint8 (unsigned char) // Int16 = 22, // qint16 (short) // UInt16 = 23, // quint16 (unsigned short) Integer = 24, // qint32 (int) // UInt32 = 25, // quint32 (unsigned int) // Int64 = 26, // qint64 (long) // UInt64 = 27, // quint64 (unsigned long) // MISC // 30 = QBrush // QColor // QFont // QPoint // QQuaternion // QVector2D, QVector3D, QVector4D // QMatrix // etc. }; struct ColumnStatistics { ColumnStatistics() { minimum = NAN; maximum = NAN; arithmeticMean = NAN; geometricMean = NAN; harmonicMean = NAN; contraharmonicMean = NAN; median = NAN; variance = NAN; standardDeviation = NAN; meanDeviation = NAN; meanDeviationAroundMedian = NAN; medianDeviation = NAN; skewness = NAN; kurtosis = NAN; entropy = NAN; } double minimum; double maximum; double arithmeticMean; double geometricMean; double harmonicMean; double contraharmonicMean; double median; double variance; double standardDeviation; double meanDeviation; // mean absolute deviation around mean double meanDeviationAroundMedian; // mean absolute deviation around median double medianDeviation; // median absolute deviation double skewness; double kurtosis; double entropy; }; explicit AbstractColumn(const QString& name); - virtual ~AbstractColumn(); + ~AbstractColumn() override; static QStringList dateFormats(); // supported date formats static QStringList timeFormats(); // supported time formats static QStringList dateTimeFormats(); // supported datetime formats static QIcon iconForMode(ColumnMode mode); virtual bool isReadOnly() const { return true; }; virtual ColumnMode columnMode() const = 0; virtual void setColumnMode(AbstractColumn::ColumnMode); virtual PlotDesignation plotDesignation() const = 0; virtual void setPlotDesignation(AbstractColumn::PlotDesignation); virtual bool copy(const AbstractColumn *source); virtual bool copy(const AbstractColumn *source, int source_start, int dest_start, int num_rows); virtual int rowCount() const = 0; void insertRows(int before, int count); void removeRows(int first, int count); virtual void clear(); virtual double maximum(int count = 0) const; virtual double minimum(int count = 0) const; bool isValid(int row) const; bool isMasked(int row) const; bool isMasked(Interval i) const; QList< Interval > maskedIntervals() const; void clearMasks(); void setMasked(Interval i, bool mask = true); void setMasked(int row, bool mask = true); virtual QString formula(int row) const; virtual QList< Interval > formulaIntervals() const; virtual void setFormula(Interval i, QString formula); virtual void setFormula(int row, QString formula); virtual void clearFormulas(); virtual QString textAt(int row) const; virtual void setTextAt(int row, const QString& new_value); virtual void replaceTexts(int first, const QVector& new_values); virtual QDate dateAt(int row) const; virtual void setDateAt(int row, const QDate& new_value); virtual QTime timeAt(int row) const; virtual void setTimeAt(int row, const QTime& new_value); virtual QDateTime dateTimeAt(int row) const; virtual void setDateTimeAt(int row, const QDateTime& new_value); virtual void replaceDateTimes(int first, const QVector& new_values); virtual double valueAt(int row) const; virtual void setValueAt(int row, double new_value); virtual void replaceValues(int first, const QVector& new_values); virtual int integerAt(int row) const; virtual void setIntegerAt(int row, int new_value); virtual void replaceInteger(int first, const QVector& new_values); signals: void plotDesignationAboutToChange(const AbstractColumn* source); void plotDesignationChanged(const AbstractColumn* source); void modeAboutToChange(const AbstractColumn* source); void modeChanged(const AbstractColumn* source); void dataAboutToChange(const AbstractColumn* source); void dataChanged(const AbstractColumn* source); void rowsAboutToBeInserted(const AbstractColumn* source, int before, int count); void rowsInserted(const AbstractColumn* source, int before, int count); void rowsAboutToBeRemoved(const AbstractColumn* source, int first, int count); void rowsRemoved(const AbstractColumn* source, int first, int count); void maskingAboutToChange(const AbstractColumn* source); void maskingChanged(const AbstractColumn* source); void aboutToBeDestroyed(const AbstractColumn* source); protected: bool XmlReadMask(XmlStreamReader* reader); void XmlWriteMask(QXmlStreamWriter* writer) const; virtual void handleRowInsertion(int before, int count); virtual void handleRowRemoval(int first, int count); private: AbstractColumnPrivate* m_abstract_column_private; friend class AbstractColumnRemoveRowsCmd; friend class AbstractColumnInsertRowsCmd; friend class AbstractColumnClearMasksCmd; friend class AbstractColumnSetMaskedCmd; }; #endif diff --git a/src/backend/core/AbstractFilter.h b/src/backend/core/AbstractFilter.h index d997adf06..2b31c996b 100644 --- a/src/backend/core/AbstractFilter.h +++ b/src/backend/core/AbstractFilter.h @@ -1,100 +1,100 @@ /*************************************************************************** File : AbstractFilter.h Project : SciDAVis -------------------------------------------------------------------- Copyright : (C) 2007,2008 by Knut Franke, Tilman Benkert Email (use @ for *) : knut.franke*gmx.de, thzs*gmx.net Description : Base class for all analysis operations. ***************************************************************************/ /*************************************************************************** * * * 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 ABSTRACT_FILTER_H #define ABSTRACT_FILTER_H #include "AbstractAspect.h" #include class AbstractColumn; class AbstractFilter : public AbstractAspect { Q_OBJECT public: explicit AbstractFilter(const QString& name) : AbstractAspect(name) {} - virtual ~AbstractFilter() {} + ~AbstractFilter() override {} virtual int inputCount() const = 0; virtual int outputCount() const = 0; int highestConnectedInput() const; bool input(int port, const AbstractColumn* source); bool input(const AbstractFilter* sources); const AbstractColumn* input(int port) const; virtual QString inputLabel(int port) const; virtual AbstractColumn* output(int port = 0) = 0; virtual const AbstractColumn* output(int port = 0) const = 0; int portIndexOf(const AbstractColumn* column); protected: virtual bool inputAcceptable(int port, const AbstractColumn* source); virtual void inputAboutToBeDisconnected(const AbstractColumn* source); protected slots: virtual void inputDescriptionAboutToChange(const AbstractColumn* source); void inputDescriptionAboutToChange(const AbstractAspect* aspect); virtual void inputDescriptionChanged(const AbstractColumn* source); void inputDescriptionChanged(const AbstractAspect* aspect); virtual void inputPlotDesignationAboutToChange(const AbstractColumn* source); virtual void inputPlotDesignationChanged(const AbstractColumn* source); virtual void inputModeAboutToChange(const AbstractColumn* source); virtual void inputModeChanged(const AbstractColumn* source); virtual void inputDataAboutToChange(const AbstractColumn* source); virtual void inputDataChanged(const AbstractColumn* source); virtual void inputRowsAboutToBeInserted(const AbstractColumn* source, int before, int count) { Q_UNUSED(source); Q_UNUSED(before); Q_UNUSED(count); } virtual void inputRowsInserted(const AbstractColumn* source, int before, int count) { Q_UNUSED(source); Q_UNUSED(before); Q_UNUSED(count); } virtual void inputRowsAboutToBeRemoved(const AbstractColumn* source, int first, int count) { Q_UNUSED(source); Q_UNUSED(first); Q_UNUSED(count); } virtual void inputRowsRemoved(const AbstractColumn* source, int first, int count) { Q_UNUSED(source); Q_UNUSED(first); Q_UNUSED(count); } virtual void inputMaskingAboutToChange(const AbstractColumn* source) { Q_UNUSED(source); } virtual void inputMaskingChanged(const AbstractColumn* source) { Q_UNUSED(source); } void inputAboutToBeDestroyed(const AbstractColumn* source) { input(portIndexOf(source), 0); } protected: QVector m_inputs; }; #endif // ifndef ABSTRACT_FILTER_H diff --git a/src/backend/core/AbstractPart.h b/src/backend/core/AbstractPart.h index f01e63593..9895ce8b9 100644 --- a/src/backend/core/AbstractPart.h +++ b/src/backend/core/AbstractPart.h @@ -1,68 +1,68 @@ /*************************************************************************** File : AbstractPart.h Project : LabPlot Description : Base class of Aspects with MDI windows as views. -------------------------------------------------------------------- Copyright : (C) 2012-2015 Alexander Semke (alexander.semke@web.de) ***************************************************************************/ /*************************************************************************** * * * 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 ABSTRACT_PART_H #define ABSTRACT_PART_H #include "AbstractAspect.h" class PartMdiView; class QMenu; class AbstractPart : public AbstractAspect { Q_OBJECT public: explicit AbstractPart(const QString &name); - virtual ~AbstractPart(); + ~AbstractPart() override; virtual QWidget* view() const = 0; void deleteView() const; PartMdiView* mdiSubWindow() const; bool hasMdiSubWindow() const; void deleteMdiSubWindow(); - virtual QMenu* createContextMenu(); + QMenu* createContextMenu() override; virtual bool exportView() const = 0; virtual bool printView() = 0; virtual bool printPreview() const = 0; private: mutable PartMdiView* m_mdiWindow; protected: mutable QWidget* m_view; signals: void showRequested(); void exportRequested(); void printRequested(); void printPreviewRequested(); }; #endif // ifndef ABSTRACT_PART_H diff --git a/src/backend/core/AbstractScript.h b/src/backend/core/AbstractScript.h index f278477cb..81f92e32f 100644 --- a/src/backend/core/AbstractScript.h +++ b/src/backend/core/AbstractScript.h @@ -1,85 +1,85 @@ /*************************************************************************** File : AbstractScript.h Project : SciDAVis Description : A chunk of scripting code. -------------------------------------------------------------------- Copyright : (C) 2006 by Ion Vasilief (ion_vasilief@yahoo.fr) Copyright : (C) 2006 Tilman Benkert (thzs@gmx.net) Copyright : (C) 2006-2008 Knut Franke (knut.franke@gmx.de) ***************************************************************************/ /*************************************************************************** * * * 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 ABSTRACT_SCRIPT_H #define ABSTRACT_SCRIPT_H #include #include #include class ApplicationWindow; class AbstractScriptingEngine; class AbstractScript : public QObject { Q_OBJECT public: AbstractScript(AbstractScriptingEngine *env, const QString &code, QObject *context=0, const QString &name=""); - ~AbstractScript(); + ~AbstractScript() override; const QString code() const; const QObject* context() const; const QString name() const; bool emitErrors() const; virtual void addCode(const QString &code); virtual void setCode(const QString &code); virtual void setContext(QObject *context); void setName(const QString &name); void setEmitErrors(bool value); public slots: virtual bool compile(bool for_eval=true); virtual QVariant eval() = 0; virtual bool exec() = 0; // local variables virtual bool setQObject(const QObject*, const char*) { return false; } virtual bool setInt(int, const char*) { return false; } virtual bool setDouble(double, const char*) { return false; } signals: void codeChanged(); void error(const QString &message, const QString &scriptName, int lineNumber); void print(const QString &output); protected: AbstractScriptingEngine *m_engine; QString m_code, m_name; QObject *m_context; enum compileStatus { notCompiled, isCompiled, compileErr } m_compiled; bool m_emit_errors; void emit_error(const QString & message, int line_number) { if(m_emit_errors) emit error(message, m_name, line_number); } }; #endif diff --git a/src/backend/core/AbstractSimpleFilter.h b/src/backend/core/AbstractSimpleFilter.h index 7102a6c11..a1bc729b3 100644 --- a/src/backend/core/AbstractSimpleFilter.h +++ b/src/backend/core/AbstractSimpleFilter.h @@ -1,108 +1,108 @@ /*************************************************************************** File : AbstractSimpleFilter.h Project : AbstractColumn -------------------------------------------------------------------- Copyright : (C) 2007 Knut Franke (knut.franke@gmx.de) Copyright : (C) 2007 Tilman Benkert (thzs@gmx.net) Copyright : (C) 2017 Stefan Gerlach (stefan.gerlach@uni.kn) Description : Simplified filter interface for filters with only one output port. ***************************************************************************/ /*************************************************************************** * * * 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 ABSTRACTSIMPLEFILTER_H #define ABSTRACTSIMPLEFILTER_H #include "AbstractFilter.h" #include "AbstractColumn.h" #include "backend/lib/IntervalAttribute.h" class SimpleFilterColumn; class AbstractSimpleFilter : public AbstractFilter { Q_OBJECT public: AbstractSimpleFilter(); - virtual int inputCount() const override; - virtual int outputCount() const override; - virtual AbstractColumn* output(int port) override; - virtual const AbstractColumn * output(int port) const override; + int inputCount() const override; + int outputCount() const override; + AbstractColumn* output(int port) override; + const AbstractColumn * output(int port) const override; virtual AbstractColumn::PlotDesignation plotDesignation() const; virtual AbstractColumn::ColumnMode columnMode() const; virtual QString textAt(int row) const; virtual QDate dateAt(int row) const; virtual QTime timeAt(int row) const; virtual QDateTime dateTimeAt(int row) const;; virtual double valueAt(int row) const; virtual int integerAt(int row) const; virtual int rowCount() const; virtual QList> dependentRows(Interval inputRange) const; - virtual void save(QXmlStreamWriter*) const override; - virtual bool load(XmlStreamReader*, bool preview) override; + void save(QXmlStreamWriter*) const override; + bool load(XmlStreamReader*, bool preview) override; virtual void writeExtraAttributes(QXmlStreamWriter*) const; signals: void formatChanged(); void digitsChanged(); protected: - virtual void inputPlotDesignationAboutToChange(const AbstractColumn*) override; - virtual void inputPlotDesignationChanged(const AbstractColumn*) override; - virtual void inputModeAboutToChange(const AbstractColumn*) override; - virtual void inputModeChanged(const AbstractColumn*) override; - virtual void inputDataAboutToChange(const AbstractColumn*) override; - virtual void inputDataChanged(const AbstractColumn*) override; - - virtual void inputRowsAboutToBeInserted(const AbstractColumn * source, int before, int count) override; - virtual void inputRowsInserted(const AbstractColumn * source, int before, int count) override; - virtual void inputRowsAboutToBeRemoved(const AbstractColumn * source, int first, int count) override; - virtual void inputRowsRemoved(const AbstractColumn * source, int first, int count) override; + void inputPlotDesignationAboutToChange(const AbstractColumn*) override; + void inputPlotDesignationChanged(const AbstractColumn*) override; + void inputModeAboutToChange(const AbstractColumn*) override; + void inputModeChanged(const AbstractColumn*) override; + void inputDataAboutToChange(const AbstractColumn*) override; + void inputDataChanged(const AbstractColumn*) override; + + void inputRowsAboutToBeInserted(const AbstractColumn * source, int before, int count) override; + void inputRowsInserted(const AbstractColumn * source, int before, int count) override; + void inputRowsAboutToBeRemoved(const AbstractColumn * source, int first, int count) override; + void inputRowsRemoved(const AbstractColumn * source, int first, int count) override; SimpleFilterColumn* m_output_column; }; class SimpleFilterColumn : public AbstractColumn { Q_OBJECT public: SimpleFilterColumn(AbstractSimpleFilter* owner) : AbstractColumn(owner->name()), m_owner(owner) {} - virtual AbstractColumn::ColumnMode columnMode() const override; - virtual int rowCount() const override { return m_owner->rowCount(); } - virtual AbstractColumn::PlotDesignation plotDesignation() const override { return m_owner->plotDesignation(); } - virtual QString textAt(int row) const override; - virtual QDate dateAt(int row) const override; - virtual QTime timeAt(int row) const override; - virtual QDateTime dateTimeAt(int row) const override; - virtual double valueAt(int row) const override; - virtual int integerAt(int row) const override; - virtual void save(QXmlStreamWriter*) const override {}; - virtual bool load(XmlStreamReader*, bool preview) override {Q_UNUSED(preview); return true;}; + AbstractColumn::ColumnMode columnMode() const override; + int rowCount() const override { return m_owner->rowCount(); } + AbstractColumn::PlotDesignation plotDesignation() const override { return m_owner->plotDesignation(); } + QString textAt(int row) const override; + QDate dateAt(int row) const override; + QTime timeAt(int row) const override; + QDateTime dateTimeAt(int row) const override; + double valueAt(int row) const override; + int integerAt(int row) const override; + void save(QXmlStreamWriter*) const override {}; + bool load(XmlStreamReader*, bool preview) override {Q_UNUSED(preview); return true;}; private: AbstractSimpleFilter* m_owner; friend class AbstractSimpleFilter; }; #endif // ifndef ABSTRACTSIMPLEFILTER_H diff --git a/src/backend/core/AspectTreeModel.h b/src/backend/core/AspectTreeModel.h index 6df33b6d0..ecb8cecab 100644 --- a/src/backend/core/AspectTreeModel.h +++ b/src/backend/core/AspectTreeModel.h @@ -1,90 +1,90 @@ /*************************************************************************** File : AspectTreeModel.h Project : LabPlot Description : Represents a tree of AbstractAspect objects as a Qt item model. -------------------------------------------------------------------- Copyright : (C) 2007-2009 by Knut Franke (knut.franke@gmx.de) Copyright : (C) 2007-2009 by Tilman Benkert (thzs@gmx.net) Copyright : (C) 2011-2016 Alexander Semke (alexander.semke@web.de) ***************************************************************************/ /*************************************************************************** * * * 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 ASPECT_TREE_MODEL_H #define ASPECT_TREE_MODEL_H #include class AbstractAspect; class AspectTreeModel : public QAbstractItemModel { Q_OBJECT public: explicit AspectTreeModel(AbstractAspect* root, QObject* parent=0); - QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const; - QModelIndex parent(const QModelIndex &index) const; - int rowCount(const QModelIndex &parent = QModelIndex()) const; - int columnCount(const QModelIndex &parent = QModelIndex()) const; - QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; - QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; - bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole); - Qt::ItemFlags flags(const QModelIndex &index) const; + QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override; + QModelIndex parent(const QModelIndex &index) const override; + int rowCount(const QModelIndex &parent = QModelIndex()) const override; + int columnCount(const QModelIndex &parent = QModelIndex()) const override; + QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; + bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override; + Qt::ItemFlags flags(const QModelIndex &index) const override; void setSelectableAspects(QList); QModelIndex modelIndexOfAspect(const AbstractAspect*, int column=0) const; QModelIndex modelIndexOfAspect(const QString& path, int column=0) const; void setReadOnly(bool); void setFilterString(const QString&); void setFilterCaseSensitivity(Qt::CaseSensitivity); void setFilterMatchCompleteWord(bool); private slots: void aspectDescriptionChanged(const AbstractAspect*); void aspectAboutToBeAdded(const AbstractAspect* parent, const AbstractAspect* before, const AbstractAspect* child); void aspectAdded(const AbstractAspect* parent); void aspectAboutToBeRemoved(const AbstractAspect*); void aspectRemoved(); void aspectHiddenAboutToChange(const AbstractAspect*); void aspectHiddenChanged(const AbstractAspect*); void aspectSelectedInView(const AbstractAspect*); void aspectDeselectedInView(const AbstractAspect*); void renameRequestedSlot(); private: AbstractAspect* m_root; bool m_readOnly; bool m_folderSelectable; QList m_selectableAspects; QString m_filterString; Qt::CaseSensitivity m_filterCaseSensitivity; bool m_matchCompleteWord; bool containsFilterString(const AbstractAspect*) const; signals: void renameRequested(const QModelIndex&); void indexSelected(const QModelIndex&); void indexDeselected(const QModelIndex&); void hiddenAspectSelected(const AbstractAspect*); }; #endif // ifndef ASPECT_TREE_MODEL_H diff --git a/src/backend/core/Folder.h b/src/backend/core/Folder.h index 5abb0fbc0..87e19f219 100644 --- a/src/backend/core/Folder.h +++ b/src/backend/core/Folder.h @@ -1,50 +1,50 @@ /*************************************************************************** File : Folder.h Project : LabPlot Description : Folder in a project -------------------------------------------------------------------- Copyright : (C) 2007 Tilman Benkert (thzs@gmx.net) Copyright : (C) 2007 Knut Franke (knut.franke@gmx.de) ***************************************************************************/ /*************************************************************************** * * * 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 FOLDER_H #define FOLDER_H #include "AbstractAspect.h" class Folder : public AbstractAspect { Q_OBJECT public: explicit Folder(const QString& name); - virtual QIcon icon() const override; - virtual QMenu* createContextMenu() override; + QIcon icon() const override; + QMenu* createContextMenu() override; - virtual void save(QXmlStreamWriter*) const override; - virtual bool load(XmlStreamReader*, bool preview) override; + void save(QXmlStreamWriter*) const override; + bool load(XmlStreamReader*, bool preview) override; protected: bool readChildAspectElement(XmlStreamReader*, bool preview); }; #endif // ifndef FOLDER_H diff --git a/src/backend/core/Project.h b/src/backend/core/Project.h index 7b4f54b1c..ff15b0391 100644 --- a/src/backend/core/Project.h +++ b/src/backend/core/Project.h @@ -1,103 +1,103 @@ /*************************************************************************** File : Project.h Project : LabPlot Description : Represents a LabPlot project. -------------------------------------------------------------------- Copyright : (C) 2011-2014 Alexander Semke (alexander.semke@web.de) Copyright : (C) 2007-2008 Tilman Benkert (thzs@gmx.net) Copyright : (C) 2007 Knut Franke (knut.franke@gmx.de) ***************************************************************************/ /*************************************************************************** * * * 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 PROJECT_H #define PROJECT_H #include "backend/core/Folder.h" #include "backend/lib/macros.h" class QString; class AbstractScriptingEngine; class Project : public Folder { Q_OBJECT public: enum MdiWindowVisibility { folderOnly, folderAndSubfolders, allMdiWindows }; public: Project(); - ~Project(); + ~Project() override; virtual const Project* project() const { return this; } - virtual Project* project() override { + Project* project() override { return this; } - virtual QUndoStack* undoStack() const override; - virtual QString path() const override { + QUndoStack* undoStack() const override; + QString path() const override { return name(); } - virtual QMenu* createContextMenu() override; + QMenu* createContextMenu() override; virtual QMenu* createFolderContextMenu(const Folder*); AbstractScriptingEngine* scriptingEngine() const; void setMdiWindowVisibility(MdiWindowVisibility visibility); MdiWindowVisibility mdiWindowVisibility() const; CLASS_D_ACCESSOR_DECL(QString, fileName, FileName) BASIC_D_ACCESSOR_DECL(QString, version, Version) CLASS_D_ACCESSOR_DECL(QString, author, Author) CLASS_D_ACCESSOR_DECL(QDateTime, modificationTime, ModificationTime) bool isLoading() const; void setChanged(const bool value=true); bool hasChanged() const; void navigateTo(const QString& path); - virtual void save(QXmlStreamWriter*) const override; - virtual bool load(XmlStreamReader*, bool preview) override; + void save(QXmlStreamWriter*) const override; + bool load(XmlStreamReader*, bool preview) override; bool load(const QString&, bool preview = false); public slots: void descriptionChanged(const AbstractAspect*); signals: void requestSaveState(QXmlStreamWriter*) const; void requestLoadState(XmlStreamReader*) const; void requestProjectContextMenu(QMenu*); void requestFolderContextMenu(const Folder*, QMenu*); void mdiWindowVisibilityChanged(); void changed() const; void requestNavigateTo(const QString& path) const; void loaded(); private: class Private; Private* d; bool readProjectAttributes(XmlStreamReader*); }; #endif // ifndef PROJECT_H diff --git a/src/backend/core/Workbook.h b/src/backend/core/Workbook.h index dabec8338..e01a03846 100644 --- a/src/backend/core/Workbook.h +++ b/src/backend/core/Workbook.h @@ -1,72 +1,72 @@ /*************************************************************************** File : Workbook.h Project : LabPlot Description : Aspect providing a container for storing data in form of spreadsheets and matrices -------------------------------------------------------------------- Copyright : (C) 2015 Alexander Semke(alexander.semke@web.de) ***************************************************************************/ /*************************************************************************** * * * 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 WORKBOOK_H #define WORKBOOK_H #include "backend/core/AbstractPart.h" #include "backend/core/AbstractScriptingEngine.h" class Spreadsheet; class Matrix; class QXmlStreamWriter; class XmlStreamReader; class Workbook : public AbstractPart, public scripted { Q_OBJECT public: Workbook(AbstractScriptingEngine* engine, const QString& name); - virtual QIcon icon() const override; - virtual QMenu* createContextMenu() override; - virtual QWidget* view() const override; + QIcon icon() const override; + QMenu* createContextMenu() override; + QWidget* view() const override; - virtual bool exportView() const override; - virtual bool printView() override; - virtual bool printPreview() const override; + bool exportView() const override; + bool printView() override; + bool printPreview() const override; Spreadsheet* currentSpreadsheet() const; Matrix* currentMatrix() const; void setChildSelectedInView(int index, bool selected); - virtual void save(QXmlStreamWriter*) const override; - virtual bool load(XmlStreamReader*, bool preview) override; + void save(QXmlStreamWriter*) const override; + bool load(XmlStreamReader*, bool preview) override; public slots: - virtual void childSelected(const AbstractAspect*) override; + void childSelected(const AbstractAspect*) override; private slots: - virtual void childDeselected(const AbstractAspect*) override; + void childDeselected(const AbstractAspect*) override; signals: void requestProjectContextMenu(QMenu*); void workbookItemSelected(int); }; #endif diff --git a/src/backend/core/abstractcolumncommands.h b/src/backend/core/abstractcolumncommands.h index e3b8c4823..fcd179c4d 100644 --- a/src/backend/core/abstractcolumncommands.h +++ b/src/backend/core/abstractcolumncommands.h @@ -1,95 +1,95 @@ /*************************************************************************** File : abstractcolumncommands.h Project : LabPlot Description : Commands to be called by AbstractColumn to modify AbstractColumnPrivate -------------------------------------------------------------------- Copyright : (C) 2007-2009 Tilman Benkert (thzs@gmx.net) Copyright : (C) 2010 Knut Franke (knut.franke@gmx.de) ***************************************************************************/ /*************************************************************************** * * * 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 ABSTRACTCOLUMNCOMMANDS_H #define ABSTRACTCOLUMNCOMMANDS_H #include "AbstractColumnPrivate.h" #include class AbstractColumnClearMasksCmd : public QUndoCommand { public: explicit AbstractColumnClearMasksCmd(AbstractColumnPrivate* col, QUndoCommand* parent = 0); - ~AbstractColumnClearMasksCmd(); + ~AbstractColumnClearMasksCmd() override; - virtual void redo(); - virtual void undo(); + void redo() override; + void undo() override; private: AbstractColumnPrivate *m_col; IntervalAttribute m_masking; bool m_copied; }; class AbstractColumnSetMaskedCmd : public QUndoCommand { public: explicit AbstractColumnSetMaskedCmd(AbstractColumnPrivate* col, Interval interval, bool masked, QUndoCommand* parent = 0); - ~AbstractColumnSetMaskedCmd(); + ~AbstractColumnSetMaskedCmd() override; - virtual void redo(); - virtual void undo(); + void redo() override; + void undo() override; private: AbstractColumnPrivate* m_col; Interval m_interval; bool m_masked; IntervalAttribute m_masking; bool m_copied; }; class AbstractColumnInsertRowsCmd : public QUndoCommand { public: explicit AbstractColumnInsertRowsCmd(AbstractColumn* col, int before, int count, QUndoCommand* parent = 0); - ~AbstractColumnInsertRowsCmd(); + ~AbstractColumnInsertRowsCmd() override; - virtual void redo(); - virtual void undo(); + void redo() override; + void undo() override; protected: AbstractColumnPrivate* m_col; int m_before; int m_count; }; class AbstractColumnRemoveRowsCmd : public QUndoCommand { public: explicit AbstractColumnRemoveRowsCmd(AbstractColumn* col, int first, int count, QUndoCommand* parent = 0); - ~AbstractColumnRemoveRowsCmd(); + ~AbstractColumnRemoveRowsCmd() override; - virtual void redo(); - virtual void undo(); + void redo() override; + void undo() override; protected: AbstractColumnPrivate* m_col; int m_first; int m_count; IntervalAttribute m_masking; }; #endif // ifndef ABSTRACTCOLUMNCOMMANDS_H diff --git a/src/backend/core/aspectcommands.h b/src/backend/core/aspectcommands.h index baa11d1ea..300f4e853 100644 --- a/src/backend/core/aspectcommands.h +++ b/src/backend/core/aspectcommands.h @@ -1,130 +1,130 @@ /*************************************************************************** File : aspectcommands.h Project : LabPlot -------------------------------------------------------------------- Copyright : (C) 2007-2010 by Knut Franke (knut.franke@gmx.de) Copyright : (C) 2007-2009 Tilman Benkert(thzs@gmx.net) Copyright : (C) 2013-2017 by Alexander Semke (alexander.semke@web.de) Description : Undo commands used by AbstractAspect. Only meant to be used within AbstractAspect.cpp ***************************************************************************/ /*************************************************************************** * * * 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 ASPECTCOMMANDS_H #define ASPECTCOMMANDS_H #include "AspectPrivate.h" #include #include class AspectChildRemoveCmd : public QUndoCommand { public: AspectChildRemoveCmd(AbstractAspectPrivate* target, AbstractAspect* child) : m_target(target), m_child(child), m_index(-1) { // , m_removed(false) { setText(i18n("%1: remove %2", m_target->m_name, m_child->name())); } - ~AspectChildRemoveCmd() { + ~AspectChildRemoveCmd() override { //TODO: this makes labplot crashing on project close/save. // if (m_removed) // delete m_child; } // calling redo transfers ownership of m_child to the undo command - virtual void redo() { + void redo() override { AbstractAspect* nextSibling; if (m_child == m_target->m_children.last()) nextSibling = 0; else nextSibling = m_target->m_children.at(m_target->indexOfChild(m_child) + 1); emit m_target->q->aspectAboutToBeRemoved(m_child); m_index = m_target->removeChild(m_child); emit m_target->q->aspectRemoved(m_target->q, nextSibling, m_child); // m_removed = true; } // calling undo transfers ownership of m_child back to its parent aspect - virtual void undo() { + void undo() override { Q_ASSERT(m_index != -1); // m_child must be a child of m_target->q emit m_target->q->aspectAboutToBeAdded(m_target->q, 0, m_child); m_target->insertChild(m_index, m_child); emit m_target->q->aspectAdded(m_child); // m_removed = false; } protected: AbstractAspectPrivate* m_target; AbstractAspect* m_child; int m_index; // bool m_removed; }; class AspectChildAddCmd : public AspectChildRemoveCmd { public: AspectChildAddCmd(AbstractAspectPrivate* target, AbstractAspect* child, int index) : AspectChildRemoveCmd(target, child) { setText(i18n("%1: add %2", m_target->m_name, m_child->name())); m_index = index; // m_removed = true; } - virtual void redo() { + void redo() override { AspectChildRemoveCmd::undo(); } - virtual void undo() { + void undo() override { AspectChildRemoveCmd::redo(); } }; class AspectChildReparentCmd : public QUndoCommand { public: AspectChildReparentCmd(AbstractAspectPrivate* target, AbstractAspectPrivate* new_parent, AbstractAspect* child, int new_index) : m_target(target), m_new_parent(new_parent), m_child(child), m_index(-1), m_new_index(new_index) { setText(i18n("%1: move %2 to %3.", m_target->m_name, m_child->name(), m_new_parent->m_name)); } // calling redo transfers ownership of m_child to the new parent aspect - virtual void redo() { + void redo() override { m_index = m_target->removeChild(m_child); m_new_parent->insertChild(m_new_index, m_child); } // calling undo transfers ownership of m_child back to its previous parent aspect - virtual void undo() { + void undo() override { Q_ASSERT(m_index != -1); m_new_parent->removeChild(m_child); m_target->insertChild(m_index, m_child); } protected: AbstractAspectPrivate * m_target; AbstractAspectPrivate * m_new_parent; AbstractAspect* m_child; int m_index; int m_new_index; }; #endif diff --git a/src/backend/core/column/Column.cpp b/src/backend/core/column/Column.cpp index 95d3faac5..9f4ab0d9b 100644 --- a/src/backend/core/column/Column.cpp +++ b/src/backend/core/column/Column.cpp @@ -1,1182 +1,1182 @@ /*************************************************************************** File : Column.cpp Project : LabPlot Description : Aspect that manages a column -------------------------------------------------------------------- Copyright : (C) 2007-2009 Tilman Benkert (thzs@gmx.net) Copyright : (C) 2013-2017 Alexander Semke (alexander.semke@web.de) Copyright : (C) 2017 Stefan Gerlach (stefan.gerlach@uni.kn) ***************************************************************************/ /*************************************************************************** * * * 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 "backend/core/column/Column.h" #include "backend/core/column/ColumnPrivate.h" #include "backend/core/column/ColumnStringIO.h" #include "backend/core/column/columncommands.h" #include "backend/core/Project.h" #include "backend/lib/XmlStreamReader.h" #include "backend/core/datatypes/String2DateTimeFilter.h" #include "backend/core/datatypes/DateTime2StringFilter.h" #include "backend/worksheet/plots/cartesian/XYCurve.h" extern "C" { #include } #include #include #include #include #include #include /** * \class Column * \brief Aspect that manages a column * * This class represents a column, i.e., (mathematically) a 1D vector of * values with a header. It provides a public reading and (undo aware) writing * interface as defined in AbstractColumn. A column * can have one of currently three data types: double, QString, or * QDateTime. The string representation of the values can differ depending * on the mode of the column. * * Column inherits from AbstractAspect and is intended to be a child * of the corresponding Spreadsheet in the aspect hierarchy. Columns don't * have a view as they are intended to be displayed inside a spreadsheet. */ Column::Column(const QString& name, AbstractColumn::ColumnMode mode) : AbstractColumn(name), d(new ColumnPrivate(this, mode)) { init(); } /** * \brief Common part of ctors */ void Column::init() { m_string_io = new ColumnStringIO(this); d->inputFilter()->input(0, m_string_io); d->outputFilter()->input(0, this); d->inputFilter()->setHidden(true); d->outputFilter()->setHidden(true); addChild(d->inputFilter()); addChild(d->outputFilter()); m_suppressDataChangedSignal = false; m_usedInActionGroup = new QActionGroup(this); connect(m_usedInActionGroup, &QActionGroup::triggered, this, &Column::navigateTo); } Column::~Column() { delete m_string_io; delete d; } QMenu* Column::createContextMenu() { QMenu* menu = AbstractAspect::createContextMenu(); QAction* firstAction = menu->actions().at(1); //add actions available in SpreadsheetView emit requestProjectContextMenu(menu); //"Used in" menu containing all curves where the column is used QMenu* usedInMenu = new QMenu(i18n("Used in")); usedInMenu->setIcon(QIcon::fromTheme("go-next-view")); //remove previously added actions for (auto* action: m_usedInActionGroup->actions()) m_usedInActionGroup->removeAction(action); //add curves where the column is currently in use QVector curves = project()->children(AbstractAspect::Recursive); for (const auto* curve: curves) { if (curve->dataSourceType() == XYCurve::DataSourceSpreadsheet && (curve->xColumn() == this || curve->yColumn() == this) ) { QAction* action = new QAction(curve->icon(), curve->name(), m_usedInActionGroup); action->setData(curve->path()); usedInMenu->addAction(action); } } menu->insertSeparator(firstAction); menu->insertMenu(firstAction, usedInMenu); menu->insertSeparator(firstAction); return menu; } void Column::navigateTo(QAction* action) { project()->navigateTo(action->data().toString()); } /*! * */ void Column::setSuppressDataChangedSignal(bool b) { m_suppressDataChangedSignal = b; } /** * \brief Set the column mode * * This sets the column mode and, if * necessary, converts it to another datatype. */ void Column::setColumnMode(AbstractColumn::ColumnMode mode) { if (mode == columnMode()) return; DEBUG("Column::setColumnMode()"); beginMacro(i18n("%1: change column type", name())); auto* old_input_filter = d->inputFilter(); auto* old_output_filter = d->outputFilter(); exec(new ColumnSetModeCmd(d, mode)); if (d->inputFilter() != old_input_filter) { removeChild(old_input_filter); addChild(d->inputFilter()); d->inputFilter()->input(0, m_string_io); } if (d->outputFilter() != old_output_filter) { removeChild(old_output_filter); addChild(d->outputFilter()); d->outputFilter()->input(0, this); } endMacro(); DEBUG("Column::setColumnMode() DONE"); } void Column::setColumnModeFast(AbstractColumn::ColumnMode mode) { if (mode == columnMode()) return; auto* old_input_filter = d->inputFilter(); auto* old_output_filter = d->outputFilter(); exec(new ColumnSetModeCmd(d, mode)); if (d->inputFilter() != old_input_filter) { removeChild(old_input_filter); addChildFast(d->inputFilter()); d->inputFilter()->input(0, m_string_io); } if (d->outputFilter() != old_output_filter) { removeChild(old_output_filter); addChildFast(d->outputFilter()); d->outputFilter()->input(0, this); } } /** * \brief Copy another column of the same type * * This function will return false if the data type * of 'other' is not the same as the type of 'this'. * Use a filter to convert a column to another type. */ bool Column::copy(const AbstractColumn* other) { Q_CHECK_PTR(other); if (other->columnMode() != columnMode()) return false; exec(new ColumnFullCopyCmd(d, other)); return true; } /** * \brief Copies a part of another column of the same type * * This function will return false if the data type * of 'other' is not the same as the type of 'this'. * \param other pointer to the column to copy * \param src_start first row to copy in the column to copy * \param dest_start first row to copy in * \param num_rows the number of rows to copy */ bool Column::copy(const AbstractColumn* source, int source_start, int dest_start, int num_rows) { Q_CHECK_PTR(source); if (source->columnMode() != columnMode()) return false; exec(new ColumnPartialCopyCmd(d, source, source_start, dest_start, num_rows)); return true; } /** * \brief Insert some empty (or initialized with zero) rows */ void Column::handleRowInsertion(int before, int count) { AbstractColumn::handleRowInsertion(before, count); exec(new ColumnInsertRowsCmd(d, before, count)); if (!m_suppressDataChangedSignal) emit dataChanged(this); setStatisticsAvailable(false); } /** * \brief Remove 'count' rows starting from row 'first' */ void Column::handleRowRemoval(int first, int count) { AbstractColumn::handleRowRemoval(first, count); exec(new ColumnRemoveRowsCmd(d, first, count)); if (!m_suppressDataChangedSignal) emit dataChanged(this); setStatisticsAvailable(false); } /** * \brief Set the column plot designation */ void Column::setPlotDesignation(AbstractColumn::PlotDesignation pd) { if (pd != plotDesignation()) exec(new ColumnSetPlotDesignationCmd(d, pd)); } /** * \brief Get width */ int Column::width() const { return d->width(); } /** * \brief Set width */ void Column::setWidth(int value) { d->setWidth(value); } /** * \brief Clear the whole column */ void Column::clear() { exec(new ColumnClearCmd(d)); } //////////////////////////////////////////////////////////////////////////////// //@} //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// //! \name Formula related functions //@{ //////////////////////////////////////////////////////////////////////////////// /** * \brief Returns the formula used to generate column values */ QString Column:: formula() const { return d->formula(); } const QStringList& Column::formulaVariableNames() const { return d->formulaVariableNames(); } const QStringList& Column::formulaVariableColumnPathes() const { return d->formulaVariableColumnPathes(); } /** * \brief Sets the formula used to generate column values */ void Column::setFormula(const QString& formula, const QStringList& variableNames, const QStringList& columnPathes) { exec(new ColumnSetGlobalFormulaCmd(d, formula, variableNames, columnPathes)); } /** * \brief Set a formula string for an interval of rows */ void Column::setFormula(Interval i, QString formula) { exec(new ColumnSetFormulaCmd(d, i, formula)); } /** * \brief Overloaded function for convenience */ void Column::setFormula(int row, QString formula) { setFormula(Interval(row, row), formula); } /** * \brief Clear all formulas */ void Column::clearFormulas() { exec(new ColumnClearFormulasCmd(d)); } //////////////////////////////////////////////////////////////////////////////// //@} //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// //! \name type specific functions //@{ //////////////////////////////////////////////////////////////////////////////// /** * \brief Set the content of row 'row' * * Use this only when columnMode() is Text */ void Column::setTextAt(int row, const QString& new_value) { DEBUG("Column::setTextAt()"); setStatisticsAvailable(false); exec(new ColumnSetTextCmd(d, row, new_value)); } /** * \brief Replace a range of values * * Use this only when columnMode() is Text */ void Column::replaceTexts(int first, const QVector& new_values) { DEBUG("Column::replaceTexts()"); if (!new_values.isEmpty()) { //TODO: do we really need this check? setStatisticsAvailable(false); exec(new ColumnReplaceTextsCmd(d, first, new_values)); } } /** * \brief Set the content of row 'row' * * Use this only when columnMode() is DateTime, Month or Day */ void Column::setDateAt(int row, const QDate& new_value) { setStatisticsAvailable(false); setDateTimeAt(row, QDateTime(new_value, timeAt(row))); } /** * \brief Set the content of row 'row' * * Use this only when columnMode() is DateTime, Month or Day */ void Column::setTimeAt(int row, const QTime& new_value) { setStatisticsAvailable(false); setDateTimeAt(row, QDateTime(dateAt(row), new_value)); } /** * \brief Set the content of row 'row' * * Use this only when columnMode() is DateTime, Month or Day */ void Column::setDateTimeAt(int row, const QDateTime& new_value) { setStatisticsAvailable(false); exec(new ColumnSetDateTimeCmd(d, row, new_value)); } /** * \brief Replace a range of values * * Use this only when columnMode() is DateTime, Month or Day */ void Column::replaceDateTimes(int first, const QVector& new_values) { if (!new_values.isEmpty()) { setStatisticsAvailable(false); exec(new ColumnReplaceDateTimesCmd(d, first, new_values)); } } /** * \brief Set the content of row 'row' * * Use this only when columnMode() is Numeric */ void Column::setValueAt(int row, double new_value) { // DEBUG("Column::setValueAt()"); setStatisticsAvailable(false); exec(new ColumnSetValueCmd(d, row, new_value)); } /** * \brief Replace a range of values * * Use this only when columnMode() is Numeric */ void Column::replaceValues(int first, const QVector& new_values) { DEBUG("Column::replaceValues()"); if (!new_values.isEmpty()) { setStatisticsAvailable(false); exec(new ColumnReplaceValuesCmd(d, first, new_values)); } } /** * \brief Set the content of row 'row' * * Use this only when columnMode() is Integer */ void Column::setIntegerAt(int row, int new_value) { DEBUG("Column::setIntegerAt()"); setStatisticsAvailable(false); exec(new ColumnSetIntegerCmd(d, row, new_value)); } /** * \brief Replace a range of values * * Use this only when columnMode() is Integer */ void Column::replaceInteger(int first, const QVector& new_values) { DEBUG("Column::replaceInteger()"); if (!new_values.isEmpty()) { setStatisticsAvailable(false); exec(new ColumnReplaceIntegersCmd(d, first, new_values)); } } void Column::setStatisticsAvailable(bool available) { d->statisticsAvailable = available; } bool Column::statisticsAvailable() const { return d->statisticsAvailable; } const Column::ColumnStatistics& Column::statistics() { if (!statisticsAvailable()) calculateStatistics(); return d->statistics; } void Column::calculateStatistics() { d->statistics = ColumnStatistics(); ColumnStatistics& statistics = d->statistics; // TODO: support other data types? QVector* rowValues = reinterpret_cast*>(data()); size_t notNanCount = 0; double val; double columnSum = 0.0; double columnProduct = 1.0; double columnSumNeg = 0.0; double columnSumSquare = 0.0; statistics.minimum = INFINITY; statistics.maximum = -INFINITY; QMap frequencyOfValues; QVector rowData; rowData.reserve(rowValues->size()); for (int row = 0; row < rowValues->size(); ++row) { val = rowValues->value(row); if (std::isnan(val) || isMasked(row)) continue; if (val < statistics.minimum) statistics.minimum = val; if (val > statistics.maximum) statistics.maximum = val; columnSum+= val; columnSumNeg += (1.0 / val); columnSumSquare += pow(val, 2.0); columnProduct *= val; if (frequencyOfValues.contains(val)) frequencyOfValues.operator [](val)++; else frequencyOfValues.insert(val, 1); ++notNanCount; rowData.push_back(val); } if (notNanCount == 0) { setStatisticsAvailable(true); return; } if (rowData.size() < rowValues->size()) rowData.squeeze(); statistics.arithmeticMean = columnSum / notNanCount; statistics.geometricMean = pow(columnProduct, 1.0 / notNanCount); statistics.harmonicMean = notNanCount / columnSumNeg; statistics.contraharmonicMean = columnSumSquare / columnSum; double columnSumVariance = 0; double columnSumMeanDeviation = 0.0; double columnSumMedianDeviation = 0.0; double sumForCentralMoment_r3 = 0.0; double sumForCentralMoment_r4 = 0.0; gsl_sort(rowData.data(), 1, notNanCount); statistics.median = (notNanCount%2) ? rowData.at((notNanCount-1)/2) : (rowData.at((notNanCount-1)/2) + rowData.at(notNanCount/2))/2.0; QVector absoluteMedianList; absoluteMedianList.reserve(notNanCount); absoluteMedianList.resize(notNanCount); int idx = 0; for(int row = 0; row < rowValues->size(); ++row) { val = rowValues->value(row); if (std::isnan(val) || isMasked(row) ) continue; columnSumVariance += pow(val - statistics.arithmeticMean, 2.0); sumForCentralMoment_r3 += pow(val - statistics.arithmeticMean, 3.0); sumForCentralMoment_r4 += pow(val - statistics.arithmeticMean, 4.0); columnSumMeanDeviation += fabs( val - statistics.arithmeticMean ); absoluteMedianList[idx] = fabs(val - statistics.median); columnSumMedianDeviation += absoluteMedianList[idx]; idx++; } statistics.meanDeviationAroundMedian = columnSumMedianDeviation / notNanCount; statistics.medianDeviation = (notNanCount%2) ? absoluteMedianList.at((notNanCount-1)/2) : (absoluteMedianList.at((notNanCount-1)/2) + absoluteMedianList.at(notNanCount/2))/2.0; const double centralMoment_r3 = sumForCentralMoment_r3 / notNanCount; const double centralMoment_r4 = sumForCentralMoment_r4 / notNanCount; statistics.variance = columnSumVariance / notNanCount; statistics.standardDeviation = sqrt(statistics.variance); statistics.skewness = centralMoment_r3 / pow(statistics.standardDeviation, 3.0); statistics.kurtosis = (centralMoment_r4 / pow(statistics.standardDeviation, 4.0)) - 3.0; statistics.meanDeviation = columnSumMeanDeviation / notNanCount; double entropy = 0.0; for (const auto& v: frequencyOfValues.values()) { const double frequencyNorm = static_cast(v) / notNanCount; entropy += (frequencyNorm * log2(frequencyNorm)); } statistics.entropy = -entropy; setStatisticsAvailable(true); } ////////////////////////////////////////////////////////////////////////////////////////////// void* Column::data() const { return d->data(); } //TODO: support all data types /** * \brief Return the content of row 'row'. * * Use this only when columnMode() is Text */ QString Column::textAt(int row) const { return d->textAt(row); } /** * \brief Return the date part of row 'row' * * Use this only when columnMode() is DateTime, Month or Day */ QDate Column::dateAt(int row) const { return d->dateAt(row); } /** * \brief Return the time part of row 'row' * * Use this only when columnMode() is DateTime, Month or Day */ QTime Column::timeAt(int row) const { return d->timeAt(row); } /** * \brief Return the QDateTime in row 'row' * * Use this only when columnMode() is DateTime, Month or Day */ QDateTime Column::dateTimeAt(int row) const { return d->dateTimeAt(row); } /** * \brief Return the double value in row 'row' */ double Column::valueAt(int row) const { return d->valueAt(row); } /** * \brief Return the int value in row 'row' */ int Column::integerAt(int row) const { return d->integerAt(row); } /* * call this function if the data of the column was changed directly via the data()-pointer * and not via the setValueAt() in order to emit the dataChanged-signal. * This is used e.g. in \c XYFitCurvePrivate::recalculate() */ void Column::setChanged() { if (!m_suppressDataChangedSignal) emit dataChanged(this); setStatisticsAvailable(false); } //////////////////////////////////////////////////////////////////////////////// //@} //////////////////////////////////////////////////////////////////////////////// /** * \brief Return an icon to be used for decorating the views and spreadsheet column headers */ QIcon Column::icon() const { return iconForMode(columnMode()); } //////////////////////////////////////////////////////////////////////////////////////////////////// //! \name serialize/deserialize //@{ //////////////////////////////////////////////////////////////////////////////////////////////////// /** * \brief Save the column as XML */ void Column::save(QXmlStreamWriter* writer) const { writer->writeStartElement("column"); writeBasicAttributes(writer); writer->writeAttribute("designation", QString::number(plotDesignation())); writer->writeAttribute("mode", QString::number(columnMode())); writer->writeAttribute("width", QString::number(width())); //save the formula used to generate column values, if available if (!formula().isEmpty() ) { writer->writeStartElement("formula"); writer->writeTextElement("text", formula()); writer->writeStartElement("variableNames"); for (auto name: formulaVariableNames()) writer->writeTextElement("name", name); writer->writeEndElement(); writer->writeStartElement("columnPathes"); for (auto path: formulaVariableColumnPathes()) writer->writeTextElement("path", path); writer->writeEndElement(); writer->writeEndElement(); } writeCommentElement(writer); writer->writeStartElement("input_filter"); d->inputFilter()->save(writer); writer->writeEndElement(); writer->writeStartElement("output_filter"); d->outputFilter()->save(writer); writer->writeEndElement(); XmlWriteMask(writer); //TODO: formula in cells is not implemented yet // QList< Interval > formulas = formulaIntervals(); // foreach(const Interval& interval, formulas) { // writer->writeStartElement("formula"); // writer->writeAttribute("start_row", QString::number(interval.start())); // writer->writeAttribute("end_row", QString::number(interval.end())); // writer->writeCharacters(formula(interval.start())); // writer->writeEndElement(); // } int i; switch(columnMode()) { case AbstractColumn::Numeric: { const char* data = reinterpret_cast(static_cast< QVector* >(d->data())->constData()); size_t size = d->rowCount() * sizeof(double); writer->writeCharacters(QByteArray::fromRawData(data, (int)size).toBase64()); break; } case AbstractColumn::Integer: { const char* data = reinterpret_cast(static_cast< QVector* >(d->data())->constData()); size_t size = d->rowCount() * sizeof(int); writer->writeCharacters(QByteArray::fromRawData(data, (int)size).toBase64()); break; } case AbstractColumn::Text: for (i = 0; i < rowCount(); ++i) { writer->writeStartElement("row"); writer->writeAttribute("index", QString::number(i)); writer->writeCharacters(textAt(i)); writer->writeEndElement(); } break; case AbstractColumn::DateTime: case AbstractColumn::Month: case AbstractColumn::Day: for (i = 0; i < rowCount(); ++i) { writer->writeStartElement("row"); writer->writeAttribute("index", QString::number(i)); writer->writeCharacters(dateTimeAt(i).toString("yyyy-dd-MM hh:mm:ss:zzz")); writer->writeEndElement(); } break; } writer->writeEndElement(); // "column" } //TODO: extra header class DecodeColumnTask : public QRunnable { public: DecodeColumnTask(ColumnPrivate* priv, const QString& content) { m_private = priv; m_content = content; }; - void run() { + void run() override { QByteArray bytes = QByteArray::fromBase64(m_content.toAscii()); if (m_private->columnMode() == AbstractColumn::Numeric) { QVector* data = new QVector(bytes.size()/(int)sizeof(double)); memcpy(data->data(), bytes.data(), bytes.size()); m_private->replaceData(data); } else { QVector* data = new QVector(bytes.size()/(int)sizeof(int)); memcpy(data->data(), bytes.data(), bytes.size()); m_private->replaceData(data); } } private: ColumnPrivate* m_private; QString m_content; }; /** * \brief Load the column from XML */ bool Column::load(XmlStreamReader* reader, bool preview) { if (reader->isStartElement() && reader->name() != "column") { reader->raiseError(i18n("no column element found")); return false; } if (!readBasicAttributes(reader)) return false; QString attributeWarning = i18n("Attribute '%1' missing or empty, default value is used"); QXmlStreamAttributes attribs = reader->attributes(); QString str = attribs.value("designation").toString(); if (str.isEmpty()) reader->raiseWarning(attributeWarning.arg("'designation'")); else d->setPlotDesignation( AbstractColumn::PlotDesignation(str.toInt()) ); str = attribs.value("mode").toString(); if (str.isEmpty()) reader->raiseWarning(attributeWarning.arg("'mode'")); else setColumnModeFast( AbstractColumn::ColumnMode(str.toInt()) ); str = attribs.value("width").toString(); if (str.isEmpty()) reader->raiseWarning(attributeWarning.arg("'width'")); else d->setWidth(str.toInt()); // read child elements while (!reader->atEnd()) { reader->readNext(); if (reader->isEndElement()) break; if (reader->isStartElement()) { bool ret_val = true; if (reader->name() == "comment") ret_val = readCommentElement(reader); else if (reader->name() == "input_filter") ret_val = XmlReadInputFilter(reader); else if (reader->name() == "output_filter") ret_val = XmlReadOutputFilter(reader); else if (reader->name() == "mask") ret_val = XmlReadMask(reader); else if (reader->name() == "formula") ret_val = XmlReadFormula(reader); else if (reader->name() == "row") ret_val = XmlReadRow(reader); else { // unknown element reader->raiseWarning(i18n("unknown element '%1'", reader->name().toString())); if (!reader->skipToEndElement()) return false; } if (!ret_val) return false; } if (!preview) { QString content = reader->text().toString().trimmed(); if (!content.isEmpty() && ( columnMode() == AbstractColumn::Numeric || columnMode() == AbstractColumn::Integer)) { DecodeColumnTask* task = new DecodeColumnTask(d, content); QThreadPool::globalInstance()->start(task); } } } return !reader->error(); } /** * \brief Read XML input filter element */ bool Column::XmlReadInputFilter(XmlStreamReader* reader) { Q_ASSERT(reader->isStartElement() && reader->name() == "input_filter"); if (!reader->skipToNextTag()) return false; if (!d->inputFilter()->load(reader, false)) return false; if (!reader->skipToNextTag()) return false; Q_ASSERT(reader->isEndElement() && reader->name() == "input_filter"); return true; } /** * \brief Read XML output filter element */ bool Column::XmlReadOutputFilter(XmlStreamReader* reader) { Q_ASSERT(reader->isStartElement() && reader->name() == "output_filter"); if (!reader->skipToNextTag()) return false; if (!d->outputFilter()->load(reader, false)) return false; if (!reader->skipToNextTag()) return false; Q_ASSERT(reader->isEndElement() && reader->name() == "output_filter"); return true; } /** * \brief Read XML formula element */ bool Column::XmlReadFormula(XmlStreamReader* reader) { QString formula; QStringList variableNames; QStringList columnPathes; while (reader->readNext()) { if (reader->isEndElement()) break; if (reader->name() == "text") formula = reader->readElementText(); else if (reader->name() == "variableNames") { while (reader->readNext()) { if (reader->name() == "variableNames" && reader->isEndElement()) break; if (reader->isStartElement()) variableNames << reader->readElementText(); } } else if (reader->name() == "columnPathes") { while (reader->readNext()) { if (reader->name() == "columnPathes" && reader->isEndElement()) break; if (reader->isStartElement()) columnPathes << reader->readElementText(); } } } setFormula(formula, variableNames, columnPathes); return true; } //TODO: read cell formula, not implemented yet // bool Column::XmlReadFormula(XmlStreamReader* reader) // { // Q_ASSERT(reader->isStartElement() && reader->name() == "formula"); // // bool ok1, ok2; // int start, end; // start = reader->readAttributeInt("start_row", &ok1); // end = reader->readAttributeInt("end_row", &ok2); // if(!ok1 || !ok2) // { // reader->raiseError(i18n("invalid or missing start or end row")); // return false; // } // setFormula(Interval(start,end), reader->readElementText()); // // return true; // } /** * \brief Read XML row element */ bool Column::XmlReadRow(XmlStreamReader* reader) { Q_ASSERT(reader->isStartElement() && reader->name() == "row"); // QXmlStreamAttributes attribs = reader->attributes(); bool ok; int index = reader->readAttributeInt("index", &ok); if (!ok) { reader->raiseError(i18n("invalid or missing row index")); return false; } QString str = reader->readElementText(); switch (columnMode()) { case AbstractColumn::Numeric: { double value = str.toDouble(&ok); if(!ok) { reader->raiseError(i18n("invalid row value")); return false; } setValueAt(index, value); break; } case AbstractColumn::Integer: { int value = str.toInt(&ok); if(!ok) { reader->raiseError(i18n("invalid row value")); return false; } setIntegerAt(index, value); break; } case AbstractColumn::Text: setTextAt(index, str); break; case AbstractColumn::DateTime: case AbstractColumn::Month: case AbstractColumn::Day: QDateTime date_time = QDateTime::fromString(str,"yyyy-dd-MM hh:mm:ss:zzz"); setDateTimeAt(index, date_time); break; } return true; } //////////////////////////////////////////////////////////////////////////////// //@} //////////////////////////////////////////////////////////////////////////////// /** * \brief Return whether the object is read-only */ bool Column::isReadOnly() const { return false; } /** * \brief Return the column mode * * This function is mostly used by spreadsheets but can also be used * by plots. The column mode specifies how to interpret * the values in the column additional to the data type. */ AbstractColumn::ColumnMode Column::columnMode() const { return d->columnMode(); } /** * \brief Return the data vector size * * This returns the number of rows that actually contain data. * Rows beyond this can be masked etc. but should be ignored by filters, * plots etc. */ int Column::rowCount() const { return d->rowCount(); } /** * \brief Return the column plot designation */ AbstractColumn::PlotDesignation Column::plotDesignation() const { return d->plotDesignation(); } AbstractSimpleFilter* Column::outputFilter() const { return d->outputFilter(); } /** * \brief Return a wrapper column object used for String I/O. */ ColumnStringIO* Column::asStringColumn() const { return m_string_io; } //////////////////////////////////////////////////////////////////////////////// //! \name IntervalAttribute related functions //@{ //////////////////////////////////////////////////////////////////////////////// /** * \brief Return the formula associated with row 'row' */ QString Column::formula(int row) const { return d->formula(row); } /** * \brief Return the intervals that have associated formulas * * This can be used to make a list of formulas with their intervals. * Here is some example code: * * \code * QStringList list; * QList< Interval > intervals = my_column.formulaIntervals(); * foreach(Interval interval, intervals) * list << QString(interval.toString() + ": " + my_column.formula(interval.start())); * \endcode */ QList< Interval > Column::formulaIntervals() const { return d->formulaIntervals(); } void Column::handleFormatChange() { DEBUG("Column::handleFormatChange() mode = " << ENUM_TO_STRING(AbstractColumn, ColumnMode, columnMode())); if (columnMode() == AbstractColumn::DateTime) { auto* input_filter = static_cast(d->inputFilter()); auto* output_filter = static_cast(d->outputFilter()); DEBUG("change format " << input_filter->format().toStdString() << " to " << output_filter->format().toStdString()); input_filter->setFormat(output_filter->format()); } emit aspectDescriptionChanged(this); // the icon for the type changed if (!m_suppressDataChangedSignal) emit dataChanged(this); // all cells must be repainted setStatisticsAvailable(false); DEBUG("Column::handleFormatChange() DONE"); } /*! * calculates the minimal value in the column. * for \c count = 0, the minimum of all elements is returned. * for \c count > 0, the minimum of the first \count elements is returned. * for \c count = 0, the minimum of the last \count elements is returned. */ double Column::minimum(int count) const { double min = INFINITY; if (count == 0 && statisticsAvailable()) min = const_cast(this)->statistics().minimum; else { ColumnMode mode = columnMode(); int start, end; if (count == 0) { start = 0; end = rowCount(); } else if (count > 0) { start = 0; end = qMin(rowCount(), count); } else { start = qMax(rowCount() + count, 0); end = rowCount(); } switch (mode) { case Numeric: { QVector* vec = static_cast*>(data()); for (int row = start; row < end; ++row) { const double val = vec->at(row); if (std::isnan(val)) continue; if (val < min) min = val; } break; } case Integer: { QVector* vec = static_cast*>(data()); for (int row = start; row < end; ++row) { const int val = vec->at(row); if (val < min) min = val; } break; } case Text: case DateTime: case Day: case Month: default: break; } } return min; } /*! * calculates the maximal value in the column. * for \c count = 0, the maximum of all elements is returned. * for \c count > 0, the maximum of the first \count elements is returned. * for \c count = 0, the maximum of the last \count elements is returned. */ double Column::maximum(int count) const { double max = -INFINITY; if (count == 0 && statisticsAvailable()) max = const_cast(this)->statistics().maximum; else { ColumnMode mode = columnMode(); int start, end; if (count == 0) { start = 0; end = rowCount(); } else if (count > 0) { start = 0; end = qMin(rowCount(), count); } else { start = qMax(rowCount() + count, 0); end = rowCount(); } switch (mode) { case Numeric: { QVector* vec = static_cast*>(data()); for (int row = start; row < end; ++row) { const double val = vec->at(row); if (std::isnan(val)) continue; if (val > max) max = val; } break; } case Integer: { QVector* vec = static_cast*>(data()); for (int row = start; row < end; ++row) { const int val = vec->at(row); if (val > max) max = val; } break; } case Text: case DateTime: case Day: case Month: default: break; } } return max; } diff --git a/src/backend/core/column/Column.h b/src/backend/core/column/Column.h index 0e32a16e3..525f0caf9 100644 --- a/src/backend/core/column/Column.h +++ b/src/backend/core/column/Column.h @@ -1,147 +1,147 @@ /*************************************************************************** File : Column.h Project : LabPlot Description : Aspect that manages a column -------------------------------------------------------------------- Copyright : (C) 2007-2009 Tilman Benkert (thzs@gmx.net) Copyright : (C) 2013-2017 Alexander Semke (alexander.semke@web.de) Copyright : (C) 2017 Stefan Gerlach (stefan.gerlach@uni.kn) ***************************************************************************/ /*************************************************************************** * * * 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 COLUMN_H #define COLUMN_H #include "backend/core/AbstractSimpleFilter.h" #include "backend/lib/XmlStreamReader.h" #include "backend/core/column/ColumnPrivate.h" class ColumnStringIO; class QActionGroup; class Column : public AbstractColumn { Q_OBJECT public: explicit Column(const QString& name, AbstractColumn::ColumnMode = AbstractColumn::Numeric); // template constructor for all supported data types (AbstractColumn::ColumnMode) must be defined in header template explicit Column(const QString& name, QVector data, AbstractColumn::ColumnMode mode = AbstractColumn::Numeric) : AbstractColumn(name), d(new ColumnPrivate(this, mode, new QVector(data))) { init(); }; void init(); - ~Column(); + ~Column() override; - virtual QIcon icon() const override; - virtual QMenu* createContextMenu() override; + QIcon icon() const override; + QMenu* createContextMenu() override; AbstractColumn::ColumnMode columnMode() const override; void setColumnMode(AbstractColumn::ColumnMode) override; void setColumnModeFast(AbstractColumn::ColumnMode); bool copy(const AbstractColumn*) override; bool copy(const AbstractColumn* source, int source_start, int dest_start, int num_rows) override; AbstractColumn::PlotDesignation plotDesignation() const override; void setPlotDesignation(AbstractColumn::PlotDesignation) override; bool isReadOnly() const override; int rowCount() const override; int width() const; void setWidth(const int); void clear() override; AbstractSimpleFilter* outputFilter() const; ColumnStringIO* asStringColumn() const; void setFormula(const QString& formula, const QStringList& variableNames, const QStringList& variableColumnPathes); QString formula() const; const QStringList& formulaVariableNames() const; const QStringList& formulaVariableColumnPathes() const; QString formula(int) const override; QList< Interval > formulaIntervals() const override; void setFormula(Interval, QString) override; void setFormula(int, QString) override; void clearFormulas() override; const AbstractColumn::ColumnStatistics& statistics(); void* data() const; QString textAt(int) const override; void setTextAt(int, const QString&) override; void replaceTexts(int, const QVector&) override; QDate dateAt(int) const override; void setDateAt(int, const QDate&) override; QTime timeAt(int) const override; void setTimeAt(int, const QTime&) override; QDateTime dateTimeAt(int) const override; void setDateTimeAt(int, const QDateTime&) override; void replaceDateTimes(int, const QVector&) override; double valueAt(int) const override; void setValueAt(int, const double) override; void replaceValues(int, const QVector&) override; int integerAt(int) const override; void setIntegerAt(int, const int) override; void replaceInteger(int, const QVector&) override; - virtual double maximum(int count = 0) const override; - virtual double minimum(int count = 0) const override; + double maximum(int count = 0) const override; + double minimum(int count = 0) const override; void setChanged(); void setSuppressDataChangedSignal(const bool); void save(QXmlStreamWriter*) const override; bool load(XmlStreamReader*, bool preview) override; private: bool XmlReadInputFilter(XmlStreamReader*); bool XmlReadOutputFilter(XmlStreamReader*); bool XmlReadFormula(XmlStreamReader*); bool XmlReadRow(XmlStreamReader*); void handleRowInsertion(int before, int count) override; void handleRowRemoval(int first, int count) override; void calculateStatistics(); void setStatisticsAvailable(bool); bool statisticsAvailable() const; bool m_suppressDataChangedSignal; QActionGroup* m_usedInActionGroup; ColumnPrivate* d; ColumnStringIO* m_string_io; signals: void requestProjectContextMenu(QMenu*); private slots: void navigateTo(QAction*); void handleFormatChange(); friend class ColumnPrivate; friend class ColumnStringIO; }; #endif diff --git a/src/backend/core/column/ColumnPrivate.h b/src/backend/core/column/ColumnPrivate.h index e55cb6fb8..85c5a712c 100644 --- a/src/backend/core/column/ColumnPrivate.h +++ b/src/backend/core/column/ColumnPrivate.h @@ -1,125 +1,125 @@ /*************************************************************************** File : ColumnPrivate.h Project : LabPlot Description : Private data class of Column -------------------------------------------------------------------- Copyright : (C) 2007,2008 Tilman Benkert (thzs@gmx.net) Copyright : (C) 2013-2017 Alexander Semke (alexander.semke@web.de) ***************************************************************************/ /*************************************************************************** * * * 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 COLUMNPRIVATE_H #define COLUMNPRIVATE_H #include "backend/core/AbstractColumn.h" #include "backend/lib/IntervalAttribute.h" class Column; class ColumnPrivate : QObject { Q_OBJECT public: ColumnPrivate(Column*, AbstractColumn::ColumnMode); - ~ColumnPrivate(); + ~ColumnPrivate() override; ColumnPrivate(Column*, AbstractColumn::ColumnMode, void*); AbstractColumn::ColumnMode columnMode() const; void setColumnMode(AbstractColumn::ColumnMode); bool copy(const AbstractColumn*); bool copy(const AbstractColumn*, int source_start, int dest_start, int num_rows); bool copy(const ColumnPrivate*); bool copy(const ColumnPrivate*, int source_start, int dest_start, int num_rows); int rowCount() const; void resizeTo(int); void insertRows(int before, int count); void removeRows(int first, int count); QString name() const; AbstractColumn::PlotDesignation plotDesignation() const; void setPlotDesignation(AbstractColumn::PlotDesignation); int width() const; void setWidth(int); void* data() const; AbstractSimpleFilter* inputFilter() const; AbstractSimpleFilter* outputFilter() const; void replaceModeData(AbstractColumn::ColumnMode, void* data, AbstractSimpleFilter *in, AbstractSimpleFilter *out); void replaceData(void*); IntervalAttribute formulaAttribute() const; void replaceFormulas(IntervalAttribute formulas); QString formula() const; const QStringList& formulaVariableNames() const; const QStringList& formulaVariableColumnPathes() const; void setFormula(const QString& formula, const QStringList& variableNames, const QStringList& variableColumnPathes); QString formula(int row) const; QList< Interval > formulaIntervals() const; void setFormula(Interval i, QString formula); void setFormula(int row, QString formula); void clearFormulas(); QString textAt(int row) const; void setTextAt(int row, const QString&); void replaceTexts(int first, const QVector&); QDate dateAt(int row) const; void setDateAt(int row, const QDate&); QTime timeAt(int row) const; void setTimeAt(int row, const QTime&); QDateTime dateTimeAt(int row) const; void setDateTimeAt(int row, const QDateTime&); void replaceDateTimes(int first, const QVector&); double valueAt(int row) const; void setValueAt(int row, double new_value); void replaceValues(int first, const QVector&); int integerAt(int row) const; void setIntegerAt(int row, int new_value); void replaceInteger(int first, const QVector&); AbstractColumn::ColumnStatistics statistics; bool statisticsAvailable; private: AbstractColumn::ColumnMode m_column_mode; // type of column data void* m_data; //pointer to the data container (QVector) AbstractSimpleFilter* m_input_filter; //input filter for string -> data type conversion AbstractSimpleFilter* m_output_filter; //output filter for data type -> string conversion QString m_formula; QStringList m_formulaVariableNames; QStringList m_formulaVariableColumnPathes; IntervalAttribute m_formulas; AbstractColumn::PlotDesignation m_plot_designation; int m_width; //column width in the view Column* m_owner; }; #endif diff --git a/src/backend/core/column/ColumnStringIO.h b/src/backend/core/column/ColumnStringIO.h index 367577b59..0b2b0004b 100644 --- a/src/backend/core/column/ColumnStringIO.h +++ b/src/backend/core/column/ColumnStringIO.h @@ -1,57 +1,57 @@ /*************************************************************************** File : ColumnStringIO.h Project : LabPlot Description : Aspect that manages a column string IO -------------------------------------------------------------------- Copyright : (C) 2007-2009 Tilman Benkert (thzs@gmx.net) Copyright : (C) 2013-2017 by Alexander Semke (alexander.semke@web.de) ***************************************************************************/ /*************************************************************************** * * * 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 COLUMNSTRINGIO_H #define COLUMNSTRINGIO_H #include "backend/core/column/Column.h" class ColumnStringIO : public AbstractColumn { Q_OBJECT public: ColumnStringIO(Column* owner); - virtual AbstractColumn::ColumnMode columnMode() const override; - virtual AbstractColumn::PlotDesignation plotDesignation() const override; - virtual int rowCount() const override; - virtual QString textAt(int) const override; - virtual void setTextAt(int, const QString&) override; + AbstractColumn::ColumnMode columnMode() const override; + AbstractColumn::PlotDesignation plotDesignation() const override; + int rowCount() const override; + QString textAt(int) const override; + void setTextAt(int, const QString&) override; virtual bool isValid(int) const; - virtual bool copy(const AbstractColumn*) override; - virtual bool copy(const AbstractColumn* source, int source_start, int dest_start, int num_rows) override; - virtual void replaceTexts(int start_row, const QVector& texts) override; - virtual void save(QXmlStreamWriter*) const override {}; - virtual bool load(XmlStreamReader*, bool preview) override {Q_UNUSED(preview); return true;}; + bool copy(const AbstractColumn*) override; + bool copy(const AbstractColumn* source, int source_start, int dest_start, int num_rows) override; + void replaceTexts(int start_row, const QVector& texts) override; + void save(QXmlStreamWriter*) const override {}; + bool load(XmlStreamReader*, bool preview) override {Q_UNUSED(preview); return true;}; private: Column* m_owner; bool m_setting; QString m_to_set; }; #endif diff --git a/src/backend/core/column/columncommands.h b/src/backend/core/column/columncommands.h index c1f38f611..53105d23a 100644 --- a/src/backend/core/column/columncommands.h +++ b/src/backend/core/column/columncommands.h @@ -1,331 +1,331 @@ /*************************************************************************** File : columncommands.h Project : LabPlot Description : Commands to be called by Column to modify ColumnPrivate -------------------------------------------------------------------- Copyright : (C) 2007,2008 Tilman Benkert (thzs@gmx.net) Copyright : (C) 2010 by Knut Franke (knut.franke@gmx.de) Copyright : (C) 2009-2017 Alexander Semke (alexander.semke@web.de) ***************************************************************************/ /*************************************************************************** * * * 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 COLUMNCOMMANDS_H #define COLUMNCOMMANDS_H #include "backend/lib/IntervalAttribute.h" #include "backend/core/column/Column.h" #include #include #include class AbstractSimpleFilter; class ColumnSetModeCmd : public QUndoCommand { public: explicit ColumnSetModeCmd(ColumnPrivate* col, AbstractColumn::ColumnMode mode, QUndoCommand* parent = 0); - ~ColumnSetModeCmd(); + ~ColumnSetModeCmd() override; - virtual void redo(); - virtual void undo(); + void redo() override; + void undo() override; private: ColumnPrivate* m_col; AbstractColumn::ColumnMode m_old_mode; AbstractColumn::ColumnMode m_mode; void* m_old_data; void* m_new_data; AbstractSimpleFilter* m_new_in_filter; AbstractSimpleFilter* m_new_out_filter; AbstractSimpleFilter* m_old_in_filter; AbstractSimpleFilter* m_old_out_filter; bool m_undone; bool m_executed; }; class ColumnFullCopyCmd : public QUndoCommand { public: explicit ColumnFullCopyCmd(ColumnPrivate* col, const AbstractColumn* src, QUndoCommand* parent = 0); - ~ColumnFullCopyCmd(); + ~ColumnFullCopyCmd() override; - virtual void redo(); - virtual void undo(); + void redo() override; + void undo() override; private: ColumnPrivate* m_col; const AbstractColumn* m_src; ColumnPrivate* m_backup; Column* m_backup_owner; }; class ColumnPartialCopyCmd : public QUndoCommand { public: explicit ColumnPartialCopyCmd(ColumnPrivate* col, const AbstractColumn* src, int src_start, int dest_start, int num_rows, QUndoCommand* parent = 0); - ~ColumnPartialCopyCmd(); + ~ColumnPartialCopyCmd() override; - virtual void redo(); - virtual void undo(); + void redo() override; + void undo() override; private: ColumnPrivate* m_col; const AbstractColumn * m_src; ColumnPrivate* m_col_backup; ColumnPrivate* m_src_backup; Column* m_col_backup_owner; Column* m_src_backup_owner; int m_src_start; int m_dest_start; int m_num_rows; int m_old_row_count; }; class ColumnInsertRowsCmd : public QUndoCommand { public: explicit ColumnInsertRowsCmd(ColumnPrivate* col, int before, int count, QUndoCommand* parent = 0); - virtual void redo(); - virtual void undo(); + void redo() override; + void undo() override; private: ColumnPrivate* m_col; int m_before, m_count; }; class ColumnRemoveRowsCmd : public QUndoCommand { public: explicit ColumnRemoveRowsCmd(ColumnPrivate* col, int first, int count, QUndoCommand* parent = 0); - ~ColumnRemoveRowsCmd(); + ~ColumnRemoveRowsCmd() override; - virtual void redo(); - virtual void undo(); + void redo() override; + void undo() override; private: ColumnPrivate* m_col; int m_first, m_count; int m_data_row_count; int m_old_size; ColumnPrivate* m_backup; Column* m_backup_owner; IntervalAttribute m_formulas; }; class ColumnSetPlotDesignationCmd : public QUndoCommand { public: explicit ColumnSetPlotDesignationCmd(ColumnPrivate* col, AbstractColumn::PlotDesignation pd, QUndoCommand* parent = 0); - virtual void redo(); - virtual void undo(); + void redo() override; + void undo() override; private: ColumnPrivate* m_col; AbstractColumn::PlotDesignation m_new_pd; AbstractColumn::PlotDesignation m_old_pd; }; class ColumnClearCmd : public QUndoCommand { public: explicit ColumnClearCmd(ColumnPrivate* col, QUndoCommand* parent = 0); - ~ColumnClearCmd(); + ~ColumnClearCmd() override; - virtual void redo(); - virtual void undo(); + void redo() override; + void undo() override; private: ColumnPrivate* m_col; void* m_data; void* m_empty_data; bool m_undone; }; class ColumnSetGlobalFormulaCmd : public QUndoCommand { public: explicit ColumnSetGlobalFormulaCmd(ColumnPrivate* col, const QString& formula, const QStringList& variableNames, const QStringList& variableColumnPathes); - virtual void redo(); - virtual void undo(); + void redo() override; + void undo() override; private: ColumnPrivate* m_col; QString m_formula; QStringList m_variableNames; QStringList m_variableColumnPathes; QString m_newFormula; QStringList m_newVariableNames; QStringList m_newVariableColumnPathes; bool m_copied; }; class ColumnSetFormulaCmd : public QUndoCommand { public: explicit ColumnSetFormulaCmd(ColumnPrivate* col, Interval interval, const QString& formula, QUndoCommand* parent = 0); - virtual void redo(); - virtual void undo(); + void redo() override; + void undo() override; private: ColumnPrivate* m_col; Interval m_interval; QString m_oldFormula; QString m_newFormula; IntervalAttribute m_formulas; bool m_copied; }; class ColumnClearFormulasCmd : public QUndoCommand { public: explicit ColumnClearFormulasCmd(ColumnPrivate* col, QUndoCommand* parent = 0); - virtual void redo(); - virtual void undo(); + void redo() override; + void undo() override; private: ColumnPrivate* m_col; IntervalAttribute m_formulas; bool m_copied; }; class ColumnSetTextCmd : public QUndoCommand { public: explicit ColumnSetTextCmd(ColumnPrivate* col, int row, const QString& new_value, QUndoCommand* parent = 0); - virtual void redo(); - virtual void undo(); + void redo() override; + void undo() override; private: ColumnPrivate* m_col; int m_row; QString m_new_value; QString m_old_value; int m_row_count; }; class ColumnSetValueCmd : public QUndoCommand { public: explicit ColumnSetValueCmd(ColumnPrivate* col, int row, double new_value, QUndoCommand* parent = 0); - virtual void redo(); - virtual void undo(); + void redo() override; + void undo() override; private: ColumnPrivate* m_col; int m_row; double m_new_value; double m_old_value; int m_row_count; }; class ColumnSetIntegerCmd : public QUndoCommand { public: explicit ColumnSetIntegerCmd(ColumnPrivate* col, int row, int new_value, QUndoCommand* parent = 0); - virtual void redo(); - virtual void undo(); + void redo() override; + void undo() override; private: ColumnPrivate* m_col; int m_row; int m_new_value; int m_old_value; int m_row_count; }; class ColumnSetDateTimeCmd : public QUndoCommand { public: explicit ColumnSetDateTimeCmd(ColumnPrivate* col, int row, const QDateTime& new_value, QUndoCommand* parent = 0); - virtual void redo(); - virtual void undo(); + void redo() override; + void undo() override; private: ColumnPrivate* m_col; int m_row; QDateTime m_new_value; QDateTime m_old_value; int m_row_count; }; class ColumnReplaceTextsCmd : public QUndoCommand { public: explicit ColumnReplaceTextsCmd(ColumnPrivate* col, int first, const QVector& new_values, QUndoCommand* parent = 0); - virtual void redo(); - virtual void undo(); + void redo() override; + void undo() override; private: ColumnPrivate* m_col; int m_first; QVector m_new_values; QVector m_old_values; bool m_copied; int m_row_count; }; class ColumnReplaceValuesCmd : public QUndoCommand { public: explicit ColumnReplaceValuesCmd(ColumnPrivate* col, int first, const QVector& new_values, QUndoCommand* parent = 0); - virtual void redo(); - virtual void undo(); + void redo() override; + void undo() override; private: ColumnPrivate* m_col; int m_first; QVector m_new_values; QVector m_old_values; bool m_copied; int m_row_count; }; class ColumnReplaceIntegersCmd : public QUndoCommand { public: explicit ColumnReplaceIntegersCmd(ColumnPrivate* col, int first, const QVector& new_values, QUndoCommand* parent = 0); - virtual void redo(); - virtual void undo(); + void redo() override; + void undo() override; private: ColumnPrivate* m_col; int m_first; QVector m_new_values; QVector m_old_values; bool m_copied; int m_row_count; }; class ColumnReplaceDateTimesCmd : public QUndoCommand { public: explicit ColumnReplaceDateTimesCmd(ColumnPrivate* col, int first, const QVector& new_values, QUndoCommand* parent = 0); - virtual void redo(); - virtual void undo(); + void redo() override; + void undo() override; private: ColumnPrivate* m_col; int m_first; QVector m_new_values; QVector m_old_values; bool m_copied; int m_row_count; }; #endif diff --git a/src/backend/core/datatypes/DateTime2DoubleFilter.h b/src/backend/core/datatypes/DateTime2DoubleFilter.h index 0174a82c8..8e0122716 100644 --- a/src/backend/core/datatypes/DateTime2DoubleFilter.h +++ b/src/backend/core/datatypes/DateTime2DoubleFilter.h @@ -1,61 +1,61 @@ /*************************************************************************** File : DateTime2DoubleFilter.h Project : LabPlot -------------------------------------------------------------------- Copyright : (C) 2007 by Tilman Benkert (thzs@gmx.net) Copyright : (C) 2007 by Knut Franke (knut.franke@gmx.de) Description : Conversion filter QDateTime -> double (using Julian day). ***************************************************************************/ /*************************************************************************** * * * 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 DATE_TIME2DOUBLE_FILTER_H #define DATE_TIME2DOUBLE_FILTER_H #include "../AbstractSimpleFilter.h" #include #include //! Conversion filter QDateTime -> double (using Julian day). class DateTime2DoubleFilter : public AbstractSimpleFilter { Q_OBJECT public: - virtual double valueAt(int row) const { + double valueAt(int row) const override { if (!m_inputs.value(0)) return NAN; QDateTime inputDate = m_inputs.value(0)->dateTimeAt(row); if (!inputDate.isValid()) return NAN; QDateTime start(QDate(1900, 1, 1)); return double(start.daysTo(inputDate)) + double( -inputDate.time().msecsTo(QTime(0,0,0,0)) ) / 86400000.0; } //! Return the data type of the column - virtual AbstractColumn::ColumnMode columnMode() const { return AbstractColumn::Numeric; } + AbstractColumn::ColumnMode columnMode() const override { return AbstractColumn::Numeric; } protected: //! Using typed ports: only DateTime inputs are accepted. - virtual bool inputAcceptable(int, const AbstractColumn* source) { + bool inputAcceptable(int, const AbstractColumn* source) override { return source->columnMode() == AbstractColumn::DateTime; } }; #endif // ifndef DATE_TIME2DOUBLE_FILTER_H diff --git a/src/backend/core/datatypes/DateTime2IntegerFilter.h b/src/backend/core/datatypes/DateTime2IntegerFilter.h index 2ddc448d6..b4621b29a 100644 --- a/src/backend/core/datatypes/DateTime2IntegerFilter.h +++ b/src/backend/core/datatypes/DateTime2IntegerFilter.h @@ -1,59 +1,59 @@ /*************************************************************************** File : DateTime2IntegerFilter.h Project : AbstractColumn -------------------------------------------------------------------- Copyright : (C) 2017 Stefan Gerlach (stefan.gerlach@uni.kn) Description : Conversion filter QDateTime -> int (using Julian day). ***************************************************************************/ /*************************************************************************** * * * 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 DATE_TIME2INTEGER_FILTER_H #define DATE_TIME2INTEGER_FILTER_H #include "../AbstractSimpleFilter.h" #include //! Conversion filter QDateTime -> int (using Julian day). class DateTime2IntegerFilter : public AbstractSimpleFilter { Q_OBJECT public: - virtual int integerAt(int row) const { + int integerAt(int row) const override { //DEBUG("integerAt()"); if (!m_inputs.value(0)) return 0; QDateTime inputDate = m_inputs.value(0)->dateTimeAt(row); if (!inputDate.isValid()) return 0; QDateTime start(QDate(1900, 1, 1)); return int(start.daysTo(inputDate)); } //! Return the data type of the column - virtual AbstractColumn::ColumnMode columnMode() const { return AbstractColumn::Integer; } + AbstractColumn::ColumnMode columnMode() const override { return AbstractColumn::Integer; } protected: //! Using typed ports: only DateTime inputs are accepted. - virtual bool inputAcceptable(int, const AbstractColumn *source) { + bool inputAcceptable(int, const AbstractColumn *source) override { return source->columnMode() == AbstractColumn::DateTime; } }; #endif // ifndef DATE_TIME2INTEGER_FILTER_H diff --git a/src/backend/core/datatypes/DateTime2StringFilter.cpp b/src/backend/core/datatypes/DateTime2StringFilter.cpp index ea9e6d361..add6f5e83 100644 --- a/src/backend/core/datatypes/DateTime2StringFilter.cpp +++ b/src/backend/core/datatypes/DateTime2StringFilter.cpp @@ -1,108 +1,108 @@ /*************************************************************************** File : DateTime2StringFilter.cpp Project : LabPlot -------------------------------------------------------------------- Copyright : (C) 2007 by Tilman Benkert (thzs@gmx.net) Copyright : (C) 2007 by Knut Franke (knut.franke@gmx.de) Description : Conversion filter QDateTime -> QString. ***************************************************************************/ /*************************************************************************** * * * 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 "DateTime2StringFilter.h" #include "backend/lib/XmlStreamReader.h" #include #include #include #include class DateTime2StringFilterSetFormatCmd : public QUndoCommand { public: DateTime2StringFilterSetFormatCmd(DateTime2StringFilter* target, const QString &new_format); - virtual void redo(); - virtual void undo(); + void redo() override; + void undo() override; private: DateTime2StringFilter* m_target; QString m_other_format; }; void DateTime2StringFilter::setFormat(const QString& format) { exec(new DateTime2StringFilterSetFormatCmd(static_cast(this), format)); } QString DateTime2StringFilter::textAt(int row) const { //DEBUG("DateTime2StringFilter::textAt()"); if (!m_inputs.value(0)) return QString(); QDateTime inputValue = m_inputs.value(0)->dateTimeAt(row); if (!inputValue.isValid()) return QString(); //QDEBUG(" : " << inputValue << " -> " << m_format << " -> " << inputValue.toString(m_format)); return inputValue.toString(m_format); } bool DateTime2StringFilter::inputAcceptable(int, const AbstractColumn *source) { return (source->columnMode() == AbstractColumn::DateTime) || (source->columnMode() == AbstractColumn::Day) || (source->columnMode() == AbstractColumn::Month); } DateTime2StringFilterSetFormatCmd::DateTime2StringFilterSetFormatCmd(DateTime2StringFilter* target, const QString &new_format) : m_target(target), m_other_format(new_format) { if(m_target->parentAspect()) setText(i18n("%1: set date-time format to %2", m_target->parentAspect()->name(), new_format)); else setText(i18n("set date-time format to %1", new_format)); } void DateTime2StringFilterSetFormatCmd::redo() { QString tmp = m_target->m_format; m_target->m_format = m_other_format; m_other_format = tmp; emit m_target->formatChanged(); } void DateTime2StringFilterSetFormatCmd::undo() { redo(); } void DateTime2StringFilter::writeExtraAttributes(QXmlStreamWriter * writer) const { writer->writeAttribute("format", format()); } bool DateTime2StringFilter::load(XmlStreamReader* reader, bool preview) { if (preview) return true; QXmlStreamAttributes attribs = reader->attributes(); QString str = attribs.value(reader->namespaceUri().toString(), "format").toString(); if (AbstractSimpleFilter::load(reader, preview)) setFormat(str); else return false; return !reader->hasError(); } diff --git a/src/backend/core/datatypes/DateTime2StringFilter.h b/src/backend/core/datatypes/DateTime2StringFilter.h index 6ba223ade..0530ce0fd 100644 --- a/src/backend/core/datatypes/DateTime2StringFilter.h +++ b/src/backend/core/datatypes/DateTime2StringFilter.h @@ -1,79 +1,79 @@ /*************************************************************************** File : DateTime2StringFilter.h Project : LabPlot -------------------------------------------------------------------- Copyright : (C) 2007 by Tilman Benkert (thzs@gmx.net) Copyright : (C) 2007 by Knut Franke (knut.franke@gmx.de) Description : Conversion filter QDateTime -> QString. ***************************************************************************/ /*************************************************************************** * * * 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 DATE_TIME2STRING_FILTER_H #define DATE_TIME2STRING_FILTER_H #include "backend/core/AbstractSimpleFilter.h" class DateTime2StringFilterSetFormatCmd; //! Conversion filter QDateTime -> QString. class DateTime2StringFilter : public AbstractSimpleFilter { Q_OBJECT public: //! Standard constructor. explicit DateTime2StringFilter(QString format="yyyy-MM-dd hh:mm:ss.zzz") : m_format(format) {} //! Set the format string to be used for conversion. void setFormat(const QString& format); //! Return the format string /** * The default format string is "yyyy-MM-dd hh:mm:ss.zzz". * \sa QDate::toString() */ QString format() const { return m_format; } //! Return the data type of the column - virtual AbstractColumn::ColumnMode columnMode() const override { return AbstractColumn::Text; } + AbstractColumn::ColumnMode columnMode() const override { return AbstractColumn::Text; } signals: void formatChanged(); private: friend class DateTime2StringFilterSetFormatCmd; //! The format string. QString m_format; public: - virtual QString textAt(int row) const override; + QString textAt(int row) const override; //! \name XML related functions //@{ - virtual void writeExtraAttributes(QXmlStreamWriter*) const override; - virtual bool load(XmlStreamReader*, bool preview) override; + void writeExtraAttributes(QXmlStreamWriter*) const override; + bool load(XmlStreamReader*, bool preview) override; //@} protected: //! Using typed ports: only DateTime inputs are accepted. - virtual bool inputAcceptable(int, const AbstractColumn *source) override; + bool inputAcceptable(int, const AbstractColumn *source) override; }; #endif // ifndef DATE_TIME2STRING_FILTER_H diff --git a/src/backend/core/datatypes/DayOfWeek2DoubleFilter.h b/src/backend/core/datatypes/DayOfWeek2DoubleFilter.h index a646ba763..aec4134f0 100644 --- a/src/backend/core/datatypes/DayOfWeek2DoubleFilter.h +++ b/src/backend/core/datatypes/DayOfWeek2DoubleFilter.h @@ -1,60 +1,60 @@ /*************************************************************************** File : DayOfWeek2DoubleFilter.h Project : AbstractColumn -------------------------------------------------------------------- Copyright : (C) 2007 by Knut Franke, Tilman Benkert Email (use @ for *) : knut.franke*gmx.de, thzs@gmx.net Description : Conversion filter QDateTime -> double, translating dates into days of the week (Monday -> 1). ***************************************************************************/ /*************************************************************************** * * * 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 DAY_OF_WEEK2DOUBLE_FILTER_H #define DAY_OF_WEEK2DOUBLE_FILTER_H #include "../AbstractSimpleFilter.h" #include #include //! Conversion filter QDateTime -> double, translating dates into days of the week (Monday -> 1). class DayOfWeek2DoubleFilter : public AbstractSimpleFilter { Q_OBJECT public: - virtual double valueAt(int row) const { + double valueAt(int row) const override { if (!m_inputs.value(0)) return NAN; QDate date = m_inputs.value(0)->dateAt(row); if (!date.isValid()) return NAN; return double(date.dayOfWeek()); } //! Return the data type of the column - virtual AbstractColumn::ColumnMode columnMode() const { return AbstractColumn::Numeric; } + AbstractColumn::ColumnMode columnMode() const override { return AbstractColumn::Numeric; } protected: //! Using typed ports: only date-time inputs are accepted. - virtual bool inputAcceptable(int, const AbstractColumn *source) { + bool inputAcceptable(int, const AbstractColumn *source) override { return source->columnMode() == AbstractColumn::Day; } }; #endif // ifndef DAY_OF_WEEK2DOUBLE_FILTER_H diff --git a/src/backend/core/datatypes/DayOfWeek2IntegerFilter.h b/src/backend/core/datatypes/DayOfWeek2IntegerFilter.h index ddc5b5069..4615696b0 100644 --- a/src/backend/core/datatypes/DayOfWeek2IntegerFilter.h +++ b/src/backend/core/datatypes/DayOfWeek2IntegerFilter.h @@ -1,59 +1,59 @@ /*************************************************************************** File : DayOfWeek2IntegerFilter.h Project : AbstractColumn -------------------------------------------------------------------- Copyright : (C) 2017 Stefan Gerlach (stefan.gerlach@uni.kn) Description : Conversion filter QDateTime -> int, translating dates into days of the week (Monday -> 1). ***************************************************************************/ /*************************************************************************** * * * 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 DAY_OF_WEEK2INTEGER_FILTER_H #define DAY_OF_WEEK2INTEGER_FILTER_H #include "../AbstractSimpleFilter.h" #include //! Conversion filter QDateTime -> int, translating dates into days of the week (Monday -> 1). class DayOfWeek2IntegerFilter : public AbstractSimpleFilter { Q_OBJECT public: - virtual int integerAt(int row) const { + int integerAt(int row) const override { DEBUG("integerAt()"); if (!m_inputs.value(0)) return 0; QDate date = m_inputs.value(0)->dateAt(row); if (!date.isValid()) return 0; return int(date.dayOfWeek()); } //! Return the data type of the column - virtual AbstractColumn::ColumnMode columnMode() const { return AbstractColumn::Integer; } + AbstractColumn::ColumnMode columnMode() const override { return AbstractColumn::Integer; } protected: //! Using typed ports: only date-time inputs are accepted. - virtual bool inputAcceptable(int, const AbstractColumn *source) { + bool inputAcceptable(int, const AbstractColumn *source) override { return source->columnMode() == AbstractColumn::Day; } }; #endif // ifndef DAY_OF_WEEK2INTEGER_FILTER_H diff --git a/src/backend/core/datatypes/Double2DateTimeFilter.h b/src/backend/core/datatypes/Double2DateTimeFilter.h index 27c40fe9c..8d317731c 100644 --- a/src/backend/core/datatypes/Double2DateTimeFilter.h +++ b/src/backend/core/datatypes/Double2DateTimeFilter.h @@ -1,72 +1,72 @@ /*************************************************************************** File : Double2DateTimeFilter.h Project : AbstractColumn -------------------------------------------------------------------- Copyright : (C) 2007 by Knut Franke, Tilman Benkert Email (use @ for *) : knut.franke*gmx.de, thzs@gmx.net Description : Conversion filter double -> QDateTime, interpreting the input numbers as (fractional) Julian days. ***************************************************************************/ /*************************************************************************** * * * 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 DOUBLE2DATE_TIME_FILTER_H #define DOUBLE2DATE_TIME_FILTER_H #include "../AbstractSimpleFilter.h" #include #include //! Conversion filter double -> QDateTime, interpreting the input numbers as (fractional) Julian days. class Double2DateTimeFilter : public AbstractSimpleFilter { Q_OBJECT public: - virtual QDate dateAt(int row) const { + QDate dateAt(int row) const override { if (!m_inputs.value(0)) return QDate(); double inputValue = m_inputs.value(0)->valueAt(row); if (std::isnan(inputValue)) return QDate(); //QDEBUG(" convert " << inputValue << " to " << QDate(1900, 1, int(inputValue))); return QDate(1900, 1, 1 + int(inputValue)); } - virtual QTime timeAt(int row) const { + QTime timeAt(int row) const override { if (!m_inputs.value(0)) return QTime(); double inputValue = m_inputs.value(0)->valueAt(row); if (std::isnan(inputValue)) return QTime(); // we only want the digits behind the dot and convert them from fraction of day to milliseconds //QDEBUG(" convert " << inputValue << " to " << QTime(0,0,0,0).addMSecs(int( (inputValue - int(inputValue)) * 86400000.0 ))); return QTime(0,0,0,0).addMSecs(int( (inputValue - int(inputValue)) * 86400000.0 )); } - virtual QDateTime dateTimeAt(int row) const { + QDateTime dateTimeAt(int row) const override { return QDateTime(dateAt(row), timeAt(row)); } //! Return the data type of the column - virtual AbstractColumn::ColumnMode columnMode() const { return AbstractColumn::DateTime; } + AbstractColumn::ColumnMode columnMode() const override { return AbstractColumn::DateTime; } protected: //! Using typed ports: only double inputs are accepted. - virtual bool inputAcceptable(int, const AbstractColumn *source) { + bool inputAcceptable(int, const AbstractColumn *source) override { return source->columnMode() == AbstractColumn::Numeric; } }; #endif // ifndef DOUBLE2DATE_TIME_FILTER_H diff --git a/src/backend/core/datatypes/Double2DayOfWeekFilter.h b/src/backend/core/datatypes/Double2DayOfWeekFilter.h index 8fac8ce00..f236e2858 100644 --- a/src/backend/core/datatypes/Double2DayOfWeekFilter.h +++ b/src/backend/core/datatypes/Double2DayOfWeekFilter.h @@ -1,68 +1,68 @@ /*************************************************************************** File : Double2DayOfWeekFilter.h Project : AbstractColumn -------------------------------------------------------------------- Copyright : (C) 2007 by Knut Franke, Tilman Benkert Email (use @ for *) : knut.franke*gmx.de, thzs@gmx.net Description : Conversion filter double -> QDateTime, interpreting the input numbers as days of the week (1 -> Monday). ***************************************************************************/ /*************************************************************************** * * * 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 DOUBLE2DAY_OF_WEEK_FILTER_H #define DOUBLE2DAY_OF_WEEK_FILTER_H #include "../AbstractSimpleFilter.h" #include #include //! Conversion filter double -> QDateTime, interpreting the input numbers as days of the week (1 = Monday). class Double2DayOfWeekFilter : public AbstractSimpleFilter { Q_OBJECT public: - virtual QDate dateAt(int row) const { + QDate dateAt(int row) const override { if (!m_inputs.value(0)) return QDate(); double inputValue = m_inputs.value(0)->valueAt(row); if (std::isnan(inputValue)) return QDate(); // Don't use Julian days here since support for years < 1 is bad // Use 1900-01-01 instead (a Monday) return QDate(1900,1,1).addDays(qRound(inputValue - 1.0)); } - virtual QTime timeAt(int row) const { + QTime timeAt(int row) const override { Q_UNUSED(row) return QTime(0,0,0,0); } - virtual QDateTime dateTimeAt(int row) const { + QDateTime dateTimeAt(int row) const override { return QDateTime(dateAt(row), timeAt(row)); } //! Return the data type of the column - virtual AbstractColumn::ColumnMode columnMode() const { return AbstractColumn::Day; } + AbstractColumn::ColumnMode columnMode() const override { return AbstractColumn::Day; } protected: //! Using typed ports: only double inputs are accepted. - virtual bool inputAcceptable(int, const AbstractColumn *source) { + bool inputAcceptable(int, const AbstractColumn *source) override { return source->columnMode() == AbstractColumn::Numeric; } }; #endif // ifndef DOUBLE2DAY_OF_WEEK_FILTER_H diff --git a/src/backend/core/datatypes/Double2IntegerFilter.h b/src/backend/core/datatypes/Double2IntegerFilter.h index 460b25ff3..5acb738b2 100644 --- a/src/backend/core/datatypes/Double2IntegerFilter.h +++ b/src/backend/core/datatypes/Double2IntegerFilter.h @@ -1,65 +1,65 @@ /*************************************************************************** File : Double2IntegerFilter.h Project : AbstractColumn -------------------------------------------------------------------- Copyright : (C) 2017 Stefan Gerlach (stefan.gerlach@uni.kn) Description : conversion filter double -> int. ***************************************************************************/ /*************************************************************************** * * * 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 DOUBLE2INTEGER_FILTER_H #define DOUBLE2INTEGER_FILTER_H #include "../AbstractSimpleFilter.h" #include #include //! conversion filter double -> int. class Double2IntegerFilter : public AbstractSimpleFilter { Q_OBJECT public: Double2IntegerFilter() {} - virtual int integerAt(int row) const { + int integerAt(int row) const override { if (!m_inputs.value(0)) return 0; double value = m_inputs.value(0)->valueAt(row); int result = 0; if (!std::isnan(value)) result = (int)round(value); //DEBUG("Double2Integer::integerAt() " << value << " -> " << result); return result; } //! Return the data type of the column - virtual AbstractColumn::ColumnMode columnMode() const { return AbstractColumn::Integer; } + AbstractColumn::ColumnMode columnMode() const override { return AbstractColumn::Integer; } protected: //! Using typed ports: only double inputs are accepted. - virtual bool inputAcceptable(int, const AbstractColumn *source) { + bool inputAcceptable(int, const AbstractColumn *source) override { return source->columnMode() == AbstractColumn::Numeric; } }; #endif // ifndef DOUBLE2INTEGER_FILTER_H diff --git a/src/backend/core/datatypes/Double2MonthFilter.h b/src/backend/core/datatypes/Double2MonthFilter.h index ca2c3f3e5..dc7ed15b3 100644 --- a/src/backend/core/datatypes/Double2MonthFilter.h +++ b/src/backend/core/datatypes/Double2MonthFilter.h @@ -1,71 +1,71 @@ /*************************************************************************** File : Double2MonthFilter.h Project : AbstractColumn -------------------------------------------------------------------- Copyright : (C) 2007 by Knut Franke, Tilman Benkert Email (use @ for *) : knut.franke*gmx.de, thzs@gmx.net Description : Conversion filter double -> QDateTime, interpreting the input numbers as months of the year. ***************************************************************************/ /*************************************************************************** * * * 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 DOUBLE2MONTH_FILTER_H #define DOUBLE2MONTH_FILTER_H #include "../AbstractSimpleFilter.h" #include #include //! Conversion filter double -> QDateTime, interpreting the input numbers as months of the year. class Double2MonthFilter : public AbstractSimpleFilter { Q_OBJECT public: - virtual QDate dateAt(int row) const { + QDate dateAt(int row) const override { return dateTimeAt(row).date(); } - virtual QTime timeAt(int row) const { + QTime timeAt(int row) const override { return dateTimeAt(row).time(); } - virtual QDateTime dateTimeAt(int row) const { + QDateTime dateTimeAt(int row) const override { DEBUG("Double2MonthFilter::dateTimeAt() row = " << row); if (!m_inputs.value(0)) return QDateTime(); double inputValue = m_inputs.value(0)->valueAt(row); if (std::isnan(inputValue)) return QDateTime(); // Don't use Julian days here since support for years < 1 is bad // Use 1900-01-01 instead QDate result_date = QDate(1900,1,1).addMonths(qRound(inputValue - 1.0)); QTime result_time = QTime(0,0,0,0); QDEBUG("value = " << inputValue << " result = " << QDateTime(result_date, result_time)); return QDateTime(result_date, result_time); } //! Return the data type of the column - virtual AbstractColumn::ColumnMode columnMode() const { return AbstractColumn::Month; } + AbstractColumn::ColumnMode columnMode() const override { return AbstractColumn::Month; } protected: - virtual bool inputAcceptable(int, const AbstractColumn *source) { + bool inputAcceptable(int, const AbstractColumn *source) override { return source->columnMode() == AbstractColumn::Numeric; } }; #endif // ifndef DOUBLE2MONTH_FILTER_H diff --git a/src/backend/core/datatypes/Double2StringFilter.cpp b/src/backend/core/datatypes/Double2StringFilter.cpp index 162204e78..76d9ad2ae 100644 --- a/src/backend/core/datatypes/Double2StringFilter.cpp +++ b/src/backend/core/datatypes/Double2StringFilter.cpp @@ -1,134 +1,134 @@ /*************************************************************************** File : Double2StringFilter.cpp Project : AbstractColumn -------------------------------------------------------------------- Copyright : (C) 2007 by Knut Franke, Tilman Benkert Email (use @ for *) : knut.franke*gmx.de, thzs@gmx.net Description : Locale-aware conversion filter double -> QString. ***************************************************************************/ /*************************************************************************** * * * 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 "Double2StringFilter.h" #include "backend/lib/XmlStreamReader.h" #include #include #include class Double2StringFilterSetFormatCmd : public QUndoCommand { public: Double2StringFilterSetFormatCmd(Double2StringFilter* target, char new_format); - virtual void redo(); - virtual void undo(); + void redo() override; + void undo() override; private: Double2StringFilter* m_target; char m_other_format; }; class Double2StringFilterSetDigitsCmd : public QUndoCommand { public: Double2StringFilterSetDigitsCmd(Double2StringFilter* target, int new_digits); - virtual void redo(); - virtual void undo(); + void redo() override; + void undo() override; private: Double2StringFilter* m_target; int m_other_digits; }; void Double2StringFilter::writeExtraAttributes(QXmlStreamWriter * writer) const { writer->writeAttribute("format", QString(QChar(numericFormat()))); writer->writeAttribute("digits", QString::number(numDigits())); } bool Double2StringFilter::load(XmlStreamReader* reader, bool preview) { if (preview) return true; QXmlStreamAttributes attribs = reader->attributes(); QString format_str = attribs.value(reader->namespaceUri().toString(), "format").toString(); QString digits_str = attribs.value(reader->namespaceUri().toString(), "digits").toString(); if (AbstractSimpleFilter::load(reader, preview)) { bool ok; int digits = digits_str.toInt(&ok); if ( (format_str.size() != 1) || !ok ) { reader->raiseError(i18n("missing or invalid format attribute")); } else { setNumericFormat( format_str.at(0).toAscii() ); setNumDigits( digits ); } } else return false; return !reader->hasError(); } void Double2StringFilter::setNumericFormat(char format) { exec(new Double2StringFilterSetFormatCmd(this, format)); } void Double2StringFilter::setNumDigits(int digits) { exec(new Double2StringFilterSetDigitsCmd(this, digits)); } Double2StringFilterSetFormatCmd::Double2StringFilterSetFormatCmd(Double2StringFilter* target, char new_format) : m_target(target), m_other_format(new_format) { if(m_target->parentAspect()) setText(i18n("%1: set numeric format to '%2'", m_target->parentAspect()->name(), new_format)); else setText(i18n("set numeric format to '%1'", new_format)); } void Double2StringFilterSetFormatCmd::redo() { char tmp = m_target->m_format; m_target->m_format = m_other_format; m_other_format = tmp; emit m_target->formatChanged(); } void Double2StringFilterSetFormatCmd::undo() { redo(); } Double2StringFilterSetDigitsCmd::Double2StringFilterSetDigitsCmd(Double2StringFilter* target, int new_digits) : m_target(target), m_other_digits(new_digits) { if(m_target->parentAspect()) setText(i18n("%1: set decimal digits to %2", m_target->parentAspect()->name(), new_digits)); else setText(i18n("set decimal digits to %1", new_digits)); } void Double2StringFilterSetDigitsCmd::redo() { int tmp = m_target->m_digits; m_target->m_digits = m_other_digits; m_other_digits = tmp; emit m_target->digitsChanged(); } void Double2StringFilterSetDigitsCmd::undo() { redo(); } diff --git a/src/backend/core/datatypes/Double2StringFilter.h b/src/backend/core/datatypes/Double2StringFilter.h index 7fd4517b6..289f32e3b 100644 --- a/src/backend/core/datatypes/Double2StringFilter.h +++ b/src/backend/core/datatypes/Double2StringFilter.h @@ -1,87 +1,87 @@ /*************************************************************************** File : Double2StringFilter.h Project : AbstractColumn -------------------------------------------------------------------- Copyright : (C) 2007 by Knut Franke, Tilman Benkert Email (use @ for *) : knut.franke*gmx.de, thzs@gmx.net Description : Locale-aware conversion filter double -> QString. ***************************************************************************/ /*************************************************************************** * * * 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 DOUBLE2STRING_FILTER_H #define DOUBLE2STRING_FILTER_H #include "../AbstractSimpleFilter.h" #include #include //! Locale-aware conversion filter double -> QString. class Double2StringFilter : public AbstractSimpleFilter { Q_OBJECT public: //! Standard constructor. explicit Double2StringFilter(char format='e', int digits=6) : m_format(format), m_digits(digits) {} //! Set format character as in QString::number void setNumericFormat(char format); //! Set number of displayed digits void setNumDigits(int digits); //! Get format character as in QString::number char numericFormat() const { return m_format; } //! Get number of displayed digits int numDigits() const { return m_digits; } //! Return the data type of the column - virtual AbstractColumn::ColumnMode columnMode() const override { return AbstractColumn::Text; } + AbstractColumn::ColumnMode columnMode() const override { return AbstractColumn::Text; } private: friend class Double2StringFilterSetFormatCmd; friend class Double2StringFilterSetDigitsCmd; //! Format character as in QString::number char m_format; //! Display digits or precision as in QString::number int m_digits; //! \name XML related functions //@{ - virtual void writeExtraAttributes(QXmlStreamWriter*) const override; - virtual bool load(XmlStreamReader*, bool preview) override; + void writeExtraAttributes(QXmlStreamWriter*) const override; + bool load(XmlStreamReader*, bool preview) override; //@} public: - virtual QString textAt(int row) const override { + QString textAt(int row) const override { //DEBUG("Double2String::textAt()"); if (!m_inputs.value(0)) return QString(); if (m_inputs.value(0)->rowCount() <= row) return QString(); double inputValue = m_inputs.value(0)->valueAt(row); if (std::isnan(inputValue)) return QString(); return QLocale().toString(inputValue, m_format, m_digits); } protected: //! Using typed ports: only double inputs are accepted. - virtual bool inputAcceptable(int, const AbstractColumn *source) override { + bool inputAcceptable(int, const AbstractColumn *source) override { return source->columnMode() == AbstractColumn::Numeric; } }; #endif // ifndef DOUBLE2STRING_FILTER_H diff --git a/src/backend/core/datatypes/Integer2DateTimeFilter.h b/src/backend/core/datatypes/Integer2DateTimeFilter.h index 996c29869..9470d9412 100644 --- a/src/backend/core/datatypes/Integer2DateTimeFilter.h +++ b/src/backend/core/datatypes/Integer2DateTimeFilter.h @@ -1,61 +1,61 @@ /*************************************************************************** File : Integer2DateTimeFilter.h Project : AbstractColumn -------------------------------------------------------------------- Copyright : (C) 2007 by Knut Franke, Tilman Benkert Email (use @ for *) : knut.franke*gmx.de, thzs@gmx.net Description : Conversion filter int -> QDateTime, interpreting the input numbers as Julian days. ***************************************************************************/ /*************************************************************************** * * * 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 INTEGER2DATE_TIME_FILTER_H #define INTEGER2DATE_TIME_FILTER_H #include "../AbstractSimpleFilter.h" #include //! Conversion filter double -> QDateTime, interpreting the input numbers as (fractional) Julian days. class Integer2DateTimeFilter : public AbstractSimpleFilter { Q_OBJECT public: - virtual QDate dateAt(int row) const { + QDate dateAt(int row) const override { if (!m_inputs.value(0)) return QDate(); int inputValue = m_inputs.value(0)->integerAt(row); return QDate(1900, 1, 1 + inputValue); } - virtual QDateTime dateTimeAt(int row) const { + QDateTime dateTimeAt(int row) const override { return QDateTime(dateAt(row), QTime()); } //! Return the data type of the column - virtual AbstractColumn::ColumnMode columnMode() const { return AbstractColumn::DateTime; } + AbstractColumn::ColumnMode columnMode() const override { return AbstractColumn::DateTime; } protected: //! Using typed ports: only double inputs are accepted. - virtual bool inputAcceptable(int, const AbstractColumn *source) { + bool inputAcceptable(int, const AbstractColumn *source) override { return source->columnMode() == AbstractColumn::Integer; } }; #endif // ifndef INTEGER2DATE_TIME_FILTER_H diff --git a/src/backend/core/datatypes/Integer2DayOfWeekFilter.h b/src/backend/core/datatypes/Integer2DayOfWeekFilter.h index 403fd3be8..beb8f8d9e 100644 --- a/src/backend/core/datatypes/Integer2DayOfWeekFilter.h +++ b/src/backend/core/datatypes/Integer2DayOfWeekFilter.h @@ -1,65 +1,65 @@ /*************************************************************************** File : Integer2DayOfWeekFilter.h Project : AbstractColumn -------------------------------------------------------------------- Copyright : (C) 2017 Stefan Gerlach (stefan.gerlach@uni.kn) Description : Conversion filter int -> QDateTime, interpreting the input numbers as days of the week (1 -> Monday). ***************************************************************************/ /*************************************************************************** * * * 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 INTEGER2DAY_OF_WEEK_FILTER_H #define INTEGER2DAY_OF_WEEK_FILTER_H #include "../AbstractSimpleFilter.h" #include //! Conversion filter int -> QDateTime, interpreting the input numbers as days of the week (1 = Monday). class Integer2DayOfWeekFilter : public AbstractSimpleFilter { Q_OBJECT public: - virtual QDate dateAt(int row) const { + QDate dateAt(int row) const override { if (!m_inputs.value(0)) return QDate(); int inputValue = m_inputs.value(0)->integerAt(row); // Don't use Julian days here since support for years < 1 is bad // Use 1900-01-01 instead (a Monday) return QDate(1900,1,1).addDays(inputValue); } - virtual QTime timeAt(int row) const { + QTime timeAt(int row) const override { Q_UNUSED(row) return QTime(0,0,0,0); } - virtual QDateTime dateTimeAt(int row) const { + QDateTime dateTimeAt(int row) const override { return QDateTime(dateAt(row), timeAt(row)); } //! Return the data type of the column - virtual AbstractColumn::ColumnMode columnMode() const { return AbstractColumn::Day; } + AbstractColumn::ColumnMode columnMode() const override { return AbstractColumn::Day; } protected: //! Using typed ports: only integer inputs are accepted. - virtual bool inputAcceptable(int, const AbstractColumn *source) { + bool inputAcceptable(int, const AbstractColumn *source) override { return source->columnMode() == AbstractColumn::Integer; } }; #endif // ifndef INTEGER2DAY_OF_WEEK_FILTER_H diff --git a/src/backend/core/datatypes/Integer2DoubleFilter.h b/src/backend/core/datatypes/Integer2DoubleFilter.h index 88bad5743..f28c7d2e3 100644 --- a/src/backend/core/datatypes/Integer2DoubleFilter.h +++ b/src/backend/core/datatypes/Integer2DoubleFilter.h @@ -1,62 +1,62 @@ /*************************************************************************** File : Integer2DoubleFilter.h Project : AbstractColumn -------------------------------------------------------------------- Copyright : (C) 2017 Stefan Gerlach (stefan.gerlach@uni.kn) Description : conversion filter int -> double. ***************************************************************************/ /*************************************************************************** * * * 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 INTEGER2DOUBLE_FILTER_H #define INTEGER2DOUBLE_FILTER_H #include "../AbstractSimpleFilter.h" #include //! conversion filter double -> int. class Integer2DoubleFilter : public AbstractSimpleFilter { Q_OBJECT public: Integer2DoubleFilter() {} - virtual double valueAt(int row) const { + double valueAt(int row) const override { if (!m_inputs.value(0)) return 0; int value = m_inputs.value(0)->integerAt(row); double result = (double)value; //DEBUG("Integer2Double::integerAt() " << value << " -> " << result); return result; } //! Return the data type of the column - virtual AbstractColumn::ColumnMode columnMode() const { return AbstractColumn::Numeric; } + AbstractColumn::ColumnMode columnMode() const override { return AbstractColumn::Numeric; } protected: //! Using typed ports: only integer inputs are accepted - virtual bool inputAcceptable(int, const AbstractColumn *source) { + bool inputAcceptable(int, const AbstractColumn *source) override { DEBUG("inputAcceptable(): source type = " << ENUM_TO_STRING(AbstractColumn, ColumnMode, source->columnMode())); return source->columnMode() == AbstractColumn::Integer; } }; #endif // ifndef INTEGER2DOUBLE_FILTER_H diff --git a/src/backend/core/datatypes/Integer2MonthFilter.h b/src/backend/core/datatypes/Integer2MonthFilter.h index 5d2caf494..6f3a60c2d 100644 --- a/src/backend/core/datatypes/Integer2MonthFilter.h +++ b/src/backend/core/datatypes/Integer2MonthFilter.h @@ -1,67 +1,67 @@ /*************************************************************************** File : Integer2MonthFilter.h Project : AbstractColumn -------------------------------------------------------------------- Copyright : (C) 2017 Stefan Gerlach (stefan.gerlach@uni.kn) Description : Conversion filter int -> QDateTime, interpreting the input numbers as months of the year. ***************************************************************************/ /*************************************************************************** * * * 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 INTEGER2MONTH_FILTER_H #define INTEGER2MONTH_FILTER_H #include "../AbstractSimpleFilter.h" #include #include //! Conversion filter double -> QDateTime, interpreting the input numbers as months of the year. class Integer2MonthFilter : public AbstractSimpleFilter { Q_OBJECT public: - virtual QDate dateAt(int row) const { + QDate dateAt(int row) const override { return dateTimeAt(row).date(); } - virtual QTime timeAt(int row) const { + QTime timeAt(int row) const override { return dateTimeAt(row).time(); } - virtual QDateTime dateTimeAt(int row) const { + QDateTime dateTimeAt(int row) const override { if (!m_inputs.value(0)) return QDateTime(); int inputValue = m_inputs.value(0)->integerAt(row); // Don't use Julian days here since support for years < 1 is bad // Use 1900-01-01 instead QDate result_date = QDate(1900,1,1).addMonths(inputValue); QTime result_time = QTime(0,0,0,0); return QDateTime(result_date, result_time); } //! Return the data type of the column - virtual AbstractColumn::ColumnMode columnMode() const { return AbstractColumn::Month; } + AbstractColumn::ColumnMode columnMode() const override { return AbstractColumn::Month; } protected: - virtual bool inputAcceptable(int, const AbstractColumn *source) { + bool inputAcceptable(int, const AbstractColumn *source) override { return source->columnMode() == AbstractColumn::Integer; } }; #endif // ifndef INTEGER2MONTH_FILTER_H diff --git a/src/backend/core/datatypes/Integer2StringFilter.h b/src/backend/core/datatypes/Integer2StringFilter.h index 63dfb13ae..210c3dc57 100644 --- a/src/backend/core/datatypes/Integer2StringFilter.h +++ b/src/backend/core/datatypes/Integer2StringFilter.h @@ -1,62 +1,62 @@ /*************************************************************************** File : Integer2StringFilter.h Project : AbstractColumn -------------------------------------------------------------------- Copyright : (C) 2017 Stefan Gerlach (stefan.gerlach@uni.kn) Description : Locale-aware conversion filter int -> QString. ***************************************************************************/ /*************************************************************************** * * * 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 INTEGER2STRING_FILTER_H #define INTEGER2STRING_FILTER_H #include "../AbstractSimpleFilter.h" #include //! Locale-aware conversion filter int -> QString. class Integer2StringFilter : public AbstractSimpleFilter { Q_OBJECT public: //! Standard constructor. explicit Integer2StringFilter() {} //! Return the data type of the column - virtual AbstractColumn::ColumnMode columnMode() const { return AbstractColumn::Text; } + AbstractColumn::ColumnMode columnMode() const override { return AbstractColumn::Text; } public: - virtual QString textAt(int row) const { + QString textAt(int row) const override { if (!m_inputs.value(0)) return QString(); if (m_inputs.value(0)->rowCount() <= row) return QString(); int inputValue = m_inputs.value(0)->integerAt(row); return QLocale().toString(inputValue); } protected: //! Using typed ports: only double inputs are accepted. - virtual bool inputAcceptable(int, const AbstractColumn *source) { + bool inputAcceptable(int, const AbstractColumn *source) override { return source->columnMode() == AbstractColumn::Integer; } }; #endif // ifndef INTEGER2STRING_FILTER_H diff --git a/src/backend/core/datatypes/Month2DoubleFilter.h b/src/backend/core/datatypes/Month2DoubleFilter.h index 8542a413c..bb8ea199a 100644 --- a/src/backend/core/datatypes/Month2DoubleFilter.h +++ b/src/backend/core/datatypes/Month2DoubleFilter.h @@ -1,64 +1,64 @@ /*************************************************************************** File : MonthDoubleFilter.h Project : AbstractColumn -------------------------------------------------------------------- Copyright : (C) 2007 by Knut Franke, Tilman Benkert Email (use @ for *) : knut.franke*gmx.de, thzs@gmx.net Description : Conversion filter QDateTime -> double, translating dates into months (January -> 1). ***************************************************************************/ /*************************************************************************** * * * 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 MONTH2DOUBLE_FILTER_H #define MONTH2DOUBLE_FILTER_H #include "../AbstractSimpleFilter.h" #include #include /** * \brief Conversion filter QDateTime -> double, translating dates into months (January -> 1). * * \sa QDate::month() */ class Month2DoubleFilter : public AbstractSimpleFilter { Q_OBJECT public: - virtual double valueAt(int row) const { + double valueAt(int row) const override { if (!m_inputs.value(0)) return NAN; QDate inputValue = m_inputs.value(0)->dateAt(row); if (!inputValue.isValid()) return NAN; return double(inputValue.month()); } //! Return the data type of the column - virtual AbstractColumn::ColumnMode columnMode() const { return AbstractColumn::Numeric; } + AbstractColumn::ColumnMode columnMode() const override { return AbstractColumn::Numeric; } protected: //! Using typed ports: only date-time inputs are accepted. - virtual bool inputAcceptable(int, const AbstractColumn *source) { + bool inputAcceptable(int, const AbstractColumn *source) override { return source->columnMode() == AbstractColumn::Month; } }; #endif // ifndef MONTH2DOUBLE_FILTER_H diff --git a/src/backend/core/datatypes/Month2IntegerFilter.h b/src/backend/core/datatypes/Month2IntegerFilter.h index fa70ec17b..ece44df0d 100644 --- a/src/backend/core/datatypes/Month2IntegerFilter.h +++ b/src/backend/core/datatypes/Month2IntegerFilter.h @@ -1,62 +1,62 @@ /*************************************************************************** File : Month2IntegerFilter.h Project : AbstractColumn -------------------------------------------------------------------- Copyright : (C) 2017 Stefan Gerlach (stefan.gerlach@uni.kn) Description : Conversion filter QDateTime -> double, translating dates into months (January -> 1). ***************************************************************************/ /*************************************************************************** * * * 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 MONTH2INTEGER_FILTER_H #define MONTH2INTEGER_FILTER_H #include "../AbstractSimpleFilter.h" #include /** * \brief Conversion filter QDateTime -> int, translating dates into months (January -> 1). * * \sa QDate::month() */ class Month2IntegerFilter : public AbstractSimpleFilter { Q_OBJECT public: - virtual int integerAt(int row) const { + int integerAt(int row) const override { DEBUG("integerAt()"); if (!m_inputs.value(0)) return 0; QDate inputValue = m_inputs.value(0)->dateAt(row); if (!inputValue.isValid()) return 0; return int(inputValue.month()); } //! Return the data type of the column - virtual AbstractColumn::ColumnMode columnMode() const { return AbstractColumn::Integer; } + AbstractColumn::ColumnMode columnMode() const override { return AbstractColumn::Integer; } protected: //! Using typed ports: only date-time inputs are accepted. - virtual bool inputAcceptable(int, const AbstractColumn *source) { + bool inputAcceptable(int, const AbstractColumn *source) override { return source->columnMode() == AbstractColumn::Month; } }; #endif // ifndef MONTH2INTEGER_FILTER_H diff --git a/src/backend/core/datatypes/SimpleCopyThroughFilter.h b/src/backend/core/datatypes/SimpleCopyThroughFilter.h index ecc5c3221..7c6681bf5 100644 --- a/src/backend/core/datatypes/SimpleCopyThroughFilter.h +++ b/src/backend/core/datatypes/SimpleCopyThroughFilter.h @@ -1,55 +1,55 @@ /*************************************************************************** File : SimpleCopyThroughFilter.h Project : AbstractColumn -------------------------------------------------------------------- Copyright : (C) 2007 by Knut Franke, Tilman Benkert Email (use @ for *) : knut.franke*gmx.de, thzs*gmx.net Description : Filter which copies the provided input unaltered to the output ***************************************************************************/ /*************************************************************************** * * * 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 SIMPLE_COPY_THROUGH_FILTER_H #define SIMPLE_COPY_THROUGH_FILTER_H #include "backend/core/AbstractSimpleFilter.h" /** * \brief Filter which copies the provided input unaltered to the output * * Most of the necessary methods for this filter are already implemented * in AbstractSimpleFilter. * * The difference between this filter and CopyThroughFilter is that * this inherits AbstractColumn and thus can be directly used * as input for other filters and plot functions. */ class SimpleCopyThroughFilter : public AbstractSimpleFilter { Q_OBJECT protected: //! All types are accepted. - virtual bool inputAcceptable(int, const AbstractColumn *){ + bool inputAcceptable(int, const AbstractColumn *) override{ return true; } }; #endif // ifndef SIMPLE_COPY_THROUGH_FILTER_H diff --git a/src/backend/core/datatypes/String2DateTimeFilter.cpp b/src/backend/core/datatypes/String2DateTimeFilter.cpp index 52ed3a313..9ba605d00 100644 --- a/src/backend/core/datatypes/String2DateTimeFilter.cpp +++ b/src/backend/core/datatypes/String2DateTimeFilter.cpp @@ -1,161 +1,161 @@ /*************************************************************************** File : String2DateTimeFilter.cpp Project : LabPlot -------------------------------------------------------------------- Copyright : (C) 2007 Tilman Benkert (thzs@gmx.net) Copyright : (C) 2007 Knut Franke (knut.franke@gmx.de) Copyright : (C) 2017 Stefan Gerlach (stefan.gerlach@uni.kn) Description : Conversion filter QString -> QDateTime. ***************************************************************************/ /*************************************************************************** * * * 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 "String2DateTimeFilter.h" #include #include "backend/lib/XmlStreamReader.h" #include #include #include #include #include class String2DateTimeFilterSetFormatCmd : public QUndoCommand { public: String2DateTimeFilterSetFormatCmd(String2DateTimeFilter* target, const QString &new_format); - virtual void redo(); - virtual void undo(); + void redo() override; + void undo() override; private: String2DateTimeFilter* m_target; QString m_other_format; }; AbstractColumn::ColumnMode String2DateTimeFilter::columnMode() const { return AbstractColumn::DateTime; } QDateTime String2DateTimeFilter::dateTimeAt(int row) const { if (!m_inputs.value(0)) return QDateTime(); QString input_value = m_inputs.value(0)->textAt(row); if (input_value.isEmpty()) return QDateTime(); // first try the selected format string m_format QDateTime result = QDateTime::fromString(input_value, m_format); if(result.isValid()) return result; // fallback: // try other format strings built from date_formats and time_formats // comma and space are valid separators between date and time QStringList strings = input_value.simplified().split(',', QString::SkipEmptyParts); if(strings.size() == 1) strings = strings.at(0).split(' ', QString::SkipEmptyParts); if(strings.size() < 1) return result; // invalid date/time from first attempt QDate date_result; QTime time_result; QString date_string = strings.at(0).trimmed(); QString time_string; if(strings.size() > 1) time_string = strings.at(1).trimmed(); else time_string = date_string; // try to find a valid date for (const auto& format: AbstractColumn::dateFormats()) { date_result = QDate::fromString(date_string, format); if (date_result.isValid()) break; } // try to find a valid time for (const auto& format: AbstractColumn::timeFormats()) { time_result = QTime::fromString(time_string, format); if (time_result.isValid()) break; } if (!date_result.isValid() && time_result.isValid()) date_result.setDate(1900,1,1); // this is what QDateTime does e.g. for QDateTime::fromString("00:00","hh:mm"); else if (date_result.isValid() && !time_result.isValid()) time_result = QTime(0, 0, 0, 0); return QDateTime(date_result, time_result); } QDate String2DateTimeFilter::dateAt(int row) const { return dateTimeAt(row).date(); } QTime String2DateTimeFilter::timeAt(int row) const { return dateTimeAt(row).time(); } bool String2DateTimeFilter::inputAcceptable(int, const AbstractColumn* source) { return source->columnMode() == AbstractColumn::Text; } void String2DateTimeFilter::writeExtraAttributes(QXmlStreamWriter* writer) const { writer->writeAttribute("format", format()); } bool String2DateTimeFilter::load(XmlStreamReader* reader, bool preview) { if (preview) return true; QXmlStreamAttributes attribs = reader->attributes(); QString str = attribs.value(reader->namespaceUri().toString(), "format").toString(); if (AbstractSimpleFilter::load(reader, preview)) setFormat(str); else return false; return !reader->hasError(); } void String2DateTimeFilter::setFormat(const QString& format) { exec(new String2DateTimeFilterSetFormatCmd(this, format)); } String2DateTimeFilterSetFormatCmd::String2DateTimeFilterSetFormatCmd(String2DateTimeFilter* target, const QString &new_format) : m_target(target), m_other_format(new_format) { if(m_target->parentAspect()) setText(i18n("%1: set date-time format to %2", m_target->parentAspect()->name(), new_format)); else setText(i18n("set date-time format to %1", new_format)); } void String2DateTimeFilterSetFormatCmd::redo() { QString tmp = m_target->m_format; m_target->m_format = m_other_format; m_other_format = tmp; emit m_target->formatChanged(); } void String2DateTimeFilterSetFormatCmd::undo() { redo(); } diff --git a/src/backend/core/datatypes/String2DateTimeFilter.h b/src/backend/core/datatypes/String2DateTimeFilter.h index 72bb867f6..e7ac8fbc6 100644 --- a/src/backend/core/datatypes/String2DateTimeFilter.h +++ b/src/backend/core/datatypes/String2DateTimeFilter.h @@ -1,89 +1,89 @@ /*************************************************************************** File : String2DateTimeFilter.h Project : LabPlot -------------------------------------------------------------------- Copyright : (C) 2007 by Tilman Benkert (thzs@gmx.net) Copyright : (C) 2007 by Knut Franke (knut.franke@gmx.de) Description : Conversion filter QString -> QDateTime. ***************************************************************************/ /*************************************************************************** * * * 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 STRING2DATE_TIME_FILTER_H #define STRING2DATE_TIME_FILTER_H #include "backend/core/AbstractSimpleFilter.h" /** * \brief Conversion filter QString -> QDateTime. * * The standard use of this filter is explicitly specifiying the date/time format of the strings * on the input, either in the constructor or via setFormat(). * However, if the input fails to comply to this format, String2DateTimeFilter * tries to guess the format, using internal lists of common date and time formats (#date_formats * and #time_formats). */ class String2DateTimeFilter : public AbstractSimpleFilter { Q_OBJECT public: //! Standard constructor. explicit String2DateTimeFilter(QString format="yyyy-MM-dd hh:mm:ss.zzz") : m_format(format) {} //! Set the format string to be used for conversion. void setFormat(const QString& format); //! Return the format string /** * The default format string is "yyyy-MM-dd hh:mm:ss.zzz". * \sa QDate::toString() */ QString format() const { return m_format; } //! Return the data type of the column - virtual AbstractColumn::ColumnMode columnMode() const override; + AbstractColumn::ColumnMode columnMode() const override; //! \name XML related functions //@{ - virtual void writeExtraAttributes(QXmlStreamWriter*) const override; - virtual bool load(XmlStreamReader*, bool preview) override; + void writeExtraAttributes(QXmlStreamWriter*) const override; + bool load(XmlStreamReader*, bool preview) override; //@} signals: void formatChanged(); private: friend class String2DateTimeFilterSetFormatCmd; //! The format string. QString m_format; static const char * date_formats[]; static const char * time_formats[]; public: - virtual QDateTime dateTimeAt(int row) const override; - virtual QDate dateAt(int row) const override; - virtual QTime timeAt(int row) const override; + QDateTime dateTimeAt(int row) const override; + QDate dateAt(int row) const override; + QTime timeAt(int row) const override; protected: //! Using typed ports: only string inputs are accepted. - virtual bool inputAcceptable(int, const AbstractColumn *source) override; + bool inputAcceptable(int, const AbstractColumn *source) override; }; #endif // ifndef STRING2DATE_TIME_FILTER_H diff --git a/src/backend/core/datatypes/String2DayOfWeekFilter.h b/src/backend/core/datatypes/String2DayOfWeekFilter.h index d6ef2c7ad..33a0f19de 100644 --- a/src/backend/core/datatypes/String2DayOfWeekFilter.h +++ b/src/backend/core/datatypes/String2DayOfWeekFilter.h @@ -1,84 +1,84 @@ /*************************************************************************** File : String2DayOfWeekFilter.h Project : AbstractColumn -------------------------------------------------------------------- Copyright : (C) 2007 by Knut Franke, Tilman Benkert Email (use @ for *) : knut.franke*gmx.de, thzs*gmx.net Description : Conversion filter String -> QDateTime, interpreting the input as days of the week (either numeric or "Mon" etc). ***************************************************************************/ /*************************************************************************** * * * 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 STRING2DAYOFWEEK_FILTER_H #define STRING2DAYOFWEEK_FILTER_H #include "../AbstractSimpleFilter.h" class QDateTime; //! Conversion filter String -> QDateTime, interpreting the input as days of the week (either numeric or "Mon" etc). class String2DayOfWeekFilter : public AbstractSimpleFilter { Q_OBJECT public: - virtual QDate dateAt(int row) const { + QDate dateAt(int row) const override { return dateTimeAt(row).date(); } - virtual QTime timeAt(int row) const{ + QTime timeAt(int row) const override{ return dateTimeAt(row).time(); } - virtual QDateTime dateTimeAt(int row) const { + QDateTime dateTimeAt(int row) const override { if (!m_inputs.value(0)) return QDateTime(); QString input_value = m_inputs.value(0)->textAt(row); if (input_value.isEmpty()) return QDateTime(); bool ok; int day_value = input_value.toInt(&ok); if(!ok) { QDate temp = QDate::fromString(input_value, "ddd"); if(!temp.isValid()) temp = QDate::fromString(input_value, "dddd"); if(!temp.isValid()) return QDateTime(); else day_value = temp.dayOfWeek(); } // Don't use Julian days here since support for years < 1 is bad // Use 1900-01-01 instead (a Monday) QDate result_date = QDate(1900,1,1).addDays(day_value - 1); QTime result_time = QTime(0,0,0,0); return QDateTime(result_date, result_time); } //! Return the data type of the column - virtual AbstractColumn::ColumnMode columnMode() const { return AbstractColumn::Day; } + AbstractColumn::ColumnMode columnMode() const override { return AbstractColumn::Day; } protected: - virtual bool inputAcceptable(int, const AbstractColumn *source) { + bool inputAcceptable(int, const AbstractColumn *source) override { return source->columnMode() == AbstractColumn::Text; } }; #endif // ifndef STRING2DAYOFWEEK_FILTER_H diff --git a/src/backend/core/datatypes/String2DoubleFilter.h b/src/backend/core/datatypes/String2DoubleFilter.h index 031f39770..d44aac5f2 100644 --- a/src/backend/core/datatypes/String2DoubleFilter.h +++ b/src/backend/core/datatypes/String2DoubleFilter.h @@ -1,76 +1,76 @@ /*************************************************************************** File : String2DoubleFilter.h Project : AbstractColumn -------------------------------------------------------------------- Copyright : (C) 2007 by Knut Franke Email (use @ for *) : knut.franke*gmx.de Description : Locale-aware conversion filter QString -> double. ***************************************************************************/ /*************************************************************************** * * * 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 STRING2DOUBLE_FILTER_H #define STRING2DOUBLE_FILTER_H #include "../AbstractSimpleFilter.h" #include #include //! Locale-aware conversion filter QString -> double. class String2DoubleFilter : public AbstractSimpleFilter { Q_OBJECT public: String2DoubleFilter() : m_use_default_locale(true) {} void setNumericLocale(QLocale locale) { m_numeric_locale = locale; m_use_default_locale = false; } void setNumericLocaleToDefault() { m_use_default_locale = true; } - virtual double valueAt(int row) const { + double valueAt(int row) const override { DEBUG("String2Double::valueAt()"); if (!m_inputs.value(0)) return 0; double result; bool valid; if (m_use_default_locale) // we need a new QLocale instance here in case the default changed since the last call result = QLocale().toDouble(m_inputs.value(0)->textAt(row), &valid); else result = m_numeric_locale.toDouble(m_inputs.value(0)->textAt(row), &valid); if (valid) return result; return NAN; } //! Return the data type of the column - virtual AbstractColumn::ColumnMode columnMode() const { return AbstractColumn::Numeric; } + AbstractColumn::ColumnMode columnMode() const override { return AbstractColumn::Numeric; } protected: //! Using typed ports: only string inputs are accepted. - virtual bool inputAcceptable(int, const AbstractColumn *source) { + bool inputAcceptable(int, const AbstractColumn *source) override { return source->columnMode() == AbstractColumn::Text; } private: QLocale m_numeric_locale; bool m_use_default_locale; }; #endif // ifndef STRING2DOUBLE_FILTER_H diff --git a/src/backend/core/datatypes/String2IntegerFilter.h b/src/backend/core/datatypes/String2IntegerFilter.h index 2b8a59b7b..560af5275 100644 --- a/src/backend/core/datatypes/String2IntegerFilter.h +++ b/src/backend/core/datatypes/String2IntegerFilter.h @@ -1,76 +1,76 @@ /*************************************************************************** File : String2IntegerFilter.h Project : AbstractColumn -------------------------------------------------------------------- Copyright : (C) 2017 Stefan Gerlach (stefan.gerlach@uni.kn) Description : Locale-aware conversion filter QString -> int. ***************************************************************************/ /*************************************************************************** * * * 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 STRING2INTEGER_FILTER_H #define STRING2INTEGER_FILTER_H #include "../AbstractSimpleFilter.h" #include //! Locale-aware conversion filter QString -> int. class String2IntegerFilter : public AbstractSimpleFilter { Q_OBJECT public: String2IntegerFilter() : m_use_default_locale(true) {} void setNumericLocale(QLocale locale) { m_numeric_locale = locale; m_use_default_locale = false; } void setNumericLocaleToDefault() { m_use_default_locale = true; } - virtual int integerAt(int row) const { + int integerAt(int row) const override { //DEBUG("String2Integer::integerAt()"); if (!m_inputs.value(0)) return 0; int result; bool valid; QString textValue = m_inputs.value(0)->textAt(row); //DEBUG(" textValue = " << textValue.toStdString()); if (m_use_default_locale) // we need a new QLocale instance here in case the default changed since the last call result = QLocale().toInt(textValue, &valid); else result = m_numeric_locale.toInt(textValue, &valid); //DEBUG(" result = " << result << " valid = " << valid); if (valid) return result; return 0; } //! Return the data type of the column - virtual AbstractColumn::ColumnMode columnMode() const { return AbstractColumn::Integer; } + AbstractColumn::ColumnMode columnMode() const override { return AbstractColumn::Integer; } protected: //! Using typed ports: only string inputs are accepted. - virtual bool inputAcceptable(int, const AbstractColumn *source) { + bool inputAcceptable(int, const AbstractColumn *source) override { return source->columnMode() == AbstractColumn::Text; } private: QLocale m_numeric_locale; bool m_use_default_locale; }; #endif // ifndef STRING2INTEGER_FILTER_H diff --git a/src/backend/core/datatypes/String2MonthFilter.h b/src/backend/core/datatypes/String2MonthFilter.h index 7a5bbfd17..4fd85436e 100644 --- a/src/backend/core/datatypes/String2MonthFilter.h +++ b/src/backend/core/datatypes/String2MonthFilter.h @@ -1,83 +1,83 @@ /*************************************************************************** File : String2MonthFilter.h Project : AbstractColumn -------------------------------------------------------------------- Copyright : (C) 2007 by Knut Franke, Tilman Benkert Email (use @ for *) : knut.franke*gmx.de, thzs*gmx.net Description : Conversion filter String -> QDateTime, interpreting the input as months of the year (either numeric or "Jan" etc). ***************************************************************************/ /*************************************************************************** * * * 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 STRING2MONTH_FILTER_H #define STRING2MONTH_FILTER_H #include "../AbstractSimpleFilter.h" class QDateTime; //! Conversion filter String -> QDateTime, interpreting the input as months of the year (either numeric or "Jan" etc). class String2MonthFilter : public AbstractSimpleFilter { Q_OBJECT public: - virtual QDate dateAt(int row) const { + QDate dateAt(int row) const override { return dateTimeAt(row).date(); } - virtual QTime timeAt(int row) const { + QTime timeAt(int row) const override { return dateTimeAt(row).time(); } - virtual QDateTime dateTimeAt(int row) const { + QDateTime dateTimeAt(int row) const override { if (!m_inputs.value(0)) return QDateTime(); QString input_value = m_inputs.value(0)->textAt(row); bool ok; int month_value = input_value.toInt(&ok); if(!ok) { QDate temp = QDate::fromString(input_value, "MMM"); if(!temp.isValid()) temp = QDate::fromString(input_value, "MMMM"); if(!temp.isValid()) return QDateTime(); else month_value = temp.month(); } // Don't use Julian days here since support for years < 1 is bad // Use 1900-01-01 instead QDate result_date = QDate(1900,1,1).addMonths(month_value - 1); QTime result_time = QTime(0,0,0,0); return QDateTime(result_date, result_time); } //! Return the data type of the column - virtual AbstractColumn::ColumnMode columnMode() const { return AbstractColumn::Month; } + AbstractColumn::ColumnMode columnMode() const override { return AbstractColumn::Month; } protected: - virtual bool inputAcceptable(int, const AbstractColumn *source) { + bool inputAcceptable(int, const AbstractColumn *source) override { return source->columnMode() == AbstractColumn::Text; } }; #endif // ifndef STRING2MONTH_FILTER_H diff --git a/src/backend/core/plugin/PluginLoader.h b/src/backend/core/plugin/PluginLoader.h index b76e688e4..816a99fbe 100644 --- a/src/backend/core/plugin/PluginLoader.h +++ b/src/backend/core/plugin/PluginLoader.h @@ -1,66 +1,66 @@ /*************************************************************************** File : PluginLoader.h Project : LabPlot/SciDAVis Description : Loader for VersionedPlugins. -------------------------------------------------------------------- Copyright : (C) 2009 Tilman Benkert (thzs*gmx.net) (replace * with @ in the email addresses) ***************************************************************************/ /*************************************************************************** * * * 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 PLUGINLOADER_H #define PLUGINLOADER_H #include class PluginLoader: public QObject { Q_OBJECT enum PluginStatus { NotYetLoaded, Active, ErrorFromQt, NoVersionedPlugin, IncompatibleApp, }; public: explicit PluginLoader(const QString& fileName); - ~PluginLoader(); + ~PluginLoader() override; QString statusString() const; PluginStatus status() const; QString fileName() const; QObject *instance(); bool isActive() const; bool load(); bool unload(); private: QPluginLoader *m_loader; QString m_fileName; QString m_statusString; PluginStatus m_status; }; #endif diff --git a/src/backend/datapicker/Datapicker.h b/src/backend/datapicker/Datapicker.h index 91b9c5856..464901c4f 100644 --- a/src/backend/datapicker/Datapicker.h +++ b/src/backend/datapicker/Datapicker.h @@ -1,94 +1,94 @@ /*************************************************************************** File : Datapicker.h Project : LabPlot Description : Datapicker -------------------------------------------------------------------- Copyright : (C) 2015 by Ankit Wagadre (wagadre.ankit@gmail.com) Copyright : (C) 2015-2016 by Alexander Semke (alexander.semke@web.de) ***************************************************************************/ /*************************************************************************** * * * 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 DATAPICKER_H #define DATAPICKER_H #include "backend/core/AbstractPart.h" #include "backend/core/AbstractScriptingEngine.h" class Spreadsheet; class DatapickerCurve; class DatapickerImage; class QXmlStreamWriter; class XmlStreamReader; class Transform; class QPointF; class QVector3D; class Datapicker : public AbstractPart, public scripted { Q_OBJECT public: explicit Datapicker(AbstractScriptingEngine* engine, const QString& name, const bool loading = false); - virtual ~Datapicker(); + ~Datapicker() override; - virtual QIcon icon() const override; - virtual QMenu* createContextMenu() override; - virtual QWidget* view() const override; + QIcon icon() const override; + QMenu* createContextMenu() override; + QWidget* view() const override; - virtual bool exportView() const override; - virtual bool printView() override; - virtual bool printPreview() const override; + bool exportView() const override; + bool printView() override; + bool printPreview() const override; DatapickerCurve* activeCurve(); Spreadsheet* currentSpreadsheet() const; DatapickerImage* image() const; void setChildSelectedInView(int index, bool selected); void setSelectedInView(const bool); void addNewPoint(const QPointF&, AbstractAspect*); QVector3D mapSceneToLogical(const QPointF&) const; QVector3D mapSceneLengthToLogical(const QPointF&) const; - virtual void save(QXmlStreamWriter*) const override; - virtual bool load(XmlStreamReader*, bool preview) override; + void save(QXmlStreamWriter*) const override; + bool load(XmlStreamReader*, bool preview) override; public slots: - virtual void childSelected(const AbstractAspect*) override; + void childSelected(const AbstractAspect*) override; private: DatapickerCurve* m_activeCurve; Transform* m_transform; DatapickerImage* m_image; void init(); void handleChildAspectAboutToBeRemoved(const AbstractAspect*); void handleChildAspectAdded(const AbstractAspect*); private slots: - virtual void childDeselected(const AbstractAspect*) override; + void childDeselected(const AbstractAspect*) override; void handleAspectAdded(const AbstractAspect*); void handleAspectAboutToBeRemoved(const AbstractAspect*); signals: void datapickerItemSelected(int); void requestUpdateActions(); }; #endif diff --git a/src/backend/datapicker/DatapickerCurve.h b/src/backend/datapicker/DatapickerCurve.h index 70071b1c3..e75c4cb37 100644 --- a/src/backend/datapicker/DatapickerCurve.h +++ b/src/backend/datapicker/DatapickerCurve.h @@ -1,149 +1,149 @@ /*************************************************************************** File : DatapickerCurve.h Project : LabPlot Description : container for Curve-Point and Datasheet/Spreadsheet of datapicker -------------------------------------------------------------------- Copyright : (C) 2015 by Ankit Wagadre (wagadre.ankit@gmail.com) ***************************************************************************/ /*************************************************************************** * * * 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 DATAPICKERCURVE_H #define DATAPICKERCURVE_H #include "backend/core/AbstractAspect.h" #include "backend/lib/macros.h" #include "backend/datapicker/DatapickerImage.h" #include "backend/worksheet/plots/cartesian/Symbol.h" class DatapickerPoint; class QAction; class DatapickerCurvePrivate; class Column; class Spreadsheet; class AbstractColumn; class DatapickerCurve: public AbstractAspect { Q_OBJECT public: explicit DatapickerCurve(const QString&); - ~DatapickerCurve(); + ~DatapickerCurve() override; enum ErrorType { NoError, SymmetricError, AsymmetricError }; struct Errors { ErrorType x; ErrorType y; }; - virtual QIcon icon() const override; - virtual QMenu* createContextMenu() override; + QIcon icon() const override; + QMenu* createContextMenu() override; void setPrinting(bool); void setSelectedInView(const bool); void addDatasheet(const DatapickerImage::GraphType&); void updateData(const DatapickerPoint*); BASIC_D_ACCESSOR_DECL(Errors, curveErrorTypes, CurveErrorTypes) BASIC_D_ACCESSOR_DECL(Symbol::Style, pointStyle, PointStyle) BASIC_D_ACCESSOR_DECL(qreal, pointOpacity, PointOpacity) BASIC_D_ACCESSOR_DECL(qreal, pointRotationAngle, PointRotationAngle) BASIC_D_ACCESSOR_DECL(qreal, pointSize, PointSize) CLASS_D_ACCESSOR_DECL(QBrush, pointBrush, PointBrush) CLASS_D_ACCESSOR_DECL(QPen, pointPen, PointPen) BASIC_D_ACCESSOR_DECL(qreal, pointErrorBarSize, PointErrorBarSize) CLASS_D_ACCESSOR_DECL(QBrush, pointErrorBarBrush, PointErrorBarBrush) CLASS_D_ACCESSOR_DECL(QPen, pointErrorBarPen, PointErrorBarPen) BASIC_D_ACCESSOR_DECL(bool, pointVisibility, PointVisibility) POINTER_D_ACCESSOR_DECL(AbstractColumn, posXColumn, PosXColumn) QString& posXColumnPath() const; POINTER_D_ACCESSOR_DECL(AbstractColumn, posYColumn, PosYColumn) QString& posYColumnPath() const; POINTER_D_ACCESSOR_DECL(AbstractColumn, posZColumn, PosZColumn) QString& posZColumnPath() const; POINTER_D_ACCESSOR_DECL(AbstractColumn, plusDeltaXColumn, PlusDeltaXColumn) QString& plusDeltaXColumnPath() const; POINTER_D_ACCESSOR_DECL(AbstractColumn, minusDeltaXColumn, MinusDeltaXColumn) QString& minusDeltaXColumnPath() const; POINTER_D_ACCESSOR_DECL(AbstractColumn, plusDeltaYColumn, PlusDeltaYColumn) QString& plusDeltaYColumnPath() const; POINTER_D_ACCESSOR_DECL(AbstractColumn, minusDeltaYColumn, MinusDeltaYColumn) QString& minusDeltaYColumnPath() const; - virtual void save(QXmlStreamWriter*) const override; - virtual bool load(XmlStreamReader*, bool preview) override; + void save(QXmlStreamWriter*) const override; + bool load(XmlStreamReader*, bool preview) override; typedef DatapickerCurvePrivate Private; protected: DatapickerCurve(const QString& name, DatapickerCurvePrivate* dd); DatapickerCurvePrivate* const d_ptr; private slots: void updateDatasheet(); private: Q_DECLARE_PRIVATE(DatapickerCurve) void init(); void initAction(); Column* appendColumn(const QString&); Spreadsheet* m_datasheet; QAction* updateDatasheetAction; signals: void curveErrorTypesChanged(const DatapickerCurve::Errors&); void posXColumnChanged(const AbstractColumn*); void posYColumnChanged(const AbstractColumn*); void posZColumnChanged(const AbstractColumn*); void plusDeltaXColumnChanged(const AbstractColumn*); void minusDeltaXColumnChanged(const AbstractColumn*); void plusDeltaYColumnChanged(const AbstractColumn*); void minusDeltaYColumnChanged(const AbstractColumn*); void pointStyleChanged(Symbol::Style); void pointSizeChanged(qreal); void pointRotationAngleChanged(qreal); void pointOpacityChanged(qreal); void pointBrushChanged(QBrush); void pointPenChanged(const QPen&); void pointErrorBarSizeChanged(qreal); void pointErrorBarBrushChanged(QBrush); void pointErrorBarPenChanged(const QPen&); void pointVisibilityChanged(bool); friend class DatapickerCurveSetCurveErrorTypesCmd; friend class DatapickerCurveSetPosXColumnCmd; friend class DatapickerCurveSetPosYColumnCmd; friend class DatapickerCurveSetPosZColumnCmd; friend class DatapickerCurveSetPlusDeltaXColumnCmd; friend class DatapickerCurveSetMinusDeltaXColumnCmd; friend class DatapickerCurveSetPlusDeltaYColumnCmd; friend class DatapickerCurveSetMinusDeltaYColumnCmd; friend class DatapickerCurveSetPointStyleCmd; friend class DatapickerCurveSetPointSizeCmd; friend class DatapickerCurveSetPointRotationAngleCmd; friend class DatapickerCurveSetPointOpacityCmd; friend class DatapickerCurveSetPointBrushCmd; friend class DatapickerCurveSetPointPenCmd; friend class DatapickerCurveSetPointErrorBarSizeCmd; friend class DatapickerCurveSetPointErrorBarPenCmd; friend class DatapickerCurveSetPointErrorBarBrushCmd; friend class DatapickerCurveSetPointVisibilityCmd; }; #endif // DATAPICKERCURVE_H diff --git a/src/backend/datapicker/DatapickerImage.h b/src/backend/datapicker/DatapickerImage.h index b191a1f20..6def10cbf 100644 --- a/src/backend/datapicker/DatapickerImage.h +++ b/src/backend/datapicker/DatapickerImage.h @@ -1,172 +1,172 @@ /*************************************************************************** File : DatapickerImage.h Project : LabPlot Description : Worksheet for Datapicker -------------------------------------------------------------------- Copyright : (C) 2015 by Ankit Wagadre (wagadre.ankit@gmail.com) Copyright : (C) 2015-2016 by Alexander Semke (alexander.semke@web.de) ***************************************************************************/ /*************************************************************************** * * * 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 DATAPICKERIMAGE_H #define DATAPICKERIMAGE_H #include "backend/core/AbstractPart.h" #include "backend/core/AbstractScriptingEngine.h" #include "backend/lib/macros.h" #include "backend/worksheet/plots/cartesian/Symbol.h" #include #include #include #include class DatapickerImagePrivate; class ImageEditor; class Segments; class QGraphicsScene; class QGraphicsPixmapItem; class DatapickerImage: public AbstractPart, public scripted { Q_OBJECT public: DatapickerImage(AbstractScriptingEngine* engine, const QString& name, bool loading = false); - ~DatapickerImage(); + ~DatapickerImage() override; enum GraphType { Cartesian, PolarInDegree, PolarInRadians, LogarithmicX, LogarithmicY, Ternary}; enum ColorAttributes { None, Intensity, Foreground, Hue, Saturation, Value }; enum PlotImageType { NoImage, OriginalImage, ProcessedImage }; enum PointsType { AxisPoints, CurvePoints, SegmentPoints }; struct ReferencePoints { GraphType type; QPointF scenePos[3]; QVector3D logicalPos[3]; double ternaryScale; }; struct EditorSettings { int intensityThresholdLow; int intensityThresholdHigh; int foregroundThresholdLow; int foregroundThresholdHigh; int hueThresholdLow; int hueThresholdHigh; int saturationThresholdLow; int saturationThresholdHigh; int valueThresholdLow; int valueThresholdHigh; }; - virtual QIcon icon() const override; - virtual QMenu* createContextMenu() override; + QIcon icon() const override; + QMenu* createContextMenu() override; void createContextMenu(QMenu*); - virtual QWidget* view() const override; + QWidget* view() const override; - virtual bool exportView() const override; - virtual bool printView() override; - virtual bool printPreview() const override; + bool exportView() const override; + bool printView() override; + bool printPreview() const override; - virtual void save(QXmlStreamWriter*) const override; - virtual bool load(XmlStreamReader*, bool preview) override; + void save(QXmlStreamWriter*) const override; + bool load(XmlStreamReader*, bool preview) override; QRectF pageRect() const; void setPageRect(const QRectF&); QGraphicsScene *scene() const; void setPrinting(bool) const; void setSelectedInView(const bool); void setSegmentsHoverEvent(const bool); void setPlotImageType(const DatapickerImage::PlotImageType); DatapickerImage::PlotImageType plotImageType(); bool isLoaded; QImage originalPlotImage; QImage processedPlotImage; QColor background; int *foregroundBins; int *hueBins; int *saturationBins; int *valueBins; int *intensityBins; QGraphicsPixmapItem* m_magnificationWindow; CLASS_D_ACCESSOR_DECL(QString, fileName, FileName) CLASS_D_ACCESSOR_DECL(DatapickerImage::ReferencePoints, axisPoints, AxisPoints) CLASS_D_ACCESSOR_DECL(DatapickerImage::EditorSettings, settings, Settings) BASIC_D_ACCESSOR_DECL(float, rotationAngle, RotationAngle) BASIC_D_ACCESSOR_DECL(PointsType, plotPointsType, PlotPointsType) BASIC_D_ACCESSOR_DECL(int, pointSeparation, PointSeparation) BASIC_D_ACCESSOR_DECL(int, minSegmentLength, minSegmentLength) BASIC_D_ACCESSOR_DECL(Symbol::Style, pointStyle, PointStyle) BASIC_D_ACCESSOR_DECL(qreal, pointOpacity, PointOpacity) BASIC_D_ACCESSOR_DECL(qreal, pointRotationAngle, PointRotationAngle) BASIC_D_ACCESSOR_DECL(qreal, pointSize, PointSize) CLASS_D_ACCESSOR_DECL(QBrush, pointBrush, PointBrush) CLASS_D_ACCESSOR_DECL(QPen, pointPen, PointPen) BASIC_D_ACCESSOR_DECL(bool, pointVisibility, PointVisibility) typedef DatapickerImagePrivate Private; private: void init(); void initSceneParameters(); DatapickerImagePrivate* const d; friend class DatapickerImagePrivate; Segments* m_segments; signals: void requestProjectContextMenu(QMenu*); void requestUpdate(); void requestUpdateActions(); void fileNameChanged(const QString&); void rotationAngleChanged(float); void axisPointsChanged(const DatapickerImage::ReferencePoints&); void settingsChanged(const DatapickerImage::EditorSettings&); void minSegmentLengthChanged(const int); void pointStyleChanged(Symbol::Style); void pointSizeChanged(qreal); void pointRotationAngleChanged(qreal); void pointOpacityChanged(qreal); void pointBrushChanged(QBrush); void pointPenChanged(const QPen&); void pointVisibilityChanged(bool); friend class DatapickerImageSetFileNameCmd; friend class DatapickerImageSetRotationAngleCmd; friend class DatapickerImageSetAxisPointsCmd; friend class DatapickerImageSetSettingsCmd; friend class DatapickerImageSetMinSegmentLengthCmd; friend class DatapickerImageSetPointStyleCmd; friend class DatapickerImageSetPointSizeCmd; friend class DatapickerImageSetPointRotationAngleCmd; friend class DatapickerImageSetPointOpacityCmd; friend class DatapickerImageSetPointBrushCmd; friend class DatapickerImageSetPointPenCmd; friend class DatapickerImageSetPointVisibilityCmd; }; #endif diff --git a/src/backend/datapicker/DatapickerPoint.h b/src/backend/datapicker/DatapickerPoint.h index fa4e09cc4..069976bb5 100644 --- a/src/backend/datapicker/DatapickerPoint.h +++ b/src/backend/datapicker/DatapickerPoint.h @@ -1,120 +1,120 @@ /*************************************************************************** File : DatapickerPoint.h Project : LabPlot Description : Graphic Item for coordinate points of Datapicker -------------------------------------------------------------------- Copyright : (C) 2015 by Ankit Wagadre (wagadre.ankit@gmail.com) ***************************************************************************/ /*************************************************************************** * * * 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 DATAPICKERPOINT_H #define DATAPICKERPOINT_H #include #include #include #include "backend/core/AbstractAspect.h" #include "backend/lib/macros.h" #include "backend/datapicker/DatapickerCurve.h" #include #include "backend/worksheet/plots/cartesian/Symbol.h" class DatapickerPoint; class ErrorBarItem : public QObject, public QGraphicsRectItem { Q_OBJECT public: enum ErrorBarType { PlusDeltaX, MinusDeltaX, PlusDeltaY, MinusDeltaY}; explicit ErrorBarItem(DatapickerPoint* parent = 0, const ErrorBarType& type = PlusDeltaX); - virtual QVariant itemChange(GraphicsItemChange change, const QVariant &value); + QVariant itemChange(GraphicsItemChange change, const QVariant &value) override; void setRectSize(const qreal); public slots: void setPosition(const QPointF&); private: void initRect(); - virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent*); + void mouseReleaseEvent(QGraphicsSceneMouseEvent*) override; QGraphicsLineItem* barLineItem; QRectF m_rect; ErrorBarType m_type; DatapickerPoint* m_parentItem; }; class DatapickerPointPrivate; class DatapickerPoint : public AbstractAspect { Q_OBJECT public: explicit DatapickerPoint(const QString& name ); - ~DatapickerPoint(); + ~DatapickerPoint() override; - virtual QIcon icon() const override; - virtual QMenu* createContextMenu() override; + QIcon icon() const override; + QMenu* createContextMenu() override; QGraphicsItem *graphicsItem() const; void setParentGraphicsItem(QGraphicsItem*); void setPrinting(bool); void initErrorBar(const DatapickerCurve::Errors&); - virtual void save(QXmlStreamWriter*) const override; - virtual bool load(XmlStreamReader*, bool preview) override; + void save(QXmlStreamWriter*) const override; + bool load(XmlStreamReader*, bool preview) override; CLASS_D_ACCESSOR_DECL(QPointF, position, Position) CLASS_D_ACCESSOR_DECL(QPointF, plusDeltaXPos, PlusDeltaXPos) CLASS_D_ACCESSOR_DECL(QPointF, minusDeltaXPos, MinusDeltaXPos) CLASS_D_ACCESSOR_DECL(QPointF, plusDeltaYPos, PlusDeltaYPos) CLASS_D_ACCESSOR_DECL(QPointF, minusDeltaYPos, MinusDeltaYPos) typedef DatapickerPointPrivate Private; public slots: void retransform(); protected: DatapickerPointPrivate* const d_ptr; DatapickerPoint(const QString &name, DatapickerPointPrivate *dd); static QPen selectedPen; static float selectedOpacity; private: Q_DECLARE_PRIVATE(DatapickerPoint) void init(); QList m_errorBarItemList; signals: friend class DatapickerPointSetPositionCmd; void positionChanged(const QPointF&); friend class DatapickerPointSetPlusDeltaXPosCmd; friend class DatapickerPointSetMinusDeltaXPosCmd; friend class DatapickerPointSetPlusDeltaYPosCmd; friend class DatapickerPointSetMinusDeltaYPosCmd; void plusDeltaXPosChanged(const QPointF&); void minusDeltaXPosChanged(const QPointF&); void plusDeltaYPosChanged(const QPointF&); void minusDeltaYPosChanged(const QPointF&); }; #endif diff --git a/src/backend/datapicker/DatapickerPointPrivate.h b/src/backend/datapicker/DatapickerPointPrivate.h index 8e45eb0f7..6bacb76ba 100644 --- a/src/backend/datapicker/DatapickerPointPrivate.h +++ b/src/backend/datapicker/DatapickerPointPrivate.h @@ -1,75 +1,75 @@ /*************************************************************************** File : DatapickerPointPrivate.h Project : LabPlot Description : Graphic Item for coordinate points of Datapicker -------------------------------------------------------------------- Copyright : (C) 2015 by Ankit Wagadre (wagadre.ankit@gmail.com) ***************************************************************************/ /*************************************************************************** * * * 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 DATAPICKERPOINTPRIVATE_H #define DATAPICKERPOINTPRIVATE_H #include class DatapickerPointPrivate: public QGraphicsItem { public: explicit DatapickerPointPrivate(DatapickerPoint*); QString name() const; void retransform(); virtual void recalcShapeAndBoundingRect(); void updateData(); void updatePropeties(); void retransformErrorBar(); bool m_printing; qreal rotationAngle; QPointF position; QRectF boundingRectangle; QRectF transformedBoundingRectangle; Symbol::Style pointStyle; QBrush brush; QPen pen; qreal opacity; qreal size; QPainterPath itemShape; QPointF plusDeltaXPos; QPointF minusDeltaXPos; QPointF plusDeltaYPos; QPointF minusDeltaYPos; QBrush errorBarBrush; QPen errorBarPen; qreal errorBarSize; //reimplemented from QGraphicsItem - virtual QRectF boundingRect() const; - virtual QPainterPath shape() const; - virtual void paint(QPainter*, const QStyleOptionGraphicsItem*, QWidget* widget = 0); + QRectF boundingRect() const override; + QPainterPath shape() const override; + void paint(QPainter*, const QStyleOptionGraphicsItem*, QWidget* widget = 0) override; DatapickerPoint* const q; private: - virtual void contextMenuEvent(QGraphicsSceneContextMenuEvent*); + void contextMenuEvent(QGraphicsSceneContextMenuEvent*) override; }; #endif diff --git a/src/backend/datapicker/ImageEditor.cpp b/src/backend/datapicker/ImageEditor.cpp index f4c68e322..5fb58e997 100644 --- a/src/backend/datapicker/ImageEditor.cpp +++ b/src/backend/datapicker/ImageEditor.cpp @@ -1,353 +1,353 @@ /*************************************************************************** File : ImageEditor.cpp Project : LabPlot Description : Edit Image on the basis of input color attributes -------------------------------------------------------------------- Copyright : (C) 2015 by Ankit Wagadre (wagadre.ankit@gmail.com) Copyright : (C) 2015-2016 Alexander Semke (alexander.semke@web.de) ***************************************************************************/ /*************************************************************************** * * * 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 "ImageEditor.h" #include #include #include #include static const QRgb white = QColor(Qt::white).rgb(); static const QRgb black = QColor(Qt::black).rgb(); //Intensity, Foreground, Saturation and Value are from 0 to 100, Hue is from 0 to 360 static const int maxIntensity = 100; static const int maxForeground = 100; static const int maxHue = 360; static const int maxSaturation = 100; static const int maxValue = 100; QMutex mutex; class DiscretizeTask : public QRunnable { public: DiscretizeTask(int start, int end, QImage* plotImage, QImage* originalImage, DatapickerImage::EditorSettings settings, QColor background) { m_start = start; m_end = end; m_plotImage = plotImage; m_originalImage = originalImage; m_settings = settings; m_background = background; }; - void run() { + void run() override { for (int y=m_start; y(m_plotImage->scanLine(y)); mutex.unlock(); int value; for (int x=0; xwidth(); ++x) { value = ImageEditor::discretizeHue(x, y, m_originalImage); if (!ImageEditor::pixelIsOn(value, DatapickerImage::Hue, m_settings)) continue; value = ImageEditor::discretizeSaturation(x, y, m_originalImage); if (!ImageEditor::pixelIsOn(value, DatapickerImage::Saturation, m_settings)) continue; value = ImageEditor::discretizeValue(x, y, m_originalImage); if (!ImageEditor::pixelIsOn(value, DatapickerImage::Value, m_settings)) continue; value = ImageEditor::discretizeIntensity(x, y, m_originalImage); if (!ImageEditor::pixelIsOn(value, DatapickerImage::Saturation, m_settings)) continue; value = ImageEditor::discretizeForeground(x, y, m_background, m_originalImage); if (!ImageEditor::pixelIsOn(value, DatapickerImage::Foreground, m_settings)) continue; line[x] = black; } } } private: int m_start; int m_end; QImage* m_plotImage; QImage* m_originalImage; DatapickerImage::EditorSettings m_settings; QColor m_background; }; /*! * */ void ImageEditor::discretize(QImage* plotImage, QImage* originalImage, DatapickerImage::EditorSettings settings, QColor background) { plotImage->fill(white); QThreadPool* pool = QThreadPool::globalInstance(); int range = ceil(double(plotImage->height())/pool->maxThreadCount()); for (int i=0; imaxThreadCount(); ++i) { const int start = i*range; int end = (i+1)*range; if (end>plotImage->height()) end = plotImage->height(); DiscretizeTask* task = new DiscretizeTask(start, end, plotImage, originalImage, settings, background); pool->start(task); } pool->waitForDone(); } bool ImageEditor::processedPixelIsOn(const QImage& plotImage, int x, int y) { if ((x < 0) || (plotImage.width() <= x) || (y < 0) || (plotImage.height() <= y)) return false; // pixel is on if it is closer to black than white in gray scale. this test must be performed // on little endian and big endian systems, with or without alpha bits (which are typically high bits) const int BLACK_WHITE_THRESHOLD = 255 / 2; // put threshold in middle of range int gray = qGray(plotImage.pixel(x, y)); return (gray < BLACK_WHITE_THRESHOLD); } //############################################################################## //##################### private helper functions ############################# //############################################################################## QRgb ImageEditor::findBackgroundColor(const QImage* plotImage) { QList::iterator itrC; ColorList colors; int x, y = 0; for (x = 0; x < plotImage->width(); ++x) { ColorEntry c; c.color = plotImage->pixel(x,y); c.count = 0; bool found = false; for (itrC = colors.begin(); itrC != colors.end(); ++itrC) { if (colorCompare(c.color.rgb(), (*itrC).color.rgb())) { found = true; ++(*itrC).count; break; } } if (!found) colors.append(c); if (++y >= plotImage->height()) y = 0; } ColorEntry cMax; cMax.count = 0; for (itrC = colors.begin(); itrC != colors.end(); ++itrC) { if ((*itrC).count > cMax.count) cMax = (*itrC); } return cMax.color.rgb(); } void ImageEditor::uploadHistogram(int* bins, QImage* originalImage, QColor background, DatapickerImage::ColorAttributes type) { //reset bin for (int i = 0; i <= colorAttributeMax(type); ++i) bins [i] = 0; for (int x = 0; x < originalImage->width(); ++x) { for (int y = 0; y < originalImage->height(); ++y) { int value = discretizeValueForeground(x, y, type, background, originalImage); bins[value] += 1; } } } int ImageEditor::colorAttributeMax(DatapickerImage::ColorAttributes type) { //Intensity, Foreground, Saturation and Value are from 0 to 100 //Hue is from 0 to 360 switch (type) { case DatapickerImage::None: return 0; case DatapickerImage::Intensity: return 100; case DatapickerImage::Foreground: return 100; case DatapickerImage::Hue: return 360; case DatapickerImage::Saturation: return 100; case DatapickerImage::Value: default: return 100; } } bool ImageEditor::colorCompare(QRgb color1, QRgb color2) { const long MASK = 0xf0f0f0f0; return (color1 & MASK) == (color2 & MASK); } int ImageEditor::discretizeHue(int x, int y, const QImage* originalImage) { const QColor color(originalImage->pixel(x,y)); const int h = color.hue(); int value = h * maxHue / 359; if (value<0) //QColor::hue() can return -1 value = 0; if (maxHue < value) value = maxHue; return value; } int ImageEditor::discretizeSaturation(int x, int y, const QImage* originalImage) { const QColor color(originalImage->pixel(x,y)); const int s = color.saturation(); int value = s * maxSaturation / 255; if (maxSaturation < value) value = maxSaturation; return value; } int ImageEditor::discretizeValue(int x, int y, const QImage* originalImage) { const QColor color(originalImage->pixel(x,y)); const int v = color.value(); int value = v * maxValue / 255; if (maxValue < value) value = maxValue; return value; } int ImageEditor::discretizeIntensity(int x, int y, const QImage* originalImage) { const QRgb color = originalImage->pixel(x,y); const int r = qRed(color); const int g = qGreen(color); const int b = qBlue(color); const double intensity = sqrt ((double) (r * r + g * g + b * b)); int value = (int) (intensity * maxIntensity / sqrt((double) (255 * 255 + 255 * 255 + 255 * 255)) + 0.5); if (maxIntensity < value) value = maxIntensity; return value; } int ImageEditor::discretizeForeground(int x, int y, const QColor background, const QImage* originalImage) { const QRgb color = originalImage->pixel(x,y); const int r = qRed(color); const int g = qGreen(color); const int b = qBlue(color); const int rBg = background.red(); const int gBg = background.green(); const int bBg = background.blue(); const double distance = sqrt ((double) ((r - rBg) * (r - rBg) + (g - gBg) * (g - gBg) + (b - bBg) * (b - bBg))); int value = (int) (distance * maxForeground / sqrt((double) (255 * 255 + 255 * 255 + 255 * 255)) + 0.5); if (maxForeground < value) value = maxForeground; return value; } int ImageEditor::discretizeValueForeground(int x, int y, DatapickerImage::ColorAttributes type, const QColor background, const QImage* originalImage) { const QColor color(originalImage->pixel(x,y)); // convert hue from 0 to 359, saturation from 0 to 255, value from 0 to 255 int value = 0; switch (type) { case DatapickerImage::None: break; case DatapickerImage::Intensity: { const int r = color.red(); const int g = color.green(); const int b = color.blue(); const double intensity = sqrt ((double) (r * r + g * g + b * b)); value = (int) (intensity * maxIntensity / sqrt((double) (255 * 255 + 255 * 255 + 255 * 255)) + 0.5); if (maxIntensity < value) value = maxIntensity; break; } case DatapickerImage::Foreground: { const int r = color.red(); const int g = color.green(); const int b = color.blue(); const int rBg = background.red(); const int gBg = background.green(); const int bBg = background.blue(); const double distance = sqrt ((double) ((r - rBg) * (r - rBg) + (g - gBg) * (g - gBg) + (b - bBg) * (b - bBg))); value = (int) (distance * maxForeground / sqrt((double) (255 * 255 + 255 * 255 + 255 * 255)) + 0.5); if (maxForeground < value) value = maxForeground; break; } case DatapickerImage::Hue: { const int h = color.hue(); value = h * maxHue / 359; if (value<0) value = 0; if (maxHue < value) value = maxHue; break; } case DatapickerImage::Saturation: { const int s = color.saturation(); value = s * maxSaturation / 255; if (maxSaturation < value) value = maxSaturation; break; } case DatapickerImage::Value: { const int v = color.value(); value = v * maxValue / 255; if (maxValue < value) value = maxValue; break; } } return value; } bool ImageEditor::pixelIsOn(int value, int low, int high) { if (low < high) return ((low <= value) && (value <= high)); else return ((low <= value) || (value <= high)); } bool ImageEditor::pixelIsOn( int value, DatapickerImage::ColorAttributes type,DatapickerImage::EditorSettings settings ) { switch (type) { case DatapickerImage::None: break; case DatapickerImage::Intensity: return pixelIsOn(value, settings.intensityThresholdLow, settings.intensityThresholdHigh); case DatapickerImage::Foreground: return pixelIsOn(value, settings.foregroundThresholdLow, settings.foregroundThresholdHigh); case DatapickerImage::Hue: return pixelIsOn(value, settings.hueThresholdLow, settings.hueThresholdHigh); case DatapickerImage::Saturation: return pixelIsOn(value, settings.saturationThresholdLow, settings.saturationThresholdHigh); case DatapickerImage::Value: return pixelIsOn(value, settings.valueThresholdLow, settings.valueThresholdHigh); } return false; } diff --git a/src/backend/datapicker/SegmentPrivate.h b/src/backend/datapicker/SegmentPrivate.h index b43c1e0ea..4b9b7c81c 100644 --- a/src/backend/datapicker/SegmentPrivate.h +++ b/src/backend/datapicker/SegmentPrivate.h @@ -1,58 +1,58 @@ /*************************************************************************** File : SegmentPrivate.h Project : LabPlot -------------------------------------------------------------------- Copyright : (C) 2015 by Ankit Wagadre (wagadre.ankit@gmail.com) ***************************************************************************/ /*************************************************************************** * * * 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 SEGMENTPRIVATE_H #define SEGMENTPRIVATE_H #include class SegmentPrivate: public QGraphicsItem { public: explicit SegmentPrivate(Segment*); void retransform(); virtual void recalcShapeAndBoundingRect(); double scaleFactor; bool m_hovered; QPainterPath linePath; QRectF boundingRectangle; QRectF transformedBoundingRectangle; QPainterPath itemShape; - virtual QRectF boundingRect() const; - virtual QPainterPath shape() const; - virtual void paint(QPainter*, const QStyleOptionGraphicsItem*, QWidget* widget = 0); + QRectF boundingRect() const override; + QPainterPath shape() const override; + void paint(QPainter*, const QStyleOptionGraphicsItem*, QWidget* widget = 0) override; Segment* const q; private: - virtual void hoverEnterEvent(QGraphicsSceneHoverEvent*); - virtual void hoverLeaveEvent(QGraphicsSceneHoverEvent*); - virtual QVariant itemChange(GraphicsItemChange change, const QVariant &value); + void hoverEnterEvent(QGraphicsSceneHoverEvent*) override; + void hoverLeaveEvent(QGraphicsSceneHoverEvent*) override; + QVariant itemChange(GraphicsItemChange change, const QVariant &value) override; }; #endif diff --git a/src/backend/datasources/AbstractDataSource.h b/src/backend/datasources/AbstractDataSource.h index a5757c930..9654631b5 100644 --- a/src/backend/datasources/AbstractDataSource.h +++ b/src/backend/datasources/AbstractDataSource.h @@ -1,53 +1,53 @@ /*************************************************************************** File : AbstractDataSource.h Project : LabPlot Description : Interface for data sources -------------------------------------------------------------------- Copyright : (C) 2009-2017 Alexander Semke (alexander.semke@web.de) Copyright : (C) 2015 Stefan Gerlach (stefan.gerlach@uni.kn) ***************************************************************************/ /*************************************************************************** * * * 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 ABSTRACTDATASOURCE_H #define ABSTRACTDATASOURCE_H #include "backend/core/AbstractPart.h" #include "backend/core/AbstractScriptingEngine.h" #include "backend/datasources/filters/AbstractFileFilter.h" #include "backend/core/AbstractColumn.h" #include class QStringList; class AbstractDataSource : public AbstractPart, public scripted { Q_OBJECT public: AbstractDataSource(AbstractScriptingEngine *engine, const QString& name); - virtual ~AbstractDataSource() {} + ~AbstractDataSource() override {} void clear(); virtual int prepareImport(QVector& dataContainer, AbstractFileFilter::ImportMode, int actualRows, int actualCols, QStringList colNameList = QStringList(), QVector = QVector()) = 0; virtual void finalizeImport(int columnOffset = 0, int startColumn = 0, int endColumn = 0, const QString& dateTimeFormat = QString(), AbstractFileFilter::ImportMode importMode = AbstractFileFilter::Replace) = 0; }; #endif // ABSTRACTDATASOURCE_H diff --git a/src/backend/datasources/LiveDataSource.h b/src/backend/datasources/LiveDataSource.h index 90d3fdec8..792a0ba28 100644 --- a/src/backend/datasources/LiveDataSource.h +++ b/src/backend/datasources/LiveDataSource.h @@ -1,211 +1,211 @@ /*************************************************************************** File : LiveDataSource.h Project : LabPlot Description : File data source -------------------------------------------------------------------- Copyright : (C) 2012-2013 Alexander Semke (alexander.semke@web.de) Copyright : (C) 2017 Fabian Kristof (fkristofszabolcs@gmail.com) ***************************************************************************/ /*************************************************************************** * * * 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 LIVEDATASOURCE_H #define LIVEDATASOURCE_H #include "backend/spreadsheet/Spreadsheet.h" #include "backend/matrix/Matrix.h" #include #include #include class QString; class AbstractFileFilter; class QFileSystemWatcher; class QAction; class QTcpSocket; class QUdpSocket; class QFile; class LiveDataSource : public Spreadsheet { Q_OBJECT Q_ENUMS(FileType) public: enum FileType {Ascii, Binary, Image, HDF, NETCDF, FITS}; enum SourceType { FileOrPipe = 0, NetworkTcpSocket, NetworkUdpSocket, LocalSocket, SerialPort }; enum UpdateType { TimeInterval = 0, NewData }; enum ReadingType { ContinousFixed = 0, FromEnd, TillEnd }; LiveDataSource(AbstractScriptingEngine*, const QString& name, bool loading = false); - ~LiveDataSource(); + ~LiveDataSource() override; void ready(); static QStringList supportedBaudRates(); static QStringList availablePorts(); static QStringList fileTypes(); static QString fileInfoString(const QString&); void setFileType(const FileType); FileType fileType() const; UpdateType updateType() const; void setUpdateType(UpdateType); SourceType sourceType() const; void setSourceType(SourceType); ReadingType readingType() const; void setReadingType(ReadingType); int sampleRate() const; void setSampleRate(int); void setBytesRead(qint64 bytes); int bytesRead() const; int port() const; void setPort(quint16); bool isPaused() const; void setSerialPort(const QString& name); QString serialPortName() const; QString host() const; void setHost(const QString&); int baudRate() const; void setBaudRate(int); void setUpdateInterval(int); int updateInterval() const; void setKeepNvalues(int); int keepNvalues() const; void setKeepLastValues(bool); bool keepLastValues() const; void setFileWatched(bool); bool isFileWatched() const; void setFileLinked(bool); bool isFileLinked() const; void setFileName(const QString&); QString fileName() const; void setLocalSocketName(const QString&); QString localSocketName() const; void updateNow(); void pauseReading(); void continueReading(); void setFilter(AbstractFileFilter*); AbstractFileFilter* filter() const; - virtual QIcon icon() const override; - virtual QMenu* createContextMenu() override; - virtual QWidget* view() const override; + QIcon icon() const override; + QMenu* createContextMenu() override; + QWidget* view() const override; - virtual void save(QXmlStreamWriter*) const override; - virtual bool load(XmlStreamReader*, bool preview) override; + void save(QXmlStreamWriter*) const override; + bool load(XmlStreamReader*, bool preview) override; private: void initActions(); void watch(); QString m_fileName; QString m_serialPortName; QString m_localSocketName; QString m_host; FileType m_fileType; UpdateType m_updateType; SourceType m_sourceType; ReadingType m_readingType; bool m_fileWatched; bool m_fileLinked; bool m_paused; bool m_prepared; bool m_keepLastValues; int m_sampleRate; int m_keepNvalues; int m_updateInterval; quint16 m_port; int m_baudRate; qint64 m_bytesRead; AbstractFileFilter* m_filter; QTimer* m_updateTimer; QFileSystemWatcher* m_fileSystemWatcher; QFile* m_file; QLocalSocket* m_localSocket; QTcpSocket* m_tcpSocket; QUdpSocket* m_udpSocket; QSerialPort* m_serialPort; QIODevice* m_device; QAction* m_reloadAction; QAction* m_toggleLinkAction; QAction* m_showEditorAction; QAction* m_showSpreadsheetAction; QAction* m_plotDataAction; public slots: void read(); private slots: void watchToggled(); void linkToggled(); void plotData(); void readyRead(); void localSocketError(QLocalSocket::LocalSocketError); void tcpSocketError(QAbstractSocket::SocketError); void serialPortError(QSerialPort::SerialPortError); }; #endif diff --git a/src/backend/datasources/filters/AbstractFileFilter.h b/src/backend/datasources/filters/AbstractFileFilter.h index ce4317c83..5ac4b44e8 100644 --- a/src/backend/datasources/filters/AbstractFileFilter.h +++ b/src/backend/datasources/filters/AbstractFileFilter.h @@ -1,69 +1,69 @@ /*************************************************************************** File : AbstractFileFilter.h Project : LabPlot Description : file I/O-filter related interface -------------------------------------------------------------------- Copyright : (C) 2009-2013 Alexander Semke (alexander.semke@web.de) Copyright : (C) 2017 Stefan Gerlach (stefan.gerlach@uni.kn) ***************************************************************************/ /*************************************************************************** * * * 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 ABSTRACTFILEFILTER_H #define ABSTRACTFILEFILTER_H #include "backend/core/AbstractColumn.h" #include #include #include // smart pointer class AbstractDataSource; class XmlStreamReader; class QXmlStreamWriter; class AbstractFileFilter : public QObject { Q_OBJECT Q_ENUMS(ImportMode); public: enum ImportMode {Append, Prepend, Replace}; AbstractFileFilter() {} - virtual ~AbstractFileFilter() {} + ~AbstractFileFilter() override {} static bool isNan(QString); static AbstractColumn::ColumnMode columnMode(const QString& valueString, const QString& dateTimeFormat, QLocale::Language); static QStringList numberFormats(); virtual QVector readDataFromFile(const QString& fileName, AbstractDataSource* = nullptr, ImportMode = AbstractFileFilter::Replace, int lines = -1) = 0; virtual void write(const QString& fileName, AbstractDataSource*) = 0; virtual void loadFilterSettings(const QString& filterName) = 0; virtual void saveFilterSettings(const QString& filterName) const = 0; virtual void save(QXmlStreamWriter*) const = 0; virtual bool load(XmlStreamReader*) = 0; signals: void completed(int) const; //!< int ranging from 0 to 100 notifies about the status of a read/write process }; #endif diff --git a/src/backend/datasources/filters/AsciiFilter.h b/src/backend/datasources/filters/AsciiFilter.h index f0d988c4e..e4ea4d4a9 100644 --- a/src/backend/datasources/filters/AsciiFilter.h +++ b/src/backend/datasources/filters/AsciiFilter.h @@ -1,115 +1,115 @@ /*************************************************************************** File : AsciiFilter.h Project : LabPlot Description : ASCII I/O-filter -------------------------------------------------------------------- Copyright : (C) 2009-2013 Alexander Semke (alexander.semke@web.de) Copyright : (C) 2017 Stefan Gerlach (stefan.gerlach@uni.kn) ***************************************************************************/ /*************************************************************************** * * * 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 ASCIIFILTER_H #define ASCIIFILTER_H #include "backend/datasources/filters/AbstractFileFilter.h" #include "backend/core/AbstractColumn.h" class QStringList; class QIODevice; class AsciiFilterPrivate; class QAbstractSocket; class AsciiFilter : public AbstractFileFilter { Q_OBJECT public: AsciiFilter(); - ~AsciiFilter(); + ~AsciiFilter() override; static QStringList separatorCharacters(); static QStringList commentCharacters(); static QStringList dataTypes(); static QStringList predefinedFilters(); static int columnNumber(const QString& fileName, const QString& separator = QString()); static size_t lineNumber(const QString& fileName); static size_t lineNumber(QIODevice&); // calculate number of lines if device supports it // read data from any device void readDataFromDevice(QIODevice& device, AbstractDataSource*, AbstractFileFilter::ImportMode = AbstractFileFilter::Replace, int lines = -1); void readFromLiveDeviceNotFile(QIODevice& device, AbstractDataSource*dataSource); qint64 readFromLiveDevice(QIODevice& device, AbstractDataSource*, qint64 from = -1); // overloaded function to read from file QVector readDataFromFile(const QString& fileName, AbstractDataSource* = nullptr, - AbstractFileFilter::ImportMode = AbstractFileFilter::Replace, int lines = -1); - void write(const QString& fileName, AbstractDataSource*); + AbstractFileFilter::ImportMode = AbstractFileFilter::Replace, int lines = -1) override; + void write(const QString& fileName, AbstractDataSource*) override; QVector preview(const QString& fileName, int lines); QVector preview(QIODevice& device); - void loadFilterSettings(const QString&); - void saveFilterSettings(const QString&) const; + void loadFilterSettings(const QString&) override; + void saveFilterSettings(const QString&) const override; void setCommentCharacter(const QString&); QString commentCharacter() const; void setSeparatingCharacter(const QString&); QString separatingCharacter() const; void setDateTimeFormat(const QString&); QString dateTimeFormat() const; void setNumberFormat(QLocale::Language); QLocale::Language numberFormat() const; void setAutoModeEnabled(const bool); bool isAutoModeEnabled() const; void setHeaderEnabled(const bool); bool isHeaderEnabled() const; void setSkipEmptyParts(const bool); bool skipEmptyParts() const; void setSimplifyWhitespacesEnabled(const bool); bool simplifyWhitespacesEnabled() const; void setNaNValueToZero(const bool); bool NaNValueToZeroEnabled() const; void setRemoveQuotesEnabled(const bool); bool removeQuotesEnabled() const; void setCreateIndexEnabled(const bool); void setVectorNames(const QString); QStringList vectorNames() const; QVector columnModes(); void setStartRow(const int); int startRow() const; void setEndRow(const int); int endRow() const; void setStartColumn(const int); int startColumn() const; void setEndColumn(const int); int endColumn() const; - virtual void save(QXmlStreamWriter*) const; - virtual bool load(XmlStreamReader*); + void save(QXmlStreamWriter*) const override; + bool load(XmlStreamReader*) override; private: std::unique_ptr const d; friend class AsciiFilterPrivate; }; #endif diff --git a/src/backend/datasources/filters/BinaryFilter.h b/src/backend/datasources/filters/BinaryFilter.h index 9ed1b7a9c..0be8b1855 100644 --- a/src/backend/datasources/filters/BinaryFilter.h +++ b/src/backend/datasources/filters/BinaryFilter.h @@ -1,93 +1,93 @@ /*************************************************************************** File : BinaryFilter.h Project : LabPlot Description : Binary I/O-filter -------------------------------------------------------------------- Copyright : (C) 2015-2017 Stefan Gerlach (stefan.gerlach@uni.kn) ***************************************************************************/ /*************************************************************************** * * * 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 BINARYFILTER_H #define BINARYFILTER_H #include "backend/datasources/filters/AbstractFileFilter.h" class BinaryFilterPrivate; class QStringList; class QIODevice; class BinaryFilter : public AbstractFileFilter { Q_OBJECT Q_ENUMS(DataType) Q_ENUMS(ByteOrder) public: //TODO; use ColumnMode? enum DataType {INT8, INT16, INT32, INT64, UINT8, UINT16, UINT32, UINT64, REAL32, REAL64}; enum ByteOrder {LittleEndian, BigEndian}; BinaryFilter(); - ~BinaryFilter(); + ~BinaryFilter() override; static QStringList dataTypes(); static QStringList byteOrders(); static int dataSize(BinaryFilter::DataType); static size_t rowNumber(const QString& fileName, const size_t vectors, const BinaryFilter::DataType); // read data from any device void readDataFromDevice(QIODevice&, AbstractDataSource* = nullptr, AbstractFileFilter::ImportMode = AbstractFileFilter::Replace, int lines = -1); QVector readDataFromFile(const QString& fileName, AbstractDataSource*, - AbstractFileFilter::ImportMode = AbstractFileFilter::Replace, int lines = -1); - void write(const QString& fileName, AbstractDataSource*); + AbstractFileFilter::ImportMode = AbstractFileFilter::Replace, int lines = -1) override; + void write(const QString& fileName, AbstractDataSource*) override; QVector preview(const QString& fileName, int lines); - void loadFilterSettings(const QString&); - void saveFilterSettings(const QString&) const; + void loadFilterSettings(const QString&) override; + void saveFilterSettings(const QString&) const override; void setVectors(const size_t); size_t vectors() const; void setDataType(const BinaryFilter::DataType); BinaryFilter::DataType dataType() const; void setByteOrder(const BinaryFilter::ByteOrder); BinaryFilter::ByteOrder byteOrder() const; void setSkipStartBytes(const size_t); size_t skipStartBytes() const; void setStartRow(const int); int startRow() const; void setEndRow(const int); int endRow() const; void setSkipBytes(const size_t); size_t skipBytes() const; void setCreateIndexEnabled(const bool); void setAutoModeEnabled(const bool); bool isAutoModeEnabled() const; - virtual void save(QXmlStreamWriter*) const; - virtual bool load(XmlStreamReader*); + void save(QXmlStreamWriter*) const override; + bool load(XmlStreamReader*) override; private: std::unique_ptr const d; friend class BinaryFilterPrivate; }; #endif diff --git a/src/backend/datasources/filters/FITSFilter.h b/src/backend/datasources/filters/FITSFilter.h index 1f5a1eaee..524849c6d 100644 --- a/src/backend/datasources/filters/FITSFilter.h +++ b/src/backend/datasources/filters/FITSFilter.h @@ -1,119 +1,119 @@ /*************************************************************************** File : FITSFilter.h Project : LabPlot Description : FITS I/O-filter -------------------------------------------------------------------- Copyright : (C) 2016 by Fabian Kristof (fkristofszabolcs@gmail.com) ***************************************************************************/ /*************************************************************************** * * * 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 FITSFILTER_H #define FITSFILTER_H #include "backend/datasources/filters/AbstractFileFilter.h" #include #include #include #include #include class FITSFilterPrivate; class FITSHeaderEditWidget; class FITSFilter : public AbstractFileFilter { Q_OBJECT public: FITSFilter(); - ~FITSFilter(); + ~FITSFilter() override; QVector readDataFromFile(const QString& fileName, AbstractDataSource* = nullptr, - AbstractFileFilter::ImportMode = AbstractFileFilter::Replace, int lines = -1); - void write(const QString& fileName, AbstractDataSource*); + AbstractFileFilter::ImportMode = AbstractFileFilter::Replace, int lines = -1) override; + void write(const QString& fileName, AbstractDataSource*) override; QVector readChdu(const QString& fileName, bool *okToMatrix = nullptr, int lines = -1); - virtual void save(QXmlStreamWriter*) const; - virtual bool load(XmlStreamReader*); + void save(QXmlStreamWriter*) const override; + bool load(XmlStreamReader*) override; struct KeywordUpdate { KeywordUpdate() : keyUpdated(false), valueUpdated(false), commentUpdated(false), unitUpdated(false) {} bool keyUpdated; bool valueUpdated; bool commentUpdated; bool unitUpdated; }; struct Keyword { Keyword(const QString& key, const QString& value, const QString& comment): key(key), value(value), comment(comment) {} Keyword() {} QString key; QString value; QString comment; QString unit; bool operator==(const Keyword& other) const { return other.key == key && other.value == value && other.comment == comment; } bool isEmpty() const { return key.isEmpty() && value.isEmpty() && comment.isEmpty(); } KeywordUpdate updates; }; static int imagesCount(const QString& fileName); static int tablesCount(const QString& fileName); void updateKeywords(const QString& fileName, const QList& originals, const QVector& updates); void addNewKeyword(const QString& filename, const QList& keywords); void addKeywordUnit(const QString& fileName, const QList& keywords); void deleteKeyword(const QString& fileName, const QList& keywords); void removeExtensions(const QStringList& extensions); void parseHeader(const QString &fileName, QTableWidget* headerEditTable, bool readKeys = true, const QList &keys = QList()); void parseExtensions(const QString& fileName, QTreeWidget* tw, bool checkPrimary = false); QList chduKeywords(const QString &fileName); static QStringList standardKeywords(); static QStringList mandatoryImageExtensionKeywords(); static QStringList mandatoryTableExtensionKeywords(); static QStringList units(); - void loadFilterSettings(const QString&); - void saveFilterSettings(const QString&) const; + void loadFilterSettings(const QString&) override; + void saveFilterSettings(const QString&) const override; void setStartRow(const int); int startRow() const; void setEndRow(const int); int endRow() const; void setStartColumn(const int); int startColumn() const; void setEndColumn(const int); int endColumn() const; void setCommentsAsUnits(const bool); void setExportTo(const int); private: std::unique_ptr const d; friend class FITSFilterPrivate; }; #endif // FITSFILTER_H diff --git a/src/backend/datasources/filters/HDFFilter.h b/src/backend/datasources/filters/HDFFilter.h index 3325a7940..c2ee6dfee 100644 --- a/src/backend/datasources/filters/HDFFilter.h +++ b/src/backend/datasources/filters/HDFFilter.h @@ -1,73 +1,73 @@ /*************************************************************************** File : HDFFilter.h Project : LabPlot Description : HDF I/O-filter -------------------------------------------------------------------- Copyright : (C) 2015-2017 Stefan Gerlach (stefan.gerlach@uni.kn) ***************************************************************************/ /*************************************************************************** * * * 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 HDFFILTER_H #define HDFFILTER_H #include "backend/datasources/filters/AbstractFileFilter.h" #include class QTreeWidgetItem; class HDFFilterPrivate; class HDFFilter : public AbstractFileFilter { Q_OBJECT public: HDFFilter(); - ~HDFFilter(); + ~HDFFilter() override; void parse(const QString& fileName, QTreeWidgetItem* rootItem); QVector readDataFromFile(const QString& fileName, AbstractDataSource* = nullptr, - AbstractFileFilter::ImportMode = AbstractFileFilter::Replace, int lines = -1); + AbstractFileFilter::ImportMode = AbstractFileFilter::Replace, int lines = -1) override; QVector readCurrentDataSet(const QString& fileName, AbstractDataSource*, bool& ok, AbstractFileFilter::ImportMode = AbstractFileFilter::Replace, int lines = -1); - void write(const QString& fileName, AbstractDataSource*); + void write(const QString& fileName, AbstractDataSource*) override; - void loadFilterSettings(const QString&); - void saveFilterSettings(const QString&) const; + void loadFilterSettings(const QString&) override; + void saveFilterSettings(const QString&) const override; void setCurrentDataSetName(const QString); const QString currentDataSetName() const; void setStartRow(const int); int startRow() const; void setEndRow(const int); int endRow() const; void setStartColumn(const int); int startColumn() const; void setEndColumn(const int); int endColumn() const; - virtual void save(QXmlStreamWriter*) const; - virtual bool load(XmlStreamReader*); + void save(QXmlStreamWriter*) const override; + bool load(XmlStreamReader*) override; private: std::unique_ptr const d; friend class HDFFilterPrivate; }; #endif diff --git a/src/backend/datasources/filters/ImageFilter.h b/src/backend/datasources/filters/ImageFilter.h index 57d28ef35..54cde00e5 100644 --- a/src/backend/datasources/filters/ImageFilter.h +++ b/src/backend/datasources/filters/ImageFilter.h @@ -1,74 +1,74 @@ /*************************************************************************** File : ImageFilter.h Project : LabPlot Description : Image I/O-filter -------------------------------------------------------------------- Copyright : (C) 2015 Stefan Gerlach (stefan.gerlach@uni.kn) ***************************************************************************/ /*************************************************************************** * * * 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 IMAGEFILTER_H #define IMAGEFILTER_H #include "backend/datasources/filters/AbstractFileFilter.h" class ImageFilterPrivate; class QStringList; class ImageFilter : public AbstractFileFilter { Q_OBJECT Q_ENUMS(ImportFormat) public: enum ImportFormat {MATRIX,XYZ,XYRGB}; ImageFilter(); - ~ImageFilter(); + ~ImageFilter() override; static QStringList importFormats(); QVector readDataFromFile(const QString& fileName, AbstractDataSource* = nullptr, - AbstractFileFilter::ImportMode = AbstractFileFilter::Replace, int lines = -1); - void write(const QString& fileName, AbstractDataSource*); + AbstractFileFilter::ImportMode = AbstractFileFilter::Replace, int lines = -1) override; + void write(const QString& fileName, AbstractDataSource*) override; - void loadFilterSettings(const QString&); - void saveFilterSettings(const QString&) const; + void loadFilterSettings(const QString&) override; + void saveFilterSettings(const QString&) const override; void setImportFormat(const ImageFilter::ImportFormat); ImageFilter::ImportFormat importFormat() const; void setStartRow(const int); int startRow() const; void setEndRow(const int); int endRow() const; void setStartColumn(const int); int startColumn() const; void setEndColumn(const int); int endColumn() const; - virtual void save(QXmlStreamWriter*) const; - virtual bool load(XmlStreamReader*); + void save(QXmlStreamWriter*) const override; + bool load(XmlStreamReader*) override; private: std::unique_ptr const d; friend class ImageFilterPrivate; }; #endif diff --git a/src/backend/datasources/filters/NetCDFFilter.h b/src/backend/datasources/filters/NetCDFFilter.h index 9048d2072..03ebff7d4 100644 --- a/src/backend/datasources/filters/NetCDFFilter.h +++ b/src/backend/datasources/filters/NetCDFFilter.h @@ -1,73 +1,73 @@ /*************************************************************************** File : NetCDFFilter.h Project : LabPlot Description : NetCDF I/O-filter -------------------------------------------------------------------- Copyright : (C) 2015 Stefan Gerlach (stefan.gerlach@uni.kn) ***************************************************************************/ /*************************************************************************** * * * 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 NETCDFFILTER_H #define NETCDFFILTER_H #include "backend/datasources/filters/AbstractFileFilter.h" #include #include class NetCDFFilterPrivate; class NetCDFFilter : public AbstractFileFilter { Q_OBJECT public: NetCDFFilter(); - ~NetCDFFilter(); + ~NetCDFFilter() override; void parse(const QString& fileName, QTreeWidgetItem* rootItem); QVector readDataFromFile(const QString& fileName, AbstractDataSource* = nullptr, - AbstractFileFilter::ImportMode = AbstractFileFilter::Replace, int lines = -1); + AbstractFileFilter::ImportMode = AbstractFileFilter::Replace, int lines = -1) override; QString readAttribute(const QString & fileName, const QString & name, const QString & varName); QVector readCurrentVar(const QString& fileName, AbstractDataSource* = nullptr, AbstractFileFilter::ImportMode = AbstractFileFilter::Replace, int lines = -1); - void write(const QString& fileName, AbstractDataSource*); + void write(const QString& fileName, AbstractDataSource*) override; - void loadFilterSettings(const QString&); - void saveFilterSettings(const QString&) const; + void loadFilterSettings(const QString&) override; + void saveFilterSettings(const QString&) const override; void setCurrentVarName(const QString); const QString currentVarName() const; void setStartRow(const int); int startRow() const; void setEndRow(const int); int endRow() const; void setStartColumn(const int); int startColumn() const; void setEndColumn(const int); int endColumn() const; - virtual void save(QXmlStreamWriter*) const; - virtual bool load(XmlStreamReader*); + void save(QXmlStreamWriter*) const override; + bool load(XmlStreamReader*) override; private: std::unique_ptr const d; friend class NetCDFFilterPrivate; }; #endif diff --git a/src/backend/datasources/projects/LabPlotProjectParser.h b/src/backend/datasources/projects/LabPlotProjectParser.h index f21855809..d4bfe5b2a 100644 --- a/src/backend/datasources/projects/LabPlotProjectParser.h +++ b/src/backend/datasources/projects/LabPlotProjectParser.h @@ -1,44 +1,44 @@ /*************************************************************************** File : LabPlotProjectParser.h Project : LabPlot Description : parser for LabPlot projects -------------------------------------------------------------------- Copyright : (C) 2017 Alexander Semke (alexander.semke@web.de) ***************************************************************************/ /*************************************************************************** * * * 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 LABPLOTPROJECTPARSER_H #define LABPLOTPROJECTPARSER_H #include "backend/datasources/projects/ProjectParser.h" class LabPlotProjectParser : public ProjectParser { Q_OBJECT public: LabPlotProjectParser(); - virtual ~LabPlotProjectParser() override; + ~LabPlotProjectParser() override; - virtual QAbstractItemModel* model() override; - virtual void importTo(Folder*, const QStringList&) override; + QAbstractItemModel* model() override; + void importTo(Folder*, const QStringList&) override; }; #endif // LABPLOTPROJECTPARSER_H diff --git a/src/backend/datasources/projects/OriginProjectParser.h b/src/backend/datasources/projects/OriginProjectParser.h index b85b6ff09..74443c22b 100644 --- a/src/backend/datasources/projects/OriginProjectParser.h +++ b/src/backend/datasources/projects/OriginProjectParser.h @@ -1,43 +1,43 @@ /*************************************************************************** File : OriginProjectParser.h Project : LabPlot Description : parser for Origin projects -------------------------------------------------------------------- Copyright : (C) 2017 Alexander Semke (alexander.semke@web.de) ***************************************************************************/ /*************************************************************************** * * * 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 ORIGINPROJECTPARSER_H #define ORIGINPROJECTPARSER_H #include "backend/datasources/projects/ProjectParser.h" class OriginProjectParser : public ProjectParser { Q_OBJECT public: OriginProjectParser(); - virtual QAbstractItemModel* model() override; - virtual void importTo(Folder*, const QStringList&) override; + QAbstractItemModel* model() override; + void importTo(Folder*, const QStringList&) override; }; #endif // ORIGINPROJECTPARSER_H diff --git a/src/backend/datasources/projects/ProjectParser.h b/src/backend/datasources/projects/ProjectParser.h index 96771e3b3..78a0618e3 100644 --- a/src/backend/datasources/projects/ProjectParser.h +++ b/src/backend/datasources/projects/ProjectParser.h @@ -1,62 +1,62 @@ /*************************************************************************** File : ProjectParser.h Project : LabPlot Description : base class for project parsers -------------------------------------------------------------------- Copyright : (C) 2017 Alexander Semke (alexander.semke@web.de) ***************************************************************************/ /*************************************************************************** * * * 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 PROJECTPARSER_H #define PROJECTPARSER_H #include class QAbstractItemModel; class QString; class Folder; class Project; class ProjectParser : public QObject { Q_OBJECT public: ProjectParser(); - virtual ~ProjectParser() {}; + ~ProjectParser() override {}; void setProjectFileName(const QString&); const QString& projectFileName() const; virtual QAbstractItemModel* model() = 0; virtual void importTo(Folder*, const QStringList&) = 0; QList topLevelClasses() const ; protected: QString m_projectFileName; Project* m_project; QList m_topLevelClasses; signals: void completed(int); }; #endif // PROJECTPARSER_H diff --git a/src/backend/lib/Interval.h b/src/backend/lib/Interval.h index 93b78203d..c86803515 100644 --- a/src/backend/lib/Interval.h +++ b/src/backend/lib/Interval.h @@ -1,270 +1,270 @@ /*************************************************************************** File : Interval.h Project : LabPlot -------------------------------------------------------------------- Copyright : (C) 2007 by Tilman Benkert (thzs@gmx.net) Copyright : (C) 2007 by Knut Franke (knut.franke@gmx.de) Copyright : (C) 2012 by Alexander Semke (alexander.semke@web.de) Description : Auxiliary class for interval based data ***************************************************************************/ /*************************************************************************** * * * 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 INTERVAL_H #define INTERVAL_H #include "backend/worksheet/plots/AbstractCoordinateSystem.h" template class Interval; template class IntervalBase { public: IntervalBase() : m_start(-1), m_end(-1){} IntervalBase(const IntervalBase& other) { m_start = other.start(); m_end = other.end(); } IntervalBase(T start, T end) { m_start = start; m_end = end; } virtual ~IntervalBase() {} T start() const { return m_start; } T end() const { return m_end; } void setStart(T start) { m_start = start; } void setEnd(T end) { m_end = end; } bool contains(const Interval& other) const { return ( m_start <= other.start() && m_end >= other.end() ); } bool contains(T value) const { return ( m_start <= value && m_end >= value ); } bool fuzzyContains(T value) const { bool rc1 = AbstractCoordinateSystem::definitelyLessThan(m_start, value); bool rc2 = AbstractCoordinateSystem::definitelyGreaterThan(m_end, value); return (rc1 && rc2); } bool intersects(const Interval& other) const { return ( contains(other.start()) || contains(other.end()) ); } //! Return the intersection of two intervals /** * This function returns an invalid interval if the two intervals do not intersect. */ static Interval intersection(const Interval& first, const Interval& second) { return Interval( qMax(first.start(), second.start()), qMin(first.end(), second.end()) ); } void translate(T offset) { m_start += offset; m_end += offset; } bool operator==(const Interval& other) const { return ( m_start == other.start() && m_end == other.end() ); } Interval& operator=(const Interval& other) { m_start = other.start(); m_end = other.end(); return *this; } //! Returns true if no gap is between two intervals. virtual bool touches(const Interval& other) const = 0; //! Merge two intervals that touch or intersect static Interval merge(const Interval& a, const Interval& b) { if( !(a.intersects(b) || a.touches(b)) ) return a; return Interval( qMin(a.start(), b.start()), qMax(a.end(), b.end()) ); } //! Subtract an interval from another static QList< Interval > subtract(const Interval& src_iv, const Interval& minus_iv) { QList< Interval > list; if( (src_iv == minus_iv) || (minus_iv.contains(src_iv)) ) return list; if( !src_iv.intersects(minus_iv) ) list.append(src_iv); else if( src_iv.end() <= minus_iv.end() ) list.append( Interval(src_iv.start(), minus_iv.start()-1) ); else if( src_iv.start() >= minus_iv.start() ) list.append( Interval(minus_iv.end()+1, src_iv.end()) ); else { list.append( Interval(src_iv.start(), minus_iv.start()-1) ); list.append( Interval(minus_iv.end()+1, src_iv.end()) ); } return list; } //! Split an interval into two static QList< Interval > split(const Interval& i, T before) { QList< Interval > list; if( before < i.start() || before > i.end() ) { list.append(i); } else { Interval left(i.start(), before-1); Interval right(before, i.end()); if(left.isValid()) list.append(left); if(right.isValid()) list.append(right); } return list; } //! Merge an interval into a list /* * This function merges all intervals in the list until none of them * intersect or touch anymore. */ static void mergeIntervalIntoList(QList< Interval > * list, Interval i) { for(int c=0; csize(); c++) { if( list->at(c).touches(i) || list->at(c).intersects(i) ) { Interval result = merge(list->takeAt(c), i); mergeIntervalIntoList(list, result); return; } } list->append(i); } //! Restrict all intervals in the list to their intersection with a given interval /** * Remark: This may decrease the list size. */ static void restrictList(QList< Interval > * list, Interval i) { Interval temp; for(int c=0; csize(); c++) { temp = intersection(list->at(c), i); if(!temp.isValid()) list->removeAt(c--); else list->replace(c, temp); } } //! Subtract an interval from all intervals in the list /** * Remark: This may increase or decrease the list size. */ static void subtractIntervalFromList(QList< Interval > * list, Interval i) { QList< Interval > temp_list; for(int c=0; csize(); c++) { temp_list = subtract(list->at(c), i); if(temp_list.isEmpty()) list->removeAt(c--); else { list->replace(c, temp_list.at(0)); if(temp_list.size()>1) list->insert(c, temp_list.at(1)); } } } QList< Interval > operator-(QList< Interval > subtrahend) { QList< Interval > *tmp1, *tmp2; tmp1 = new QList< Interval >(); *tmp1 << *static_cast< Interval* >(this); foreach(Interval i, subtrahend) { tmp2 = new QList< Interval >(); foreach(Interval j, *tmp1) *tmp2 << subtract(j, i); delete tmp1; tmp1 = tmp2; } QList< Interval > result = *tmp1; delete tmp1; return result; } //! Return a string in the format '[start,end]' QString toString() const { return "[" + QString::number(m_start) + "," + QString::number(m_end) + "]"; } protected: //! Interval start T m_start; //! Interval end T m_end; }; //! Auxiliary class for interval based data /** * This class represents an interval of * the type [start,end]. It should be pretty * self explanatory. * * For the template argument (T), only numerical types ((unsigned) short, (unsigned) int, * (unsigned) long, float, double, long double) are supported. */ template class Interval : public IntervalBase { public: Interval() {} Interval(T start, T end) : IntervalBase(start, end) {} Interval(const Interval& other) : IntervalBase(other) {} T size() const { return IntervalBase::m_end - IntervalBase::m_start + 1; } bool isValid() const { return ( IntervalBase::m_start >= 0 && IntervalBase::m_end >= 0 && IntervalBase::m_start <= IntervalBase::m_end ); } - bool touches(const Interval& other) const { + bool touches(const Interval& other) const override { return ( (other.end() == IntervalBase::m_start-1) || (other.start() == IntervalBase::m_end+1) ); } }; template<> class Interval : public IntervalBase { public: Interval() {} Interval(float start, float end) : IntervalBase(start, end) {} Interval(const Interval& other) : IntervalBase(other) {} float size() const { return IntervalBase::m_end - IntervalBase::m_start; } bool isValid() const { return ( IntervalBase::m_start <= IntervalBase::m_end ); } - bool touches(const Interval& other) const { + bool touches(const Interval& other) const override { return ( (other.end() == IntervalBase::m_start) || (other.start() == IntervalBase::m_end) ); } }; template<> class Interval : public IntervalBase { public: Interval() {} Interval(double start, double end) : IntervalBase(start, end) {} Interval(const Interval& other) : IntervalBase(other) {} double size() const { return IntervalBase::m_end - IntervalBase::m_start; } bool isValid() const { return ( IntervalBase::m_start <= IntervalBase::m_end ); } - bool touches(const Interval& other) const { + bool touches(const Interval& other) const override { return ( (other.end() == IntervalBase::m_start) || (other.start() == IntervalBase::m_end) ); } }; template<> class Interval : public IntervalBase { public: Interval() {} Interval(long double start, long double end) : IntervalBase(start, end) {} Interval(const Interval& other) : IntervalBase(other) {} long double size() const { return IntervalBase::m_end - IntervalBase::m_start; } bool isValid() const { return ( IntervalBase::m_start <= IntervalBase::m_end ); } - bool touches(const Interval& other) const { + bool touches(const Interval& other) const override { return ( (other.end() == IntervalBase::m_start) || (other.start() == IntervalBase::m_end) ); } }; #endif diff --git a/src/backend/lib/PropertyChangeCommand.h b/src/backend/lib/PropertyChangeCommand.h index 359e1d759..5a5591fa2 100644 --- a/src/backend/lib/PropertyChangeCommand.h +++ b/src/backend/lib/PropertyChangeCommand.h @@ -1,66 +1,66 @@ /*************************************************************************** File : PropertyChangeCommand.h Project : SciDAVis / LabPlot -------------------------------------------------------------------- Copyright : (C) 2010 Knut Franke Email (use @ for *) : Knut.Franke*gmx.net Description : Generic undo command changing a single variable. ***************************************************************************/ /*************************************************************************** * * * 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 PROPERTY_CHANGE_COMMAND_H #define PROPERTY_CHANGE_COMMAND_H #include /** * \class PropertyChangeCommand * \brief Generic undo command changing a single variable. * * Given a pointer to a variable (usually a member of the class instantiating the command, or of * its private implementation class) and a new value, assigns the value to the variable. A backup * of the old value is made, so that undo/redo can switch back and forth between the two values. * The value type needs to support copy construction and assignment. */ template class PropertyChangeCommand : public QUndoCommand { public: PropertyChangeCommand(const QString &text, T *property, const T &new_value) : m_property(property), m_other_value(new_value) { setText(text); } - virtual void redo() { + void redo() override { T tmp = *m_property; *m_property = m_other_value; m_other_value = tmp; } - virtual void undo() { redo(); } + void undo() override { redo(); } private: T *m_property; T m_other_value; }; #endif // ifndef PROPERTY_CHANGE_COMMAND_H diff --git a/src/backend/lib/SignallingUndoCommand.h b/src/backend/lib/SignallingUndoCommand.h index 31a900f46..b8341e91a 100644 --- a/src/backend/lib/SignallingUndoCommand.h +++ b/src/backend/lib/SignallingUndoCommand.h @@ -1,57 +1,57 @@ /*************************************************************************** File : SignallingUndoCommand.h Project : SciDAVis / LabPlot -------------------------------------------------------------------- Copyright : (C) 2010 Knut Franke Email (use @ for *) : Knut.Franke*gmx.net Description : An undo command calling a method/signal/slot on a QObject on redo/undo. ***************************************************************************/ /*************************************************************************** * * * 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 SIGNALLING_UNDO_COMMAND_H #define SIGNALLING_UNDO_COMMAND_H #include #include class SignallingUndoCommand : public QUndoCommand { public: SignallingUndoCommand(const QString &text, QObject *receiver, const char *redoMethod, const char *undoMethod, QGenericArgument val0 = QGenericArgument(), QGenericArgument val1 = QGenericArgument(), QGenericArgument val2 = QGenericArgument(), QGenericArgument val3 = QGenericArgument()); - ~SignallingUndoCommand(); + ~SignallingUndoCommand() override; - virtual void redo(); - virtual void undo(); + void redo() override; + void undo() override; private: QGenericArgument arg(int index); QByteArray m_redo, m_undo; QObject *m_receiver; int m_argument_count; int *m_argument_types; void **m_argument_data; }; #endif // ifndef SIGNALLING_UNDO_COMMAND_H diff --git a/src/backend/lib/commandtemplates.h b/src/backend/lib/commandtemplates.h index 39a35e647..26059b097 100644 --- a/src/backend/lib/commandtemplates.h +++ b/src/backend/lib/commandtemplates.h @@ -1,123 +1,123 @@ /*************************************************************************** File : commandtemplates.h Project : LabPlot Description : Undo/Redo command templates -------------------------------------------------------------------- Copyright : (C) 2009 Tilman Benkert (thzs@gmx.net) Copyright : (C) 2017 by Alexander Semke (alexander.semke@web.de) ***************************************************************************/ /*************************************************************************** * * * 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 COMMANDTEMPLATES_H #define COMMANDTEMPLATES_H #include template class StandardSetterCmd : public QUndoCommand { public: StandardSetterCmd(target_class* target, value_type target_class::* field, value_type newValue, const QString& description) // use i18n("%1: ...") for last arg : m_target(target), m_field(field), m_otherValue(newValue) { setText(description.arg(m_target->name())); } virtual void initialize() {}; virtual void finalize() {}; - virtual void redo() { + void redo() override { initialize(); value_type tmp = *m_target.*m_field; *m_target.*m_field = m_otherValue; m_otherValue = tmp; finalize(); } - virtual void undo() { redo(); } + void undo() override { redo(); } protected: target_class* m_target; value_type target_class::*m_field; value_type m_otherValue; }; template class StandardMacroSetterCmd : public QUndoCommand { public: StandardMacroSetterCmd(target_class* target, value_type target_class::*field, value_type newValue, const QString& description) // use i18n("%1: ...") for last arg : m_target(target), m_field(field), m_otherValue(newValue) { setText(description.arg(m_target->name())); } virtual void initialize() {}; virtual void finalize() {}; virtual void finalizeUndo() {}; - virtual void redo() { + void redo() override { initialize(); value_type tmp = *m_target.*m_field; *m_target.*m_field = m_otherValue; m_otherValue = tmp; finalize(); } //call finalizeUndo() at the end where only the signal is emmited //and no actual finalize-method is called that can potentially //cause new entries on the undo-stack - virtual void undo() { + void undo() override { initialize(); value_type tmp = *m_target.*m_field; *m_target.*m_field = m_otherValue; m_otherValue = tmp; finalizeUndo(); } protected: target_class* m_target; value_type target_class::*m_field; value_type m_otherValue; }; template class StandardSwapMethodSetterCmd : public QUndoCommand { public: StandardSwapMethodSetterCmd(target_class* target, value_type (target_class::*method)(value_type), value_type newValue, const QString& description) // use i18n("%1: ...") for last arg : m_target(target), m_method(method), m_otherValue(newValue) { setText(description.arg(m_target->name())); } virtual void initialize() {}; virtual void finalize() {}; - virtual void redo() { + void redo() override { initialize(); m_otherValue = (*m_target.*m_method)(m_otherValue); finalize(); } - virtual void undo() { redo(); } + void undo() override { redo(); } protected: target_class* m_target; value_type (target_class::*m_method)(value_type); value_type m_otherValue; }; #endif diff --git a/src/backend/matrix/Matrix.h b/src/backend/matrix/Matrix.h index 62b559228..14f4c8981 100644 --- a/src/backend/matrix/Matrix.h +++ b/src/backend/matrix/Matrix.h @@ -1,174 +1,174 @@ /*************************************************************************** File : Matrix.h Project : Matrix Description : Spreadsheet with a MxN matrix data model -------------------------------------------------------------------- Copyright : (C) 2008-2009 Tilman Benkert (thzs@gmx.net) Copyright : (C) 2015-2017 Alexander Semke (alexander.semke@web.de) Copyright : (C) 2017 Stefan Gerlach (stefan.gerlach@uni.kn) ***************************************************************************/ /*************************************************************************** * * * 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 MATRIX_H #define MATRIX_H #include "backend/datasources/AbstractDataSource.h" #include "backend/datasources/filters/AbstractFileFilter.h" #include "backend/lib/macros.h" class MatrixPrivate; class MatrixModel; class MatrixView; class Matrix : public AbstractDataSource { Q_OBJECT Q_ENUMS(HeaderFormat) public: enum HeaderFormat {HeaderRowsColumns, HeaderValues, HeaderRowsColumnsValues}; Matrix(AbstractScriptingEngine* engine, const QString& name, bool loading = false, const AbstractColumn::ColumnMode = AbstractColumn::Numeric); Matrix(AbstractScriptingEngine* engine, int rows, int cols, const QString& name, const AbstractColumn::ColumnMode = AbstractColumn::Numeric); - ~Matrix(); + ~Matrix() override; - virtual QIcon icon() const override; - virtual QMenu* createContextMenu() override; - virtual QWidget* view() const override; + QIcon icon() const override; + QMenu* createContextMenu() override; + QWidget* view() const override; - virtual bool exportView() const override; - virtual bool printView() override; - virtual bool printPreview() const override; + bool exportView() const override; + bool printView() override; + bool printPreview() const override; void* data() const; void setData(void*); BASIC_D_ACCESSOR_DECL(AbstractColumn::ColumnMode, mode, Mode) BASIC_D_ACCESSOR_DECL(int, rowCount, RowCount) BASIC_D_ACCESSOR_DECL(int, columnCount, ColumnCount) BASIC_D_ACCESSOR_DECL(char, numericFormat, NumericFormat) BASIC_D_ACCESSOR_DECL(int, precision, Precision) BASIC_D_ACCESSOR_DECL(HeaderFormat, headerFormat, HeaderFormat) BASIC_D_ACCESSOR_DECL(double, xStart, XStart) BASIC_D_ACCESSOR_DECL(double, xEnd, XEnd) BASIC_D_ACCESSOR_DECL(double, yStart, YStart) BASIC_D_ACCESSOR_DECL(double, yEnd, YEnd) CLASS_D_ACCESSOR_DECL(QString, formula, Formula) void setSuppressDataChangedSignal(bool); void setChanged(); int rowHeight(int row) const; void setRowHeight(int row, int height); int columnWidth(int col) const; void setColumnWidth(int col, int width); void setDimensions(int rows, int cols); void setCoordinates(double x1, double x2, double y1, double y2); void insertColumns(int before, int count); void appendColumns(int count); void removeColumns(int first, int count); void clearColumn(int); void insertRows(int before, int count); void appendRows(int count); void removeRows(int first, int count); void clearRow(int); template T cell(int row, int col) const; template QString text(int row, int col); template void setCell(int row, int col, T value); void clearCell(int row, int col); template QVector columnCells(int col, int first_row, int last_row); template void setColumnCells(int col, int first_row, int last_row, const QVector& values); template QVector rowCells(int row, int first_column, int last_column); template void setRowCells(int row, int first_column, int last_column, const QVector& values); void copy(Matrix* other); - virtual void save(QXmlStreamWriter*) const override; - virtual bool load(XmlStreamReader*, bool preview) override; + void save(QXmlStreamWriter*) const override; + bool load(XmlStreamReader*, bool preview) override; - virtual int prepareImport(QVector& dataContainer, AbstractFileFilter::ImportMode, + int prepareImport(QVector& dataContainer, AbstractFileFilter::ImportMode, int rows, int cols, QStringList colNameList, QVector) override; - virtual void finalizeImport(int columnOffset, int startColumn, int endColumn, + void finalizeImport(int columnOffset, int startColumn, int endColumn, const QString& dateTimeFormat, AbstractFileFilter::ImportMode) override; typedef MatrixPrivate Private; public slots: void clear(); void transpose(); void mirrorVertically(); void mirrorHorizontally(); void addColumns(); void addRows(); void duplicate(); signals: void requestProjectContextMenu(QMenu*); void columnsAboutToBeInserted(int before, int count); void columnsInserted(int first, int count); void columnsAboutToBeRemoved(int first, int count); void columnsRemoved(int first, int count); void rowsAboutToBeInserted(int before, int count); void rowsInserted(int first, int count); void rowsAboutToBeRemoved(int first, int count); void rowsRemoved(int first, int count); void dataChanged(int top, int left, int bottom, int right); void coordinatesChanged(); friend class MatrixInsertRowsCmd; friend class MatrixInsertColumnsCmd; void rowCountChanged(int); void columnCountChanged(int); friend class MatrixSetXStartCmd; friend class MatrixSetXEndCmd; friend class MatrixSetYStartCmd; friend class MatrixSetYEndCmd; void xStartChanged(double); void xEndChanged(double); void yStartChanged(double); void yEndChanged(double); friend class MatrixSetNumericFormatCmd; friend class MatrixSetPrecisionCmd; void numericFormatChanged(char); void precisionChanged(int); void headerFormatChanged(Matrix::HeaderFormat); private: void init(); MatrixPrivate* const d; mutable MatrixModel* m_model; friend class MatrixPrivate; template friend class MatrixRemoveColumnsCmd; template friend class MatrixRemoveRowsCmd; }; #endif diff --git a/src/backend/matrix/MatrixModel.h b/src/backend/matrix/MatrixModel.h index 4dc9d9fe6..0f536e584 100644 --- a/src/backend/matrix/MatrixModel.h +++ b/src/backend/matrix/MatrixModel.h @@ -1,80 +1,80 @@ /*************************************************************************** File : MatrixModel.h Project : LabPlot Description : Matrix data model -------------------------------------------------------------------- Copyright : (C) 2015 Alexander Semke (alexander.semke@web.de) Copyright : (C) 2008-2009 Tilman Benkert (thzs@gmx.net) ***************************************************************************/ /*************************************************************************** * * * 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 MATRIXMODEL_H #define MATRIXMODEL_H #include class Matrix; class MatrixModel : public QAbstractItemModel { Q_OBJECT public: explicit MatrixModel(Matrix*); //! \name Overloaded functions from QAbstractItemModel //@{ - Qt::ItemFlags flags(const QModelIndex&) const; - QVariant data(const QModelIndex& index, int role) const; - QVariant headerData(int section, Qt::Orientation orientation,int role = Qt::DisplayRole) const; - int rowCount(const QModelIndex& parent = QModelIndex()) const; - int columnCount(const QModelIndex& parent = QModelIndex()) const; - bool setData(const QModelIndex& index, const QVariant& value, int role); - QModelIndex index(int row, int column, const QModelIndex& parent = QModelIndex()) const; - QModelIndex parent(const QModelIndex& child) const; + Qt::ItemFlags flags(const QModelIndex&) const override; + QVariant data(const QModelIndex& index, int role) const override; + QVariant headerData(int section, Qt::Orientation orientation,int role = Qt::DisplayRole) const override; + int rowCount(const QModelIndex& parent = QModelIndex()) const override; + int columnCount(const QModelIndex& parent = QModelIndex()) const override; + bool setData(const QModelIndex& index, const QVariant& value, int role) override; + QModelIndex index(int row, int column, const QModelIndex& parent = QModelIndex()) const override; + QModelIndex parent(const QModelIndex& child) const override; //@} void updateHeader(); void setSuppressDataChangedSignal(bool); void setChanged(); private slots: void handleColumnsAboutToBeInserted(int before, int count); void handleColumnsInserted(int first, int count); void handleColumnsAboutToBeRemoved(int first, int count); void handleColumnsRemoved(int first, int count); void handleRowsAboutToBeInserted(int before, int count); void handleRowsInserted(int first, int count); void handleRowsAboutToBeRemoved(int first, int count); void handleRowsRemoved(int first, int count); void handleDataChanged(int top, int left, int bottom, int right); void handleCoordinatesChanged(); void handleFormatChanged(); private: Matrix* m_matrix; bool m_suppressDataChangedSignal; signals: void changed(); }; #endif diff --git a/src/backend/matrix/matrixcommands.h b/src/backend/matrix/matrixcommands.h index ee8de1354..dda7c5d4b 100644 --- a/src/backend/matrix/matrixcommands.h +++ b/src/backend/matrix/matrixcommands.h @@ -1,410 +1,410 @@ /*************************************************************************** File : matrixcommands.h Project : LabPlot Description : Commands used in Matrix (part of the undo/redo framework) -------------------------------------------------------------------- Copyright : (C) 2008 Tilman Benkert (thzs@gmx.net) Copyright : (C) 2015 Alexander Semke (alexander.semke@web.de) Copyright : (C) 2017 Stefan Gerlach (stefan.gerlach@uni.kn) ***************************************************************************/ /*************************************************************************** * * * 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 MATRIX_COMMANDS_H #define MATRIX_COMMANDS_H #include #include #include #include "Matrix.h" #include "MatrixPrivate.h" //! Insert columns class MatrixInsertColumnsCmd : public QUndoCommand { public: MatrixInsertColumnsCmd(MatrixPrivate*, int before, int count, QUndoCommand* = 0); - virtual void redo(); - virtual void undo(); + void redo() override; + void undo() override; private: MatrixPrivate* m_private_obj; int m_before; //! Column to insert before int m_count; //! The number of new columns }; //! Insert rows class MatrixInsertRowsCmd : public QUndoCommand { public: MatrixInsertRowsCmd(MatrixPrivate*, int before, int count, QUndoCommand* = 0); - virtual void redo(); - virtual void undo(); + void redo() override; + void undo() override; private: MatrixPrivate* m_private_obj; int m_before; //! Row to insert before int m_count; //! The number of new rows }; //! Remove columns template class MatrixRemoveColumnsCmd : public QUndoCommand { public: MatrixRemoveColumnsCmd(MatrixPrivate* private_obj, int first, int count, QUndoCommand* parent = 0) : QUndoCommand(parent), m_private_obj(private_obj), m_first(first), m_count(count) { setText(i18np("%1: remove %2 column", "%1: remove %2 columns", m_private_obj->name(), m_count)); } - virtual void redo() { + void redo() override { if(m_backups.isEmpty()) { int last_row = m_private_obj->rowCount-1; for (int i = 0; i < m_count; i++) m_backups.append(m_private_obj->columnCells(m_first+i, 0, last_row)); } m_private_obj->removeColumns(m_first, m_count); emit m_private_obj->q->columnCountChanged(m_private_obj->columnCount); } - virtual void undo() { + void undo() override { m_private_obj->insertColumns(m_first, m_count); int last_row = m_private_obj->rowCount-1; //TODO: use memcopy to copy from the backup vector for (int i = 0; i < m_count; i++) m_private_obj->setColumnCells(m_first+i, 0, last_row, m_backups.at(i)); emit m_private_obj->q->columnCountChanged(m_private_obj->columnCount); } private: MatrixPrivate* m_private_obj; int m_first; //! First column to remove int m_count; //! The number of columns to remove QVector> m_backups; //! Backups of the removed columns }; //! Remove rows template class MatrixRemoveRowsCmd : public QUndoCommand { public: MatrixRemoveRowsCmd(MatrixPrivate* private_obj, int first, int count, QUndoCommand* parent = 0) : QUndoCommand(parent), m_private_obj(private_obj), m_first(first), m_count(count) { setText(i18np("%1: remove %2 row", "%1: remove %2 rows", m_private_obj->name(), m_count)); } - virtual void redo() { + void redo() override { if(m_backups.isEmpty()) { int last_row = m_first+m_count-1; for (int col = 0; col < m_private_obj->columnCount; col++) m_backups.append(m_private_obj->columnCells(col, m_first, last_row)); } m_private_obj->removeRows(m_first, m_count); emit m_private_obj->q->rowCountChanged(m_private_obj->rowCount); } - virtual void undo() { + void undo() override { m_private_obj->insertRows(m_first, m_count); int last_row = m_first+m_count-1; for (int col = 0; col < m_private_obj->columnCount; col++) m_private_obj->setColumnCells(col, m_first, last_row, m_backups.at(col)); emit m_private_obj->q->rowCountChanged(m_private_obj->rowCount); } private: MatrixPrivate* m_private_obj; int m_first; //! First row to remove int m_count; //! The number of rows to remove QVector< QVector > m_backups; //! Backups of the removed rows }; //! Clear matrix template class MatrixClearCmd : public QUndoCommand { public: explicit MatrixClearCmd(MatrixPrivate* private_obj, QUndoCommand* parent = 0) : QUndoCommand(parent), m_private_obj(private_obj) { setText(i18n("%1: clear", m_private_obj->name())); } - virtual void redo() { + void redo() override { if(m_backups.isEmpty()) { int last_row = m_private_obj->rowCount-1; for (int i = 0; i < m_private_obj->columnCount; i++) m_backups.append(m_private_obj->columnCells(i, 0, last_row)); } for (int i = 0; i < m_private_obj->columnCount; i++) m_private_obj->clearColumn(i); } - virtual void undo() { + void undo() override { int last_row = m_private_obj->rowCount-1; for (int i = 0; i < m_private_obj->columnCount; i++) m_private_obj->setColumnCells(i, 0, last_row, m_backups.at(i)); } private: MatrixPrivate* m_private_obj; QVector> m_backups; //! Backups of the cleared cells }; //! Clear matrix column template class MatrixClearColumnCmd : public QUndoCommand { public: MatrixClearColumnCmd(MatrixPrivate* private_obj, int col, QUndoCommand* parent = 0) : QUndoCommand(parent), m_private_obj(private_obj), m_col(col) { setText(i18n("%1: clear column %2", m_private_obj->name(), m_col+1)); } - virtual void redo() { + void redo() override { if(m_backup.isEmpty()) m_backup = m_private_obj->columnCells(m_col, 0, m_private_obj->rowCount-1); m_private_obj->clearColumn(m_col); } - virtual void undo() { + void undo() override { m_private_obj->setColumnCells(m_col, 0, m_private_obj->rowCount-1, m_backup); } private: MatrixPrivate* m_private_obj; int m_col; //! The index of the column QVector m_backup; //! Backup of the cleared column }; // Set cell value template class MatrixSetCellValueCmd : public QUndoCommand { public: MatrixSetCellValueCmd(MatrixPrivate* private_obj, int row, int col, T value, QUndoCommand* parent = 0) : QUndoCommand(parent), m_private_obj(private_obj), m_row(row), m_col(col), m_value(value) { // remark: don't use many QString::arg() calls in ctors of commands that might be called often, // they use a lot of execution time setText(i18n("%1: set cell value", m_private_obj->name())); } - virtual void redo() { + void redo() override { m_old_value = m_private_obj->cell(m_row, m_col); m_private_obj->setCell(m_row, m_col, m_value); } - virtual void undo() { + void undo() override { m_private_obj->setCell(m_row, m_col, m_old_value); } private: MatrixPrivate* m_private_obj; int m_row; //! The index of the row int m_col; //! The index of the column T m_value; //! New cell value T m_old_value; //! Backup of the changed value }; // Set matrix coordinates class MatrixSetCoordinatesCmd : public QUndoCommand { public: MatrixSetCoordinatesCmd(MatrixPrivate*, double x1, double x2, double y1, double y2, QUndoCommand* = 0); - virtual void redo(); - virtual void undo(); + void redo() override; + void undo() override; private: MatrixPrivate* m_private_obj; double m_new_x1; double m_new_x2; double m_new_y1; double m_new_y2; double m_old_x1; double m_old_x2; double m_old_y1; double m_old_y2; }; //! Set matrix formula class MatrixSetFormulaCmd : public QUndoCommand { public: MatrixSetFormulaCmd(MatrixPrivate*, QString formula); - virtual void redo(); - virtual void undo(); + void redo() override; + void undo() override; private: MatrixPrivate* m_private_obj; QString m_other_formula; }; // Set cell values for (a part of) a column at once template class MatrixSetColumnCellsCmd : public QUndoCommand { public: MatrixSetColumnCellsCmd(MatrixPrivate* private_obj, int col, int first_row, int last_row, const QVector& values, QUndoCommand* parent = 0) : QUndoCommand(parent), m_private_obj(private_obj), m_col(col), m_first_row(first_row), m_last_row(last_row), m_values(values) { setText(i18n("%1: set cell values", m_private_obj->name())); } - virtual void redo() { + void redo() override { if (m_old_values.isEmpty()) m_old_values = m_private_obj->columnCells(m_col, m_first_row, m_last_row); m_private_obj->setColumnCells(m_col, m_first_row, m_last_row, m_values); } - virtual void undo() { + void undo() override { m_private_obj->setColumnCells(m_col, m_first_row, m_last_row, m_old_values); } private: MatrixPrivate* m_private_obj; int m_col; //! The index of the column int m_first_row; //! The index of the first row int m_last_row; //! The index of the last row QVector m_values; //! New cell values QVector m_old_values; //! Backup of the changed values }; //! Set cell values for (a part of) a row at once template class MatrixSetRowCellsCmd : public QUndoCommand { public: MatrixSetRowCellsCmd(MatrixPrivate* private_obj, int row, int first_column, int last_column, const QVector& values, QUndoCommand* parent = 0) : QUndoCommand(parent), m_private_obj(private_obj), m_row(row), m_first_column(first_column), m_last_column(last_column), m_values(values) { setText(i18n("%1: set cell values", m_private_obj->name())); } - virtual void redo() { + void redo() override { if (m_old_values.isEmpty()) m_old_values = m_private_obj->rowCells(m_row, m_first_column, m_last_column); m_private_obj->setRowCells(m_row, m_first_column, m_last_column, m_values); } - virtual void undo() { + void undo() override { m_private_obj->setRowCells(m_row, m_first_column, m_last_column, m_old_values); } private: MatrixPrivate* m_private_obj; int m_row; //! The index of the row int m_first_column; //! The index of the first column int m_last_column; //! The index of the last column QVector m_values; //! New cell values QVector m_old_values; //! Backup of the changed values }; //! Transpose the matrix template class MatrixTransposeCmd : public QUndoCommand { public: explicit MatrixTransposeCmd(MatrixPrivate* private_obj, QUndoCommand* parent = 0) : QUndoCommand(parent), m_private_obj(private_obj) { setText(i18n("%1: transpose", m_private_obj->name())); } - virtual void redo() { + void redo() override { int rows = m_private_obj->rowCount; int cols = m_private_obj->columnCount; int temp_size = qMax(rows, cols); m_private_obj->suppressDataChange = true; if (cols < rows) m_private_obj->insertColumns(cols, temp_size - cols); else if (cols > rows) m_private_obj->insertRows(rows, temp_size - rows); for (int i = 1; i < temp_size; i++) { QVector row = m_private_obj->rowCells(i, 0, i-1); QVector col = m_private_obj->columnCells(i, 0, i-1); m_private_obj->setRowCells(i, 0, i-1, col); m_private_obj->setColumnCells(i, 0, i-1, row); } if (cols < rows) m_private_obj->removeRows(cols, temp_size - cols); else if (cols > rows) m_private_obj->removeColumns(rows, temp_size - rows); m_private_obj->suppressDataChange = false; m_private_obj->emitDataChanged(0, 0, m_private_obj->rowCount-1, m_private_obj->columnCount-1); } - virtual void undo() { + void undo() override { redo(); } private: MatrixPrivate* m_private_obj; }; //! Mirror the matrix horizontally template class MatrixMirrorHorizontallyCmd : public QUndoCommand { public: explicit MatrixMirrorHorizontallyCmd(MatrixPrivate* private_obj, QUndoCommand* parent = 0) : QUndoCommand(parent), m_private_obj(private_obj) { setText(i18n("%1: mirror horizontally", m_private_obj->name())); } - virtual void redo() { + void redo() override { int rows = m_private_obj->rowCount; int cols = m_private_obj->columnCount; int middle = cols/2; m_private_obj->suppressDataChange = true; for (int i = 0; i temp = m_private_obj->columnCells(i, 0, rows-1); m_private_obj->setColumnCells(i, 0, rows-1, m_private_obj->columnCells(cols-i-1, 0, rows-1)); m_private_obj->setColumnCells(cols-i-1, 0, rows-1, temp); } m_private_obj->suppressDataChange = false; m_private_obj->emitDataChanged(0, 0, rows-1, cols-1); } - virtual void undo() { + void undo() override { redo(); } private: MatrixPrivate* m_private_obj; }; // Mirror the matrix vertically template class MatrixMirrorVerticallyCmd : public QUndoCommand { public: explicit MatrixMirrorVerticallyCmd(MatrixPrivate* private_obj, QUndoCommand* parent = 0) : QUndoCommand(parent), m_private_obj(private_obj) { setText(i18n("%1: mirror vertically", m_private_obj->name())); } - virtual void redo() { + void redo() override { int rows = m_private_obj->rowCount; int cols = m_private_obj->columnCount; int middle = rows/2; m_private_obj->suppressDataChange = true; for (int i = 0; i < middle; i++) { QVector temp = m_private_obj->rowCells(i, 0, cols-1); m_private_obj->setRowCells(i, 0, cols-1, m_private_obj->rowCells(rows-i-1, 0, cols-1)); m_private_obj->setRowCells(rows-i-1, 0, cols-1, temp); } m_private_obj->suppressDataChange = false; m_private_obj->emitDataChanged(0, 0, rows-1, cols-1); } - virtual void undo() { + void undo() override { redo(); } private: MatrixPrivate* m_private_obj; }; // Replace matrix values class MatrixReplaceValuesCmd : public QUndoCommand { public: explicit MatrixReplaceValuesCmd(MatrixPrivate*, void* new_values, QUndoCommand* = 0); - virtual void redo(); - virtual void undo(); + void redo() override; + void undo() override; private: MatrixPrivate* m_private_obj; void* m_old_values; void* m_new_values; }; #endif // MATRIX_COMMANDS_H diff --git a/src/backend/note/Note.h b/src/backend/note/Note.h index d4c6cd0ec..2586d32dc 100644 --- a/src/backend/note/Note.h +++ b/src/backend/note/Note.h @@ -1,79 +1,79 @@ /*************************************************************************** File : Notes.h Project : LabPlot Description : Widget for taking notes -------------------------------------------------------------------- Copyright : (C) 2016 Garvit Khatri (garvitdelhi@gmail.com) Copyright : (C) 2016 Alexander Semke (alexander.semke@web.de) ***************************************************************************/ /*************************************************************************** * * * 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 NOTE_H #define NOTE_H #include "backend/core/AbstractPart.h" #include #include #include class Note : public AbstractPart { Q_OBJECT public: explicit Note(const QString& name); - virtual QWidget* view() const override; - virtual QIcon icon() const override; + QWidget* view() const override; + QIcon icon() const override; - virtual bool exportView() const override; - virtual bool printView() override; - virtual bool printPreview() const override; + bool exportView() const override; + bool printView() override; + bool printPreview() const override; void setNote(const QString&); const QString& note() const; void setBackgroundColor(const QColor&); const QColor& backgroundColor() const; void setTextColor(const QColor&); const QColor& textColor() const; void setTextFont(const QFont&); const QFont& textFont() const; - virtual void save(QXmlStreamWriter*) const override; - virtual bool load(XmlStreamReader*, bool preview) override; + void save(QXmlStreamWriter*) const override; + bool load(XmlStreamReader*, bool preview) override; signals: void backgroundColorChanged(QColor); void textColorChanged(QColor); void textFontChanged(QFont); private: QColor m_backgroundColor; QColor m_textColor; QFont m_textFont; QString m_note; }; #endif // NOTE_H diff --git a/src/backend/spreadsheet/Spreadsheet.h b/src/backend/spreadsheet/Spreadsheet.h index 1de67cfa2..70b6764a9 100644 --- a/src/backend/spreadsheet/Spreadsheet.h +++ b/src/backend/spreadsheet/Spreadsheet.h @@ -1,118 +1,118 @@ /*************************************************************************** File : Spreadsheet.h Project : LabPlot Description : Aspect providing a spreadsheet table with column logic -------------------------------------------------------------------- Copyright : (C) 2010-2017 Alexander Semke(alexander.semke@web.de) Copyright : (C) 2006-2008 Tilman Benkert (thzs@gmx.net) ***************************************************************************/ /*************************************************************************** * * * 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 SPREADSHEET_H #define SPREADSHEET_H #include "backend/datasources/AbstractDataSource.h" #include "backend/core/column/ColumnStringIO.h" class AbstractFileFilter; template class QList; class Spreadsheet : public AbstractDataSource { Q_OBJECT public: Spreadsheet(AbstractScriptingEngine* engine, const QString& name, bool loading = false); - virtual QIcon icon() const override; - virtual QMenu* createContextMenu() override; - virtual QWidget* view() const override; + QIcon icon() const override; + QMenu* createContextMenu() override; + QWidget* view() const override; - virtual bool exportView() const override; - virtual bool printView() override; - virtual bool printPreview() const override; + bool exportView() const override; + bool printView() override; + bool printPreview() const override; int columnCount() const; int columnCount(AbstractColumn::PlotDesignation) const; Column* column(int index) const; Column* column(const QString&) const; int rowCount() const; void removeRows(int first, int count); void insertRows(int before, int count); void removeColumns(int first, int count); void insertColumns(int before, int count); int colX(int col); int colY(int col); QString text(int row, int col) const; void copy(Spreadsheet* other); - virtual void save(QXmlStreamWriter*) const override; - virtual bool load(XmlStreamReader*, bool preview) override; + void save(QXmlStreamWriter*) const override; + bool load(XmlStreamReader*, bool preview) override; void setColumnSelectedInView(int index, bool selected); // used from model to inform dock void emitRowCountChanged() { emit rowCountChanged(rowCount()); } void emitColumnCountChanged() { emit columnCountChanged(columnCount()); } //data import - virtual int prepareImport(QVector& dataContainer, AbstractFileFilter::ImportMode, + int prepareImport(QVector& dataContainer, AbstractFileFilter::ImportMode, int rows, int cols, QStringList colNameList, QVector) override; - virtual void finalizeImport(int columnOffset, int startColumn , int endColumn, + void finalizeImport(int columnOffset, int startColumn , int endColumn, const QString& dateTimeFormat, AbstractFileFilter::ImportMode) override; int resize(AbstractFileFilter::ImportMode, QStringList colNameList, int cols); public slots: void appendRows(int); void appendRow(); void appendColumns(int); void appendColumn(); void prependColumns(int); void setColumnCount(int); void setRowCount(int); void clear(); void clearMasks(); void moveColumn(int from, int to); void sortColumns(Column* leading, QVector, bool ascending); private: void init(); private slots: - virtual void childSelected(const AbstractAspect*) override; - virtual void childDeselected(const AbstractAspect*) override; + void childSelected(const AbstractAspect*) override; + void childDeselected(const AbstractAspect*) override; signals: void requestProjectContextMenu(QMenu*); void columnSelected(int); void columnDeselected(int); // for spreadsheet dock void rowCountChanged(int); void columnCountChanged(int); }; #endif diff --git a/src/backend/spreadsheet/SpreadsheetModel.h b/src/backend/spreadsheet/SpreadsheetModel.h index 97d3cce5a..c40aaefb5 100644 --- a/src/backend/spreadsheet/SpreadsheetModel.h +++ b/src/backend/spreadsheet/SpreadsheetModel.h @@ -1,95 +1,95 @@ /*************************************************************************** File : SpreadsheetModel.h Project : LabPlot Description : Model for the access to a Spreadsheet -------------------------------------------------------------------- Copyright : (C) 2007 Tilman Benkert (thzs@gmx.net) Copyright : (C) 2009 Knut Franke (knut.franke@gmx.de) Copyright : (C) 2013-2016 Alexander Semke (alexander.semke@web.de) ***************************************************************************/ /*************************************************************************** * * * 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 SPREADSHEETMODEL_H #define SPREADSHEETMODEL_H #include #include class Column; class Spreadsheet; class AbstractAspect; class AbstractColumn; class SpreadsheetModel : public QAbstractItemModel { Q_OBJECT public: explicit SpreadsheetModel(Spreadsheet*); enum CustomDataRole { MaskingRole = Qt::UserRole, //!< bool determining whether the cell is masked FormulaRole = Qt::UserRole+1, //!< the cells formula CommentRole = Qt::UserRole+2, //!< the column comment (for headerData()) }; - Qt::ItemFlags flags( const QModelIndex & index ) const; - QVariant data(const QModelIndex& index, int role) const; - QVariant headerData(int section, Qt::Orientation orientation,int role) const; - int rowCount(const QModelIndex& parent = QModelIndex()) const; - int columnCount(const QModelIndex& parent = QModelIndex()) const; - bool setData(const QModelIndex& index, const QVariant& value, int role); - QModelIndex index(int row, int column, const QModelIndex& parent = QModelIndex()) const; - QModelIndex parent(const QModelIndex& child) const; - bool hasChildren (const QModelIndex& parent = QModelIndex() ) const; + Qt::ItemFlags flags( const QModelIndex & index ) const override; + QVariant data(const QModelIndex& index, int role) const override; + QVariant headerData(int section, Qt::Orientation orientation,int role) const override; + int rowCount(const QModelIndex& parent = QModelIndex()) const override; + int columnCount(const QModelIndex& parent = QModelIndex()) const override; + bool setData(const QModelIndex& index, const QVariant& value, int role) override; + QModelIndex index(int row, int column, const QModelIndex& parent = QModelIndex()) const override; + QModelIndex parent(const QModelIndex& child) const override; + bool hasChildren (const QModelIndex& parent = QModelIndex() ) const override; Column* column(int index); void activateFormulaMode(bool on); bool formulaModeActive() const; private slots: void handleAspectAboutToBeAdded(const AbstractAspect* parent, const AbstractAspect* before, const AbstractAspect* child); void handleAspectAdded(const AbstractAspect*); void handleAspectAboutToBeRemoved(const AbstractAspect*); void handleAspectRemoved(const AbstractAspect* parent, const AbstractAspect* before, const AbstractAspect* child); void handleDescriptionChange(const AbstractAspect*); void handleModeChange(const AbstractColumn*); void handleDigitsChange(); void handlePlotDesignationChange(const AbstractColumn*); void handleDataChange(const AbstractColumn*); void handleRowsInserted(const AbstractColumn* col, int before, int count); void handleRowsRemoved(const AbstractColumn* col, int first, int count); protected: void updateVerticalHeader(); void updateHorizontalHeader(); private: Spreadsheet* m_spreadsheet; bool m_formula_mode; QList m_vertical_header_data; QStringList m_horizontal_header_data; int m_defaultHeaderHeight; }; #endif diff --git a/src/backend/worksheet/TextLabel.h b/src/backend/worksheet/TextLabel.h index ae4811134..922c25b76 100644 --- a/src/backend/worksheet/TextLabel.h +++ b/src/backend/worksheet/TextLabel.h @@ -1,146 +1,146 @@ /*************************************************************************** File : TextLabel.h Project : LabPlot Description : Text label supporting reach text and latex formatting -------------------------------------------------------------------- Copyright : (C) 2009 Tilman Benkert (thzs@gmx.net) Copyright : (C) 2012-2014 Alexander Semke (alexander.semke@web.de) ***************************************************************************/ /*************************************************************************** * * * 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 TEXTLABEL_H #define TEXTLABEL_H #include "backend/lib/macros.h" #include "tools/TeXRenderer.h" #include "backend/worksheet/WorksheetElement.h" #include #include #include class TextLabelPrivate; class TextLabel : public WorksheetElement { Q_OBJECT public: enum Type {General, PlotTitle, AxisTitle, PlotLegendTitle}; enum HorizontalPosition {hPositionLeft, hPositionCenter, hPositionRight, hPositionCustom}; enum VerticalPosition {vPositionTop, vPositionCenter, vPositionBottom, vPositionCustom}; enum HorizontalAlignment {hAlignLeft, hAlignCenter, hAlignRight}; enum VerticalAlignment {vAlignTop, vAlignCenter, vAlignBottom}; struct TextWrapper { TextWrapper() : teXUsed(false) {} TextWrapper(const QString& t, bool b) : text(t), teXUsed(b) {} TextWrapper(const QString& t) : text(t), teXUsed(false) {} QString text; bool teXUsed; }; struct PositionWrapper { QPointF point; HorizontalPosition horizontalPosition; VerticalPosition verticalPosition; }; explicit TextLabel(const QString& name, Type type = General); - ~TextLabel(); + ~TextLabel() override; Type type() const; - virtual QIcon icon() const override; - virtual QMenu* createContextMenu() override; - virtual QGraphicsItem* graphicsItem() const override; + QIcon icon() const override; + QMenu* createContextMenu() override; + QGraphicsItem* graphicsItem() const override; void setParentGraphicsItem(QGraphicsItem*); - virtual void save(QXmlStreamWriter*) const override; - virtual bool load(XmlStreamReader*, bool preview) override; - virtual void loadThemeConfig(const KConfig& config) override; - virtual void saveThemeConfig(const KConfig& config) override; + void save(QXmlStreamWriter*) const override; + bool load(XmlStreamReader*, bool preview) override; + void loadThemeConfig(const KConfig& config) override; + void saveThemeConfig(const KConfig& config) override; CLASS_D_ACCESSOR_DECL(TextWrapper, text, Text); BASIC_D_ACCESSOR_DECL(QColor, teXFontColor, TeXFontColor); BASIC_D_ACCESSOR_DECL(QColor, teXBackgroundColor, TeXBackgroundColor); CLASS_D_ACCESSOR_DECL(QFont, teXFont, TeXFont); CLASS_D_ACCESSOR_DECL(PositionWrapper, position, Position); void setPosition(const QPointF&); void setPositionInvalid(bool); BASIC_D_ACCESSOR_DECL(HorizontalAlignment, horizontalAlignment, HorizontalAlignment); BASIC_D_ACCESSOR_DECL(VerticalAlignment, verticalAlignment, VerticalAlignment); BASIC_D_ACCESSOR_DECL(float, rotationAngle, RotationAngle); - virtual void setVisible(bool on) override; - virtual bool isVisible() const override; - virtual void setPrinting(bool) override; + void setVisible(bool on) override; + bool isVisible() const override; + void setPrinting(bool) override; - virtual void retransform() override; - virtual void handleResize(double horizontalRatio, double verticalRatio, bool pageResize) override; + void retransform() override; + void handleResize(double horizontalRatio, double verticalRatio, bool pageResize) override; typedef TextLabelPrivate Private; private slots: void updateTeXImage(); //SLOTs for changes triggered via QActions in the context menu void visibilityChanged(); protected: TextLabelPrivate* const d_ptr; TextLabel(const QString& name, TextLabelPrivate* dd, Type type = General); private: Q_DECLARE_PRIVATE(TextLabel) void init(); void initActions(); Type m_type; QAction* visibilityAction; signals: friend class TextLabelSetTextCmd; friend class TextLabelSetTeXFontCmd; friend class TextLabelSetTeXFontColorCmd; friend class TextLabelSetTeXBackgroundColorCmd; friend class TextLabelSetPositionCmd; friend class TextLabelSetHorizontalAlignmentCmd; friend class TextLabelSetVerticalAlignmentCmd; friend class TextLabelSetRotationAngleCmd; void textWrapperChanged(const TextLabel::TextWrapper&); void teXFontSizeChanged(const int); void teXFontChanged(const QFont); void teXFontColorChanged(const QColor); void teXBackgroundColorChanged(const QColor); void positionChanged(const TextLabel::PositionWrapper&); void horizontalAlignmentChanged(TextLabel::HorizontalAlignment); void verticalAlignmentChanged(TextLabel::VerticalAlignment); void rotationAngleChanged(float); void visibleChanged(bool); void teXImageUpdated(bool); void changed(); }; #endif diff --git a/src/backend/worksheet/TextLabelPrivate.h b/src/backend/worksheet/TextLabelPrivate.h index 342aece65..3355b6edf 100644 --- a/src/backend/worksheet/TextLabelPrivate.h +++ b/src/backend/worksheet/TextLabelPrivate.h @@ -1,94 +1,94 @@ /*************************************************************************** File : TextLabelPrivate.h Project : LabPlot Description : Private members of TextLabel -------------------------------------------------------------------- Copyright : (C) 2012-2014 by Alexander Semke (alexander.semke@web.de) ***************************************************************************/ /*************************************************************************** * * * 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 TEXTLABELPRIVATE_H #define TEXTLABELPRIVATE_H #include #include #include class QGraphicsSceneHoverEvent; class TextLabelPrivate: public QGraphicsItem { public: explicit TextLabelPrivate(TextLabel*); float rotationAngle; float scaleFactor; int teXImageResolution; float teXImageScaleFactor; TextLabel::TextWrapper textWrapper; QFont teXFont; QColor teXFontColor; QColor teXBackgroundColor; QImage teXImage; QFutureWatcher teXImageFutureWatcher; bool teXRenderSuccessful; TextLabel::PositionWrapper position; //position in parent's coordinate system, the label gets aligned around this point. bool positionInvalid; TextLabel::HorizontalAlignment horizontalAlignment; TextLabel::VerticalAlignment verticalAlignment; QString name() const; void retransform(); bool swapVisible(bool on); virtual void recalcShapeAndBoundingRect(); void updatePosition(); QPointF positionFromItemPosition(const QPointF&); void updateText(); void updateTeXImage(); QStaticText staticText; bool suppressItemChangeEvent; bool suppressRetransform; bool m_printing; bool m_hovered; QRectF boundingRectangle; //bounding rectangle of the text QRectF transformedBoundingRectangle; //bounding rectangle of transformed (rotated etc.) text QPainterPath labelShape; //reimplemented from QGraphicsItem - virtual QRectF boundingRect() const; - virtual QPainterPath shape() const; - virtual void paint(QPainter*, const QStyleOptionGraphicsItem*, QWidget* widget = 0); - virtual QVariant itemChange(GraphicsItemChange change, const QVariant &value); + QRectF boundingRect() const override; + QPainterPath shape() const override; + void paint(QPainter*, const QStyleOptionGraphicsItem*, QWidget* widget = 0) override; + QVariant itemChange(GraphicsItemChange change, const QVariant &value) override; TextLabel* const q; private: - virtual void contextMenuEvent(QGraphicsSceneContextMenuEvent*); - virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent*); - virtual void hoverEnterEvent(QGraphicsSceneHoverEvent*); - virtual void hoverLeaveEvent(QGraphicsSceneHoverEvent*); + void contextMenuEvent(QGraphicsSceneContextMenuEvent*) override; + void mouseReleaseEvent(QGraphicsSceneMouseEvent*) override; + void hoverEnterEvent(QGraphicsSceneHoverEvent*) override; + void hoverLeaveEvent(QGraphicsSceneHoverEvent*) override; }; #endif diff --git a/src/backend/worksheet/Worksheet.cpp b/src/backend/worksheet/Worksheet.cpp index ad1e0c9a8..f67f1dc48 100644 --- a/src/backend/worksheet/Worksheet.cpp +++ b/src/backend/worksheet/Worksheet.cpp @@ -1,1055 +1,1055 @@ /*************************************************************************** File : Worksheet.cpp Project : LabPlot Description : Worksheet -------------------------------------------------------------------- Copyright : (C) 2009 Tilman Benkert (thzs@gmx.net) Copyright : (C) 2011-2016 by Alexander Semke (alexander.semke@web.de) ***************************************************************************/ /*************************************************************************** * * * 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 "Worksheet.h" #include "WorksheetPrivate.h" #include "WorksheetElement.h" #include "commonfrontend/worksheet/WorksheetView.h" #include "backend/worksheet/plots/cartesian/CartesianPlot.h" #include "backend/worksheet/TextLabel.h" #include "backend/lib/commandtemplates.h" #include "backend/lib/XmlStreamReader.h" #include "kdefrontend/worksheet/ExportWorksheetDialog.h" #include "kdefrontend/ThemeHandler.h" #include #include #include #include #include #include #include #include #include #include /** * \class Worksheet * \brief Top-level container for worksheet elements like plot, labels, etc. * * The worksheet is, besides the data containers \c Spreadsheet and \c Matrix, another central part of the application * and provides an area for showing and grouping together different kinds of worksheet objects - plots, labels &etc; * * * \ingroup worksheet */ Worksheet::Worksheet(AbstractScriptingEngine* engine, const QString& name, bool loading) : AbstractPart(name), scripted(engine), d(new WorksheetPrivate(this)) { connect(this, &Worksheet::aspectAdded, this, &Worksheet::handleAspectAdded); connect(this, &Worksheet::aspectAboutToBeRemoved, this, &Worksheet::handleAspectAboutToBeRemoved); connect(this, &Worksheet::aspectRemoved, this, &Worksheet::handleAspectRemoved); if (!loading) init(); } Worksheet::~Worksheet() { delete d; } void Worksheet::init() { KConfig config; KConfigGroup group = config.group( "Worksheet" ); //size d->scaleContent = group.readEntry("ScaleContent", false); d->useViewSize = group.readEntry("UseViewSize", false); d->pageRect.setX(0); d->pageRect.setY(0); d->pageRect.setWidth(group.readEntry("Width", 1500)); d->pageRect.setHeight(group.readEntry("Height",1500)); d->m_scene->setSceneRect(d->pageRect); //background d->backgroundType = (PlotArea::BackgroundType) group.readEntry("BackgroundType", (int) PlotArea::Color); d->backgroundColorStyle = (PlotArea::BackgroundColorStyle) group.readEntry("BackgroundColorStyle", (int) PlotArea::SingleColor); d->backgroundImageStyle = (PlotArea::BackgroundImageStyle) group.readEntry("BackgroundImageStyle", (int) PlotArea::Scaled); d->backgroundBrushStyle = (Qt::BrushStyle) group.readEntry("BackgroundBrushStyle", (int) Qt::SolidPattern); d->backgroundFileName = group.readEntry("BackgroundFileName", QString()); d->backgroundFirstColor = group.readEntry("BackgroundFirstColor", QColor(Qt::white)); d->backgroundSecondColor = group.readEntry("BackgroundSecondColor", QColor(Qt::black)); d->backgroundOpacity = group.readEntry("BackgroundOpacity", 1.0); //layout d->layout = (Worksheet::Layout) group.readEntry("Layout", (int) Worksheet::VerticalLayout); d->layoutTopMargin = group.readEntry("LayoutTopMargin", convertToSceneUnits(1, Centimeter)); d->layoutBottomMargin = group.readEntry("LayoutBottomMargin", convertToSceneUnits(1, Centimeter)); d->layoutLeftMargin = group.readEntry("LayoutLeftMargin", convertToSceneUnits(1, Centimeter)); d->layoutRightMargin = group.readEntry("LayoutRightMargin", convertToSceneUnits(1, Centimeter)); d->layoutVerticalSpacing = group.readEntry("LayoutVerticalSpacing", convertToSceneUnits(1, Centimeter)); d->layoutHorizontalSpacing = group.readEntry("LayoutHorizontalSpacing", convertToSceneUnits(1, Centimeter)); d->layoutRowCount = group.readEntry("LayoutRowCount", 2); d->layoutColumnCount = group.readEntry("LayoutColumnCount", 2); //default theme KConfigGroup settings = KSharedConfig::openConfig()->group(QLatin1String("Settings_Worksheet")); d->theme = settings.readEntry(QLatin1String("Theme"), ""); if (!d->theme.isEmpty()) loadTheme(d->theme); } /*! converts from \c unit to the scene units. At the moment, 1 scene unit corresponds to 1/10 mm. */ float Worksheet::convertToSceneUnits(const float value, const Worksheet::Unit unit) { switch (unit) { case Worksheet::Millimeter: return value*10.0; case Worksheet::Centimeter: return value*100.0; case Worksheet::Inch: return value*25.4*10.; case Worksheet::Point: return value*25.4/72.*10.; } return 0; } /*! converts from the scene units to \c unit . At the moment, 1 scene unit corresponds to 1/10 mm. */ float Worksheet::convertFromSceneUnits(const float value, const Worksheet::Unit unit) { switch (unit) { case Worksheet::Millimeter: return value/10.0; case Worksheet::Centimeter: return value/100.0; case Worksheet::Inch: return value/25.4/10.; case Worksheet::Point: return value/25.4/10.*72.; } return 0; } QIcon Worksheet::icon() const { return QIcon::fromTheme("labplot-worksheet"); } /** * Return a new context menu. The caller takes ownership of the menu. */ QMenu* Worksheet::createContextMenu() { QMenu* menu = AbstractPart::createContextMenu(); Q_ASSERT(menu); emit requestProjectContextMenu(menu); return menu; } //! Construct a primary view on me. /** * This method may be called multiple times during the life time of an Aspect, or it might not get * called at all. Aspects must not depend on the existence of a view for their operation. */ QWidget* Worksheet::view() const { if (!m_view) { m_view = new WorksheetView(const_cast(this)); connect(dynamic_cast(m_view), &WorksheetView::statusInfo, this, &Worksheet::statusInfo); } return m_view; } /*! * returns the list of all parent aspects (folders and sub-folders) * together with all the data containers required to plot the data in the worksheet */ QVector Worksheet::dependsOn() const { //add all parent aspects (folders and sub-folders) QVector aspects = AbstractAspect::dependsOn(); //traverse all plots and add all data containers they depend on for (const auto* plot : children()) aspects << plot->dependsOn(); return aspects; } bool Worksheet::exportView() const { ExportWorksheetDialog* dlg = new ExportWorksheetDialog(m_view); dlg->setFileName(name()); bool ret; if ( (ret = (dlg->exec() == QDialog::Accepted)) ) { QString path = dlg->path(); const WorksheetView::ExportFormat format = dlg->exportFormat(); const WorksheetView::ExportArea area = dlg->exportArea(); const bool background = dlg->exportBackground(); const int resolution = dlg->exportResolution(); WorksheetView* view = reinterpret_cast(m_view); WAIT_CURSOR; view->exportToFile(path, format, area, background, resolution); RESET_CURSOR; } delete dlg; return ret; } bool Worksheet::printView() { QPrinter printer; QPrintDialog* dlg = new QPrintDialog(&printer, m_view); dlg->setWindowTitle(i18n("Print Worksheet")); bool ret; if ( (ret = (dlg->exec() == QDialog::Accepted)) ) { WorksheetView* view = reinterpret_cast(m_view); view->print(&printer); } delete dlg; return ret; } bool Worksheet::printPreview() const { const WorksheetView* view = reinterpret_cast(m_view); QPrintPreviewDialog* dlg = new QPrintPreviewDialog(m_view); connect(dlg, &QPrintPreviewDialog::paintRequested, view, &WorksheetView::print); return dlg->exec(); } void Worksheet::handleAspectAdded(const AbstractAspect* aspect) { const WorksheetElement* addedElement = qobject_cast(aspect); if (!addedElement) return; if (aspect->parentAspect() != this) return; //add the GraphicsItem of the added child to the scene QGraphicsItem* item = addedElement->graphicsItem(); d->m_scene->addItem(item); qreal zVal = 0; for (auto* child : children(IncludeHidden)) child->graphicsItem()->setZValue(zVal++); //if a theme was selected in the worksheet, apply this theme for newly added children if (!d->theme.isEmpty() && !isLoading()) { KConfig config(ThemeHandler::themeFilePath(d->theme), KConfig::SimpleConfig); const_cast(addedElement)->loadThemeConfig(config); } //recalculated the layout if (!isLoading()) { if (d->layout != Worksheet::NoLayout) d->updateLayout(false); } } void Worksheet::handleAspectAboutToBeRemoved(const AbstractAspect* aspect) { const WorksheetElement* removedElement = qobject_cast(aspect); if (removedElement) { QGraphicsItem* item = removedElement->graphicsItem(); Q_ASSERT(item != NULL); d->m_scene->removeItem(item); } } void Worksheet::handleAspectRemoved(const AbstractAspect* parent, const AbstractAspect* before, const AbstractAspect* child) { Q_UNUSED(parent); Q_UNUSED(before); Q_UNUSED(child); if (d->layout != Worksheet::NoLayout) d->updateLayout(false); } QGraphicsScene* Worksheet::scene() const { return d->m_scene; } QRectF Worksheet::pageRect() const { return d->m_scene->sceneRect(); } /*! this slot is called when a worksheet element is selected in the project explorer. emits \c itemSelected() which forwards this event to the \c WorksheetView in order to select the corresponding \c QGraphicsItem. */ void Worksheet::childSelected(const AbstractAspect* aspect) { WorksheetElement* element=qobject_cast(const_cast(aspect)); if (element) emit itemSelected(element->graphicsItem()); } /*! this slot is called when a worksheet element is deselected in the project explorer. emits \c itemDeselected() which forwards this event to \c WorksheetView in order to deselect the corresponding \c QGraphicsItem. */ void Worksheet::childDeselected(const AbstractAspect* aspect) { WorksheetElement* element=qobject_cast(const_cast(aspect)); if (element) emit itemDeselected(element->graphicsItem()); } /*! * Emits the signal to select or to deselect the aspect corresponding to \c QGraphicsItem \c item in the project explorer, * if \c selected=true or \c selected=false, respectively. * The signal is handled in \c AspectTreeModel and forwarded to the tree view in \c ProjectExplorer. * This function is called in \c WorksheetView upon selection changes. */ void Worksheet::setItemSelectedInView(const QGraphicsItem* item, const bool b) { //determine the corresponding aspect const AbstractAspect* aspect = 0; for (const auto* child : children(IncludeHidden) ) { aspect = this->aspectFromGraphicsItem(child, item); if (aspect) break; } if (!aspect) return; //forward selection/deselection to AbstractTreeModel if (b) emit childAspectSelectedInView(aspect); else emit childAspectDeselectedInView(aspect); } /*! * helper function: checks whether \c aspect or one of its children has the \c GraphicsItem \c item * Returns a pointer to \c WorksheetElement having this item. */ WorksheetElement* Worksheet::aspectFromGraphicsItem(const WorksheetElement* aspect, const QGraphicsItem* item) const { if ( aspect->graphicsItem() == item ) return const_cast(aspect); else { for (const auto* child : aspect->children(AbstractAspect::IncludeHidden) ) { WorksheetElement* a = this->aspectFromGraphicsItem(child, item); if (a) return a; } return 0; } } /*! Selects or deselects the worksheet in the project explorer. This function is called in \c WorksheetView. The worksheet gets deselected if there are selected items in the view, and selected if there are no selected items in the view. */ void Worksheet::setSelectedInView(const bool b) { if (b) emit childAspectSelectedInView(this); else emit childAspectDeselectedInView(this); } void Worksheet::deleteAspectFromGraphicsItem(const QGraphicsItem* item) { Q_ASSERT(item); //determine the corresponding aspect AbstractAspect* aspect = 0; for (const auto* child : children(IncludeHidden) ) { aspect = this->aspectFromGraphicsItem(child, item); if (aspect) break; } if (!aspect) return; if (aspect->parentAspect()) aspect->parentAspect()->removeChild(aspect); else this->removeChild(aspect); } void Worksheet::setIsClosing() { if (m_view) { WorksheetView* view = reinterpret_cast(m_view); view->setIsClosing(); } } void Worksheet::update() { emit requestUpdate(); } void Worksheet::setSuppressLayoutUpdate(bool value) { d->suppressLayoutUpdate = value; } void Worksheet::updateLayout() { d->updateLayout(); } /* =============================== getter methods for general options ==================================== */ BASIC_D_READER_IMPL(Worksheet, bool, scaleContent, scaleContent) BASIC_D_READER_IMPL(Worksheet, bool, useViewSize, useViewSize) /* =============================== getter methods for background options ================================= */ BASIC_D_READER_IMPL(Worksheet, PlotArea::BackgroundType, backgroundType, backgroundType) BASIC_D_READER_IMPL(Worksheet, PlotArea::BackgroundColorStyle, backgroundColorStyle, backgroundColorStyle) BASIC_D_READER_IMPL(Worksheet, PlotArea::BackgroundImageStyle, backgroundImageStyle, backgroundImageStyle) BASIC_D_READER_IMPL(Worksheet, Qt::BrushStyle, backgroundBrushStyle, backgroundBrushStyle) CLASS_D_READER_IMPL(Worksheet, QColor, backgroundFirstColor, backgroundFirstColor) CLASS_D_READER_IMPL(Worksheet, QColor, backgroundSecondColor, backgroundSecondColor) CLASS_D_READER_IMPL(Worksheet, QString, backgroundFileName, backgroundFileName) BASIC_D_READER_IMPL(Worksheet, float, backgroundOpacity, backgroundOpacity) /* =============================== getter methods for layout options ====================================== */ BASIC_D_READER_IMPL(Worksheet, Worksheet::Layout, layout, layout) BASIC_D_READER_IMPL(Worksheet, float, layoutTopMargin, layoutTopMargin) BASIC_D_READER_IMPL(Worksheet, float, layoutBottomMargin, layoutBottomMargin) BASIC_D_READER_IMPL(Worksheet, float, layoutLeftMargin, layoutLeftMargin) BASIC_D_READER_IMPL(Worksheet, float, layoutRightMargin, layoutRightMargin) BASIC_D_READER_IMPL(Worksheet, float, layoutHorizontalSpacing, layoutHorizontalSpacing) BASIC_D_READER_IMPL(Worksheet, float, layoutVerticalSpacing, layoutVerticalSpacing) BASIC_D_READER_IMPL(Worksheet, int, layoutRowCount, layoutRowCount) BASIC_D_READER_IMPL(Worksheet, int, layoutColumnCount, layoutColumnCount) CLASS_D_READER_IMPL(Worksheet, QString, theme, theme) /* ============================ setter methods and undo commands for general options ===================== */ void Worksheet::setUseViewSize(bool useViewSize) { if (useViewSize != d->useViewSize) { d->useViewSize = useViewSize; emit useViewSizeRequested(); } } STD_SETTER_CMD_IMPL_S(Worksheet, SetScaleContent, bool, scaleContent) void Worksheet::setScaleContent(bool scaleContent) { if (scaleContent != d->scaleContent) exec(new WorksheetSetScaleContentCmd(d, scaleContent, i18n("%1: change \"rescale the content\" property"))); } /* ============================ setter methods and undo commands for background options ================= */ STD_SETTER_CMD_IMPL_F_S(Worksheet, SetBackgroundType, PlotArea::BackgroundType, backgroundType, update) void Worksheet::setBackgroundType(PlotArea::BackgroundType type) { if (type != d->backgroundType) exec(new WorksheetSetBackgroundTypeCmd(d, type, i18n("%1: background type changed"))); } STD_SETTER_CMD_IMPL_F_S(Worksheet, SetBackgroundColorStyle, PlotArea::BackgroundColorStyle, backgroundColorStyle, update) void Worksheet::setBackgroundColorStyle(PlotArea::BackgroundColorStyle style) { if (style != d->backgroundColorStyle) exec(new WorksheetSetBackgroundColorStyleCmd(d, style, i18n("%1: background color style changed"))); } STD_SETTER_CMD_IMPL_F_S(Worksheet, SetBackgroundImageStyle, PlotArea::BackgroundImageStyle, backgroundImageStyle, update) void Worksheet::setBackgroundImageStyle(PlotArea::BackgroundImageStyle style) { if (style != d->backgroundImageStyle) exec(new WorksheetSetBackgroundImageStyleCmd(d, style, i18n("%1: background image style changed"))); } STD_SETTER_CMD_IMPL_F_S(Worksheet, SetBackgroundBrushStyle, Qt::BrushStyle, backgroundBrushStyle, update) void Worksheet::setBackgroundBrushStyle(Qt::BrushStyle style) { if (style != d->backgroundBrushStyle) exec(new WorksheetSetBackgroundBrushStyleCmd(d, style, i18n("%1: background brush style changed"))); } STD_SETTER_CMD_IMPL_F_S(Worksheet, SetBackgroundFirstColor, QColor, backgroundFirstColor, update) void Worksheet::setBackgroundFirstColor(const QColor &color) { if (color!= d->backgroundFirstColor) exec(new WorksheetSetBackgroundFirstColorCmd(d, color, i18n("%1: set background first color"))); } STD_SETTER_CMD_IMPL_F_S(Worksheet, SetBackgroundSecondColor, QColor, backgroundSecondColor, update) void Worksheet::setBackgroundSecondColor(const QColor &color) { if (color!= d->backgroundSecondColor) exec(new WorksheetSetBackgroundSecondColorCmd(d, color, i18n("%1: set background second color"))); } STD_SETTER_CMD_IMPL_F_S(Worksheet, SetBackgroundFileName, QString, backgroundFileName, update) void Worksheet::setBackgroundFileName(const QString& fileName) { if (fileName!= d->backgroundFileName) exec(new WorksheetSetBackgroundFileNameCmd(d, fileName, i18n("%1: set background image"))); } STD_SETTER_CMD_IMPL_F_S(Worksheet, SetBackgroundOpacity, float, backgroundOpacity, update) void Worksheet::setBackgroundOpacity(float opacity) { if (opacity != d->backgroundOpacity) exec(new WorksheetSetBackgroundOpacityCmd(d, opacity, i18n("%1: set opacity"))); } /* ============================ setter methods and undo commands for layout options ================= */ STD_SETTER_CMD_IMPL_F_S(Worksheet, SetLayout, Worksheet::Layout, layout, updateLayout) void Worksheet::setLayout(Worksheet::Layout layout) { if (layout != d->layout) { beginMacro(i18n("%1: set layout", name())); exec(new WorksheetSetLayoutCmd(d, layout, i18n("%1: set layout"))); endMacro(); } } STD_SETTER_CMD_IMPL_M_F_S(Worksheet, SetLayoutTopMargin, float, layoutTopMargin, updateLayout) void Worksheet::setLayoutTopMargin(float margin) { if (margin != d->layoutTopMargin) { beginMacro(i18n("%1: set layout top margin", name())); exec(new WorksheetSetLayoutTopMarginCmd(d, margin, i18n("%1: set layout top margin"))); endMacro(); } } STD_SETTER_CMD_IMPL_M_F_S(Worksheet, SetLayoutBottomMargin, float, layoutBottomMargin, updateLayout) void Worksheet::setLayoutBottomMargin(float margin) { if (margin != d->layoutBottomMargin) { beginMacro(i18n("%1: set layout bottom margin", name())); exec(new WorksheetSetLayoutBottomMarginCmd(d, margin, i18n("%1: set layout bottom margin"))); endMacro(); } } STD_SETTER_CMD_IMPL_M_F_S(Worksheet, SetLayoutLeftMargin, float, layoutLeftMargin, updateLayout) void Worksheet::setLayoutLeftMargin(float margin) { if (margin != d->layoutLeftMargin) { beginMacro(i18n("%1: set layout left margin", name())); exec(new WorksheetSetLayoutLeftMarginCmd(d, margin, i18n("%1: set layout left margin"))); endMacro(); } } STD_SETTER_CMD_IMPL_M_F_S(Worksheet, SetLayoutRightMargin, float, layoutRightMargin, updateLayout) void Worksheet::setLayoutRightMargin(float margin) { if (margin != d->layoutRightMargin) { beginMacro(i18n("%1: set layout right margin", name())); exec(new WorksheetSetLayoutRightMarginCmd(d, margin, i18n("%1: set layout right margin"))); endMacro(); } } STD_SETTER_CMD_IMPL_M_F_S(Worksheet, SetLayoutVerticalSpacing, float, layoutVerticalSpacing, updateLayout) void Worksheet::setLayoutVerticalSpacing(float spacing) { if (spacing != d->layoutVerticalSpacing) { beginMacro(i18n("%1: set layout vertical spacing", name())); exec(new WorksheetSetLayoutVerticalSpacingCmd(d, spacing, i18n("%1: set layout vertical spacing"))); endMacro(); } } STD_SETTER_CMD_IMPL_M_F_S(Worksheet, SetLayoutHorizontalSpacing, float, layoutHorizontalSpacing, updateLayout) void Worksheet::setLayoutHorizontalSpacing(float spacing) { if (spacing != d->layoutHorizontalSpacing) { beginMacro(i18n("%1: set layout horizontal spacing", name())); exec(new WorksheetSetLayoutHorizontalSpacingCmd(d, spacing, i18n("%1: set layout horizontal spacing"))); endMacro(); } } STD_SETTER_CMD_IMPL_M_F_S(Worksheet, SetLayoutRowCount, int, layoutRowCount, updateLayout) void Worksheet::setLayoutRowCount(int count) { if (count != d->layoutRowCount) { beginMacro(i18n("%1: set layout row count", name())); exec(new WorksheetSetLayoutRowCountCmd(d, count, i18n("%1: set layout row count"))); endMacro(); } } STD_SETTER_CMD_IMPL_M_F_S(Worksheet, SetLayoutColumnCount, int, layoutColumnCount, updateLayout) void Worksheet::setLayoutColumnCount(int count) { if (count != d->layoutColumnCount) { beginMacro(i18n("%1: set layout column count", name())); exec(new WorksheetSetLayoutColumnCountCmd(d, count, i18n("%1: set layout column count"))); endMacro(); } } class WorksheetSetPageRectCmd : public StandardMacroSetterCmd { public: WorksheetSetPageRectCmd(Worksheet::Private* target, QRectF newValue, const QString& description) : StandardMacroSetterCmd(target, &Worksheet::Private::pageRect, newValue, description) {} - virtual void finalize() { + void finalize() override { m_target->updatePageRect(); m_target->q->pageRectChanged(m_target->*m_field); } - virtual void finalizeUndo() { + void finalizeUndo() override { m_target->m_scene->setSceneRect(m_target->*m_field); m_target->q->pageRectChanged(m_target->*m_field); } }; void Worksheet::setPageRect(const QRectF& rect) { //don't allow any rectangulars of width/height equal to zero if (qFuzzyCompare(rect.width(), 0.) || qFuzzyCompare(rect.height(), 0.)) { pageRectChanged(d->pageRect); return; } if (rect != d->pageRect) { if (!d->useViewSize) { beginMacro(i18n("%1: set page size", name())); exec(new WorksheetSetPageRectCmd(d, rect, i18n("%1: set page size"))); endMacro(); } else { d->pageRect = rect; d->updatePageRect(); pageRectChanged(d->pageRect); } } } void Worksheet::setPrinting(bool on) const { QVector childElements = children(AbstractAspect::Recursive | AbstractAspect::IncludeHidden); for (auto* child : childElements) child->setPrinting(on); } STD_SETTER_CMD_IMPL_S(Worksheet, SetTheme, QString, theme) void Worksheet::setTheme(const QString& theme) { if (theme != d->theme) { if (!theme.isEmpty()) { beginMacro( i18n("%1: load theme %2", name(), theme) ); exec(new WorksheetSetThemeCmd(d, theme, i18n("%1: set theme"))); loadTheme(theme); endMacro(); } else { exec(new WorksheetSetThemeCmd(d, theme, i18n("%1: disable theming"))); } } } //############################################################################## //###################### Private implementation ############################### //############################################################################## WorksheetPrivate::WorksheetPrivate(Worksheet* owner):q(owner), m_scene(new QGraphicsScene()), scaleContent(false), suppressLayoutUpdate(false) { } QString WorksheetPrivate::name() const { return q->name(); } void WorksheetPrivate::updatePageRect() { QRectF oldRect = m_scene->sceneRect(); m_scene->setSceneRect(pageRect); if (layout != Worksheet::NoLayout) updateLayout(); else { if (scaleContent) { qreal horizontalRatio = pageRect.width() / oldRect.width(); qreal verticalRatio = pageRect.height() / oldRect.height(); QVector childElements = q->children(AbstractAspect::IncludeHidden); if (useViewSize) { //don't make the change of the geometry undoable/redoable if the view size is used. for (auto* elem : childElements) { elem->setUndoAware(false); elem->handleResize(horizontalRatio, verticalRatio, true); elem->setUndoAware(true); } } else { for (auto* child : childElements) child->handleResize(horizontalRatio, verticalRatio, true); } } } } void WorksheetPrivate::update() { q->update(); } WorksheetPrivate::~WorksheetPrivate() { delete m_scene; } void WorksheetPrivate::updateLayout(bool undoable) { if (suppressLayoutUpdate) return; QVector list = q->children(); if (layout==Worksheet::NoLayout) { for(auto* elem : list) elem->graphicsItem()->setFlag(QGraphicsItem::ItemIsMovable, true); return; } float x=layoutLeftMargin; float y=layoutTopMargin; float w, h; int count=list.count(); if (layout == Worksheet::VerticalLayout) { w= m_scene->sceneRect().width() - layoutLeftMargin - layoutRightMargin; h=(m_scene->sceneRect().height()-layoutTopMargin-layoutBottomMargin- (count-1)*layoutVerticalSpacing)/count; foreach(WorksheetElementContainer* elem, list) { setContainerRect(elem, x, y, h, w, undoable); y+=h + layoutVerticalSpacing; } } else if (layout == Worksheet::HorizontalLayout) { w=(m_scene->sceneRect().width()-layoutLeftMargin-layoutRightMargin- (count-1)*layoutHorizontalSpacing)/count; h= m_scene->sceneRect().height() - layoutTopMargin-layoutBottomMargin; foreach(WorksheetElementContainer* elem, list) { setContainerRect(elem, x, y, h, w, undoable); x+=w + layoutHorizontalSpacing; } } else { //GridLayout //add new rows, if not sufficient if (count>layoutRowCount*layoutColumnCount) { layoutRowCount = floor( (float)count/layoutColumnCount + 0.5); emit q->layoutRowCountChanged(layoutRowCount); } w=(m_scene->sceneRect().width()-layoutLeftMargin-layoutRightMargin- (layoutColumnCount-1)*layoutHorizontalSpacing)/layoutColumnCount; h=(m_scene->sceneRect().height()-layoutTopMargin-layoutBottomMargin- (layoutRowCount-1)*layoutVerticalSpacing)/layoutRowCount; int columnIndex=0; //counts the columns in a row foreach(WorksheetElementContainer* elem, list) { setContainerRect(elem, x, y, h, w, undoable); x+=w + layoutHorizontalSpacing; columnIndex++; if (columnIndex==layoutColumnCount) { columnIndex=0; x=layoutLeftMargin; y+=h + layoutVerticalSpacing; } } } } void WorksheetPrivate::setContainerRect(WorksheetElementContainer* elem, float x, float y, float h, float w, bool undoable) { if (useViewSize) { //when using the view size, no need to put rect changes onto the undo-stack elem->setUndoAware(false); elem->setRect(QRectF(x,y,w,h)); elem->setUndoAware(true); } else { //don't put rect changed onto the undo-stack if undoable-flag is set to true, //e.g. when new child is added or removed (the layout and the childrend rects will be updated anyway) if (!undoable) { elem->setUndoAware(false); elem->setRect(QRectF(x,y,w,h)); elem->setUndoAware(true); } else elem->setRect(QRectF(x,y,w,h)); } elem->graphicsItem()->setFlag(QGraphicsItem::ItemIsMovable, false); } //############################################################################## //################## Serialization/Deserialization ########################### //############################################################################## //! Save as XML void Worksheet::save(QXmlStreamWriter* writer) const { writer->writeStartElement( "worksheet" ); writeBasicAttributes(writer); writeCommentElement(writer); //applied theme if (!d->theme.isEmpty()){ writer->writeStartElement( "theme" ); writer->writeAttribute("name", d->theme); writer->writeEndElement(); } //geometry writer->writeStartElement( "geometry" ); QRectF rect = d->m_scene->sceneRect(); writer->writeAttribute( "x", QString::number(rect.x()) ); writer->writeAttribute( "y", QString::number(rect.y()) ); writer->writeAttribute( "width", QString::number(rect.width()) ); writer->writeAttribute( "height", QString::number(rect.height()) ); writer->writeAttribute( "useViewSize", QString::number(d->useViewSize) ); writer->writeEndElement(); //layout writer->writeStartElement( "layout" ); writer->writeAttribute( "layout", QString::number(d->layout) ); writer->writeAttribute( "topMargin", QString::number(d->layoutTopMargin) ); writer->writeAttribute( "bottomMargin", QString::number(d->layoutBottomMargin) ); writer->writeAttribute( "leftMargin", QString::number(d->layoutLeftMargin) ); writer->writeAttribute( "rightMargin", QString::number(d->layoutRightMargin) ); writer->writeAttribute( "verticalSpacing", QString::number(d->layoutVerticalSpacing) ); writer->writeAttribute( "horizontalSpacing", QString::number(d->layoutHorizontalSpacing) ); writer->writeAttribute( "columnCount", QString::number(d->layoutColumnCount) ); writer->writeAttribute( "rowCount", QString::number(d->layoutRowCount) ); writer->writeEndElement(); //background properties writer->writeStartElement( "background" ); writer->writeAttribute( "type", QString::number(d->backgroundType) ); writer->writeAttribute( "colorStyle", QString::number(d->backgroundColorStyle) ); writer->writeAttribute( "imageStyle", QString::number(d->backgroundImageStyle) ); writer->writeAttribute( "brushStyle", QString::number(d->backgroundBrushStyle) ); writer->writeAttribute( "firstColor_r", QString::number(d->backgroundFirstColor.red()) ); writer->writeAttribute( "firstColor_g", QString::number(d->backgroundFirstColor.green()) ); writer->writeAttribute( "firstColor_b", QString::number(d->backgroundFirstColor.blue()) ); writer->writeAttribute( "secondColor_r", QString::number(d->backgroundSecondColor.red()) ); writer->writeAttribute( "secondColor_g", QString::number(d->backgroundSecondColor.green()) ); writer->writeAttribute( "secondColor_b", QString::number(d->backgroundSecondColor.blue()) ); writer->writeAttribute( "fileName", d->backgroundFileName ); writer->writeAttribute( "opacity", QString::number(d->backgroundOpacity) ); writer->writeEndElement(); //serialize all children for (auto* child : children(IncludeHidden)) child->save(writer); writer->writeEndElement(); // close "worksheet" section } //! Load from XML bool Worksheet::load(XmlStreamReader* reader, bool preview) { if(!reader->isStartElement() || reader->name() != "worksheet") { reader->raiseError(i18n("no worksheet element found")); return false; } if (!readBasicAttributes(reader)) return false; //clear the theme that was potentially set in init() in order to correctly load here the worksheets without any theme used d->theme = ""; QString attributeWarning = i18n("Attribute '%1' missing or empty, default value is used"); QXmlStreamAttributes attribs; QString str; QRectF rect; while (!reader->atEnd()) { reader->readNext(); if (reader->isEndElement() && reader->name() == "worksheet") break; if (!reader->isStartElement()) continue; if (reader->name() == "comment") { if (!readCommentElement(reader)) return false; } else if (!preview && reader->name() == "theme") { attribs = reader->attributes(); d->theme = attribs.value("name").toString(); } else if (!preview && reader->name() == "geometry") { attribs = reader->attributes(); str = attribs.value("x").toString(); if(str.isEmpty()) reader->raiseWarning(attributeWarning.arg("'x'")); else rect.setX(str.toDouble()); str = attribs.value("y").toString(); if(str.isEmpty()) reader->raiseWarning(attributeWarning.arg("'y'")); else rect.setY(str.toDouble()); str = attribs.value("width").toString(); if(str.isEmpty()) reader->raiseWarning(attributeWarning.arg("'width'")); else rect.setWidth(str.toDouble()); str = attribs.value("height").toString(); if(str.isEmpty()) reader->raiseWarning(attributeWarning.arg("'height'")); else rect.setHeight(str.toDouble()); str = attribs.value("useViewSize").toString(); if(str.isEmpty()) reader->raiseWarning(attributeWarning.arg("'useViewSize'")); else d->useViewSize = str.toInt(); } else if (!preview && reader->name() == "layout") { attribs = reader->attributes(); str = attribs.value("layout").toString(); if(str.isEmpty()) reader->raiseWarning(attributeWarning.arg("layout")); else d->layout = Worksheet::Layout(str.toInt()); str = attribs.value("topMargin").toString(); if(str.isEmpty()) reader->raiseWarning(attributeWarning.arg("topMargin")); else d->layoutTopMargin = str.toDouble(); str = attribs.value("bottomMargin").toString(); if(str.isEmpty()) reader->raiseWarning(attributeWarning.arg("bottomMargin")); else d->layoutBottomMargin = str.toDouble(); str = attribs.value("leftMargin").toString(); if(str.isEmpty()) reader->raiseWarning(attributeWarning.arg("leftMargin")); else d->layoutLeftMargin = str.toDouble(); str = attribs.value("rightMargin").toString(); if(str.isEmpty()) reader->raiseWarning(attributeWarning.arg("rightMargin")); else d->layoutRightMargin = str.toDouble(); str = attribs.value("verticalSpacing").toString(); if(str.isEmpty()) reader->raiseWarning(attributeWarning.arg("verticalSpacing")); else d->layoutVerticalSpacing = str.toDouble(); str = attribs.value("horizontalSpacing").toString(); if(str.isEmpty()) reader->raiseWarning(attributeWarning.arg("horizontalSpacing")); else d->layoutHorizontalSpacing = str.toDouble(); str = attribs.value("columnCount").toString(); if(str.isEmpty()) reader->raiseWarning(attributeWarning.arg("columnCount")); else d->layoutColumnCount = str.toInt(); str = attribs.value("rowCount").toString(); if(str.isEmpty()) reader->raiseWarning(attributeWarning.arg("rowCount")); else d->layoutRowCount = str.toInt(); } else if (!preview && reader->name() == "background") { attribs = reader->attributes(); str = attribs.value("type").toString(); if(str.isEmpty()) reader->raiseWarning(attributeWarning.arg("type")); else d->backgroundType = PlotArea::BackgroundType(str.toInt()); str = attribs.value("colorStyle").toString(); if(str.isEmpty()) reader->raiseWarning(attributeWarning.arg("colorStyle")); else d->backgroundColorStyle = PlotArea::BackgroundColorStyle(str.toInt()); str = attribs.value("imageStyle").toString(); if(str.isEmpty()) reader->raiseWarning(attributeWarning.arg("imageStyle")); else d->backgroundImageStyle = PlotArea::BackgroundImageStyle(str.toInt()); str = attribs.value("brushStyle").toString(); if(str.isEmpty()) reader->raiseWarning(attributeWarning.arg("brushStyle")); else d->backgroundBrushStyle = Qt::BrushStyle(str.toInt()); str = attribs.value("firstColor_r").toString(); if(str.isEmpty()) reader->raiseWarning(attributeWarning.arg("firstColor_r")); else d->backgroundFirstColor.setRed(str.toInt()); str = attribs.value("firstColor_g").toString(); if(str.isEmpty()) reader->raiseWarning(attributeWarning.arg("firstColor_g")); else d->backgroundFirstColor.setGreen(str.toInt()); str = attribs.value("firstColor_b").toString(); if(str.isEmpty()) reader->raiseWarning(attributeWarning.arg("firstColor_b")); else d->backgroundFirstColor.setBlue(str.toInt()); str = attribs.value("secondColor_r").toString(); if(str.isEmpty()) reader->raiseWarning(attributeWarning.arg("secondColor_r")); else d->backgroundSecondColor.setRed(str.toInt()); str = attribs.value("secondColor_g").toString(); if(str.isEmpty()) reader->raiseWarning(attributeWarning.arg("secondColor_g")); else d->backgroundSecondColor.setGreen(str.toInt()); str = attribs.value("secondColor_b").toString(); if(str.isEmpty()) reader->raiseWarning(attributeWarning.arg("secondColor_b")); else d->backgroundSecondColor.setBlue(str.toInt()); str = attribs.value("fileName").toString(); d->backgroundFileName = str; str = attribs.value("opacity").toString(); if(str.isEmpty()) reader->raiseWarning(attributeWarning.arg("opacity")); else d->backgroundOpacity = str.toDouble(); } else if(reader->name() == "cartesianPlot") { CartesianPlot* plot = new CartesianPlot(""); plot->setIsLoading(true); if (!plot->load(reader, preview)) { delete plot; return false; } else { addChildFast(plot); plot->setIsLoading(false); } } else if(reader->name() == "textLabel") { TextLabel* label = new TextLabel(""); if (!label->load(reader, preview)) { delete label; return false; } else addChildFast(label); } else { // unknown element reader->raiseWarning(i18n("unknown element '%1'", reader->name().toString())); if (!reader->skipToEndElement()) return false; } } if (!preview) { d->m_scene->setSceneRect(rect); d->updateLayout(); } return true; } //############################################################################## //######################### Theme management ################################## //############################################################################## void Worksheet::loadTheme(const QString& theme) { KConfig config(ThemeHandler::themeFilePath(theme), KConfig::SimpleConfig); //apply the same background color for Worksheet as for the CartesianPlot const KConfigGroup group = config.group("CartesianPlot"); this->setBackgroundBrushStyle((Qt::BrushStyle)group.readEntry("BackgroundBrushStyle",(int) this->backgroundBrushStyle())); this->setBackgroundColorStyle((PlotArea::BackgroundColorStyle)(group.readEntry("BackgroundColorStyle",(int) this->backgroundColorStyle()))); this->setBackgroundFirstColor(group.readEntry("BackgroundFirstColor",(QColor) this->backgroundFirstColor())); this->setBackgroundImageStyle((PlotArea::BackgroundImageStyle)group.readEntry("BackgroundImageStyle",(int) this->backgroundImageStyle())); this->setBackgroundOpacity(group.readEntry("BackgroundOpacity", this->backgroundOpacity())); this->setBackgroundSecondColor(group.readEntry("BackgroundSecondColor",(QColor) this->backgroundSecondColor())); this->setBackgroundType((PlotArea::BackgroundType)(group.readEntry("BackgroundType",(int) this->backgroundType()))); //load the theme for all the children const QVector& childElements = children(AbstractAspect::IncludeHidden); for (auto* child : childElements) child->loadThemeConfig(config); } diff --git a/src/backend/worksheet/Worksheet.h b/src/backend/worksheet/Worksheet.h index efaa113d2..659555622 100644 --- a/src/backend/worksheet/Worksheet.h +++ b/src/backend/worksheet/Worksheet.h @@ -1,176 +1,176 @@ /*************************************************************************** File : Worksheet.h Project : LabPlot Description : Worksheet (2D visualization) part -------------------------------------------------------------------- Copyright : (C) 2009 Tilman Benkert (thzs@gmx.net) Copyright : (C) 2011-2016 by Alexander Semke (alexander.semke@web.de) ***************************************************************************/ /*************************************************************************** * * * 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 WORKSHEET_H #define WORKSHEET_H #include "backend/core/AbstractPart.h" #include "backend/core/AbstractScriptingEngine.h" #include "backend/worksheet/plots/PlotArea.h" #include "backend/lib/macros.h" class QGraphicsItem; class QGraphicsScene; class QRectF; class WorksheetPrivate; class Worksheet: public AbstractPart, public scripted { Q_OBJECT public: Worksheet(AbstractScriptingEngine* engine, const QString& name, bool loading = false); - ~Worksheet(); + ~Worksheet() override; enum Unit {Millimeter, Centimeter, Inch, Point}; enum Layout {NoLayout, VerticalLayout, HorizontalLayout, GridLayout}; static float convertToSceneUnits(const float value, const Worksheet::Unit unit); static float convertFromSceneUnits(const float value, const Worksheet::Unit unit); - virtual QIcon icon() const override; - virtual QMenu* createContextMenu() override; - virtual QWidget* view() const override; - virtual QVector dependsOn() const override; + QIcon icon() const override; + QMenu* createContextMenu() override; + QWidget* view() const override; + QVector dependsOn() const override; - virtual bool exportView() const override; - virtual bool printView() override; - virtual bool printPreview() const override; + bool exportView() const override; + bool printView() override; + bool printPreview() const override; - virtual void save(QXmlStreamWriter*) const override; - virtual bool load(XmlStreamReader*, bool preview) override; + void save(QXmlStreamWriter*) const override; + bool load(XmlStreamReader*, bool preview) override; QRectF pageRect() const; void setPageRect(const QRectF&); QGraphicsScene* scene() const; void update(); void setPrinting(bool) const; void setThemeName(const QString&); void setItemSelectedInView(const QGraphicsItem*, const bool); void setSelectedInView(const bool); void deleteAspectFromGraphicsItem(const QGraphicsItem*); void setIsClosing(); BASIC_D_ACCESSOR_DECL(float, backgroundOpacity, BackgroundOpacity) BASIC_D_ACCESSOR_DECL(PlotArea::BackgroundType, backgroundType, BackgroundType) BASIC_D_ACCESSOR_DECL(PlotArea::BackgroundColorStyle, backgroundColorStyle, BackgroundColorStyle) BASIC_D_ACCESSOR_DECL(PlotArea::BackgroundImageStyle, backgroundImageStyle, BackgroundImageStyle) BASIC_D_ACCESSOR_DECL(Qt::BrushStyle, backgroundBrushStyle, BackgroundBrushStyle) CLASS_D_ACCESSOR_DECL(QColor, backgroundFirstColor, BackgroundFirstColor) CLASS_D_ACCESSOR_DECL(QColor, backgroundSecondColor, BackgroundSecondColor) CLASS_D_ACCESSOR_DECL(QString, backgroundFileName, BackgroundFileName) BASIC_D_ACCESSOR_DECL(bool, scaleContent, ScaleContent) BASIC_D_ACCESSOR_DECL(bool, useViewSize, UseViewSize) BASIC_D_ACCESSOR_DECL(Worksheet::Layout, layout, Layout) BASIC_D_ACCESSOR_DECL(float, layoutTopMargin, LayoutTopMargin) BASIC_D_ACCESSOR_DECL(float, layoutBottomMargin, LayoutBottomMargin) BASIC_D_ACCESSOR_DECL(float, layoutLeftMargin, LayoutLeftMargin) BASIC_D_ACCESSOR_DECL(float, layoutRightMargin, LayoutRightMargin) BASIC_D_ACCESSOR_DECL(float, layoutHorizontalSpacing, LayoutHorizontalSpacing) BASIC_D_ACCESSOR_DECL(float, layoutVerticalSpacing, LayoutVerticalSpacing) BASIC_D_ACCESSOR_DECL(int, layoutRowCount, LayoutRowCount) BASIC_D_ACCESSOR_DECL(int, layoutColumnCount, LayoutColumnCount) QString theme() const; void setSuppressLayoutUpdate(bool); void updateLayout(); typedef WorksheetPrivate Private; public slots: void setTheme(const QString&); private: void init(); WorksheetElement* aspectFromGraphicsItem(const WorksheetElement*, const QGraphicsItem*) const; void loadTheme(const QString&); WorksheetPrivate* const d; friend class WorksheetPrivate; private slots: void handleAspectAdded(const AbstractAspect*); void handleAspectAboutToBeRemoved(const AbstractAspect*); void handleAspectRemoved(const AbstractAspect* parent, const AbstractAspect* before, const AbstractAspect* child); - virtual void childSelected(const AbstractAspect*) override; - virtual void childDeselected(const AbstractAspect*) override; + void childSelected(const AbstractAspect*) override; + void childDeselected(const AbstractAspect*) override; signals: void requestProjectContextMenu(QMenu*); void itemSelected(QGraphicsItem*); void itemDeselected(QGraphicsItem*); void requestUpdate(); void useViewSizeRequested(); friend class WorksheetSetBackgroundTypeCmd; friend class WorksheetSetBackgroundColorStyleCmd; friend class WorksheetSetBackgroundImageStyleCmd; friend class WorksheetSetBackgroundBrushStyleCmd; friend class WorksheetSetBackgroundFirstColorCmd; friend class WorksheetSetBackgroundSecondColorCmd; friend class WorksheetSetBackgroundFileNameCmd; friend class WorksheetSetBackgroundOpacityCmd; friend class WorksheetSetScaleContentCmd; friend class WorksheetSetPageRectCmd; friend class WorksheetSetLayoutCmd; friend class WorksheetSetLayoutTopMarginCmd; friend class WorksheetSetLayoutBottomMarginCmd; friend class WorksheetSetLayoutLeftMarginCmd; friend class WorksheetSetLayoutRightMarginCmd; friend class WorksheetSetLayoutVerticalSpacingCmd; friend class WorksheetSetLayoutHorizontalSpacingCmd; friend class WorksheetSetLayoutRowCountCmd; friend class WorksheetSetLayoutColumnCountCmd; friend class WorksheetSetThemeCmd; void backgroundTypeChanged(PlotArea::BackgroundType); void backgroundColorStyleChanged(PlotArea::BackgroundColorStyle); void backgroundImageStyleChanged(PlotArea::BackgroundImageStyle); void backgroundBrushStyleChanged(Qt::BrushStyle); void backgroundFirstColorChanged(const QColor&); void backgroundSecondColorChanged(const QColor&); void backgroundFileNameChanged(const QString&); void backgroundOpacityChanged(float); void scaleContentChanged(bool); void pageRectChanged(const QRectF&); void layoutChanged(Worksheet::Layout); void layoutTopMarginChanged(float); void layoutBottomMarginChanged(float); void layoutLeftMarginChanged(float); void layoutRightMarginChanged(float); void layoutVerticalSpacingChanged(float); void layoutHorizontalSpacingChanged(float); void layoutRowCountChanged(int); void layoutColumnCountChanged(int); void themeChanged(const QString&); }; #endif diff --git a/src/backend/worksheet/WorksheetElement.h b/src/backend/worksheet/WorksheetElement.h index e81e57a21..79a427bd5 100644 --- a/src/backend/worksheet/WorksheetElement.h +++ b/src/backend/worksheet/WorksheetElement.h @@ -1,86 +1,86 @@ /*************************************************************************** File : WorksheetElement.h Project : LabPlot Description : Base class for all Worksheet children. -------------------------------------------------------------------- Copyright : (C) 2009 Tilman Benkert (thzs@gmx.net) Copyright : (C) 2012-2015 by Alexander Semke (alexander.semke@web.de) ***************************************************************************/ /*************************************************************************** * * * 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 WORKSHEETELEMENT_H #define WORKSHEETELEMENT_H #include "backend/core/AbstractAspect.h" #include class QAction; class QGraphicsItem; class QPen; class KConfig; class WorksheetElement : public AbstractAspect { Q_OBJECT public: explicit WorksheetElement(const QString&); - virtual ~WorksheetElement(); + ~WorksheetElement() override; enum WorksheetElementName {NameCartesianPlot = 1}; virtual QGraphicsItem* graphicsItem() const = 0; virtual void setZValue(qreal); virtual void setVisible(bool on) = 0; virtual bool isVisible() const = 0; virtual bool isFullyVisible() const; virtual void setPrinting(bool) = 0; - virtual QMenu* createContextMenu(); + QMenu* createContextMenu() override; virtual void loadThemeConfig(const KConfig&); virtual void saveThemeConfig(const KConfig&); static QPainterPath shapeFromPath(const QPainterPath&, const QPen&); virtual void handleResize(double horizontalRatio, double verticalRatio, bool pageResize = false) = 0; public slots: virtual void retransform() = 0; private: QMenu* m_drawingOrderMenu; QMenu* m_moveBehindMenu; QMenu* m_moveInFrontOfMenu; private slots: void prepareMoveBehindMenu(); void prepareMoveInFrontOfMenu(); void execMoveBehind(QAction*); void execMoveInFrontOf(QAction*); signals: friend class AbstractPlotSetHorizontalPaddingCmd; friend class AbstractPlotSetVerticalPaddingCmd; void horizontalPaddingChanged(float); void verticalPaddingChanged(float); void hovered(); void unhovered(); }; #endif diff --git a/src/backend/worksheet/WorksheetElementContainer.h b/src/backend/worksheet/WorksheetElementContainer.h index 5fb00f4e6..434dfeb47 100644 --- a/src/backend/worksheet/WorksheetElementContainer.h +++ b/src/backend/worksheet/WorksheetElementContainer.h @@ -1,79 +1,79 @@ /*************************************************************************** File : WorksheetElementContainer.h Project : LabPlot Description : Worksheet element container - parent of multiple elements. -------------------------------------------------------------------- Copyright : (C) 2009 Tilman Benkert (thzs@gmx.net) Copyright : (C) 2012-2017 Alexander Semke (alexander.semke@web.de) ***************************************************************************/ /*************************************************************************** * * * 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 WORKSHEETELEMENTCONTAINER_H #define WORKSHEETELEMENTCONTAINER_H #include "backend/worksheet/WorksheetElement.h" class WorksheetElementContainerPrivate; //TODO: align class WorksheetElementContainer : public WorksheetElement { Q_OBJECT public: explicit WorksheetElementContainer(const QString&); - virtual ~WorksheetElementContainer(); + ~WorksheetElementContainer() override; - virtual QGraphicsItem* graphicsItem() const override; + QGraphicsItem* graphicsItem() const override; - virtual void setVisible(bool) override; - virtual bool isVisible() const override; - virtual bool isFullyVisible() const override; - virtual void setPrinting(bool) override; + void setVisible(bool) override; + bool isVisible() const override; + bool isFullyVisible() const override; + void setPrinting(bool) override; QRectF rect() const; virtual void setRect(const QRectF&) = 0; virtual void prepareGeometryChange(); typedef WorksheetElementContainerPrivate Private; public slots: - virtual void retransform() override; - virtual void handleResize(double horizontalRatio, double verticalRatio, bool pageResize = false) override; + void retransform() override; + void handleResize(double horizontalRatio, double verticalRatio, bool pageResize = false) override; void childHovered(); void childUnhovered(); protected: WorksheetElementContainerPrivate* const d_ptr; WorksheetElementContainer(const QString&, WorksheetElementContainerPrivate*); protected slots: virtual void handleAspectAdded(const AbstractAspect*); private: Q_DECLARE_PRIVATE(WorksheetElementContainer) signals: friend class WorksheetElementContainerSetVisibleCmd; void visibleChanged(bool); }; #endif diff --git a/src/backend/worksheet/WorksheetElementContainerPrivate.h b/src/backend/worksheet/WorksheetElementContainerPrivate.h index 382944af2..667b4bb3f 100644 --- a/src/backend/worksheet/WorksheetElementContainerPrivate.h +++ b/src/backend/worksheet/WorksheetElementContainerPrivate.h @@ -1,65 +1,65 @@ /*************************************************************************** File : WorksheetElementContainerPrivate.h Project : LabPlot Description : Private members of WorksheetElementContainer. -------------------------------------------------------------------- Copyright : (C) 2009 Tilman Benkert (thzs@gmx.net) Copyright : (C) 2012-2015 by Alexander Semke (alexander.semke@web.de) ***************************************************************************/ /*************************************************************************** * * * 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 WORKSHEETELEMENTCONTAINERPRIVATE_H #define WORKSHEETELEMENTCONTAINERPRIVATE_H #include class QGraphicsSceneContextMenuEvent; class WorksheetElementContainer; class WorksheetElementContainerPrivate : public QGraphicsItem { public: explicit WorksheetElementContainerPrivate(WorksheetElementContainer*); - virtual ~WorksheetElementContainerPrivate(){} + ~WorksheetElementContainerPrivate() override{} QString name() const; - virtual QRectF boundingRect() const; - virtual void paint(QPainter*, const QStyleOptionGraphicsItem*, QWidget* widget = 0); - virtual void hoverEnterEvent(QGraphicsSceneHoverEvent*); - virtual void hoverLeaveEvent(QGraphicsSceneHoverEvent*); + QRectF boundingRect() const override; + void paint(QPainter*, const QStyleOptionGraphicsItem*, QWidget* widget = 0) override; + void hoverEnterEvent(QGraphicsSceneHoverEvent*) override; + void hoverLeaveEvent(QGraphicsSceneHoverEvent*) override; bool swapVisible(bool on); void prepareGeometryChangeRequested(); void recalcShapeAndBoundingRect(); - void contextMenuEvent(QGraphicsSceneContextMenuEvent*); + void contextMenuEvent(QGraphicsSceneContextMenuEvent*) override; WorksheetElementContainer* q; QRectF boundingRectangle; QPainterPath containerShape; QRectF rect; bool m_hovered; bool m_printing; signals: void selectedChange(QGraphicsItem*); }; #endif diff --git a/src/backend/worksheet/WorksheetElementGroup.h b/src/backend/worksheet/WorksheetElementGroup.h index d320632ea..93d33b7d3 100644 --- a/src/backend/worksheet/WorksheetElementGroup.h +++ b/src/backend/worksheet/WorksheetElementGroup.h @@ -1,47 +1,47 @@ /*************************************************************************** File : WorksheetElementGroup.h Project : LabPlot/SciDAVis Description : Groups worksheet elements for collective operations. -------------------------------------------------------------------- Copyright : (C) 2009 Tilman Benkert (thzs*gmx.net) (replace * with @ in the email addresses) ***************************************************************************/ /*************************************************************************** * * * 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 WORKSHEETELEMENTGROUP_H #define WORKSHEETELEMENTGROUP_H #include "backend/worksheet/WorksheetElementContainer.h" class WorksheetElementGroup: public WorksheetElementContainer { Q_OBJECT public: explicit WorksheetElementGroup(const QString &name); - ~WorksheetElementGroup(); + ~WorksheetElementGroup() override; protected: WorksheetElementGroup(const QString &name, WorksheetElementContainerPrivate *dd); }; #endif diff --git a/src/backend/worksheet/plots/AbstractPlot.h b/src/backend/worksheet/plots/AbstractPlot.h index d75b09aab..e25d6f7b9 100644 --- a/src/backend/worksheet/plots/AbstractPlot.h +++ b/src/backend/worksheet/plots/AbstractPlot.h @@ -1,69 +1,69 @@ /*************************************************************************** File : AbstractPlot.h Project : LabPlot Description : Base class for plots of different types -------------------------------------------------------------------- Copyright : (C) 2009 Tilman Benkert (thzs@gmx.net) Copyright : (C) 2011-2017 by Alexander Semke (alexander.semke@web.de) ***************************************************************************/ /*************************************************************************** * * * 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 ABSTRACTPLOT_H #define ABSTRACTPLOT_H #include "backend/worksheet/WorksheetElementContainer.h" #include "backend/lib/macros.h" class AbstractCoordinateSystem; class PlotArea; class TextLabel; class AbstractPlotPrivate; class AbstractPlot : public WorksheetElementContainer { Q_OBJECT public: explicit AbstractPlot(const QString &name); - virtual ~AbstractPlot(){} + ~AbstractPlot() override{} - virtual void handleResize(double horizontalRatio, double verticalRatio, bool pageResize) override; + void handleResize(double horizontalRatio, double verticalRatio, bool pageResize) override; AbstractCoordinateSystem* coordinateSystem() const; PlotArea* plotArea(); TextLabel* title(); BASIC_D_ACCESSOR_DECL(float, horizontalPadding, HorizontalPadding) BASIC_D_ACCESSOR_DECL(float, verticalPadding, VerticalPadding) typedef AbstractPlotPrivate Private; protected: AbstractPlot(const QString&, AbstractPlotPrivate*); AbstractCoordinateSystem* m_coordinateSystem; PlotArea* m_plotArea; TextLabel* m_title; private: void init(); Q_DECLARE_PRIVATE(AbstractPlot) }; #endif diff --git a/src/backend/worksheet/plots/AbstractPlotPrivate.h b/src/backend/worksheet/plots/AbstractPlotPrivate.h index 0289e5759..de1f24cbf 100644 --- a/src/backend/worksheet/plots/AbstractPlotPrivate.h +++ b/src/backend/worksheet/plots/AbstractPlotPrivate.h @@ -1,46 +1,46 @@ /*************************************************************************** File : AbstractPlotPrivate.h Project : LabPlot Description : Private members of AbstractPlot ------------------------------------------------------------------- Copyright : (C) 2012-2015 Alexander Semke (alexander.semke@web.de) ***************************************************************************/ /*************************************************************************** * * * 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 ABSTRACTPLOTPRIVATE_H #define ABSTRACTPLOTPRIVATE_H #include "backend/worksheet/WorksheetElementContainerPrivate.h" class AbstractPlotPrivate:public WorksheetElementContainerPrivate { public: explicit AbstractPlotPrivate(AbstractPlot* owner); - virtual ~AbstractPlotPrivate() {} + ~AbstractPlotPrivate() override {} virtual QString name() const; virtual void retransform() {} float horizontalPadding; //horiz. offset between the plot area and the area defining the coodinate system, in scene units float verticalPadding; //vert. offset between the plot area and the area defining the coodinate system, in scene units }; #endif diff --git a/src/backend/worksheet/plots/PlotArea.h b/src/backend/worksheet/plots/PlotArea.h index 430b04190..541b2b700 100644 --- a/src/backend/worksheet/plots/PlotArea.h +++ b/src/backend/worksheet/plots/PlotArea.h @@ -1,116 +1,116 @@ /*************************************************************************** File : PlotArea.h Project : LabPlot Description : Plot area (for background filling and clipping). -------------------------------------------------------------------- Copyright : (C) 2011-2015 by Alexander Semke (alexander.semke@web.de) Copyright : (C) 2012-2013 by Stefan Gerlach (stefan.gerlach@uni-konstanz.de) ***************************************************************************/ /*************************************************************************** * * * 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 PLOTAREA_H #define PLOTAREA_H #include "backend/worksheet/WorksheetElement.h" #include "backend/lib/macros.h" class PlotAreaPrivate; //TODO: align class PlotArea : public WorksheetElement { Q_OBJECT public: explicit PlotArea(const QString& name); - virtual ~PlotArea(); + ~PlotArea() override; enum BackgroundType {Color, Image, Pattern}; enum BackgroundColorStyle {SingleColor, HorizontalLinearGradient, VerticalLinearGradient, TopLeftDiagonalLinearGradient, BottomLeftDiagonalLinearGradient, RadialGradient }; enum BackgroundImageStyle {ScaledCropped, Scaled, ScaledAspectRatio, Centered, Tiled, CenterTiled}; - virtual QGraphicsItem* graphicsItem() const override; - virtual void setVisible(bool on) override; - virtual bool isVisible() const override; - virtual void setPrinting(bool) override {}; - virtual void loadThemeConfig(const KConfig& config) override; - virtual void saveThemeConfig(const KConfig& config) override; + QGraphicsItem* graphicsItem() const override; + void setVisible(bool on) override; + bool isVisible() const override; + void setPrinting(bool) override {}; + void loadThemeConfig(const KConfig& config) override; + void saveThemeConfig(const KConfig& config) override; BASIC_D_ACCESSOR_DECL(PlotArea::BackgroundType, backgroundType, BackgroundType) BASIC_D_ACCESSOR_DECL(PlotArea::BackgroundColorStyle, backgroundColorStyle, BackgroundColorStyle) BASIC_D_ACCESSOR_DECL(PlotArea::BackgroundImageStyle, backgroundImageStyle, BackgroundImageStyle) BASIC_D_ACCESSOR_DECL(Qt::BrushStyle, backgroundBrushStyle, BackgroundBrushStyle) CLASS_D_ACCESSOR_DECL(QColor, backgroundFirstColor, BackgroundFirstColor) CLASS_D_ACCESSOR_DECL(QColor, backgroundSecondColor, BackgroundSecondColor) CLASS_D_ACCESSOR_DECL(QString, backgroundFileName, BackgroundFileName) BASIC_D_ACCESSOR_DECL(qreal, backgroundOpacity, BackgroundOpacity) CLASS_D_ACCESSOR_DECL(QPen, borderPen, BorderPen) BASIC_D_ACCESSOR_DECL(qreal, borderCornerRadius, BorderCornerRadius) BASIC_D_ACCESSOR_DECL(qreal, borderOpacity, BorderOpacity) BASIC_D_ACCESSOR_DECL(bool, clippingEnabled, ClippingEnabled) CLASS_D_ACCESSOR_DECL(QRectF, rect, Rect) - virtual void save(QXmlStreamWriter*) const override; - virtual bool load(XmlStreamReader*, bool preview) override; + void save(QXmlStreamWriter*) const override; + bool load(XmlStreamReader*, bool preview) override; - virtual void retransform() override; - virtual void handleResize(double horizontalRatio, double verticalRatio, bool pageResize) override; + void retransform() override; + void handleResize(double horizontalRatio, double verticalRatio, bool pageResize) override; typedef PlotAreaPrivate Private; protected: PlotArea(const QString& name, PlotAreaPrivate* dd); PlotAreaPrivate* const d_ptr; private: Q_DECLARE_PRIVATE(PlotArea) void init(); signals: friend class PlotAreaSetBackgroundTypeCmd; friend class PlotAreaSetBackgroundColorStyleCmd; friend class PlotAreaSetBackgroundImageStyleCmd; friend class PlotAreaSetBackgroundBrushStyleCmd; friend class PlotAreaSetBackgroundFirstColorCmd; friend class PlotAreaSetBackgroundSecondColorCmd; friend class PlotAreaSetBackgroundFileNameCmd; friend class PlotAreaSetBackgroundOpacityCmd; friend class PlotAreaSetBorderPenCmd; friend class PlotAreaSetBorderCornerRadiusCmd; friend class PlotAreaSetBorderOpacityCmd; void backgroundTypeChanged(PlotArea::BackgroundType); void backgroundColorStyleChanged(PlotArea::BackgroundColorStyle); void backgroundImageStyleChanged(PlotArea::BackgroundImageStyle); void backgroundBrushStyleChanged(Qt::BrushStyle); void backgroundFirstColorChanged(QColor&); void backgroundSecondColorChanged(QColor&); void backgroundFileNameChanged(QString&); void backgroundOpacityChanged(float); void borderPenChanged(QPen&); void borderCornerRadiusChanged(float); void borderOpacityChanged(float); }; #endif diff --git a/src/backend/worksheet/plots/PlotAreaPrivate.h b/src/backend/worksheet/plots/PlotAreaPrivate.h index 6856f541a..0c5b84422 100644 --- a/src/backend/worksheet/plots/PlotAreaPrivate.h +++ b/src/backend/worksheet/plots/PlotAreaPrivate.h @@ -1,68 +1,68 @@ /*************************************************************************** File : PlotAreaPrivate.h Project : LabPlot Description : Private members of PlotArea. -------------------------------------------------------------------- Copyright : (C) 2011 by Alexander Semke (alexander.semke@web.de) ***************************************************************************/ /*************************************************************************** * * * 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 PLOTAREAPRIVATE_H #define PLOTAREAPRIVATE_H #include #include #include class PlotArea; class PlotAreaPrivate: public QGraphicsItem { public: explicit PlotAreaPrivate(PlotArea *owner); QString name() const; bool swapVisible(bool on); bool toggleClipping(bool on); bool clippingEnabled() const; void setRect(const QRectF&); //QGraphicsItem's virtual functions - virtual void paint(QPainter*, const QStyleOptionGraphicsItem*, QWidget*); - virtual QRectF boundingRect() const; - virtual QPainterPath shape() const; + void paint(QPainter*, const QStyleOptionGraphicsItem*, QWidget*) override; + QRectF boundingRect() const override; + QPainterPath shape() const override; QRectF rect; PlotArea::BackgroundType backgroundType; PlotArea::BackgroundColorStyle backgroundColorStyle; PlotArea::BackgroundImageStyle backgroundImageStyle; Qt::BrushStyle backgroundBrushStyle; QColor backgroundFirstColor; QColor backgroundSecondColor; QString backgroundFileName; qreal backgroundOpacity; QPen borderPen; qreal borderOpacity; qreal borderCornerRadius; PlotArea* const q; }; #endif diff --git a/src/backend/worksheet/plots/cartesian/Axis.cpp b/src/backend/worksheet/plots/cartesian/Axis.cpp index 60c9b481d..fbbb8e3ab 100644 --- a/src/backend/worksheet/plots/cartesian/Axis.cpp +++ b/src/backend/worksheet/plots/cartesian/Axis.cpp @@ -1,2331 +1,2331 @@ /*************************************************************************** File : Axis.cpp Project : LabPlot Description : Axis for cartesian coordinate systems. -------------------------------------------------------------------- Copyright : (C) 2011-2015 Alexander Semke (alexander.semke@web.de) Copyright : (C) 2013 Stefan Gerlach (stefan.gerlach@uni-konstanz.de) ***************************************************************************/ /*************************************************************************** * * * 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 "backend/worksheet/plots/cartesian/Axis.h" #include "backend/worksheet/plots/cartesian/AxisPrivate.h" #include "backend/worksheet/Worksheet.h" #include "backend/worksheet/TextLabel.h" #include "backend/worksheet/plots/cartesian/CartesianCoordinateSystem.h" #include "backend/worksheet/plots/cartesian/CartesianPlot.h" #include "backend/core/AbstractColumn.h" #include "backend/lib/commandtemplates.h" #include "backend/lib/XmlStreamReader.h" #include "backend/lib/macros.h" // #include "backend/lib/trace.h" #include "kdefrontend/GuiTools.h" #include #include #include #include #include #include /** * \class AxisGrid * \brief Helper class to get the axis grid drawn with the z-Value=0. * * The painting of the grid lines is separated from the painting of the axis itself. * This allows to use a different z-values for the grid lines (z=0, drawn below all other objects ) * and for the axis (z=FLT_MAX, drawn on top of all other objects) * * \ingroup worksheet */ class AxisGrid : public QGraphicsItem { public: AxisGrid(AxisPrivate* a) { axis = a; setFlag(QGraphicsItem::ItemIsSelectable, false); setFlag(QGraphicsItem::ItemIsFocusable, false); setAcceptHoverEvents(false); } - QRectF boundingRect() const { + QRectF boundingRect() const override { QPainterPath gridShape; gridShape.addPath(WorksheetElement::shapeFromPath(axis->majorGridPath, axis->majorGridPen)); gridShape.addPath(WorksheetElement::shapeFromPath(axis->minorGridPath, axis->minorGridPen)); QRectF boundingRectangle = gridShape.boundingRect(); return boundingRectangle; } - void paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget) { + void paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget) override { Q_UNUSED(option) Q_UNUSED(widget) if (!axis->isVisible()) return; if (axis->linePath.isEmpty()) return; //draw major grid if (axis->majorGridPen.style() != Qt::NoPen) { painter->setOpacity(axis->majorGridOpacity); painter->setPen(axis->majorGridPen); painter->setBrush(Qt::NoBrush); painter->drawPath(axis->majorGridPath); } //draw minor grid if (axis->minorGridPen.style() != Qt::NoPen) { painter->setOpacity(axis->minorGridOpacity); painter->setPen(axis->minorGridPen); painter->setBrush(Qt::NoBrush); painter->drawPath(axis->minorGridPath); } } private: AxisPrivate* axis; }; /** * \class Axis * \brief Axis for cartesian coordinate systems. * * \ingroup worksheet */ Axis::Axis(const QString& name, CartesianPlot* plot, const AxisOrientation& orientation) : WorksheetElement(name), d_ptr(new AxisPrivate(this, plot)) { d_ptr->orientation = orientation; init(); } Axis::Axis(const QString& name, const AxisOrientation& orientation, AxisPrivate* dd) : WorksheetElement(name), d_ptr(dd) { d_ptr->orientation = orientation; init(); } void Axis::init() { Q_D(Axis); KConfig config; KConfigGroup group = config.group( "Axis" ); d->autoScale = true; d->position = Axis::AxisCustom; d->offset = group.readEntry("PositionOffset", 0); d->scale = (Axis::AxisScale) group.readEntry("Scale", (int) Axis::ScaleLinear); d->autoScale = group.readEntry("AutoScale", true); d->start = group.readEntry("Start", 0); d->end = group.readEntry("End", 10); d->zeroOffset = group.readEntry("ZeroOffset", 0); d->scalingFactor = group.readEntry("ScalingFactor", 1.0); d->linePen.setStyle( (Qt::PenStyle) group.readEntry("LineStyle", (int) Qt::SolidLine) ); d->linePen.setWidthF( group.readEntry("LineWidth", Worksheet::convertToSceneUnits( 1.0, Worksheet::Point ) ) ); d->lineOpacity = group.readEntry("LineOpacity", 1.0); d->arrowType = (Axis::ArrowType) group.readEntry("ArrowType", (int)Axis::NoArrow); d->arrowPosition = (Axis::ArrowPosition) group.readEntry("ArrowPosition", (int)Axis::ArrowRight); d->arrowSize = group.readEntry("ArrowSize", Worksheet::convertToSceneUnits(10, Worksheet::Point)); // axis title d->title = new TextLabel(this->name(), TextLabel::AxisTitle); connect( d->title, &TextLabel::changed, this, &Axis::labelChanged); addChild(d->title); d->title->setHidden(true); d->title->graphicsItem()->setParentItem(graphicsItem()); d->title->graphicsItem()->setFlag(QGraphicsItem::ItemIsMovable, false); d->title->graphicsItem()->setAcceptHoverEvents(false); d->title->setText(this->name()); if (d->orientation == AxisVertical) d->title->setRotationAngle(90); d->titleOffsetX = Worksheet::convertToSceneUnits(2, Worksheet::Point); //distance to the axis tick labels d->titleOffsetY = Worksheet::convertToSceneUnits(2, Worksheet::Point); //distance to the axis tick labels d->majorTicksDirection = (Axis::TicksDirection) group.readEntry("MajorTicksDirection", (int) Axis::ticksOut); d->majorTicksType = (Axis::TicksType) group.readEntry("MajorTicksType", (int) Axis::TicksTotalNumber); d->majorTicksNumber = group.readEntry("MajorTicksNumber", 11); d->majorTicksIncrement = group.readEntry("MajorTicksIncrement", 1.0); d->majorTicksPen.setStyle((Qt::PenStyle) group.readEntry("MajorTicksLineStyle", (int)Qt::SolidLine) ); d->majorTicksPen.setColor( group.readEntry("MajorTicksColor", QColor(Qt::black) ) ); d->majorTicksPen.setWidthF( group.readEntry("MajorTicksWidth", Worksheet::convertToSceneUnits(1.0, Worksheet::Point) ) ); d->majorTicksLength = group.readEntry("MajorTicksLength", Worksheet::convertToSceneUnits(6.0, Worksheet::Point)); d->majorTicksOpacity = group.readEntry("MajorTicksOpacity", 1.0); d->minorTicksDirection = (Axis::TicksDirection) group.readEntry("MinorTicksDirection", (int) Axis::ticksOut); d->minorTicksType = (Axis::TicksType) group.readEntry("MinorTicksType", (int) Axis::TicksTotalNumber); d->minorTicksNumber = group.readEntry("MinorTicksNumber", 1); d->minorTicksIncrement = group.readEntry("MinorTicksIncrement", 0.5); d->minorTicksPen.setStyle((Qt::PenStyle) group.readEntry("MinorTicksLineStyle", (int)Qt::SolidLine) ); d->minorTicksPen.setColor( group.readEntry("MinorTicksColor", QColor(Qt::black) ) ); d->minorTicksPen.setWidthF( group.readEntry("MinorTicksWidth", Worksheet::convertToSceneUnits(1.0, Worksheet::Point) ) ); d->minorTicksLength = group.readEntry("MinorTicksLength", Worksheet::convertToSceneUnits(3.0, Worksheet::Point)); d->minorTicksOpacity = group.readEntry("MinorTicksOpacity", 1.0); //Labels d->labelsFormat = (Axis::LabelsFormat) group.readEntry("LabelsFormat", (int)Axis::FormatDecimal); d->labelsAutoPrecision = group.readEntry("LabelsAutoPrecision", true); d->labelsPrecision = group.readEntry("LabelsPrecision", 1); d->labelsPosition = (Axis::LabelsPosition) group.readEntry("LabelsPosition", (int) Axis::LabelsOut); d->labelsOffset= group.readEntry("LabelsOffset", Worksheet::convertToSceneUnits( 5.0, Worksheet::Point )); d->labelsRotationAngle = group.readEntry("LabelsRotation", 0); d->labelsFont = group.readEntry("LabelsFont", QFont()); d->labelsFont.setPixelSize( Worksheet::convertToSceneUnits( 10.0, Worksheet::Point ) ); d->labelsColor = group.readEntry("LabelsFontColor", QColor(Qt::black)); d->labelsPrefix = group.readEntry("LabelsPrefix", "" ); d->labelsSuffix = group.readEntry("LabelsSuffix", "" ); d->labelsOpacity = group.readEntry("LabelsOpacity", 1.0); //major grid d->majorGridPen.setStyle( (Qt::PenStyle) group.readEntry("MajorGridStyle", (int) Qt::NoPen) ); d->majorGridPen.setColor(group.readEntry("MajorGridColor", QColor(Qt::gray)) ); d->majorGridPen.setWidthF( group.readEntry("MajorGridWidth", Worksheet::convertToSceneUnits( 1.0, Worksheet::Point ) ) ); d->majorGridOpacity = group.readEntry("MajorGridOpacity", 1.0); //minor grid d->minorGridPen.setStyle( (Qt::PenStyle) group.readEntry("MinorGridStyle", (int) Qt::NoPen) ); d->minorGridPen.setColor(group.readEntry("MajorGridColor", QColor(Qt::gray)) ); d->minorGridPen.setWidthF( group.readEntry("MinorGridWidth", Worksheet::convertToSceneUnits( 1.0, Worksheet::Point ) ) ); d->minorGridOpacity = group.readEntry("MinorGridOpacity", 1.0); this->initActions(); this->initMenus(); } /*! * For the most frequently edited properties, create Actions and ActionGroups for the context menu. * For some ActionGroups the actual actions are created in \c GuiTool, */ void Axis::initActions() { visibilityAction = new QAction(i18n("visible"), this); visibilityAction->setCheckable(true); connect(visibilityAction, &QAction::triggered, this, &Axis::visibilityChanged); //Orientation orientationActionGroup = new QActionGroup(this); orientationActionGroup->setExclusive(true); connect(orientationActionGroup, &QActionGroup::triggered, this, &Axis::orientationChangedSlot); orientationHorizontalAction = new QAction(i18n("horizontal"), orientationActionGroup); orientationHorizontalAction->setCheckable(true); orientationVerticalAction = new QAction(i18n("vertical"), orientationActionGroup); orientationVerticalAction->setCheckable(true); //Line lineStyleActionGroup = new QActionGroup(this); lineStyleActionGroup->setExclusive(true); connect(lineStyleActionGroup, &QActionGroup::triggered, this, &Axis::lineStyleChanged); lineColorActionGroup = new QActionGroup(this); lineColorActionGroup->setExclusive(true); connect(lineColorActionGroup, &QActionGroup::triggered, this, &Axis::lineColorChanged); //Ticks //TODO } void Axis::initMenus() { //Orientation orientationMenu = new QMenu(i18n("Orientation")); orientationMenu->addAction(orientationHorizontalAction); orientationMenu->addAction(orientationVerticalAction); //Line lineMenu = new QMenu(i18n("Line")); lineStyleMenu = new QMenu(i18n("style"), lineMenu); lineMenu->addMenu( lineStyleMenu ); lineColorMenu = new QMenu(i18n("color"), lineMenu); GuiTools::fillColorMenu( lineColorMenu, lineColorActionGroup ); lineMenu->addMenu( lineColorMenu ); } QMenu* Axis::createContextMenu() { Q_D(const Axis); QMenu* menu = WorksheetElement::createContextMenu(); QAction* firstAction = menu->actions().at(1); //skip the first action because of the "title-action" visibilityAction->setChecked(isVisible()); menu->insertAction(firstAction, visibilityAction); //Orientation if ( d->orientation == AxisHorizontal ) orientationHorizontalAction->setChecked(true); else orientationVerticalAction->setChecked(true); menu->insertMenu(firstAction, orientationMenu); //Line styles GuiTools::updatePenStyles( lineStyleMenu, lineStyleActionGroup, d->linePen.color() ); GuiTools::selectPenStyleAction(lineStyleActionGroup, d->linePen.style() ); GuiTools::selectColorAction(lineColorActionGroup, d->linePen.color() ); menu->insertMenu(firstAction, lineMenu); menu->insertSeparator(firstAction); return menu; } /*! Returns an icon to be used in the project explorer. */ QIcon Axis::icon() const{ Q_D(const Axis); QIcon ico; if (d->orientation == Axis::AxisHorizontal) ico = QIcon::fromTheme("labplot-axis-horizontal"); else ico = QIcon::fromTheme("labplot-axis-vertical"); return ico; } Axis::~Axis() { if (orientationMenu) delete orientationMenu; if (lineMenu) delete lineMenu; //no need to delete d->title, since it was added with addChild in init(); //no need to delete the d-pointer here - it inherits from QGraphicsItem //and is deleted during the cleanup in QGraphicsScene } QGraphicsItem *Axis::graphicsItem() const { return d_ptr; } /*! * overrides the implementation in WorksheetElement and sets the z-value to the maximal possible, * axes are drawn on top of all other object in the plot. */ void Axis::setZValue(qreal) { Q_D(Axis); d->setZValue(std::numeric_limits::max()); d->gridItem->setParentItem(d->parentItem()); d->gridItem->setZValue(0); } void Axis::retransform() { Q_D(Axis); d->retransform(); } void Axis::setSuppressRetransform(bool value) { Q_D(Axis); d->suppressRetransform = value; } void Axis::handleResize(double horizontalRatio, double verticalRatio, bool pageResize) { DEBUG("Axis::handleResize()"); Q_D(Axis); Q_UNUSED(pageResize); double ratio = 0; if (horizontalRatio > 1.0 || verticalRatio > 1.0) ratio = qMax(horizontalRatio, verticalRatio); else ratio = qMin(horizontalRatio, verticalRatio); QPen pen = d->linePen; pen.setWidthF(pen.widthF() * ratio); d->linePen = pen; d->majorTicksLength *= ratio; // ticks are perpendicular to axis line -> verticalRatio relevant d->minorTicksLength *= ratio; d->labelsFont.setPixelSize( d->labelsFont.pixelSize() * ratio ); //TODO: take into account rotated labels d->labelsOffset *= ratio; d->title->handleResize(horizontalRatio, verticalRatio, pageResize); } /* ============================ getter methods ================= */ BASIC_SHARED_D_READER_IMPL(Axis, bool, autoScale, autoScale) BASIC_SHARED_D_READER_IMPL(Axis, Axis::AxisOrientation, orientation, orientation) BASIC_SHARED_D_READER_IMPL(Axis, Axis::AxisPosition, position, position) BASIC_SHARED_D_READER_IMPL(Axis, Axis::AxisScale, scale, scale) BASIC_SHARED_D_READER_IMPL(Axis, double, offset, offset) BASIC_SHARED_D_READER_IMPL(Axis, double, start, start) BASIC_SHARED_D_READER_IMPL(Axis, double, end, end) BASIC_SHARED_D_READER_IMPL(Axis, qreal, scalingFactor, scalingFactor) BASIC_SHARED_D_READER_IMPL(Axis, qreal, zeroOffset, zeroOffset) BASIC_SHARED_D_READER_IMPL(Axis, TextLabel*, title, title) BASIC_SHARED_D_READER_IMPL(Axis, qreal, titleOffsetX, titleOffsetX) BASIC_SHARED_D_READER_IMPL(Axis, qreal, titleOffsetY, titleOffsetY) CLASS_SHARED_D_READER_IMPL(Axis, QPen, linePen, linePen) BASIC_SHARED_D_READER_IMPL(Axis, qreal, lineOpacity, lineOpacity) BASIC_SHARED_D_READER_IMPL(Axis, Axis::ArrowType, arrowType, arrowType) BASIC_SHARED_D_READER_IMPL(Axis, Axis::ArrowPosition, arrowPosition, arrowPosition) BASIC_SHARED_D_READER_IMPL(Axis, qreal, arrowSize, arrowSize) BASIC_SHARED_D_READER_IMPL(Axis, Axis::TicksDirection, majorTicksDirection, majorTicksDirection) BASIC_SHARED_D_READER_IMPL(Axis, Axis::TicksType, majorTicksType, majorTicksType) BASIC_SHARED_D_READER_IMPL(Axis, int, majorTicksNumber, majorTicksNumber) BASIC_SHARED_D_READER_IMPL(Axis, qreal, majorTicksIncrement, majorTicksIncrement) BASIC_SHARED_D_READER_IMPL(Axis, const AbstractColumn*, majorTicksColumn, majorTicksColumn) QString& Axis::majorTicksColumnPath() const { return d_ptr->majorTicksColumnPath; } BASIC_SHARED_D_READER_IMPL(Axis, qreal, majorTicksLength, majorTicksLength) CLASS_SHARED_D_READER_IMPL(Axis, QPen, majorTicksPen, majorTicksPen) BASIC_SHARED_D_READER_IMPL(Axis, qreal, majorTicksOpacity, majorTicksOpacity) BASIC_SHARED_D_READER_IMPL(Axis, Axis::TicksDirection, minorTicksDirection, minorTicksDirection) BASIC_SHARED_D_READER_IMPL(Axis, Axis::TicksType, minorTicksType, minorTicksType) BASIC_SHARED_D_READER_IMPL(Axis, int, minorTicksNumber, minorTicksNumber) BASIC_SHARED_D_READER_IMPL(Axis, qreal, minorTicksIncrement, minorTicksIncrement) BASIC_SHARED_D_READER_IMPL(Axis, const AbstractColumn*, minorTicksColumn, minorTicksColumn) QString& Axis::minorTicksColumnPath() const { return d_ptr->minorTicksColumnPath; } BASIC_SHARED_D_READER_IMPL(Axis, qreal, minorTicksLength, minorTicksLength) CLASS_SHARED_D_READER_IMPL(Axis, QPen, minorTicksPen, minorTicksPen) BASIC_SHARED_D_READER_IMPL(Axis, qreal, minorTicksOpacity, minorTicksOpacity) BASIC_SHARED_D_READER_IMPL(Axis, Axis::LabelsFormat, labelsFormat, labelsFormat); BASIC_SHARED_D_READER_IMPL(Axis, bool, labelsAutoPrecision, labelsAutoPrecision); BASIC_SHARED_D_READER_IMPL(Axis, int, labelsPrecision, labelsPrecision); BASIC_SHARED_D_READER_IMPL(Axis, Axis::LabelsPosition, labelsPosition, labelsPosition); BASIC_SHARED_D_READER_IMPL(Axis, qreal, labelsOffset, labelsOffset); BASIC_SHARED_D_READER_IMPL(Axis, qreal, labelsRotationAngle, labelsRotationAngle); CLASS_SHARED_D_READER_IMPL(Axis, QColor, labelsColor, labelsColor); CLASS_SHARED_D_READER_IMPL(Axis, QFont, labelsFont, labelsFont); CLASS_SHARED_D_READER_IMPL(Axis, QString, labelsPrefix, labelsPrefix); CLASS_SHARED_D_READER_IMPL(Axis, QString, labelsSuffix, labelsSuffix); BASIC_SHARED_D_READER_IMPL(Axis, qreal, labelsOpacity, labelsOpacity); CLASS_SHARED_D_READER_IMPL(Axis, QPen, majorGridPen, majorGridPen) BASIC_SHARED_D_READER_IMPL(Axis, qreal, majorGridOpacity, majorGridOpacity) CLASS_SHARED_D_READER_IMPL(Axis, QPen, minorGridPen, minorGridPen) BASIC_SHARED_D_READER_IMPL(Axis, qreal, minorGridOpacity, minorGridOpacity) /* ============================ setter methods and undo commands ================= */ STD_SETTER_CMD_IMPL_F_S(Axis, SetAutoScale, bool, autoScale, retransform); void Axis::setAutoScale(bool autoScale) { Q_D(Axis); if (autoScale != d->autoScale) { exec(new AxisSetAutoScaleCmd(d, autoScale, i18n("%1: set axis auto scaling"))); if (autoScale) { CartesianPlot *plot = qobject_cast(parentAspect()); if (!plot) return; if (d->orientation == Axis::AxisHorizontal) { d->end = plot->xMax(); d->start = plot->xMin(); } else { d->end = plot->yMax(); d->start = plot->yMin(); } retransform(); emit endChanged(d->end); emit startChanged(d->start); } } } STD_SWAP_METHOD_SETTER_CMD_IMPL(Axis, SetVisible, bool, swapVisible); void Axis::setVisible(bool on) { Q_D(Axis); exec(new AxisSetVisibleCmd(d, on, on ? i18n("%1: set visible") : i18n("%1: set invisible"))); } bool Axis::isVisible() const { Q_D(const Axis); return d->isVisible(); } void Axis::setPrinting(bool on) { Q_D(Axis); d->setPrinting(on); } STD_SETTER_CMD_IMPL_F_S(Axis, SetOrientation, Axis::AxisOrientation, orientation, retransform); void Axis::setOrientation( AxisOrientation orientation) { Q_D(Axis); if (orientation != d->orientation) exec(new AxisSetOrientationCmd(d, orientation, i18n("%1: set axis orientation"))); } STD_SETTER_CMD_IMPL_F_S(Axis, SetPosition, Axis::AxisPosition, position, retransform); void Axis::setPosition(AxisPosition position) { Q_D(Axis); if (position != d->position) exec(new AxisSetPositionCmd(d, position, i18n("%1: set axis position"))); } STD_SETTER_CMD_IMPL_F_S(Axis, SetScaling, Axis::AxisScale, scale, retransformTicks); void Axis::setScale(AxisScale scale) { Q_D(Axis); if (scale != d->scale) exec(new AxisSetScalingCmd(d, scale, i18n("%1: set axis scale"))); } STD_SETTER_CMD_IMPL_F(Axis, SetOffset, double, offset, retransform); void Axis::setOffset(double offset, bool undo) { Q_D(Axis); if (offset != d->offset) { if (undo) { exec(new AxisSetOffsetCmd(d, offset, i18n("%1: set axis offset"))); } else { d->offset = offset; //don't need to call retransform() afterward //since the only usage of this call is in CartesianPlot, where retransform is called for all children anyway. } emit positionChanged(offset); } } STD_SETTER_CMD_IMPL_F_S(Axis, SetStart, double, start, retransform); void Axis::setStart(double start) { Q_D(Axis); if (start != d->start) exec(new AxisSetStartCmd(d, start, i18n("%1: set axis start"))); } STD_SETTER_CMD_IMPL_F_S(Axis, SetEnd, double, end, retransform); void Axis::setEnd(double end) { Q_D(Axis); if (end != d->end) exec(new AxisSetEndCmd(d, end, i18n("%1: set axis end"))); } STD_SETTER_CMD_IMPL_F_S(Axis, SetZeroOffset, qreal, zeroOffset, retransform); void Axis::setZeroOffset(qreal zeroOffset) { Q_D(Axis); if (zeroOffset != d->zeroOffset) exec(new AxisSetZeroOffsetCmd(d, zeroOffset, i18n("%1: set axis zero offset"))); } STD_SETTER_CMD_IMPL_F_S(Axis, SetScalingFactor, qreal, scalingFactor, retransform); void Axis::setScalingFactor(qreal scalingFactor) { Q_D(Axis); if (scalingFactor != d->scalingFactor) exec(new AxisSetScalingFactorCmd(d, scalingFactor, i18n("%1: set axis scaling factor"))); } //Title STD_SETTER_CMD_IMPL_F_S(Axis, SetTitleOffsetX, qreal, titleOffsetX, retransform); void Axis::setTitleOffsetX(qreal offset) { Q_D(Axis); if (offset != d->titleOffsetX) exec(new AxisSetTitleOffsetXCmd(d, offset, i18n("%1: set title offset"))); } STD_SETTER_CMD_IMPL_F_S(Axis, SetTitleOffsetY, qreal, titleOffsetY, retransform); void Axis::setTitleOffsetY(qreal offset) { Q_D(Axis); if (offset != d->titleOffsetY) exec(new AxisSetTitleOffsetYCmd(d, offset, i18n("%1: set title offset"))); } //Line STD_SETTER_CMD_IMPL_F_S(Axis, SetLinePen, QPen, linePen, recalcShapeAndBoundingRect); void Axis::setLinePen(const QPen &pen) { Q_D(Axis); if (pen != d->linePen) exec(new AxisSetLinePenCmd(d, pen, i18n("%1: set line style"))); } STD_SETTER_CMD_IMPL_F_S(Axis, SetLineOpacity, qreal, lineOpacity, update); void Axis::setLineOpacity(qreal opacity) { Q_D(Axis); if (opacity != d->lineOpacity) exec(new AxisSetLineOpacityCmd(d, opacity, i18n("%1: set line opacity"))); } STD_SETTER_CMD_IMPL_F_S(Axis, SetArrowType, Axis::ArrowType, arrowType, retransformArrow); void Axis::setArrowType(ArrowType type) { Q_D(Axis); if (type != d->arrowType) exec(new AxisSetArrowTypeCmd(d, type, i18n("%1: set arrow type"))); } STD_SETTER_CMD_IMPL_F_S(Axis, SetArrowPosition, Axis::ArrowPosition, arrowPosition, retransformArrow); void Axis::setArrowPosition(ArrowPosition position) { Q_D(Axis); if (position != d->arrowPosition) exec(new AxisSetArrowPositionCmd(d, position, i18n("%1: set arrow position"))); } STD_SETTER_CMD_IMPL_F_S(Axis, SetArrowSize, qreal, arrowSize, retransformArrow); void Axis::setArrowSize(qreal arrowSize) { Q_D(Axis); if (arrowSize != d->arrowSize) exec(new AxisSetArrowSizeCmd(d, arrowSize, i18n("%1: set arrow size"))); } //Major ticks STD_SETTER_CMD_IMPL_F_S(Axis, SetMajorTicksDirection, Axis::TicksDirection, majorTicksDirection, retransformTicks); void Axis::setMajorTicksDirection(const TicksDirection majorTicksDirection) { Q_D(Axis); if (majorTicksDirection != d->majorTicksDirection) exec(new AxisSetMajorTicksDirectionCmd(d, majorTicksDirection, i18n("%1: set major ticks direction"))); } STD_SETTER_CMD_IMPL_F_S(Axis, SetMajorTicksType, Axis::TicksType, majorTicksType, retransformTicks); void Axis::setMajorTicksType(const TicksType majorTicksType) { Q_D(Axis); if (majorTicksType!= d->majorTicksType) exec(new AxisSetMajorTicksTypeCmd(d, majorTicksType, i18n("%1: set major ticks type"))); } STD_SETTER_CMD_IMPL_F_S(Axis, SetMajorTicksNumber, int, majorTicksNumber, retransformTicks); void Axis::setMajorTicksNumber(int majorTicksNumber) { Q_D(Axis); if (majorTicksNumber != d->majorTicksNumber) exec(new AxisSetMajorTicksNumberCmd(d, majorTicksNumber, i18n("%1: set the total number of the major ticks"))); } STD_SETTER_CMD_IMPL_F_S(Axis, SetMajorTicksIncrement, qreal, majorTicksIncrement, retransformTicks); void Axis::setMajorTicksIncrement(qreal majorTicksIncrement) { Q_D(Axis); if (majorTicksIncrement != d->majorTicksIncrement) exec(new AxisSetMajorTicksIncrementCmd(d, majorTicksIncrement, i18n("%1: set the increment for the major ticks"))); } STD_SETTER_CMD_IMPL_F_S(Axis, SetMajorTicksColumn, const AbstractColumn*, majorTicksColumn, retransformTicks) void Axis::setMajorTicksColumn(const AbstractColumn* column) { Q_D(Axis); if (column != d->majorTicksColumn) { exec(new AxisSetMajorTicksColumnCmd(d, column, i18n("%1: assign major ticks' values"))); if (column) { connect(column, &AbstractColumn::dataChanged, this, &Axis::retransformTicks); connect(column->parentAspect(), &AbstractAspect::aspectAboutToBeRemoved, this, &Axis::majorTicksColumnAboutToBeRemoved); //TODO: add disconnect in the undo-function } } } STD_SETTER_CMD_IMPL_F_S(Axis, SetMajorTicksPen, QPen, majorTicksPen, recalcShapeAndBoundingRect); void Axis::setMajorTicksPen(const QPen &pen) { Q_D(Axis); if (pen != d->majorTicksPen) exec(new AxisSetMajorTicksPenCmd(d, pen, i18n("%1: set major ticks style"))); } STD_SETTER_CMD_IMPL_F_S(Axis, SetMajorTicksLength, qreal, majorTicksLength, retransformTicks); void Axis::setMajorTicksLength(qreal majorTicksLength) { Q_D(Axis); if (majorTicksLength != d->majorTicksLength) exec(new AxisSetMajorTicksLengthCmd(d, majorTicksLength, i18n("%1: set major ticks length"))); } STD_SETTER_CMD_IMPL_F_S(Axis, SetMajorTicksOpacity, qreal, majorTicksOpacity, update); void Axis::setMajorTicksOpacity(qreal opacity) { Q_D(Axis); if (opacity != d->majorTicksOpacity) exec(new AxisSetMajorTicksOpacityCmd(d, opacity, i18n("%1: set major ticks opacity"))); } //Minor ticks STD_SETTER_CMD_IMPL_F_S(Axis, SetMinorTicksDirection, Axis::TicksDirection, minorTicksDirection, retransformTicks); void Axis::setMinorTicksDirection(const TicksDirection minorTicksDirection) { Q_D(Axis); if (minorTicksDirection != d->minorTicksDirection) exec(new AxisSetMinorTicksDirectionCmd(d, minorTicksDirection, i18n("%1: set minor ticks direction"))); } STD_SETTER_CMD_IMPL_F_S(Axis, SetMinorTicksType, Axis::TicksType, minorTicksType, retransformTicks); void Axis::setMinorTicksType(const TicksType minorTicksType) { Q_D(Axis); if (minorTicksType!= d->minorTicksType) exec(new AxisSetMinorTicksTypeCmd(d, minorTicksType, i18n("%1: set minor ticks type"))); } STD_SETTER_CMD_IMPL_F_S(Axis, SetMinorTicksNumber, int, minorTicksNumber, retransformTicks); void Axis::setMinorTicksNumber(int minorTicksNumber) { Q_D(Axis); if (minorTicksNumber != d->minorTicksNumber) exec(new AxisSetMinorTicksNumberCmd(d, minorTicksNumber, i18n("%1: set the total number of the minor ticks"))); } STD_SETTER_CMD_IMPL_F_S(Axis, SetMinorTicksIncrement, qreal, minorTicksIncrement, retransformTicks); void Axis::setMinorTicksIncrement(qreal minorTicksIncrement) { Q_D(Axis); if (minorTicksIncrement != d->minorTicksIncrement) exec(new AxisSetMinorTicksIncrementCmd(d, minorTicksIncrement, i18n("%1: set the increment for the minor ticks"))); } STD_SETTER_CMD_IMPL_F_S(Axis, SetMinorTicksColumn, const AbstractColumn*, minorTicksColumn, retransformTicks) void Axis::setMinorTicksColumn(const AbstractColumn* column) { Q_D(Axis); if (column != d->minorTicksColumn) { exec(new AxisSetMinorTicksColumnCmd(d, column, i18n("%1: assign minor ticks' values"))); if (column) { connect(column, &AbstractColumn::dataChanged, this, &Axis::retransformTicks); connect(column->parentAspect(), &AbstractAspect::aspectAboutToBeRemoved, this, &Axis::minorTicksColumnAboutToBeRemoved); //TODO: add disconnect in the undo-function } } } STD_SETTER_CMD_IMPL_F_S(Axis, SetMinorTicksPen, QPen, minorTicksPen, recalcShapeAndBoundingRect); void Axis::setMinorTicksPen(const QPen &pen) { Q_D(Axis); if (pen != d->minorTicksPen) exec(new AxisSetMinorTicksPenCmd(d, pen, i18n("%1: set minor ticks style"))); } STD_SETTER_CMD_IMPL_F_S(Axis, SetMinorTicksLength, qreal, minorTicksLength, retransformTicks); void Axis::setMinorTicksLength(qreal minorTicksLength) { Q_D(Axis); if (minorTicksLength != d->minorTicksLength) exec(new AxisSetMinorTicksLengthCmd(d, minorTicksLength, i18n("%1: set minor ticks length"))); } STD_SETTER_CMD_IMPL_F_S(Axis, SetMinorTicksOpacity, qreal, minorTicksOpacity, update); void Axis::setMinorTicksOpacity(qreal opacity) { Q_D(Axis); if (opacity != d->minorTicksOpacity) exec(new AxisSetMinorTicksOpacityCmd(d, opacity, i18n("%1: set minor ticks opacity"))); } //Labels STD_SETTER_CMD_IMPL_F_S(Axis, SetLabelsFormat, Axis::LabelsFormat, labelsFormat, retransformTicks); void Axis::setLabelsFormat(const LabelsFormat labelsFormat) { Q_D(Axis); if (labelsFormat != d->labelsFormat) exec(new AxisSetLabelsFormatCmd(d, labelsFormat, i18n("%1: set labels format"))); } STD_SETTER_CMD_IMPL_F_S(Axis, SetLabelsAutoPrecision, bool, labelsAutoPrecision, retransformTickLabelStrings); void Axis::setLabelsAutoPrecision(const bool labelsAutoPrecision) { Q_D(Axis); if (labelsAutoPrecision != d->labelsAutoPrecision) exec(new AxisSetLabelsAutoPrecisionCmd(d, labelsAutoPrecision, i18n("%1: set labels precision"))); } STD_SETTER_CMD_IMPL_F_S(Axis, SetLabelsPrecision, int, labelsPrecision, retransformTickLabelStrings); void Axis::setLabelsPrecision(const int labelsPrecision) { Q_D(Axis); if (labelsPrecision != d->labelsPrecision) exec(new AxisSetLabelsPrecisionCmd(d, labelsPrecision, i18n("%1: set labels precision"))); } STD_SETTER_CMD_IMPL_F_S(Axis, SetLabelsPosition, Axis::LabelsPosition, labelsPosition, retransformTickLabelPositions); void Axis::setLabelsPosition(const LabelsPosition labelsPosition) { Q_D(Axis); if (labelsPosition != d->labelsPosition) exec(new AxisSetLabelsPositionCmd(d, labelsPosition, i18n("%1: set labels position"))); } STD_SETTER_CMD_IMPL_F_S(Axis, SetLabelsOffset, double, labelsOffset, retransformTickLabelPositions); void Axis::setLabelsOffset(double offset) { Q_D(Axis); if (offset != d->labelsOffset) exec(new AxisSetLabelsOffsetCmd(d, offset, i18n("%1: set label offset"))); } STD_SETTER_CMD_IMPL_F_S(Axis, SetLabelsRotationAngle, qreal, labelsRotationAngle, recalcShapeAndBoundingRect); void Axis::setLabelsRotationAngle(qreal angle) { Q_D(Axis); if (angle != d->labelsRotationAngle) exec(new AxisSetLabelsRotationAngleCmd(d, angle, i18n("%1: set label rotation angle"))); } STD_SETTER_CMD_IMPL_F_S(Axis, SetLabelsColor, QColor, labelsColor, update); void Axis::setLabelsColor(const QColor &color) { Q_D(Axis); if (color != d->labelsColor) exec(new AxisSetLabelsColorCmd(d, color, i18n("%1: set label color"))); } STD_SETTER_CMD_IMPL_F_S(Axis, SetLabelsFont, QFont, labelsFont, retransformTickLabelStrings); void Axis::setLabelsFont(const QFont &font) { Q_D(Axis); if (font != d->labelsFont) exec(new AxisSetLabelsFontCmd(d, font, i18n("%1: set label font"))); } STD_SETTER_CMD_IMPL_F_S(Axis, SetLabelsPrefix, QString, labelsPrefix, retransformTickLabelStrings); void Axis::setLabelsPrefix(const QString& prefix) { Q_D(Axis); if (prefix != d->labelsPrefix) exec(new AxisSetLabelsPrefixCmd(d, prefix, i18n("%1: set label prefix"))); } STD_SETTER_CMD_IMPL_F_S(Axis, SetLabelsSuffix, QString, labelsSuffix, retransformTickLabelStrings); void Axis::setLabelsSuffix(const QString& suffix) { Q_D(Axis); if (suffix != d->labelsSuffix) exec(new AxisSetLabelsSuffixCmd(d, suffix, i18n("%1: set label suffix"))); } STD_SETTER_CMD_IMPL_F_S(Axis, SetLabelsOpacity, qreal, labelsOpacity, update); void Axis::setLabelsOpacity(qreal opacity) { Q_D(Axis); if (opacity != d->labelsOpacity) exec(new AxisSetLabelsOpacityCmd(d, opacity, i18n("%1: set labels opacity"))); } //Major grid STD_SETTER_CMD_IMPL_F_S(Axis, SetMajorGridPen, QPen, majorGridPen, retransformMajorGrid); void Axis::setMajorGridPen(const QPen &pen) { Q_D(Axis); if (pen != d->majorGridPen) exec(new AxisSetMajorGridPenCmd(d, pen, i18n("%1: set major grid style"))); } STD_SETTER_CMD_IMPL_F_S(Axis, SetMajorGridOpacity, qreal, majorGridOpacity, update); void Axis::setMajorGridOpacity(qreal opacity) { Q_D(Axis); if (opacity != d->majorGridOpacity) exec(new AxisSetMajorGridOpacityCmd(d, opacity, i18n("%1: set major grid opacity"))); } //Minor grid STD_SETTER_CMD_IMPL_F_S(Axis, SetMinorGridPen, QPen, minorGridPen, retransformMinorGrid); void Axis::setMinorGridPen(const QPen &pen) { Q_D(Axis); if (pen != d->minorGridPen) exec(new AxisSetMinorGridPenCmd(d, pen, i18n("%1: set minor grid style"))); } STD_SETTER_CMD_IMPL_F_S(Axis, SetMinorGridOpacity, qreal, minorGridOpacity, update); void Axis::setMinorGridOpacity(qreal opacity) { Q_D(Axis); if (opacity != d->minorGridOpacity) exec(new AxisSetMinorGridOpacityCmd(d, opacity, i18n("%1: set minor grid opacity"))); } //############################################################################## //#################################### SLOTs ################################ //############################################################################## void Axis::labelChanged() { Q_D(Axis); d->recalcShapeAndBoundingRect(); } void Axis::retransformTicks() { Q_D(Axis); d->retransformTicks(); } void Axis::majorTicksColumnAboutToBeRemoved(const AbstractAspect* aspect) { Q_D(Axis); if (aspect == d->majorTicksColumn) { d->majorTicksColumn = 0; d->retransformTicks(); } } void Axis::minorTicksColumnAboutToBeRemoved(const AbstractAspect* aspect) { Q_D(Axis); if (aspect == d->minorTicksColumn) { d->minorTicksColumn = 0; d->retransformTicks(); } } //############################################################################## //###### SLOTs for changes triggered via QActions in the context menu ######## //############################################################################## void Axis::orientationChangedSlot(QAction* action) { if (action == orientationHorizontalAction) this->setOrientation(AxisHorizontal); else this->setOrientation(AxisVertical); } void Axis::lineStyleChanged(QAction* action) { Q_D(const Axis); QPen pen = d->linePen; pen.setStyle(GuiTools::penStyleFromAction(lineStyleActionGroup, action)); this->setLinePen(pen); } void Axis::lineColorChanged(QAction* action) { Q_D(const Axis); QPen pen = d->linePen; pen.setColor(GuiTools::colorFromAction(lineColorActionGroup, action)); this->setLinePen(pen); } void Axis::visibilityChangedSlot() { Q_D(const Axis); this->setVisible(!d->isVisible()); } //##################################################################### //################### Private implementation ########################## //##################################################################### AxisPrivate::AxisPrivate(Axis* owner, CartesianPlot* plot) : majorTicksColumn(0), minorTicksColumn(0), gridItem(new AxisGrid(this)), q(owner), suppressRetransform(false), m_plot(plot), m_cSystem(dynamic_cast(plot->coordinateSystem())), m_hovered(false), m_suppressRecalc(false), m_printing(false) { setFlag(QGraphicsItem::ItemIsSelectable, true); setFlag(QGraphicsItem::ItemIsFocusable, true); setAcceptHoverEvents(true); } QString AxisPrivate::name() const{ return q->name(); } bool AxisPrivate::swapVisible(bool on) { bool oldValue = isVisible(); setVisible(on); emit q->visibilityChanged(on); return oldValue; } QRectF AxisPrivate::boundingRect() const{ return boundingRectangle; } /*! Returns the shape of the XYCurve as a QPainterPath in local coordinates */ QPainterPath AxisPrivate::shape() const{ return axisShape; } /*! recalculates the position of the axis on the worksheet */ void AxisPrivate::retransform() { if (suppressRetransform) return; // PERFTRACE(name().toLatin1() + ", AxisPrivate::retransform()"); m_suppressRecalc = true; retransformLine(); m_suppressRecalc = false; recalcShapeAndBoundingRect(); } void AxisPrivate::retransformLine() { if (suppressRetransform) return; linePath = QPainterPath(); lines.clear(); QPointF startPoint; QPointF endPoint; if (orientation == Axis::AxisHorizontal) { if (position == Axis::AxisTop) offset = m_plot->yMax(); else if (position == Axis::AxisBottom) offset = m_plot->yMin(); else if (position == Axis::AxisCentered) offset = m_plot->yMin() + (m_plot->yMax()-m_plot->yMin())/2; startPoint.setX(start); startPoint.setY(offset); endPoint.setX(end); endPoint.setY(offset); } else { // vertical if (position == Axis::AxisLeft) offset = m_plot->xMin(); else if (position == Axis::AxisRight) offset = m_plot->xMax(); else if (position == Axis::AxisCentered) offset = m_plot->xMin() + (m_plot->xMax()-m_plot->xMin())/2; startPoint.setX(offset); startPoint.setY(start); endPoint.setY(end); endPoint.setX(offset); } lines.append(QLineF(startPoint, endPoint)); lines = m_cSystem->mapLogicalToScene(lines, AbstractCoordinateSystem::MarkGaps); foreach (const QLineF& line, lines) { linePath.moveTo(line.p1()); linePath.lineTo(line.p2()); } if (linePath.isEmpty()) { recalcShapeAndBoundingRect(); return; } else { retransformArrow(); retransformTicks(); } } void AxisPrivate::retransformArrow() { if (suppressRetransform) return; arrowPath = QPainterPath(); if (arrowType == Axis::NoArrow || lines.isEmpty()) { recalcShapeAndBoundingRect(); return; } if (arrowPosition == Axis::ArrowRight || arrowPosition == Axis::ArrowBoth) { const QPointF& endPoint = lines.at(lines.size()-1).p2(); this->addArrow(endPoint, 1); } if (arrowPosition == Axis::ArrowLeft || arrowPosition == Axis::ArrowBoth) { const QPointF& endPoint = lines.at(0).p1(); this->addArrow(endPoint, -1); } recalcShapeAndBoundingRect(); } void AxisPrivate::addArrow(const QPointF& startPoint, int direction) { static const double cos_phi = cos(M_PI/6.); if (orientation == Axis::AxisHorizontal) { QPointF endPoint = QPointF(startPoint.x() + direction*arrowSize, startPoint.y()); arrowPath.moveTo(startPoint); arrowPath.lineTo(endPoint); switch (arrowType) { case Axis::NoArrow: break; case Axis::SimpleArrowSmall: arrowPath.moveTo(endPoint); arrowPath.lineTo(QPointF(endPoint.x()-direction*arrowSize/4, endPoint.y()-arrowSize/4*cos_phi)); arrowPath.moveTo(endPoint); arrowPath.lineTo(QPointF(endPoint.x()-direction*arrowSize/4, endPoint.y()+arrowSize/4*cos_phi)); break; case Axis::SimpleArrowBig: arrowPath.moveTo(endPoint); arrowPath.lineTo(QPointF(endPoint.x()-direction*arrowSize/2, endPoint.y()-arrowSize/2*cos_phi)); arrowPath.moveTo(endPoint); arrowPath.lineTo(QPointF(endPoint.x()-direction*arrowSize/2, endPoint.y()+arrowSize/2*cos_phi)); break; case Axis::FilledArrowSmall: arrowPath.lineTo(QPointF(endPoint.x()-direction*arrowSize/4, endPoint.y()-arrowSize/4*cos_phi)); arrowPath.lineTo(QPointF(endPoint.x()-direction*arrowSize/4, endPoint.y()+arrowSize/4*cos_phi)); arrowPath.lineTo(endPoint); break; case Axis::FilledArrowBig: arrowPath.lineTo(QPointF(endPoint.x()-direction*arrowSize/2, endPoint.y()-arrowSize/2*cos_phi)); arrowPath.lineTo(QPointF(endPoint.x()-direction*arrowSize/2, endPoint.y()+arrowSize/2*cos_phi)); arrowPath.lineTo(endPoint); break; case Axis::SemiFilledArrowSmall: arrowPath.lineTo(QPointF(endPoint.x()-direction*arrowSize/4, endPoint.y()-arrowSize/4*cos_phi)); arrowPath.lineTo(QPointF(endPoint.x()-direction*arrowSize/8, endPoint.y())); arrowPath.lineTo(QPointF(endPoint.x()-direction*arrowSize/4, endPoint.y()+arrowSize/4*cos_phi)); arrowPath.lineTo(endPoint); break; case Axis::SemiFilledArrowBig: arrowPath.lineTo(QPointF(endPoint.x()-direction*arrowSize/2, endPoint.y()-arrowSize/2*cos_phi)); arrowPath.lineTo(QPointF(endPoint.x()-direction*arrowSize/4, endPoint.y())); arrowPath.lineTo(QPointF(endPoint.x()-direction*arrowSize/2, endPoint.y()+arrowSize/2*cos_phi)); arrowPath.lineTo(endPoint); break; } } else { //vertical orientation QPointF endPoint = QPointF(startPoint.x(), startPoint.y()-direction*arrowSize); arrowPath.moveTo(startPoint); arrowPath.lineTo(endPoint); switch (arrowType) { case Axis::NoArrow: break; case Axis::SimpleArrowSmall: arrowPath.moveTo(endPoint); arrowPath.lineTo(QPointF(endPoint.x()-arrowSize/4*cos_phi, endPoint.y()+direction*arrowSize/4)); arrowPath.moveTo(endPoint); arrowPath.lineTo(QPointF(endPoint.x()+arrowSize/4*cos_phi, endPoint.y()+direction*arrowSize/4)); break; case Axis::SimpleArrowBig: arrowPath.moveTo(endPoint); arrowPath.lineTo(QPointF(endPoint.x()-arrowSize/2*cos_phi, endPoint.y()+direction*arrowSize/2)); arrowPath.moveTo(endPoint); arrowPath.lineTo(QPointF(endPoint.x()+arrowSize/2*cos_phi, endPoint.y()+direction*arrowSize/2)); break; case Axis::FilledArrowSmall: arrowPath.lineTo(QPointF(endPoint.x()-arrowSize/4*cos_phi, endPoint.y()+direction*arrowSize/4)); arrowPath.lineTo(QPointF(endPoint.x()+arrowSize/4*cos_phi, endPoint.y()+direction*arrowSize/4)); arrowPath.lineTo(endPoint); break; case Axis::FilledArrowBig: arrowPath.lineTo(QPointF(endPoint.x()-arrowSize/2*cos_phi, endPoint.y()+direction*arrowSize/2)); arrowPath.lineTo(QPointF(endPoint.x()+arrowSize/2*cos_phi, endPoint.y()+direction*arrowSize/2)); arrowPath.lineTo(endPoint); break; case Axis::SemiFilledArrowSmall: arrowPath.lineTo(QPointF(endPoint.x()-arrowSize/4*cos_phi, endPoint.y()+direction*arrowSize/4)); arrowPath.lineTo(QPointF(endPoint.x(), endPoint.y()+direction*arrowSize/8)); arrowPath.lineTo(QPointF(endPoint.x()+arrowSize/4*cos_phi, endPoint.y()+direction*arrowSize/4)); arrowPath.lineTo(endPoint); break; case Axis::SemiFilledArrowBig: arrowPath.lineTo(QPointF(endPoint.x()-arrowSize/2*cos_phi, endPoint.y()+direction*arrowSize/2)); arrowPath.lineTo(QPointF(endPoint.x(), endPoint.y()+direction*arrowSize/4)); arrowPath.lineTo(QPointF(endPoint.x()+arrowSize/2*cos_phi, endPoint.y()+direction*arrowSize/2)); arrowPath.lineTo(endPoint); break; } } } //! helper function for retransformTicks() bool AxisPrivate::transformAnchor(QPointF* anchorPoint) { QVector points; points.append(*anchorPoint); points = m_cSystem->mapLogicalToScene(points); if (points.count() != 1) { // point is not mappable or in a coordinate gap return false; } else { *anchorPoint = points.at(0); return true; } } /*! recalculates the position of the axis ticks. */ void AxisPrivate::retransformTicks() { if (suppressRetransform) return; //TODO: check that start and end are > 0 for log and >=0 for sqrt, etc. majorTicksPath = QPainterPath(); minorTicksPath = QPainterPath(); majorTickPoints.clear(); minorTickPoints.clear(); tickLabelValues.clear(); if ( majorTicksNumber < 1 || (majorTicksDirection == Axis::noTicks && minorTicksDirection == Axis::noTicks) ) { retransformTickLabelPositions(); //this calls recalcShapeAndBoundingRect() return; } //determine the spacing for the major ticks double majorTicksSpacing = 0; int tmpMajorTicksNumber = 0; if (majorTicksType == Axis::TicksTotalNumber) { //the total number of the major ticks is given - > determine the spacing tmpMajorTicksNumber = majorTicksNumber; switch (scale) { case Axis::ScaleLinear: majorTicksSpacing = (end-start)/(majorTicksNumber-1); break; case Axis::ScaleLog10: majorTicksSpacing = (log10(end)-log10(start))/(majorTicksNumber-1); break; case Axis::ScaleLog2: majorTicksSpacing = (log(end)-log(start))/log(2)/(majorTicksNumber-1); break; case Axis::ScaleLn: majorTicksSpacing = (log(end)-log(start))/(majorTicksNumber-1); break; case Axis::ScaleSqrt: majorTicksSpacing = (sqrt(end)-sqrt(start))/(majorTicksNumber-1); break; case Axis::ScaleX2: majorTicksSpacing = (pow(end,2)-pow(start,2))/(majorTicksNumber-1); } } else if (majorTicksType == Axis::TicksIncrement) { //the spacing (increment) of the major ticks is given - > determine the number majorTicksSpacing = majorTicksIncrement; switch (scale) { case Axis::ScaleLinear: tmpMajorTicksNumber = qRound((end-start)/majorTicksSpacing + 1); break; case Axis::ScaleLog10: tmpMajorTicksNumber = qRound((log10(end)-log10(start))/majorTicksSpacing + 1); break; case Axis::ScaleLog2: tmpMajorTicksNumber = qRound((log(end)-log(start))/log(2)/majorTicksSpacing + 1); break; case Axis::ScaleLn: tmpMajorTicksNumber = qRound((log(end)-log(start))/majorTicksSpacing + 1); break; case Axis::ScaleSqrt: tmpMajorTicksNumber = qRound((sqrt(end)-sqrt(start))/majorTicksSpacing + 1); break; case Axis::ScaleX2: tmpMajorTicksNumber = qRound((pow(end,2)-pow(start,2))/majorTicksSpacing + 1); } } else { //custom column was provided if (majorTicksColumn) { tmpMajorTicksNumber = majorTicksColumn->rowCount(); } else { retransformTickLabelPositions(); //this calls recalcShapeAndBoundingRect() return; } } int tmpMinorTicksNumber; if (minorTicksType == Axis::TicksTotalNumber) tmpMinorTicksNumber = minorTicksNumber; else if (minorTicksType == Axis::TicksIncrement) tmpMinorTicksNumber = (end - start)/ (majorTicksNumber - 1)/minorTicksIncrement - 1; else (minorTicksColumn) ? tmpMinorTicksNumber = minorTicksColumn->rowCount() : tmpMinorTicksNumber = 0; QPointF anchorPoint; QPointF startPoint; QPointF endPoint; qreal majorTickPos=0.0; qreal minorTickPos; qreal nextMajorTickPos = 0.0; int xDirection = m_cSystem->xDirection(); int yDirection = m_cSystem->yDirection(); double middleX = m_plot->xMin() + (m_plot->xMax() - m_plot->xMin())/2; double middleY = m_plot->yMin() + (m_plot->yMax() - m_plot->yMin())/2; bool valid; for (int iMajor = 0; iMajor < tmpMajorTicksNumber; iMajor++) { //calculate major tick's position if (majorTicksType != Axis::TicksCustomColumn) { switch (scale) { case Axis::ScaleLinear: majorTickPos = start + majorTicksSpacing*iMajor; nextMajorTickPos = start + majorTicksSpacing*(iMajor+1); break; case Axis::ScaleLog10: majorTickPos = pow(10, log10(start) + majorTicksSpacing*iMajor); nextMajorTickPos = pow(10, log10(start) + majorTicksSpacing*(iMajor+1)); break; case Axis::ScaleLog2: majorTickPos = pow(2, log(start)/log(2) + majorTicksSpacing*iMajor); nextMajorTickPos = pow(2, log(start)/log(2) + majorTicksSpacing*(iMajor+1)); break; case Axis::ScaleLn: majorTickPos = exp(log(start) + majorTicksSpacing*iMajor); nextMajorTickPos = exp(log(start) + majorTicksSpacing*(iMajor+1)); break; case Axis::ScaleSqrt: majorTickPos = pow(sqrt(start) + majorTicksSpacing*iMajor, 2); nextMajorTickPos = pow(sqrt(start) + majorTicksSpacing*(iMajor+1), 2); break; case Axis::ScaleX2: majorTickPos = sqrt(sqrt(start) + majorTicksSpacing*iMajor); nextMajorTickPos = sqrt(sqrt(start) + majorTicksSpacing*(iMajor+1)); break; } } else { majorTickPos = majorTicksColumn->valueAt(iMajor); if (std::isnan(majorTickPos)) break; //stop iterating after the first non numerical value in the column } //calculate start and end points for major tick's line if (majorTicksDirection != Axis::noTicks ) { if (orientation == Axis::AxisHorizontal) { anchorPoint.setX(majorTickPos); anchorPoint.setY(offset); valid = transformAnchor(&anchorPoint); if (valid) { if (offset < middleY) { startPoint = anchorPoint + QPointF(0, (majorTicksDirection & Axis::ticksIn) ? yDirection * majorTicksLength : 0); endPoint = anchorPoint + QPointF(0, (majorTicksDirection & Axis::ticksOut) ? -yDirection * majorTicksLength : 0); } else { startPoint = anchorPoint + QPointF(0, (majorTicksDirection & Axis::ticksOut) ? yDirection * majorTicksLength : 0); endPoint = anchorPoint + QPointF(0, (majorTicksDirection & Axis::ticksIn) ? -yDirection * majorTicksLength : 0); } } } else { // vertical anchorPoint.setY(majorTickPos); anchorPoint.setX(offset); valid = transformAnchor(&anchorPoint); if (valid) { if (offset < middleX) { startPoint = anchorPoint + QPointF((majorTicksDirection & Axis::ticksIn) ? xDirection * majorTicksLength : 0, 0); endPoint = anchorPoint + QPointF((majorTicksDirection & Axis::ticksOut) ? -xDirection * majorTicksLength : 0, 0); } else { startPoint = anchorPoint + QPointF((majorTicksDirection & Axis::ticksOut) ? xDirection * majorTicksLength : 0, 0); endPoint = anchorPoint + QPointF((majorTicksDirection & Axis::ticksIn) ? -xDirection * majorTicksLength : 0, 0); } } } //add major tick's line to the painter path if (valid) { majorTicksPath.moveTo(startPoint); majorTicksPath.lineTo(endPoint); majorTickPoints << anchorPoint; tickLabelValues<< scalingFactor*majorTickPos+zeroOffset; } } //minor ticks if ((Axis::noTicks != minorTicksDirection) && (tmpMajorTicksNumber > 1) && (tmpMinorTicksNumber > 0) && (iMajorvalueAt(iMinor); if (std::isnan(minorTickPos)) break; //stop iterating after the first non numerical value in the column //in the case a custom column is used for the minor ticks, we draw them _once_ for the whole range of the axis. //execute the minor ticks loop only once. if (iMajor > 0) break; } //calculate start and end points for minor tick's line if (orientation == Axis::AxisHorizontal) { anchorPoint.setX(minorTickPos); anchorPoint.setY(offset); valid = transformAnchor(&anchorPoint); if (valid) { if (offset < middleY) { startPoint = anchorPoint + QPointF(0, (minorTicksDirection & Axis::ticksIn) ? yDirection * minorTicksLength : 0); endPoint = anchorPoint + QPointF(0, (minorTicksDirection & Axis::ticksOut) ? -yDirection * minorTicksLength : 0); } else { startPoint = anchorPoint + QPointF(0, (minorTicksDirection & Axis::ticksOut) ? yDirection * minorTicksLength : 0); endPoint = anchorPoint + QPointF(0, (minorTicksDirection & Axis::ticksIn) ? -yDirection * minorTicksLength : 0); } } } else { // vertical anchorPoint.setY(minorTickPos); anchorPoint.setX(offset); valid = transformAnchor(&anchorPoint); if (valid) { if (offset < middleX) { startPoint = anchorPoint + QPointF((minorTicksDirection & Axis::ticksIn) ? xDirection * minorTicksLength : 0, 0); endPoint = anchorPoint + QPointF((minorTicksDirection & Axis::ticksOut) ? -xDirection * minorTicksLength : 0, 0); } else { startPoint = anchorPoint + QPointF((minorTicksDirection & Axis::ticksOut) ? xDirection * minorTicksLength : 0, 0); endPoint = anchorPoint + QPointF((minorTicksDirection & Axis::ticksIn) ? -xDirection * minorTicksLength : 0, 0); } } } //add minor tick's line to the painter path if (valid) { minorTicksPath.moveTo(startPoint); minorTicksPath.lineTo(endPoint); minorTickPoints << anchorPoint; } } } } //tick positions where changed -> update the position of the tick labels and grid lines retransformTickLabelStrings(); retransformMajorGrid(); retransformMinorGrid(); } /*! creates the tick label strings starting with the most optimal (=the smallest possible number of float digits) precision for the floats */ void AxisPrivate::retransformTickLabelStrings() { if (suppressRetransform) return; // DEBUG("AxisPrivate::retransformTickLabelStrings()"); if (labelsAutoPrecision) { //check, whether we need to increase the current precision int newPrecision = upperLabelsPrecision(labelsPrecision); if (newPrecision!= labelsPrecision) { labelsPrecision = newPrecision; emit q->labelsPrecisionChanged(labelsPrecision); } else { //check, whether we can reduce the current precision newPrecision = lowerLabelsPrecision(labelsPrecision); if (newPrecision!= labelsPrecision) { labelsPrecision = newPrecision; emit q->labelsPrecisionChanged(labelsPrecision); } } } // DEBUG("labelsPrecision =" << labelsPrecision); tickLabelStrings.clear(); QString str; if (labelsFormat == Axis::FormatDecimal) { QString nullStr = QString::number(0, 'f', labelsPrecision); foreach (double value, tickLabelValues) { str = QString::number(value, 'f', labelsPrecision); if (str == "-" + nullStr) str = nullStr; str = labelsPrefix + str + labelsSuffix; tickLabelStrings << str; } } else if (labelsFormat == Axis::FormatScientificE) { QString nullStr = QString::number(0, 'e', labelsPrecision); foreach (double value, tickLabelValues) { str = QString::number(value, 'e', labelsPrecision); if (str == "-" + nullStr) str = nullStr; tickLabelStrings << str; } } else if (labelsFormat == Axis::FormatPowers10) { foreach (double value, tickLabelValues) { str = "10" + QString::number(log10(value), 'f', labelsPrecision) + ""; str = labelsPrefix + str + labelsSuffix; tickLabelStrings << str; } } else if (labelsFormat == Axis::FormatPowers2) { foreach (double value, tickLabelValues) { str = "2" + QString::number(log2(value), 'f', labelsPrecision) + ""; str = labelsPrefix + str + labelsSuffix; tickLabelStrings << str; } } else if (labelsFormat == Axis::FormatPowersE) { foreach (double value, tickLabelValues) { str = "e" + QString::number(log(value), 'f', labelsPrecision) + ""; str = labelsPrefix + str + labelsSuffix; tickLabelStrings << str; } } else if (labelsFormat == Axis::FormatMultipliesPi) { foreach (double value, tickLabelValues) { str = "" + QString::number(value / M_PI, 'f', labelsPrecision) + "" + QChar(0x03C0); str = labelsPrefix + str + labelsSuffix; tickLabelStrings << str; } } //recalculate the position of the tick labels retransformTickLabelPositions(); } /*! returns the smallest upper limit for the precision where no duplicates for the tick label float occur. */ int AxisPrivate::upperLabelsPrecision(int precision) { // DEBUG("AxisPrivate::upperLabelsPrecision() precision =" << precision); //round float to the current precision and look for duplicates. //if there are duplicates, increase the precision. QVector tempValues; for (int i = 0; i < tickLabelValues.size(); ++i) tempValues.append( roundP(tickLabelValues[i], precision) ); for (int i = 0; i < tempValues.size(); ++i) { for (int j = 0; j < tempValues.size(); ++j) { if (i == j) continue; if (tempValues.at(i) == tempValues.at(j)) { //duplicate for the current precision found, increase the precision and check again return upperLabelsPrecision(precision + 1); } } } //no duplicates for the current precision found: return the current value return precision; } /*! returns highest lower limit for the precision where no duplicates for the tick label float occur. */ int AxisPrivate::lowerLabelsPrecision(int precision) { // DEBUG("AxisPrivate::lowerLabelsPrecision() precision =" << precision); //round float to the current precision and look for duplicates. //if there are duplicates, decrease the precision. QVector tempValues; for (int i = 0; i < tickLabelValues.size(); ++i) tempValues.append( roundP(tickLabelValues[i], precision-1) ); for (int i = 0; i < tempValues.size(); ++i) { for (int j = 0; j < tempValues.size(); ++j) { if (i == j) continue; if (tempValues.at(i) == tempValues.at(j)) { //duplicate found for the reduced precision //-> current precision cannot be reduced, return the current value return precision; } } } //no duplicates found, reduce further, and check again if (precision == 0) return 0; else return lowerLabelsPrecision(precision - 1); } double AxisPrivate::roundP(double value, int precision) { //DEBUG("AxisPrivate::round() value =" << value << "precision =" << precision); double result = round(value * pow(10, precision)) / pow(10, precision); //DEBUG(" result =" << result); return result; } /*! recalculates the position of the tick labels. Called when the geometry related properties (position, offset, font size, suffix, prefix) of the labels are changed. */ void AxisPrivate::retransformTickLabelPositions() { tickLabelPoints.clear(); if (majorTicksDirection == Axis::noTicks || labelsPosition == Axis::NoLabels) { recalcShapeAndBoundingRect(); return; } QFontMetrics fm(labelsFont); float width = 0; float height = fm.ascent(); QString label; QPointF pos; double middleX = m_plot->xMin() + (m_plot->xMax() - m_plot->xMin())/2; double middleY = m_plot->yMin() + (m_plot->yMax() - m_plot->yMin())/2; int xDirection = m_cSystem->xDirection(); int yDirection = m_cSystem->yDirection(); QPointF startPoint, endPoint, anchorPoint; QTextDocument td; td.setDefaultFont(labelsFont); for ( int i = 0; i < majorTickPoints.size(); i++ ) { if (labelsFormat == Axis::FormatDecimal || labelsFormat == Axis::FormatScientificE) { width = fm.width(tickLabelStrings.at(i)); } else { td.setHtml(tickLabelStrings.at(i)); width = td.size().width(); height = td.size().height(); } anchorPoint = majorTickPoints.at(i); //center align all labels with respect to the end point of the tick line if (orientation == Axis::AxisHorizontal) { if (offset < middleY) { startPoint = anchorPoint + QPointF(0, (majorTicksDirection & Axis::ticksIn) ? yDirection * majorTicksLength : 0); endPoint = anchorPoint + QPointF(0, (majorTicksDirection & Axis::ticksOut) ? -yDirection * majorTicksLength : 0); } else { startPoint = anchorPoint + QPointF(0, (majorTicksDirection & Axis::ticksOut) ? yDirection * majorTicksLength : 0); endPoint = anchorPoint + QPointF(0, (majorTicksDirection & Axis::ticksIn) ? -yDirection * majorTicksLength : 0); } if (labelsPosition == Axis::LabelsOut) { pos.setX( endPoint.x() - width/2); pos.setY( endPoint.y() + height + labelsOffset ); } else { pos.setX( startPoint.x() - width/2); pos.setY( startPoint.y() - labelsOffset ); } } else {// vertical if (offset < middleX) { startPoint = anchorPoint + QPointF((majorTicksDirection & Axis::ticksIn) ? xDirection * majorTicksLength : 0, 0); endPoint = anchorPoint + QPointF((majorTicksDirection & Axis::ticksOut) ? -xDirection * majorTicksLength : 0, 0); } else { startPoint = anchorPoint + QPointF((majorTicksDirection & Axis::ticksOut) ? xDirection * majorTicksLength : 0, 0); endPoint = anchorPoint + QPointF((majorTicksDirection & Axis::ticksIn) ? -xDirection * majorTicksLength : 0, 0); } if (labelsPosition == Axis::LabelsOut) { pos.setX( endPoint.x() - width - labelsOffset ); pos.setY( endPoint.y() + height/2 ); } else { pos.setX( startPoint.x() + labelsOffset ); pos.setY( startPoint.y() + height/2 ); } } tickLabelPoints << pos; } recalcShapeAndBoundingRect(); } void AxisPrivate::retransformMajorGrid() { if (suppressRetransform) return; majorGridPath = QPainterPath(); if (majorGridPen.style() == Qt::NoPen || majorTickPoints.size() == 0) { recalcShapeAndBoundingRect(); return; } //major tick points are already in scene coordinates, convert them back to logical... //TODO: mapping should work without SuppressPageClipping-flag, check float comparisons in the map-function. //Currently, grid lines disappear somtimes without this flag QVector logicalMajorTickPoints = m_cSystem->mapSceneToLogical(majorTickPoints, AbstractCoordinateSystem::SuppressPageClipping); if (logicalMajorTickPoints.isEmpty()) return; //TODO: //when iterating over all grid lines, skip the first and the last points for auto scaled axes, //since we don't want to paint any grid lines at the plot boundaries bool skipLowestTick, skipUpperTick; if (orientation == Axis::AxisHorizontal) { //horizontal axis skipLowestTick = qFuzzyCompare(logicalMajorTickPoints.at(0).x(), m_plot->xMin()); skipUpperTick = qFuzzyCompare(logicalMajorTickPoints.at(logicalMajorTickPoints.size()-1).x(), m_plot->xMax()); } else { skipLowestTick = qFuzzyCompare(logicalMajorTickPoints.at(0).y(), m_plot->yMin()); skipUpperTick = qFuzzyCompare(logicalMajorTickPoints.at(logicalMajorTickPoints.size()-1).y(), m_plot->yMax()); } int start, end; if (skipLowestTick) { if (logicalMajorTickPoints.size() > 1) start = 1; else start = 0; } else { start = 0; } if (skipUpperTick) { if (logicalMajorTickPoints.size() > 1) end = logicalMajorTickPoints.size() - 1; else end = 0; } else { end = logicalMajorTickPoints.size(); } QVector lines; if (orientation == Axis::AxisHorizontal) { //horizontal axis double yMin = m_plot->yMin(); double yMax = m_plot->yMax(); for (int i=start; ixMin(); double xMax = m_plot->xMax(); //skip the first and the last points, since we don't want to paint any grid lines at the plot boundaries for (int i = start; i < end; ++i) { const QPointF& point = logicalMajorTickPoints.at(i); lines.append( QLineF(xMin, point.y(), xMax, point.y()) ); } } lines = m_cSystem->mapLogicalToScene(lines, AbstractCoordinateSystem::SuppressPageClipping); foreach (const QLineF& line, lines) { majorGridPath.moveTo(line.p1()); majorGridPath.lineTo(line.p2()); } recalcShapeAndBoundingRect(); } void AxisPrivate::retransformMinorGrid() { if (suppressRetransform) return; minorGridPath = QPainterPath(); if (minorGridPen.style() == Qt::NoPen) { recalcShapeAndBoundingRect(); return; } //minor tick points are already in scene coordinates, convert them back to logical... //TODO: mapping should work without SuppressPageClipping-flag, check float comparisons in the map-function. //Currently, grid lines disappear somtimes without this flag QVector logicalMinorTickPoints = m_cSystem->mapSceneToLogical(minorTickPoints, AbstractCoordinateSystem::SuppressPageClipping); QVector lines; if (orientation == Axis::AxisHorizontal) { //horizontal axis double yMin = m_plot->yMin(); double yMax = m_plot->yMax(); for (int i = 0; i < logicalMinorTickPoints.size(); ++i) { const QPointF& point = logicalMinorTickPoints.at(i); lines.append( QLineF(point.x(), yMin, point.x(), yMax) ); } } else { //vertical axis double xMin = m_plot->xMin(); double xMax = m_plot->xMax(); for (int i = 0; i < logicalMinorTickPoints.size(); ++i) { const QPointF& point = logicalMinorTickPoints.at(i); lines.append( QLineF(xMin, point.y(), xMax, point.y()) ); } } lines = m_cSystem->mapLogicalToScene(lines, AbstractCoordinateSystem::SuppressPageClipping); foreach (const QLineF& line, lines) { minorGridPath.moveTo(line.p1()); minorGridPath.lineTo(line.p2()); } recalcShapeAndBoundingRect(); } void AxisPrivate::recalcShapeAndBoundingRect() { if (m_suppressRecalc) return; prepareGeometryChange(); if (linePath.isEmpty()) { axisShape = QPainterPath(); boundingRectangle = QRectF(); title->setPositionInvalid(true); if (m_plot) m_plot->prepareGeometryChange(); return; } else { title->setPositionInvalid(false); } axisShape = WorksheetElement::shapeFromPath(linePath, linePen); axisShape.addPath(WorksheetElement::shapeFromPath(arrowPath, linePen)); axisShape.addPath(WorksheetElement::shapeFromPath(majorTicksPath, majorTicksPen)); axisShape.addPath(WorksheetElement::shapeFromPath(minorTicksPath, minorTicksPen)); QPainterPath tickLabelsPath = QPainterPath(); if (labelsPosition != Axis::NoLabels) { QTransform trafo; QPainterPath tempPath; QFontMetrics fm(labelsFont); QTextDocument td; td.setDefaultFont(labelsFont); for (int i = 0; i < tickLabelPoints.size(); i++) { tempPath = QPainterPath(); if (labelsFormat == Axis::FormatDecimal || labelsFormat == Axis::FormatScientificE) { tempPath.addRect( fm.boundingRect(tickLabelStrings.at(i)) ); } else { td.setHtml(tickLabelStrings.at(i)); tempPath.addRect( QRectF(0, -td.size().height(), td.size().width(), td.size().height()) ); } trafo.reset(); trafo.translate( tickLabelPoints.at(i).x(), tickLabelPoints.at(i).y() ); trafo.rotate( -labelsRotationAngle ); tempPath = trafo.map(tempPath); tickLabelsPath.addPath(WorksheetElement::shapeFromPath(tempPath, linePen)); } axisShape.addPath(WorksheetElement::shapeFromPath(tickLabelsPath, QPen())); } //add title label, if available if ( title->isVisible() && !title->text().text.isEmpty() ) { //determine the new position of the title label: //we calculate the new position here and not in retransform(), //since it depends on the size and position of the tick labels, tickLabelsPath, available here. QRectF rect=linePath.boundingRect(); qreal offsetX = titleOffsetX - labelsOffset; //the distance to the axis line qreal offsetY = titleOffsetY - labelsOffset; //the distance to the axis line if (orientation == Axis::AxisHorizontal) { offsetY -= title->graphicsItem()->boundingRect().height()/2 + tickLabelsPath.boundingRect().height(); title->setPosition( QPointF( (rect.topLeft().x() + rect.topRight().x())/2 + offsetX, rect.bottomLeft().y() - offsetY ) ); } else { offsetX -= title->graphicsItem()->boundingRect().width()/2 + tickLabelsPath.boundingRect().width(); title->setPosition( QPointF( rect.topLeft().x() + offsetX, (rect.topLeft().y() + rect.bottomLeft().y())/2 - offsetY) ); } axisShape.addPath(WorksheetElement::shapeFromPath(title->graphicsItem()->mapToParent(title->graphicsItem()->shape()), linePen)); } boundingRectangle = axisShape.boundingRect(); //if the axis goes beyond the current bounding box of the plot (too high offset is used, too long labels etc.) //request a prepareGeometryChange() for the plot in order to properly keep track of geometry changes if (m_plot) m_plot->prepareGeometryChange(); } /*! paints the content of the axis. Reimplemented from \c QGraphicsItem. \sa QGraphicsItem::paint() */ void AxisPrivate::paint(QPainter *painter, const QStyleOptionGraphicsItem* option, QWidget* widget) { Q_UNUSED(option) Q_UNUSED(widget) if (!isVisible()) return; if (linePath.isEmpty()) return; //draw the line if (linePen.style() != Qt::NoPen) { painter->setOpacity(lineOpacity); painter->setPen(linePen); painter->setBrush(Qt::SolidPattern); painter->drawPath(linePath); //draw the arrow if (arrowType != Axis::NoArrow) painter->drawPath(arrowPath); } //draw the major ticks if (majorTicksDirection != Axis::noTicks) { painter->setOpacity(majorTicksOpacity); painter->setPen(majorTicksPen); painter->setBrush(Qt::NoBrush); painter->drawPath(majorTicksPath); } //draw the minor ticks if (minorTicksDirection != Axis::noTicks) { painter->setOpacity(minorTicksOpacity); painter->setPen(minorTicksPen); painter->setBrush(Qt::NoBrush); painter->drawPath(minorTicksPath); } // draw tick labels if (labelsPosition != Axis::NoLabels) { painter->setOpacity(labelsOpacity); painter->setPen(QPen(labelsColor)); painter->setFont(labelsFont); QTextDocument td; td.setDefaultFont(labelsFont); for (int i = 0; i < tickLabelPoints.size(); i++) { painter->translate(tickLabelPoints.at(i)); painter->save(); painter->rotate(-labelsRotationAngle); if (labelsFormat == Axis::FormatDecimal || labelsFormat == Axis::FormatScientificE) { painter->drawText(QPoint(0,0), tickLabelStrings.at(i)); } else { td.setHtml(tickLabelStrings.at(i)); painter->translate(0, -td.size().height()); td.drawContents(painter); } painter->restore(); painter->translate(-tickLabelPoints.at(i)); } } if (m_hovered && !isSelected() && !m_printing){ painter->setPen(QPen(QApplication::palette().color(QPalette::Shadow), 2, Qt::SolidLine)); painter->drawPath(axisShape); } if (isSelected() && !m_printing){ painter->setPen(QPen(QApplication::palette().color(QPalette::Highlight), 2, Qt::SolidLine)); painter->drawPath(axisShape); } } void AxisPrivate::contextMenuEvent(QGraphicsSceneContextMenuEvent* event) { q->createContextMenu()->exec(event->screenPos()); } void AxisPrivate::hoverEnterEvent(QGraphicsSceneHoverEvent*) { if (!isSelected()) { m_hovered = true; q->hovered(); update(axisShape.boundingRect()); } } void AxisPrivate::hoverLeaveEvent(QGraphicsSceneHoverEvent*) { if (m_hovered) { m_hovered = false; q->unhovered(); update(axisShape.boundingRect()); } } void AxisPrivate::setPrinting(bool on) { m_printing = on; } //############################################################################## //################## Serialization/Deserialization ########################### //############################################################################## //! Save as XML void Axis::save(QXmlStreamWriter* writer) const{ Q_D(const Axis); writer->writeStartElement( "axis" ); writeBasicAttributes( writer ); writeCommentElement( writer ); //general writer->writeStartElement( "general" ); writer->writeAttribute( "autoScale", QString::number(d->autoScale) ); writer->writeAttribute( "orientation", QString::number(d->orientation) ); writer->writeAttribute( "position", QString::number(d->position) ); writer->writeAttribute( "scale", QString::number(d->scale) ); writer->writeAttribute( "offset", QString::number(d->offset) ); writer->writeAttribute( "start", QString::number(d->start) ); writer->writeAttribute( "end", QString::number(d->end) ); writer->writeAttribute( "scalingFactor", QString::number(d->scalingFactor) ); writer->writeAttribute( "zeroOffset", QString::number(d->zeroOffset) ); writer->writeAttribute( "titleOffsetX", QString::number(d->titleOffsetX) ); writer->writeAttribute( "titleOffsetY", QString::number(d->titleOffsetY) ); writer->writeAttribute( "visible", QString::number(d->isVisible()) ); writer->writeEndElement(); //label d->title->save( writer ); //line writer->writeStartElement( "line" ); WRITE_QPEN(d->linePen); writer->writeAttribute( "opacity", QString::number(d->lineOpacity) ); writer->writeAttribute( "arrowType", QString::number(d->arrowType) ); writer->writeAttribute( "arrowPosition", QString::number(d->arrowPosition) ); writer->writeAttribute( "arrowSize", QString::number(d->arrowSize) ); writer->writeEndElement(); //major ticks writer->writeStartElement( "majorTicks" ); writer->writeAttribute( "direction", QString::number(d->majorTicksDirection) ); writer->writeAttribute( "type", QString::number(d->majorTicksType) ); writer->writeAttribute( "number", QString::number(d->majorTicksNumber) ); writer->writeAttribute( "increment", QString::number(d->majorTicksIncrement) ); WRITE_COLUMN(d->majorTicksColumn, majorTicksColumn); writer->writeAttribute( "length", QString::number(d->majorTicksLength) ); WRITE_QPEN(d->majorTicksPen); writer->writeAttribute( "opacity", QString::number(d->majorTicksOpacity) ); writer->writeEndElement(); //minor ticks writer->writeStartElement( "minorTicks" ); writer->writeAttribute( "direction", QString::number(d->minorTicksDirection) ); writer->writeAttribute( "type", QString::number(d->minorTicksType) ); writer->writeAttribute( "number", QString::number(d->minorTicksNumber) ); writer->writeAttribute( "increment", QString::number(d->minorTicksIncrement) ); WRITE_COLUMN(d->minorTicksColumn, minorTicksColumn); writer->writeAttribute( "length", QString::number(d->minorTicksLength) ); WRITE_QPEN(d->minorTicksPen); writer->writeAttribute( "opacity", QString::number(d->minorTicksOpacity) ); writer->writeEndElement(); //extra ticks //labels writer->writeStartElement( "labels" ); writer->writeAttribute( "position", QString::number(d->labelsPosition) ); writer->writeAttribute( "offset", QString::number(d->labelsOffset) ); writer->writeAttribute( "rotation", QString::number(d->labelsRotationAngle) ); writer->writeAttribute( "format", QString::number(d->labelsFormat) ); writer->writeAttribute( "precision", QString::number(d->labelsPrecision) ); writer->writeAttribute( "autoPrecision", QString::number(d->labelsAutoPrecision) ); WRITE_QCOLOR(d->labelsColor); WRITE_QFONT(d->labelsFont); writer->writeAttribute( "prefix", d->labelsPrefix ); writer->writeAttribute( "suffix", d->labelsSuffix ); writer->writeAttribute( "opacity", QString::number(d->labelsOpacity) ); writer->writeEndElement(); //grid writer->writeStartElement( "majorGrid" ); WRITE_QPEN(d->majorGridPen); writer->writeAttribute( "opacity", QString::number(d->majorGridOpacity) ); writer->writeEndElement(); writer->writeStartElement( "minorGrid" ); WRITE_QPEN(d->minorGridPen); writer->writeAttribute( "opacity", QString::number(d->minorGridOpacity) ); writer->writeEndElement(); writer->writeEndElement(); // close "axis" section } //! Load from XML bool Axis::load(XmlStreamReader* reader, bool preview) { Q_D(Axis); if (!reader->isStartElement() || reader->name() != "axis") { reader->raiseError(i18n("no axis element found")); return false; } if (!readBasicAttributes(reader)) return false; QString attributeWarning = i18n("Attribute '%1' missing or empty, default value is used"); QXmlStreamAttributes attribs; QString str; QRectF rect; while (!reader->atEnd()) { reader->readNext(); if (reader->isEndElement() && reader->name() == "axis") break; if (!reader->isStartElement()) continue; if (!preview && reader->name() == "comment") { if (!readCommentElement(reader)) return false; } else if (!preview && reader->name() == "general") { attribs = reader->attributes(); str = attribs.value("autoScale").toString(); if (str.isEmpty()) reader->raiseWarning(attributeWarning.arg("'autoScale'")); else d->autoScale = (bool)str.toInt(); str = attribs.value("orientation").toString(); if (str.isEmpty()) reader->raiseWarning(attributeWarning.arg("'orientation'")); else d->orientation = (Axis::AxisOrientation)str.toInt(); str = attribs.value("position").toString(); if (str.isEmpty()) reader->raiseWarning(attributeWarning.arg("'position'")); else d->position = (Axis::AxisPosition)str.toInt(); str = attribs.value("scale").toString(); if (str.isEmpty()) reader->raiseWarning(attributeWarning.arg("'scale'")); else d->scale = (Axis::AxisScale)str.toInt(); str = attribs.value("offset").toString(); if (str.isEmpty()) reader->raiseWarning(attributeWarning.arg("'offset'")); else d->offset = str.toDouble(); str = attribs.value("start").toString(); if (str.isEmpty()) reader->raiseWarning(attributeWarning.arg("'start'")); else d->start = str.toDouble(); str = attribs.value("end").toString(); if (str.isEmpty()) reader->raiseWarning(attributeWarning.arg("'end'")); else d->end = str.toDouble(); str = attribs.value("scalingFactor").toString(); if (str.isEmpty()) reader->raiseWarning(attributeWarning.arg("'scalingFactor'")); else d->scalingFactor = str.toDouble(); str = attribs.value("zeroOffset").toString(); if (str.isEmpty()) reader->raiseWarning(attributeWarning.arg("'zeroOffset'")); else d->zeroOffset = str.toDouble(); str = attribs.value("titleOffsetX").toString(); if (str.isEmpty()) reader->raiseWarning(attributeWarning.arg("'titleOffsetX'")); else d->titleOffsetX = str.toDouble(); str = attribs.value("titleOffsetY").toString(); if (str.isEmpty()) reader->raiseWarning(attributeWarning.arg("'titleOffsetY'")); else d->titleOffsetY = str.toDouble(); str = attribs.value("visible").toString(); if (str.isEmpty()) reader->raiseWarning(attributeWarning.arg("'visible'")); else d->setVisible(str.toInt()); } else if (reader->name() == "textLabel") { d->title->load(reader, preview); } else if (!preview && reader->name() == "line") { attribs = reader->attributes(); READ_QPEN(d->linePen); str = attribs.value("opacity").toString(); if (str.isEmpty()) reader->raiseWarning(attributeWarning.arg("'opacity'")); else d->lineOpacity = str.toDouble(); str = attribs.value("arrowType").toString(); if (str.isEmpty()) reader->raiseWarning(attributeWarning.arg("'arrowType'")); else d->arrowType = (Axis::ArrowType)str.toInt(); str = attribs.value("arrowPosition").toString(); if (str.isEmpty()) reader->raiseWarning(attributeWarning.arg("'arrowPosition'")); else d->arrowPosition = (Axis::ArrowPosition)str.toInt(); str = attribs.value("arrowSize").toString(); if (str.isEmpty()) reader->raiseWarning(attributeWarning.arg("'arrowSize'")); else d->arrowSize = str.toDouble(); } else if (!preview && reader->name() == "majorTicks") { attribs = reader->attributes(); str = attribs.value("direction").toString(); if (str.isEmpty()) reader->raiseWarning(attributeWarning.arg("'direction'")); else d->majorTicksDirection = (Axis::TicksDirection)str.toInt(); str = attribs.value("type").toString(); if (str.isEmpty()) reader->raiseWarning(attributeWarning.arg("'type'")); else d->majorTicksType = (Axis::TicksType)str.toInt(); str = attribs.value("number").toString(); if (str.isEmpty()) reader->raiseWarning(attributeWarning.arg("'number'")); else d->majorTicksNumber = str.toInt(); str = attribs.value("increment").toString(); if (str.isEmpty()) reader->raiseWarning(attributeWarning.arg("'increment'")); else d->majorTicksIncrement = str.toDouble(); READ_COLUMN(majorTicksColumn); str = attribs.value("length").toString(); if (str.isEmpty()) reader->raiseWarning(attributeWarning.arg("'length'")); else d->majorTicksLength = str.toDouble(); READ_QPEN(d->majorTicksPen); str = attribs.value("opacity").toString(); if (str.isEmpty()) reader->raiseWarning(attributeWarning.arg("'opacity'")); else d->majorTicksOpacity = str.toDouble(); } else if (!preview && reader->name() == "minorTicks") { attribs = reader->attributes(); str = attribs.value("direction").toString(); if (str.isEmpty()) reader->raiseWarning(attributeWarning.arg("'direction'")); else d->minorTicksDirection = (Axis::TicksDirection)str.toInt(); str = attribs.value("type").toString(); if (str.isEmpty()) reader->raiseWarning(attributeWarning.arg("'type'")); else d->minorTicksType = (Axis::TicksType)str.toInt(); str = attribs.value("number").toString(); if (str.isEmpty()) reader->raiseWarning(attributeWarning.arg("'number'")); else d->minorTicksNumber = str.toInt(); str = attribs.value("increment").toString(); if (str.isEmpty()) reader->raiseWarning(attributeWarning.arg("'increment'")); else d->minorTicksIncrement = str.toDouble(); READ_COLUMN(minorTicksColumn); str = attribs.value("length").toString(); if (str.isEmpty()) reader->raiseWarning(attributeWarning.arg("'length'")); else d->minorTicksLength = str.toDouble(); READ_QPEN(d->minorTicksPen); str = attribs.value("opacity").toString(); if (str.isEmpty()) reader->raiseWarning(attributeWarning.arg("'opacity'")); else d->minorTicksOpacity = str.toDouble(); } else if (!preview && reader->name() == "labels") { attribs = reader->attributes(); str = attribs.value("position").toString(); if (str.isEmpty()) reader->raiseWarning(attributeWarning.arg("'position'")); else d->labelsPosition = (Axis::LabelsPosition)str.toInt(); str = attribs.value("offset").toString(); if (str.isEmpty()) reader->raiseWarning(attributeWarning.arg("'offset'")); else d->labelsOffset = str.toDouble(); str = attribs.value("rotation").toString(); if (str.isEmpty()) reader->raiseWarning(attributeWarning.arg("'rotation'")); else d->labelsRotationAngle = str.toDouble(); str = attribs.value("format").toString(); if (str.isEmpty()) reader->raiseWarning(attributeWarning.arg("'format'")); else d->labelsFormat = (Axis::LabelsFormat)str.toInt(); str = attribs.value("precision").toString(); if (str.isEmpty()) reader->raiseWarning(attributeWarning.arg("'precision'")); else d->labelsPrecision = str.toInt(); str = attribs.value("autoPrecision").toString(); if (str.isEmpty()) reader->raiseWarning(attributeWarning.arg("'autoPrecision'")); else d->labelsAutoPrecision = str.toInt(); READ_QCOLOR(d->labelsColor); READ_QFONT(d->labelsFont); //don't produce any warning if no prefix or suffix is set (empty string is allowd here in xml) d->labelsPrefix = attribs.value("prefix").toString(); d->labelsSuffix = attribs.value("suffix").toString(); str = attribs.value("opacity").toString(); if (str.isEmpty()) reader->raiseWarning(attributeWarning.arg("'opacity'")); else d->labelsOpacity = str.toDouble(); } else if (!preview && reader->name() == "majorGrid") { attribs = reader->attributes(); READ_QPEN(d->majorGridPen); str = attribs.value("opacity").toString(); if (str.isEmpty()) reader->raiseWarning(attributeWarning.arg("'opacity'")); else d->majorGridOpacity = str.toDouble(); } else if (!preview && reader->name() == "minorGrid") { attribs = reader->attributes(); READ_QPEN(d->minorGridPen); str = attribs.value("opacity").toString(); if (str.isEmpty()) reader->raiseWarning(attributeWarning.arg("'opacity'")); else d->minorGridOpacity = str.toDouble(); } else { // unknown element reader->raiseWarning(i18n("unknown element '%1'", reader->name().toString())); if (!reader->skipToEndElement()) return false; } } return true; } //############################################################################## //######################### Theme management ################################## //############################################################################## void Axis::loadThemeConfig(const KConfig& config) { const KConfigGroup group = config.group("Axis"); QPen p; // Tick label this->setLabelsColor(group.readEntry("LabelsFontColor",(QColor) this->labelsColor())); this->setLabelsOpacity(group.readEntry("LabelsOpacity",this->labelsOpacity())); //Line this->setLineOpacity(group.readEntry("LineOpacity",this->lineOpacity())); p.setColor(group.readEntry("LineColor", (QColor) this->linePen().color())); p.setStyle((Qt::PenStyle)group.readEntry("LineStyle",(int) this->linePen().style())); p.setWidthF(group.readEntry("LineWidth", this->linePen().widthF())); this->setLinePen(p); //Major ticks this->setMajorGridOpacity(group.readEntry("MajorGridOpacity", this->majorGridOpacity())); p.setColor(group.readEntry("MajorGridColor",(QColor) this->majorGridPen().color())); p.setStyle((Qt::PenStyle)group.readEntry("MajorGridStyle",(int) this->majorGridPen().style())); p.setWidthF(group.readEntry("MajorGridWidth", this->majorGridPen().widthF())); this->setMajorGridPen(p); p.setColor(group.readEntry("MajorTicksColor",(QColor)this->majorTicksPen().color())); p.setStyle((Qt::PenStyle)group.readEntry("MajorTicksLineStyle",(int) this->majorTicksPen().style())); p.setWidthF(group.readEntry("MajorTicksWidth", this->majorTicksPen().widthF())); this->setMajorTicksPen(p); this->setMajorTicksOpacity(group.readEntry("MajorTicksOpacity",this->majorTicksOpacity())); this->setMajorTicksType((Axis::TicksType)group.readEntry("MajorTicksType",(int)this->majorTicksType())); //Minor ticks this->setMinorGridOpacity(group.readEntry("MinorGridOpacity", this->minorGridOpacity())); p.setColor(group.readEntry("MinorGridColor",(QColor) this->minorGridPen().color())); p.setStyle((Qt::PenStyle)group.readEntry("MinorGridStyle",(int) this->minorGridPen().style())); p.setWidthF(group.readEntry("MinorGridWidth", this->minorGridPen().widthF())); this->setMinorGridPen(p); p.setColor(group.readEntry("MinorTicksColor",(QColor) this->minorTicksPen().color())); p.setStyle((Qt::PenStyle)group.readEntry("MinorTicksLineStyle",(int) this->minorTicksPen().style())); p.setWidthF(group.readEntry("MinorTicksWidth", this->minorTicksPen().widthF())); this->setMinorTicksPen(p); this->setMinorTicksOpacity(group.readEntry("MinorTicksOpacity",this->minorTicksOpacity())); this->setMinorTicksType((Axis::TicksType)group.readEntry("MinorTicksType",(int)this->minorTicksType())); const QVector& childElements = children(AbstractAspect::IncludeHidden); for (auto* child : childElements) child->loadThemeConfig(config); } void Axis::saveThemeConfig(const KConfig& config) { KConfigGroup group = config.group("Axis"); // Tick label group.writeEntry("LabelsFontColor", (QColor) this->labelsColor()); group.writeEntry("LabelsOpacity", this->labelsOpacity()); //Line group.writeEntry("LineOpacity", this->lineOpacity()); group.writeEntry("LineColor", (QColor) this->linePen().color()); group.writeEntry("LineStyle", (int) this->linePen().style()); group.writeEntry("LineWidth", this->linePen().widthF()); //Major ticks group.writeEntry("MajorGridOpacity", this->majorGridOpacity()); group.writeEntry("MajorGridColor", (QColor) this->majorGridPen().color()); group.writeEntry("MajorGridStyle", (int) this->majorGridPen().style()); group.writeEntry("MajorGridWidth", this->majorGridPen().widthF()); group.writeEntry("MajorTicksColor", (QColor)this->majorTicksPen().color()); group.writeEntry("MajorTicksLineStyle", (int) this->majorTicksPen().style()); group.writeEntry("MajorTicksWidth", this->majorTicksPen().widthF()); group.writeEntry("MajorTicksOpacity", this->majorTicksOpacity()); group.writeEntry("MajorTicksType", (int)this->majorTicksType()); //Minor ticks group.writeEntry("MinorGridOpacity", this->minorGridOpacity()); group.writeEntry("MinorGridColor",(QColor) this->minorGridPen().color()); group.writeEntry("MinorGridStyle", (int) this->minorGridPen().style()); group.writeEntry("MinorGridWidth", this->minorGridPen().widthF()); group.writeEntry("MinorTicksColor", (QColor) this->minorTicksPen().color()); group.writeEntry("MinorTicksLineStyle",( int) this->minorTicksPen().style()); group.writeEntry("MinorTicksWidth", this->minorTicksPen().widthF()); group.writeEntry("MinorTicksOpacity", this->minorTicksOpacity()); group.writeEntry("MinorTicksType", (int)this->minorTicksType()); const QVector& childElements = children(AbstractAspect::IncludeHidden); childElements.at(0)->saveThemeConfig(config); } diff --git a/src/backend/worksheet/plots/cartesian/Axis.h b/src/backend/worksheet/plots/cartesian/Axis.h index 0d3eeefc2..ac5d9f35d 100644 --- a/src/backend/worksheet/plots/cartesian/Axis.h +++ b/src/backend/worksheet/plots/cartesian/Axis.h @@ -1,292 +1,292 @@ /*************************************************************************** File : Axis.h Project : LabPlot Description : Axis for cartesian coordinate systems. -------------------------------------------------------------------- Copyright : (C) 2009 Tilman Benkert (thzs@gmx.net) Copyright : (C) 2011-2017 Alexander Semke (alexander.semke@web.de) Copyright : (C) 2013 Stefan Gerlach (stefan.gerlach@uni-konstanz.de) ***************************************************************************/ /*************************************************************************** * * * 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 AXISNEW_H #define AXISNEW_H #include "backend/worksheet/WorksheetElement.h" #include "backend/lib/macros.h" class CartesianPlot; class TextLabel; class AxisPrivate; class AbstractColumn; class QActionGroup; //TODO: align class Axis: public WorksheetElement { Q_OBJECT public: enum AxisOrientation {AxisHorizontal, AxisVertical}; enum AxisPosition {AxisTop, AxisBottom, AxisLeft, AxisRight, AxisCentered, AxisCustom}; enum LabelsFormat {FormatDecimal, FormatScientificE, FormatPowers10, FormatPowers2, FormatPowersE, FormatMultipliesPi}; enum TicksFlags { noTicks = 0x00, ticksIn = 0x01, ticksOut = 0x02, ticksBoth = 0x03, }; Q_DECLARE_FLAGS(TicksDirection, TicksFlags) enum TicksType {TicksTotalNumber, TicksIncrement, TicksCustomColumn, TicksCustomValues}; enum ArrowType {NoArrow, SimpleArrowSmall, SimpleArrowBig, FilledArrowSmall, FilledArrowBig, SemiFilledArrowSmall, SemiFilledArrowBig}; enum ArrowPosition {ArrowLeft, ArrowRight, ArrowBoth}; enum AxisScale {ScaleLinear, ScaleLog10, ScaleLog2, ScaleLn, ScaleSqrt, ScaleX2}; enum LabelsPosition {NoLabels, LabelsIn, LabelsOut}; explicit Axis(const QString&, CartesianPlot*, const AxisOrientation& orientation = AxisHorizontal); - virtual ~Axis(); + ~Axis() override; - virtual QIcon icon() const override; - virtual QMenu* createContextMenu() override; + QIcon icon() const override; + QMenu* createContextMenu() override; - virtual QGraphicsItem* graphicsItem() const override; - virtual void setZValue(qreal) override; + QGraphicsItem* graphicsItem() const override; + void setZValue(qreal) override; - virtual void save(QXmlStreamWriter*) const override; - virtual bool load(XmlStreamReader*, bool preview) override; - virtual void loadThemeConfig(const KConfig&) override; - virtual void saveThemeConfig(const KConfig&) override; + void save(QXmlStreamWriter*) const override; + bool load(XmlStreamReader*, bool preview) override; + void loadThemeConfig(const KConfig&) override; + void saveThemeConfig(const KConfig&) override; BASIC_D_ACCESSOR_DECL(bool, autoScale, AutoScale) BASIC_D_ACCESSOR_DECL(AxisOrientation, orientation, Orientation) BASIC_D_ACCESSOR_DECL(AxisPosition, position, Position) BASIC_D_ACCESSOR_DECL(AxisScale, scale, Scale) BASIC_D_ACCESSOR_DECL(double, start, Start) BASIC_D_ACCESSOR_DECL(double, end, End) void setOffset(const double, const bool=true); double offset() const; BASIC_D_ACCESSOR_DECL(qreal, scalingFactor, ScalingFactor) BASIC_D_ACCESSOR_DECL(qreal, zeroOffset, ZeroOffset) POINTER_D_ACCESSOR_DECL(TextLabel, title, Title) BASIC_D_ACCESSOR_DECL(double, titleOffsetX, TitleOffsetX) BASIC_D_ACCESSOR_DECL(double, titleOffsetY, TitleOffsetY) CLASS_D_ACCESSOR_DECL(QPen, linePen, LinePen) BASIC_D_ACCESSOR_DECL(qreal, lineOpacity, LineOpacity) BASIC_D_ACCESSOR_DECL(ArrowType, arrowType, ArrowType) BASIC_D_ACCESSOR_DECL(ArrowPosition, arrowPosition, ArrowPosition) BASIC_D_ACCESSOR_DECL(double, arrowSize, ArrowSize) BASIC_D_ACCESSOR_DECL(TicksDirection, majorTicksDirection, MajorTicksDirection) BASIC_D_ACCESSOR_DECL(TicksType, majorTicksType, MajorTicksType) BASIC_D_ACCESSOR_DECL(int, majorTicksNumber, MajorTicksNumber) BASIC_D_ACCESSOR_DECL(qreal, majorTicksIncrement, MajorTicksIncrement) POINTER_D_ACCESSOR_DECL(const AbstractColumn, majorTicksColumn, MajorTicksColumn) QString& majorTicksColumnPath() const; CLASS_D_ACCESSOR_DECL(QPen, majorTicksPen, MajorTicksPen) BASIC_D_ACCESSOR_DECL(qreal, majorTicksLength, MajorTicksLength) BASIC_D_ACCESSOR_DECL(qreal, majorTicksOpacity, MajorTicksOpacity) BASIC_D_ACCESSOR_DECL(TicksDirection, minorTicksDirection, MinorTicksDirection) BASIC_D_ACCESSOR_DECL(TicksType, minorTicksType, MinorTicksType) BASIC_D_ACCESSOR_DECL(int, minorTicksNumber, MinorTicksNumber) BASIC_D_ACCESSOR_DECL(qreal, minorTicksIncrement, MinorTicksIncrement) POINTER_D_ACCESSOR_DECL(const AbstractColumn, minorTicksColumn, MinorTicksColumn) QString& minorTicksColumnPath() const; CLASS_D_ACCESSOR_DECL(QPen, minorTicksPen, MinorTicksPen) BASIC_D_ACCESSOR_DECL(qreal, minorTicksLength, MinorTicksLength) BASIC_D_ACCESSOR_DECL(qreal, minorTicksOpacity, MinorTicksOpacity) BASIC_D_ACCESSOR_DECL(LabelsFormat, labelsFormat, LabelsFormat) BASIC_D_ACCESSOR_DECL(bool, labelsAutoPrecision, LabelsAutoPrecision) BASIC_D_ACCESSOR_DECL(int, labelsPrecision, LabelsPrecision) BASIC_D_ACCESSOR_DECL(LabelsPosition, labelsPosition, LabelsPosition) BASIC_D_ACCESSOR_DECL(qreal, labelsOffset, LabelsOffset) BASIC_D_ACCESSOR_DECL(qreal, labelsRotationAngle, LabelsRotationAngle) CLASS_D_ACCESSOR_DECL(QColor, labelsColor, LabelsColor) CLASS_D_ACCESSOR_DECL(QFont, labelsFont, LabelsFont) CLASS_D_ACCESSOR_DECL(QString, labelsPrefix, LabelsPrefix) CLASS_D_ACCESSOR_DECL(QString, labelsSuffix, LabelsSuffix) BASIC_D_ACCESSOR_DECL(qreal, labelsOpacity, LabelsOpacity) CLASS_D_ACCESSOR_DECL(QPen, majorGridPen, MajorGridPen) BASIC_D_ACCESSOR_DECL(qreal, majorGridOpacity, MajorGridOpacity) CLASS_D_ACCESSOR_DECL(QPen, minorGridPen, MinorGridPen) BASIC_D_ACCESSOR_DECL(qreal, minorGridOpacity, MinorGridOpacity) - virtual void setVisible(bool) override; - virtual bool isVisible() const override; - virtual void setPrinting(bool) override; + void setVisible(bool) override; + bool isVisible() const override; + void setPrinting(bool) override; void setSuppressRetransform(bool); - virtual void retransform() override; - virtual void handleResize(double horizontalRatio, double verticalRatio, bool pageResize) override; + void retransform() override; + void handleResize(double horizontalRatio, double verticalRatio, bool pageResize) override; typedef AxisPrivate Private; protected: AxisPrivate* const d_ptr; Axis(const QString&, const AxisOrientation&, AxisPrivate*); TextLabel* m_title; private: Q_DECLARE_PRIVATE(Axis) void init(); void initActions(); void initMenus(); QAction* visibilityAction; QAction* orientationHorizontalAction; QAction* orientationVerticalAction; QActionGroup* orientationActionGroup; QActionGroup* lineStyleActionGroup; QActionGroup* lineColorActionGroup; QMenu* orientationMenu; QMenu* lineMenu; QMenu* lineStyleMenu; QMenu* lineColorMenu; private slots: void labelChanged(); void retransformTicks(); void majorTicksColumnAboutToBeRemoved(const AbstractAspect*); void minorTicksColumnAboutToBeRemoved(const AbstractAspect*); //SLOTs for changes triggered via QActions in the context menu void orientationChangedSlot(QAction*); void lineStyleChanged(QAction*); void lineColorChanged(QAction*); void visibilityChangedSlot(); signals: friend class AxisSetOrientationCmd; friend class AxisSetPositionCmd; friend class AxisSetScalingCmd; friend class AxisSetAutoScaleCmd; friend class AxisSetStartCmd; friend class AxisSetEndCmd; friend class AxisSetZeroOffsetCmd; friend class AxisSetScalingFactorCmd; void orientationChanged(Axis::AxisOrientation); void positionChanged(Axis::AxisPosition); void positionChanged(double); void scaleChanged(Axis::AxisScale); void startChanged(double); void autoScaleChanged(bool); void endChanged(double); void zeroOffsetChanged(qreal); void scalingFactorChanged(qreal); //title friend class AxisSetTitleOffsetXCmd; friend class AxisSetTitleOffsetYCmd; void titleOffsetXChanged(qreal); void titleOffsetYChanged(qreal); // line friend class AxisSetLinePenCmd; friend class AxisSetLineOpacityCmd; friend class AxisSetArrowTypeCmd; friend class AxisSetArrowPositionCmd; friend class AxisSetArrowSizeCmd; void linePenChanged(const QPen&); void lineOpacityChanged(qreal); void arrowTypeChanged(Axis::ArrowType); void arrowPositionChanged(Axis::ArrowPosition); void arrowSizeChanged(qreal); // major ticks friend class AxisSetMajorTicksDirectionCmd; friend class AxisSetMajorTicksTypeCmd; friend class AxisSetMajorTicksNumberCmd; friend class AxisSetMajorTicksIncrementCmd; friend class AxisSetMajorTicksColumnCmd; friend class AxisSetMajorTicksPenCmd; friend class AxisSetMajorTicksLengthCmd; friend class AxisSetMajorTicksOpacityCmd; void majorTicksDirectionChanged(Axis::TicksDirection); void majorTicksTypeChanged(Axis::TicksType); void majorTicksNumberChanged(int); void majorTicksIncrementChanged(qreal); void majorTicksColumnChanged(const AbstractColumn*); void majorTicksPenChanged(QPen); void majorTicksLengthChanged(qreal); void majorTicksOpacityChanged(qreal); // minor ticks friend class AxisSetMinorTicksDirectionCmd; friend class AxisSetMinorTicksTypeCmd; friend class AxisSetMinorTicksNumberCmd; friend class AxisSetMinorTicksIncrementCmd; friend class AxisSetMinorTicksColumnCmd; friend class AxisSetMinorTicksPenCmd; friend class AxisSetMinorTicksLengthCmd; friend class AxisSetMinorTicksOpacityCmd; void minorTicksDirectionChanged(Axis::TicksDirection); void minorTicksTypeChanged(Axis::TicksType); void minorTicksNumberChanged(int); void minorTicksIncrementChanged(qreal); void minorTicksColumnChanged(const AbstractColumn*); void minorTicksPenChanged(QPen); void minorTicksLengthChanged(qreal); void minorTicksOpacityChanged(qreal); //labels friend class AxisSetLabelsFormatCmd; friend class AxisSetLabelsAutoPrecisionCmd; friend class AxisSetLabelsPrecisionCmd; friend class AxisSetLabelsPositionCmd; friend class AxisSetLabelsOffsetCmd; friend class AxisSetLabelsRotationAngleCmd; friend class AxisSetLabelsColorCmd; friend class AxisSetLabelsFontCmd; friend class AxisSetLabelsPrefixCmd; friend class AxisSetLabelsSuffixCmd; friend class AxisSetLabelsOpacityCmd; void labelsFormatChanged(Axis::LabelsFormat); void labelsAutoPrecisionChanged(bool); void labelsPrecisionChanged(int); void labelsPositionChanged(Axis::LabelsPosition); void labelsOffsetChanged(double); void labelsRotationAngleChanged(qreal); void labelsColorChanged(QColor); void labelsFontChanged(QFont); void labelsPrefixChanged(QString); void labelsSuffixChanged(QString); void labelsOpacityChanged(qreal); friend class AxisSetMajorGridPenCmd; friend class AxisSetMajorGridOpacityCmd; friend class AxisSetMinorGridPenCmd; friend class AxisSetMinorGridOpacityCmd; void majorGridPenChanged(QPen); void majorGridOpacityChanged(qreal); void minorGridPenChanged(QPen); void minorGridOpacityChanged(qreal); void visibilityChanged(bool); }; Q_DECLARE_OPERATORS_FOR_FLAGS(Axis::TicksDirection) #endif diff --git a/src/backend/worksheet/plots/cartesian/AxisPrivate.h b/src/backend/worksheet/plots/cartesian/AxisPrivate.h index d3592bc56..48823171f 100644 --- a/src/backend/worksheet/plots/cartesian/AxisPrivate.h +++ b/src/backend/worksheet/plots/cartesian/AxisPrivate.h @@ -1,167 +1,167 @@ /*************************************************************************** File : AxisPrivate.h Project : LabPlot Description : Private members of Axis. -------------------------------------------------------------------- Copyright : (C) 2011-2017 Alexander Semke (alexander.semke@web.de) ***************************************************************************/ /*************************************************************************** * * * 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 AXISPRIVATE_H #define AXISPRIVATE_H #include #include #include #include "Axis.h" class QGraphicsSceneHoverEvent; class AxisGrid; class CartesianPlot; class CartesianCoordinateSystem; class TextLabel; class AxisPrivate: public QGraphicsItem { public: explicit AxisPrivate(Axis*, CartesianPlot*); - virtual QRectF boundingRect() const override; - virtual QPainterPath shape() const override; + QRectF boundingRect() const override; + QPainterPath shape() const override; QString name() const; void retransform(); void retransformLine(); void retransformArrow(); void retransformTicks(); void retransformTickLabelPositions(); void retransformTickLabelStrings(); void retransformMinorGrid(); void retransformMajorGrid(); bool swapVisible(bool); void recalcShapeAndBoundingRect(); void setPrinting(bool); //general bool autoScale; Axis::AxisOrientation orientation; //!< horizontal or vertical Axis::AxisPosition position; //!< left, right, bottom, top or custom (usually not changed after creation) Axis::AxisScale scale; double offset; //!< offset from zero in the direction perpendicular to the axis double start; //!< start coordinate of the axis line double end; //!< end coordinate of the axis line qreal scalingFactor; qreal zeroOffset; //line QVector lines; QPen linePen; qreal lineOpacity; Axis::ArrowType arrowType; Axis::ArrowPosition arrowPosition; qreal arrowSize; // Title TextLabel* title; qreal titleOffsetX; //distance to the axis line qreal titleOffsetY; //distance to the axis line // Ticks Axis::TicksDirection majorTicksDirection; //!< major ticks direction: inwards, outwards, both, or none Axis::TicksType majorTicksType; //!< the way how the number of major ticks is specified - either as a total number or an increment int majorTicksNumber; //!< number of major ticks qreal majorTicksIncrement; //!< increment (step) for the major ticks const AbstractColumn* majorTicksColumn; //!< column containing values for major ticks' positions QString majorTicksColumnPath; qreal majorTicksLength; //!< major tick length (in page units!) QPen majorTicksPen; qreal majorTicksOpacity; Axis::TicksDirection minorTicksDirection; //!< minor ticks direction: inwards, outwards, both, or none Axis::TicksType minorTicksType; //!< the way how the number of minor ticks is specified - either as a total number or an increment int minorTicksNumber; //!< number of minor ticks (between each two major ticks) qreal minorTicksIncrement; //!< increment (step) for the minor ticks const AbstractColumn* minorTicksColumn; //!< column containing values for minor ticks' positions QString minorTicksColumnPath; qreal minorTicksLength; //!< minor tick length (in page units!) QPen minorTicksPen; qreal minorTicksOpacity; // Tick Label Axis::LabelsFormat labelsFormat; int labelsPrecision; bool labelsAutoPrecision; Axis::LabelsPosition labelsPosition; qreal labelsRotationAngle; QColor labelsColor; QFont labelsFont; qreal labelsOffset; //!< offset, distance to the end of the tick line (in page units) qreal labelsOpacity; QString labelsPrefix; QString labelsSuffix; //Grid AxisGrid* gridItem; QPen majorGridPen; qreal majorGridOpacity; QPen minorGridPen; qreal minorGridOpacity; Axis* const q; QPainterPath linePath; QPainterPath majorGridPath; QPainterPath minorGridPath; bool suppressRetransform; private: - virtual void contextMenuEvent(QGraphicsSceneContextMenuEvent*) override; - virtual void hoverEnterEvent(QGraphicsSceneHoverEvent*) override; - virtual void hoverLeaveEvent(QGraphicsSceneHoverEvent*) override; - virtual void paint(QPainter*, const QStyleOptionGraphicsItem*, QWidget* widget = 0) override; + void contextMenuEvent(QGraphicsSceneContextMenuEvent*) override; + void hoverEnterEvent(QGraphicsSceneHoverEvent*) override; + void hoverLeaveEvent(QGraphicsSceneHoverEvent*) override; + void paint(QPainter*, const QStyleOptionGraphicsItem*, QWidget* widget = 0) override; void addArrow(const QPointF& point, int direction); int upperLabelsPrecision(int); int lowerLabelsPrecision(int); double roundP(double value, int precision); bool transformAnchor(QPointF*); QPainterPath arrowPath; QPainterPath majorTicksPath; QPainterPath minorTicksPath; QRectF boundingRectangle; QPainterPath axisShape; QVector majorTickPoints;//!< position of the major ticks on the axis. QVector minorTickPoints;//!< position of the major ticks on the axis. QVector tickLabelPoints; //!< position of the major tick labels (left lower edge of label's bounding rect) QVector tickLabelValues; //!< major tick labels values QVector tickLabelStrings; //!< the actual text of the major tick labels CartesianPlot* m_plot; const CartesianCoordinateSystem* m_cSystem; bool m_hovered; bool m_suppressRecalc; bool m_printing; }; #endif diff --git a/src/backend/worksheet/plots/cartesian/CartesianCoordinateSystem.cpp b/src/backend/worksheet/plots/cartesian/CartesianCoordinateSystem.cpp index fa9820062..368d0e974 100644 --- a/src/backend/worksheet/plots/cartesian/CartesianCoordinateSystem.cpp +++ b/src/backend/worksheet/plots/cartesian/CartesianCoordinateSystem.cpp @@ -1,681 +1,681 @@ /*************************************************************************** File : CartesianCoordinateSystem.cpp Project : LabPlot Description : Cartesian coordinate system for plots. -------------------------------------------------------------------- Copyright : (C) 2012-2016 by Alexander Semke (alexander.semke@web.de) ***************************************************************************/ /*************************************************************************** * * * 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 "backend/worksheet/plots/cartesian/CartesianCoordinateSystem.h" #include "backend/worksheet/plots/cartesian/CartesianPlot.h" /* ============================================================================ */ /* =================================== scales ================================= */ /* ============================================================================ */ /** * \class CartesianScale * \brief Base class for cartesian coordinate system scales. */ CartesianScale::CartesianScale(ScaleType type, const Interval &interval, double a, double b, double c) : m_type(type), m_interval(interval), m_a(a), m_b(b), m_c(c) { } CartesianScale::~CartesianScale() {} void CartesianScale::getProperties(ScaleType *type, Interval *interval, double *a, double *b, double *c) const { if (type) *type = m_type; if (interval) *interval = m_interval; if (a) *a = m_a; if (b) *b = m_b; if (c) *c = m_c; } double CartesianScale::start() const { return m_interval.start(); } double CartesianScale::end() const { return m_interval.end(); } bool CartesianScale::contains(double value) const { return m_interval.fuzzyContains(value); } /** * \class CartesianCoordinateSystem::LinearScale * \brief implementation of the linear scale for cartesian coordinate system. */ class LinearScale : public CartesianScale { public: LinearScale(const Interval &interval, double offset, double gradient) : CartesianScale(ScaleLinear, interval, offset, gradient, 0) { Q_ASSERT(gradient != 0.0); } - virtual ~LinearScale() {} + ~LinearScale() override {} - virtual bool map(double *value) const { + bool map(double *value) const override { *value = *value * m_b + m_a; return true; } - virtual bool inverseMap(double *value) const { + bool inverseMap(double *value) const override { if (m_b == 0.0) return false; *value = (*value - m_a) / m_b; return true; } - virtual int direction() const { + int direction() const override { return m_b < 0 ? -1 : 1; } }; /** * \class CartesianCoordinateSystem::LinearScale * \brief implementation of the linear scale for cartesian coordinate system. */ class LogScale : public CartesianScale { public: LogScale(const Interval &interval, double offset, double scaleFactor, double base) : CartesianScale(ScaleLog, interval, offset, scaleFactor, base) { Q_ASSERT(scaleFactor != 0.0); Q_ASSERT(base > 0.0); } - virtual ~LogScale() {} + ~LogScale() override {} - virtual bool map(double *value) const { + bool map(double *value) const override { if (*value > 0.0) *value = log(*value)/log(m_c) * m_b + m_a; else return false; return true; } - virtual bool inverseMap(double *value) const { + bool inverseMap(double *value) const override { if (m_a == 0.0) return false; if (m_c <= 0.0) return false; *value = pow(m_c, (*value - m_a) / m_b); return true; } - virtual int direction() const { + int direction() const override { return m_b < 0 ? -1 : 1; } }; /* ============================================================================ */ /* ========================= coordinate system ================================ */ /* ============================================================================ */ class CartesianCoordinateSystemPrivate { public: CartesianCoordinateSystemPrivate(CartesianCoordinateSystem *owner); ~CartesianCoordinateSystemPrivate(); CartesianCoordinateSystem* const q; CartesianPlot* plot; QVector xScales; QVector yScales; }; /** * \class CartesianCoordinateSystem * \brief Cartesian coordinate system for plots. */ CartesianCoordinateSystem::CartesianCoordinateSystem(CartesianPlot* plot) : AbstractCoordinateSystem(plot), d(new CartesianCoordinateSystemPrivate(this)) { d->plot=plot; // TODO: set some standard scales } CartesianCoordinateSystem::~CartesianCoordinateSystem() { delete d; } CartesianScale *CartesianScale::createScale(ScaleType type, const Interval &interval, double a, double b, double c) { switch (type) { case ScaleLinear: return new LinearScale(interval, a, b); case ScaleLog: return new LogScale(interval, a, b, c); default: return NULL; } } CartesianScale *CartesianScale::createLinearScale(const Interval &interval, double sceneStart, double sceneEnd, double logicalStart, double logicalEnd) { DEBUG("CartesianScale::createLinearScale() scene start/end = " << sceneStart << '/' << sceneEnd << ", logical start/end = " << logicalStart << '/' << logicalEnd); double lDiff = logicalEnd - logicalStart; if (lDiff == 0.0) return NULL; double b = (sceneEnd - sceneStart) / lDiff; double a = sceneStart - b * logicalStart; return new LinearScale(interval, a, b); } CartesianScale *CartesianScale::createLogScale(const Interval &interval, double sceneStart, double sceneEnd, double logicalStart, double logicalEnd, double base) { if (base < 0.0 || base == 0.0) return NULL; if (logicalStart < 0.0 || logicalStart == 0.0) return NULL; if (logicalEnd < 0.0 || logicalEnd == 0.0) return NULL; double lDiff = (log(logicalEnd) - log(logicalStart)) / log(base); if (lDiff == 0.0) return NULL; double b = (sceneEnd - sceneStart) / lDiff; double a = sceneStart - b * log(logicalStart)/log(base); return new LogScale(interval, a, b, base); } //############################################################################## //######################### logical to scene mappers ########################### //############################################################################## QVector CartesianCoordinateSystem::mapLogicalToScene(const QVector &points, const MappingFlags &flags) const { const QRectF pageRect = d->plot->plotRect(); QVector result; bool noPageClipping = pageRect.isNull() || (flags & SuppressPageClipping); foreach (const CartesianScale* xScale, d->xScales) { if (!xScale) continue; foreach (const CartesianScale* yScale, d->yScales) { if (!yScale) continue; foreach(const QPointF& point, points) { double x = point.x(); double y = point.y(); if (!xScale->contains(x)) continue; if (!yScale->contains(y)) continue; if (!xScale->map(&x)) continue; if (!yScale->map(&y)) continue; const QPointF mappedPoint(x, y); if (noPageClipping || rectContainsPoint(pageRect, mappedPoint)) result.append(mappedPoint); } } } return result; } /*! Maps the points in logical coordinates from \c points and fills the \c visiblePoints with the points in logical coordinates restricted to the current intervals. \param logicalPoints List of points in logical coordinates \param scenePoints List for the points in scene coordinates \param visiblePoints List for the logical coordinates restricted to the current region of the coordinate system \param flags */ void CartesianCoordinateSystem::mapLogicalToScene(const QVector& logicalPoints, QVector& scenePoints, std::vector& visiblePoints, const MappingFlags& flags) const{ const QRectF pageRect = d->plot->plotRect(); QVector result; const bool noPageClipping = pageRect.isNull() || (flags & SuppressPageClipping); foreach (const CartesianScale* xScale, d->xScales) { if (!xScale) continue; foreach (const CartesianScale* yScale, d->yScales) { if (!yScale) continue; for (int i=0; icontains(x)) continue; if (!xScale->map(&x)) continue; double y = point.y(); if (!yScale->contains(y)) continue; if (!yScale->map(&y)) continue; const QPointF mappedPoint(x, y); if (noPageClipping || rectContainsPoint(pageRect, mappedPoint)) { scenePoints.append(mappedPoint); visiblePoints[i].flip(); } } } } } QPointF CartesianCoordinateSystem::mapLogicalToScene(const QPointF& logicalPoint, const MappingFlags& flags) const{ const QRectF pageRect = d->plot->plotRect(); QVector result; bool noPageClipping = pageRect.isNull() || (flags & SuppressPageClipping); double x = logicalPoint.x(); double y = logicalPoint.y(); foreach (const CartesianScale* xScale, d->xScales) { if (!xScale) continue; foreach (const CartesianScale* yScale, d->yScales) { if (!yScale) continue; if (!xScale->contains(x)) continue; if (!xScale->map(&x)) continue; if (!yScale->contains(y)) continue; if (!yScale->map(&y)) continue; QPointF mappedPoint(x, y); if (noPageClipping || rectContainsPoint(pageRect, mappedPoint)) return mappedPoint; } } return QPointF(); } QVector CartesianCoordinateSystem::mapLogicalToScene(const QVector &lines, const MappingFlags &flags) const{ QRectF pageRect = d->plot->plotRect(); QVector result; const bool doPageClipping = !pageRect.isNull() && !(flags & SuppressPageClipping); double xGapBefore = NAN; double xGapAfter = NAN; double yGapBefore = NAN; double yGapAfter = NAN; QVectorIterator xIterator(d->xScales); while (xIterator.hasNext()) { const CartesianScale* xScale = xIterator.next(); if (!xScale) continue; xGapBefore = xGapAfter; if (xIterator.hasNext()) { const CartesianScale* nextXScale = xIterator.peekNext(); if (!nextXScale) continue; Interval nextXInterval; nextXScale->getProperties(NULL, &nextXInterval); double x1 = xScale->end(); double x2 = nextXScale->start(); bool valid = xScale->map(&x1); if (valid) valid = nextXScale->map(&x2); if (valid) xGapAfter = x2 - x1; else xGapAfter = NAN; } else xGapAfter = NAN; QVectorIterator yIterator(d->yScales); while (yIterator.hasNext()) { const CartesianScale* yScale = yIterator.next(); if (!yScale) continue; yGapBefore = yGapAfter; if (yIterator.hasNext()) { const CartesianScale* nextYScale = yIterator.peekNext(); if (!nextYScale) continue; double y1 = yScale->end(); double y2 = nextYScale->start(); bool valid = yScale->map(&y1); if (valid) valid = nextYScale->map(&y2); if (valid) yGapAfter = y2 - y1; else yGapAfter = NAN; } else yGapAfter = NAN; const QRectF scaleRect = QRectF(xScale->start(), yScale->start(), xScale->end() - xScale->start(), yScale->end() - yScale->start()).normalized(); foreach (QLineF line, lines) { LineClipResult clipResult; if (!AbstractCoordinateSystem::clipLineToRect(&line, scaleRect, &clipResult)) continue; double x1 = line.x1(); if (!xScale->map(&x1)) continue; double x2 = line.x2(); if (!xScale->map(&x2)) continue; double y1 = line.y1(); if (!yScale->map(&y1)) continue; double y2 = line.y2(); if (!yScale->map(&y2)) continue; if (flags & MarkGaps) { //mark the end of the gap if (!std::isnan(xGapBefore)) { if (clipResult.xClippedLeft[0]) { QLineF gapMarker(x1 + xGapBefore/4, y1 - xGapBefore/2, x1 - xGapBefore/4, y1 + xGapBefore/2); // if (AbstractCoordinateSystem::clipLineToRect(&gapMarker, pageRect)) result.append(gapMarker); } if (clipResult.xClippedLeft[1]) { QLineF gapMarker(x2 + xGapBefore/4, y2 - xGapBefore/2, x2 - xGapBefore/4, y2 + xGapBefore/2); // if (AbstractCoordinateSystem::clipLineToRect(&gapMarker, pageRect)) result.append(gapMarker); } } //mark the beginning of the gap if (!std::isnan(xGapAfter)) { if (clipResult.xClippedRight[0]) { QLineF gapMarker(x1 + xGapAfter/4, y1 - xGapAfter/2, x1 - xGapAfter/4, y1 + xGapAfter/2); // if (AbstractCoordinateSystem::clipLineToRect(&gapMarker, pageRect)) result.append(gapMarker); } if (clipResult.xClippedRight[1]) { QLineF gapMarker(x2 + xGapAfter/4, y2 - xGapAfter/2, x2 - xGapAfter/4, y2 + xGapAfter/2); // if (AbstractCoordinateSystem::clipLineToRect(&gapMarker, pageRect)) result.append(gapMarker); } } if (!std::isnan(yGapBefore)) { if (clipResult.yClippedTop[0]) { QLineF gapMarker(x1 + yGapBefore/2, y1 - yGapBefore/4, x1 - yGapBefore/2, y1 + yGapBefore/4); // if (AbstractCoordinateSystem::clipLineToRect(&gapMarker, pageRect)) result.append(gapMarker); } if (clipResult.yClippedTop[1]) { QLineF gapMarker(x2 + yGapBefore/2, y2 - yGapBefore/4, x2 - yGapBefore/2, y2 + yGapBefore/4); // if (AbstractCoordinateSystem::clipLineToRect(&gapMarker, pageRect)) result.append(gapMarker); } } if (!std::isnan(yGapAfter)) { if (clipResult.yClippedBottom[0]) { QLineF gapMarker(QPointF(x1 + yGapAfter / 2, y1 - yGapAfter / 4), QPointF(x1 - yGapAfter / 2, y1 + yGapAfter / 4)); if (AbstractCoordinateSystem::clipLineToRect(&gapMarker, pageRect)) result.append(gapMarker); } if (clipResult.yClippedBottom[1]) { QLineF gapMarker(QPointF(x2 + yGapAfter / 2, y2 - yGapAfter / 4), QPointF(x2 - yGapAfter / 2, y2 + yGapAfter / 4)); if (AbstractCoordinateSystem::clipLineToRect(&gapMarker, pageRect)) result.append(gapMarker); } } } QLineF mappedLine(QPointF(x1, y1), QPointF(x2, y2)); if (doPageClipping) { if (!AbstractCoordinateSystem::clipLineToRect(&mappedLine, pageRect)) continue; } result.append(mappedLine); } } } return result; } //############################################################################## //######################### scene to logical mappers ########################### //############################################################################## QVector CartesianCoordinateSystem::mapSceneToLogical(const QVector &points, const MappingFlags &flags) const{ QRectF pageRect = d->plot->plotRect(); QVector result; bool noPageClipping = pageRect.isNull() || (flags & SuppressPageClipping); foreach(const QPointF& point, points) { if (noPageClipping || pageRect.contains(point)) { bool found = false; double x = point.x(); double y = point.y(); foreach (const CartesianScale* xScale, d->xScales) { if (found) break; if (!xScale) continue; foreach (const CartesianScale* yScale, d->yScales) { if (found) break; if (!yScale) continue; if (!xScale->inverseMap(&x)) { x = point.x(); continue; } if (!yScale->inverseMap(&y)) { y = point.y(); continue; } if (!xScale->contains(x)) { x = point.x(); continue; } if (!yScale->contains(y)) { y = point.y(); continue; } result.append(QPointF(x, y)); found = true; } } } } return result; } QPointF CartesianCoordinateSystem::mapSceneToLogical(const QPointF& logicalPoint, const MappingFlags& flags) const { QRectF pageRect = d->plot->plotRect(); QPointF result; bool noPageClipping = pageRect.isNull() || (flags & SuppressPageClipping); if (noPageClipping || pageRect.contains(logicalPoint)) { double x = logicalPoint.x(); double y = logicalPoint.y(); foreach (const CartesianScale* xScale, d->xScales) { if (!xScale) continue; foreach (const CartesianScale* yScale, d->yScales) { if (!yScale) continue; if (!xScale->inverseMap(&x)) continue; if (!yScale->inverseMap(&y)) continue; if (!xScale->contains(x)) continue; if (!yScale->contains(y)) continue; result.setX(x); result.setY(y); return result; } } } return result; } /** * \brief Determine the horizontal direction relative to the page. * * This function is needed for untransformed lengths such as axis tick length. * \return 1 or -1 */ int CartesianCoordinateSystem::xDirection() const { if (d->xScales.isEmpty()) return 1; return d->xScales.at(0)->direction(); } /** * \brief Determine the vertical direction relative to the page. * * This function is needed for untransformed lengths such as axis tick length. * \return 1 or -1 */ int CartesianCoordinateSystem::yDirection() const{ if (d->yScales.isEmpty()) return 1; return d->yScales.at(0)->direction(); } // TODO: design elegant, flexible and undo-aware API for changing scales bool CartesianCoordinateSystem::setXScales(const QVector &scales) { while (!d->xScales.isEmpty()) delete d->xScales.takeFirst(); d->xScales = scales; return true; // TODO: check scales validity } QVector CartesianCoordinateSystem::xScales() const { return d->xScales; // TODO: should rather return a copy of the scales here } bool CartesianCoordinateSystem::setYScales(const QVector &scales) { while (!d->yScales.isEmpty()) delete d->yScales.takeFirst(); d->yScales = scales; return true; // TODO: check scales validity } QVector CartesianCoordinateSystem::yScales() const { return d->yScales; // TODO: should rather return a copy of the scales here } /*! * Adjusted the function QRectF::contains(QPointF) from Qt 4.8.4 to handle the * comparison of float numbers correctly. * TODO: check whether the newer versions of Qt do the comparison correctly. */ bool CartesianCoordinateSystem::rectContainsPoint(const QRectF& rect, const QPointF& point) const{ qreal l = rect.x(); qreal r = rect.x(); qreal w = rect.width(); qreal h = rect.height(); if (w < 0) l += w; else r += w; if ( AbstractCoordinateSystem::essentiallyEqual(l, r)) // null rect return false; if ( AbstractCoordinateSystem::definitelyLessThan(point.x(), l) || AbstractCoordinateSystem::definitelyGreaterThan(point.x(), r) ) return false; qreal t = rect.y(); qreal b = rect.y(); if (h < 0) t += h; else b += h; if ( AbstractCoordinateSystem::essentiallyEqual(t, b) ) // null rect return false; if ( AbstractCoordinateSystem::definitelyLessThan(point.y(), t) || AbstractCoordinateSystem::definitelyGreaterThan(point.y(), b) ) return false; return true; } //############################################################################## //######################### Private implementation ############################# //############################################################################## CartesianCoordinateSystemPrivate::CartesianCoordinateSystemPrivate(CartesianCoordinateSystem *owner) :q(owner), plot(0) { } CartesianCoordinateSystemPrivate::~CartesianCoordinateSystemPrivate() { while (!xScales.isEmpty()) delete xScales.takeFirst(); while (!yScales.isEmpty()) delete yScales.takeFirst(); } diff --git a/src/backend/worksheet/plots/cartesian/CartesianCoordinateSystem.h b/src/backend/worksheet/plots/cartesian/CartesianCoordinateSystem.h index 8cd45e5cb..503a56e9d 100644 --- a/src/backend/worksheet/plots/cartesian/CartesianCoordinateSystem.h +++ b/src/backend/worksheet/plots/cartesian/CartesianCoordinateSystem.h @@ -1,101 +1,101 @@ /*************************************************************************** File : CartesianCoordinateSystem.h Project : LabPlot Description : Cartesian coordinate system for plots. -------------------------------------------------------------------- Copyright : (C) 2012-2016 by Alexander Semke (alexander.semke@web.de) ***************************************************************************/ /*************************************************************************** * * * 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 CARTESIANCOORDINATESYSTEM_H #define CARTESIANCOORDINATESYSTEM_H #include "backend/worksheet/plots/AbstractCoordinateSystem.h" #include "backend/lib/Interval.h" #include class CartesianPlot; class CartesianCoordinateSystemPrivate; class CartesianCoordinateSystemSetScalePropertiesCmd; class CartesianScale { public: static constexpr double LIMIT_MAX = 1e15; static constexpr double LIMIT_MIN = -1e15; virtual ~CartesianScale(); enum ScaleType {ScaleLinear, ScaleLog}; static CartesianScale *createScale(ScaleType type, const Interval &interval, double a, double b, double c); static CartesianScale *createLinearScale(const Interval &interval, double sceneStart, double sceneEnd, double logicalStart, double logicalEnd); static CartesianScale *createLogScale(const Interval &interval, double sceneStart, double sceneEnd, double logicalStart, double logicalEnd, double base); virtual void getProperties(ScaleType *type = NULL, Interval *interval = NULL, double *a = NULL, double *b = NULL, double *c = NULL) const; inline double start() const; inline double end() const; inline bool contains(double) const; virtual bool map(double*) const = 0; virtual bool inverseMap(double*) const = 0; virtual int direction() const = 0; protected: CartesianScale(ScaleType type, const Interval &interval, double a, double b, double c); ScaleType m_type; Interval m_interval; double m_a; double m_b; double m_c; }; class CartesianCoordinateSystem: public AbstractCoordinateSystem { public: explicit CartesianCoordinateSystem(CartesianPlot*); - virtual ~CartesianCoordinateSystem(); + ~CartesianCoordinateSystem() override; - virtual QVector mapLogicalToScene(const QVector&, const MappingFlags &flags = DefaultMapping) const; + QVector mapLogicalToScene(const QVector&, const MappingFlags &flags = DefaultMapping) const override; void mapLogicalToScene(const QVector& logicalPoints, QVector& scenePoints, std::vector& visiblePoints, const MappingFlags& flags = DefaultMapping) const; - virtual QPointF mapLogicalToScene(const QPointF&,const MappingFlags& flags = DefaultMapping) const; - virtual QVector mapLogicalToScene(const QVector&, const MappingFlags &flags = DefaultMapping) const; + QPointF mapLogicalToScene(const QPointF&,const MappingFlags& flags = DefaultMapping) const override; + QVector mapLogicalToScene(const QVector&, const MappingFlags &flags = DefaultMapping) const override; - virtual QVector mapSceneToLogical(const QVector&, const MappingFlags &flags = DefaultMapping) const; - virtual QPointF mapSceneToLogical(const QPointF&, const MappingFlags &flags = DefaultMapping) const; + QVector mapSceneToLogical(const QVector&, const MappingFlags &flags = DefaultMapping) const override; + QPointF mapSceneToLogical(const QPointF&, const MappingFlags &flags = DefaultMapping) const override; int xDirection() const; int yDirection() const; bool setXScales(const QVector&); QVector xScales() const; bool setYScales(const QVector&); QVector yScales() const; private: void init(); bool rectContainsPoint(const QRectF&, const QPointF&) const; CartesianCoordinateSystemPrivate* d; }; #endif diff --git a/src/backend/worksheet/plots/cartesian/CartesianPlot.cpp b/src/backend/worksheet/plots/cartesian/CartesianPlot.cpp index 4536fd824..864a03f75 100644 --- a/src/backend/worksheet/plots/cartesian/CartesianPlot.cpp +++ b/src/backend/worksheet/plots/cartesian/CartesianPlot.cpp @@ -1,2925 +1,2925 @@ /*************************************************************************** File : CartesianPlot.cpp Project : LabPlot Description : Cartesian plot -------------------------------------------------------------------- Copyright : (C) 2011-2017 by Alexander Semke (alexander.semke@web.de) Copyright : (C) 2016-2017 by Stefan Gerlach (stefan.gerlach@uni.kn) ***************************************************************************/ /*************************************************************************** * * * 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 "CartesianPlot.h" #include "CartesianPlotPrivate.h" #include "Axis.h" #include "XYCurve.h" #include "Histogram.h" #include "XYEquationCurve.h" #include "XYDataReductionCurve.h" #include "XYDifferentiationCurve.h" #include "XYIntegrationCurve.h" #include "XYInterpolationCurve.h" #include "XYSmoothCurve.h" #include "XYFitCurve.h" #include "XYFourierFilterCurve.h" #include "XYFourierTransformCurve.h" #include "backend/core/Project.h" #include "backend/spreadsheet/Spreadsheet.h" #include "backend/worksheet/plots/cartesian/CartesianPlotLegend.h" #include "backend/worksheet/plots/cartesian/CustomPoint.h" #include "backend/worksheet/plots/PlotArea.h" #include "backend/worksheet/plots/AbstractPlotPrivate.h" #include "backend/worksheet/Worksheet.h" #include "backend/worksheet/plots/cartesian/Axis.h" #include "backend/worksheet/TextLabel.h" #include "backend/lib/XmlStreamReader.h" #include "backend/lib/commandtemplates.h" #include "backend/lib/macros.h" #include "backend/lib/trace.h" #include "kdefrontend/spreadsheet/PlotDataDialog.h" //for PlotDataDialog::AnalysisAction. TODO: find a better place for this enum. #include "kdefrontend/ThemeHandler.h" #include "kdefrontend/widgets/ThemesWidget.h" #include #include #include #include #include #include #include #include #include #include #include /** * \class CartesianPlot * \brief A xy-plot. * * */ CartesianPlot::CartesianPlot(const QString &name):AbstractPlot(name, new CartesianPlotPrivate(this)), m_legend(0), m_zoomFactor(1.2), m_menusInitialized(false), addNewMenu(nullptr), zoomMenu(nullptr), dataAnalysisMenu(nullptr), themeMenu(nullptr) { init(); } CartesianPlot::CartesianPlot(const QString &name, CartesianPlotPrivate *dd):AbstractPlot(name, dd), m_legend(0), m_zoomFactor(1.2), addNewMenu(nullptr), zoomMenu(nullptr), dataAnalysisMenu(nullptr), themeMenu(nullptr) { init(); } CartesianPlot::~CartesianPlot() { if (m_menusInitialized) { delete addNewMenu; delete zoomMenu; delete themeMenu; } delete m_coordinateSystem; //don't need to delete objects added with addChild() //no need to delete the d-pointer here - it inherits from QGraphicsItem //and is deleted during the cleanup in QGraphicsScene } /*! initializes all member variables of \c CartesianPlot */ void CartesianPlot::init() { Q_D(CartesianPlot); d->cSystem = new CartesianCoordinateSystem(this); m_coordinateSystem = d->cSystem; d->rangeType = CartesianPlot::RangeFree; d->rangeLastValues = 1000; d->rangeFirstValues = 1000; d->autoScaleX = true; d->autoScaleY = true; d->xScale = ScaleLinear; d->yScale = ScaleLinear; d->xRangeBreakingEnabled = false; d->yRangeBreakingEnabled = false; //the following factor determines the size of the offset between the min/max points of the curves //and the coordinate system ranges, when doing auto scaling //Factor 1 corresponds to the exact match - min/max values of the curves correspond to the start/end values of the ranges. d->autoScaleOffsetFactor = 0.05; //TODO: make this factor optional. //Provide in the UI the possibility to choose between "exact" or 0% offset, 2%, 5% and 10% for the auto fit option m_plotArea = new PlotArea(name() + " plot area"); addChildFast(m_plotArea); //offset between the plot area and the area defining the coordinate system, in scene units. d->horizontalPadding = Worksheet::convertToSceneUnits(1.5, Worksheet::Centimeter); d->verticalPadding = Worksheet::convertToSceneUnits(1.5, Worksheet::Centimeter); connect(this, SIGNAL(aspectAdded(const AbstractAspect*)), this, SLOT(childAdded(const AbstractAspect*))); connect(this, SIGNAL(aspectRemoved(const AbstractAspect*,const AbstractAspect*,const AbstractAspect*)), this, SLOT(childRemoved(const AbstractAspect*,const AbstractAspect*,const AbstractAspect*))); graphicsItem()->setFlag(QGraphicsItem::ItemIsMovable, true); graphicsItem()->setFlag(QGraphicsItem::ItemClipsChildrenToShape, true); graphicsItem()->setFlag(QGraphicsItem::ItemIsSelectable, true); graphicsItem()->setFlag(QGraphicsItem::ItemSendsGeometryChanges, true); graphicsItem()->setFlag(QGraphicsItem::ItemIsFocusable, true); } /*! initializes all children of \c CartesianPlot and setups a default plot of type \c type with a plot title. */ void CartesianPlot::initDefault(Type type) { Q_D(CartesianPlot); switch (type) { case FourAxes: { d->xMin = 0; d->xMax = 1; d->yMin = 0; d->yMax = 1; //Axes Axis* axis = new Axis("x axis 1", this, Axis::AxisHorizontal); axis->setSuppressRetransform(true); addChild(axis); axis->setPosition(Axis::AxisBottom); axis->setStart(0); axis->setEnd(1); axis->setMajorTicksDirection(Axis::ticksIn); axis->setMajorTicksNumber(6); axis->setMinorTicksDirection(Axis::ticksIn); axis->setMinorTicksNumber(1); QPen pen = axis->majorGridPen(); pen.setStyle(Qt::SolidLine); axis->setMajorGridPen(pen); pen = axis->minorGridPen(); pen.setStyle(Qt::DotLine); axis->setMinorGridPen(pen); axis->setSuppressRetransform(false); axis = new Axis("x axis 2", this, Axis::AxisHorizontal); axis->setSuppressRetransform(true); addChild(axis); axis->setPosition(Axis::AxisTop); axis->setStart(0); axis->setEnd(1); axis->setMajorTicksDirection(Axis::ticksIn); axis->setMajorTicksNumber(6); axis->setMinorTicksDirection(Axis::ticksIn); axis->setMinorTicksNumber(1); axis->setLabelsPosition(Axis::NoLabels); axis->title()->setText(QString()); axis->setSuppressRetransform(false); axis = new Axis("y axis 1", this, Axis::AxisVertical); axis->setSuppressRetransform(true); addChild(axis); axis->setPosition(Axis::AxisLeft); axis->setStart(0); axis->setEnd(1); axis->setMajorTicksDirection(Axis::ticksIn); axis->setMajorTicksNumber(6); axis->setMinorTicksDirection(Axis::ticksIn); axis->setMinorTicksNumber(1); pen = axis->majorGridPen(); pen.setStyle(Qt::SolidLine); axis->setMajorGridPen(pen); pen = axis->minorGridPen(); pen.setStyle(Qt::DotLine); axis->setMinorGridPen(pen); axis->setSuppressRetransform(false); axis = new Axis("y axis 2", this, Axis::AxisVertical); axis->setSuppressRetransform(true); addChild(axis); axis->setPosition(Axis::AxisRight); axis->setStart(0); axis->setEnd(1); axis->setOffset(1); axis->setMajorTicksDirection(Axis::ticksIn); axis->setMajorTicksNumber(6); axis->setMinorTicksDirection(Axis::ticksIn); axis->setMinorTicksNumber(1); axis->setLabelsPosition(Axis::NoLabels); axis->title()->setText(QString()); axis->setSuppressRetransform(false); break; } case TwoAxes: { d->xMin = 0; d->xMax = 1; d->yMin = 0; d->yMax = 1; Axis* axis = new Axis("x axis 1", this, Axis::AxisHorizontal); axis->setSuppressRetransform(true); addChild(axis); axis->setPosition(Axis::AxisBottom); axis->setStart(0); axis->setEnd(1); axis->setMajorTicksDirection(Axis::ticksBoth); axis->setMajorTicksNumber(6); axis->setMinorTicksDirection(Axis::ticksBoth); axis->setMinorTicksNumber(1); axis->setArrowType(Axis::FilledArrowSmall); axis->setSuppressRetransform(false); axis = new Axis("y axis 1", this, Axis::AxisVertical); axis->setSuppressRetransform(true); addChild(axis); axis->setPosition(Axis::AxisLeft); axis->setStart(0); axis->setEnd(1); axis->setMajorTicksDirection(Axis::ticksBoth); axis->setMajorTicksNumber(6); axis->setMinorTicksDirection(Axis::ticksBoth); axis->setMinorTicksNumber(1); axis->setArrowType(Axis::FilledArrowSmall); axis->setSuppressRetransform(false); break; } case TwoAxesCentered: { d->xMin = -0.5; d->xMax = 0.5; d->yMin = -0.5; d->yMax = 0.5; d->horizontalPadding = Worksheet::convertToSceneUnits(1.0, Worksheet::Centimeter); d->verticalPadding = Worksheet::convertToSceneUnits(1.0, Worksheet::Centimeter); QPen pen = m_plotArea->borderPen(); pen.setStyle(Qt::NoPen); m_plotArea->setBorderPen(pen); Axis* axis = new Axis("x axis 1", this, Axis::AxisHorizontal); axis->setSuppressRetransform(true); addChild(axis); axis->setPosition(Axis::AxisCentered); axis->setStart(-0.5); axis->setEnd(0.5); axis->setMajorTicksDirection(Axis::ticksBoth); axis->setMajorTicksNumber(6); axis->setMinorTicksDirection(Axis::ticksBoth); axis->setMinorTicksNumber(1); axis->setArrowType(Axis::FilledArrowSmall); axis->title()->setText(QString()); axis->setSuppressRetransform(false); axis = new Axis("y axis 1", this, Axis::AxisVertical); axis->setSuppressRetransform(true); addChild(axis); axis->setPosition(Axis::AxisCentered); axis->setStart(-0.5); axis->setEnd(0.5); axis->setMajorTicksDirection(Axis::ticksBoth); axis->setMajorTicksNumber(6); axis->setMinorTicksDirection(Axis::ticksBoth); axis->setMinorTicksNumber(1); axis->setArrowType(Axis::FilledArrowSmall); axis->title()->setText(QString()); axis->setSuppressRetransform(false); break; } case TwoAxesCenteredZero: { d->xMin = -0.5; d->xMax = 0.5; d->yMin = -0.5; d->yMax = 0.5; d->horizontalPadding = Worksheet::convertToSceneUnits(1.0, Worksheet::Centimeter); d->verticalPadding = Worksheet::convertToSceneUnits(1.0, Worksheet::Centimeter); QPen pen = m_plotArea->borderPen(); pen.setStyle(Qt::NoPen); m_plotArea->setBorderPen(pen); Axis* axis = new Axis("x axis 1", this, Axis::AxisHorizontal); axis->setSuppressRetransform(true); addChild(axis); axis->setPosition(Axis::AxisCustom); axis->setOffset(0); axis->setStart(-0.5); axis->setEnd(0.5); axis->setMajorTicksDirection(Axis::ticksBoth); axis->setMajorTicksNumber(6); axis->setMinorTicksDirection(Axis::ticksBoth); axis->setMinorTicksNumber(1); axis->setArrowType(Axis::FilledArrowSmall); axis->title()->setText(QString()); axis->setSuppressRetransform(false); axis = new Axis("y axis 1", this, Axis::AxisVertical); axis->setSuppressRetransform(true); addChild(axis); axis->setPosition(Axis::AxisCustom); axis->setOffset(0); axis->setStart(-0.5); axis->setEnd(0.5); axis->setMajorTicksDirection(Axis::ticksBoth); axis->setMajorTicksNumber(6); axis->setMinorTicksDirection(Axis::ticksBoth); axis->setMinorTicksNumber(1); axis->setArrowType(Axis::FilledArrowSmall); axis->title()->setText(QString()); axis->setSuppressRetransform(false); break; } } d->xMinPrev = d->xMin; d->xMaxPrev = d->xMax; d->yMinPrev = d->yMin; d->yMaxPrev = d->yMax; //Plot title m_title = new TextLabel(this->name(), TextLabel::PlotTitle); addChild(m_title); m_title->setHidden(true); m_title->setParentGraphicsItem(m_plotArea->graphicsItem()); //Geometry, specify the plot rect in scene coordinates. //TODO: Use default settings for left, top, width, height and for min/max for the coordinate system float x = Worksheet::convertToSceneUnits(2, Worksheet::Centimeter); float y = Worksheet::convertToSceneUnits(2, Worksheet::Centimeter); float w = Worksheet::convertToSceneUnits(10, Worksheet::Centimeter); float h = Worksheet::convertToSceneUnits(10, Worksheet::Centimeter); //all plot children are initialized -> set the geometry of the plot in scene coordinates. d->rect = QRectF(x,y,w,h); } void CartesianPlot::initActions() { //"add new" actions addCurveAction = new QAction(QIcon::fromTheme("labplot-xy-curve"), i18n("xy-curve"), this); addHistogramPlot = new QAction(QIcon::fromTheme("labplot-xy-fourier_filter-curve"), i18n("Histogram"), this); addEquationCurveAction = new QAction(QIcon::fromTheme("labplot-xy-equation-curve"), i18n("xy-curve from a mathematical equation"), this); // no icons yet addDataReductionCurveAction = new QAction(i18n("xy-curve from a data reduction"), this); addDifferentiationCurveAction = new QAction(i18n("xy-curve from a differentiation"), this); addIntegrationCurveAction = new QAction(i18n("xy-curve from an integration"), this); addInterpolationCurveAction = new QAction(i18n("xy-curve from an interpolation"), this); addSmoothCurveAction = new QAction(i18n("xy-curve from a smooth"), this); addFitCurveAction = new QAction(QIcon::fromTheme("labplot-xy-fit-curve"), i18n("xy-curve from a fit to data"), this); addFourierFilterCurveAction = new QAction(i18n("xy-curve from a Fourier filter"), this); addFourierTransformCurveAction = new QAction(i18n("xy-curve from a Fourier transform"), this); // addInterpolationCurveAction = new QAction(QIcon::fromTheme("labplot-xy-interpolation-curve"), i18n("xy-curve from an interpolation"), this); // addSmoothCurveAction = new QAction(QIcon::fromTheme("labplot-xy-smooth-curve"), i18n("xy-curve from a smooth"), this); // addFourierFilterCurveAction = new QAction(QIcon::fromTheme("labplot-xy-fourier_filter-curve"), i18n("xy-curve from a Fourier filter"), this); // addFourierTransformCurveAction = new QAction(QIcon::fromTheme("labplot-xy-fourier_transform-curve"), i18n("xy-curve from a Fourier transform"), this); addLegendAction = new QAction(QIcon::fromTheme("text-field"), i18n("legend"), this); if (children().size()>0) addLegendAction->setEnabled(false); //only one legend is allowed -> disable the action addHorizontalAxisAction = new QAction(QIcon::fromTheme("labplot-axis-horizontal"), i18n("horizontal axis"), this); addVerticalAxisAction = new QAction(QIcon::fromTheme("labplot-axis-vertical"), i18n("vertical axis"), this); addCustomPointAction = new QAction(QIcon::fromTheme("draw-cross"), i18n("custom point"), this); connect(addCurveAction, SIGNAL(triggered()), SLOT(addCurve())); connect(addHistogramPlot,SIGNAL(triggered()), SLOT(addHistogram())); connect(addEquationCurveAction, SIGNAL(triggered()), SLOT(addEquationCurve())); connect(addDataReductionCurveAction, SIGNAL(triggered()), SLOT(addDataReductionCurve())); connect(addDifferentiationCurveAction, SIGNAL(triggered()), SLOT(addDifferentiationCurve())); connect(addIntegrationCurveAction, SIGNAL(triggered()), SLOT(addIntegrationCurve())); connect(addInterpolationCurveAction, SIGNAL(triggered()), SLOT(addInterpolationCurve())); connect(addSmoothCurveAction, SIGNAL(triggered()), SLOT(addSmoothCurve())); connect(addFitCurveAction, SIGNAL(triggered()), SLOT(addFitCurve())); connect(addFourierFilterCurveAction, SIGNAL(triggered()), SLOT(addFourierFilterCurve())); connect(addFourierTransformCurveAction, SIGNAL(triggered()), SLOT(addFourierTransformCurve())); connect(addLegendAction, SIGNAL(triggered()), SLOT(addLegend())); connect(addHorizontalAxisAction, SIGNAL(triggered()), SLOT(addHorizontalAxis())); connect(addVerticalAxisAction, SIGNAL(triggered()), SLOT(addVerticalAxis())); connect(addCustomPointAction, SIGNAL(triggered()), SLOT(addCustomPoint())); //Analysis menu actions addDataOperationAction = new QAction(i18n("Data operation"), this); addDataReductionAction = new QAction(i18n("Reduce data"), this); addDifferentiationAction = new QAction(i18n("Differentiate"), this); addIntegrationAction = new QAction(i18n("Integrate"), this); addInterpolationAction = new QAction(i18n("Interpolate"), this); addSmoothAction = new QAction(i18n("Smooth"), this); QAction* fitAction = new QAction(i18n("Linear"), this); fitAction->setData(PlotDataDialog::FitLinear); addFitAction.append(fitAction); fitAction = new QAction(i18n("Power"), this); fitAction->setData(PlotDataDialog::FitPower); addFitAction.append(fitAction); fitAction = new QAction(i18n("Exponential (degree 1)"), this); fitAction->setData(PlotDataDialog::FitExp1); addFitAction.append(fitAction); fitAction = new QAction(i18n("Exponential (degree 2)"), this); fitAction->setData(PlotDataDialog::FitExp2); addFitAction.append(fitAction); fitAction = new QAction(i18n("Inverse exponential"), this); fitAction->setData(PlotDataDialog::FitInvExp); addFitAction.append(fitAction); fitAction = new QAction(i18n("Gauss"), this); fitAction->setData(PlotDataDialog::FitGauss); addFitAction.append(fitAction); fitAction = new QAction(i18n("Cauchy-Lorentz"), this); fitAction->setData(PlotDataDialog::FitCauchyLorentz); addFitAction.append(fitAction); fitAction = new QAction(i18n("Arc Tangent"), this); fitAction->setData(PlotDataDialog::FitTan); addFitAction.append(fitAction); fitAction = new QAction(i18n("Hyperbolic tangent"), this); fitAction->setData(PlotDataDialog::FitTanh); addFitAction.append(fitAction); fitAction = new QAction(i18n("Error function"), this); fitAction->setData(PlotDataDialog::FitErrFunc); addFitAction.append(fitAction); fitAction = new QAction(i18n("Custom"), this); fitAction->setData(PlotDataDialog::FitCustom); addFitAction.append(fitAction); addFourierFilterAction = new QAction(i18n("Fourier filter"), this); connect(addDataReductionAction, SIGNAL(triggered()), SLOT(addDataReductionCurve())); connect(addDifferentiationAction, SIGNAL(triggered()), SLOT(addDifferentiationCurve())); connect(addIntegrationAction, SIGNAL(triggered()), SLOT(addIntegrationCurve())); connect(addInterpolationAction, SIGNAL(triggered()), SLOT(addInterpolationCurve())); connect(addSmoothAction, SIGNAL(triggered()), SLOT(addSmoothCurve())); for (const auto& action: addFitAction) connect(action, SIGNAL(triggered()), SLOT(addFitCurve())); connect(addFourierFilterAction, SIGNAL(triggered()), SLOT(addFourierFilterCurve())); //zoom/navigate actions scaleAutoAction = new QAction(QIcon::fromTheme("labplot-auto-scale-all"), i18n("auto scale"), this); scaleAutoXAction = new QAction(QIcon::fromTheme("labplot-auto-scale-x"), i18n("auto scale X"), this); scaleAutoYAction = new QAction(QIcon::fromTheme("labplot-auto-scale-y"), i18n("auto scale Y"), this); zoomInAction = new QAction(QIcon::fromTheme("zoom-in"), i18n("zoom in"), this); zoomOutAction = new QAction(QIcon::fromTheme("zoom-out"), i18n("zoom out"), this); zoomInXAction = new QAction(QIcon::fromTheme("labplot-zoom-in-x"), i18n("zoom in X"), this); zoomOutXAction = new QAction(QIcon::fromTheme("labplot-zoom-out-x"), i18n("zoom out X"), this); zoomInYAction = new QAction(QIcon::fromTheme("labplot-zoom-in-y"), i18n("zoom in Y"), this); zoomOutYAction = new QAction(QIcon::fromTheme("labplot-zoom-out-y"), i18n("zoom out Y"), this); shiftLeftXAction = new QAction(QIcon::fromTheme("labplot-shift-left-x"), i18n("shift left X"), this); shiftRightXAction = new QAction(QIcon::fromTheme("labplot-shift-right-x"), i18n("shift right X"), this); shiftUpYAction = new QAction(QIcon::fromTheme("labplot-shift-up-y"), i18n("shift up Y"), this); shiftDownYAction = new QAction(QIcon::fromTheme("labplot-shift-down-y"), i18n("shift down Y"), this); connect(scaleAutoAction, SIGNAL(triggered()), SLOT(scaleAuto())); connect(scaleAutoXAction, SIGNAL(triggered()), SLOT(scaleAutoX())); connect(scaleAutoYAction, SIGNAL(triggered()), SLOT(scaleAutoY())); connect(zoomInAction, SIGNAL(triggered()), SLOT(zoomIn())); connect(zoomOutAction, SIGNAL(triggered()), SLOT(zoomOut())); connect(zoomInXAction, SIGNAL(triggered()), SLOT(zoomInX())); connect(zoomOutXAction, SIGNAL(triggered()), SLOT(zoomOutX())); connect(zoomInYAction, SIGNAL(triggered()), SLOT(zoomInY())); connect(zoomOutYAction, SIGNAL(triggered()), SLOT(zoomOutY())); connect(shiftLeftXAction, SIGNAL(triggered()), SLOT(shiftLeftX())); connect(shiftRightXAction, SIGNAL(triggered()), SLOT(shiftRightX())); connect(shiftUpYAction, SIGNAL(triggered()), SLOT(shiftUpY())); connect(shiftDownYAction, SIGNAL(triggered()), SLOT(shiftDownY())); //visibility action visibilityAction = new QAction(i18n("visible"), this); visibilityAction->setCheckable(true); connect(visibilityAction, SIGNAL(triggered()), this, SLOT(visibilityChanged())); } void CartesianPlot::initMenus() { initActions(); addNewMenu = new QMenu(i18n("Add new")); addNewMenu->addAction(addCurveAction); addNewMenu->addAction(addHistogramPlot); addNewMenu->addAction(addEquationCurveAction); addNewMenu->addSeparator(); addNewMenu->addAction(addDataReductionCurveAction); addNewMenu->addAction(addDifferentiationCurveAction); addNewMenu->addAction(addIntegrationCurveAction); addNewMenu->addAction(addInterpolationCurveAction); addNewMenu->addAction(addSmoothCurveAction); addNewMenu->addAction(addFitCurveAction); addNewMenu->addAction(addFourierFilterCurveAction); addNewMenu->addAction(addFourierTransformCurveAction); addNewMenu->addSeparator(); addNewMenu->addAction(addLegendAction); addNewMenu->addSeparator(); addNewMenu->addAction(addHorizontalAxisAction); addNewMenu->addAction(addVerticalAxisAction); addNewMenu->addSeparator(); addNewMenu->addAction(addCustomPointAction); zoomMenu = new QMenu(i18n("Zoom")); zoomMenu->addAction(scaleAutoAction); zoomMenu->addAction(scaleAutoXAction); zoomMenu->addAction(scaleAutoYAction); zoomMenu->addSeparator(); zoomMenu->addAction(zoomInAction); zoomMenu->addAction(zoomOutAction); zoomMenu->addSeparator(); zoomMenu->addAction(zoomInXAction); zoomMenu->addAction(zoomOutXAction); zoomMenu->addSeparator(); zoomMenu->addAction(zoomInYAction); zoomMenu->addAction(zoomOutYAction); zoomMenu->addSeparator(); zoomMenu->addAction(shiftLeftXAction); zoomMenu->addAction(shiftRightXAction); zoomMenu->addSeparator(); zoomMenu->addAction(shiftUpYAction); zoomMenu->addAction(shiftDownYAction); // Data manipulation menu QMenu* dataManipulationMenu = new QMenu(i18n("Data Manipulation")); dataManipulationMenu->setIcon(QIcon::fromTheme("zoom-draw")); dataManipulationMenu->addAction(addDataOperationAction); dataManipulationMenu->addAction(addDataReductionAction); // Data fit menu QMenu* dataFitMenu = new QMenu(i18n("Fit")); dataFitMenu->setIcon(QIcon::fromTheme("labplot-xy-fit-curve")); dataFitMenu->addAction(addFitAction.at(0)); dataFitMenu->addAction(addFitAction.at(1)); dataFitMenu->addAction(addFitAction.at(2)); dataFitMenu->addAction(addFitAction.at(3)); dataFitMenu->addAction(addFitAction.at(4)); dataFitMenu->addSeparator(); dataFitMenu->addAction(addFitAction.at(5)); dataFitMenu->addAction(addFitAction.at(6)); dataFitMenu->addSeparator(); dataFitMenu->addAction(addFitAction.at(7)); dataFitMenu->addAction(addFitAction.at(8)); dataFitMenu->addAction(addFitAction.at(9)); dataFitMenu->addSeparator(); dataFitMenu->addAction(addFitAction.at(10)); //analysis menu dataAnalysisMenu = new QMenu(i18n("Analysis")); dataAnalysisMenu->insertMenu(0, dataManipulationMenu); dataAnalysisMenu->addSeparator(); dataAnalysisMenu->addAction(addDifferentiationAction); dataAnalysisMenu->addAction(addIntegrationAction); dataAnalysisMenu->addSeparator(); dataAnalysisMenu->addAction(addInterpolationAction); dataAnalysisMenu->addAction(addSmoothAction); dataAnalysisMenu->addAction(addFourierFilterAction); dataAnalysisMenu->addSeparator(); dataAnalysisMenu->addMenu(dataFitMenu); //themes menu themeMenu = new QMenu(i18n("Apply Theme")); ThemesWidget* themeWidget = new ThemesWidget(0); connect(themeWidget, SIGNAL(themeSelected(QString)), this, SLOT(loadTheme(QString))); connect(themeWidget, SIGNAL(themeSelected(QString)), themeMenu, SLOT(close())); QWidgetAction* widgetAction = new QWidgetAction(this); widgetAction->setDefaultWidget(themeWidget); themeMenu->addAction(widgetAction); m_menusInitialized = true; } QMenu* CartesianPlot::createContextMenu() { if (!m_menusInitialized) initMenus(); QMenu* menu = WorksheetElement::createContextMenu(); QAction* firstAction = menu->actions().at(1); visibilityAction->setChecked(isVisible()); menu->insertAction(firstAction, visibilityAction); menu->insertMenu(firstAction, addNewMenu); menu->insertMenu(firstAction, zoomMenu); menu->insertSeparator(firstAction); menu->insertMenu(firstAction, themeMenu); menu->insertSeparator(firstAction); return menu; } QMenu* CartesianPlot::analysisMenu() { if (!m_menusInitialized) initMenus(); return dataAnalysisMenu; } /*! Returns an icon to be used in the project explorer. */ QIcon CartesianPlot::icon() const { return QIcon::fromTheme("office-chart-line"); } QVector CartesianPlot::dependsOn() const { //aspects which the plotted data in the worksheet depends on (spreadsheets and later matrices) QVector aspects; for (const auto* curve : children()) { if (curve->xColumn() && dynamic_cast(curve->xColumn()->parentAspect()) ) aspects << curve->xColumn()->parentAspect(); if (curve->yColumn() && dynamic_cast(curve->yColumn()->parentAspect()) ) aspects << curve->yColumn()->parentAspect(); } return aspects; } void CartesianPlot::navigate(CartesianPlot::NavigationOperation op) { if (op == ScaleAuto) scaleAuto(); else if (op == ScaleAutoX) scaleAutoX(); else if (op == ScaleAutoY) scaleAutoY(); else if (op == ZoomIn) zoomIn(); else if (op == ZoomOut) zoomOut(); else if (op == ZoomInX) zoomInX(); else if (op == ZoomOutX) zoomOutX(); else if (op == ZoomInY) zoomInY(); else if (op == ZoomOutY) zoomOutY(); else if (op == ShiftLeftX) shiftLeftX(); else if (op == ShiftRightX) shiftRightX(); else if (op == ShiftUpY) shiftUpY(); else if (op == ShiftDownY) shiftDownY(); } void CartesianPlot::setSuppressDataChangedSignal(bool value) { Q_D(CartesianPlot); d->suppressRetransform = value; } void CartesianPlot::processDropEvent(QDropEvent* event) { PERFTRACE("CartesianPlot::processDropEvent"); const QMimeData* mimeData = event->mimeData(); if (!mimeData) return; //deserialize the mime data to the vector of aspect pointers QByteArray data = mimeData->data(QLatin1String("labplot-dnd")); QVector vec; QDataStream stream(&data, QIODevice::ReadOnly); stream >> vec; QVector columns; for (auto i : vec) { AbstractAspect* aspect = (AbstractAspect*)i; AbstractColumn* column = dynamic_cast(aspect); if (column) columns << column; } //return if there are no columns being dropped. //TODO: extend this later when we allow to drag&drop plots, etc. if (columns.isEmpty()) return; //determine the first column with "x plot designation" as the x-data column for all curves to be created const AbstractColumn* xColumn = nullptr; for (const auto* column : columns) { if (column->plotDesignation() == AbstractColumn::X) { xColumn = column; break; } } //if no column with "x plot designation" is available, use the x-data column of the first curve in the plot, if (xColumn == nullptr) { QVector curves = children(); if (!curves.isEmpty()) xColumn = curves.at(0)->xColumn(); } //use the first dropped column if no column with "x plot designation" nor curves are available if (xColumn == nullptr) xColumn = columns.at(0); //create curves bool curvesAdded = false; for (const auto* column : columns) { if (column == xColumn) continue; XYCurve* curve = new XYCurve(column->name()); curve->suppressRetransform(true); //suppress retransform, all curved will be recalculated at the end curve->setXColumn(xColumn); curve->setYColumn(column); addChild(curve); curve->suppressRetransform(false); curvesAdded = true; } if (curvesAdded) dataChanged(); } //############################################################################## //################################ getter methods ############################ //############################################################################## BASIC_SHARED_D_READER_IMPL(CartesianPlot, CartesianPlot::RangeType, rangeType, rangeType) BASIC_SHARED_D_READER_IMPL(CartesianPlot, int, rangeLastValues, rangeLastValues) BASIC_SHARED_D_READER_IMPL(CartesianPlot, int, rangeFirstValues, rangeFirstValues) BASIC_SHARED_D_READER_IMPL(CartesianPlot, bool, autoScaleX, autoScaleX) BASIC_SHARED_D_READER_IMPL(CartesianPlot, double, xMin, xMin) BASIC_SHARED_D_READER_IMPL(CartesianPlot, double, xMax, xMax) BASIC_SHARED_D_READER_IMPL(CartesianPlot, CartesianPlot::Scale, xScale, xScale) BASIC_SHARED_D_READER_IMPL(CartesianPlot, bool, xRangeBreakingEnabled, xRangeBreakingEnabled) CLASS_SHARED_D_READER_IMPL(CartesianPlot, CartesianPlot::RangeBreaks, xRangeBreaks, xRangeBreaks) BASIC_SHARED_D_READER_IMPL(CartesianPlot, bool, autoScaleY, autoScaleY) BASIC_SHARED_D_READER_IMPL(CartesianPlot, double, yMin, yMin) BASIC_SHARED_D_READER_IMPL(CartesianPlot, double, yMax, yMax) BASIC_SHARED_D_READER_IMPL(CartesianPlot, CartesianPlot::Scale, yScale, yScale) BASIC_SHARED_D_READER_IMPL(CartesianPlot, bool, yRangeBreakingEnabled, yRangeBreakingEnabled) CLASS_SHARED_D_READER_IMPL(CartesianPlot, CartesianPlot::RangeBreaks, yRangeBreaks, yRangeBreaks) CLASS_SHARED_D_READER_IMPL(CartesianPlot, QString, theme, theme) /*! return the actual bounding rectangular of the plot (plot's rectangular minus padding) in plot's coordinates */ //TODO: return here a private variable only, update this variable on rect and padding changes. QRectF CartesianPlot::plotRect() { Q_D(const CartesianPlot); QRectF rect = d->mapRectFromScene(d->rect); rect.setX(rect.x() + d->horizontalPadding); rect.setY(rect.y() + d->verticalPadding); rect.setWidth(rect.width() - d->horizontalPadding); rect.setHeight(rect.height()-d->verticalPadding); return rect; } CartesianPlot::MouseMode CartesianPlot::mouseMode() const { Q_D(const CartesianPlot); return d->mouseMode; } //############################################################################## //###################### setter methods and undo commands #################### //############################################################################## /*! set the rectangular, defined in scene coordinates */ class CartesianPlotSetRectCmd : public QUndoCommand { public: CartesianPlotSetRectCmd(CartesianPlotPrivate* private_obj, QRectF rect) : m_private(private_obj), m_rect(rect) { setText(i18n("%1: change geometry rect", m_private->name())); }; - virtual void redo() { + void redo() override { QRectF tmp = m_private->rect; const double horizontalRatio = m_rect.width() / m_private->rect.width(); const double verticalRatio = m_rect.height() / m_private->rect.height(); m_private->q->handleResize(horizontalRatio, verticalRatio, false); m_private->rect = m_rect; m_rect = tmp; m_private->retransform(); emit m_private->q->rectChanged(m_private->rect); }; - virtual void undo() { + void undo() override { redo(); } private: CartesianPlotPrivate* m_private; QRectF m_rect; }; void CartesianPlot::setRect(const QRectF& rect) { Q_D(CartesianPlot); if (rect != d->rect) exec(new CartesianPlotSetRectCmd(d, rect)); } STD_SETTER_CMD_IMPL_F_S(CartesianPlot, SetRangeType, CartesianPlot::RangeType, rangeType, rangeChanged); void CartesianPlot::setRangeType(RangeType type) { Q_D(CartesianPlot); if (type != d->rangeType) exec(new CartesianPlotSetRangeTypeCmd(d, type, i18n("%1: set range type"))); } STD_SETTER_CMD_IMPL_F_S(CartesianPlot, SetRangeLastValues, int, rangeLastValues, rangeChanged); void CartesianPlot::setRangeLastValues(int values) { Q_D(CartesianPlot); if (values != d->rangeLastValues) exec(new CartesianPlotSetRangeLastValuesCmd(d, values, i18n("%1: set range"))); } STD_SETTER_CMD_IMPL_F_S(CartesianPlot, SetRangeFirstValues, int, rangeFirstValues, rangeChanged); void CartesianPlot::setRangeFirstValues(int values) { Q_D(CartesianPlot); if (values != d->rangeFirstValues) exec(new CartesianPlotSetRangeFirstValuesCmd(d, values, i18n("%1: set range"))); } class CartesianPlotSetAutoScaleXCmd : public QUndoCommand { public: CartesianPlotSetAutoScaleXCmd(CartesianPlotPrivate* private_obj, bool autoScale) : m_private(private_obj), m_autoScale(autoScale), m_minOld(0.0), m_maxOld(0.0) { setText(i18n("%1: change x-range auto scaling", m_private->name())); }; - virtual void redo() { + void redo() override { m_autoScaleOld = m_private->autoScaleX; if (m_autoScale) { m_minOld = m_private->xMin; m_maxOld = m_private->xMax; m_private->q->scaleAutoX(); } m_private->autoScaleX = m_autoScale; emit m_private->q->xAutoScaleChanged(m_autoScale); }; - virtual void undo() { + void undo() override { if (!m_autoScaleOld) { m_private->xMin = m_minOld; m_private->xMax = m_maxOld; m_private->retransformScales(); } m_private->autoScaleX = m_autoScaleOld; emit m_private->q->xAutoScaleChanged(m_autoScaleOld); } private: CartesianPlotPrivate* m_private; bool m_autoScale; bool m_autoScaleOld; double m_minOld; double m_maxOld; }; void CartesianPlot::setAutoScaleX(bool autoScaleX) { Q_D(CartesianPlot); if (autoScaleX != d->autoScaleX) exec(new CartesianPlotSetAutoScaleXCmd(d, autoScaleX)); } STD_SETTER_CMD_IMPL_F_S(CartesianPlot, SetXMin, double, xMin, retransformScales) void CartesianPlot::setXMin(double xMin) { Q_D(CartesianPlot); if (xMin != d->xMin) exec(new CartesianPlotSetXMinCmd(d, xMin, i18n("%1: set min x"))); } STD_SETTER_CMD_IMPL_F_S(CartesianPlot, SetXMax, double, xMax, retransformScales) void CartesianPlot::setXMax(double xMax) { Q_D(CartesianPlot); if (xMax != d->xMax) exec(new CartesianPlotSetXMaxCmd(d, xMax, i18n("%1: set max x"))); } STD_SETTER_CMD_IMPL_F_S(CartesianPlot, SetXScale, CartesianPlot::Scale, xScale, retransformScales) void CartesianPlot::setXScale(Scale scale) { Q_D(CartesianPlot); if (scale != d->xScale) exec(new CartesianPlotSetXScaleCmd(d, scale, i18n("%1: set x scale"))); } STD_SETTER_CMD_IMPL_F_S(CartesianPlot, SetXRangeBreakingEnabled, bool, xRangeBreakingEnabled, retransformScales) void CartesianPlot::setXRangeBreakingEnabled(bool enabled) { Q_D(CartesianPlot); if (enabled != d->xRangeBreakingEnabled) exec(new CartesianPlotSetXRangeBreakingEnabledCmd(d, enabled, i18n("%1: x-range breaking enabled"))); } STD_SETTER_CMD_IMPL_F_S(CartesianPlot, SetXRangeBreaks, CartesianPlot::RangeBreaks, xRangeBreaks, retransformScales) void CartesianPlot::setXRangeBreaks(const RangeBreaks& breakings) { Q_D(CartesianPlot); exec(new CartesianPlotSetXRangeBreaksCmd(d, breakings, i18n("%1: x-range breaks changed"))); } class CartesianPlotSetAutoScaleYCmd : public QUndoCommand { public: CartesianPlotSetAutoScaleYCmd(CartesianPlotPrivate* private_obj, bool autoScale) : m_private(private_obj), m_autoScale(autoScale), m_minOld(0.0), m_maxOld(0.0) { setText(i18n("%1: change y-range auto scaling", m_private->name())); }; - virtual void redo() { + void redo() override { m_autoScaleOld = m_private->autoScaleY; if (m_autoScale) { m_minOld = m_private->yMin; m_maxOld = m_private->yMax; m_private->q->scaleAutoY(); } m_private->autoScaleY = m_autoScale; emit m_private->q->yAutoScaleChanged(m_autoScale); }; - virtual void undo() { + void undo() override { if (!m_autoScaleOld) { m_private->yMin = m_minOld; m_private->yMax = m_maxOld; m_private->retransformScales(); } m_private->autoScaleY = m_autoScaleOld; emit m_private->q->yAutoScaleChanged(m_autoScaleOld); } private: CartesianPlotPrivate* m_private; bool m_autoScale; bool m_autoScaleOld; double m_minOld; double m_maxOld; }; void CartesianPlot::setAutoScaleY(bool autoScaleY) { Q_D(CartesianPlot); if (autoScaleY != d->autoScaleY) exec(new CartesianPlotSetAutoScaleYCmd(d, autoScaleY)); } STD_SETTER_CMD_IMPL_F_S(CartesianPlot, SetYMin, double, yMin, retransformScales) void CartesianPlot::setYMin(double yMin) { Q_D(CartesianPlot); if (yMin != d->yMin) exec(new CartesianPlotSetYMinCmd(d, yMin, i18n("%1: set min y"))); } STD_SETTER_CMD_IMPL_F_S(CartesianPlot, SetYMax, double, yMax, retransformScales) void CartesianPlot::setYMax(double yMax) { Q_D(CartesianPlot); if (yMax != d->yMax) exec(new CartesianPlotSetYMaxCmd(d, yMax, i18n("%1: set max y"))); } STD_SETTER_CMD_IMPL_F_S(CartesianPlot, SetYScale, CartesianPlot::Scale, yScale, retransformScales) void CartesianPlot::setYScale(Scale scale) { Q_D(CartesianPlot); if (scale != d->yScale) exec(new CartesianPlotSetYScaleCmd(d, scale, i18n("%1: set y scale"))); } STD_SETTER_CMD_IMPL_F_S(CartesianPlot, SetYRangeBreakingEnabled, bool, yRangeBreakingEnabled, retransformScales) void CartesianPlot::setYRangeBreakingEnabled(bool enabled) { Q_D(CartesianPlot); if (enabled != d->yRangeBreakingEnabled) exec(new CartesianPlotSetYRangeBreakingEnabledCmd(d, enabled, i18n("%1: y-range breaking enabled"))); } STD_SETTER_CMD_IMPL_F_S(CartesianPlot, SetYRangeBreaks, CartesianPlot::RangeBreaks, yRangeBreaks, retransformScales) void CartesianPlot::setYRangeBreaks(const RangeBreaks& breaks) { Q_D(CartesianPlot); exec(new CartesianPlotSetYRangeBreaksCmd(d, breaks, i18n("%1: y-range breaks changed"))); } STD_SETTER_CMD_IMPL_S(CartesianPlot, SetTheme, QString, theme) void CartesianPlot::setTheme(const QString& theme) { Q_D(CartesianPlot); if (theme != d->theme) { if (!theme.isEmpty()) { beginMacro( i18n("%1: load theme %2", name(), theme) ); exec(new CartesianPlotSetThemeCmd(d, theme, i18n("%1: set theme"))); loadTheme(theme); endMacro(); } else exec(new CartesianPlotSetThemeCmd(d, theme, i18n("%1: disable theming"))); } } //################################################################ //########################## Slots ############################### //################################################################ void CartesianPlot::addHorizontalAxis() { Axis* axis = new Axis("x-axis", this, Axis::AxisHorizontal); if (axis->autoScale()) { axis->setUndoAware(false); axis->setStart(xMin()); axis->setEnd(xMax()); axis->setUndoAware(true); } addChild(axis); } void CartesianPlot::addVerticalAxis() { Axis* axis = new Axis("y-axis", this, Axis::AxisVertical); if (axis->autoScale()) { axis->setUndoAware(false); axis->setStart(yMin()); axis->setEnd(yMax()); axis->setUndoAware(true); } addChild(axis); } void CartesianPlot::addCurve() { addChild(new XYCurve("xy-curve")); } void CartesianPlot::addEquationCurve() { addChild(new XYEquationCurve("f(x)")); } void CartesianPlot::addHistogram() { addChild(new Histogram("Histogram")); } /*! * returns the first selected XYCurve in the plot */ const XYCurve* CartesianPlot::currentCurve() const { for (const auto* curve: this->children()) { if (curve->graphicsItem()->isSelected()) return curve; } return 0; } void CartesianPlot::addDataReductionCurve() { XYDataReductionCurve* curve = new XYDataReductionCurve("Data reduction"); const XYCurve* curCurve = currentCurve(); if (curCurve) { beginMacro( i18n("%1: reduce '%2'", name(), curCurve->name()) ); curve->setName( i18n("Reduction of '%1'", curCurve->name()) ); curve->setDataSourceType(XYCurve::DataSourceCurve); curve->setDataSourceCurve(curCurve); this->addChild(curve); curve->recalculate(); emit curve->dataReductionDataChanged(curve->dataReductionData()); } else { beginMacro(i18n("%1: add data reduction curve", name())); this->addChild(curve); } endMacro(); } void CartesianPlot::addDifferentiationCurve() { XYDifferentiationCurve* curve = new XYDifferentiationCurve("Differentiation"); const XYCurve* curCurve = currentCurve(); if (curCurve) { beginMacro( i18n("%1: differentiate '%2'", name(), curCurve->name()) ); curve->setName( i18n("Derivative of '%1'", curCurve->name()) ); curve->setDataSourceType(XYCurve::DataSourceCurve); curve->setDataSourceCurve(curCurve); this->addChild(curve); curve->recalculate(); emit curve->differentiationDataChanged(curve->differentiationData()); } else { beginMacro(i18n("%1: add differentiation curve", name())); this->addChild(curve); } endMacro(); } void CartesianPlot::addIntegrationCurve() { XYIntegrationCurve* curve = new XYIntegrationCurve("Integration"); const XYCurve* curCurve = currentCurve(); if (curCurve) { beginMacro( i18n("%1: integrate '%2'", name(), curCurve->name()) ); curve->setName( i18n("Integral of '%1'", curCurve->name()) ); curve->setDataSourceType(XYCurve::DataSourceCurve); curve->setDataSourceCurve(curCurve); this->addChild(curve); curve->recalculate(); emit curve->integrationDataChanged(curve->integrationData()); } else { beginMacro(i18n("%1: add differentiation curve", name())); this->addChild(curve); } endMacro(); } void CartesianPlot::addInterpolationCurve() { XYInterpolationCurve* curve = new XYInterpolationCurve("Interpolation"); const XYCurve* curCurve = currentCurve(); if (curCurve) { beginMacro( i18n("%1: interpolate '%2'", name(), curCurve->name()) ); curve->setName( i18n("Interpolation of '%1'", curCurve->name()) ); curve->setDataSourceType(XYCurve::DataSourceCurve); curve->setDataSourceCurve(curCurve); curve->recalculate(); this->addChild(curve); emit curve->interpolationDataChanged(curve->interpolationData()); } else { beginMacro(i18n("%1: add interpolation curve", name())); this->addChild(curve); } endMacro(); } void CartesianPlot::addSmoothCurve() { XYSmoothCurve* curve = new XYSmoothCurve("Smooth"); const XYCurve* curCurve = currentCurve(); if (curCurve) { beginMacro( i18n("%1: smooth '%2'", name(), curCurve->name()) ); curve->setName( i18n("Smoothing of '%1'", curCurve->name()) ); curve->setDataSourceType(XYCurve::DataSourceCurve); curve->setDataSourceCurve(curCurve); this->addChild(curve); curve->recalculate(); emit curve->smoothDataChanged(curve->smoothData()); } else { beginMacro(i18n("%1: add smoothing curve", name())); this->addChild(curve); } endMacro(); } void CartesianPlot::addFitCurve() { XYFitCurve* curve = new XYFitCurve("fit"); const XYCurve* curCurve = currentCurve(); if (curCurve) { beginMacro( i18n("%1: fit to '%2'", name(), curCurve->name()) ); curve->setName( i18n("Fit to '%1'", curCurve->name()) ); curve->setDataSourceType(XYCurve::DataSourceCurve); curve->setDataSourceCurve(curCurve); //set the fit model category and type const QAction* action = qobject_cast(QObject::sender()); PlotDataDialog::AnalysisAction type = (PlotDataDialog::AnalysisAction)action->data().toInt(); curve->initFitData(type); this->addChild(curve); curve->recalculate(); emit curve->fitDataChanged(curve->fitData()); } else { beginMacro(i18n("%1: add fit curve", name())); this->addChild(curve); } endMacro(); } void CartesianPlot::addFourierFilterCurve() { XYFourierFilterCurve* curve = new XYFourierFilterCurve("Fourier filter"); const XYCurve* curCurve = currentCurve(); if (curCurve) { beginMacro( i18n("%1: Fourier filtering of '%2'", name(), curCurve->name()) ); curve->setName( i18n("Fourier filtering of '%1'", curCurve->name()) ); curve->setDataSourceType(XYCurve::DataSourceCurve); curve->setDataSourceCurve(curCurve); this->addChild(curve); } else { beginMacro(i18n("%1: add Fourier filter curve", name())); this->addChild(curve); } endMacro(); } void CartesianPlot::addFourierTransformCurve() { XYFourierTransformCurve* curve = new XYFourierTransformCurve("Fourier transform"); this->addChild(curve); } void CartesianPlot::addLegend() { //don't do anything if there's already a legend if (m_legend) return; m_legend = new CartesianPlotLegend(this, "legend"); this->addChild(m_legend); m_legend->retransform(); //only one legend is allowed -> disable the action if (m_menusInitialized) addLegendAction->setEnabled(false); } void CartesianPlot::addCustomPoint() { CustomPoint* point = new CustomPoint(this, "custom point"); this->addChild(point); } void CartesianPlot::childAdded(const AbstractAspect* child) { Q_D(CartesianPlot); const XYCurve* curve = qobject_cast(child); if (curve) { connect(curve, SIGNAL(dataChanged()), this, SLOT(dataChanged())); connect(curve, SIGNAL(xDataChanged()), this, SLOT(xDataChanged())); connect(curve, SIGNAL(yDataChanged()), this, SLOT(yDataChanged())); connect(curve, SIGNAL(visibilityChanged(bool)), this, SLOT(curveVisibilityChanged())); //update the legend on changes of the name, line and symbol styles connect(curve, SIGNAL(aspectDescriptionChanged(const AbstractAspect*)), this, SLOT(updateLegend())); connect(curve, SIGNAL(lineTypeChanged(XYCurve::LineType)), this, SLOT(updateLegend())); connect(curve, SIGNAL(linePenChanged(QPen)), this, SLOT(updateLegend())); connect(curve, SIGNAL(lineOpacityChanged(qreal)), this, SLOT(updateLegend())); connect(curve, SIGNAL(symbolsStyleChanged(Symbol::Style)), this, SLOT(updateLegend())); connect(curve, SIGNAL(symbolsSizeChanged(qreal)), this, SLOT(updateLegend())); connect(curve, SIGNAL(symbolsRotationAngleChanged(qreal)), this, SLOT(updateLegend())); connect(curve, SIGNAL(symbolsOpacityChanged(qreal)), this, SLOT(updateLegend())); connect(curve, SIGNAL(symbolsBrushChanged(QBrush)), this, SLOT(updateLegend())); connect(curve, SIGNAL(symbolsPenChanged(QPen)), this, SLOT(updateLegend())); updateLegend(); d->curvesXMinMaxIsDirty = true; d->curvesYMinMaxIsDirty = true; } else { const Histogram* histo = qobject_cast(child); if (histo) { connect(histo, SIGNAL(HistogramdataChanged()), this, SLOT(HistogramdataChanged())); connect(histo, SIGNAL(xHistogramDataChanged()), this, SLOT(xHistogramDataChanged())); connect(histo, SIGNAL(yHistogramDataChanged()), this, SLOT(yHistogramDataChanged())); connect(histo, SIGNAL(visibilityChanged(bool)), this, SLOT(curveVisibilityChanged())); } } //if a theme was selected, apply the theme settings for newly added children, too if (!d->theme.isEmpty() && !isLoading()) { const WorksheetElement* el = dynamic_cast(child); if (el) { KConfig config(ThemeHandler::themeFilePath(d->theme), KConfig::SimpleConfig); const_cast(el)->loadThemeConfig(config); } } } void CartesianPlot::childRemoved(const AbstractAspect* parent, const AbstractAspect* before, const AbstractAspect* child) { Q_UNUSED(parent); Q_UNUSED(before); if (m_legend == child) { if (m_menusInitialized) addLegendAction->setEnabled(true); m_legend = nullptr; } else { const XYCurve* curve = qobject_cast(child); if (curve) updateLegend(); } } void CartesianPlot::updateLegend() { if (m_legend) m_legend->retransform(); } /*! called when in one of the curves the data was changed. Autoscales the coordinate system and the x-axes, when "auto-scale" is active. */ void CartesianPlot::dataChanged() { Q_D(CartesianPlot); d->curvesXMinMaxIsDirty = true; d->curvesYMinMaxIsDirty = true; if (d->autoScaleX && d->autoScaleY) this->scaleAuto(); else if (d->autoScaleX) this->scaleAutoX(); else if (d->autoScaleY) this->scaleAutoY(); else { //free ranges -> rentransform the curve that sent XYCurve* curve = dynamic_cast(QObject::sender()); if (curve) curve->retransform(); else { //no sender available, the function was called in CartesianPlot::dataChanged() (live data source got new data) //-> retransform all available curves since we don't know which curves are affected. //TODO: this logic can be very expensive qDebug()<<"HERE"; for (auto curve : children()) QtConcurrent::run(curve, &XYCurve::retransform); // curve->retransform(); } } } void CartesianPlot::HistogramdataChanged() { Q_D(CartesianPlot); d->curvesXMinMaxIsDirty = true; d->curvesYMinMaxIsDirty = true; if (d->autoScaleX && d->autoScaleY) this->scaleAuto(); else if (d->autoScaleX) this->scaleAutoY(); else if (d->autoScaleY) this->scaleAutoY(); else { Histogram* curve = dynamic_cast(QObject::sender()); if (curve) curve->retransform(); else { //no sender available, the function was called in CartesianPlot::dataChanged() (live data source got new data) //-> retransform all available curves since we don't know which curves are affected. //TODO: this logic can be very expensive for (auto curve : children()) curve->retransform(); } } } /*! called when in one of the curves the x-data was changed. Autoscales the coordinate system and the x-axes, when "auto-scale" is active. */ void CartesianPlot::xDataChanged() { if (project()->isLoading()) return; Q_D(CartesianPlot); if (d->suppressRetransform) return; d->curvesXMinMaxIsDirty = true; if (d->autoScaleX) this->scaleAutoX(); else { XYCurve* curve = dynamic_cast(QObject::sender()); Q_ASSERT(curve); curve->retransform(); } } void CartesianPlot::xHistogramDataChanged() { if (project()->isLoading()) return; Q_D(CartesianPlot); if (d->suppressRetransform) return; d->curvesXMinMaxIsDirty = true; if (d->autoScaleX) this->scaleAutoX(); else { Histogram* curve = dynamic_cast(QObject::sender()); Q_ASSERT(curve); curve->retransform(); } } /*! called when in one of the curves the x-data was changed. Autoscales the coordinate system and the x-axes, when "auto-scale" is active. */ void CartesianPlot::yDataChanged() { if (project()->isLoading()) return; Q_D(CartesianPlot); if (d->suppressRetransform) return; d->curvesYMinMaxIsDirty = true; if (d->autoScaleY) this->scaleAutoY(); else { XYCurve* curve = dynamic_cast(QObject::sender()); Q_ASSERT(curve); curve->retransform(); } } void CartesianPlot::yHistogramDataChanged() { if (project()->isLoading()) return; Q_D(CartesianPlot); if (d->suppressRetransform) return; d->curvesYMinMaxIsDirty = true; if (d->autoScaleY) this->scaleAutoY(); else { Histogram* curve = dynamic_cast(QObject::sender()); Q_ASSERT(curve); curve->retransform(); } } void CartesianPlot::curveVisibilityChanged() { Q_D(CartesianPlot); d->curvesXMinMaxIsDirty = true; d->curvesYMinMaxIsDirty = true; updateLegend(); if (d->autoScaleX && d->autoScaleY) this->scaleAuto(); else if (d->autoScaleX) this->scaleAutoX(); else if (d->autoScaleY) this->scaleAutoY(); } void CartesianPlot::setMouseMode(const MouseMode mouseMode) { Q_D(CartesianPlot); d->mouseMode = mouseMode; d->setHandlesChildEvents(mouseMode != CartesianPlot::SelectionMode); QList items = d->childItems(); if (d->mouseMode == CartesianPlot::SelectionMode) { for (auto* item: items) item->setFlag(QGraphicsItem::ItemStacksBehindParent, false); } else { for (auto* item: items) item->setFlag(QGraphicsItem::ItemStacksBehindParent, true); } //when doing zoom selection, prevent the graphics item from being movable //if it's currently movable (no worksheet layout available) const Worksheet* worksheet = dynamic_cast(parentAspect()); if (worksheet) { if (mouseMode == CartesianPlot::SelectionMode) { if (worksheet->layout() != Worksheet::NoLayout) graphicsItem()->setFlag(QGraphicsItem::ItemIsMovable, false); else graphicsItem()->setFlag(QGraphicsItem::ItemIsMovable, true); } else //zoom m_selection graphicsItem()->setFlag(QGraphicsItem::ItemIsMovable, false); } } void CartesianPlot::scaleAutoX() { Q_D(CartesianPlot); if (d->curvesXMinMaxIsDirty) { int count = 0; switch (d->rangeType) { case CartesianPlot::RangeFree: count = 0; break; case CartesianPlot::RangeLast: count = -d->rangeLastValues; break; case CartesianPlot::RangeFirst: count = d->rangeFirstValues; break; } d->curvesXMin = INFINITY; d->curvesXMax = -INFINITY; //loop over all xy-curves and determine the maximum and minimum x-values for (const auto* curve: this->children()) { if (!curve->isVisible()) continue; if (!curve->xColumn()) continue; const double min = curve->xColumn()->minimum(count); if (min < d->curvesXMin) d->curvesXMin = min; const double max = curve->xColumn()->maximum(count); if (max > d->curvesXMax) d->curvesXMax = max; } //loop over all histograms and determine the maximum and minimum x-values for (const auto* curve: this->children()) { if (!curve->isVisible()) continue; if (!curve->xColumn()) continue; const double min = curve->xColumn()->minimum(count); if (min < d->curvesXMin) d->curvesXMin = min; const double max = curve->xColumn()->maximum(count); if (max > d->curvesXMax) d->curvesXMax = max; } d->curvesXMinMaxIsDirty = false; } bool update = false; if (d->curvesXMin != d->xMin && d->curvesXMin != INFINITY) { d->xMin = d->curvesXMin; update = true; } if (d->curvesXMax != d->xMax && d->curvesXMax != -INFINITY) { d->xMax = d->curvesXMax; update = true; } if (update) { if (d->xMax == d->xMin) { //in case min and max are equal (e.g. if we plot a single point), subtract/add 10% of the value if (d->xMax != 0) { d->xMax = d->xMax*1.1; d->xMin = d->xMin*0.9; } else { d->xMax = 0.1; d->xMin = -0.1; } } else { double offset = (d->xMax - d->xMin)*d->autoScaleOffsetFactor; d->xMin -= offset; d->xMax += offset; } d->retransformScales(); } } void CartesianPlot::scaleAutoY() { Q_D(CartesianPlot); if (d->curvesYMinMaxIsDirty) { int count = 0; switch (d->rangeType) { case CartesianPlot::RangeFree: count = 0; break; case CartesianPlot::RangeLast: count = -d->rangeLastValues; break; case CartesianPlot::RangeFirst: count = d->rangeFirstValues; break; } d->curvesYMin = INFINITY; d->curvesYMax = -INFINITY; //loop over all xy-curves and determine the maximum and minimum y-values for (const auto* curve: this->children()) { if (!curve->isVisible()) continue; if (!curve->yColumn()) continue; const double min = curve->yColumn()->minimum(count); if (min < d->curvesYMin) d->curvesYMin = min; const double max = curve->yColumn()->maximum(count); if (max > d->curvesYMax) d->curvesYMax = max; } //loop over all histograms and determine the maximum y-value for (const auto* curve: this->children()) { if (!curve->isVisible()) continue; if (d->curvesYMin > 0.0) d->curvesYMin = 0.0; if ( curve->getYMaximum() > d->curvesYMax) d->curvesYMax = curve->getYMaximum(); } d->curvesYMinMaxIsDirty = false; } bool update = false; if (d->curvesYMin != d->yMin && d->curvesYMin != INFINITY) { d->yMin = d->curvesYMin; update = true; } if (d->curvesYMax != d->yMax && d->curvesYMax != -INFINITY) { d->yMax = d->curvesYMax; update = true; } if (update) { if (d->yMax == d->yMin) { //in case min and max are equal (e.g. if we plot a single point), subtract/add 10% of the value if (d->yMax != 0) { d->yMax = d->yMax*1.1; d->yMin = d->yMin*0.9; } else { d->yMax = 0.1; d->yMin = -0.1; } } else { double offset = (d->yMax - d->yMin)*d->autoScaleOffsetFactor; d->yMin -= offset; d->yMax += offset; } d->retransformScales(); } } void CartesianPlot::scaleAuto() { DEBUG("CartesianPlot::scaleAuto()"); Q_D(CartesianPlot); int count = 0; switch (d->rangeType) { case CartesianPlot::RangeFree: count = 0; break; case CartesianPlot::RangeLast: count = -d->rangeLastValues; break; case CartesianPlot::RangeFirst: count = d->rangeFirstValues; break; } if (d->curvesXMinMaxIsDirty) { d->curvesXMin = INFINITY; d->curvesXMax = -INFINITY; //loop over all xy-curves and determine the maximum and minimum x-values for (const auto* curve: this->children()) { if (!curve->isVisible()) continue; if (!curve->xColumn()) continue; const double min = curve->xColumn()->minimum(count); if (min < d->curvesXMin) d->curvesXMin = min; double max = curve->xColumn()->maximum(count); if (max > d->curvesXMax) d->curvesXMax = max; } //loop over all histograms and determine the maximum and minimum x-values for (const auto* curve: this->children()) { if (!curve->isVisible()) continue; if (!curve->xColumn()) continue; const double min = curve->xColumn()->minimum(count); if (min < d->curvesXMin) d->curvesXMin = min; const double max = curve->xColumn()->maximum(count); if (max > d->curvesXMax) d->curvesXMax = max; } d->curvesXMinMaxIsDirty = false; } if (d->curvesYMinMaxIsDirty) { d->curvesYMin = INFINITY; d->curvesYMax = -INFINITY; //loop over all xy-curves and determine the maximum and minimum y-values for (const auto* curve: this->children()) { if (!curve->isVisible()) continue; if (!curve->yColumn()) continue; const double min = curve->yColumn()->minimum(count); if (min < d->curvesYMin) d->curvesYMin = min; const double max = curve->yColumn()->maximum(count); if (max > d->curvesYMax) d->curvesYMax = max; } //loop over all histograms and determine the maximum y-value for (const auto* curve: this->children()) { if (!curve->isVisible()) continue; if (d->curvesYMin > 0.0) d->curvesYMin = 0.0; const double max = curve->getYMaximum(); if (max > d->curvesYMax) d->curvesYMax = max; } } bool updateX = false; bool updateY = false; if (d->curvesXMin != d->xMin && d->curvesXMin != INFINITY) { d->xMin = d->curvesXMin; updateX = true; } if (d->curvesXMax != d->xMax && d->curvesXMax != -INFINITY) { d->xMax = d->curvesXMax; updateX = true; } if (d->curvesYMin != d->yMin && d->curvesYMin != INFINITY) { d->yMin = d->curvesYMin; updateY = true; } if (d->curvesYMax != d->yMax && d->curvesYMax != -INFINITY) { d->yMax = d->curvesYMax; updateY = true; } DEBUG(" xmin/xmax = " << d->xMin << '/' << d->xMax << ", ymin/ymax = " << d->yMin << '/' << d->yMax); if (updateX || updateY) { if (updateX) { if (d->xMax == d->xMin) { //in case min and max are equal (e.g. if we plot a single point), subtract/add 10% of the value if (d->xMax != 0) { d->xMax = d->xMax*1.1; d->xMin = d->xMin*0.9; } else { d->xMax = 0.1; d->xMin = -0.1; } } else { double offset = (d->xMax - d->xMin)*d->autoScaleOffsetFactor; d->xMin -= offset; d->xMax += offset; } } if (updateY) { if (d->yMax == d->yMin) { //in case min and max are equal (e.g. if we plot a single point), subtract/add 10% of the value if (d->yMax != 0) { d->yMax = d->yMax*1.1; d->yMin = d->yMin*0.9; } else { d->yMax = 0.1; d->yMin = -0.1; } } else { double offset = (d->yMax - d->yMin)*d->autoScaleOffsetFactor; d->yMin -= offset; d->yMax += offset; } } d->retransformScales(); } } void CartesianPlot::zoomIn() { DEBUG("CartesianPlot::zoomIn()"); Q_D(CartesianPlot); double oldRange = (d->xMax - d->xMin); double newRange = (d->xMax - d->xMin) / m_zoomFactor; d->xMax = d->xMax + (newRange - oldRange) / 2; d->xMin = d->xMin - (newRange - oldRange) / 2; oldRange = (d->yMax - d->yMin); newRange = (d->yMax - d->yMin) / m_zoomFactor; d->yMax = d->yMax + (newRange - oldRange) / 2; d->yMin = d->yMin - (newRange - oldRange) / 2; d->retransformScales(); } void CartesianPlot::zoomOut() { Q_D(CartesianPlot); double oldRange = (d->xMax-d->xMin); double newRange = (d->xMax-d->xMin)*m_zoomFactor; d->xMax = d->xMax + (newRange-oldRange)/2; d->xMin = d->xMin - (newRange-oldRange)/2; oldRange = (d->yMax-d->yMin); newRange = (d->yMax-d->yMin)*m_zoomFactor; d->yMax = d->yMax + (newRange-oldRange)/2; d->yMin = d->yMin - (newRange-oldRange)/2; d->retransformScales(); } void CartesianPlot::zoomInX() { Q_D(CartesianPlot); double oldRange = (d->xMax-d->xMin); double newRange = (d->xMax-d->xMin)/m_zoomFactor; d->xMax = d->xMax + (newRange-oldRange)/2; d->xMin = d->xMin - (newRange-oldRange)/2; d->retransformScales(); } void CartesianPlot::zoomOutX() { Q_D(CartesianPlot); double oldRange = (d->xMax-d->xMin); double newRange = (d->xMax-d->xMin)*m_zoomFactor; d->xMax = d->xMax + (newRange-oldRange)/2; d->xMin = d->xMin - (newRange-oldRange)/2; d->retransformScales(); } void CartesianPlot::zoomInY() { Q_D(CartesianPlot); double oldRange = (d->yMax-d->yMin); double newRange = (d->yMax-d->yMin)/m_zoomFactor; d->yMax = d->yMax + (newRange-oldRange)/2; d->yMin = d->yMin - (newRange-oldRange)/2; d->retransformScales(); } void CartesianPlot::zoomOutY() { Q_D(CartesianPlot); double oldRange = (d->yMax-d->yMin); double newRange = (d->yMax-d->yMin)*m_zoomFactor; d->yMax = d->yMax + (newRange-oldRange)/2; d->yMin = d->yMin - (newRange-oldRange)/2; d->retransformScales(); } void CartesianPlot::shiftLeftX() { Q_D(CartesianPlot); double offsetX = (d->xMax-d->xMin)*0.1; d->xMax -= offsetX; d->xMin -= offsetX; d->retransformScales(); } void CartesianPlot::shiftRightX() { Q_D(CartesianPlot); double offsetX = (d->xMax-d->xMin)*0.1; d->xMax += offsetX; d->xMin += offsetX; d->retransformScales(); } void CartesianPlot::shiftUpY() { Q_D(CartesianPlot); double offsetY = (d->yMax-d->yMin)*0.1; d->yMax += offsetY; d->yMin += offsetY; d->retransformScales(); } void CartesianPlot::shiftDownY() { Q_D(CartesianPlot); double offsetY = (d->yMax-d->yMin)*0.1; d->yMax -= offsetY; d->yMin -= offsetY; d->retransformScales(); } //############################################################################## //###### SLOTs for changes triggered via QActions in the context menu ######## //############################################################################## void CartesianPlot::visibilityChanged() { Q_D(CartesianPlot); this->setVisible(!d->isVisible()); } //##################################################################### //################### Private implementation ########################## //##################################################################### CartesianPlotPrivate::CartesianPlotPrivate(CartesianPlot* plot) : AbstractPlotPrivate(plot), curvesXMinMaxIsDirty(false), curvesYMinMaxIsDirty(false), curvesXMin(INFINITY), curvesXMax(-INFINITY), curvesYMin(INFINITY), curvesYMax(-INFINITY), q(plot), mouseMode(CartesianPlot::SelectionMode), cSystem(nullptr), suppressRetransform(false), // m_printing(false), m_selectionBandIsShown(false) { setData(0, WorksheetElement::NameCartesianPlot); } /*! updates the position of plot rectangular in scene coordinates to \c r and recalculates the scales. The size of the plot corresponds to the size of the plot area, the area which is filled with the background color etc. and which can pose the parent item for several sub-items (like TextLabel). Note, the size of the area used to define the coordinate system doesn't need to be equal to this plot area. Also, the size (=bounding box) of CartesianPlot can be greater than the size of the plot area. */ void CartesianPlotPrivate::retransform() { if (suppressRetransform) return; PERFTRACE("CartesianPlotPrivate::retransform()"); prepareGeometryChange(); setPos( rect.x()+rect.width()/2, rect.y()+rect.height()/2); retransformScales(); //plotArea position is always (0, 0) in parent's coordinates, don't need to update here q->plotArea()->setRect(rect); //call retransform() for the title and the legend (if available) //when a predefined position relative to the (Left, Centered etc.) is used, //the actual position needs to be updated on plot's geometry changes. if (q->title()) q->title()->retransform(); if (q->m_legend) q->m_legend->retransform(); WorksheetElementContainerPrivate::recalcShapeAndBoundingRect(); } void CartesianPlotPrivate::retransformScales() { PERFTRACE("CartesianPlotPrivate::retransformScales()"); DEBUG(" xmin/xmax = " << xMin << '/'<< xMax << ", ymin/ymax = " << yMin << '/' << yMax); CartesianPlot* plot = dynamic_cast(q); QVector scales; //perform the mapping from the scene coordinates to the plot's coordinates here. QRectF itemRect = mapRectFromScene(rect); //check ranges for log-scales if (xScale != CartesianPlot::ScaleLinear) checkXRange(); //check whether we have x-range breaks - the first break, if available, should be valid bool hasValidBreak = (xRangeBreakingEnabled && !xRangeBreaks.list.isEmpty() && xRangeBreaks.list.first().isValid()); static const int breakGap = 20; double sceneStart, sceneEnd, logicalStart, logicalEnd; //create x-scales int plotSceneStart = itemRect.x() + horizontalPadding; int plotSceneEnd = itemRect.x() + itemRect.width() - horizontalPadding; if (!hasValidBreak) { //no breaks available -> range goes from the plot beginning to the end of the plot sceneStart = plotSceneStart; sceneEnd = plotSceneEnd; logicalStart = xMin; logicalEnd = xMax; //TODO: how should we handle the case sceneStart == sceneEnd? //(to reproduce, create plots and adjust the spacing/pading to get zero size for the plots) if (sceneStart != sceneEnd) scales << this->createScale(xScale, sceneStart, sceneEnd, logicalStart, logicalEnd); } else { int sceneEndLast = plotSceneStart; int logicalEndLast = xMin; for (const auto& rb: xRangeBreaks.list) { if (!rb.isValid()) break; //current range goes from the end of the previous one (or from the plot beginning) to curBreak.start sceneStart = sceneEndLast; if (&rb == &xRangeBreaks.list.first()) sceneStart += breakGap; sceneEnd = plotSceneStart + (plotSceneEnd-plotSceneStart) * rb.position; logicalStart = logicalEndLast; logicalEnd = rb.start; if (sceneStart != sceneEnd) scales << this->createScale(xScale, sceneStart, sceneEnd, logicalStart, logicalEnd); sceneEndLast = sceneEnd; logicalEndLast = rb.end; } //add the remaining range going from the last available range break to the end of the plot (=end of the x-data range) sceneStart = sceneEndLast+breakGap; sceneEnd = plotSceneEnd; logicalStart = logicalEndLast; logicalEnd = xMax; if (sceneStart != sceneEnd) scales << this->createScale(xScale, sceneStart, sceneEnd, logicalStart, logicalEnd); } cSystem->setXScales(scales); //check ranges for log-scales if (yScale != CartesianPlot::ScaleLinear) checkYRange(); //check whether we have y-range breaks - the first break, if available, should be valid hasValidBreak = (yRangeBreakingEnabled && !yRangeBreaks.list.isEmpty() && yRangeBreaks.list.first().isValid()); //create y-scales scales.clear(); plotSceneStart = itemRect.y()+itemRect.height()-verticalPadding; plotSceneEnd = itemRect.y()+verticalPadding; if (!hasValidBreak) { //no breaks available -> range goes from the plot beginning to the end of the plot sceneStart = plotSceneStart; sceneEnd = plotSceneEnd; logicalStart = yMin; logicalEnd = yMax; if (sceneStart != sceneEnd) scales << this->createScale(yScale, sceneStart, sceneEnd, logicalStart, logicalEnd); } else { int sceneEndLast = plotSceneStart; int logicalEndLast = yMin; for (const auto& rb: yRangeBreaks.list) { if (!rb.isValid()) break; //current range goes from the end of the previous one (or from the plot beginning) to curBreak.start sceneStart = sceneEndLast; if (&rb == &yRangeBreaks.list.first()) sceneStart -= breakGap; sceneEnd = plotSceneStart + (plotSceneEnd-plotSceneStart) * rb.position; logicalStart = logicalEndLast; logicalEnd = rb.start; if (sceneStart != sceneEnd) scales << this->createScale(yScale, sceneStart, sceneEnd, logicalStart, logicalEnd); sceneEndLast = sceneEnd; logicalEndLast = rb.end; } //add the remaining range going from the last available range break to the end of the plot (=end of the y-data range) sceneStart = sceneEndLast-breakGap; sceneEnd = plotSceneEnd; logicalStart = logicalEndLast; logicalEnd = yMax; if (sceneStart != sceneEnd) scales << this->createScale(yScale, sceneStart, sceneEnd, logicalStart, logicalEnd); } cSystem->setYScales(scales); //calculate the changes in x and y and save the current values for xMin, xMax, yMin, yMax double deltaXMin = 0; double deltaXMax = 0; double deltaYMin = 0; double deltaYMax = 0; if (xMin != xMinPrev) { deltaXMin = xMin - xMinPrev; emit plot->xMinChanged(xMin); } if (xMax != xMaxPrev) { deltaXMax = xMax - xMaxPrev; emit plot->xMaxChanged(xMax); } if (yMin != yMinPrev) { deltaYMin = yMin - yMinPrev; emit plot->yMinChanged(yMin); } if (yMax!=yMaxPrev) { deltaYMax = yMax - yMaxPrev; emit plot->yMaxChanged(yMax); } xMinPrev = xMin; xMaxPrev = xMax; yMinPrev = yMin; yMaxPrev = yMax; //adjust auto-scale axes for (auto* axis: q->children()) { if (!axis->autoScale()) continue; if (axis->orientation() == Axis::AxisHorizontal) { if (deltaXMax != 0) { axis->setUndoAware(false); axis->setSuppressRetransform(true); axis->setEnd(xMax); axis->setUndoAware(true); axis->setSuppressRetransform(false); } if (deltaXMin != 0) { axis->setUndoAware(false); axis->setSuppressRetransform(true); axis->setStart(xMin); axis->setUndoAware(true); axis->setSuppressRetransform(false); } //TODO; // if (axis->position() == Axis::AxisCustom && deltaYMin != 0) { // axis->setOffset(axis->offset() + deltaYMin, false); // } } else { if (deltaYMax != 0) { axis->setUndoAware(false); axis->setSuppressRetransform(true); axis->setEnd(yMax); axis->setUndoAware(true); axis->setSuppressRetransform(false); } if (deltaYMin != 0) { axis->setUndoAware(false); axis->setSuppressRetransform(true); axis->setStart(yMin); axis->setUndoAware(true); axis->setSuppressRetransform(false); } //TODO; // if (axis->position() == Axis::AxisCustom && deltaXMin != 0) { // axis->setOffset(axis->offset() + deltaXMin, false); // } } } // call retransform() on the parent to trigger the update of all axes and curvesю //no need to do this on load since all plots are retransformed again after the project is loaded. if (!q->isLoading()) q->retransform(); } void CartesianPlotPrivate::rangeChanged() { curvesXMinMaxIsDirty = true; curvesYMinMaxIsDirty = true; if (autoScaleX && autoScaleY) q->scaleAuto(); else if (autoScaleX) q->scaleAutoX(); else if (autoScaleY) q->scaleAutoY(); } /*! * don't allow any negative values for the x range when log or sqrt scalings are used */ void CartesianPlotPrivate::checkXRange() { double min = 0.01; if (xMin <= 0.0) { (min < xMax*min) ? xMin = min : xMin = xMax*min; emit q->xMinChanged(xMin); } else if (xMax <= 0.0) { (-min > xMin*min) ? xMax = -min : xMax = xMin*min; emit q->xMaxChanged(xMax); } } /*! * don't allow any negative values for the y range when log or sqrt scalings are used */ void CartesianPlotPrivate::checkYRange() { double min = 0.01; if (yMin <= 0.0) { (min < yMax*min) ? yMin = min : yMin = yMax*min; emit q->yMinChanged(yMin); } else if (yMax <= 0.0) { (-min > yMin*min) ? yMax = -min : yMax = yMin*min; emit q->yMaxChanged(yMax); } } CartesianScale* CartesianPlotPrivate::createScale(CartesianPlot::Scale type, double sceneStart, double sceneEnd, double logicalStart, double logicalEnd) { DEBUG("CartesianPlotPrivate::createScale() scence start/end = " << sceneStart << '/' << sceneEnd << ", logical start/end = " << logicalStart << '/' << logicalEnd); // Interval interval (logicalStart-0.01, logicalEnd+0.01); //TODO: move this to CartesianScale Interval interval (CartesianScale::LIMIT_MIN, CartesianScale::LIMIT_MAX); // Interval interval (logicalStart, logicalEnd); if (type == CartesianPlot::ScaleLinear) return CartesianScale::createLinearScale(interval, sceneStart, sceneEnd, logicalStart, logicalEnd); else { double base; if (type == CartesianPlot::ScaleLog10) base = 10.0; else if (type == CartesianPlot::ScaleLog2) base = 2.0; else base = M_E; return CartesianScale::createLogScale(interval, sceneStart, sceneEnd, logicalStart, logicalEnd, base); } } /*! * Reimplemented from QGraphicsItem. */ QVariant CartesianPlotPrivate::itemChange(GraphicsItemChange change, const QVariant &value) { if (change == QGraphicsItem::ItemPositionChange) { const QPointF& itemPos = value.toPointF();//item's center point in parent's coordinates; float x = itemPos.x(); float y = itemPos.y(); //calculate the new rect and forward the changes to the frontend QRectF newRect; float w = rect.width(); float h = rect.height(); newRect.setX(x-w/2); newRect.setY(y-h/2); newRect.setWidth(w); newRect.setHeight(h); emit q->rectChanged(newRect); } return QGraphicsItem::itemChange(change, value); } void CartesianPlotPrivate::mousePressEvent(QGraphicsSceneMouseEvent *event) { if (mouseMode == CartesianPlot::ZoomSelectionMode || mouseMode == CartesianPlot::ZoomXSelectionMode || mouseMode == CartesianPlot::ZoomYSelectionMode) { if (mouseMode == CartesianPlot::ZoomSelectionMode) m_selectionStart = event->pos(); else if (mouseMode == CartesianPlot::ZoomXSelectionMode) { m_selectionStart.setX(event->pos().x()); m_selectionStart.setY(q->plotRect().height()/2); } else if (mouseMode == CartesianPlot::ZoomYSelectionMode) { m_selectionStart.setX(-q->plotRect().width()/2); m_selectionStart.setY(event->pos().y()); } m_selectionEnd = m_selectionStart; m_selectionBandIsShown = true; } else QGraphicsItem::mousePressEvent(event); } void CartesianPlotPrivate::mouseMoveEvent(QGraphicsSceneMouseEvent* event) { if (mouseMode == CartesianPlot::SelectionMode) QGraphicsItem::mouseMoveEvent(event); else if (mouseMode == CartesianPlot::ZoomSelectionMode || mouseMode == CartesianPlot::ZoomXSelectionMode || mouseMode == CartesianPlot::ZoomYSelectionMode) { QGraphicsItem::mouseMoveEvent(event); if ( !boundingRect().contains(event->pos()) ) { q->info(""); return; } QString info; QPointF logicalStart = cSystem->mapSceneToLogical(m_selectionStart); if (mouseMode == CartesianPlot::ZoomSelectionMode) { m_selectionEnd = event->pos(); QPointF logicalEnd = cSystem->mapSceneToLogical(m_selectionEnd); info = QString::fromUtf8("Δx=") + QString::number(logicalEnd.x()-logicalStart.x()) + QString::fromUtf8(", Δy=") + QString::number(logicalEnd.y()-logicalStart.y()); } else if (mouseMode == CartesianPlot::ZoomXSelectionMode) { m_selectionEnd.setX(event->pos().x()); m_selectionEnd.setY(-q->plotRect().height()/2); QPointF logicalEnd = cSystem->mapSceneToLogical(m_selectionEnd); info = QString::fromUtf8("Δx=") + QString::number(logicalEnd.x()-logicalStart.x()); } else if (mouseMode == CartesianPlot::ZoomYSelectionMode) { m_selectionEnd.setX(q->plotRect().width()/2); m_selectionEnd.setY(event->pos().y()); QPointF logicalEnd = cSystem->mapSceneToLogical(m_selectionEnd); info = QString::fromUtf8("Δy=") + QString::number(logicalEnd.y()-logicalStart.y()); } q->info(info); update(); } //TODO: implement the navigation in plot on mouse move events, //calculate the position changes and call shift*()-functions } void CartesianPlotPrivate::mouseReleaseEvent(QGraphicsSceneMouseEvent* event) { if (mouseMode == CartesianPlot::SelectionMode) { const QPointF& itemPos = pos();//item's center point in parent's coordinates; float x = itemPos.x(); float y = itemPos.y(); //calculate the new rect and set it QRectF newRect; float w = rect.width(); float h = rect.height(); newRect.setX(x-w/2); newRect.setY(y-h/2); newRect.setWidth(w); newRect.setHeight(h); suppressRetransform = true; q->setRect(newRect); suppressRetransform = false; QGraphicsItem::mouseReleaseEvent(event); } else if (mouseMode == CartesianPlot::ZoomSelectionMode || mouseMode == CartesianPlot::ZoomXSelectionMode || mouseMode == CartesianPlot::ZoomYSelectionMode) { //don't zoom if very small region was selected, avoid occasional/unwanted zooming if ( qAbs(m_selectionEnd.x()-m_selectionStart.x()) < 20 || qAbs(m_selectionEnd.y()-m_selectionStart.y()) < 20 ) { m_selectionBandIsShown = false; return; } //determine the new plot ranges QPointF logicalZoomStart = cSystem->mapSceneToLogical(m_selectionStart, AbstractCoordinateSystem::SuppressPageClipping); QPointF logicalZoomEnd = cSystem->mapSceneToLogical(m_selectionEnd, AbstractCoordinateSystem::SuppressPageClipping); if (m_selectionEnd.x() > m_selectionStart.x()) { xMin = logicalZoomStart.x(); xMax = logicalZoomEnd.x(); } else { xMin = logicalZoomEnd.x(); xMax = logicalZoomStart.x(); } if (m_selectionEnd.y() > m_selectionStart.y()) { yMin = logicalZoomEnd.y(); yMax = logicalZoomStart.y(); } else { yMin = logicalZoomStart.y(); yMax = logicalZoomEnd.y(); } m_selectionBandIsShown = false; retransformScales(); } } void CartesianPlotPrivate::wheelEvent(QGraphicsSceneWheelEvent* event) { //determine first, which axes are selected and zoom only in the corresponding direction. //zoom the entire plot if no axes selected. bool zoomX = false; bool zoomY = false; for (auto* axis: q->children()) { if (!axis->graphicsItem()->isSelected()) continue; if (axis->orientation() == Axis::AxisHorizontal) zoomX = true; else zoomY = true; } if (event->delta() > 0) { if (!zoomX && !zoomY) { //no special axis selected -> zoom in everything q->zoomIn(); } else { if (zoomX) q->zoomInX(); if (zoomY) q->zoomInY(); } } else { if (!zoomX && !zoomY) { //no special axis selected -> zoom in everything q->zoomOut(); } else { if (zoomX) q->zoomOutX(); if (zoomY) q->zoomOutY(); } } } void CartesianPlotPrivate::hoverMoveEvent(QGraphicsSceneHoverEvent* event) { QPointF point = event->pos(); QString info; if (q->plotRect().contains(point)) { QPointF logicalPoint = cSystem->mapSceneToLogical(point); if (mouseMode == CartesianPlot::ZoomSelectionMode && !m_selectionBandIsShown) info = "x=" + QString::number(logicalPoint.x()) + ", y=" + QString::number(logicalPoint.y()); else if (mouseMode == CartesianPlot::ZoomXSelectionMode && !m_selectionBandIsShown) { QPointF p1(logicalPoint.x(), yMin); QPointF p2(logicalPoint.x(), yMax); m_selectionStartLine.setP1(cSystem->mapLogicalToScene(p1)); m_selectionStartLine.setP2(cSystem->mapLogicalToScene(p2)); info = "x=" + QString::number(logicalPoint.x()); update(); } else if (mouseMode == CartesianPlot::ZoomYSelectionMode && !m_selectionBandIsShown) { QPointF p1(xMin, logicalPoint.y()); QPointF p2(xMax, logicalPoint.y()); m_selectionStartLine.setP1(cSystem->mapLogicalToScene(p1)); m_selectionStartLine.setP2(cSystem->mapLogicalToScene(p2)); info = "y=" + QString::number(logicalPoint.y()); update(); } } q->info(info); QGraphicsItem::hoverMoveEvent(event); } void CartesianPlotPrivate::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget * widget) { if (!isVisible()) return; painter->setPen(QPen(Qt::black, 3)); if ((mouseMode == CartesianPlot::ZoomXSelectionMode || mouseMode == CartesianPlot::ZoomYSelectionMode) && (!m_selectionBandIsShown)) painter->drawLine(m_selectionStartLine); if (m_selectionBandIsShown) { painter->save(); painter->setPen(QPen(Qt::black, 5)); painter->drawRect(QRectF(m_selectionStart, m_selectionEnd)); painter->setBrush(Qt::blue); painter->setOpacity(0.2); painter->drawRect(QRectF(m_selectionStart, m_selectionEnd)); painter->restore(); } WorksheetElementContainerPrivate::paint(painter, option, widget); } //############################################################################## //################## Serialization/Deserialization ########################### //############################################################################## //! Save as XML void CartesianPlot::save(QXmlStreamWriter* writer) const { Q_D(const CartesianPlot); writer->writeStartElement( "cartesianPlot" ); writeBasicAttributes(writer); writeCommentElement(writer); //applied theme if (!d->theme.isEmpty()) { writer->writeStartElement( "theme" ); writer->writeAttribute("name", d->theme); writer->writeEndElement(); } //geometry writer->writeStartElement( "geometry" ); writer->writeAttribute( "x", QString::number(d->rect.x()) ); writer->writeAttribute( "y", QString::number(d->rect.y()) ); writer->writeAttribute( "width", QString::number(d->rect.width()) ); writer->writeAttribute( "height", QString::number(d->rect.height()) ); writer->writeAttribute( "visible", QString::number(d->isVisible()) ); writer->writeEndElement(); //coordinate system and padding writer->writeStartElement( "coordinateSystem" ); writer->writeAttribute( "autoScaleX", QString::number(d->autoScaleX) ); writer->writeAttribute( "autoScaleY", QString::number(d->autoScaleY) ); writer->writeAttribute( "xMin", QString::number(d->xMin) ); writer->writeAttribute( "xMax", QString::number(d->xMax) ); writer->writeAttribute( "yMin", QString::number(d->yMin) ); writer->writeAttribute( "yMax", QString::number(d->yMax) ); writer->writeAttribute( "xScale", QString::number(d->xScale) ); writer->writeAttribute( "yScale", QString::number(d->yScale) ); writer->writeAttribute( "horizontalPadding", QString::number(d->horizontalPadding) ); writer->writeAttribute( "verticalPadding", QString::number(d->verticalPadding) ); writer->writeEndElement(); //x-scale breaks if (d->xRangeBreakingEnabled || !d->xRangeBreaks.list.isEmpty()) { writer->writeStartElement("xRangeBreaks"); writer->writeAttribute( "enabled", QString::number(d->xRangeBreakingEnabled) ); for (const auto& rb: d->xRangeBreaks.list) { writer->writeStartElement("xRangeBreak"); writer->writeAttribute("start", QString::number(rb.start)); writer->writeAttribute("end", QString::number(rb.end)); writer->writeAttribute("position", QString::number(rb.position)); writer->writeAttribute("style", QString::number(rb.style)); writer->writeEndElement(); } writer->writeEndElement(); } //y-scale breaks if (d->yRangeBreakingEnabled || !d->yRangeBreaks.list.isEmpty()) { writer->writeStartElement("yRangeBreaks"); writer->writeAttribute( "enabled", QString::number(d->yRangeBreakingEnabled) ); for (const auto& rb: d->yRangeBreaks.list) { writer->writeStartElement("yRangeBreak"); writer->writeAttribute("start", QString::number(rb.start)); writer->writeAttribute("end", QString::number(rb.end)); writer->writeAttribute("position", QString::number(rb.position)); writer->writeAttribute("style", QString::number(rb.style)); writer->writeEndElement(); } writer->writeEndElement(); } //serialize all children (plot area, title text label, axes and curves) for (auto *elem: children(IncludeHidden)) elem->save(writer); writer->writeEndElement(); // close "cartesianPlot" section } //! Load from XML bool CartesianPlot::load(XmlStreamReader* reader, bool preview) { Q_D(CartesianPlot); if (!reader->isStartElement() || reader->name() != "cartesianPlot") { reader->raiseError(i18n("no cartesianPlot element found")); return false; } if (!readBasicAttributes(reader)) return false; QString attributeWarning = i18n("Attribute '%1' missing or empty, default value is used"); QXmlStreamAttributes attribs; QString str; while (!reader->atEnd()) { reader->readNext(); if (reader->isEndElement() && reader->name() == "cartesianPlot") break; if (!reader->isStartElement()) continue; if (reader->name() == "comment") { if (!readCommentElement(reader)) return false; } else if (!preview && reader->name() == "theme") { attribs = reader->attributes(); d->theme = attribs.value("name").toString(); } else if (!preview && reader->name() == "geometry") { attribs = reader->attributes(); str = attribs.value("x").toString(); if (str.isEmpty()) reader->raiseWarning(attributeWarning.arg("'x'")); else d->rect.setX( str.toDouble() ); str = attribs.value("y").toString(); if (str.isEmpty()) reader->raiseWarning(attributeWarning.arg("'y'")); else d->rect.setY( str.toDouble() ); str = attribs.value("width").toString(); if (str.isEmpty()) reader->raiseWarning(attributeWarning.arg("'width'")); else d->rect.setWidth( str.toDouble() ); str = attribs.value("height").toString(); if (str.isEmpty()) reader->raiseWarning(attributeWarning.arg("'height'")); else d->rect.setHeight( str.toDouble() ); str = attribs.value("visible").toString(); if (str.isEmpty()) reader->raiseWarning(attributeWarning.arg("'visible'")); else d->setVisible(str.toInt()); } else if (!preview && reader->name() == "coordinateSystem") { attribs = reader->attributes(); str = attribs.value("autoScaleX").toString(); if (str.isEmpty()) reader->raiseWarning(attributeWarning.arg("'autoScaleX'")); else d->autoScaleX = bool(str.toInt()); str = attribs.value("autoScaleY").toString(); if (str.isEmpty()) reader->raiseWarning(attributeWarning.arg("'autoScaleY'")); else d->autoScaleY = bool(str.toInt()); str = attribs.value("xMin").toString(); if (str.isEmpty()) reader->raiseWarning(attributeWarning.arg("'xMin'")); else { d->xMin = str.toDouble(); d->xMinPrev = d->xMin; } str = attribs.value("xMax").toString(); if (str.isEmpty()) reader->raiseWarning(attributeWarning.arg("'xMax'")); else { d->xMax = str.toDouble(); d->xMaxPrev = d->xMax; } str = attribs.value("yMin").toString(); if (str.isEmpty()) reader->raiseWarning(attributeWarning.arg("'yMin'")); else { d->yMin = str.toDouble(); d->yMinPrev = d->yMin; } str = attribs.value("yMax").toString(); if (str.isEmpty()) reader->raiseWarning(attributeWarning.arg("'yMax'")); else { d->yMax = str.toDouble(); d->yMaxPrev = d->yMax; } str = attribs.value("xScale").toString(); if (str.isEmpty()) reader->raiseWarning(attributeWarning.arg("'xScale'")); else d->xScale = CartesianPlot::Scale(str.toInt()); str = attribs.value("yScale").toString(); if (str.isEmpty()) reader->raiseWarning(attributeWarning.arg("'yScale'")); else d->yScale = CartesianPlot::Scale(str.toInt()); str = attribs.value("horizontalPadding").toString(); if (str.isEmpty()) reader->raiseWarning(attributeWarning.arg("'horizontalPadding'")); else d->horizontalPadding = str.toDouble(); str = attribs.value("verticalPadding").toString(); if (str.isEmpty()) reader->raiseWarning(attributeWarning.arg("'verticalPadding'")); else d->verticalPadding = str.toDouble(); } else if (!preview && reader->name() == "xRangeBreaks") { //delete default rang break d->xRangeBreaks.list.clear(); attribs = reader->attributes(); str = attribs.value("enabled").toString(); if (str.isEmpty()) reader->raiseWarning(attributeWarning.arg("'enabled'")); else d->xRangeBreakingEnabled = str.toInt(); } else if (!preview && reader->name() == "xRangeBreak") { attribs = reader->attributes(); RangeBreak b; str = attribs.value("start").toString(); if (str.isEmpty()) reader->raiseWarning(attributeWarning.arg("'start'")); else b.start = str.toDouble(); str = attribs.value("end").toString(); if (str.isEmpty()) reader->raiseWarning(attributeWarning.arg("'end'")); else b.end = str.toDouble(); str = attribs.value("position").toString(); if (str.isEmpty()) reader->raiseWarning(attributeWarning.arg("'position'")); else b.position = str.toDouble(); str = attribs.value("style").toString(); if (str.isEmpty()) reader->raiseWarning(attributeWarning.arg("'style'")); else b.style = CartesianPlot::RangeBreakStyle(str.toInt()); d->xRangeBreaks.list << b; } else if (!preview && reader->name() == "yRangeBreaks") { //delete default rang break d->yRangeBreaks.list.clear(); attribs = reader->attributes(); str = attribs.value("enabled").toString(); if (str.isEmpty()) reader->raiseWarning(attributeWarning.arg("'enabled'")); else d->yRangeBreakingEnabled = str.toInt(); } else if (!preview && reader->name() == "yRangeBreak") { attribs = reader->attributes(); RangeBreak b; str = attribs.value("start").toString(); if (str.isEmpty()) reader->raiseWarning(attributeWarning.arg("'start'")); else b.start = str.toDouble(); str = attribs.value("end").toString(); if (str.isEmpty()) reader->raiseWarning(attributeWarning.arg("'end'")); else b.end = str.toDouble(); str = attribs.value("position").toString(); if (str.isEmpty()) reader->raiseWarning(attributeWarning.arg("'position'")); else b.position = str.toDouble(); str = attribs.value("style").toString(); if (str.isEmpty()) reader->raiseWarning(attributeWarning.arg("'style'")); else b.style = CartesianPlot::RangeBreakStyle(str.toInt()); d->yRangeBreaks.list << b; } else if (reader->name() == "textLabel") { m_title = new TextLabel(""); if (m_title->load(reader, preview)) addChildFast(m_title); else { delete m_title; m_title=0; return false; } } else if (reader->name() == "plotArea") m_plotArea->load(reader, preview); else if (reader->name() == "axis") { Axis* axis = new Axis("", this); if (axis->load(reader, preview)) addChildFast(axis); else { delete axis; return false; } } else if (reader->name() == "xyCurve") { XYCurve* curve = new XYCurve(""); if (curve->load(reader, preview)) addChildFast(curve); else { removeChild(curve); return false; } } else if (reader->name() == "xyEquationCurve") { XYEquationCurve* curve = new XYEquationCurve(""); if (curve->load(reader, preview)) addChildFast(curve); else { removeChild(curve); return false; } } else if (reader->name() == "xyDataReductionCurve") { XYDataReductionCurve* curve = new XYDataReductionCurve(""); if (curve->load(reader, preview)) addChildFast(curve); else { removeChild(curve); return false; } } else if (reader->name() == "xyDifferentiationCurve") { XYDifferentiationCurve* curve = new XYDifferentiationCurve(""); if (curve->load(reader, preview)) addChildFast(curve); else { removeChild(curve); return false; } } else if (reader->name() == "xyIntegrationCurve") { XYIntegrationCurve* curve = new XYIntegrationCurve(""); if (curve->load(reader, preview)) addChildFast(curve); else { removeChild(curve); return false; } } else if (reader->name() == "xyInterpolationCurve") { XYInterpolationCurve* curve = new XYInterpolationCurve(""); if (curve->load(reader, preview)) addChildFast(curve); else { removeChild(curve); return false; } } else if (reader->name() == "xyFitCurve") { XYFitCurve* curve = new XYFitCurve(""); if (curve->load(reader, preview)) addChildFast(curve); else { removeChild(curve); return false; } } else if (reader->name() == "xyFourierFilterCurve") { XYFourierFilterCurve* curve = new XYFourierFilterCurve(""); if (curve->load(reader, preview)) addChildFast(curve); else { removeChild(curve); return false; } } else if (reader->name() == "xyFourierTransformCurve") { XYFourierTransformCurve* curve = new XYFourierTransformCurve(""); if (curve->load(reader, preview)) addChildFast(curve); else { removeChild(curve); return false; } } else if (reader->name() == "xySmoothCurve") { XYSmoothCurve* curve = new XYSmoothCurve(""); if (curve->load(reader, preview)) addChildFast(curve); else { removeChild(curve); return false; } } else if (reader->name() == "cartesianPlotLegend") { m_legend = new CartesianPlotLegend(this, ""); if (m_legend->load(reader, preview)) addChildFast(m_legend); else { delete m_legend; return false; } } else if (reader->name() == "customPoint") { CustomPoint* point = new CustomPoint(this, ""); if (point->load(reader, preview)) addChildFast(point); else { delete point; return false; } } else if(reader->name() == "Histogram") { Histogram* curve = new Histogram("Histogram"); if (curve->load(reader, preview)) addChildFast(curve); else { removeChild(curve); return false; } } else { // unknown element reader->raiseWarning(i18n("unknown cartesianPlot element '%1'", reader->name().toString())); if (!reader->skipToEndElement()) return false; } } if (preview) return true; d->retransform(); if (m_title) { m_title->setHidden(true); m_title->graphicsItem()->setParentItem(m_plotArea->graphicsItem()); } //if a theme was used, initialize the color palette if (!d->theme.isEmpty()) { //TODO: check whether the theme config really exists KConfig config( ThemeHandler::themeFilePath(d->theme), KConfig::SimpleConfig ); this->setColorPalette(config); } return true; } //############################################################################## //######################### Theme management ################################## //############################################################################## void CartesianPlot::loadTheme(const QString& theme) { KConfig config(ThemeHandler::themeFilePath(theme), KConfig::SimpleConfig); loadThemeConfig(config); } void CartesianPlot::loadThemeConfig(const KConfig& config) { QString str = config.name(); str = str.right(str.length() - str.lastIndexOf(QDir::separator()) - 1); this->setTheme(str); //load the color palettes for the curves this->setColorPalette(config); //load the theme for all the children for (auto* child: children(AbstractAspect::IncludeHidden)) child->loadThemeConfig(config); Q_D(CartesianPlot); d->update(this->rect()); } void CartesianPlot::saveTheme(KConfig &config) { const QVector& axisElements = children(AbstractAspect::IncludeHidden); const QVector& plotAreaElements = children(AbstractAspect::IncludeHidden); const QVector& textLabelElements = children(AbstractAspect::IncludeHidden); axisElements.at(0)->saveThemeConfig(config); plotAreaElements.at(0)->saveThemeConfig(config); textLabelElements.at(0)->saveThemeConfig(config); for (auto *child: children(AbstractAspect::IncludeHidden)) child->saveThemeConfig(config); } //Generating colors from 5-color theme palette void CartesianPlot::setColorPalette(const KConfig& config) { KConfigGroup group = config.group("Theme"); //read the five colors defining the palette m_themeColorPalette.clear(); m_themeColorPalette.append(group.readEntry("ThemePaletteColor1", QColor())); m_themeColorPalette.append(group.readEntry("ThemePaletteColor2", QColor())); m_themeColorPalette.append(group.readEntry("ThemePaletteColor3", QColor())); m_themeColorPalette.append(group.readEntry("ThemePaletteColor4", QColor())); m_themeColorPalette.append(group.readEntry("ThemePaletteColor5", QColor())); //generate 30 additional shades if the color palette contains more than one color if (m_themeColorPalette.at(0) != m_themeColorPalette.at(1)) { QColor c; //3 factors to create shades from theme's palette float fac[3] = {0.25,0.45,0.65}; //Generate 15 lighter shades for (int i = 0; i < 5; i++) { for (int j = 1; j < 4; j++) { c.setRed( m_themeColorPalette.at(i).red()*(1-fac[j-1]) ); c.setGreen( m_themeColorPalette.at(i).green()*(1-fac[j-1]) ); c.setBlue( m_themeColorPalette.at(i).blue()*(1-fac[j-1]) ); m_themeColorPalette.append(c); } } //Generate 15 darker shades for (int i = 0; i < 5; i++) { for (int j = 4; j < 7; j++) { c.setRed( m_themeColorPalette.at(i).red()+((255-m_themeColorPalette.at(i).red())*fac[j-4]) ); c.setGreen( m_themeColorPalette.at(i).green()+((255-m_themeColorPalette.at(i).green())*fac[j-4]) ); c.setBlue( m_themeColorPalette.at(i).blue()+((255-m_themeColorPalette.at(i).blue())*fac[j-4]) ); m_themeColorPalette.append(c); } } } } const QList& CartesianPlot::themeColorPalette() const { return m_themeColorPalette; } diff --git a/src/backend/worksheet/plots/cartesian/CartesianPlot.h b/src/backend/worksheet/plots/cartesian/CartesianPlot.h index 94fe9efc6..c48aa9ad5 100644 --- a/src/backend/worksheet/plots/cartesian/CartesianPlot.h +++ b/src/backend/worksheet/plots/cartesian/CartesianPlot.h @@ -1,284 +1,284 @@ /*************************************************************************** File : CartesianPlot.h Project : LabPlot Description : Cartesian plot -------------------------------------------------------------------- Copyright : (C) 2011-2017 by Alexander Semke (alexander.semke@web.de) ***************************************************************************/ /*************************************************************************** * * * 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 CARTESIANPLOT_H #define CARTESIANPLOT_H #include "backend/worksheet/plots/AbstractPlot.h" #include "backend/worksheet/plots/cartesian/Histogram.h" #include class QDropEvent; class QToolBar; class CartesianPlotPrivate; class CartesianPlotLegend; class AbstractColumn; class XYCurve; class XYEquationCurve; class XYDataReductionCurve; class XYDifferentiationCurve; class XYIntegrationCurve; class XYInterpolationCurve; class XYSmoothCurve; class XYFitCurve; class XYFourierFilterCurve; class KConfig; class XYFourierTransformCurve; class CartesianPlot:public AbstractPlot { Q_OBJECT public: explicit CartesianPlot(const QString &name); - virtual ~CartesianPlot(); + ~CartesianPlot() override; enum Scale {ScaleLinear, ScaleLog10, ScaleLog2, ScaleLn, ScaleSqrt, ScaleX2}; enum Type {FourAxes, TwoAxes, TwoAxesCentered, TwoAxesCenteredZero}; enum RangeType {RangeFree, RangeLast, RangeFirst}; enum RangeBreakStyle {RangeBreakSimple, RangeBreakVertical, RangeBreakSloped}; enum MouseMode {SelectionMode, ZoomSelectionMode, ZoomXSelectionMode, ZoomYSelectionMode}; enum NavigationOperation {ScaleAuto, ScaleAutoX, ScaleAutoY, ZoomIn, ZoomOut, ZoomInX, ZoomOutX, ZoomInY, ZoomOutY, ShiftLeftX, ShiftRightX, ShiftUpY, ShiftDownY }; struct RangeBreak { RangeBreak() : start(NAN), end(NAN), position(0.5), style(RangeBreakSloped) {} bool isValid() const { return (!std::isnan(start) && !std::isnan(end)); } double start; double end; double position; RangeBreakStyle style; }; //simple wrapper for QList in order to get our macros working struct RangeBreaks { RangeBreaks() : lastChanged(-1) { RangeBreak b; list << b; }; QList list; int lastChanged; }; void initDefault(Type = FourAxes); QIcon icon() const override; QMenu* createContextMenu() override; QMenu* analysisMenu(); - virtual QVector dependsOn() const override; + QVector dependsOn() const override; void setRect(const QRectF&) override; QRectF plotRect(); void setMouseMode(const MouseMode); MouseMode mouseMode() const; void navigate(NavigationOperation); void setSuppressDataChangedSignal(bool); const QList& themeColorPalette() const; void processDropEvent(QDropEvent*); - virtual void save(QXmlStreamWriter*) const override; - virtual bool load(XmlStreamReader*, bool preview) override; - virtual void loadThemeConfig(const KConfig&) override; + void save(QXmlStreamWriter*) const override; + bool load(XmlStreamReader*, bool preview) override; + void loadThemeConfig(const KConfig&) override; void saveTheme(KConfig& config); BASIC_D_ACCESSOR_DECL(CartesianPlot::RangeType, rangeType, RangeType) BASIC_D_ACCESSOR_DECL(int, rangeLastValues, RangeLastValues) BASIC_D_ACCESSOR_DECL(int, rangeFirstValues, RangeFirstValues) BASIC_D_ACCESSOR_DECL(bool, autoScaleX, AutoScaleX) BASIC_D_ACCESSOR_DECL(bool, autoScaleY, AutoScaleY) BASIC_D_ACCESSOR_DECL(double, xMin, XMin) BASIC_D_ACCESSOR_DECL(double, xMax, XMax) BASIC_D_ACCESSOR_DECL(double, yMin, YMin) BASIC_D_ACCESSOR_DECL(double, yMax, YMax) BASIC_D_ACCESSOR_DECL(CartesianPlot::Scale, xScale, XScale) BASIC_D_ACCESSOR_DECL(CartesianPlot::Scale, yScale, YScale) BASIC_D_ACCESSOR_DECL(bool, xRangeBreakingEnabled, XRangeBreakingEnabled) BASIC_D_ACCESSOR_DECL(bool, yRangeBreakingEnabled, YRangeBreakingEnabled) CLASS_D_ACCESSOR_DECL(RangeBreaks, xRangeBreaks, XRangeBreaks) CLASS_D_ACCESSOR_DECL(RangeBreaks, yRangeBreaks, YRangeBreaks) QString theme() const; typedef CartesianPlotPrivate Private; public slots: void setTheme(const QString&); private: void init(); void initActions(); void initMenus(); void setColorPalette(const KConfig&); const XYCurve* currentCurve() const; CartesianPlotLegend* m_legend; double m_zoomFactor; QList m_themeColorPalette; bool m_menusInitialized; QAction* visibilityAction; //"add new" actions QAction* addCurveAction; QAction* addEquationCurveAction; QAction* addHistogramPlot; QAction* addDataReductionCurveAction; QAction* addDifferentiationCurveAction; QAction* addIntegrationCurveAction; QAction* addInterpolationCurveAction; QAction* addSmoothCurveAction; QAction* addFitCurveAction; QAction* addFourierFilterCurveAction; QAction* addFourierTransformCurveAction; QAction* addHorizontalAxisAction; QAction* addVerticalAxisAction; QAction* addLegendAction; QAction* addCustomPointAction; //scaling, zooming, navigation actions QAction* scaleAutoXAction; QAction* scaleAutoYAction; QAction* scaleAutoAction; QAction* zoomInAction; QAction* zoomOutAction; QAction* zoomInXAction; QAction* zoomOutXAction; QAction* zoomInYAction; QAction* zoomOutYAction; QAction* shiftLeftXAction; QAction* shiftRightXAction; QAction* shiftUpYAction; QAction* shiftDownYAction; //analysis menu actions QAction* addDataOperationAction; QAction* addDataReductionAction; QAction* addDifferentiationAction; QAction* addIntegrationAction; QAction* addInterpolationAction; QAction* addSmoothAction; QVector addFitAction; QAction* addFourierFilterAction; QMenu* addNewMenu; QMenu* zoomMenu; QMenu* dataAnalysisMenu; QMenu* themeMenu; Q_DECLARE_PRIVATE(CartesianPlot) public slots: void addHorizontalAxis(); void addVerticalAxis(); void addCurve(); void addHistogram(); void addEquationCurve(); void addDataReductionCurve(); void addDifferentiationCurve(); void addIntegrationCurve(); void addInterpolationCurve(); void addSmoothCurve(); void addFitCurve(); void addFourierFilterCurve(); void addFourierTransformCurve(); void addLegend(); void addCustomPoint(); void scaleAuto(); void scaleAutoX(); void scaleAutoY(); void zoomIn(); void zoomOut(); void zoomInX(); void zoomOutX(); void zoomInY(); void zoomOutY(); void shiftLeftX(); void shiftRightX(); void shiftUpY(); void shiftDownY(); void dataChanged(); private slots: void updateLegend(); void childAdded(const AbstractAspect*); void childRemoved(const AbstractAspect* parent, const AbstractAspect* before, const AbstractAspect* child); void xDataChanged(); void yDataChanged(); void HistogramdataChanged(); void xHistogramDataChanged(); void yHistogramDataChanged(); void curveVisibilityChanged(); //SLOTs for changes triggered via QActions in the context menu void visibilityChanged(); void loadTheme(const QString&); protected: CartesianPlot(const QString &name, CartesianPlotPrivate *dd); signals: friend class CartesianPlotSetCRangeTypeCmd; friend class CartesianPlotSetCRangeLastValuesCmd; friend class CartesianPlotSetCRangeFirstValuesCmd; friend class CartesianPlotSetRectCmd; friend class CartesianPlotSetAutoScaleXCmd; friend class CartesianPlotSetXMinCmd; friend class CartesianPlotSetXMaxCmd; friend class CartesianPlotSetXScaleCmd; friend class CartesianPlotSetAutoScaleYCmd; friend class CartesianPlotSetYMinCmd; friend class CartesianPlotSetYMaxCmd; friend class CartesianPlotSetYScaleCmd; friend class CartesianPlotSetXRangeBreakingEnabledCmd; friend class CartesianPlotSetYRangeBreakingEnabledCmd; friend class CartesianPlotSetXRangeBreaksCmd; friend class CartesianPlotSetYRangeBreaksCmd; friend class CartesianPlotSetThemeCmd; void rangeTypeChanged(CartesianPlot::RangeType); void rangeLastValuesChanged(int); void rangeFirstValuesChanged(int); void rectChanged(QRectF&); void xAutoScaleChanged(bool); void xMinChanged(double); void xMaxChanged(double); void xScaleChanged(int); void yAutoScaleChanged(bool); void yMinChanged(double); void yMaxChanged(double); void yScaleChanged(int); void xRangeBreakingEnabledChanged(bool); void xRangeBreaksChanged(const CartesianPlot::RangeBreaks&); void yRangeBreakingEnabledChanged(bool); void yRangeBreaksChanged(const CartesianPlot::RangeBreaks&); void themeChanged(const QString&); }; #endif diff --git a/src/backend/worksheet/plots/cartesian/CartesianPlotLegend.h b/src/backend/worksheet/plots/cartesian/CartesianPlotLegend.h index 9494f3a67..0ff2c6234 100644 --- a/src/backend/worksheet/plots/cartesian/CartesianPlotLegend.h +++ b/src/backend/worksheet/plots/cartesian/CartesianPlotLegend.h @@ -1,170 +1,170 @@ /*************************************************************************** File : CartesianPlotLegend.h Project : LabPlot Description : Legend for the cartesian plot -------------------------------------------------------------------- Copyright : (C) 2013-2017 Alexander Semke (alexander.semke@web.de) ***************************************************************************/ /*************************************************************************** * * * 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 CARTESIANPLOTLEGEND_H #define CARTESIANPLOTLEGEND_H #include "backend/worksheet/WorksheetElement.h" #include "backend/worksheet/plots/PlotArea.h" #include "backend/lib/macros.h" class CartesianPlot; class CartesianPlotLegendPrivate; class TextLabel; class CartesianPlotLegend : public WorksheetElement { Q_OBJECT Q_ENUMS(HorizontalPosition) Q_ENUMS(VerticalPosition) public: enum HorizontalPosition {hPositionLeft, hPositionCenter, hPositionRight, hPositionCustom}; enum VerticalPosition {vPositionTop, vPositionCenter, vPositionBottom, vPositionCustom}; struct PositionWrapper { QPointF point; HorizontalPosition horizontalPosition; VerticalPosition verticalPosition; }; CartesianPlotLegend(CartesianPlot* parentPlot, const QString &name); - virtual ~CartesianPlotLegend(); + ~CartesianPlotLegend() override; - virtual QIcon icon() const override; - virtual QMenu* createContextMenu() override; - virtual QGraphicsItem* graphicsItem() const override; - virtual void save(QXmlStreamWriter*) const override; - virtual bool load(XmlStreamReader*, bool preview) override; - virtual void loadThemeConfig(const KConfig& config) override; + QIcon icon() const override; + QMenu* createContextMenu() override; + QGraphicsItem* graphicsItem() const override; + void save(QXmlStreamWriter*) const override; + bool load(XmlStreamReader*, bool preview) override; + void loadThemeConfig(const KConfig& config) override; - virtual void setVisible(bool) override; - virtual bool isVisible() const override; - virtual void setPrinting(bool) override; + void setVisible(bool) override; + bool isVisible() const override; + void setPrinting(bool) override; TextLabel* title(); CLASS_D_ACCESSOR_DECL(QFont, labelFont, LabelFont) CLASS_D_ACCESSOR_DECL(QColor, labelColor, LabelColor) BASIC_D_ACCESSOR_DECL(bool, labelColumnMajor, LabelColumnMajor) CLASS_D_ACCESSOR_DECL(PositionWrapper, position, Position); BASIC_D_ACCESSOR_DECL(float, lineSymbolWidth, LineSymbolWidth) BASIC_D_ACCESSOR_DECL(float, backgroundOpacity, BackgroundOpacity) BASIC_D_ACCESSOR_DECL(PlotArea::BackgroundType, backgroundType, BackgroundType) BASIC_D_ACCESSOR_DECL(PlotArea::BackgroundColorStyle, backgroundColorStyle, BackgroundColorStyle) BASIC_D_ACCESSOR_DECL(PlotArea::BackgroundImageStyle, backgroundImageStyle, BackgroundImageStyle) BASIC_D_ACCESSOR_DECL(Qt::BrushStyle, backgroundBrushStyle, BackgroundBrushStyle) CLASS_D_ACCESSOR_DECL(QColor, backgroundFirstColor, BackgroundFirstColor) CLASS_D_ACCESSOR_DECL(QColor, backgroundSecondColor, BackgroundSecondColor) CLASS_D_ACCESSOR_DECL(QString, backgroundFileName, BackgroundFileName) CLASS_D_ACCESSOR_DECL(QPen, borderPen, BorderPen) BASIC_D_ACCESSOR_DECL(float, borderCornerRadius, BorderCornerRadius) BASIC_D_ACCESSOR_DECL(float, borderOpacity, BorderOpacity) BASIC_D_ACCESSOR_DECL(float, layoutTopMargin, LayoutTopMargin) BASIC_D_ACCESSOR_DECL(float, layoutBottomMargin, LayoutBottomMargin) BASIC_D_ACCESSOR_DECL(float, layoutLeftMargin, LayoutLeftMargin) BASIC_D_ACCESSOR_DECL(float, layoutRightMargin, LayoutRightMargin) BASIC_D_ACCESSOR_DECL(float, layoutHorizontalSpacing, LayoutHorizontalSpacing) BASIC_D_ACCESSOR_DECL(float, layoutVerticalSpacing, LayoutVerticalSpacing) BASIC_D_ACCESSOR_DECL(int, layoutColumnCount, LayoutColumnCount) - virtual void retransform() override; - virtual void handleResize(double horizontalRatio, double verticalRatio, bool pageResize) override; + void retransform() override; + void handleResize(double horizontalRatio, double verticalRatio, bool pageResize) override; typedef CartesianPlotLegendPrivate Private; protected: CartesianPlotLegend(CartesianPlot*, const QString& name, CartesianPlotLegendPrivate* dd); CartesianPlotLegendPrivate* const d_ptr; private: Q_DECLARE_PRIVATE(CartesianPlotLegend) void init(); void initActions(); CartesianPlot* m_plot; QAction* visibilityAction; private slots: //SLOTs for changes triggered via QActions in the context menu void visibilityChangedSlot(); signals: friend class CartesianPlotLegendSetLabelFontCmd; friend class CartesianPlotLegendSetLabelColorCmd; friend class CartesianPlotLegendSetLabelColumnMajorCmd; friend class CartesianPlotLegendSetLineSymbolWidthCmd; friend class CartesianPlotLegendSetPositionCmd; friend class CartesianPlotLegendSetBackgroundTypeCmd; friend class CartesianPlotLegendSetBackgroundColorStyleCmd; friend class CartesianPlotLegendSetBackgroundImageStyleCmd; friend class CartesianPlotLegendSetBackgroundBrushStyleCmd; friend class CartesianPlotLegendSetBackgroundFirstColorCmd; friend class CartesianPlotLegendSetBackgroundSecondColorCmd; friend class CartesianPlotLegendSetBackgroundFileNameCmd; friend class CartesianPlotLegendSetBackgroundOpacityCmd; friend class CartesianPlotLegendSetBorderPenCmd; friend class CartesianPlotLegendSetBorderCornerRadiusCmd; friend class CartesianPlotLegendSetBorderOpacityCmd; friend class CartesianPlotLegendSetLayoutTopMarginCmd; friend class CartesianPlotLegendSetLayoutBottomMarginCmd; friend class CartesianPlotLegendSetLayoutLeftMarginCmd; friend class CartesianPlotLegendSetLayoutRightMarginCmd; friend class CartesianPlotLegendSetLayoutVerticalSpacingCmd; friend class CartesianPlotLegendSetLayoutHorizontalSpacingCmd; friend class CartesianPlotLegendSetLayoutColumnCountCmd; void labelFontChanged(QFont&); void labelColorChanged(QColor&); void labelColumnMajorChanged(bool); void lineSymbolWidthChanged(float); void positionChanged(const CartesianPlotLegend::PositionWrapper&); void backgroundTypeChanged(PlotArea::BackgroundType); void backgroundColorStyleChanged(PlotArea::BackgroundColorStyle); void backgroundImageStyleChanged(PlotArea::BackgroundImageStyle); void backgroundBrushStyleChanged(Qt::BrushStyle); void backgroundFirstColorChanged(QColor&); void backgroundSecondColorChanged(QColor&); void backgroundFileNameChanged(QString&); void backgroundOpacityChanged(float); void borderPenChanged(QPen&); void borderCornerRadiusChanged(float); void borderOpacityChanged(float); void layoutTopMarginChanged(float); void layoutBottomMarginChanged(float); void layoutLeftMarginChanged(float); void layoutRightMarginChanged(float); void layoutVerticalSpacingChanged(float); void layoutHorizontalSpacingChanged(float); void layoutColumnCountChanged(int); void positionChanged(QPointF&); void visibilityChanged(bool); }; #endif diff --git a/src/backend/worksheet/plots/cartesian/CartesianPlotLegendPrivate.h b/src/backend/worksheet/plots/cartesian/CartesianPlotLegendPrivate.h index 55a7b8932..4420633b8 100644 --- a/src/backend/worksheet/plots/cartesian/CartesianPlotLegendPrivate.h +++ b/src/backend/worksheet/plots/cartesian/CartesianPlotLegendPrivate.h @@ -1,105 +1,105 @@ /*************************************************************************** File : CartesianPlotLegendPrivate.h Project : LabPlot Description : Private members of CartesianPlotLegend -------------------------------------------------------------------- Copyright : (C) 2013 by Alexander Semke (alexander.semke@web.de) ***************************************************************************/ /*************************************************************************** * * * 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 CARTESIANPLOTLEGENDPRIVATE_H #define CARTESIANPLOTLEGENDPRIVATE_H #include #include #include #include class CartesianPlotLegend; class XYCurve; class QGraphicsSceneContextMenuEvent; class CartesianPlotLegendPrivate : public QGraphicsItem { public: explicit CartesianPlotLegendPrivate(CartesianPlotLegend* owner); CartesianPlotLegend* const q; QString name() const; bool swapVisible(bool on); void retransform(); void updatePosition(); //QGraphicsItem's virtual functions - virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); - virtual QRectF boundingRect() const; - virtual QPainterPath shape() const; - virtual QVariant itemChange(GraphicsItemChange change, const QVariant &value); - virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent*); + void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override; + QRectF boundingRect() const override; + QPainterPath shape() const override; + QVariant itemChange(GraphicsItemChange change, const QVariant &value) override; + void mouseReleaseEvent(QGraphicsSceneMouseEvent*) override; bool suppressItemChangeEvent; bool suppressRetransform; bool m_printing; bool m_hovered; QList curvesList; //list containing all visible curves QRectF rect; QFont labelFont; QColor labelColor; bool labelColumnMajor; CartesianPlotLegend::PositionWrapper position; //position in parent's coordinate system float lineSymbolWidth; //the width of line+symbol QList maxColumnTextWidths; //the maximal width of the text within each column int columnCount; //the actual number of columns, can be smaller then the specified layoutColumnCount int rowCount; //the number of rows in the legend, depends on the number of curves and on columnCount TextLabel* title; //Background PlotArea::BackgroundType backgroundType; PlotArea::BackgroundColorStyle backgroundColorStyle; PlotArea::BackgroundImageStyle backgroundImageStyle; Qt::BrushStyle backgroundBrushStyle; QColor backgroundFirstColor; QColor backgroundSecondColor; QString backgroundFileName; float backgroundOpacity; //Border QPen borderPen; qreal borderCornerRadius; qreal borderOpacity; //Layout float layoutTopMargin; float layoutBottomMargin; float layoutLeftMargin; float layoutRightMargin; float layoutVerticalSpacing; float layoutHorizontalSpacing; int layoutColumnCount; private: - void contextMenuEvent(QGraphicsSceneContextMenuEvent*); - virtual void hoverEnterEvent(QGraphicsSceneHoverEvent*); - virtual void hoverLeaveEvent(QGraphicsSceneHoverEvent*); + void contextMenuEvent(QGraphicsSceneContextMenuEvent*) override; + void hoverEnterEvent(QGraphicsSceneHoverEvent*) override; + void hoverLeaveEvent(QGraphicsSceneHoverEvent*) override; }; #endif diff --git a/src/backend/worksheet/plots/cartesian/CartesianPlotPrivate.h b/src/backend/worksheet/plots/cartesian/CartesianPlotPrivate.h index 893db5250..755f2886d 100644 --- a/src/backend/worksheet/plots/cartesian/CartesianPlotPrivate.h +++ b/src/backend/worksheet/plots/cartesian/CartesianPlotPrivate.h @@ -1,92 +1,92 @@ /*************************************************************************** File : CartesianPlotPrivate.h Project : LabPlot Description : Private members of CartesianPlot. -------------------------------------------------------------------- Copyright : (C) 2014-2017 Alexander Semke (alexander.semke@web.de) *******************************************************7*******************/ /*************************************************************************** * * * 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 CARTESIANPLOTPRIVATE_H #define CARTESIANPLOTPRIVATE_H #include "CartesianPlot.h" #include "CartesianCoordinateSystem.h" #include "backend/worksheet/plots/AbstractPlotPrivate.h" #include class CartesianPlotPrivate : public AbstractPlotPrivate { public: explicit CartesianPlotPrivate(CartesianPlot*); - void retransform(); + void retransform() override; void retransformScales(); void rangeChanged(); CartesianPlot::RangeType rangeType; int rangeFirstValues; int rangeLastValues; double xMin, xMax, yMin, yMax; float xMinPrev, xMaxPrev, yMinPrev, yMaxPrev; bool autoScaleX, autoScaleY; float autoScaleOffsetFactor; CartesianPlot::Scale xScale, yScale; bool xRangeBreakingEnabled; bool yRangeBreakingEnabled; CartesianPlot::RangeBreaks xRangeBreaks; CartesianPlot::RangeBreaks yRangeBreaks; QString theme; //cached values of minimum and maximum for all visible curves bool curvesXMinMaxIsDirty, curvesYMinMaxIsDirty; double curvesXMin, curvesXMax, curvesYMin, curvesYMax; CartesianPlot* const q; CartesianPlot::MouseMode mouseMode; CartesianCoordinateSystem* cSystem; bool suppressRetransform; private: - virtual QVariant itemChange(GraphicsItemChange change, const QVariant &value); - virtual void mousePressEvent(QGraphicsSceneMouseEvent*); - virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent*); - virtual void mouseMoveEvent(QGraphicsSceneMouseEvent*); - virtual void wheelEvent(QGraphicsSceneWheelEvent*); - virtual void hoverMoveEvent(QGraphicsSceneHoverEvent*); - virtual void paint(QPainter*, const QStyleOptionGraphicsItem*, QWidget* widget = nullptr); + QVariant itemChange(GraphicsItemChange change, const QVariant &value) override; + void mousePressEvent(QGraphicsSceneMouseEvent*) override; + void mouseReleaseEvent(QGraphicsSceneMouseEvent*) override; + void mouseMoveEvent(QGraphicsSceneMouseEvent*) override; + void wheelEvent(QGraphicsSceneWheelEvent*) override; + void hoverMoveEvent(QGraphicsSceneHoverEvent*) override; + void paint(QPainter*, const QStyleOptionGraphicsItem*, QWidget* widget = nullptr) override; void checkXRange(); void checkYRange(); CartesianScale* createScale(CartesianPlot::Scale type, double sceneStart, double sceneEnd, double logicalStart, double logicalEnd); // bool m_printing; bool m_selectionBandIsShown; QPointF m_selectionStart; QPointF m_selectionEnd; QLineF m_selectionStartLine; }; #endif diff --git a/src/backend/worksheet/plots/cartesian/CustomPoint.h b/src/backend/worksheet/plots/cartesian/CustomPoint.h index c77db1c54..459dacdb6 100644 --- a/src/backend/worksheet/plots/cartesian/CustomPoint.h +++ b/src/backend/worksheet/plots/cartesian/CustomPoint.h @@ -1,106 +1,106 @@ /*************************************************************************** File : CustomPoint.h Project : LabPlot Description : Custom user-defined point on the plot -------------------------------------------------------------------- Copyright : (C) 2015 Ankit Wagadre (wagadre.ankit@gmail.com) Copyright : (C) 2015 Alexander Semke (alexander.semke@web.de) ***************************************************************************/ /*************************************************************************** * * * 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 CUSTOMPOINT_H #define CUSTOMPOINT_H #include #include #include "backend/lib/macros.h" #include "backend/worksheet/plots/cartesian/Symbol.h" #include "backend/worksheet/WorksheetElement.h" class CustomPointPrivate; class CartesianPlot; class CustomPoint : public WorksheetElement { Q_OBJECT public: explicit CustomPoint(const CartesianPlot*, const QString&); - ~CustomPoint(); + ~CustomPoint() override; - virtual QIcon icon() const override; - virtual QMenu* createContextMenu() override; - virtual QGraphicsItem* graphicsItem() const override; + QIcon icon() const override; + QMenu* createContextMenu() override; + QGraphicsItem* graphicsItem() const override; - virtual void save(QXmlStreamWriter*) const override; - virtual bool load(XmlStreamReader*, bool preview) override; + void save(QXmlStreamWriter*) const override; + bool load(XmlStreamReader*, bool preview) override; CLASS_D_ACCESSOR_DECL(QPointF, position, Position) BASIC_D_ACCESSOR_DECL(Symbol::Style, symbolStyle, SymbolStyle) BASIC_D_ACCESSOR_DECL(qreal, symbolOpacity, SymbolOpacity) BASIC_D_ACCESSOR_DECL(qreal, symbolRotationAngle, SymbolRotationAngle) BASIC_D_ACCESSOR_DECL(qreal, symbolSize, SymbolSize) CLASS_D_ACCESSOR_DECL(QBrush, symbolBrush, SymbolBrush) CLASS_D_ACCESSOR_DECL(QPen, symbolPen, SymbolPen) - virtual void setVisible(bool on) override; - virtual bool isVisible() const override; - virtual void setPrinting(bool) override; + void setVisible(bool on) override; + bool isVisible() const override; + void setPrinting(bool) override; - virtual void retransform() override; - virtual void handleResize(double horizontalRatio, double verticalRatio, bool pageResize) override; + void retransform() override; + void handleResize(double horizontalRatio, double verticalRatio, bool pageResize) override; typedef CustomPointPrivate Private; private slots: void visibilityChanged(); protected: CustomPointPrivate* const d_ptr; CustomPoint(const QString& name, CustomPointPrivate* dd); private: Q_DECLARE_PRIVATE(CustomPoint) void init(); void initActions(); QAction* visibilityAction; signals: friend class CustomPointSetPositionCmd; void positionChanged(const QPointF&); void visibleChanged(bool); void changed(); friend class CustomPointSetSymbolStyleCmd; friend class CustomPointSetSymbolSizeCmd; friend class CustomPointSetSymbolRotationAngleCmd; friend class CustomPointSetSymbolOpacityCmd; friend class CustomPointSetSymbolBrushCmd; friend class CustomPointSetSymbolPenCmd; void symbolStyleChanged(Symbol::Style); void symbolSizeChanged(qreal); void symbolRotationAngleChanged(qreal); void symbolOpacityChanged(qreal); void symbolBrushChanged(QBrush); void symbolPenChanged(const QPen&); }; #endif diff --git a/src/backend/worksheet/plots/cartesian/CustomPointPrivate.h b/src/backend/worksheet/plots/cartesian/CustomPointPrivate.h index 9159cd046..e31a745ce 100644 --- a/src/backend/worksheet/plots/cartesian/CustomPointPrivate.h +++ b/src/backend/worksheet/plots/cartesian/CustomPointPrivate.h @@ -1,83 +1,83 @@ /*************************************************************************** File : CustomPointPrivate.h Project : LabPlot Description : Custom user-defined point on the plot -------------------------------------------------------------------- Copyright : (C) 2015 Ankit Wagadre (wagadre.ankit@gmail.com) Copyright : (C) 2015 Alexander Semke (alexander.semke@web.de) ***************************************************************************/ /*************************************************************************** * * * 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 CUSTOMPOINTPRIVATE_H #define CUSTOMPOINTPRIVATE_H #include class CustomPointPrivate: public QGraphicsItem { public: explicit CustomPointPrivate(CustomPoint*, const CartesianPlot*); const CartesianPlot* plot; QString name() const; void retransform(); bool swapVisible(bool); virtual void recalcShapeAndBoundingRect(); void updatePosition(); void updateData(); bool suppressItemChangeEvent; bool suppressRetransform; bool m_printing; bool m_hovered; bool m_visible; //point inside the plot (visible) or not QRectF boundingRectangle; QRectF transformedBoundingRectangle; QPainterPath pointShape; QPointF position; //position in plot coordinates QPointF positionScene; //position in scene coordinatates //symbol Symbol::Style symbolStyle; QBrush symbolBrush; QPen symbolPen; qreal symbolOpacity; qreal symbolRotationAngle; qreal symbolSize; //reimplemented from QGraphicsItem - virtual QRectF boundingRect() const; - virtual QPainterPath shape() const; - virtual void paint(QPainter*, const QStyleOptionGraphicsItem*, QWidget* widget = 0); - virtual QVariant itemChange(GraphicsItemChange change, const QVariant& value); + QRectF boundingRect() const override; + QPainterPath shape() const override; + void paint(QPainter*, const QStyleOptionGraphicsItem*, QWidget* widget = 0) override; + QVariant itemChange(GraphicsItemChange change, const QVariant& value) override; CustomPoint* const q; private: - virtual void contextMenuEvent(QGraphicsSceneContextMenuEvent*); - virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent*); - virtual void hoverEnterEvent(QGraphicsSceneHoverEvent*); - virtual void hoverLeaveEvent(QGraphicsSceneHoverEvent*); + void contextMenuEvent(QGraphicsSceneContextMenuEvent*) override; + void mouseReleaseEvent(QGraphicsSceneMouseEvent*) override; + void hoverEnterEvent(QGraphicsSceneHoverEvent*) override; + void hoverLeaveEvent(QGraphicsSceneHoverEvent*) override; }; #endif diff --git a/src/backend/worksheet/plots/cartesian/Histogram.h b/src/backend/worksheet/plots/cartesian/Histogram.h index 4afcebb92..5b06f096d 100644 --- a/src/backend/worksheet/plots/cartesian/Histogram.h +++ b/src/backend/worksheet/plots/cartesian/Histogram.h @@ -1,199 +1,199 @@ /*************************************************************************** File : Histogram.h Project : LabPlot Description : Histogram -------------------------------------------------------------------- Copyright : (C) 2016 Anu Mittal (anu22mittal@gmail.com) ***************************************************************************/ /*************************************************************************** * * * 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 HISTOGRAM_H #define HISTOGRAM_H #include "backend/worksheet/WorksheetElement.h" #include "backend/worksheet/plots/PlotArea.h" #include "backend/core/AbstractColumn.h" #include "backend/lib/macros.h" class HistogramPrivate; class Histogram: public WorksheetElement { Q_OBJECT public: enum BinsOption {Number,Width,SquareRoot,RiceRule,SturgisRule}; enum ValuesType {NoValues, ValuesY, ValuesYBracketed, ValuesCustomColumn}; enum ValuesPosition {ValuesAbove, ValuesUnder, ValuesLeft, ValuesRight}; enum FillingPosition {NoFilling, FillingAbove, FillingBelow, FillingZeroBaseline, FillingLeft, FillingRight}; enum HistogramType {Ordinary,Cumulative, AvgShift}; struct HistogramData { HistogramData() : type(Ordinary),binsOption(Number), binValue(10) {}; HistogramType type; BinsOption binsOption; int binValue; }; explicit Histogram(const QString &name); //size_t bins; - virtual QIcon icon() const override; - virtual QMenu* createContextMenu() override; - virtual QGraphicsItem* graphicsItem() const override; - virtual void save(QXmlStreamWriter*) const override; - virtual bool load(XmlStreamReader*, bool preview) override; + QIcon icon() const override; + QMenu* createContextMenu() override; + QGraphicsItem* graphicsItem() const override; + void save(QXmlStreamWriter*) const override; + bool load(XmlStreamReader*, bool preview) override; CLASS_D_ACCESSOR_DECL(HistogramData, histogramData, HistogramData) POINTER_D_ACCESSOR_DECL(const AbstractColumn, xColumn, XColumn) POINTER_D_ACCESSOR_DECL(const AbstractColumn, yColumn, YColumn) QString& xColumnPath() const; QString& yColumnPath() const; BASIC_D_ACCESSOR_DECL(float, xMin, XMin) BASIC_D_ACCESSOR_DECL(float, xMax, XMax) BASIC_D_ACCESSOR_DECL(float, yMin, YMin) BASIC_D_ACCESSOR_DECL(float, yMax, YMax) BASIC_D_ACCESSOR_DECL(ValuesType, valuesType, ValuesType) POINTER_D_ACCESSOR_DECL(const AbstractColumn, valuesColumn, ValuesColumn) QString& valuesColumnPath() const; CLASS_D_ACCESSOR_DECL(QPen, linePen, LinePen) BASIC_D_ACCESSOR_DECL(ValuesPosition, valuesPosition, ValuesPosition) BASIC_D_ACCESSOR_DECL(qreal, valuesDistance, ValuesDistance) BASIC_D_ACCESSOR_DECL(qreal, valuesRotationAngle, ValuesRotationAngle) BASIC_D_ACCESSOR_DECL(qreal, valuesOpacity, ValuesOpacity) CLASS_D_ACCESSOR_DECL(QString, valuesPrefix, ValuesPrefix) CLASS_D_ACCESSOR_DECL(QString, valuesSuffix, ValuesSuffix) CLASS_D_ACCESSOR_DECL(QColor, valuesColor, ValuesColor) CLASS_D_ACCESSOR_DECL(QFont, valuesFont, ValuesFont) BASIC_D_ACCESSOR_DECL(FillingPosition, fillingPosition, FillingPosition) BASIC_D_ACCESSOR_DECL(PlotArea::BackgroundType, fillingType, FillingType) BASIC_D_ACCESSOR_DECL(PlotArea::BackgroundColorStyle, fillingColorStyle, FillingColorStyle) BASIC_D_ACCESSOR_DECL(PlotArea::BackgroundImageStyle, fillingImageStyle, FillingImageStyle) BASIC_D_ACCESSOR_DECL(Qt::BrushStyle, fillingBrushStyle, FillingBrushStyle) CLASS_D_ACCESSOR_DECL(QColor, fillingFirstColor, FillingFirstColor) CLASS_D_ACCESSOR_DECL(QColor, fillingSecondColor, FillingSecondColor) CLASS_D_ACCESSOR_DECL(QString, fillingFileName, FillingFileName) BASIC_D_ACCESSOR_DECL(qreal, fillingOpacity, FillingOpacity) - virtual void setVisible(bool on) override; - virtual bool isVisible() const override; - virtual void setPrinting(bool on) override; + void setVisible(bool on) override; + bool isVisible() const override; + void setPrinting(bool on) override; void suppressRetransform(bool); double getYMaximum() const; void setHistrogramType(Histogram::HistogramType); Histogram::HistogramType getHistrogramType(); void setbinsOption(Histogram::BinsOption); void setBinValue(int); typedef WorksheetElement BaseClass; typedef HistogramPrivate Private; bool isSourceDataChangedSinceLastPlot() const; public slots: - virtual void retransform() override; - virtual void handleResize(double horizontalRatio, double verticalRatio, bool pageResize) override; + void retransform() override; + void handleResize(double horizontalRatio, double verticalRatio, bool pageResize) override; private slots: void updateValues(); void xColumnAboutToBeRemoved(const AbstractAspect*); void valuesColumnAboutToBeRemoved(const AbstractAspect*); //SLOTs for changes triggered via QActions in the context menu void visibilityChangedSlot(); void handleSourceDataChanged(); protected: Histogram(const QString& name, HistogramPrivate* dd); HistogramPrivate* const d_ptr; private: Q_DECLARE_PRIVATE(Histogram) void init(); void initActions(); QAction* visibilityAction; signals: //General-Tab void HistogramdataChanged(); void xHistogramDataChanged(); void yHistogramDataChanged(); void visibilityChanged(bool); friend class HistogramSetXColumnCmd; friend class HistogramSetYColumnCmd; friend class HistogramSetLinePenCmd; void xColumnChanged(const AbstractColumn*); void yColumnChanged(const AbstractColumn*); //Values-Tab friend class HistogramSetValuesColumnCmd; friend class HistogramSetValuesTypeCmd; friend class HistogramSetValuesPositionCmd; friend class HistogramSetValuesDistanceCmd; friend class HistogramSetValuesRotationAngleCmd; friend class HistogramSetValuesOpacityCmd; friend class HistogramSetValuesPrefixCmd; friend class HistogramSetValuesSuffixCmd; friend class HistogramSetValuesFontCmd; friend class HistogramSetValuesColorCmd; void valuesTypeChanged(Histogram::ValuesType); void valuesColumnChanged(const AbstractColumn*); void valuesPositionChanged(Histogram::ValuesPosition); void valuesDistanceChanged(qreal); void valuesRotationAngleChanged(qreal); void valuesOpacityChanged(qreal); void valuesPrefixChanged(QString); void valuesSuffixChanged(QString); void valuesFontChanged(QFont); void valuesColorChanged(QColor); void linePenChanged(const QPen&); //Filling friend class HistogramSetFillingPositionCmd; friend class HistogramSetFillingTypeCmd; friend class HistogramSetFillingColorStyleCmd; friend class HistogramSetFillingImageStyleCmd; friend class HistogramSetFillingBrushStyleCmd; friend class HistogramSetFillingFirstColorCmd; friend class HistogramSetFillingSecondColorCmd; friend class HistogramSetFillingFileNameCmd; friend class HistogramSetFillingOpacityCmd; void fillingPositionChanged(Histogram::FillingPosition); void fillingTypeChanged(PlotArea::BackgroundType); void fillingColorStyleChanged(PlotArea::BackgroundColorStyle); void fillingImageStyleChanged(PlotArea::BackgroundImageStyle); void fillingBrushStyleChanged(Qt::BrushStyle); void fillingFirstColorChanged(QColor&); void fillingSecondColorChanged(QColor&); void fillingFileNameChanged(QString&); void fillingOpacityChanged(float); friend class HistogramSetDataCmd; void histogramDataChanged(const Histogram::HistogramData&); void sourceDataChangedSinceLastPlot(); }; #endif diff --git a/src/backend/worksheet/plots/cartesian/HistogramPrivate.h b/src/backend/worksheet/plots/cartesian/HistogramPrivate.h index 5f6aed204..cfb8956fe 100644 --- a/src/backend/worksheet/plots/cartesian/HistogramPrivate.h +++ b/src/backend/worksheet/plots/cartesian/HistogramPrivate.h @@ -1,151 +1,151 @@ /*************************************************************************** File : HistogramPrivate.h Project : LabPlot Description : Private members of Histogram -------------------------------------------------------------------- Copyright : (C) 2016 Anu Mittal (anu22mittal@gmail.com) ***************************************************************************/ /*************************************************************************** * * * 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 HISTOGRAMPRIVATE_H #define HISTOGRAMPRIVATE_H #include #include #include #include extern "C" { #include } class HistogramPrivate : public QGraphicsItem { public: explicit HistogramPrivate(Histogram *owner); QString name() const; - virtual QRectF boundingRect() const; - QPainterPath shape() const; + QRectF boundingRect() const override; + QPainterPath shape() const override; bool m_printing; bool m_hovered; bool m_suppressRecalc; bool m_suppressRetransform; QPixmap m_pixmap; QImage m_hoverEffectImage; QImage m_selectionEffectImage; bool m_hoverEffectImageIsDirty; bool m_selectionEffectImageIsDirty; void retransform(); void updateLines(); void updateValues(); void updateFilling(); bool swapVisible(bool on); void recalcShapeAndBoundingRect(); void drawSymbols(QPainter*); void drawValues(QPainter*); void drawFilling(QPainter*); void draw(QPainter*); void updatePixmap(); double getYMaximum(); bool autoScaleX, autoScaleY; Histogram::HistogramType histogramType; Histogram::BinsOption binsOption; - virtual void paint(QPainter*, const QStyleOptionGraphicsItem*, QWidget* widget = 0); + void paint(QPainter*, const QStyleOptionGraphicsItem*, QWidget* widget = 0) override; //data columns const AbstractColumn* xColumn; QString xColumnPath; QString yColumnPath; void recalculate(); Histogram::HistogramData histogramData; //line bool lineSkipGaps; int lineInterpolationPointsCount; QPen linePen; qreal lineOpacity; //values int value; Histogram::ValuesType valuesType; const AbstractColumn* valuesColumn; QString valuesColumnPath; Histogram::ValuesPosition valuesPosition; qreal valuesDistance; qreal valuesRotationAngle; qreal valuesOpacity; QString valuesPrefix; QString valuesSuffix; QFont valuesFont; QColor valuesColor; //filling Histogram::FillingPosition fillingPosition; PlotArea::BackgroundType fillingType; PlotArea::BackgroundColorStyle fillingColorStyle; PlotArea::BackgroundImageStyle fillingImageStyle; Qt::BrushStyle fillingBrushStyle; QColor fillingFirstColor; QColor fillingSecondColor; QString fillingFileName; qreal fillingOpacity; QPainterPath linePath; //long long int bins; QPainterPath valuesPath; QRectF boundingRectangle; QPainterPath curveShape; QVector lines; QVector symbolPointsLogical; //points in logical coordinates QVector symbolPointsScene; //points in scene coordinates std::vector visiblePoints; //vector of the size of symbolPointsLogical with true of false for the points currently visible or not in the plot QVector valuesPoints; std::vector connectedPointsLogical; //vector of the size of symbolPointsLogical with true for points connected with the consecutive point and //false otherwise (don't connect because of a gap (NAN) in-between) QVector valuesStrings; QVector fillPolygons; //cached values of minimum and maximum for all visible curves bool curvesXMinMaxIsDirty, curvesYMinMaxIsDirty; double curvesXMin, curvesXMax, curvesYMin, curvesYMax; float xMin, xMax; float xMinPrev, xMaxPrev; bool autoScaleHistogramX; Histogram* const q; bool sourceDataChangedSinceLastPlot; // #include class XYCurvePrivate; class XYCurve: public WorksheetElement { Q_OBJECT public: enum LineType {NoLine, Line, StartHorizontal, StartVertical, MidpointHorizontal, MidpointVertical, Segments2, Segments3, SplineCubicNatural, SplineCubicPeriodic, SplineAkimaNatural, SplineAkimaPeriodic }; enum DropLineType {NoDropLine, DropLineX, DropLineY, DropLineXY, DropLineXZeroBaseline, DropLineXMinBaseline, DropLineXMaxBaseline}; enum ValuesType {NoValues, ValuesX, ValuesY, ValuesXY, ValuesXYBracketed, ValuesCustomColumn}; enum ValuesPosition {ValuesAbove, ValuesUnder, ValuesLeft, ValuesRight}; enum ErrorType {NoError, SymmetricError, AsymmetricError}; enum FillingPosition {NoFilling, FillingAbove, FillingBelow, FillingZeroBaseline, FillingLeft, FillingRight}; enum ErrorBarsType {ErrorBarsSimple, ErrorBarsWithEnds}; enum DataSourceType {DataSourceSpreadsheet, DataSourceCurve}; explicit XYCurve(const QString &name); - virtual ~XYCurve(); + ~XYCurve() override; - virtual QIcon icon() const override; - virtual QMenu* createContextMenu() override; - virtual QGraphicsItem* graphicsItem() const override; - virtual void save(QXmlStreamWriter*) const override; - virtual bool load(XmlStreamReader*, bool preview) override; - virtual void loadThemeConfig(const KConfig&) override; - virtual void saveThemeConfig(const KConfig&) override; + QIcon icon() const override; + QMenu* createContextMenu() override; + QGraphicsItem* graphicsItem() const override; + void save(QXmlStreamWriter*) const override; + bool load(XmlStreamReader*, bool preview) override; + void loadThemeConfig(const KConfig&) override; + void saveThemeConfig(const KConfig&) override; BASIC_D_ACCESSOR_DECL(DataSourceType, dataSourceType, DataSourceType) POINTER_D_ACCESSOR_DECL(const XYCurve, dataSourceCurve, DataSourceCurve) POINTER_D_ACCESSOR_DECL(const AbstractColumn, xColumn, XColumn) POINTER_D_ACCESSOR_DECL(const AbstractColumn, yColumn, YColumn) const QString& dataSourceCurvePath() const; const QString& xColumnPath() const; const QString& yColumnPath() const; BASIC_D_ACCESSOR_DECL(LineType, lineType, LineType) BASIC_D_ACCESSOR_DECL(bool, lineSkipGaps, LineSkipGaps) BASIC_D_ACCESSOR_DECL(int, lineInterpolationPointsCount, LineInterpolationPointsCount) CLASS_D_ACCESSOR_DECL(QPen, linePen, LinePen) BASIC_D_ACCESSOR_DECL(qreal, lineOpacity, LineOpacity) BASIC_D_ACCESSOR_DECL(DropLineType, dropLineType, DropLineType) CLASS_D_ACCESSOR_DECL(QPen, dropLinePen, DropLinePen) BASIC_D_ACCESSOR_DECL(qreal, dropLineOpacity, DropLineOpacity) BASIC_D_ACCESSOR_DECL(Symbol::Style, symbolsStyle, SymbolsStyle) BASIC_D_ACCESSOR_DECL(qreal, symbolsOpacity, SymbolsOpacity) BASIC_D_ACCESSOR_DECL(qreal, symbolsRotationAngle, SymbolsRotationAngle) BASIC_D_ACCESSOR_DECL(qreal, symbolsSize, SymbolsSize) CLASS_D_ACCESSOR_DECL(QBrush, symbolsBrush, SymbolsBrush) CLASS_D_ACCESSOR_DECL(QPen, symbolsPen, SymbolsPen) BASIC_D_ACCESSOR_DECL(ValuesType, valuesType, ValuesType) POINTER_D_ACCESSOR_DECL(const AbstractColumn, valuesColumn, ValuesColumn) const QString& valuesColumnPath() const; BASIC_D_ACCESSOR_DECL(ValuesPosition, valuesPosition, ValuesPosition) BASIC_D_ACCESSOR_DECL(qreal, valuesDistance, ValuesDistance) BASIC_D_ACCESSOR_DECL(qreal, valuesRotationAngle, ValuesRotationAngle) BASIC_D_ACCESSOR_DECL(qreal, valuesOpacity, ValuesOpacity) CLASS_D_ACCESSOR_DECL(QString, valuesPrefix, ValuesPrefix) CLASS_D_ACCESSOR_DECL(QString, valuesSuffix, ValuesSuffix) CLASS_D_ACCESSOR_DECL(QColor, valuesColor, ValuesColor) CLASS_D_ACCESSOR_DECL(QFont, valuesFont, ValuesFont) BASIC_D_ACCESSOR_DECL(FillingPosition, fillingPosition, FillingPosition) BASIC_D_ACCESSOR_DECL(PlotArea::BackgroundType, fillingType, FillingType) BASIC_D_ACCESSOR_DECL(PlotArea::BackgroundColorStyle, fillingColorStyle, FillingColorStyle) BASIC_D_ACCESSOR_DECL(PlotArea::BackgroundImageStyle, fillingImageStyle, FillingImageStyle) BASIC_D_ACCESSOR_DECL(Qt::BrushStyle, fillingBrushStyle, FillingBrushStyle) CLASS_D_ACCESSOR_DECL(QColor, fillingFirstColor, FillingFirstColor) CLASS_D_ACCESSOR_DECL(QColor, fillingSecondColor, FillingSecondColor) CLASS_D_ACCESSOR_DECL(QString, fillingFileName, FillingFileName) BASIC_D_ACCESSOR_DECL(qreal, fillingOpacity, FillingOpacity) BASIC_D_ACCESSOR_DECL(ErrorType, xErrorType, XErrorType) POINTER_D_ACCESSOR_DECL(const AbstractColumn, xErrorPlusColumn, XErrorPlusColumn) const QString& xErrorPlusColumnPath() const; POINTER_D_ACCESSOR_DECL(const AbstractColumn, xErrorMinusColumn, XErrorMinusColumn) const QString& xErrorMinusColumnPath() const; BASIC_D_ACCESSOR_DECL(ErrorType, yErrorType, YErrorType) POINTER_D_ACCESSOR_DECL(const AbstractColumn, yErrorPlusColumn, YErrorPlusColumn) const QString& yErrorPlusColumnPath() const; POINTER_D_ACCESSOR_DECL(const AbstractColumn, yErrorMinusColumn, YErrorMinusColumn) const QString& yErrorMinusColumnPath() const; BASIC_D_ACCESSOR_DECL(ErrorBarsType, errorBarsType, ErrorBarsType) BASIC_D_ACCESSOR_DECL(qreal, errorBarsCapSize, ErrorBarsCapSize) CLASS_D_ACCESSOR_DECL(QPen, errorBarsPen, ErrorBarsPen) BASIC_D_ACCESSOR_DECL(qreal, errorBarsOpacity, ErrorBarsOpacity) - virtual void setVisible(bool on) override; - virtual bool isVisible() const override; - virtual void setPrinting(bool on) override; + void setVisible(bool on) override; + bool isVisible() const override; + void setPrinting(bool on) override; void suppressRetransform(bool); bool isSourceDataChangedSinceLastRecalc() const; typedef XYCurvePrivate Private; - virtual void retransform() override; - virtual void handleResize(double horizontalRatio, double verticalRatio, bool pageResize) override; + void retransform() override; + void handleResize(double horizontalRatio, double verticalRatio, bool pageResize) override; public slots: void handleSourceDataChanged(); private slots: void updateValues(); void updateErrorBars(); void xColumnAboutToBeRemoved(const AbstractAspect*); void yColumnAboutToBeRemoved(const AbstractAspect*); void valuesColumnAboutToBeRemoved(const AbstractAspect*); void xErrorPlusColumnAboutToBeRemoved(const AbstractAspect*); void xErrorMinusColumnAboutToBeRemoved(const AbstractAspect*); void yErrorPlusColumnAboutToBeRemoved(const AbstractAspect*); void yErrorMinusColumnAboutToBeRemoved(const AbstractAspect*); //SLOTs for changes triggered via QActions in the context menu void visibilityChanged(); void navigateTo(); protected: XYCurve(const QString& name, XYCurvePrivate* dd); XYCurvePrivate* const d_ptr; private: Q_DECLARE_PRIVATE(XYCurve) void init(); void initActions(); QAction* visibilityAction; QAction* navigateToAction; signals: void sourceDataChanged(); //emitted when the source data used in the analysis curves was changed to enable the recalculation in the dock widgets //General-Tab void dataChanged(); //emitted when the actual curve data to be plotted was changed to re-adjust the plot void xDataChanged(); void yDataChanged(); void visibilityChanged(bool); friend class XYCurveSetDataSourceTypeCmd; friend class XYCurveSetDataSourceCurveCmd; friend class XYCurveSetXColumnCmd; friend class XYCurveSetYColumnCmd; void dataSourceTypeChanged(XYCurve::DataSourceType); void dataSourceCurveChanged(const XYCurve*); void xColumnChanged(const AbstractColumn*); void yColumnChanged(const AbstractColumn*); //Line-Tab friend class XYCurveSetLineTypeCmd; friend class XYCurveSetLineSkipGapsCmd; friend class XYCurveSetLineInterpolationPointsCountCmd; friend class XYCurveSetLinePenCmd; friend class XYCurveSetLineOpacityCmd; friend class XYCurveSetDropLineTypeCmd; friend class XYCurveSetDropLinePenCmd; friend class XYCurveSetDropLineOpacityCmd; void lineTypeChanged(XYCurve::LineType); void lineSkipGapsChanged(bool); void lineInterpolationPointsCountChanged(int); void linePenChanged(const QPen&); void lineOpacityChanged(qreal); void dropLineTypeChanged(XYCurve::DropLineType); void dropLinePenChanged(const QPen&); void dropLineOpacityChanged(qreal); //Symbol-Tab friend class XYCurveSetSymbolsStyleCmd; friend class XYCurveSetSymbolsSizeCmd; friend class XYCurveSetSymbolsRotationAngleCmd; friend class XYCurveSetSymbolsOpacityCmd; friend class XYCurveSetSymbolsBrushCmd; friend class XYCurveSetSymbolsPenCmd; void symbolsStyleChanged(Symbol::Style); void symbolsSizeChanged(qreal); void symbolsRotationAngleChanged(qreal); void symbolsOpacityChanged(qreal); void symbolsBrushChanged(QBrush); void symbolsPenChanged(const QPen&); //Values-Tab friend class XYCurveSetValuesColumnCmd; friend class XYCurveSetValuesTypeCmd; friend class XYCurveSetValuesPositionCmd; friend class XYCurveSetValuesDistanceCmd; friend class XYCurveSetValuesRotationAngleCmd; friend class XYCurveSetValuesOpacityCmd; friend class XYCurveSetValuesPrefixCmd; friend class XYCurveSetValuesSuffixCmd; friend class XYCurveSetValuesFontCmd; friend class XYCurveSetValuesColorCmd; void valuesTypeChanged(XYCurve::ValuesType); void valuesColumnChanged(const AbstractColumn*); void valuesPositionChanged(XYCurve::ValuesPosition); void valuesDistanceChanged(qreal); void valuesRotationAngleChanged(qreal); void valuesOpacityChanged(qreal); void valuesPrefixChanged(QString); void valuesSuffixChanged(QString); void valuesFontChanged(QFont); void valuesColorChanged(QColor); //Filling friend class XYCurveSetFillingPositionCmd; friend class XYCurveSetFillingTypeCmd; friend class XYCurveSetFillingColorStyleCmd; friend class XYCurveSetFillingImageStyleCmd; friend class XYCurveSetFillingBrushStyleCmd; friend class XYCurveSetFillingFirstColorCmd; friend class XYCurveSetFillingSecondColorCmd; friend class XYCurveSetFillingFileNameCmd; friend class XYCurveSetFillingOpacityCmd; void fillingPositionChanged(XYCurve::FillingPosition); void fillingTypeChanged(PlotArea::BackgroundType); void fillingColorStyleChanged(PlotArea::BackgroundColorStyle); void fillingImageStyleChanged(PlotArea::BackgroundImageStyle); void fillingBrushStyleChanged(Qt::BrushStyle); void fillingFirstColorChanged(QColor&); void fillingSecondColorChanged(QColor&); void fillingFileNameChanged(QString&); void fillingOpacityChanged(float); //Error bars friend class XYCurveSetXErrorTypeCmd; friend class XYCurveSetXErrorPlusColumnCmd; friend class XYCurveSetXErrorMinusColumnCmd; friend class XYCurveSetYErrorTypeCmd; friend class XYCurveSetYErrorPlusColumnCmd; friend class XYCurveSetYErrorMinusColumnCmd; friend class XYCurveSetErrorBarsCapSizeCmd; friend class XYCurveSetErrorBarsTypeCmd; friend class XYCurveSetErrorBarsPenCmd; friend class XYCurveSetErrorBarsOpacityCmd; void xErrorTypeChanged(XYCurve::ErrorType); void xErrorPlusColumnChanged(const AbstractColumn*); void xErrorMinusColumnChanged(const AbstractColumn*); void yErrorTypeChanged(XYCurve::ErrorType); void yErrorPlusColumnChanged(const AbstractColumn*); void yErrorMinusColumnChanged(const AbstractColumn*); void errorBarsCapSizeChanged(qreal); void errorBarsTypeChanged(XYCurve::ErrorBarsType); void errorBarsPenChanged(QPen); void errorBarsOpacityChanged(qreal); }; #endif diff --git a/src/backend/worksheet/plots/cartesian/XYCurvePrivate.h b/src/backend/worksheet/plots/cartesian/XYCurvePrivate.h index 614368043..a908cbce1 100644 --- a/src/backend/worksheet/plots/cartesian/XYCurvePrivate.h +++ b/src/backend/worksheet/plots/cartesian/XYCurvePrivate.h @@ -1,172 +1,172 @@ /*************************************************************************** File : XYCurvePrivate.h Project : LabPlot Description : Private members of XYCurve -------------------------------------------------------------------- Copyright : (C) 2010-2017 Alexander Semke (alexander.semke@web.de) Copyright : (C) 2013 by Stefan Gerlach (stefan.gerlach@uni-konstanz.de) ***************************************************************************/ /*************************************************************************** * * * 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 XYCURVEPRIVATE_H #define XYCURVEPRIVATE_H #include #include class CartesianPlot; class XYCurvePrivate : public QGraphicsItem { public: explicit XYCurvePrivate(XYCurve*); - virtual QRectF boundingRect() const override; + QRectF boundingRect() const override; QPainterPath shape() const override; QString name() const; void retransform(); void updateLines(); void updateDropLines(); void updateSymbols(); void updateValues(); void updateFilling(); void updateErrorBars(); bool swapVisible(bool); void recalcShapeAndBoundingRect(); void updatePixmap(); void setPrinting(bool); void suppressRetransform(bool); //data source XYCurve::DataSourceType dataSourceType; const XYCurve* dataSourceCurve; const AbstractColumn* xColumn; const AbstractColumn* yColumn; QString dataSourceCurvePath; QString xColumnPath; QString yColumnPath; bool sourceDataChangedSinceLastRecalc; //line XYCurve::LineType lineType; bool lineSkipGaps; int lineInterpolationPointsCount; QPen linePen; qreal lineOpacity; //drop lines XYCurve::DropLineType dropLineType; QPen dropLinePen; qreal dropLineOpacity; //symbols Symbol::Style symbolsStyle; QBrush symbolsBrush; QPen symbolsPen; qreal symbolsOpacity; qreal symbolsRotationAngle; qreal symbolsSize; //values XYCurve::ValuesType valuesType; const AbstractColumn* valuesColumn; QString valuesColumnPath; XYCurve::ValuesPosition valuesPosition; qreal valuesDistance; qreal valuesRotationAngle; qreal valuesOpacity; QString valuesPrefix; QString valuesSuffix; QFont valuesFont; QColor valuesColor; //filling XYCurve::FillingPosition fillingPosition; PlotArea::BackgroundType fillingType; PlotArea::BackgroundColorStyle fillingColorStyle; PlotArea::BackgroundImageStyle fillingImageStyle; Qt::BrushStyle fillingBrushStyle; QColor fillingFirstColor; QColor fillingSecondColor; QString fillingFileName; qreal fillingOpacity; //error bars XYCurve::ErrorType xErrorType; const AbstractColumn* xErrorPlusColumn; QString xErrorPlusColumnPath; const AbstractColumn* xErrorMinusColumn; QString xErrorMinusColumnPath; XYCurve::ErrorType yErrorType; const AbstractColumn* yErrorPlusColumn; QString yErrorPlusColumnPath; const AbstractColumn* yErrorMinusColumn; QString yErrorMinusColumnPath; XYCurve::ErrorBarsType errorBarsType; double errorBarsCapSize; QPen errorBarsPen; qreal errorBarsOpacity; XYCurve* const q; friend class XYCurve; private: void contextMenuEvent(QGraphicsSceneContextMenuEvent*) override; - virtual void hoverEnterEvent(QGraphicsSceneHoverEvent*) override; - virtual void hoverLeaveEvent(QGraphicsSceneHoverEvent*) override; - virtual void paint(QPainter*, const QStyleOptionGraphicsItem*, QWidget* widget = 0) override; + void hoverEnterEvent(QGraphicsSceneHoverEvent*) override; + void hoverLeaveEvent(QGraphicsSceneHoverEvent*) override; + void paint(QPainter*, const QStyleOptionGraphicsItem*, QWidget* widget = 0) override; void drawSymbols(QPainter*); void drawValues(QPainter*); void drawFilling(QPainter*); void draw(QPainter*); QPainterPath linePath; QPainterPath dropLinePath; QPainterPath valuesPath; QPainterPath errorBarsPath; QPainterPath symbolsPath; QRectF boundingRectangle; QPainterPath curveShape; QVector lines; QVector symbolPointsLogical; //points in logical coordinates QVector symbolPointsScene; //points in scene coordinates std::vector visiblePoints; //vector of the size of symbolPointsLogical with true of false for the points currently visible or not in the plot QVector valuesPoints; std::vector connectedPointsLogical; //vector of the size of symbolPointsLogical with true for points connected with the consecutive point and //false otherwise (don't connect because of a gap (NAN) in-between) QVector valuesStrings; QVector fillPolygons; QPixmap m_pixmap; QImage m_hoverEffectImage; QImage m_selectionEffectImage; bool m_hoverEffectImageIsDirty; bool m_selectionEffectImageIsDirty; bool m_hovered; bool m_suppressRecalc; bool m_suppressRetransform; bool m_printing; }; #endif diff --git a/src/backend/worksheet/plots/cartesian/XYDataReductionCurve.h b/src/backend/worksheet/plots/cartesian/XYDataReductionCurve.h index 7cf5f7394..fe1b3c948 100644 --- a/src/backend/worksheet/plots/cartesian/XYDataReductionCurve.h +++ b/src/backend/worksheet/plots/cartesian/XYDataReductionCurve.h @@ -1,102 +1,102 @@ /*************************************************************************** File : XYDataReductionCurve.h Project : LabPlot Description : A xy-curve defined by a data reduction -------------------------------------------------------------------- Copyright : (C) 2016 Stefan Gerlach (stefan.gerlach@uni.kn) ***************************************************************************/ /*************************************************************************** * * * 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 XYDATAREDUCTIONCURVE_H #define XYDATAREDUCTIONCURVE_H #include "backend/worksheet/plots/cartesian/XYCurve.h" extern "C" { #include "backend/nsl/nsl_geom_linesim.h" } class XYDataReductionCurvePrivate; class XYDataReductionCurve: public XYCurve { Q_OBJECT public: struct DataReductionData { DataReductionData() : type(nsl_geom_linesim_type_douglas_peucker_variant), autoTolerance(true), tolerance(0.0), autoTolerance2(true), tolerance2(0.0), autoRange(true), xRange(2) {}; nsl_geom_linesim_type type; // type of simplification bool autoTolerance; // automatic tolerance double tolerance; // tolerance bool autoTolerance2; // automatic tolerance2 double tolerance2; // tolerance2 bool autoRange; // use all data? QVector xRange; // x range for integration }; struct DataReductionResult { DataReductionResult() : available(false), valid(false), elapsedTime(0), npoints(0), posError(0), areaError(0) {}; bool available; bool valid; QString status; qint64 elapsedTime; size_t npoints; double posError; double areaError; }; explicit XYDataReductionCurve(const QString& name); - virtual ~XYDataReductionCurve(); + ~XYDataReductionCurve() override; void recalculate(); - virtual QIcon icon() const override; - virtual void save(QXmlStreamWriter*) const override; - virtual bool load(XmlStreamReader*, bool preview) override; + QIcon icon() const override; + void save(QXmlStreamWriter*) const override; + bool load(XmlStreamReader*, bool preview) override; POINTER_D_ACCESSOR_DECL(const AbstractColumn, xDataColumn, XDataColumn) POINTER_D_ACCESSOR_DECL(const AbstractColumn, yDataColumn, YDataColumn) const QString& xDataColumnPath() const; const QString& yDataColumnPath() const; CLASS_D_ACCESSOR_DECL(DataReductionData, dataReductionData, DataReductionData) const DataReductionResult& dataReductionResult() const; typedef XYDataReductionCurvePrivate Private; protected: XYDataReductionCurve(const QString& name, XYDataReductionCurvePrivate* dd); private: Q_DECLARE_PRIVATE(XYDataReductionCurve) void init(); signals: friend class XYDataReductionCurveSetXDataColumnCmd; friend class XYDataReductionCurveSetYDataColumnCmd; void xDataColumnChanged(const AbstractColumn*); void yDataColumnChanged(const AbstractColumn*); friend class XYDataReductionCurveSetDataReductionDataCmd; void dataReductionDataChanged(const XYDataReductionCurve::DataReductionData&); void completed(int) const; //!< int ranging from 0 to 100 notifies about the status of the analysis process }; #endif diff --git a/src/backend/worksheet/plots/cartesian/XYDataReductionCurvePrivate.h b/src/backend/worksheet/plots/cartesian/XYDataReductionCurvePrivate.h index 98a9eaf1c..a8b4278d8 100644 --- a/src/backend/worksheet/plots/cartesian/XYDataReductionCurvePrivate.h +++ b/src/backend/worksheet/plots/cartesian/XYDataReductionCurvePrivate.h @@ -1,61 +1,61 @@ /*************************************************************************** File : XYDataReductionCurvePrivate.h Project : LabPlot Description : Private members of XYDataReductionCurve -------------------------------------------------------------------- Copyright : (C) 2016 Stefan Gerlach (stefan.gerlach@uni.kn) ***************************************************************************/ /*************************************************************************** * * * 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 XYDATAREDUCTIONCURVEPRIVATE_H #define XYDATAREDUCTIONCURVEPRIVATE_H #include "backend/worksheet/plots/cartesian/XYCurvePrivate.h" #include "backend/worksheet/plots/cartesian/XYDataReductionCurve.h" class XYDataReductionCurve; class Column; class XYDataReductionCurvePrivate: public XYCurvePrivate { public: explicit XYDataReductionCurvePrivate(XYDataReductionCurve*); - ~XYDataReductionCurvePrivate(); + ~XYDataReductionCurvePrivate() override; void recalculate(); const AbstractColumn* xDataColumn; //* xVector; QVector* yVector; XYDataReductionCurve* const q; }; #endif diff --git a/src/backend/worksheet/plots/cartesian/XYDifferentiationCurve.h b/src/backend/worksheet/plots/cartesian/XYDifferentiationCurve.h index 9c99843d5..8777bdb0a 100644 --- a/src/backend/worksheet/plots/cartesian/XYDifferentiationCurve.h +++ b/src/backend/worksheet/plots/cartesian/XYDifferentiationCurve.h @@ -1,94 +1,94 @@ /*************************************************************************** File : XYDifferentiationCurve.h Project : LabPlot Description : A xy-curve defined by an differentiation -------------------------------------------------------------------- Copyright : (C) 2016 Stefan Gerlach (stefan.gerlach@uni.kn) ***************************************************************************/ /*************************************************************************** * * * 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 XYDIFFERENTIATIONCURVE_H #define XYDIFFERENTIATIONCURVE_H #include "backend/worksheet/plots/cartesian/XYCurve.h" extern "C" { #include "backend/nsl/nsl_diff.h" } class XYDifferentiationCurvePrivate; class XYDifferentiationCurve : public XYCurve { Q_OBJECT public: struct DifferentiationData { DifferentiationData() : derivOrder(nsl_diff_deriv_order_first), accOrder(2), autoRange(true), xRange(2) {}; nsl_diff_deriv_order_type derivOrder; // order of differentiation int accOrder; // order ofaccuracy bool autoRange; // use all data? QVector xRange; // x range for integration }; struct DifferentiationResult { DifferentiationResult() : available(false), valid(false), elapsedTime(0) {}; bool available; bool valid; QString status; qint64 elapsedTime; }; explicit XYDifferentiationCurve(const QString& name); - virtual ~XYDifferentiationCurve(); + ~XYDifferentiationCurve() override; void recalculate(); - virtual QIcon icon() const override; - virtual void save(QXmlStreamWriter*) const override; - virtual bool load(XmlStreamReader*, bool preview) override; + QIcon icon() const override; + void save(QXmlStreamWriter*) const override; + bool load(XmlStreamReader*, bool preview) override; POINTER_D_ACCESSOR_DECL(const AbstractColumn, xDataColumn, XDataColumn) POINTER_D_ACCESSOR_DECL(const AbstractColumn, yDataColumn, YDataColumn) const QString& xDataColumnPath() const; const QString& yDataColumnPath() const; CLASS_D_ACCESSOR_DECL(DifferentiationData, differentiationData, DifferentiationData) const DifferentiationResult& differentiationResult() const; typedef XYDifferentiationCurvePrivate Private; protected: XYDifferentiationCurve(const QString& name, XYDifferentiationCurvePrivate* dd); private: Q_DECLARE_PRIVATE(XYDifferentiationCurve) void init(); signals: friend class XYDifferentiationCurveSetXDataColumnCmd; friend class XYDifferentiationCurveSetYDataColumnCmd; void xDataColumnChanged(const AbstractColumn*); void yDataColumnChanged(const AbstractColumn*); friend class XYDifferentiationCurveSetDifferentiationDataCmd; void differentiationDataChanged(const XYDifferentiationCurve::DifferentiationData&); }; #endif diff --git a/src/backend/worksheet/plots/cartesian/XYDifferentiationCurvePrivate.h b/src/backend/worksheet/plots/cartesian/XYDifferentiationCurvePrivate.h index 20a9dc30a..83aa1f080 100644 --- a/src/backend/worksheet/plots/cartesian/XYDifferentiationCurvePrivate.h +++ b/src/backend/worksheet/plots/cartesian/XYDifferentiationCurvePrivate.h @@ -1,61 +1,61 @@ /*************************************************************************** File : XYDifferentiationCurvePrivate.h Project : LabPlot Description : Private members of XYDifferentiationCurve -------------------------------------------------------------------- Copyright : (C) 2016 Stefan Gerlach (stefan.gerlach@uni.kn) ***************************************************************************/ /*************************************************************************** * * * 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 XYDIFFERENTIATIONCURVEPRIVATE_H #define XYDIFFERENTIATIONCURVEPRIVATE_H #include "backend/worksheet/plots/cartesian/XYCurvePrivate.h" #include "backend/worksheet/plots/cartesian/XYDifferentiationCurve.h" class XYDifferentiationCurve; class Column; class XYDifferentiationCurvePrivate: public XYCurvePrivate { public: explicit XYDifferentiationCurvePrivate(XYDifferentiationCurve*); - ~XYDifferentiationCurvePrivate(); + ~XYDifferentiationCurvePrivate() override; void recalculate(); const AbstractColumn* xDataColumn; //* xVector; QVector* yVector; XYDifferentiationCurve* const q; }; #endif diff --git a/src/backend/worksheet/plots/cartesian/XYEquationCurve.h b/src/backend/worksheet/plots/cartesian/XYEquationCurve.h index 21d72ca36..90fde03e5 100644 --- a/src/backend/worksheet/plots/cartesian/XYEquationCurve.h +++ b/src/backend/worksheet/plots/cartesian/XYEquationCurve.h @@ -1,76 +1,76 @@ /*************************************************************************** File : XYEquationCurve.h Project : LabPlot Description : A xy-curve defined by a mathematical equation -------------------------------------------------------------------- Copyright : (C) 2014-2017 Alexander Semke (alexander.semke@web.de) ***************************************************************************/ /*************************************************************************** * * * 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 XYEQUATIONCURVE_H #define XYEQUATIONCURVE_H #include "backend/worksheet/plots/cartesian/XYCurve.h" class XYEquationCurvePrivate; class XYEquationCurve : public XYCurve { Q_OBJECT public: enum EquationType {Cartesian, Polar, Parametric, Implicit, Neutral}; struct EquationData { EquationData() : type(Cartesian), min("0"), max("1"), count(1000) {}; EquationType type; QString expression1; QString expression2; QString min; QString max; int count; }; explicit XYEquationCurve(const QString& name); - virtual ~XYEquationCurve(); + ~XYEquationCurve() override; void recalculate(); - virtual QIcon icon() const override; - virtual void save(QXmlStreamWriter*) const override; - virtual bool load(XmlStreamReader*, bool preview) override; + QIcon icon() const override; + void save(QXmlStreamWriter*) const override; + bool load(XmlStreamReader*, bool preview) override; CLASS_D_ACCESSOR_DECL(EquationData, equationData, EquationData) typedef XYEquationCurvePrivate Private; protected: XYEquationCurve(const QString& name, XYEquationCurvePrivate* dd); private: Q_DECLARE_PRIVATE(XYEquationCurve) void init(); signals: friend class XYEquationCurveSetEquationDataCmd; void equationDataChanged(const XYEquationCurve::EquationData&); }; #endif diff --git a/src/backend/worksheet/plots/cartesian/XYEquationCurvePrivate.h b/src/backend/worksheet/plots/cartesian/XYEquationCurvePrivate.h index 5801dd3be..94e0f8a3b 100644 --- a/src/backend/worksheet/plots/cartesian/XYEquationCurvePrivate.h +++ b/src/backend/worksheet/plots/cartesian/XYEquationCurvePrivate.h @@ -1,54 +1,54 @@ /*************************************************************************** File : XYEquationCurvePrivate.h Project : LabPlot Description : Private members of XYEquationCurve -------------------------------------------------------------------- Copyright : (C) 2014 Alexander Semke (alexander.semke@web.de) ***************************************************************************/ /*************************************************************************** * * * 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 XYEQUATIONCURVEPRIVATE_H #define XYEQUATIONCURVEPRIVATE_H #include "backend/worksheet/plots/cartesian/XYCurvePrivate.h" #include "backend/worksheet/plots/cartesian/XYEquationCurve.h" class XYEquationCurve; class Column; class XYEquationCurvePrivate: public XYCurvePrivate { public: explicit XYEquationCurvePrivate(XYEquationCurve*); - ~XYEquationCurvePrivate(); + ~XYEquationCurvePrivate() override; void recalculate(); XYEquationCurve::EquationData equationData; Column* xColumn; Column* yColumn; QVector* xVector; QVector* yVector; XYEquationCurve* const q; }; #endif diff --git a/src/backend/worksheet/plots/cartesian/XYFitCurve.h b/src/backend/worksheet/plots/cartesian/XYFitCurve.h index 807c7a35f..5d76c905d 100644 --- a/src/backend/worksheet/plots/cartesian/XYFitCurve.h +++ b/src/backend/worksheet/plots/cartesian/XYFitCurve.h @@ -1,164 +1,164 @@ /*************************************************************************** File : XYFitCurve.h Project : LabPlot Description : A xy-curve defined by a fit model -------------------------------------------------------------------- Copyright : (C) 2014-2016 Alexander Semke (alexander.semke@web.de) Copyright : (C) 2016 Stefan Gerlach (stefan.gerlach@uni.kn) ***************************************************************************/ /*************************************************************************** * * * 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 XYFITCURVE_H #define XYFITCURVE_H #include "backend/worksheet/plots/cartesian/XYCurve.h" #include "kdefrontend/spreadsheet/PlotDataDialog.h" //for PlotDataDialog::AnalysisAction. TODO: find a better place for this enum. extern "C" { #include "backend/nsl/nsl_fit.h" } class XYFitCurvePrivate; class XYFitCurve : public XYCurve { Q_OBJECT public: struct FitData { FitData() : modelCategory(nsl_fit_model_basic), modelType(0), xErrorsType(nsl_fit_error_no), yWeightsType(nsl_fit_weight_no), degree(1), maxIterations(500), eps(1e-4), evaluatedPoints(100), evaluateFullRange(true), useDataErrors(true), useResults(true), autoRange(true), xRange(2) {}; nsl_fit_model_category modelCategory; unsigned int modelType; nsl_fit_error_type xErrorsType; nsl_fit_weight_type yWeightsType; unsigned int degree; QString model; QStringList paramNames; QStringList paramNamesUtf8; // Utf8 version of paramNames QVector paramStartValues; QVector paramLowerLimits; QVector paramUpperLimits; QVector paramFixed; int maxIterations; double eps; size_t evaluatedPoints; bool evaluateFullRange; // evaluate fit function on full data range (default) bool useDataErrors; // use given data errors when fitting (default) bool useResults; // use results as new start values (default) bool autoRange; // use all data? QVector xRange; // x range for integration }; struct FitResult { FitResult() : available(false), valid(false), iterations(0), elapsedTime(0), dof(0), sse(0), sst(0), rms(0), rsd(0), mse(0), rmse(0), mae(0), rsquare(0), rsquareAdj(0), chisq_p(0), fdist_F(0), fdist_p(0), aic(0), bic(0) {}; bool available; bool valid; QString status; int iterations; qint64 elapsedTime; double dof; //degrees of freedom // residuals: r_i = y_i - Y_i double sse; // sum of squared errors (SSE) / residual sum of squares (RSS) / sum of sq. residuals (SSR) / S = chi^2 = \sum_i^n r_i^2 double sst; // total sum of squares (SST) = \sum_i^n (y_i - )^2 double rms; // residual mean square / reduced chi^2 = SSE/dof double rsd; // residual standard deviation = sqrt(SSE/dof) double mse; // mean squared error = SSE/n double rmse; // root-mean squared error = \sqrt(mse) double mae; // mean absolute error = \sum_i^n |r_i| double rsquare; double rsquareAdj; double chisq_p; // chi^2 distribution p-value double fdist_F; // F distribution F-value double fdist_p; // F distribution p-value double aic; // Akaike information criterion double bic; // Schwarz Bayesian information criterion // see also http://www.originlab.com/doc/Origin-Help/NLFit-Algorithm QVector paramValues; QVector errorValues; QVector tdist_tValues; QVector tdist_pValues; QVector tdist_marginValues; QString solverOutput; }; explicit XYFitCurve(const QString& name); - virtual ~XYFitCurve(); + ~XYFitCurve() override; void recalculate(); void initFitData(PlotDataDialog::AnalysisAction); static void initFitData(XYFitCurve::FitData&); - virtual QIcon icon() const override; - virtual void save(QXmlStreamWriter*) const override; - virtual bool load(XmlStreamReader*, bool preview) override; + QIcon icon() const override; + void save(QXmlStreamWriter*) const override; + bool load(XmlStreamReader*, bool preview) override; POINTER_D_ACCESSOR_DECL(const AbstractColumn, xDataColumn, XDataColumn) POINTER_D_ACCESSOR_DECL(const AbstractColumn, yDataColumn, YDataColumn) POINTER_D_ACCESSOR_DECL(const AbstractColumn, xErrorColumn, XErrorColumn) POINTER_D_ACCESSOR_DECL(const AbstractColumn, yErrorColumn, YErrorColumn) const QString& xDataColumnPath() const; const QString& yDataColumnPath() const; const QString& xErrorColumnPath() const; const QString& yErrorColumnPath() const; CLASS_D_ACCESSOR_DECL(FitData, fitData, FitData) const FitResult& fitResult() const; typedef XYFitCurvePrivate Private; protected: XYFitCurve(const QString& name, XYFitCurvePrivate* dd); private: Q_DECLARE_PRIVATE(XYFitCurve) void init(); signals: friend class XYFitCurveSetXDataColumnCmd; friend class XYFitCurveSetYDataColumnCmd; friend class XYFitCurveSetXErrorColumnCmd; friend class XYFitCurveSetYErrorColumnCmd; void xDataColumnChanged(const AbstractColumn*); void yDataColumnChanged(const AbstractColumn*); void xErrorColumnChanged(const AbstractColumn*); void yErrorColumnChanged(const AbstractColumn*); friend class XYFitCurveSetFitDataCmd; void fitDataChanged(const XYFitCurve::FitData&); }; #endif diff --git a/src/backend/worksheet/plots/cartesian/XYFitCurvePrivate.h b/src/backend/worksheet/plots/cartesian/XYFitCurvePrivate.h index 01e63b515..694abaa1d 100644 --- a/src/backend/worksheet/plots/cartesian/XYFitCurvePrivate.h +++ b/src/backend/worksheet/plots/cartesian/XYFitCurvePrivate.h @@ -1,75 +1,75 @@ /*************************************************************************** File : XYFitCurvePrivate.h Project : LabPlot Description : Private members of XYFitCurve -------------------------------------------------------------------- Copyright : (C) 2014 Alexander Semke (alexander.semke@web.de) ***************************************************************************/ /*************************************************************************** * * * 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 XYFITCURVEPRIVATE_H #define XYFITCURVEPRIVATE_H #include "backend/worksheet/plots/cartesian/XYCurvePrivate.h" #include "backend/worksheet/plots/cartesian/XYFitCurve.h" class XYFitCurve; class Column; extern "C" { #include } class XYFitCurvePrivate: public XYCurvePrivate { public: explicit XYFitCurvePrivate(XYFitCurve*); - ~XYFitCurvePrivate(); + ~XYFitCurvePrivate() override; void recalculate(); const AbstractColumn* xDataColumn; //* xVector; QVector* yVector; QVector* residualsVector; XYFitCurve* const q; private: void writeSolverState(gsl_multifit_fdfsolver* s); }; #endif diff --git a/src/backend/worksheet/plots/cartesian/XYFourierFilterCurve.h b/src/backend/worksheet/plots/cartesian/XYFourierFilterCurve.h index a20c21321..95e167018 100644 --- a/src/backend/worksheet/plots/cartesian/XYFourierFilterCurve.h +++ b/src/backend/worksheet/plots/cartesian/XYFourierFilterCurve.h @@ -1,101 +1,101 @@ /*************************************************************************** File : XYFourierFilterCurve.h Project : LabPlot Description : A xy-curve defined by a Fourier filter -------------------------------------------------------------------- Copyright : (C) 2016 Stefan Gerlach (stefan.gerlach@uni.kn) ***************************************************************************/ /*************************************************************************** * * * 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 XYFOURIERFILTERCURVE_H #define XYFOURIERFILTERCURVE_H #include "backend/worksheet/plots/cartesian/XYCurve.h" extern "C" { #include "backend/nsl/nsl_filter.h" } class XYFourierFilterCurvePrivate; class XYFourierFilterCurve : public XYCurve { Q_OBJECT public: struct FilterData { FilterData() : type(nsl_filter_type_low_pass), form(nsl_filter_form_ideal), order(1), cutoff(0), unit(nsl_filter_cutoff_unit_frequency), cutoff2(0), unit2(nsl_filter_cutoff_unit_frequency), autoRange(true), xRange(2) {}; nsl_filter_type type; nsl_filter_form form; unsigned int order; double cutoff; // (low) cutoff nsl_filter_cutoff_unit unit; // (low) value unit double cutoff2; // high cutoff nsl_filter_cutoff_unit unit2; // high value unit bool autoRange; // use all data? QVector xRange; // x range for integration }; struct FilterResult { FilterResult() : available(false), valid(false), elapsedTime(0) {}; bool available; bool valid; QString status; qint64 elapsedTime; }; explicit XYFourierFilterCurve(const QString& name); - virtual ~XYFourierFilterCurve(); + ~XYFourierFilterCurve() override; void recalculate(); - virtual QIcon icon() const override; - virtual void save(QXmlStreamWriter*) const override; - virtual bool load(XmlStreamReader*, bool preview) override; + QIcon icon() const override; + void save(QXmlStreamWriter*) const override; + bool load(XmlStreamReader*, bool preview) override; POINTER_D_ACCESSOR_DECL(const AbstractColumn, xDataColumn, XDataColumn) POINTER_D_ACCESSOR_DECL(const AbstractColumn, yDataColumn, YDataColumn) const QString& xDataColumnPath() const; const QString& yDataColumnPath() const; CLASS_D_ACCESSOR_DECL(FilterData, filterData, FilterData) const FilterResult& filterResult() const; typedef XYFourierFilterCurvePrivate Private; protected: XYFourierFilterCurve(const QString& name, XYFourierFilterCurvePrivate* dd); private: Q_DECLARE_PRIVATE(XYFourierFilterCurve) void init(); signals: friend class XYFourierFilterCurveSetXDataColumnCmd; friend class XYFourierFilterCurveSetYDataColumnCmd; void xDataColumnChanged(const AbstractColumn*); void yDataColumnChanged(const AbstractColumn*); friend class XYFourierFilterCurveSetFilterDataCmd; void filterDataChanged(const XYFourierFilterCurve::FilterData&); }; #endif diff --git a/src/backend/worksheet/plots/cartesian/XYFourierFilterCurvePrivate.h b/src/backend/worksheet/plots/cartesian/XYFourierFilterCurvePrivate.h index 6baf50c99..3747e2564 100644 --- a/src/backend/worksheet/plots/cartesian/XYFourierFilterCurvePrivate.h +++ b/src/backend/worksheet/plots/cartesian/XYFourierFilterCurvePrivate.h @@ -1,63 +1,63 @@ /*************************************************************************** File : XYFourierFilterCurvePrivate.h Project : LabPlot Description : Private members of XYFourierFilterCurve -------------------------------------------------------------------- Copyright : (C) 2016 Stefan Gerlach (stefan.gerlach@uni.kn) ***************************************************************************/ /*************************************************************************** * * * 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 XYFOURIERFILTERCURVEPRIVATE_H #define XYFOURIERFILTERCURVEPRIVATE_H #include "backend/worksheet/plots/cartesian/XYCurvePrivate.h" #include "backend/worksheet/plots/cartesian/XYFourierFilterCurve.h" class XYFourierFilterCurve; class Column; class XYFourierFilterCurvePrivate: public XYCurvePrivate { public: explicit XYFourierFilterCurvePrivate(XYFourierFilterCurve*); - ~XYFourierFilterCurvePrivate(); + ~XYFourierFilterCurvePrivate() override; void recalculate(); const AbstractColumn* xDataColumn; //* xVector; QVector* yVector; XYFourierFilterCurve* const q; // private: // void writeSolverState(gsl_multifit_fdfsolver* s); }; #endif diff --git a/src/backend/worksheet/plots/cartesian/XYFourierTransformCurve.h b/src/backend/worksheet/plots/cartesian/XYFourierTransformCurve.h index fc28a69dc..7fc9fe90e 100644 --- a/src/backend/worksheet/plots/cartesian/XYFourierTransformCurve.h +++ b/src/backend/worksheet/plots/cartesian/XYFourierTransformCurve.h @@ -1,99 +1,99 @@ /*************************************************************************** File : XYFourierTransformCurve.h Project : LabPlot Description : A xy-curve defined by a Fourier transform -------------------------------------------------------------------- Copyright : (C) 2016 Stefan Gerlach (stefan.gerlach@uni.kn) ***************************************************************************/ /*************************************************************************** * * * 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 XYFOURIERTRANSFORMCURVE_H #define XYFOURIERTRANSFORMCURVE_H #include "backend/worksheet/plots/cartesian/XYCurve.h" extern "C" { #include "backend/nsl/nsl_dft.h" #include "backend/nsl/nsl_sf_window.h" } class XYFourierTransformCurvePrivate; class XYFourierTransformCurve: public XYCurve { Q_OBJECT public: struct TransformData { TransformData() : type(nsl_dft_result_magnitude), twoSided(false), shifted(false), xScale(nsl_dft_xscale_frequency), windowType(nsl_sf_window_uniform), autoRange(true), xRange(2) {}; nsl_dft_result_type type; bool twoSided; bool shifted; nsl_dft_xscale xScale; nsl_sf_window_type windowType; bool autoRange; // use all data? QVector xRange; // x range for transform }; struct TransformResult { TransformResult() : available(false), valid(false), elapsedTime(0) {}; bool available; bool valid; QString status; qint64 elapsedTime; }; explicit XYFourierTransformCurve(const QString& name); - virtual ~XYFourierTransformCurve(); + ~XYFourierTransformCurve() override; void recalculate(); - virtual QIcon icon() const override; - virtual void save(QXmlStreamWriter*) const override; - virtual bool load(XmlStreamReader*, bool preview) override; + QIcon icon() const override; + void save(QXmlStreamWriter*) const override; + bool load(XmlStreamReader*, bool preview) override; POINTER_D_ACCESSOR_DECL(const AbstractColumn, xDataColumn, XDataColumn) POINTER_D_ACCESSOR_DECL(const AbstractColumn, yDataColumn, YDataColumn) const QString& xDataColumnPath() const; const QString& yDataColumnPath() const; CLASS_D_ACCESSOR_DECL(TransformData, transformData, TransformData) const TransformResult& transformResult() const; typedef XYFourierTransformCurvePrivate Private; protected: XYFourierTransformCurve(const QString& name, XYFourierTransformCurvePrivate* dd); private: Q_DECLARE_PRIVATE(XYFourierTransformCurve) void init(); signals: friend class XYFourierTransformCurveSetXDataColumnCmd; friend class XYFourierTransformCurveSetYDataColumnCmd; void xDataColumnChanged(const AbstractColumn*); void yDataColumnChanged(const AbstractColumn*); friend class XYFourierTransformCurveSetTransformDataCmd; void transformDataChanged(const XYFourierTransformCurve::TransformData&); }; #endif diff --git a/src/backend/worksheet/plots/cartesian/XYFourierTransformCurvePrivate.h b/src/backend/worksheet/plots/cartesian/XYFourierTransformCurvePrivate.h index 8d1687d5c..1e88773f3 100644 --- a/src/backend/worksheet/plots/cartesian/XYFourierTransformCurvePrivate.h +++ b/src/backend/worksheet/plots/cartesian/XYFourierTransformCurvePrivate.h @@ -1,63 +1,63 @@ /*************************************************************************** File : XYFourierTransformCurvePrivate.h Project : LabPlot Description : Private members of XYFourierTransformCurve -------------------------------------------------------------------- Copyright : (C) 2016 Stefan Gerlach (stefan.gerlach@uni.kn) ***************************************************************************/ /*************************************************************************** * * * 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 XYFOURIERTRANSFORMCURVEPRIVATE_H #define XYFOURIERTRANSFORMCURVEPRIVATE_H #include "backend/worksheet/plots/cartesian/XYCurvePrivate.h" #include "backend/worksheet/plots/cartesian/XYFourierTransformCurve.h" class XYFourierTransformCurve; class Column; class XYFourierTransformCurvePrivate: public XYCurvePrivate { public: explicit XYFourierTransformCurvePrivate(XYFourierTransformCurve*); - ~XYFourierTransformCurvePrivate(); + ~XYFourierTransformCurvePrivate() override; void recalculate(); const AbstractColumn* xDataColumn; //* xVector; QVector* yVector; XYFourierTransformCurve* const q; // private: // void writeSolverState(gsl_multifit_fdfsolver* s); }; #endif diff --git a/src/backend/worksheet/plots/cartesian/XYIntegrationCurve.h b/src/backend/worksheet/plots/cartesian/XYIntegrationCurve.h index 96dc817c1..603d27a44 100644 --- a/src/backend/worksheet/plots/cartesian/XYIntegrationCurve.h +++ b/src/backend/worksheet/plots/cartesian/XYIntegrationCurve.h @@ -1,95 +1,95 @@ /*************************************************************************** File : XYIntegrationCurve.h Project : LabPlot Description : A xy-curve defined by an integration -------------------------------------------------------------------- Copyright : (C) 2016 Stefan Gerlach (stefan.gerlach@uni.kn) ***************************************************************************/ /*************************************************************************** * * * 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 XYINTEGRATIONCURVE_H #define XYINTEGRATIONCURVE_H #include "backend/worksheet/plots/cartesian/XYCurve.h" extern "C" { #include "backend/nsl/nsl_int.h" } class XYIntegrationCurvePrivate; class XYIntegrationCurve: public XYCurve { Q_OBJECT public: struct IntegrationData { IntegrationData() : method(nsl_int_method_trapezoid), absolute(false), autoRange(true), xRange(2) {}; nsl_int_method_type method; // method for integration bool absolute; // absolute area? bool autoRange; // use all data? QVector xRange; // x range for integration }; struct IntegrationResult { IntegrationResult() : available(false), valid(false), elapsedTime(0), value(0) {}; bool available; bool valid; QString status; qint64 elapsedTime; double value; // final result of integration }; explicit XYIntegrationCurve(const QString& name); - virtual ~XYIntegrationCurve(); + ~XYIntegrationCurve() override; void recalculate(); - virtual QIcon icon() const override; - virtual void save(QXmlStreamWriter*) const override; - virtual bool load(XmlStreamReader*, bool preview) override; + QIcon icon() const override; + void save(QXmlStreamWriter*) const override; + bool load(XmlStreamReader*, bool preview) override; POINTER_D_ACCESSOR_DECL(const AbstractColumn, xDataColumn, XDataColumn) POINTER_D_ACCESSOR_DECL(const AbstractColumn, yDataColumn, YDataColumn) const QString& xDataColumnPath() const; const QString& yDataColumnPath() const; CLASS_D_ACCESSOR_DECL(IntegrationData, integrationData, IntegrationData) const IntegrationResult& integrationResult() const; typedef XYIntegrationCurvePrivate Private; protected: XYIntegrationCurve(const QString& name, XYIntegrationCurvePrivate* dd); private: Q_DECLARE_PRIVATE(XYIntegrationCurve) void init(); signals: friend class XYIntegrationCurveSetXDataColumnCmd; friend class XYIntegrationCurveSetYDataColumnCmd; void xDataColumnChanged(const AbstractColumn*); void yDataColumnChanged(const AbstractColumn*); friend class XYIntegrationCurveSetIntegrationDataCmd; void integrationDataChanged(const XYIntegrationCurve::IntegrationData&); }; #endif diff --git a/src/backend/worksheet/plots/cartesian/XYIntegrationCurvePrivate.h b/src/backend/worksheet/plots/cartesian/XYIntegrationCurvePrivate.h index 11952f402..6f458e583 100644 --- a/src/backend/worksheet/plots/cartesian/XYIntegrationCurvePrivate.h +++ b/src/backend/worksheet/plots/cartesian/XYIntegrationCurvePrivate.h @@ -1,61 +1,61 @@ /*************************************************************************** File : XYIntegrationCurvePrivate.h Project : LabPlot Description : Private members of XYIntegrationCurve -------------------------------------------------------------------- Copyright : (C) 2016 Stefan Gerlach (stefan.gerlach@uni.kn) ***************************************************************************/ /*************************************************************************** * * * 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 XYINTEGRATIONCURVEPRIVATE_H #define XYINTEGRATIONCURVEPRIVATE_H #include "backend/worksheet/plots/cartesian/XYCurvePrivate.h" #include "backend/worksheet/plots/cartesian/XYIntegrationCurve.h" class XYIntegrationCurve; class Column; class XYIntegrationCurvePrivate: public XYCurvePrivate { public: explicit XYIntegrationCurvePrivate(XYIntegrationCurve*); - ~XYIntegrationCurvePrivate(); + ~XYIntegrationCurvePrivate() override; void recalculate(); const AbstractColumn* xDataColumn; //* xVector; QVector* yVector; XYIntegrationCurve* const q; }; #endif diff --git a/src/backend/worksheet/plots/cartesian/XYInterpolationCurve.h b/src/backend/worksheet/plots/cartesian/XYInterpolationCurve.h index f07202ffe..8c96895eb 100644 --- a/src/backend/worksheet/plots/cartesian/XYInterpolationCurve.h +++ b/src/backend/worksheet/plots/cartesian/XYInterpolationCurve.h @@ -1,102 +1,102 @@ /*************************************************************************** File : XYInterpolationCurve.h Project : LabPlot Description : A xy-curve defined by an interpolation -------------------------------------------------------------------- Copyright : (C) 2016 Stefan Gerlach (stefan.gerlach@uni.kn) ***************************************************************************/ /*************************************************************************** * * * 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 XYINTERPOLATIONCURVE_H #define XYINTERPOLATIONCURVE_H #include "backend/worksheet/plots/cartesian/XYCurve.h" extern "C" { #include #include "backend/nsl/nsl_interp.h" } class XYInterpolationCurvePrivate; class XYInterpolationCurve: public XYCurve { Q_OBJECT public: enum PointsMode {Auto, Multiple, Custom}; struct InterpolationData { InterpolationData() : type(nsl_interp_type_linear), variant(nsl_interp_pch_variant_finite_difference), tension(0.0), continuity(0.0), bias(0.0), evaluate(nsl_interp_evaluate_function), npoints(100), pointsMode(XYInterpolationCurve::Auto), autoRange(true), xRange(2) {}; nsl_interp_type type; // type of interpolation nsl_interp_pch_variant variant; // variant of cubic Hermite interpolation double tension, continuity, bias; // TCB values nsl_interp_evaluate evaluate; // what to evaluate unsigned int npoints; // nr. of points XYInterpolationCurve::PointsMode pointsMode; // mode to interpret points bool autoRange; // use all data? QVector xRange; // x range for interpolation }; struct InterpolationResult { InterpolationResult() : available(false), valid(false), elapsedTime(0) {}; bool available; bool valid; QString status; qint64 elapsedTime; }; explicit XYInterpolationCurve(const QString& name); - virtual ~XYInterpolationCurve(); + ~XYInterpolationCurve() override; void recalculate(); - virtual QIcon icon() const override; - virtual void save(QXmlStreamWriter*) const override; - virtual bool load(XmlStreamReader*, bool preview) override; + QIcon icon() const override; + void save(QXmlStreamWriter*) const override; + bool load(XmlStreamReader*, bool preview) override; POINTER_D_ACCESSOR_DECL(const AbstractColumn, xDataColumn, XDataColumn) POINTER_D_ACCESSOR_DECL(const AbstractColumn, yDataColumn, YDataColumn) const QString& xDataColumnPath() const; const QString& yDataColumnPath() const; CLASS_D_ACCESSOR_DECL(InterpolationData, interpolationData, InterpolationData) const InterpolationResult& interpolationResult() const; typedef XYInterpolationCurvePrivate Private; protected: XYInterpolationCurve(const QString& name, XYInterpolationCurvePrivate* dd); private: Q_DECLARE_PRIVATE(XYInterpolationCurve) void init(); signals: friend class XYInterpolationCurveSetXDataColumnCmd; friend class XYInterpolationCurveSetYDataColumnCmd; void xDataColumnChanged(const AbstractColumn*); void yDataColumnChanged(const AbstractColumn*); friend class XYInterpolationCurveSetInterpolationDataCmd; void interpolationDataChanged(const XYInterpolationCurve::InterpolationData&); }; #endif diff --git a/src/backend/worksheet/plots/cartesian/XYInterpolationCurvePrivate.h b/src/backend/worksheet/plots/cartesian/XYInterpolationCurvePrivate.h index d4fdf31d2..8ece19b60 100644 --- a/src/backend/worksheet/plots/cartesian/XYInterpolationCurvePrivate.h +++ b/src/backend/worksheet/plots/cartesian/XYInterpolationCurvePrivate.h @@ -1,61 +1,61 @@ /*************************************************************************** File : XYInterpolationCurvePrivate.h Project : LabPlot Description : Private members of XYInterpolationCurve -------------------------------------------------------------------- Copyright : (C) 2016 Stefan Gerlach (stefan.gerlach@uni.kn) ***************************************************************************/ /*************************************************************************** * * * 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 XYINTERPOLATIONCURVEPRIVATE_H #define XYINTERPOLATIONCURVEPRIVATE_H #include "backend/worksheet/plots/cartesian/XYCurvePrivate.h" #include "backend/worksheet/plots/cartesian/XYInterpolationCurve.h" class XYInterpolationCurve; class Column; class XYInterpolationCurvePrivate: public XYCurvePrivate { public: explicit XYInterpolationCurvePrivate(XYInterpolationCurve*); - ~XYInterpolationCurvePrivate(); + ~XYInterpolationCurvePrivate() override; void recalculate(); const AbstractColumn* xDataColumn; //* xVector; QVector* yVector; XYInterpolationCurve* const q; }; #endif diff --git a/src/backend/worksheet/plots/cartesian/XYSmoothCurve.h b/src/backend/worksheet/plots/cartesian/XYSmoothCurve.h index a1f35adee..6aee47f4e 100644 --- a/src/backend/worksheet/plots/cartesian/XYSmoothCurve.h +++ b/src/backend/worksheet/plots/cartesian/XYSmoothCurve.h @@ -1,101 +1,101 @@ /*************************************************************************** File : XYSmoothCurve.h Project : LabPlot Description : A xy-curve defined by a smooth -------------------------------------------------------------------- Copyright : (C) 2016 Stefan Gerlach (stefan.gerlach@uni.kn) ***************************************************************************/ /*************************************************************************** * * * 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 XYSMOOTHCURVE_H #define XYSMOOTHCURVE_H #include "backend/worksheet/plots/cartesian/XYCurve.h" extern "C" { #include "backend/nsl/nsl_smooth.h" } class XYSmoothCurvePrivate; class XYSmoothCurve: public XYCurve { Q_OBJECT public: struct SmoothData { SmoothData() : type(nsl_smooth_type_moving_average), points(5), weight(nsl_smooth_weight_uniform), percentile(0.5), order(2), mode(nsl_smooth_pad_none), lvalue(0.0), rvalue(0.0), autoRange(true), xRange(2) {}; nsl_smooth_type type; // type of smoothing unsigned int points; // number of points nsl_smooth_weight_type weight; // type of weight double percentile; // percentile for percentile filter (0.0 .. 1.0) unsigned order; // order for Savitzky-Golay filter nsl_smooth_pad_mode mode; // mode of padding for edges double lvalue, rvalue; // values for constant padding bool autoRange; // use all data? QVector xRange; // x range for integration }; struct SmoothResult { SmoothResult() : available(false), valid(false), elapsedTime(0) {}; bool available; bool valid; QString status; qint64 elapsedTime; }; explicit XYSmoothCurve(const QString& name); - virtual ~XYSmoothCurve(); + ~XYSmoothCurve() override; void recalculate(); - virtual QIcon icon() const override; - virtual void save(QXmlStreamWriter*) const override; - virtual bool load(XmlStreamReader*, bool preview) override; + QIcon icon() const override; + void save(QXmlStreamWriter*) const override; + bool load(XmlStreamReader*, bool preview) override; POINTER_D_ACCESSOR_DECL(const AbstractColumn, xDataColumn, XDataColumn) POINTER_D_ACCESSOR_DECL(const AbstractColumn, yDataColumn, YDataColumn) const QString& xDataColumnPath() const; const QString& yDataColumnPath() const; CLASS_D_ACCESSOR_DECL(SmoothData, smoothData, SmoothData) const SmoothResult& smoothResult() const; typedef XYSmoothCurvePrivate Private; protected: XYSmoothCurve(const QString& name, XYSmoothCurvePrivate* dd); private: Q_DECLARE_PRIVATE(XYSmoothCurve) void init(); signals: friend class XYSmoothCurveSetXDataColumnCmd; friend class XYSmoothCurveSetYDataColumnCmd; void xDataColumnChanged(const AbstractColumn*); void yDataColumnChanged(const AbstractColumn*); friend class XYSmoothCurveSetSmoothDataCmd; void smoothDataChanged(const XYSmoothCurve::SmoothData&); }; #endif diff --git a/src/backend/worksheet/plots/cartesian/XYSmoothCurvePrivate.h b/src/backend/worksheet/plots/cartesian/XYSmoothCurvePrivate.h index 5f5730569..cb5e0c478 100644 --- a/src/backend/worksheet/plots/cartesian/XYSmoothCurvePrivate.h +++ b/src/backend/worksheet/plots/cartesian/XYSmoothCurvePrivate.h @@ -1,63 +1,63 @@ /*************************************************************************** File : XYSmoothCurvePrivate.h Project : LabPlot Description : Private members of XYSmoothCurve -------------------------------------------------------------------- Copyright : (C) 2016 Stefan Gerlach (stefan.gerlach@uni.kn) ***************************************************************************/ /*************************************************************************** * * * 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 XYSMOOTHCURVEPRIVATE_H #define XYSMOOTHCURVEPRIVATE_H #include "backend/worksheet/plots/cartesian/XYCurvePrivate.h" #include "backend/worksheet/plots/cartesian/XYSmoothCurve.h" class XYSmoothCurve; class Column; class XYSmoothCurvePrivate: public XYCurvePrivate { public: explicit XYSmoothCurvePrivate(XYSmoothCurve*); - ~XYSmoothCurvePrivate(); + ~XYSmoothCurvePrivate() override; void recalculate(); const AbstractColumn* xDataColumn; //* xVector; QVector* yVector; XYSmoothCurve* const q; // private: }; #endif diff --git a/src/cantor/cantor_part.h b/src/cantor/cantor_part.h index dc480d6aa..3208685b7 100644 --- a/src/cantor/cantor_part.h +++ b/src/cantor/cantor_part.h @@ -1,177 +1,177 @@ /* 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 CANTORPART_H #define CANTORPART_H #include #include #include class QWidget; class Worksheet; class WorksheetView; class SarchBar; class SearchBar; class ScriptEditorWidget; class KAboutData; class QAction; class KToggleAction; class KProgressDialog; namespace Cantor{ class PanelPluginHandler; } /** * This is a "Part". It that does all the real work in a KPart * application. * * @short Main Part * @author Alexander Rieder */ class CantorPart : public KParts::ReadWritePart { Q_OBJECT public: /** * Default constructor */ CantorPart(QWidget *parentWidget,QObject *parent, const QVariantList &args); /** * Destructor */ - virtual ~CantorPart(); + ~CantorPart() override; /** * This is a virtual function inherited from KParts::ReadWritePart. * A shell will use this to inform this Part if it should act * read-only */ - virtual void setReadWrite(bool rw); + void setReadWrite(bool rw) override; /** * Reimplemented to disable and enable Save action */ - virtual void setModified(bool modified); + void setModified(bool modified) override; KAboutData& createAboutData(); Worksheet* worksheet(); Q_SIGNALS: void setCaption(const QString& caption); void showHelp(const QString& help); protected: /** * This must be implemented by each part */ - virtual bool openFile(); + bool openFile() override; /** * This must be implemented by each read-write part */ - virtual bool saveFile(); + bool saveFile() override; /** * Called when this part becomes the active one, * or if it looses activity **/ - void guiActivateEvent( KParts::GUIActivateEvent * event ); + void guiActivateEvent( KParts::GUIActivateEvent * event ) override; void loadAssistants(); void adjustGuiToSession(); protected Q_SLOTS: void fileSaveAs(); void fileSavePlain(); void exportToLatex(); void evaluateOrInterrupt(); void restartBackend(); void enableTypesetting(bool enable); void showBackendHelp(); void print(); void printPreview(); void worksheetStatusChanged(Cantor::Session::Status stauts); void showSessionError(const QString& error); void worksheetSessionChanged(); void initialized(); void updateCaption(); void pluginsChanged(); void runCommand(const QString& value); void runAssistant(); void publishWorksheet(); void showScriptEditor(bool show); void scriptEditorClosed(); void runScript(const QString& file); void showSearchBar(); void showExtendedSearchBar(); void findNext(); void findPrev(); void searchBarDeleted(); /** sets the status message, or cached it, if the StatusBar is blocked. * Use this method instead of "emit setStatusBarText" */ void setStatusMessage(const QString& message); /** Shows an important status message. It makes sure the message is displayed, * by blocking the statusbarText for 3 seconds */ void showImportantStatusMessage(const QString& message); /** Blocks the StatusBar for new messages, so the currently shown one won't be overridden */ void blockStatusBar(); /** Removes the block from the StatusBar, and shows the last one of the StatusMessages that where set during the block **/ void unblockStatusBar(); private: Worksheet *m_worksheet; WorksheetView *m_worksheetview; SearchBar *m_searchBar; QPointer m_scriptEditor; Cantor::PanelPluginHandler* m_panelHandler; KProgressDialog* m_initProgressDlg; QAction * m_evaluate; QAction * m_save; QAction * m_findNext; QAction * m_findPrev; KToggleAction* m_typeset; KToggleAction* m_highlight; KToggleAction* m_completion; KToggleAction* m_exprNumbering; KToggleAction* m_animateWorksheet; QAction * m_showBackendHelp; QString m_cachedStatusMessage; bool m_statusBarBlocked; }; #endif // CANTORPART_H diff --git a/src/cantor/panelplugin.h b/src/cantor/panelplugin.h index 44c77d099..6539030c7 100644 --- a/src/cantor/panelplugin.h +++ b/src/cantor/panelplugin.h @@ -1,117 +1,117 @@ /* 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 #include #include namespace Cantor { class Session; class PanelPluginPrivate; /** * A plugin provides some additional features for the worksheet */ class CANTOR_EXPORT PanelPlugin : public QObject /*, public KXMLGUIClient*/ { Q_OBJECT public: /** * Create a new PanelPlugin * @param parent the parent Object @see QObject **/ PanelPlugin( QObject* parent ); /** * Destructor */ - ~PanelPlugin(); + ~PanelPlugin() override; /** * Sets the properties of this PanelPlugin * accodring to KPluginInfo * @param info KPluginInfo */ void setPluginInfo(KPluginInfo info); /** * 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 */ diff --git a/src/cantor/panelpluginhandler.h b/src/cantor/panelpluginhandler.h index f22850609..c36623d88 100644 --- a/src/cantor/panelpluginhandler.h +++ b/src/cantor/panelpluginhandler.h @@ -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 */ #ifndef _PANELPLUGINHANDLER_H #define _PANELPLUGINHANDLER_H #include #include namespace Cantor { class PanelPluginHandlerPrivate; class PanelPlugin; class Session; /** * Simple interface that exports a list of known PanelPlugins. * Needed as the Panel must be handled by the Shell while plugins * belong to the Part. */ class CANTOR_EXPORT PanelPluginHandler : public QObject { Q_OBJECT public: PanelPluginHandler(QObject* parent); - ~PanelPluginHandler(); + ~PanelPluginHandler() override; QList plugins(); void addPlugin(PanelPlugin* plugin); void setSession(Session* session); Q_SIGNALS: void pluginsChanged(); private: void loadPlugins(); private: PanelPluginHandlerPrivate* d; }; } #endif /* _PANELPLUGINHANDLER_H */ diff --git a/src/commonfrontend/cantorWorksheet/CantorWorksheetView.h b/src/commonfrontend/cantorWorksheet/CantorWorksheetView.h index fdddeaeac..c2c4b3d86 100644 --- a/src/commonfrontend/cantorWorksheet/CantorWorksheetView.h +++ b/src/commonfrontend/cantorWorksheet/CantorWorksheetView.h @@ -1,96 +1,96 @@ /*************************************************************************** File : CantorWorksheetView.h Project : LabPlot Description : View class for CantorWorksheet -------------------------------------------------------------------- Copyright : (C) 2015 Garvit Khatri (garvitdelhi@gmail.com) ***************************************************************************/ /*************************************************************************** * * * 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 CANTORWORKSHEETVIEW_H #define CANTORWORKSHEETVIEW_H #include #include class QAbstractItemModel; class QToolBar; class QMenu; class CantorWorksheet; namespace KParts { class ReadWritePart; } class CantorWorksheetView : public QWidget { Q_OBJECT public: CantorWorksheetView(CantorWorksheet*); - ~CantorWorksheetView(); + ~CantorWorksheetView() override; public slots: void createContextMenu(QMenu*) const; void fillToolBar(QToolBar*); private slots: void triggerCantorAction(QAction*); private: CantorWorksheet* m_worksheet; QAction* m_restartBackendAction; QAction* m_evaluateWorsheetAction; QAction* m_evaluateEntryAction; QAction* m_insertCommandEntryAction; QAction* m_insertTextEntryAction; QAction* m_insertLatexEntryAction; QAction* m_insertPageBreakAction; QAction* m_removeCurrentEntryAction; QAction* m_computeEigenvectorsAction; QAction* m_createMattrixAction; QAction* m_computeEigenvaluesAction; QAction* m_invertMattrixAction; QAction* m_differentiationAction; QAction* m_integrationAction; QAction* m_solveEquationsAction; QAction* m_zoomIn; QAction* m_zoomOut; QAction* m_find; QAction* m_replace; QAction* m_syntaxHighlighting; QAction* m_lineNumbers; QAction* m_animateWorksheet; QAction* m_latexTypesetting; QAction* m_showCompletion; QMenu* m_worksheetMenu; QMenu* m_linearAlgebraMenu; QMenu* m_calculateMenu; QMenu* m_settingsMenu; KParts::ReadWritePart* part; void initActions(); void initMenus(); private slots: void statusChanged(Cantor::Session::Status); }; #endif // CANTORWORKSHEETVIEW_H diff --git a/src/commonfrontend/core/PartMdiView.h b/src/commonfrontend/core/PartMdiView.h index bcebf4f94..eaa74e03e 100644 --- a/src/commonfrontend/core/PartMdiView.h +++ b/src/commonfrontend/core/PartMdiView.h @@ -1,54 +1,54 @@ /*************************************************************************** File : PartMdiView.h Project : LabPlot Description : QMdiSubWindow wrapper for aspect views. -------------------------------------------------------------------- Copyright : (C) 2013 by Alexander Semke (alexander.semke@web.de) Copyright : (C) 2007,2008 Tilman Benkert (thzs@gmx.net) Copyright : (C) 2007,2008 Knut Franke (knut.franke@gmx.de) ***************************************************************************/ /*************************************************************************** * * * 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 PART_MDI_VIEW_H #define PART_MDI_VIEW_H #include class AbstractAspect; class AbstractPart; class PartMdiView : public QMdiSubWindow { Q_OBJECT public: explicit PartMdiView(AbstractPart* part); AbstractPart* part() const; private: - void closeEvent(QCloseEvent*); + void closeEvent(QCloseEvent*) override; AbstractPart* m_part; private slots: void handleAspectDescriptionChanged(const AbstractAspect*); void handleAspectAboutToBeRemoved(const AbstractAspect*); }; #endif // ifndef PART_MDI_VIEW_H diff --git a/src/commonfrontend/datapicker/DatapickerImageView.h b/src/commonfrontend/datapicker/DatapickerImageView.h index 98d54ecc8..32e5186be 100644 --- a/src/commonfrontend/datapicker/DatapickerImageView.h +++ b/src/commonfrontend/datapicker/DatapickerImageView.h @@ -1,143 +1,143 @@ /*************************************************************************** File : DatapickerImageView.h Project : LabPlot Description : DatapickerImage view for datapicker -------------------------------------------------------------------- Copyright : (C) 2015 by Ankit Wagadre (wagadre.ankit@gmail.com) ***************************************************************************/ /*************************************************************************** * * * 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 DATAPICKERIMAGEVIEW_H #define DATAPICKERIMAGEVIEW_H #include "commonfrontend/worksheet/WorksheetView.h" class QMenu; class QToolBar; class QToolButton; class QWheelEvent; class AbstractAspect; class DatapickerImage; class Datapicker; class Transform; class QActionGroup; class QPrinter; class DatapickerImageView : public QGraphicsView { Q_OBJECT public: explicit DatapickerImageView(DatapickerImage* image); - ~DatapickerImageView(); + ~DatapickerImageView() override; void setScene(QGraphicsScene*); void exportToFile(const QString&, const WorksheetView::ExportFormat, const int); private: enum MouseMode {SelectAndEditMode, NavigationMode, ZoomSelectionMode, SelectAndMoveMode}; void initActions(); void initMenus(); - void drawForeground(QPainter*, const QRectF&); - void drawBackground(QPainter*, const QRectF&); + void drawForeground(QPainter*, const QRectF&) override; + void drawBackground(QPainter*, const QRectF&) override; void exportPaint(QPainter* painter, const QRectF& targetRect, const QRectF& sourceRect); //events - void contextMenuEvent(QContextMenuEvent*); - void wheelEvent(QWheelEvent*); - void mousePressEvent(QMouseEvent*); - void mouseReleaseEvent(QMouseEvent*); - void mouseMoveEvent(QMouseEvent*); + void contextMenuEvent(QContextMenuEvent*) override; + void wheelEvent(QWheelEvent*) override; + void mousePressEvent(QMouseEvent*) override; + void mouseReleaseEvent(QMouseEvent*) override; + void mouseMoveEvent(QMouseEvent*) override; DatapickerImage* m_image; Datapicker* m_datapicker; Transform* m_transform; MouseMode m_mouseMode; bool m_selectionBandIsShown; QPoint m_selectionStart; QPoint m_selectionEnd; int magnificationFactor; float m_rotationAngle; //Menus QMenu* m_zoomMenu; QMenu* m_viewMouseModeMenu; QMenu* m_viewImageMenu; QMenu* m_navigationMenu; QMenu* m_magnificationMenu; QToolButton* tbZoom; QAction* currentZoomAction; //Actions QAction* zoomInViewAction; QAction* zoomOutViewAction; QAction* zoomOriginAction; QAction* zoomFitPageHeightAction; QAction* zoomFitPageWidthAction; QAction* setAxisPointsAction; QAction* setCurvePointsAction; QAction* selectSegmentAction; QAction* addCurveAction; QAction* navigationModeAction; QAction* zoomSelectionModeAction; QAction* selectAndEditModeAction; QAction* selectAndMoveModeAction; QActionGroup* navigationActionGroup; QAction* shiftLeftAction; QAction* shiftRightAction; QAction* shiftDownAction; QAction* shiftUpAction; QActionGroup* magnificationActionGroup; QAction* noMagnificationAction; QAction* twoTimesMagnificationAction; QAction* threeTimesMagnificationAction; QAction* fourTimesMagnificationAction; QAction* fiveTimesMagnificationAction; public slots: void createContextMenu(QMenu*) const; void fillToolBar(QToolBar*); void print(QPrinter*); private slots: void mouseModeChanged(QAction*); void magnificationChanged(QAction*); void changeZoom(QAction*); void changeSelectedItemsPosition(QAction*); void changePointsType(QAction*); void handleImageActions(); void updateBackground(); void addCurve(); void changeRotationAngle(); signals: void statusInfo(const QString&); }; #endif diff --git a/src/commonfrontend/datapicker/DatapickerView.h b/src/commonfrontend/datapicker/DatapickerView.h index bf60d2d6d..78d6fd6fa 100644 --- a/src/commonfrontend/datapicker/DatapickerView.h +++ b/src/commonfrontend/datapicker/DatapickerView.h @@ -1,68 +1,68 @@ /*************************************************************************** File : DatapickerView.h Project : LabPlot Description : View class for Datapicker -------------------------------------------------------------------- Copyright : (C) 2015 by Ankit Wagadre (wagadre.ankit@gmail.com) Copyright : (C) 2015 by Alexander Semke (alexander.semke@web.de) ***************************************************************************/ /*************************************************************************** * * * 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 DATAPICKERVIEW_H #define DATAPICKERVIEW_H #include class AbstractAspect; class Datapicker; class TabWidget; class QMenu; class QToolBar; class DatapickerView : public QWidget { Q_OBJECT public: explicit DatapickerView(Datapicker*); - virtual ~DatapickerView(); + ~DatapickerView() override; void createContextMenu(QMenu*) const; void fillToolBar(QToolBar*); int currentIndex() const; private: TabWidget* m_tabWidget; Datapicker* m_datapicker; int lastSelectedIndex; bool m_initializing; private slots: void showTabContextMenu(const QPoint&); void itemSelected(int); void tabChanged(int); void tabMoved(int,int); void handleDescriptionChanged(const AbstractAspect*); void handleAspectAdded(const AbstractAspect*); void handleAspectAboutToBeRemoved(const AbstractAspect*); }; #endif diff --git a/src/commonfrontend/matrix/MatrixView.h b/src/commonfrontend/matrix/MatrixView.h index f1703719c..3591e13cf 100644 --- a/src/commonfrontend/matrix/MatrixView.h +++ b/src/commonfrontend/matrix/MatrixView.h @@ -1,176 +1,176 @@ /*************************************************************************** File : MatrixView.cpp Project : LabPlot Description : View class for Matrix -------------------------------------------------------------------- Copyright : (C) 2015 Alexander Semke (alexander.semke@web.de) Copyright : (C) 2008-2009 Tilman Benkert (thzs@gmx.net) ***************************************************************************/ /*************************************************************************** * * * 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 MATRIXVIEW_H #define MATRIXVIEW_H #include #include #include #include "backend/datasources/filters/FITSFilter.h" #include "kdefrontend/widgets/FITSHeaderEditWidget.h" class Matrix; class MatrixModel; class QAction; class QLabel; class QMenu; class QStackedWidget; class QTableView; class MatrixView : public QWidget { Q_OBJECT public: explicit MatrixView(Matrix*); - virtual ~MatrixView(); + ~MatrixView() override; MatrixModel* model() const; int selectedColumnCount(bool full = false) const; bool isColumnSelected(int col, bool full = false) const; int selectedRowCount(bool full = false) const; bool isRowSelected(int row, bool full = false) const; int firstSelectedColumn(bool full = false) const; int lastSelectedColumn(bool full = false) const; int firstSelectedRow(bool full = false) const; int lastSelectedRow(bool full = false) const; bool isCellSelected(int row, int col) const; void setCellSelected(int row, int col); void setCellsSelected(int first_row, int first_col, int last_row, int last_col); void getCurrentCell(int* row, int* col) const; void resizeHeaders(); void adjustHeaders(); void exportToFile(const QString& path, const QString& separator) const; void exportToLaTeX(const QString&, const bool verticalHeaders, const bool horizontalHeaders, const bool latexHeaders, const bool gridLines, const bool entire, const bool captions) const; void exportToFits(const QString& fileName, const int exportTo) const; public slots: void createContextMenu(QMenu*) const; void print(QPrinter*) const; private: void init(); void initActions(); void initMenus(); void connectActions(); void goToCell(int row, int col); void updateImage(); - bool eventFilter(QObject*, QEvent*); - virtual void keyPressEvent(QKeyEvent*); + bool eventFilter(QObject*, QEvent*) override; + void keyPressEvent(QKeyEvent*) override; QStackedWidget* m_stackedWidget; QTableView* m_tableView; QLabel* m_imageLabel; Matrix* m_matrix; MatrixModel* m_model; QImage m_image; bool m_imageIsDirty; //Actions QAction* action_cut_selection; QAction* action_copy_selection; QAction* action_paste_into_selection; QAction* action_clear_selection; QAction* action_select_all; QAction* action_clear_matrix; QAction* action_go_to_cell; QAction* action_set_formula; QAction* action_recalculate; QAction* action_duplicate; QAction* action_transpose; QAction* action_mirror_vertically; QAction* action_mirror_horizontally; QAction* action_header_format_1; QAction* action_header_format_2; QAction* action_header_format_3; QAction* action_insert_columns; QAction* action_remove_columns; QAction* action_clear_columns; QAction* action_add_columns; QAction* action_statistics_columns; QAction* action_insert_rows; QAction* action_remove_rows; QAction* action_clear_rows; QAction* action_add_rows; QAction* action_statistics_rows; QAction* action_data_view; QAction* action_image_view; QAction* action_fill_function; QAction* action_fill_const; //Menus QMenu* m_selectionMenu; QMenu* m_columnMenu; QMenu* m_rowMenu; QMenu* m_matrixMenu; QMenu* m_headerFormatMenu; private slots: void goToCell(); void advanceCell(); void handleHorizontalSectionResized(int logicalIndex, int oldSize, int newSize); void handleVerticalSectionResized(int logicalIndex, int oldSize, int newSize); void switchView(QAction*); void matrixDataChanged(); void fillWithFunctionValues(); void fillWithConstValues(); void cutSelection(); void copySelection(); void pasteIntoSelection(); void clearSelectedCells(); void headerFormatChanged(QAction*); void addColumns(); void insertEmptyColumns(); void removeSelectedColumns(); void clearSelectedColumns(); void addRows(); void insertEmptyRows(); void removeSelectedRows(); void clearSelectedRows(); void showColumnStatistics(); void showRowStatistics(); }; #endif diff --git a/src/commonfrontend/spreadsheet/SpreadsheetView.h b/src/commonfrontend/spreadsheet/SpreadsheetView.h index 81f6b8bac..505f9e41b 100644 --- a/src/commonfrontend/spreadsheet/SpreadsheetView.h +++ b/src/commonfrontend/spreadsheet/SpreadsheetView.h @@ -1,265 +1,265 @@ /*************************************************************************** File : SpreadsheetView.h Project : LabPlot Description : View class for Spreadsheet -------------------------------------------------------------------- Copyright : (C) 2010-2015 by Alexander Semke (alexander.semke@web.de) ***************************************************************************/ /*************************************************************************** * * * 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 SPREADSHEETVIEW_H #define SPREADSHEETVIEW_H #include #include "backend/core/AbstractColumn.h" #include "backend/lib/IntervalAttribute.h" class Column; class Spreadsheet; class SpreadsheetModel; class SpreadsheetItemDelegate; class SpreadsheetHeaderView; class AbstractAspect; class QTableView; class QPrinter; class QMenu; class QToolBar; class QModelIndex; class QItemSelection; class SpreadsheetView : public QWidget { Q_OBJECT public: explicit SpreadsheetView(Spreadsheet* spreadsheet, bool readOnly = false); - virtual ~SpreadsheetView(); + ~SpreadsheetView() override; void resizeHeader(); void showComments(bool on = true); bool areCommentsShown() const; int selectedColumnCount(bool full = false) const; int selectedColumnCount(AbstractColumn::PlotDesignation) const; bool isColumnSelected(int col, bool full = false) const; QVector selectedColumns(bool full = false) const; int firstSelectedColumn(bool full = false) const; int lastSelectedColumn(bool full = false) const; bool isRowSelected(int row, bool full = false) const; int firstSelectedRow(bool full = false) const; int lastSelectedRow(bool full = false) const; IntervalAttribute selectedRows(bool full = false) const; bool isCellSelected(int row, int col) const; void setCellSelected(int row, int col, bool select = true); void setCellsSelected(int first_row, int first_col, int last_row, int last_col, bool select = true); void getCurrentCell(int* row, int* col) const; bool exportView(); bool printView(); bool printPreview(); private: void init(); void initActions(); void initMenus(); void connectActions(); void exportToFile(const QString&, const bool, const QString&) const; void exportToLaTeX(const QString&, const bool exportHeaders, const bool gridLines, const bool captions, const bool latexHeaders, const bool skipEmptyRows,const bool exportEntire) const; void exportToFits(const QString &fileName, const int exportTo, const bool commentsAsUnits) const; QTableView* m_tableView; Spreadsheet* m_spreadsheet; SpreadsheetItemDelegate* m_delegate; SpreadsheetModel* m_model; SpreadsheetHeaderView* m_horizontalHeader; bool m_suppressSelectionChangedEvent; bool m_readOnly; - bool eventFilter(QObject*, QEvent*); + bool eventFilter(QObject*, QEvent*) override; void checkColumnMenu(); void checkSpreadsheetMenu(); //selection related actions QAction* action_cut_selection; QAction* action_copy_selection; QAction* action_paste_into_selection; QAction* action_mask_selection; QAction* action_unmask_selection; QAction* action_clear_selection; // QAction* action_set_formula; // QAction* action_recalculate; QAction* action_fill_row_numbers; QAction* action_fill_sel_row_numbers; QAction* action_fill_random; QAction* action_fill_equidistant; QAction* action_fill_random_nonuniform; QAction* action_fill_const; QAction* action_fill_function; //spreadsheet related actions QAction* action_toggle_comments; QAction* action_select_all; QAction* action_add_column; QAction* action_clear_spreadsheet; QAction* action_clear_masks; QAction* action_sort_spreadsheet; QAction* action_go_to_cell; QAction* action_statistics_all_columns; //column related actions QAction* action_insert_columns; QAction* action_remove_columns; QAction* action_clear_columns; QAction* action_add_columns; QAction* action_set_as_none; QAction* action_set_as_x; QAction* action_set_as_y; QAction* action_set_as_z; QAction* action_set_as_xerr; QAction* action_set_as_xerr_plus; QAction* action_set_as_xerr_minus; QAction* action_set_as_yerr; QAction* action_set_as_yerr_plus; QAction* action_set_as_yerr_minus; QAction* action_reverse_columns; QAction* action_drop_values; QAction* action_mask_values; QAction* action_join_columns; QAction* action_normalize_columns; QAction* action_normalize_selection; QAction* action_sort_columns; QAction* action_sort_asc_column; QAction* action_sort_desc_column; QAction* action_statistics_columns; //row related actions QAction* action_insert_rows; QAction* action_remove_rows; QAction* action_clear_rows; QAction* action_add_rows; QAction* action_statistics_rows; //analysis and plot data menu actions QAction* action_plot_data; QAction* addDataOperationAction; QAction* addDataReductionAction; QAction* addDifferentiationAction; QAction* addIntegrationAction; QAction* addInterpolationAction; QAction* addSmoothAction; QVector addFitAction; QAction* addFourierFilterAction; //Menus QMenu* m_selectionMenu; QMenu* m_columnMenu; QMenu* m_columnGenerateDataMenu; QMenu* m_columnSortMenu; QMenu* m_rowMenu; QMenu* m_spreadsheetMenu; public slots: void createContextMenu(QMenu*); void fillToolBar(QToolBar*); void print(QPrinter*) const; private slots: void createColumnContextMenu(QMenu*); void goToCell(int row, int col); void toggleComments(); void goToNextColumn(); void goToPreviousColumn(); void goToCell(); void sortSpreadsheet(); void sortDialog(QVector); void cutSelection(); void copySelection(); void pasteIntoSelection(); void clearSelectedCells(); void maskSelection(); void unmaskSelection(); // void recalculateSelectedCells(); void plotData(); void fillSelectedCellsWithRowNumbers(); void fillWithRowNumbers(); void fillSelectedCellsWithRandomNumbers(); void fillWithRandomValues(); void fillWithEquidistantValues(); void fillWithFunctionValues(); void fillSelectedCellsWithConstValues(); void addRows(); void insertEmptyRows(); void removeSelectedRows(); void clearSelectedRows(); void addColumns(); void insertEmptyColumns(); void removeSelectedColumns(); void clearSelectedColumns(); void reverseColumns(); void dropColumnValues(); void maskColumnValues(); void joinColumns(); void normalizeSelectedColumns(); void normalizeSelection(); void sortSelectedColumns(); void sortColumnAscending(); void sortColumnDescending(); void setSelectionAs(); void activateFormulaMode(bool on); bool formulaModeActive() const; void showColumnStatistics(bool forAll = false); void showAllColumnsStatistics(); void showRowStatistics(); void handleHorizontalSectionResized(int logicalIndex, int oldSize, int newSize); void handleHorizontalSectionMoved(int index, int from, int to); void handleHorizontalHeaderDoubleClicked(int index); void handleHeaderDataChanged(Qt::Orientation orientation, int first, int last); void currentColumnChanged(const QModelIndex& current, const QModelIndex & previous); void handleAspectAdded(const AbstractAspect*); void handleAspectAboutToBeRemoved(const AbstractAspect*); void updateHeaderGeometry(Qt::Orientation o, int first, int last); void selectColumn(int); void deselectColumn(int); void columnClicked(int); void selectionChanged(const QItemSelection& selected, const QItemSelection& deselected); }; #endif diff --git a/src/commonfrontend/workbook/WorkbookView.h b/src/commonfrontend/workbook/WorkbookView.h index 2e2c95ebd..d92b944b9 100644 --- a/src/commonfrontend/workbook/WorkbookView.h +++ b/src/commonfrontend/workbook/WorkbookView.h @@ -1,86 +1,86 @@ /*************************************************************************** File : WorkbookView.h Project : LabPlot Description : View class for Workbook -------------------------------------------------------------------- Copyright : (C) 2015 by Alexander Semke (alexander.semke@web.de) ***************************************************************************/ /*************************************************************************** * * * 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 WORKBOOKVIEW_H #define WORKBOOKVIEW_H #include #include class AbstractAspect; class Workbook; class QAction; class QMenu; class QPrinter; class QToolBar; class TabWidget : public QTabWidget { Q_OBJECT public: explicit TabWidget(QWidget* parent) : QTabWidget(parent) { connect(tabBar(),SIGNAL(tabMoved(int,int)),this, SIGNAL(tabMoved(int,int))); } signals: void tabMoved(int, int); }; class WorkbookView : public QWidget { Q_OBJECT public: explicit WorkbookView(Workbook*); - virtual ~WorkbookView(); + ~WorkbookView() override; int currentIndex() const; private: TabWidget* m_tabWidget; Workbook* m_workbook; int lastSelectedIndex; bool m_initializing; //actions QAction* action_add_spreadsheet; QAction* action_add_matrix; private slots: void createContextMenu(QMenu*) const; void showTabContextMenu(const QPoint&); void addSpreadsheet(); void addMatrix(); void itemSelected(int); void tabChanged(int); void tabMoved(int,int); void handleDescriptionChanged(const AbstractAspect*); void handleAspectAdded(const AbstractAspect*); void handleAspectAboutToBeRemoved(const AbstractAspect*); }; #endif diff --git a/src/commonfrontend/worksheet/WorksheetView.h b/src/commonfrontend/worksheet/WorksheetView.h index 58829dc7c..d17bafa54 100644 --- a/src/commonfrontend/worksheet/WorksheetView.h +++ b/src/commonfrontend/worksheet/WorksheetView.h @@ -1,272 +1,272 @@ /*************************************************************************** File : WorksheetView.h Project : LabPlot Description : Worksheet view -------------------------------------------------------------------- Copyright : (C) 2009-2016 by Alexander Semke (alexander.semke@web.de) ***************************************************************************/ /*************************************************************************** * * * 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 WORKSHEETVIEW_H #define WORKSHEETVIEW_H #include #include "backend/worksheet/Worksheet.h" #include "backend/worksheet/plots/cartesian/CartesianPlot.h" #include class QMenu; class QToolBar; class QToolButton; class QWheelEvent; class QTimeLine; class AbstractAspect; class WorksheetElement; class WorksheetView : public QGraphicsView { Q_OBJECT public: explicit WorksheetView(Worksheet* worksheet); enum ExportFormat {Pdf, Svg, Png}; enum GridStyle {NoGrid, LineGrid, DotGrid}; enum ExportArea {ExportBoundingBox, ExportSelection, ExportWorksheet}; struct GridSettings { GridStyle style; QColor color; int horizontalSpacing; int verticalSpacing; double opacity; }; void setScene(QGraphicsScene*); void exportToFile(const QString&, const ExportFormat, const ExportArea, const bool, const int); void exportToClipboard(); void setIsClosing(); void setIsBeingPresented(bool presenting); private: enum MouseMode {SelectionMode, NavigationMode, ZoomSelectionMode}; enum CartesianPlotActionMode {ApplyActionToSelection, ApplyActionToAll}; void initActions(); void initMenus(); void processResize(); void drawForeground(QPainter*, const QRectF&) override; void drawBackground(QPainter*, const QRectF&) override; void drawBackgroundItems(QPainter*, const QRectF&); bool isPlotAtPos(const QPoint&) const; CartesianPlot* plotAt(const QPoint&) const; void exportPaint(QPainter* painter, const QRectF& targetRect, const QRectF& sourceRect, const bool); void cartesianPlotAdd(CartesianPlot*, QAction*); //events - virtual void resizeEvent(QResizeEvent*) override; - virtual void contextMenuEvent(QContextMenuEvent*) override; - virtual void wheelEvent(QWheelEvent*) override; - virtual void mousePressEvent(QMouseEvent*) override; - virtual void mouseReleaseEvent(QMouseEvent*) override; - virtual void mouseMoveEvent(QMouseEvent*) override; - virtual void keyPressEvent(QKeyEvent*) override; - virtual void dragEnterEvent(QDragEnterEvent*) override; - virtual void dragMoveEvent(QDragMoveEvent*) override; - virtual void dropEvent(QDropEvent*) override; + void resizeEvent(QResizeEvent*) override; + void contextMenuEvent(QContextMenuEvent*) override; + void wheelEvent(QWheelEvent*) override; + void mousePressEvent(QMouseEvent*) override; + void mouseReleaseEvent(QMouseEvent*) override; + void mouseMoveEvent(QMouseEvent*) override; + void keyPressEvent(QKeyEvent*) override; + void dragEnterEvent(QDragEnterEvent*) override; + void dragMoveEvent(QDragMoveEvent*) override; + void dropEvent(QDropEvent*) override; Worksheet* m_worksheet; MouseMode m_mouseMode; CartesianPlotActionMode m_cartesianPlotActionMode; CartesianPlot::MouseMode m_cartesianPlotMouseMode; bool m_selectionBandIsShown; QPoint m_selectionStart; QPoint m_selectionEnd; int magnificationFactor; QGraphicsPixmapItem* m_magnificationWindow; GridSettings m_gridSettings; QList m_selectedItems; bool m_suppressSelectionChangedEvent; WorksheetElement* lastAddedWorksheetElement; QTimeLine* m_fadeInTimeLine; QTimeLine* m_fadeOutTimeLine; bool m_isClosing; bool m_menusInitialized; //Menus QMenu* m_addNewMenu; QMenu* m_addNewCartesianPlotMenu; QMenu* m_zoomMenu; QMenu* m_magnificationMenu; QMenu* m_layoutMenu; QMenu* m_gridMenu; QMenu* m_themeMenu; QMenu* m_viewMouseModeMenu; QMenu* m_cartesianPlotMenu; QMenu* m_cartesianPlotMouseModeMenu; QMenu* m_cartesianPlotAddNewMenu; QMenu* m_cartesianPlotZoomMenu; QMenu* m_cartesianPlotActionModeMenu; QMenu* m_dataManipulationMenu; QToolButton* tbNewCartesianPlot; QToolButton* tbZoom; QToolButton* tbMagnification; QAction* currentZoomAction; QAction* currentMagnificationAction; //Actions QAction* selectAllAction; QAction* deleteAction; QAction* backspaceAction; QAction* zoomInViewAction; QAction* zoomOutViewAction; QAction* zoomOriginAction; QAction* zoomFitPageHeightAction; QAction* zoomFitPageWidthAction; QAction* zoomFitSelectionAction; QAction* navigationModeAction; QAction* zoomSelectionModeAction; QAction* selectionModeAction; QAction* addCartesianPlot1Action; QAction* addCartesianPlot2Action; QAction* addCartesianPlot3Action; QAction* addCartesianPlot4Action; QAction* addTextLabelAction; QAction* addHistogram; QAction* addBarChartPlot; QAction* verticalLayoutAction; QAction* horizontalLayoutAction; QAction* gridLayoutAction; QAction* breakLayoutAction; QAction* noGridAction; QAction* denseLineGridAction; QAction* sparseLineGridAction; QAction* denseDotGridAction; QAction* sparseDotGridAction; QAction* customGridAction; QAction* snapToGridAction; QAction* noMagnificationAction; QAction* twoTimesMagnificationAction; QAction* threeTimesMagnificationAction; QAction* fourTimesMagnificationAction; QAction* fiveTimesMagnificationAction; QAction* showPresenterMode; //Actions for cartesian plots QAction* cartesianPlotApplyToSelectionAction; QAction* cartesianPlotApplyToAllAction; QAction* cartesianPlotSelectionModeAction; QAction* cartesianPlotZoomSelectionModeAction; QAction* cartesianPlotZoomXSelectionModeAction; QAction* cartesianPlotZoomYSelectionModeAction; QAction* addCurveAction; QAction* addEquationCurveAction; QAction* addDataOperationCurveAction; QAction* addDataReductionCurveAction; QAction* addDifferentiationCurveAction; QAction* addIntegrationCurveAction; QAction* addInterpolationCurveAction; QAction* addSmoothCurveAction; QAction* addFitCurveAction; QAction* addFourierFilterCurveAction; QAction* addFourierTransformCurveAction; QAction* addHorizontalAxisAction; QAction* addVerticalAxisAction; QAction* addLegendAction; QAction* addCustomPointAction; QAction* scaleAutoXAction; QAction* scaleAutoYAction; QAction* scaleAutoAction; QAction* zoomInAction; QAction* zoomOutAction; QAction* zoomInXAction; QAction* zoomOutXAction; QAction* zoomInYAction; QAction* zoomOutYAction; QAction* shiftLeftXAction; QAction* shiftRightXAction; QAction* shiftUpYAction; QAction* shiftDownYAction; // Analysis menu QAction* addDataOperationAction; QAction* addDataReductionAction; QAction* addDifferentiationAction; QAction* addIntegrationAction; QAction* addInterpolationAction; QAction* addSmoothAction; QAction* addFitAction; QAction* addFourierFilterAction; QAction* addFourierTransformAction; public slots: void createContextMenu(QMenu*); void createAnalysisMenu(QMenu*); void fillToolBar(QToolBar*); void fillCartesianPlotToolBar(QToolBar*); void print(QPrinter*); void selectItem(QGraphicsItem*); void presenterMode(); private slots: void addNew(QAction*); void aspectAboutToBeRemoved(const AbstractAspect*); void selectAllElements(); void deleteElement(); void mouseModeChanged(QAction*); void useViewSizeRequested(); void changeZoom(QAction*); void magnificationChanged(QAction*); void changeLayout(QAction*); void changeGrid(QAction*); void changeSnapToGrid(); void deselectItem(QGraphicsItem*); void selectionChanged(); void updateBackground(); void layoutChanged(Worksheet::Layout); void fadeIn(qreal); void fadeOut(qreal); //SLOTs for cartesian plots void cartesianPlotActionModeChanged(QAction*); void cartesianPlotMouseModeChanged(QAction*); void cartesianPlotNavigationChanged(QAction*); void cartesianPlotAddNew(QAction*); void handleCartesianPlotActions(); signals: void statusInfo(const QString&); }; #endif diff --git a/src/kdefrontend/spreadsheet/ExportSpreadsheetDialog.h b/src/kdefrontend/spreadsheet/ExportSpreadsheetDialog.h index 0ade818c8..7b6eea158 100644 --- a/src/kdefrontend/spreadsheet/ExportSpreadsheetDialog.h +++ b/src/kdefrontend/spreadsheet/ExportSpreadsheetDialog.h @@ -1,95 +1,95 @@ /*************************************************************************** File : ExportSpreadsheetDialog.h Project : LabPlot Description : export spreadsheet dialog -------------------------------------------------------------------- Copyright : (C) 2014-2017 by Alexander Semke (alexander.semke@web.de) ***************************************************************************/ /*************************************************************************** * * * 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 EXPORTSPREADSHEETDIALOG_H #define EXPORTSPREADSHEETDIALOG_H #include namespace Ui { class ExportSpreadsheetWidget; } class QPushButton; class QAbstractButton; class ExportSpreadsheetDialog : public QDialog { Q_OBJECT public: explicit ExportSpreadsheetDialog(QWidget*); - virtual ~ExportSpreadsheetDialog(); + ~ExportSpreadsheetDialog() override; QString path() const; void setFileName(const QString&); void setMatrixMode(bool); void setExportSelection(bool); bool exportHeader() const; bool exportLatexHeader() const; bool gridLines() const; bool captions() const; bool skipEmptyRows() const; bool exportSelection() const; bool entireSpreadheet() const; bool matrixVerticalHeader() const; bool matrixHorizontalHeader() const; QString separator() const; int exportToFits() const; bool commentsAsUnitsFits() const; void setExportTo(const QStringList& to); void setExportToImage(bool possible); enum Format { ASCII = 0, Binary, LaTeX, FITS, }; Format format() const; private: Ui::ExportSpreadsheetWidget* ui; bool m_showOptions; bool m_matrixMode; Format m_format; QPushButton* m_showOptionsButton; QPushButton* m_okButton; QPushButton* m_cancelButton; private slots: void setFormat(Format format); void slotButtonClicked(QAbstractButton *); void okClicked(); void toggleOptions(); void selectFile(); void formatChanged(int); void fileNameChanged(const QString&); void fitsExportToChanged(int); void loadSettings(); }; #endif diff --git a/src/kdefrontend/spreadsheet/PlotDataDialog.h b/src/kdefrontend/spreadsheet/PlotDataDialog.h index be950d52a..210e75d9b 100644 --- a/src/kdefrontend/spreadsheet/PlotDataDialog.h +++ b/src/kdefrontend/spreadsheet/PlotDataDialog.h @@ -1,88 +1,88 @@ /*************************************************************************** File : PlotDataDialog.h Project : LabPlot Description : Dialog for generating plots for the spreadsheet data -------------------------------------------------------------------- Copyright : (C) 2017 by Alexander Semke (alexander.semke@web.de) ***************************************************************************/ /*************************************************************************** * * * 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 PLOTDATADIALOG_H #define PLOTDATADIALOG_H namespace Ui { class PlotDataWidget; } #include class QComboBox; class AspectTreeModel; class CartesianPlot; class Column; class Spreadsheet; class TreeViewComboBox; class Worksheet; class PlotDataDialog : public QDialog { Q_OBJECT public: enum AnalysisAction {DataReduction, Differentiation, Integration, Interpolation, Smoothing, FitLinear, FitPower, FitExp1, FitExp2, FitInvExp, FitGauss, FitCauchyLorentz, FitTan, FitTanh, FitErrFunc, FitCustom, FourierFilter}; explicit PlotDataDialog(Spreadsheet*, QWidget* parent = 0, Qt::WFlags fl = 0); - ~PlotDataDialog(); + ~PlotDataDialog() override; void setAnalysisAction(AnalysisAction); private: Ui::PlotDataWidget* ui; QPushButton* m_okButton; Spreadsheet* m_spreadsheet; TreeViewComboBox* cbExistingPlots; TreeViewComboBox* cbExistingWorksheets; QVector m_columns; QVector m_columnComboBoxes; AspectTreeModel* m_plotsModel; AspectTreeModel* m_worksheetsModel; AnalysisAction m_analysisAction; bool m_analysisMode; void processColumns(); void addCurvesToPlot(CartesianPlot*) const; void addCurvesToPlots(Worksheet*) const; void addCurve(const QString& name, Column* xColumn, Column* yColumn, CartesianPlot*) const; Column* columnFromName(const QString&) const; protected slots: virtual void checkOkButton(); private slots: void plot(); void curvePlacementChanged(); void plotPlacementChanged(); void loadSettings(); }; #endif diff --git a/src/kdefrontend/widgets/FITSHeaderEditWidget.h b/src/kdefrontend/widgets/FITSHeaderEditWidget.h index 8f3ee9149..1353fba03 100644 --- a/src/kdefrontend/widgets/FITSHeaderEditWidget.h +++ b/src/kdefrontend/widgets/FITSHeaderEditWidget.h @@ -1,100 +1,100 @@ /*************************************************************************** File : FITSHeaderEditWidget.h Project : LabPlot Description : Widget for listing/editing FITS header keywords -------------------------------------------------------------------- Copyright : (C) 2016 by Fabian Kristof (fkristofszabolcs@gmail.com) ***************************************************************************/ /*************************************************************************** * * * 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 FITSHEADEREDITWIDGET_H #define FITSHEADEREDITWIDGET_H #include #include "backend/datasources/filters/FITSFilter.h" namespace Ui { class FITSHeaderEditWidget; } class FITSHeaderEditWidget : public QWidget { Q_OBJECT public: explicit FITSHeaderEditWidget(QWidget *parent = 0); - ~FITSHeaderEditWidget(); + ~FITSHeaderEditWidget() override; private: Ui::FITSHeaderEditWidget* ui; QAction* m_action_remove_keyword; QAction* m_action_add_keyword; QAction* m_action_addmodify_unit; QAction* m_action_remove_extension; QMenu* m_KeywordActionsMenu; QMenu* m_ExtensionActionsMenu; struct HeaderUpdate { QList newKeywords; QVector updatedKeywords; QList removedKeywords; }; struct ExtensionData { HeaderUpdate updates; QList keywords; }; QMap m_extensionDatas; QStringList m_removedExtensions; QString m_seletedExtension; FITSFilter* m_fitsFilter; bool m_initializingTable; void initActions(); void initContextMenus(); void connectActions(); void fillTable(); QList mandatoryKeywords() const; - bool eventFilter(QObject*, QEvent*); + bool eventFilter(QObject*, QEvent*) override; public slots: bool save(); private slots: void openFile(); void fillTableSlot(QTreeWidgetItem* item, int col); void updateKeyword(QTableWidgetItem*); void removeKeyword(); void removeExtension(); void addKeyword(); void addModifyKeywordUnit(); void closeFile(); void enableButtonCloseFile(QTreeWidgetItem *, int); void enableButtonAddUnit(); signals: void changed(bool); }; #endif // FITSHEADEREDITWIDGET_H diff --git a/src/kdefrontend/worksheet/ExportWorksheetDialog.h b/src/kdefrontend/worksheet/ExportWorksheetDialog.h index 17bc0cb3c..c15ad81e9 100644 --- a/src/kdefrontend/worksheet/ExportWorksheetDialog.h +++ b/src/kdefrontend/worksheet/ExportWorksheetDialog.h @@ -1,73 +1,73 @@ /*************************************************************************** File : ExportWorksheetDialog.h Project : LabPlot Description : export worksheet dialog -------------------------------------------------------------------- Copyright : (C) 2011-2016 by Alexander Semke (alexander.semke@web.de) ***************************************************************************/ /*************************************************************************** * * * 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 EXPORTWORKSHEETDIALOG_H #define EXPORTWORKSHEETDIALOG_H #include #include "commonfrontend/worksheet/WorksheetView.h" namespace Ui { class ExportWorksheetWidget; } class QPushButton; class QAbstractButton; class ExportWorksheetDialog : public QDialog { Q_OBJECT public: explicit ExportWorksheetDialog(QWidget*); - virtual ~ExportWorksheetDialog(); + ~ExportWorksheetDialog() override; QString path() const; void setFileName(const QString&); WorksheetView::ExportFormat exportFormat() const; WorksheetView::ExportArea exportArea() const; bool exportBackground() const; int exportResolution() const; private: Ui::ExportWorksheetWidget* ui; bool m_showOptions; QPushButton* m_showOptionsButton; QPushButton* m_okButton; QPushButton* m_cancelButton; private slots: void slotButtonClicked(QAbstractButton *); void okClicked(); void toggleOptions(); void selectFile(); void formatChanged(int); void fileNameChanged(const QString&); void loadSettings(); }; #endif