Embed image data in glabels file.

This commit is contained in:
Jim Evins
2017-03-12 22:39:15 -04:00
parent fe1aa77799
commit fd79d7c6bd
11 changed files with 287 additions and 32 deletions
+1
View File
@@ -36,6 +36,7 @@ set (glabels_sources
ColorPaletteButtonItem.cpp
ColorSwatch.cpp
Cursors.cpp
DataCache.cpp
Db.cpp
Distance.cpp
EnumUtil.cpp
+82
View File
@@ -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();
}
}
+51
View File
@@ -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
+37 -7
View File
@@ -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 );
+2
View File
@@ -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
+20
View File
@@ -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)
+2
View File
@@ -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 );
///////////////////////////////////////////////////////////////
+28 -3
View File
@@ -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 ) ) );
}
+1 -1
View File
@@ -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
View File
@@ -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 );
}
}
}
+7 -6
View File
@@ -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 );
};