File indexing completed on 2024-03-24 17:24:23

0001 /**
0002  * SPDX-FileCopyrightText: (C) 2003 by Sébastien Laoût <slaout@linux62.org>
0003  * SPDX-License-Identifier: GPL-2.0-or-later
0004  */
0005 
0006 #include "basketfactory.h"
0007 
0008 #include <QGraphicsView>
0009 #include <QLocale>
0010 #include <QtCore/QDir>
0011 #include <QtCore/QTextStream>
0012 #include <QtXml/QDomElement>
0013 
0014 #include <KLocalizedString>
0015 #include <KMessageBox>
0016 
0017 #include "basketscene.h"
0018 #include "bnpview.h"
0019 #include "global.h"
0020 #include "note.h" // For balanced column width computation
0021 #include "xmlwork.h"
0022 
0023 /** BasketFactory */
0024 
0025 // TODO: Don't create a basket with a name that already exists!
0026 
0027 QString BasketFactory::newFolderName()
0028 {
0029     QString folderName;
0030     QString fullPath;
0031     QDir dir;
0032 
0033     int i = QDir(Global::basketsFolder()).count();
0034     QString time = QTime::currentTime().toString("hhmmss");
0035 
0036     for (;; ++i) {
0037         folderName = QString("basket%1-%2/").arg(i).arg(time);
0038         fullPath = Global::basketsFolder() + folderName;
0039         dir = QDir(fullPath);
0040         if (!dir.exists()) // OK : The folder do not yet exists :
0041             break;         //  We've found one !
0042     }
0043 
0044     return folderName;
0045 }
0046 
0047 QString BasketFactory::unpackTemplate(const QString &templateName)
0048 {
0049     // Find a name for a new folder and create it:
0050     QString folderName = newFolderName();
0051     QString fullPath = Global::basketsFolder() + folderName;
0052     QDir dir;
0053     if (!dir.mkpath(fullPath)) {
0054         KMessageBox::error(/*parent=*/nullptr, i18n("Sorry, but the folder creation for this new basket has failed."), i18n("Basket Creation Failed"));
0055         return QString();
0056     }
0057 
0058     // Unpack the template file to that folder:
0059     // TODO: REALLY unpack (this hand-creation is temporary, or it could be used in case the template can't be found)
0060     QFile file(fullPath + "/.basket");
0061     if (file.open(QIODevice::WriteOnly)) {
0062         QTextStream stream(&file);
0063         stream.setCodec("UTF-8");
0064         int nbColumns = (templateName == "mindmap" || templateName == "free" ? 0 : templateName.left(1).toInt());
0065         BasketScene *currentBasket = Global::bnpView->currentBasket();
0066         int columnWidth = (currentBasket && nbColumns > 0 ? (currentBasket->graphicsView()->viewport()->width() - (nbColumns - 1) * Note::RESIZER_WIDTH) / nbColumns : 0);
0067         stream << QString(
0068                       "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n"
0069                       "<!DOCTYPE basket>\n"
0070                       "<basket>\n"
0071                       " <properties>\n"
0072                       "  <disposition mindMap=\"%1\" columnCount=\"%2\" free=\"%3\" />\n"
0073                       " </properties>\n"
0074                       " <notes>\n")
0075                       .arg((templateName == "mindmap" ? "true" : "false"), QString::number(nbColumns), (templateName == "free" || templateName == "mindmap" ? "true" : "false"));
0076         if (nbColumns > 0)
0077             for (int i = 0; i < nbColumns; ++i)
0078                 stream << QString("  <group width=\"%1\"></group>\n").arg(columnWidth);
0079         stream << " </notes>\n"
0080                   "</basket>\n";
0081         file.close();
0082         return folderName;
0083     } else {
0084         KMessageBox::error(nullptr, i18n("Sorry, but the template copying for this new basket has failed."), i18n("Basket Creation Failed"));
0085         return QString();
0086     }
0087 }
0088 
0089 void BasketFactory::newBasket(const QString &icon,
0090                               const QString &name,
0091                               BasketScene *parent,
0092                               const QString &backgroundImage,
0093                               const QColor &backgroundColor,
0094                               const QColor &textColor,
0095                               const QString &templateName)
0096 {
0097     // Unpack the templateName file to a new basket folder:
0098     QString folderName = unpackTemplate(templateName);
0099     if (folderName.isEmpty())
0100         return;
0101 
0102     // Read the properties, change those that should be customized and save the result:
0103     QDomDocument *document = XMLWork::openFile("basket", Global::basketsFolder() + folderName + "/.basket");
0104     if (!document) {
0105         KMessageBox::error(/*parent=*/nullptr, i18n("Sorry, but the template customization for this new basket has failed."), i18n("Basket Creation Failed"));
0106         return;
0107     }
0108     QDomElement properties = XMLWork::getElement(document->documentElement(), "properties");
0109 
0110     if (!icon.isEmpty()) {
0111         QDomElement iconElement = XMLWork::getElement(properties, "icon");
0112         if (!iconElement.tagName().isEmpty()) // If there is already an icon, remove it since we will add our own value below
0113             iconElement.removeChild(iconElement.firstChild());
0114         XMLWork::addElement(*document, properties, "icon", icon);
0115     }
0116 
0117     if (!name.isEmpty()) {
0118         QDomElement nameElement = XMLWork::getElement(properties, "name");
0119         if (!nameElement.tagName().isEmpty()) // If there is already a name, remove it since we will add our own value below
0120             nameElement.removeChild(nameElement.firstChild());
0121         XMLWork::addElement(*document, properties, "name", name);
0122     }
0123 
0124     if (backgroundColor.isValid()) {
0125         QDomElement appearanceElement = XMLWork::getElement(properties, "appearance");
0126         if (appearanceElement.tagName().isEmpty()) { // If there is not already an appearance tag, add it since we will access it below
0127             appearanceElement = document->createElement("appearance");
0128             properties.appendChild(appearanceElement);
0129         }
0130         appearanceElement.setAttribute("backgroundColor", backgroundColor.name());
0131     }
0132 
0133     if (!backgroundImage.isEmpty()) {
0134         QDomElement appearanceElement = XMLWork::getElement(properties, "appearance");
0135         if (appearanceElement.tagName().isEmpty()) { // If there is not already an appearance tag, add it since we will access it below
0136             appearanceElement = document->createElement("appearance");
0137             properties.appendChild(appearanceElement);
0138         }
0139         appearanceElement.setAttribute("backgroundImage", backgroundImage);
0140     }
0141 
0142     if (textColor.isValid()) {
0143         QDomElement appearanceElement = XMLWork::getElement(properties, "appearance");
0144         if (appearanceElement.tagName().isEmpty()) { // If there is not already an appearance tag, add it since we will access it below
0145             appearanceElement = document->createElement("appearance");
0146             properties.appendChild(appearanceElement);
0147         }
0148         appearanceElement.setAttribute("textColor", textColor.name());
0149     }
0150 
0151     // Load it in the parent basket (it will save the tree and switch to this new basket):
0152     Global::bnpView->loadNewBasket(folderName, properties, parent);
0153 }