File indexing completed on 2024-05-26 04:38:02
0001 /* 0002 * Copyright (C) 2016 Dan Leinir Turthra Jensen <admin@leinir.dk> 0003 * 0004 * This library is free software; you can redistribute it and/or 0005 * modify it under the terms of the GNU Lesser General Public 0006 * License as published by the Free Software Foundation; either 0007 * version 2.1 of the License, or (at your option) version 3, or any 0008 * later version accepted by the membership of KDE e.V. (or its 0009 * successor approved by the membership of KDE e.V.), which shall 0010 * act as a proxy defined in Section 6 of version 3 of the license. 0011 * 0012 * This library is distributed in the hope that it will be useful, 0013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 0014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0015 * Lesser General Public License for more details. 0016 * 0017 * You should have received a copy of the GNU Lesser General Public 0018 * License along with this library. If not, see <http://www.gnu.org/licenses/>. 0019 * 0020 */ 0021 0022 #include "AcbfTextlayer.h" 0023 #include "AcbfTextarea.h" 0024 0025 #include <QXmlStreamReader> 0026 #include <QXmlStreamWriter> 0027 0028 #include <acbf_debug.h> 0029 0030 using namespace AdvancedComicBookFormat; 0031 0032 class Textlayer::Private 0033 { 0034 public: 0035 Private() {} 0036 QString language; 0037 QString bgcolor; 0038 QList<Textarea*> textareas; 0039 }; 0040 0041 Textlayer::Textlayer(Page* parent) 0042 : QObject(parent) 0043 , d(new Private) 0044 { 0045 static const int typeId = qRegisterMetaType<Textlayer*>("Textlayer*"); 0046 Q_UNUSED(typeId); 0047 } 0048 0049 Textlayer::~Textlayer() = default; 0050 0051 void Textlayer::toXml(QXmlStreamWriter* writer) 0052 { 0053 writer->writeStartElement(QStringLiteral("text-layer")); 0054 if(!d->language.isEmpty()) { 0055 writer->writeAttribute(QStringLiteral("lang"), d->language); 0056 } 0057 if(!d->bgcolor.isEmpty()) { 0058 writer->writeAttribute(QStringLiteral("bgcolor"), d->bgcolor); 0059 } 0060 0061 for(Textarea* area : d->textareas) { 0062 area->toXml(writer); 0063 } 0064 0065 writer->writeEndElement(); 0066 } 0067 0068 bool Textlayer::fromXml(QXmlStreamReader *xmlReader, const QString& xmlData) 0069 { 0070 setBgcolor(xmlReader->attributes().value(QStringLiteral("bgcolor")).toString()); 0071 setLanguage(xmlReader->attributes().value(QStringLiteral("lang")).toString()); 0072 while(xmlReader->readNextStartElement()) 0073 { 0074 if(xmlReader->name() == QStringLiteral("text-area")) 0075 { 0076 Textarea* newArea = new Textarea(this); 0077 if(!newArea->fromXml(xmlReader, xmlData)) { 0078 return false; 0079 } 0080 d->textareas.append(newArea); 0081 } 0082 else 0083 { 0084 qCWarning(ACBF_LOG) << Q_FUNC_INFO << "currently unsupported subsection:" << xmlReader->name(); 0085 xmlReader->skipCurrentElement(); 0086 } 0087 } 0088 if (xmlReader->hasError()) { 0089 qCWarning(ACBF_LOG) << Q_FUNC_INFO << "Failed to read ACBF XML document at token" << xmlReader->name() << "(" << xmlReader->lineNumber() << ":" << xmlReader->columnNumber() << ") The reported error was:" << xmlReader->errorString(); 0090 } 0091 qCDebug(ACBF_LOG) << Q_FUNC_INFO << "Created a text layer with" << d->textareas.count() << "text areas"; 0092 return !xmlReader->hasError(); 0093 } 0094 0095 QString Textlayer::language() const 0096 { 0097 return d->language; 0098 } 0099 0100 void Textlayer::setLanguage(const QString& language) 0101 { 0102 d->language = language; 0103 emit languageChanged(); 0104 } 0105 0106 QString Textlayer::bgcolor() const 0107 { 0108 if (d->bgcolor.isEmpty()) { 0109 Page* page = qobject_cast<Page*>(parent()); 0110 if (page) { 0111 return page->bgcolor(); 0112 } 0113 } 0114 return d->bgcolor; 0115 } 0116 0117 void Textlayer::setBgcolor(const QString& newColor) 0118 { 0119 d->bgcolor = newColor; 0120 emit bgcolorChanged(); 0121 } 0122 0123 QObjectList Textlayer::textareas() const 0124 { 0125 QObjectList areas; 0126 for (Textarea* area : d->textareas) { 0127 areas << area; 0128 } 0129 return areas; 0130 } 0131 0132 int Textlayer::textAreaIndex(Textarea* textarea) 0133 { 0134 return d->textareas.indexOf(textarea); 0135 } 0136 0137 Textarea * Textlayer::textarea(int index) const 0138 { 0139 return d->textareas.at(index); 0140 } 0141 0142 int Textlayer::textareaIndex(Textarea* textarea) const 0143 { 0144 return d->textareas.indexOf(textarea); 0145 } 0146 0147 void Textlayer::addTextarea(Textarea* textarea, int index) 0148 { 0149 if(index > -1 && d->textareas.count() < index) { 0150 d->textareas.insert(index, textarea); 0151 } 0152 else { 0153 d->textareas.append(textarea); 0154 } 0155 Q_EMIT textareaAdded(textarea); 0156 Q_EMIT textareasChanged(); 0157 Q_EMIT textareaPointStringsChanged(); 0158 } 0159 0160 void Textlayer::addTextarea(int index) 0161 { 0162 Textarea* text = new Textarea(this); 0163 addTextarea(text, index); 0164 } 0165 0166 void Textlayer::removeTextarea(Textarea* textarea) 0167 { 0168 d->textareas.removeAll(textarea); 0169 Q_EMIT textareasChanged(); 0170 Q_EMIT textareaPointStringsChanged(); 0171 } 0172 0173 void Textlayer::removeTextarea(int index) 0174 { 0175 removeTextarea(textarea(index)); 0176 } 0177 0178 bool Textlayer::swapTextareas(int swapThis, int withThis) 0179 { 0180 bool success{false}; 0181 if (swapThis > -1 && swapThis < d->textareas.count() && withThis > -1 && withThis < d->textareas.count()) { 0182 d->textareas.swapItemsAt(swapThis, withThis); 0183 InternalReferenceObject* first = qobject_cast<InternalReferenceObject*>(d->textareas[swapThis]); 0184 InternalReferenceObject* second = qobject_cast<InternalReferenceObject*>(d->textareas[withThis]); 0185 Q_EMIT first->propertyDataChanged(); 0186 Q_EMIT second->propertyDataChanged(); 0187 Q_EMIT textareasChanged(); 0188 Q_EMIT textareaPointStringsChanged(); 0189 success = true; 0190 } else { 0191 qCWarning(ACBF_LOG) << "There was an attempt to swap two textareas, and at least one of them was outside the bounds of the current list of textareas in this layer:" << this << swapThis << withThis; 0192 } 0193 return success; 0194 } 0195 0196 QStringList Textlayer::textareaPointStrings() 0197 { 0198 QStringList textAreaList; 0199 for (int i=0; i<d->textareas.size(); i++) { 0200 QStringList points; 0201 for (int p=0; p< textarea(i)->pointCount(); p++) { 0202 points.append(QString("%1,%2").arg(textarea(i)->point(p).x()).arg(textarea(i)->point(p).y())); 0203 } 0204 textAreaList.append(points.join(" ")); 0205 } 0206 return textAreaList; 0207 }