Embed image data in glabels file.
This commit is contained in:
@@ -36,6 +36,7 @@ set (glabels_sources
|
||||
ColorPaletteButtonItem.cpp
|
||||
ColorSwatch.cpp
|
||||
Cursors.cpp
|
||||
DataCache.cpp
|
||||
Db.cpp
|
||||
Distance.cpp
|
||||
EnumUtil.cpp
|
||||
|
||||
@@ -0,0 +1,82 @@
|
||||
/* DataCache.cpp
|
||||
*
|
||||
* Copyright (C) 2017 Jim Evins <evins@snaught.com>
|
||||
*
|
||||
* This file is part of gLabels-qt.
|
||||
*
|
||||
* gLabels-qt 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* gLabels-qt 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 gLabels-qt. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "DataCache.h"
|
||||
|
||||
#include "LabelModelImageObject.h"
|
||||
|
||||
|
||||
namespace glabels
|
||||
{
|
||||
|
||||
DataCache::DataCache()
|
||||
{
|
||||
// empty
|
||||
}
|
||||
|
||||
|
||||
DataCache::DataCache( const LabelModel* model )
|
||||
{
|
||||
foreach( LabelModelObject* object, model->objectList() )
|
||||
{
|
||||
if ( LabelModelImageObject* imageObject = dynamic_cast<LabelModelImageObject*>(object) )
|
||||
{
|
||||
TextNode filenameNode = imageObject->filenameNode();
|
||||
if ( !filenameNode.isField() )
|
||||
{
|
||||
if ( const QImage* image = imageObject->image() )
|
||||
{
|
||||
addImage( filenameNode.data(), *imageObject->image() );
|
||||
}
|
||||
else
|
||||
{
|
||||
// TODO handle SVG files
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool DataCache::hasImage( const QString& name ) const
|
||||
{
|
||||
return mImageMap.contains( name );
|
||||
}
|
||||
|
||||
|
||||
QImage DataCache::getImage( const QString& name ) const
|
||||
{
|
||||
return mImageMap[ name ];
|
||||
}
|
||||
|
||||
|
||||
void DataCache::addImage( const QString& name, const QImage& image )
|
||||
{
|
||||
mImageMap[ name ] = image;
|
||||
}
|
||||
|
||||
|
||||
QList<QString> DataCache::imageNames() const
|
||||
{
|
||||
return mImageMap.keys();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
/* DataCache.h
|
||||
*
|
||||
* Copyright (C) 2017 Jim Evins <evins@snaught.com>
|
||||
*
|
||||
* This file is part of gLabels-qt.
|
||||
*
|
||||
* gLabels-qt 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* gLabels-qt 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 gLabels-qt. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef glabels_DataCache_h
|
||||
#define glabels_DataCache_h
|
||||
|
||||
|
||||
#include "LabelModel.h"
|
||||
|
||||
|
||||
namespace glabels
|
||||
{
|
||||
|
||||
class DataCache
|
||||
{
|
||||
public:
|
||||
DataCache();
|
||||
|
||||
DataCache( const LabelModel* model );
|
||||
|
||||
bool hasImage( const QString& name ) const;
|
||||
QImage getImage( const QString& name ) const;
|
||||
void addImage( const QString& name, const QImage& image );
|
||||
QList<QString> imageNames() const;
|
||||
|
||||
private:
|
||||
QMap<QString,QImage> mImageMap;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endif // glabels_DataCache_h
|
||||
@@ -120,7 +120,16 @@ namespace glabels
|
||||
|
||||
|
||||
///
|
||||
/// Image Property Default Setter
|
||||
/// Image image Property Getter
|
||||
///
|
||||
const QImage* LabelModelImageObject::image() const
|
||||
{
|
||||
return mImage;
|
||||
}
|
||||
|
||||
|
||||
///
|
||||
/// Image Property Setter
|
||||
///
|
||||
void LabelModelImageObject::setImage( const QImage& value )
|
||||
{
|
||||
@@ -144,6 +153,30 @@ namespace glabels
|
||||
}
|
||||
|
||||
|
||||
///
|
||||
/// Image Property Setter
|
||||
///
|
||||
void LabelModelImageObject::setImage( const QString& name, const QImage& value )
|
||||
{
|
||||
if ( !value.isNull() )
|
||||
{
|
||||
if ( mImage )
|
||||
{
|
||||
delete mImage;
|
||||
}
|
||||
if ( mSvg )
|
||||
{
|
||||
delete mSvg;
|
||||
}
|
||||
|
||||
mImage = new QImage(value);
|
||||
mFilenameNode = TextNode( false, name );
|
||||
|
||||
emit changed();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
///
|
||||
/// naturalSize Property Getter (assumes 72 DPI, i.e. 1pixel == 1pt)
|
||||
///
|
||||
@@ -246,18 +279,15 @@ namespace glabels
|
||||
if ( mImage )
|
||||
{
|
||||
delete mImage;
|
||||
mImage = 0;
|
||||
}
|
||||
if ( mSvg )
|
||||
{
|
||||
delete mSvg;
|
||||
}
|
||||
|
||||
if ( mFilenameNode.isField() )
|
||||
{
|
||||
mImage = 0;
|
||||
mSvg = 0;
|
||||
}
|
||||
else
|
||||
|
||||
if ( !mFilenameNode.isField() )
|
||||
{
|
||||
QString filename = mFilenameNode.data();
|
||||
QFileInfo fileInfo( filename );
|
||||
|
||||
@@ -65,7 +65,9 @@ namespace glabels
|
||||
//
|
||||
// Image Property: image
|
||||
//
|
||||
virtual const QImage* image() const;
|
||||
virtual void setImage( const QImage& value );
|
||||
virtual void setImage( const QString& name, const QImage& value );
|
||||
|
||||
//
|
||||
// Property: naturalSize
|
||||
|
||||
@@ -600,6 +600,16 @@ namespace glabels
|
||||
}
|
||||
|
||||
|
||||
///
|
||||
/// Virtual Image Property Default Getter
|
||||
/// (Overridden by concrete class)
|
||||
///
|
||||
const QImage* LabelModelObject::image() const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
///
|
||||
/// Virtual Image Property Default Setter
|
||||
/// (Overridden by concrete class)
|
||||
@@ -610,6 +620,16 @@ namespace glabels
|
||||
}
|
||||
|
||||
|
||||
///
|
||||
/// Virtual Image Property Default Setter
|
||||
/// (Overridden by concrete class)
|
||||
///
|
||||
void LabelModelObject::setImage( const QString& name, const QImage& value )
|
||||
{
|
||||
// empty
|
||||
}
|
||||
|
||||
|
||||
///
|
||||
/// Virtual Line Width Property Default Getter
|
||||
/// (Overridden by concrete class)
|
||||
|
||||
@@ -257,7 +257,9 @@ namespace glabels
|
||||
//
|
||||
// Virtual Image Property: image
|
||||
//
|
||||
virtual const QImage* image() const;
|
||||
virtual void setImage( const QImage& value );
|
||||
virtual void setImage( const QString& name, const QImage& value );
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include <QFile>
|
||||
#include <QTextBlock>
|
||||
#include <QTextDocument>
|
||||
#include <QBuffer>
|
||||
#include <QtDebug>
|
||||
|
||||
#include "EnumUtil.h"
|
||||
@@ -36,6 +37,7 @@
|
||||
#include "LabelModelLineObject.h"
|
||||
#include "LabelModelImageObject.h"
|
||||
#include "LabelModelTextObject.h"
|
||||
#include "DataCache.h"
|
||||
#include "XmlTemplateCreator.h"
|
||||
#include "XmlUtil.h"
|
||||
|
||||
@@ -444,14 +446,37 @@ namespace glabels
|
||||
void
|
||||
XmlLabelCreator::createDataNode( QDomElement &parent, const LabelModel* label )
|
||||
{
|
||||
// TODO
|
||||
QDomDocument doc = parent.ownerDocument();
|
||||
QDomElement node = doc.createElement( "Data" );
|
||||
parent.appendChild( node );
|
||||
|
||||
DataCache data( label );
|
||||
|
||||
foreach ( QString name, data.imageNames() )
|
||||
{
|
||||
createPngFileNode( node, name, data.getImage( name ) );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
XmlLabelCreator::createPixdataNode( QDomElement &parent, const LabelModel* label, const QString& name )
|
||||
XmlLabelCreator::createPngFileNode( QDomElement &parent, const QString& name, const QImage& image )
|
||||
{
|
||||
// TODO
|
||||
QDomDocument doc = parent.ownerDocument();
|
||||
QDomElement node = doc.createElement( "File" );
|
||||
parent.appendChild( node );
|
||||
|
||||
XmlUtil::setStringAttr( node, "name", name );
|
||||
XmlUtil::setStringAttr( node, "mimetype", "image/png" );
|
||||
XmlUtil::setStringAttr( node, "encoding", "base64" );
|
||||
|
||||
QByteArray ba;
|
||||
QBuffer buffer(&ba);
|
||||
buffer.open(QIODevice::WriteOnly);
|
||||
image.save(&buffer, "PNG");
|
||||
QByteArray ba64 = ba.toBase64();
|
||||
|
||||
node.appendChild( doc.createTextNode( QString( ba64 ) ) );
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -68,7 +68,7 @@ namespace glabels
|
||||
static void createShadowAttrs( QDomElement &node, const LabelModelObject* object );
|
||||
static void createMergeNode( QDomElement &parent, const LabelModel* label );
|
||||
static void createDataNode( QDomElement &parent, const LabelModel* label );
|
||||
static void createPixdataNode( QDomElement &parent, const LabelModel* label, const QString& name );
|
||||
static void createPngFileNode( QDomElement &parent, const QString& name, const QImage& image );
|
||||
static void createSvgFileNode( QDomElement &parent, const LabelModel* label, const QString& name );
|
||||
|
||||
};
|
||||
|
||||
+56
-15
@@ -40,6 +40,7 @@
|
||||
#include "LabelModelTextObject.h"
|
||||
#include "XmlTemplateParser.h"
|
||||
#include "XmlUtil.h"
|
||||
#include "DataCache.h"
|
||||
|
||||
#include "Merge/Factory.h"
|
||||
|
||||
@@ -151,7 +152,7 @@ namespace glabels
|
||||
return list;
|
||||
}
|
||||
|
||||
return parseObjects( root );
|
||||
return parseObjects( root, DataCache() );
|
||||
}
|
||||
|
||||
|
||||
@@ -217,11 +218,12 @@ namespace glabels
|
||||
LabelModel* label = new LabelModel();
|
||||
|
||||
/* Pass 1, extract data nodes to pre-load cache. */
|
||||
DataCache data;
|
||||
for ( QDomNode child = node.firstChild(); !child.isNull(); child = child.nextSibling() )
|
||||
{
|
||||
if ( child.toElement().tagName() == "Data" )
|
||||
{
|
||||
parseDataNode( child.toElement(), label );
|
||||
parseDataNode( child.toElement(), data );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -242,7 +244,7 @@ namespace glabels
|
||||
}
|
||||
else if ( tagName == "Objects" )
|
||||
{
|
||||
parseObjectsNode( child.toElement(), label );
|
||||
parseObjectsNode( child.toElement(), data, label );
|
||||
}
|
||||
else if ( tagName == "Merge" )
|
||||
{
|
||||
@@ -264,7 +266,7 @@ namespace glabels
|
||||
|
||||
|
||||
QList<LabelModelObject*>
|
||||
XmlLabelParser::parseObjects( const QDomElement &node )
|
||||
XmlLabelParser::parseObjects( const QDomElement &node, const DataCache& data )
|
||||
{
|
||||
QList<LabelModelObject*> list;
|
||||
|
||||
@@ -290,7 +292,7 @@ namespace glabels
|
||||
}
|
||||
else if ( tagName == "Object-image" )
|
||||
{
|
||||
list.append( parseObjectImageNode( child.toElement() ) );
|
||||
list.append( parseObjectImageNode( child.toElement(), data ) );
|
||||
}
|
||||
#if 0
|
||||
else if ( tagName == "Object-barcode" )
|
||||
@@ -309,9 +311,9 @@ namespace glabels
|
||||
|
||||
|
||||
void
|
||||
XmlLabelParser::parseObjectsNode( const QDomElement &node, LabelModel* label )
|
||||
XmlLabelParser::parseObjectsNode( const QDomElement &node, const DataCache& data, LabelModel* label )
|
||||
{
|
||||
QList<LabelModelObject*> list = parseObjects( node );
|
||||
QList<LabelModelObject*> list = parseObjects( node, data );
|
||||
|
||||
foreach ( LabelModelObject* object, list )
|
||||
{
|
||||
@@ -441,7 +443,7 @@ namespace glabels
|
||||
|
||||
|
||||
LabelModelImageObject*
|
||||
XmlLabelParser::parseObjectImageNode( const QDomElement &node )
|
||||
XmlLabelParser::parseObjectImageNode( const QDomElement &node, const DataCache& data )
|
||||
{
|
||||
LabelModelImageObject* object = new LabelModelImageObject();
|
||||
|
||||
@@ -460,7 +462,21 @@ namespace glabels
|
||||
bool field_flag = !key.isEmpty();
|
||||
QString filename = XmlUtil::getStringAttr( node, "src", "" );
|
||||
|
||||
object->setFilenameNode( TextNode( field_flag, field_flag ? key : filename ) );
|
||||
if ( field_flag )
|
||||
{
|
||||
object->setFilenameNode( TextNode( true, key ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( data.hasImage( filename ) )
|
||||
{
|
||||
object->setImage( filename, data.getImage( filename ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
object->setFilenameNode( TextNode( false, filename ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* affine attrs */
|
||||
@@ -607,23 +623,48 @@ namespace glabels
|
||||
|
||||
|
||||
void
|
||||
XmlLabelParser::parseDataNode( const QDomElement &node, LabelModel* label )
|
||||
XmlLabelParser::parseDataNode( const QDomElement &node, DataCache& data )
|
||||
{
|
||||
// TODO
|
||||
for ( QDomNode child = node.firstChild(); !child.isNull(); child = child.nextSibling() )
|
||||
{
|
||||
QString tagName = child.toElement().tagName();
|
||||
|
||||
if ( tagName == "File" )
|
||||
{
|
||||
parseFileNode( child.toElement(), data );
|
||||
}
|
||||
else if ( !child.isComment() )
|
||||
{
|
||||
qWarning() << "Unexpected" << node.tagName() << "child:" << tagName;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
XmlLabelParser::parsePixdataNode( const QDomElement &node, LabelModel* label )
|
||||
XmlLabelParser::parsePixdataNode( const QDomElement& node, DataCache& data )
|
||||
{
|
||||
// TODO
|
||||
// TODO, compatability with glabels-3
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
XmlLabelParser::parseFileNode( const QDomElement &node, LabelModel* label )
|
||||
XmlLabelParser::parseFileNode( const QDomElement& node, DataCache& data )
|
||||
{
|
||||
// TODO
|
||||
QString name = XmlUtil::getStringAttr( node, "name", "" );
|
||||
QString mimetype = XmlUtil::getStringAttr( node, "mimetype", "image/png" );
|
||||
QString encoding = XmlUtil::getStringAttr( node, "encoding", "base64" );
|
||||
|
||||
if ( mimetype == "image/png" )
|
||||
{
|
||||
QByteArray ba64 = node.text().toUtf8();
|
||||
QByteArray ba = QByteArray::fromBase64( ba64 );
|
||||
QImage image;
|
||||
image.loadFromData( ba, "PNG" );
|
||||
|
||||
data.addImage( name, image );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -38,6 +38,7 @@ namespace glabels
|
||||
class LabelModelImageObject;
|
||||
class LabelModelBarcodeObject;
|
||||
class LabelModelTextObject;
|
||||
class DataCache;
|
||||
|
||||
|
||||
///
|
||||
@@ -55,21 +56,21 @@ namespace glabels
|
||||
private:
|
||||
static void gunzip( const QByteArray& gzippedData, QByteArray& data );
|
||||
static LabelModel* parseRootNode( const QDomElement &node );
|
||||
static QList<LabelModelObject*> parseObjects( const QDomElement &node );
|
||||
static void parseObjectsNode( const QDomElement &node, LabelModel* label );
|
||||
static QList<LabelModelObject*> parseObjects( const QDomElement &node, const DataCache& data );
|
||||
static void parseObjectsNode( const QDomElement &node, const DataCache& data, LabelModel* label );
|
||||
static LabelModelBoxObject* parseObjectBoxNode( const QDomElement &node );
|
||||
static LabelModelEllipseObject* parseObjectEllipseNode( const QDomElement &node );
|
||||
static LabelModelLineObject* parseObjectLineNode( const QDomElement &node );
|
||||
static LabelModelImageObject* parseObjectImageNode( const QDomElement &node );
|
||||
static LabelModelImageObject* parseObjectImageNode( const QDomElement &node, const DataCache& data );
|
||||
static LabelModelBarcodeObject* parseObjectBarcodeNode( const QDomElement &node );
|
||||
static LabelModelTextObject* parseObjectTextNode( const QDomElement &node );
|
||||
static QString parsePNode( const QDomElement &node );
|
||||
static void parseAffineAttrs( const QDomElement &node, LabelModelObject* object );
|
||||
static void parseShadowAttrs( const QDomElement &node, LabelModelObject* object );
|
||||
static void parseMergeNode( const QDomElement &node, LabelModel* label );
|
||||
static void parseDataNode( const QDomElement &node, LabelModel* label );
|
||||
static void parsePixdataNode( const QDomElement &node, LabelModel* label );
|
||||
static void parseFileNode( const QDomElement &node, LabelModel* label );
|
||||
static void parseDataNode( const QDomElement &node, DataCache& data );
|
||||
static void parsePixdataNode( const QDomElement &node, DataCache& data );
|
||||
static void parseFileNode( const QDomElement &node, DataCache& data );
|
||||
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user