File indexing completed on 2024-04-21 04:32:09

0001 /*
0002  * Copyright (C) 2009-2015 by Stephen Allewell
0003  * steve.allewell@gmail.com
0004  *
0005  * This program is free software; you can redistribute it and/or modify
0006  * it under the terms of the GNU General Public License as published by
0007  * the Free Software Foundation; either version 2 of the License, or
0008  * (at your option) any later version.
0009  */
0010 
0011 #include "LibraryTreeWidgetItem.h"
0012 
0013 /*
0014 struct LIBRARY (original)
0015 {
0016   Q_UINT32 patterns;
0017   [
0018     Q_UINT16 checksum
0019     QByteArray compressedDataStream
0020     [
0021       QString scheme
0022       Q_INT32 width
0023       Q_INT32 height
0024       [
0025         Q_INT8 count
0026         Q_INT8 type
0027         Q_UINT32 color
0028       ] height x width
0029       Q_INT32 backstitches
0030       [
0031         QPoint start
0032         QPoint end
0033         Q_INT32 color
0034       ] backstitches
0035       Q_INT32 knots
0036       [
0037         QPoint start
0038         Q_INT32 color
0039       ] knots
0040     ]
0041   ] patterns
0042 ]
0043 
0044 struct LIBRARY (new kde3)
0045 [
0046   "KXStitchLib"
0047   Q_INT16 version
0048   [
0049     Q_UINT16 key
0050     Q_UINT16 modifier
0051     Q_INT16 baseline
0052     Q_UINT16 checksum
0053     QByteArray compressedDataStream
0054     [
0055       QString scheme
0056       Q_INT32 width
0057       Q_INT32 height
0058       [
0059         Q_INT8 count
0060         Q_INT8 type
0061         Q_UINT32 color
0062       ] height x width
0063       Q_INT32 backstitches
0064       [
0065         QPoint start
0066         QPoint end
0067         Q_INT32 color
0068       ] backstitches
0069       Q_INT32 knots
0070       [
0071         QPoint start
0072         Q_INT32 color
0073       ] knots
0074     ]
0075   ]
0076 ]
0077 
0078 struct LIBRARY (new kde4)
0079 [
0080   "KXStitchLib"
0081   quint16 version
0082   [
0083     version 100
0084     qint32 patterns
0085     [
0086       quint32 key
0087       quint32 modifier
0088       quint32 baseline
0089       Pattern
0090     ]
0091   ]
0092 ]
0093 */
0094 
0095 #include <QStandardPaths>
0096 #include <QTreeWidget>
0097 
0098 #include "LibraryPattern.h"
0099 #include "Pattern.h"
0100 
0101 LibraryTreeWidgetItem::LibraryTreeWidgetItem(QTreeWidget *parent, const QString &name)
0102     : QTreeWidgetItem(parent, QTreeWidgetItem::UserType)
0103 {
0104     setText(0, name);
0105 }
0106 
0107 LibraryTreeWidgetItem::LibraryTreeWidgetItem(LibraryTreeWidgetItem *parent, const QString &name)
0108     : QTreeWidgetItem(parent, QTreeWidgetItem::UserType)
0109 {
0110     setText(0, name);
0111 }
0112 
0113 LibraryTreeWidgetItem::~LibraryTreeWidgetItem()
0114 {
0115     qDeleteAll(m_libraryFiles);
0116 }
0117 
0118 int LibraryTreeWidgetItem::maxHeight()
0119 {
0120     int max = 0;
0121 
0122     for (LibraryPattern *libraryPattern = first(); libraryPattern; libraryPattern = next()) {
0123         max = std::max(max, libraryPattern->pattern()->stitches().height());
0124     }
0125 
0126     return max;
0127 }
0128 
0129 LibraryPattern *LibraryTreeWidgetItem::findCharacter(int key, Qt::KeyboardModifiers modifiers)
0130 {
0131     LibraryPattern *libraryPattern;
0132 
0133     for (libraryPattern = first(); libraryPattern; libraryPattern = next()) {
0134         if (libraryPattern->key() == key && libraryPattern->modifiers() == modifiers) {
0135             break;
0136         }
0137     }
0138 
0139     return libraryPattern;
0140 }
0141 
0142 LibraryPattern *LibraryTreeWidgetItem::first()
0143 {
0144     LibraryPattern *libraryPattern = nullptr;
0145     m_libraryFilesIndex = 0;
0146 
0147     if (!m_libraryFiles.isEmpty()) {
0148         libraryPattern = m_libraryFiles[0]->first();
0149 
0150         if (libraryPattern == nullptr) { // the first file is empty
0151             libraryPattern = next();
0152         }
0153     }
0154 
0155     return libraryPattern;
0156 }
0157 
0158 LibraryPattern *LibraryTreeWidgetItem::next()
0159 {
0160     LibraryPattern *libraryPattern = nullptr;
0161 
0162     while (libraryPattern == nullptr && !m_libraryFiles.isEmpty() && m_libraryFilesIndex != m_libraryFiles.count()) {
0163         libraryPattern = m_libraryFiles[m_libraryFilesIndex]->next();
0164 
0165         if (libraryPattern == nullptr) { // reached the end of the current file
0166             if (++m_libraryFilesIndex < m_libraryFiles.count()) {
0167                 libraryPattern = m_libraryFiles[m_libraryFilesIndex]->first(); // get the first pattern of the next file
0168             }
0169         }
0170     }
0171 
0172     return libraryPattern;
0173 }
0174 
0175 void LibraryTreeWidgetItem::addPath(const QString &path)
0176 {
0177     m_libraryFiles.append(new LibraryFile(path));
0178 }
0179 
0180 QString LibraryTreeWidgetItem::path()
0181 {
0182     return m_libraryFiles.first()->path();
0183 }
0184 
0185 QStringList LibraryTreeWidgetItem::paths()
0186 {
0187     QStringList paths;
0188     QListIterator<LibraryFile *> libraryFilesIterator(m_libraryFiles);
0189 
0190     while (libraryFilesIterator.hasNext()) {
0191         paths.append(libraryFilesIterator.next()->localFile());
0192     }
0193 
0194     return paths;
0195 }
0196 
0197 LibraryFile *LibraryTreeWidgetItem::writablePath()
0198 {
0199     LibraryFile *libraryFile = nullptr;
0200     QListIterator<LibraryFile *> libraryFilesIterator(m_libraryFiles);
0201 
0202     while (libraryFilesIterator.hasNext()) {
0203         libraryFile = libraryFilesIterator.next();
0204 
0205         if (libraryFile->isWritable()) {
0206             return libraryFile;
0207         }
0208     }
0209 
0210     QString path = m_libraryFiles[0]->path();
0211     path.remove(0, path.indexOf(QLatin1String("/library")));
0212     path.prepend(QStandardPaths::writableLocation(QStandardPaths::DataLocation));
0213     addPath(path);
0214     libraryFile = m_libraryFiles.last();
0215     return libraryFile;
0216 }
0217 
0218 void LibraryTreeWidgetItem::addPattern(LibraryPattern *libraryPattern)
0219 {
0220     writablePath()->addPattern(libraryPattern);
0221 }
0222 
0223 void LibraryTreeWidgetItem::deletePattern(LibraryPattern *libraryPattern)
0224 {
0225     QListIterator<LibraryFile *> libraryFilesIterator(m_libraryFiles);
0226 
0227     while (libraryFilesIterator.hasNext()) {
0228         LibraryFile *file = libraryFilesIterator.next();
0229 
0230         for (LibraryPattern *pattern = file->first(); pattern; pattern = file->next()) {
0231             if (pattern == libraryPattern) {
0232                 file->deletePattern(libraryPattern);
0233             }
0234         }
0235     }
0236 }