"Fossies" - the Fresh Open Source Software Archive

Member "labplot-2.8.2/src/backend/core/Folder.cpp" (24 Feb 2021, 11282 Bytes) of package /linux/privat/labplot-2.8.2.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "Folder.cpp" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 2.8.1_vs_2.8.2.

    1 /***************************************************************************
    2     File                 : Folder.cpp
    3     Project              : LabPlot
    4     Description          : Folder in a project
    5     --------------------------------------------------------------------
    6     Copyright            : (C) 2009-2015 Alexander Semke (alexander.semke@web.de)
    7     Copyright            : (C) 2007 Tilman Benkert (thzs@gmx.net)
    8     Copyright            : (C) 2007 Knut Franke (knut.franke@gmx.de)
    9 
   10  ***************************************************************************/
   11 
   12 /***************************************************************************
   13  *                                                                         *
   14  *  This program is free software; you can redistribute it and/or modify   *
   15  *  it under the terms of the GNU General Public License as published by   *
   16  *  the Free Software Foundation; either version 2 of the License, or      *
   17  *  (at your option) any later version.                                    *
   18  *                                                                         *
   19  *  This program is distributed in the hope that it will be useful,        *
   20  *  but WITHOUT ANY WARRANTY; without even the implied warranty of         *
   21  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          *
   22  *  GNU General Public License for more details.                           *
   23  *                                                                         *
   24  *   You should have received a copy of the GNU General Public License     *
   25  *   along with this program; if not, write to the Free Software           *
   26  *   Foundation, Inc., 51 Franklin Street, Fifth Floor,                    *
   27  *   Boston, MA  02110-1301  USA                                           *
   28  *                                                                         *
   29  ***************************************************************************/
   30 
   31 #include "backend/core/Folder.h"
   32 #include "backend/datapicker/Datapicker.h"
   33 #include "backend/core/Project.h"
   34 #include "backend/core/Workbook.h"
   35 #include "backend/core/column/Column.h"
   36 #include "backend/datasources/LiveDataSource.h"
   37 #include "backend/matrix/Matrix.h"
   38 #include "backend/note/Note.h"
   39 #include "backend/spreadsheet/Spreadsheet.h"
   40 #ifdef HAVE_CANTOR_LIBS
   41 #include "backend/cantorWorksheet/CantorWorksheet.h"
   42 #endif
   43 #ifdef HAVE_MQTT
   44 #include "backend/datasources/MQTTClient.h"
   45 #endif
   46 #include "backend/worksheet/Worksheet.h"
   47 
   48 #include <QDropEvent>
   49 #include <QIcon>
   50 #include <QMimeData>
   51 #include <KLocalizedString>
   52 
   53 /**
   54  * \class Folder
   55  * \brief Folder in a project
   56  */
   57 
   58 Folder::Folder(const QString &name, AspectType type) : AbstractAspect(name, type) {
   59 }
   60 
   61 QIcon Folder::icon() const {
   62     return QIcon::fromTheme("folder");
   63 }
   64 
   65 /**
   66  * \brief Return a new context menu.
   67  *
   68  * The caller takes ownership of the menu.
   69  */
   70 QMenu* Folder::createContextMenu() {
   71     if (project()
   72 #ifdef HAVE_MQTT
   73         && type() != AspectType::MQTTSubscription
   74 #endif
   75     )
   76         return project()->createFolderContextMenu(this);
   77     return nullptr;
   78 }
   79 
   80 bool Folder::isDraggable() const {
   81     if (dynamic_cast<const Project*>(this))
   82         return false;
   83     else
   84         return true;
   85 }
   86 
   87 QVector<AspectType> Folder::dropableOn() const {
   88     return QVector<AspectType>{AspectType::Folder, AspectType::Project};
   89 }
   90 
   91 void Folder::processDropEvent(const QVector<quintptr>& vec) {
   92     //reparent AbstractPart and Folder objects only
   93     AbstractAspect* lastMovedAspect{nullptr};
   94     for (auto a : vec) {
   95         auto* aspect = reinterpret_cast<AbstractAspect*>(a);
   96         auto* part = dynamic_cast<AbstractPart*>(aspect);
   97         if (part) {
   98             part->reparent(this);
   99             lastMovedAspect = part;
  100         } else {
  101             auto* folder = dynamic_cast<Folder*>(aspect);
  102             if (folder && folder != this) {
  103                 folder->reparent(this);
  104                 lastMovedAspect = folder;
  105             }
  106         }
  107     }
  108 
  109     //select the last moved aspect in the project explorer
  110     if (lastMovedAspect)
  111         lastMovedAspect->setSelected(true);
  112 }
  113 
  114 /**
  115  * \brief Save as XML
  116  */
  117 void Folder::save(QXmlStreamWriter* writer) const {
  118     writer->writeStartElement(QLatin1String("folder"));
  119     writeBasicAttributes(writer);
  120     writeCommentElement(writer);
  121 
  122     for (auto* child : children<AbstractAspect>(ChildIndexFlag::IncludeHidden)) {
  123         writer->writeStartElement(QLatin1String("child_aspect"));
  124         child->save(writer);
  125         writer->writeEndElement(); // "child_aspect"
  126     }
  127     writer->writeEndElement(); // "folder"
  128 }
  129 
  130 /**
  131  * \brief Load from XML
  132  */
  133 bool Folder::load(XmlStreamReader* reader, bool preview) {
  134     if (!readBasicAttributes(reader))
  135         return false;
  136 
  137     // read child elements
  138     while (!reader->atEnd()) {
  139         reader->readNext();
  140 
  141         if (reader->isEndElement()) break;
  142 
  143         if (reader->isStartElement()) {
  144             if (reader->name() == QLatin1String("comment")) {
  145                 if (!readCommentElement(reader))
  146                     return false;
  147             } else if (reader->name() == QLatin1String("child_aspect")) {
  148                 if (!readChildAspectElement(reader, preview))
  149                     return false;
  150             } else {// unknown element
  151                 reader->raiseWarning(i18n("unknown element '%1'", reader->name().toString()));
  152                 if (!reader->skipToEndElement()) return false;
  153             }
  154         }
  155     }
  156 
  157     return !reader->hasError();
  158 }
  159 
  160 void Folder::setPathesToLoad(const QStringList& pathes) {
  161     m_pathesToLoad = pathes;
  162 }
  163 
  164 const QStringList& Folder::pathesToLoad() const {
  165     return m_pathesToLoad;
  166 }
  167 
  168 /**
  169  * \brief Read child aspect from XML
  170  */
  171 bool Folder::readChildAspectElement(XmlStreamReader* reader, bool preview) {
  172     if (!reader->skipToNextTag())
  173         return false;
  174 
  175     if (reader->isEndElement() && reader->name() == QLatin1String("child_aspect"))
  176         return true; // empty element tag
  177 
  178     //check whether we need to skip the loading of the current child aspect
  179     if (!m_pathesToLoad.isEmpty()) {
  180         const QString& name = reader->attributes().value("name").toString(); //name of the current child aspect
  181         const QString childPath = path() + '/' + name; //child's path is not available yet (child not added yet) -> construct it manually
  182 
  183         //skip the current child aspect it is not in the list of aspects to be loaded
  184         if (m_pathesToLoad.indexOf(childPath) == -1) {
  185              //skip to the end of the current element
  186             if (!reader->skipToEndElement())
  187                 return false;
  188 
  189             //skip to the end of the "child_asspect" element
  190             if (!reader->skipToEndElement())
  191                 return false;
  192             return true;
  193         }
  194     }
  195 
  196     QString element_name = reader->name().toString();
  197     if (element_name == QLatin1String("folder")) {
  198         Folder* folder = new Folder(QString());
  199 
  200         if (!m_pathesToLoad.isEmpty()) {
  201             //a child folder to be read -> provide the list of aspects to be loaded to the child folder, too.
  202             //since the child folder and all its children are not added yet (path() returns empty string),
  203             //we need to remove the path of the current child folder from the full pathes provided in m_pathesToLoad.
  204             //E.g. we want to import the path "Project/Folder/Spreadsheet" in the following project
  205             // Project
  206             //        \Spreadsheet
  207             //        \Folder
  208             //               \Spreadsheet
  209             //
  210             //Here, we remove the part "Project/Folder/" and proceed for this child folder with "Spreadsheet" only.
  211             //With this the logic above where it is determined whether to import the child aspect or not works out.
  212 
  213             //manually construct the path of the child folder to be read
  214             const QString& curFolderPath = path()  + '/' + reader->attributes().value("name").toString();
  215 
  216             //remove the path of the current child folder
  217             QStringList pathesToLoadNew;
  218             for (auto path : m_pathesToLoad) {
  219                 if (path.startsWith(curFolderPath))
  220                     pathesToLoadNew << path.right(path.length() - curFolderPath.length());
  221             }
  222 
  223             folder->setPathesToLoad(pathesToLoadNew);
  224         }
  225 
  226         if (!folder->load(reader, preview)) {
  227             delete folder;
  228             return false;
  229         }
  230         addChildFast(folder);
  231     } else if (element_name == QLatin1String("workbook")) {
  232         Workbook* workbook = new Workbook(QString());
  233         if (!workbook->load(reader, preview)) {
  234             delete workbook;
  235             return false;
  236         }
  237         addChildFast(workbook);
  238     } else if (element_name == QLatin1String("spreadsheet")) {
  239         Spreadsheet* spreadsheet = new Spreadsheet(QString(), true);
  240         if (!spreadsheet->load(reader, preview)) {
  241             delete spreadsheet;
  242             return false;
  243         }
  244         addChildFast(spreadsheet);
  245     } else if (element_name == QLatin1String("matrix")) {
  246         Matrix* matrix = new Matrix(QString(), true);
  247         if (!matrix->load(reader, preview)) {
  248             delete matrix;
  249             return false;
  250         }
  251         addChildFast(matrix);
  252     } else if (element_name == QLatin1String("worksheet")) {
  253         Worksheet* worksheet = new Worksheet(QString());
  254         worksheet->setIsLoading(true);
  255         if (!worksheet->load(reader, preview)) {
  256             delete worksheet;
  257             return false;
  258         }
  259         addChildFast(worksheet);
  260         worksheet->setIsLoading(false);
  261     } else if (element_name == QLatin1String("cantorWorksheet")) {
  262 #ifdef HAVE_CANTOR_LIBS
  263         CantorWorksheet* cantorWorksheet = new CantorWorksheet(QLatin1String("null"), true);
  264         if (!cantorWorksheet->load(reader, preview)) {
  265             delete cantorWorksheet;
  266 
  267             //if we only failed to load because of the missing CAS, don't return with false here.
  268             //in this case we continue loading the project and show a warning about missing CAS at the end.
  269             if (!reader->failedCASMissing())
  270                 return false;
  271             else {
  272                 //failed because of the missing CAS. Read until the end of the current
  273                 //element in XML and continue loading the project.
  274                 while (!reader->atEnd()) {
  275                     reader->readNext();
  276                     if (reader->isEndElement() && reader->name() == QLatin1String("cantorWorksheet"))
  277                         break;
  278                 }
  279             }
  280         } else
  281             addChildFast(cantorWorksheet);
  282 #else
  283     if (!preview) {
  284         while (!reader->atEnd()) {
  285             reader->readNext();
  286             if (reader->isEndElement() && reader->name() == QLatin1String("cantorWorksheet"))
  287                 break;
  288 
  289             if (!reader->isStartElement())
  290                 continue;
  291 
  292             if (reader->name() == QLatin1String("general")) {
  293                 const QString& backendName = reader->attributes().value("backend_name").toString().trimmed();
  294                 if (!backendName.isEmpty())
  295                     reader->raiseMissingCASWarning(backendName);
  296             } else
  297                 reader->skipToEndElement();
  298         }
  299     }
  300 #endif
  301 #ifdef HAVE_MQTT
  302     } else if (element_name == QLatin1String("MQTTClient")) {
  303         MQTTClient* client = new MQTTClient(QString());
  304         if (!client->load(reader, preview)) {
  305             delete client;
  306             return false;
  307         }
  308         addChildFast(client);
  309 #endif
  310     } else if (element_name == QLatin1String("liveDataSource")
  311         || element_name == QLatin1String("LiveDataSource")) { //TODO: remove "LiveDataSources" in couple of releases
  312         auto* liveDataSource = new LiveDataSource(QString(), true);
  313         if (!liveDataSource->load(reader, preview)) {
  314             delete liveDataSource;
  315             return false;
  316         }
  317         addChildFast(liveDataSource);
  318     } else if (element_name == QLatin1String("datapicker")) {
  319         Datapicker* datapicker = new Datapicker(QString(), true);
  320         if (!datapicker->load(reader, preview)) {
  321             delete datapicker;
  322             return false;
  323         }
  324         addChildFast(datapicker);
  325     } else if (element_name == QLatin1String("note")) {
  326         Note* note = new Note(QString());
  327         if (!note->load(reader, preview)) {
  328             delete note;
  329             return false;
  330         }
  331         addChildFast(note);
  332     } else {
  333         reader->raiseWarning(i18n("unknown element '%1' found", element_name));
  334         if (!reader->skipToEndElement())
  335             return false;
  336     }
  337 
  338     if (!reader->skipToNextTag()) return false;
  339     return !reader->hasError();
  340 }