Moved Merge subsystem into merge namespace.

This commit is contained in:
Jim Evins
2016-05-22 14:38:59 -04:00
parent b1e7a6507c
commit c7f02f027a
34 changed files with 1434 additions and 1380 deletions
+2 -2
View File
@@ -20,7 +20,7 @@
#include "ColorNode.h"
#include "Merge/MergeRecord.h"
#include "Merge/Record.h"
///
@@ -160,7 +160,7 @@ uint32_t ColorNode::rgba( void ) const
}
QColor ColorNode::color( MergeRecord* record ) const
QColor ColorNode::color( merge::Record* record ) const
{
if ( mFieldFlag )
{
+2 -3
View File
@@ -24,8 +24,7 @@
#include <QString>
#include <QColor>
#include <stdint.h>
class MergeRecord; // Forward reference
#include "Merge/Record.h"
///
@@ -89,7 +88,7 @@ public:
/////////////////////////////////
public:
uint32_t rgba( void ) const;
QColor color( MergeRecord* record ) const;
QColor color( merge::Record* record ) const;
/////////////////////////////////
+5 -7
View File
@@ -28,9 +28,7 @@
#include <QMimeData>
#include <QtDebug>
#include "Merge/Merge.h"
#include "Merge/MergeNone.h"
#include "Merge/MergeRecord.h"
#include "Merge/None.h"
#include "LabelModelObject.h"
#include "LabelRegion.h"
#include "XmlLabelCreator.h"
@@ -48,7 +46,7 @@ namespace
///
LabelModel::LabelModel() : mUntitledInstance(0), mModified(true), mTmplate(0), mRotate(false)
{
mMerge = new MergeNone();
mMerge = new merge::None();
}
@@ -278,7 +276,7 @@ QString LabelModel::shortName()
///
/// Get merge object
///
Merge* LabelModel::merge() const
merge::Merge* LabelModel::merge() const
{
return mMerge;
}
@@ -287,7 +285,7 @@ Merge* LabelModel::merge() const
///
/// Set merge object
///
void LabelModel::setMerge( Merge* merge )
void LabelModel::setMerge( merge::Merge* merge )
{
if ( merge != mMerge )
{
@@ -1399,7 +1397,7 @@ void LabelModel::paste()
///
/// Draw label objects
///
void LabelModel::draw( QPainter* painter, bool inEditor, MergeRecord* record ) const
void LabelModel::draw( QPainter* painter, bool inEditor, merge::Record* record ) const
{
foreach ( LabelModelObject* object, mObjectList )
{
+7 -6
View File
@@ -26,6 +26,9 @@
#include <QPainter>
#include "libglabels/Template.h"
#include "Merge/Merge.h"
#include "Merge/Record.h"
#include "Settings.h"
@@ -33,8 +36,6 @@
class LabelModelObject;
class Handle;
class LabelRegion;
class Merge;
class MergeRecord;
class ColorNode;
@@ -103,8 +104,8 @@ public:
const QList<LabelModelObject*>& objectList() const;
Merge* merge() const;
void setMerge( Merge* merge );
merge::Merge* merge() const;
void setMerge( merge::Merge* merge );
/////////////////////////////////
@@ -200,7 +201,7 @@ public:
// Drawing operations
/////////////////////////////////
public:
void draw( QPainter* painter, bool inEditor = true, MergeRecord* record = 0 ) const;
void draw( QPainter* painter, bool inEditor = true, merge::Record* record = 0 ) const;
/////////////////////////////////
@@ -226,7 +227,7 @@ private:
QList<LabelModelObject*> mObjectList;
Merge* mMerge;
merge::Merge* mMerge;
};
+2 -2
View File
@@ -66,7 +66,7 @@ LabelModelBoxObject* LabelModelBoxObject::clone() const
///
/// Draw shadow of object
///
void LabelModelBoxObject::drawShadow( QPainter* painter, bool inEditor, MergeRecord* record ) const
void LabelModelBoxObject::drawShadow( QPainter* painter, bool inEditor, merge::Record* record ) const
{
QColor lineColor = mLineColorNode.color( record );
QColor fillColor = mFillColorNode.color( record );
@@ -111,7 +111,7 @@ void LabelModelBoxObject::drawShadow( QPainter* painter, bool inEditor, MergeRec
///
/// Draw object itself
///
void LabelModelBoxObject::drawObject( QPainter* painter, bool inEditor, MergeRecord* record ) const
void LabelModelBoxObject::drawObject( QPainter* painter, bool inEditor, merge::Record* record ) const
{
QColor lineColor = mLineColorNode.color( record );
QColor fillColor = mFillColorNode.color( record );
+2 -2
View File
@@ -51,8 +51,8 @@ public:
// Drawing operations
///////////////////////////////////////////////////////////////
protected:
virtual void drawShadow( QPainter* painter, bool inEditor, MergeRecord* record ) const;
virtual void drawObject( QPainter* painter, bool inEditor, MergeRecord* record ) const;
virtual void drawShadow( QPainter* painter, bool inEditor, merge::Record* record ) const;
virtual void drawObject( QPainter* painter, bool inEditor, merge::Record* record ) const;
virtual QPainterPath hoverPath( double scale ) const;
};
+1 -2
View File
@@ -29,7 +29,6 @@
#include "TextNode.h"
#include "BarcodeStyle.h"
#include "LabelRegion.h"
#include "Merge/MergeRecord.h"
///
@@ -992,7 +991,7 @@ Handle* LabelModelObject::handleAt( double scale,
///
/// Draw object + shadow
///
void LabelModelObject::draw( QPainter* painter, bool inEditor, MergeRecord* record ) const
void LabelModelObject::draw( QPainter* painter, bool inEditor, merge::Record* record ) const
{
painter->save();
painter->translate( mX0.pt(), mY0.pt() );
+4 -4
View File
@@ -27,6 +27,7 @@
#include <QPainter>
#include "libglabels/Distance.h"
#include "Merge/Record.h"
#include "ColorNode.h"
#include "TextNode.h"
#include "BarcodeStyle.h"
@@ -36,7 +37,6 @@
// Forward References
class LabelRegion;
class MergeRecord;
///
@@ -338,12 +338,12 @@ public:
// Drawing operations
///////////////////////////////////////////////////////////////
public:
void draw( QPainter* painter, bool inEditor, MergeRecord* record ) const;
void draw( QPainter* painter, bool inEditor, merge::Record* record ) const;
void drawSelectionHighlight( QPainter* painter, double scale ) const;
protected:
virtual void drawShadow( QPainter* painter, bool inEditor, MergeRecord* record ) const = 0;
virtual void drawObject( QPainter* painter, bool inEditor, MergeRecord* record ) const = 0;
virtual void drawShadow( QPainter* painter, bool inEditor, merge::Record* record ) const = 0;
virtual void drawObject( QPainter* painter, bool inEditor, merge::Record* record ) const = 0;
virtual QPainterPath hoverPath( double scale ) const = 0;
+5 -5
View File
@@ -10,12 +10,12 @@ project (Merge CXX)
# Sources
#=======================================
set (merge_sources
Factory.cpp
Record.cpp
Merge.cpp
MergeFactory.cpp
MergeRecord.cpp
MergeNone.cpp
MergeText.cpp
MergeTextCsv.cpp
None.cpp
Text.cpp
TextCsv.cpp
)
set (merge_qobject_headers
+180
View File
@@ -0,0 +1,180 @@
/* Merge/Factory.cpp
*
* Copyright (C) 2016 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 "Factory.h"
#include "None.h"
#include "TextCsv.h"
namespace merge
{
///
/// Static data
///
QMap<QString,Factory::BackendEntry> Factory::mBackendIdMap;
QMap<QString,Factory::BackendEntry> Factory::mBackendNameMap;
///
/// Constructor
///
Factory::Factory()
{
registerBackend( None::id(),
tr("None"),
NONE,
&None::create );
registerBackend( TextCsv::id(),
tr("Text: Comma Separated Values (CSV)"),
FILE,
&TextCsv::create );
}
///
/// Initialize
///
void Factory::init()
{
static Factory* singletonInstance = 0;
if ( !singletonInstance )
{
singletonInstance = new Factory();
}
}
///
/// Create Merge object
///
Merge* Factory::createMerge( const QString& id )
{
QMap<QString,BackendEntry>::iterator iBackend = mBackendIdMap.find( id );
if ( iBackend != mBackendIdMap.end() )
{
return iBackend->create();
}
return None::create();
}
///
/// Get name list
///
QStringList Factory::nameList()
{
QStringList list;
foreach ( BackendEntry backend, mBackendIdMap )
{
list << backend.name;
}
return list;
}
///
/// Convert ID to name
///
QString Factory::idToName( const QString& id )
{
if ( mBackendIdMap.contains( id ) )
{
return mBackendIdMap[id].name;
}
else
{
return tr("None");
}
}
///
/// Convert name to ID
///
QString Factory::nameToId( const QString& name )
{
if ( mBackendNameMap.contains( name ) )
{
return mBackendNameMap[name].id;
}
else
{
return "None";
}
}
///
/// Convert ID to type
///
Factory::SourceType Factory::idToType( const QString& id )
{
if ( mBackendIdMap.contains( id ) )
{
return mBackendIdMap[id].type;
}
else
{
return NONE;
}
}
///
/// Lookup ID from index
///
QString Factory::indexToId( int index )
{
QList<QString> ids = mBackendIdMap.keys();
if ( (index > 0) && (index < ids.size()) )
{
return ids[index];
}
return "None";
}
///
/// Register backend
///
void Factory::registerBackend( const QString& id,
const QString& name,
SourceType type,
CreateFct create )
{
BackendEntry backend;
backend.name = name;
backend.type = type;
backend.create = create;
mBackendIdMap[ id ] = backend;
}
}
+102
View File
@@ -0,0 +1,102 @@
/* Merge/Factory.h
*
* Copyright (C) 2016 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 merge_Factory_h
#define merge_Factory_h
#include <QCoreApplication>
#include <QStringList>
#include <QMap>
namespace merge
{
class Merge; // Forward reference
///
/// Factory
///
class Factory
{
Q_DECLARE_TR_FUNCTIONS(Factory)
/////////////////////////////////
// Source Type
/////////////////////////////////
public:
enum SourceType { NONE, FIXED, FILE };
/////////////////////////////////
// Life Cycle
/////////////////////////////////
protected:
Factory();
/////////////////////////////////
// Static methods
/////////////////////////////////
public:
static void init();
static Merge* createMerge( const QString& id );
static QStringList nameList();
static QString idToName( const QString& id );
static QString nameToId( const QString& name );
static SourceType idToType( const QString& id );
static QString indexToId( int index );
/////////////////////////////////
// private methods
/////////////////////////////////
private:
typedef Merge* (*CreateFct)();
static void registerBackend( const QString& id,
const QString& name,
SourceType type,
CreateFct create );
/////////////////////////////////
// private data
/////////////////////////////////
class BackendEntry
{
public:
QString id;
QString name;
SourceType type;
CreateFct create;
};
static QMap<QString,BackendEntry> mBackendIdMap;
static QMap<QString,BackendEntry> mBackendNameMap;
};
}
#endif // merge_Factory_h
+148 -141
View File
@@ -1,4 +1,4 @@
/* Merge.cpp
/* Merge/Merge.cpp
*
* Copyright (C) 2015-2016 Jim Evins <evins@snaught.com>
*
@@ -20,184 +20,191 @@
#include "Merge.h"
#include "Record.h"
///
/// Constructor
///
Merge::Merge()
namespace merge
{
}
///
/// Constructor
///
Merge::Merge( const Merge* merge ) : mSource(merge->mSource)
{
foreach ( MergeRecord* record, merge->mRecordList )
///
/// Constructor
///
Merge::Merge()
{
mRecordList << record->clone();
}
}
///
/// Destructor
///
Merge::~Merge()
{
foreach ( MergeRecord* record, mRecordList )
///
/// Constructor
///
Merge::Merge( const Merge* merge ) : mSource(merge->mSource)
{
delete record;
foreach ( Record* record, merge->mRecordList )
{
mRecordList << record->clone();
}
}
mRecordList.clear();
}
///
/// Get id
///
QString Merge::id() const
{
return mId;
}
///
/// Get source
///
QString Merge::source() const
{
return mSource;
}
///
/// Set source
///
void Merge::setSource( const QString& source )
{
mSource = source;
// Clear out any old records
foreach ( MergeRecord* record, mRecordList )
///
/// Destructor
///
Merge::~Merge()
{
delete record;
foreach ( Record* record, mRecordList )
{
delete record;
}
mRecordList.clear();
}
mRecordList.clear();
open();
for ( MergeRecord* record = readNextRecord(); record != 0; record = readNextRecord() )
///
/// Get id
///
QString Merge::id() const
{
mRecordList.append( record );
return mId;
}
close();
///
/// Get source
///
QString Merge::source() const
{
return mSource;
}
///
/// Set source
///
void Merge::setSource( const QString& source )
{
mSource = source;
// Clear out any old records
foreach ( Record* record, mRecordList )
{
delete record;
}
mRecordList.clear();
open();
for ( Record* record = readNextRecord(); record != 0; record = readNextRecord() )
{
mRecordList.append( record );
}
close();
emit sourceChanged();
}
///
/// Get record list
///
const QList<MergeRecord*>& Merge::recordList( void ) const
{
return mRecordList;
}
///
/// Select matching record
///
void Merge::select( MergeRecord* record )
{
record->setSelected( true );
emit selectionChanged();
}
///
/// Unselect matching record
///
void Merge::unselect( MergeRecord* record )
{
record->setSelected( false );
emit selectionChanged();
}
///
/// Select/unselect i'th record
///
void Merge::setSelected( int i, bool state )
{
if ( (i >= 0) && (i < mRecordList.size()) )
{
mRecordList[i]->setSelected( state );
emit selectionChanged();
emit sourceChanged();
}
}
///
/// Select all records
///
void Merge::selectAll()
{
foreach ( MergeRecord* record, mRecordList )
///
/// Get record list
///
const QList<Record*>& Merge::recordList( void ) const
{
return mRecordList;
}
///
/// Select matching record
///
void Merge::select( Record* record )
{
record->setSelected( true );
emit selectionChanged();
}
emit selectionChanged();
}
///
/// Unselect all records
///
void Merge::unselectAll()
{
foreach ( MergeRecord* record, mRecordList )
///
/// Unselect matching record
///
void Merge::unselect( Record* record )
{
record->setSelected( false );
emit selectionChanged();
}
emit selectionChanged();
}
///
/// Return count of selected records
///
int Merge::nSelectedRecords() const
{
int count = 0;
foreach ( MergeRecord* record, mRecordList )
///
/// Select/unselect i'th record
///
void Merge::setSelected( int i, bool state )
{
if ( record->isSelected() )
if ( (i >= 0) && (i < mRecordList.size()) )
{
count++;
mRecordList[i]->setSelected( state );
emit selectionChanged();
}
}
return count;
}
///
/// Return list of selected records
///
const QList<MergeRecord*> Merge::selectedRecords() const
{
QList<MergeRecord*> list;
foreach ( MergeRecord* record, mRecordList )
///
/// Select all records
///
void Merge::selectAll()
{
if ( record->isSelected() )
foreach ( Record* record, mRecordList )
{
list.append( record );
record->setSelected( true );
}
emit selectionChanged();
}
///
/// Unselect all records
///
void Merge::unselectAll()
{
foreach ( Record* record, mRecordList )
{
record->setSelected( false );
}
emit selectionChanged();
}
///
/// Return count of selected records
///
int Merge::nSelectedRecords() const
{
int count = 0;
foreach ( Record* record, mRecordList )
{
if ( record->isSelected() )
{
count++;
}
}
return count;
}
///
/// Return list of selected records
///
const QList<Record*> Merge::selectedRecords() const
{
QList<Record*> list;
foreach ( Record* record, mRecordList )
{
if ( record->isSelected() )
{
list.append( record );
}
}
return list;
}
return list;
}
+79 -75
View File
@@ -1,4 +1,4 @@
/* Merge.h
/* Merge/Merge.h
*
* Copyright (C) 2015-2016 Jim Evins <evins@snaught.com>
*
@@ -18,95 +18,99 @@
* along with gLabels-qt. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef Merge_h
#define Merge_h
#ifndef merge_Merge_h
#define merge_Merge_h
#include <QObject>
#include <QString>
#include <QStringList>
#include <QList>
#include "MergeRecord.h"
///
/// Merge Object
///
struct Merge : QObject
namespace merge
{
Q_OBJECT
class Record; // Forward reference
/////////////////////////////////
// Life Cycle
/////////////////////////////////
protected:
Merge();
Merge( const Merge* merge );
public:
virtual ~Merge();
/////////////////////////////////
// Object duplication
/////////////////////////////////
virtual Merge* clone() const = 0;
/////////////////////////////////
// Properties
/////////////////////////////////
public:
QString id() const;
QString source() const;
void setSource( const QString& source );
const QList<MergeRecord*>& recordList( void ) const;
/////////////////////////////////
// Selection methods
/////////////////////////////////
public:
void select( MergeRecord* record );
void unselect( MergeRecord* record );
void setSelected( int i, bool state = true );
void selectAll();
void unselectAll();
int nSelectedRecords() const;
const QList<MergeRecord*> selectedRecords() const;
///
/// Merge Object
///
struct Merge : QObject
{
Q_OBJECT
/////////////////////////////////
// Virtual methods
/////////////////////////////////
public:
virtual QStringList keys() const = 0;
virtual QString primaryKey() const = 0;
protected:
virtual void open() = 0;
virtual void close() = 0;
virtual MergeRecord* readNextRecord() = 0;
/////////////////////////////////
// Life Cycle
/////////////////////////////////
protected:
Merge();
Merge( const Merge* merge );
public:
virtual ~Merge();
/////////////////////////////////
// Object duplication
/////////////////////////////////
virtual Merge* clone() const = 0;
/////////////////////////////////
// Properties
/////////////////////////////////
public:
QString id() const;
QString source() const;
void setSource( const QString& source );
const QList<Record*>& recordList( void ) const;
/////////////////////////////////
// Selection methods
/////////////////////////////////
public:
void select( Record* record );
void unselect( Record* record );
void setSelected( int i, bool state = true );
void selectAll();
void unselectAll();
int nSelectedRecords() const;
const QList<Record*> selectedRecords() const;
/////////////////////////////////
// Virtual methods
/////////////////////////////////
public:
virtual QStringList keys() const = 0;
virtual QString primaryKey() const = 0;
protected:
virtual void open() = 0;
virtual void close() = 0;
virtual Record* readNextRecord() = 0;
/////////////////////////////////
// Signals
/////////////////////////////////
signals:
void sourceChanged();
void selectionChanged();
/////////////////////////////////
// Signals
/////////////////////////////////
signals:
void sourceChanged();
void selectionChanged();
/////////////////////////////////
// Private data
/////////////////////////////////
protected:
QString mId;
private:
QString mSource;
QList<MergeRecord*> mRecordList;
};
/////////////////////////////////
// Private data
/////////////////////////////////
protected:
QString mId;
private:
QString mSource;
QList<Record*> mRecordList;
};
}
#endif // Merge_h
#endif // merge_Merge_h
-176
View File
@@ -1,176 +0,0 @@
/* MergeFactory.cpp
*
* Copyright (C) 2016 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 "MergeFactory.h"
#include "MergeNone.h"
#include "MergeTextCsv.h"
///
/// Static data
///
QMap<QString,MergeFactory::BackendEntry> MergeFactory::mBackendIdMap;
QMap<QString,MergeFactory::BackendEntry> MergeFactory::mBackendNameMap;
///
/// Constructor
///
MergeFactory::MergeFactory()
{
registerBackend( MergeNone::id(),
tr("None"),
NONE,
&MergeNone::create );
registerBackend( MergeTextCsv::id(),
tr("Text: Comma Separated Values (CSV)"),
FILE,
&MergeTextCsv::create );
}
///
/// Initialize
///
void MergeFactory::init()
{
static MergeFactory* singletonInstance = 0;
if ( !singletonInstance )
{
singletonInstance = new MergeFactory();
}
}
///
/// Create Merge object
///
Merge* MergeFactory::createMerge( const QString& id )
{
QMap<QString,BackendEntry>::iterator iBackend = mBackendIdMap.find( id );
if ( iBackend != mBackendIdMap.end() )
{
return iBackend->create();
}
return MergeNone::create();
}
///
/// Get name list
///
QStringList MergeFactory::nameList()
{
QStringList list;
foreach ( BackendEntry backend, mBackendIdMap )
{
list << backend.name;
}
return list;
}
///
/// Convert ID to name
///
QString MergeFactory::idToName( const QString& id )
{
if ( mBackendIdMap.contains( id ) )
{
return mBackendIdMap[id].name;
}
else
{
return tr("None");
}
}
///
/// Convert name to ID
///
QString MergeFactory::nameToId( const QString& name )
{
if ( mBackendNameMap.contains( name ) )
{
return mBackendNameMap[name].id;
}
else
{
return "None";
}
}
///
/// Convert ID to type
///
MergeFactory::SourceType MergeFactory::idToType( const QString& id )
{
if ( mBackendIdMap.contains( id ) )
{
return mBackendIdMap[id].type;
}
else
{
return NONE;
}
}
///
/// Lookup ID from index
///
QString MergeFactory::indexToId( int index )
{
QList<QString> ids = mBackendIdMap.keys();
if ( (index > 0) && (index < ids.size()) )
{
return ids[index];
}
return "None";
}
///
/// Register backend
///
void MergeFactory::registerBackend( const QString& id,
const QString& name,
SourceType type,
CreateFct create )
{
BackendEntry backend;
backend.name = name;
backend.type = type;
backend.create = create;
mBackendIdMap[ id ] = backend;
}
-96
View File
@@ -1,96 +0,0 @@
/* MergeFactory.h
*
* Copyright (C) 2016 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 MergeFactory_h
#define MergeFactory_h
#include "Merge.h"
#include <QCoreApplication>
#include <QStringList>
///
/// MergeFactory
///
struct MergeFactory
{
Q_DECLARE_TR_FUNCTIONS(MergeFactory)
/////////////////////////////////
// Source Type
/////////////////////////////////
public:
enum SourceType { NONE, FIXED, FILE };
/////////////////////////////////
// Life Cycle
/////////////////////////////////
protected:
MergeFactory();
/////////////////////////////////
// Static methods
/////////////////////////////////
public:
static void init();
static Merge* createMerge( const QString& id );
static QStringList nameList();
static QString idToName( const QString& id );
static QString nameToId( const QString& name );
static SourceType idToType( const QString& id );
static QString indexToId( int index );
/////////////////////////////////
// private methods
/////////////////////////////////
private:
typedef Merge* (*CreateFct)();
static void registerBackend( const QString& id,
const QString& name,
SourceType type,
CreateFct create );
/////////////////////////////////
// private data
/////////////////////////////////
class BackendEntry
{
public:
QString id;
QString name;
SourceType type;
CreateFct create;
};
static QMap<QString,BackendEntry> mBackendIdMap;
static QMap<QString,BackendEntry> mBackendNameMap;
};
#endif // MergeFactory_h
-117
View File
@@ -1,117 +0,0 @@
/* MergeNone.cpp
*
* Copyright (C) 2015 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 "MergeNone.h"
///
/// Constructor
///
MergeNone::MergeNone() : Merge()
{
mId = "None";
}
///
/// Constructor
///
MergeNone::MergeNone( const MergeNone* merge ) : Merge( merge )
{
}
///
/// Destructor
///
MergeNone::~MergeNone()
{
}
///
/// Clone
///
MergeNone* MergeNone::clone() const
{
return new MergeNone( this );
}
///
/// Get ID
///
QString MergeNone::id()
{
return "None";
}
///
/// Create
///
Merge* MergeNone::create()
{
return new MergeNone();
}
///
/// Get key list
///
QStringList MergeNone::keys() const
{
QStringList emptyList;
return emptyList;
}
///
/// Get primary key
///
QString MergeNone::primaryKey() const
{
return "";
}
///
/// Open source
///
void MergeNone::open()
{
}
///
/// Close source
///
void MergeNone::close()
{
}
///
/// Read next record
///
MergeRecord* MergeNone::readNextRecord()
{
return 0;
}
-70
View File
@@ -1,70 +0,0 @@
/* MergeNone.h
*
* Copyright (C) 2015 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 MergeNone_h
#define MergeNone_h
#include "Merge.h"
///
/// MergeNone Backend
///
struct MergeNone : public Merge
{
/////////////////////////////////
// Life Cycle
/////////////////////////////////
public:
MergeNone();
MergeNone( const MergeNone* merge );
virtual ~MergeNone();
/////////////////////////////////
// Object duplication
/////////////////////////////////
MergeNone* clone() const;
/////////////////////////////////
// Static methods
/////////////////////////////////
public:
static QString id();
static Merge* create();
/////////////////////////////////
// Implementation of virtual methods
/////////////////////////////////
public:
QStringList keys() const;
QString primaryKey() const;
protected:
void open();
void close();
MergeRecord* readNextRecord();
};
#endif // MergeNone_h
-412
View File
@@ -1,412 +0,0 @@
/* MergeText.cpp
*
* Copyright (C) 2016 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 "MergeText.h"
#include <algorithm>
#include <QtDebug>
///
/// Constructor
///
MergeText::MergeText( QChar delimiter, bool line1HasKeys )
: mNFieldsMax(0), mDelimeter(delimiter), mLine1HasKeys(line1HasKeys)
{
}
///
/// Constructor
///
MergeText::MergeText( const MergeText* merge )
: Merge( merge ),
mNFieldsMax(merge->mNFieldsMax),
mDelimeter(merge->mDelimeter), mLine1HasKeys(merge->mLine1HasKeys)
{
}
///
/// Destructor
///
MergeText::~MergeText()
{
}
///
/// Get key list
///
QStringList MergeText::keys() const
{
QStringList keys;
for ( int iField = 0; iField < mNFieldsMax; iField++ )
{
keys << keyFromIndex(iField);
}
return keys;
}
///
/// Get primary key
///
QString MergeText::primaryKey() const
{
return keyFromIndex(0);
}
///
/// Open source
///
void MergeText::open()
{
mFile.setFileName( source() );
mFile.open( QIODevice::ReadOnly|QIODevice::Text );
mKeys.clear();
mNFieldsMax = 0;
if ( mLine1HasKeys && mFile.isOpen() )
{
mKeys = parseLine();
if ( (mKeys.size() == 1) && (mKeys[0] == "") )
{
mKeys.clear();
}
else
{
mNFieldsMax = mKeys.size();
}
}
}
///
/// Close source
///
void MergeText::close()
{
if ( mFile.isOpen() )
{
mFile.close();
}
}
///
/// Read next record
///
MergeRecord* MergeText::readNextRecord()
{
QStringList values = parseLine();
if ( !values.isEmpty() )
{
MergeRecord* record = new MergeRecord();
int iField = 0;
foreach ( QString value, values )
{
(*record)[ keyFromIndex(iField) ] = value;
iField++;
}
mNFieldsMax = std::max( mNFieldsMax, iField );
return record;
}
return 0;
}
///
/// Key from field index
///
QString MergeText::keyFromIndex( int iField ) const
{
if ( mLine1HasKeys && ( iField < mKeys.size() ) )
{
return mKeys[iField];
}
else
{
return QString::number( iField+1 );
}
}
///
/// Parse line.
///
/// Attempt to be a robust parser of various CSV (and similar) formats.
///
/// Based on CSV format described in RFC 4180 section 2.
///
/// Additions to RFC 4180 rules:
/// - delimeters and other special characters may be "escaped" by a leading
/// backslash (\)
/// - C escape sequences for newline (\n) and tab (\t) are also translated.
/// - if quoted text is not followed by a delimeter, any additional text is
/// concatenated with quoted portion.
///
/// Returns a list of fields. A blank line is considered a line with one
/// empty field. Returns an empty list when done.
///
QStringList MergeText::parseLine()
{
QStringList fields;
enum State
{
DELIM, QUOTED, QUOTED_QUOTE1, QUOTED_ESCAPED, SIMPLE, SIMPLE_ESCAPED, DONE
} state = DELIM;
QByteArray field;
while ( state != DONE )
{
char c;
if ( mFile.getChar( &c ) )
{
switch (state)
{
case DELIM:
switch (c)
{
case '\n':
/* last field is empty. */
fields << "";
state = DONE;
break;
case '\r':
/* ignore */
state = DELIM;
break;
case '"':
/* start a quoted field. */
state = QUOTED;
break;
case '\\':
/* simple field, but 1st character is an escape. */
state = SIMPLE_ESCAPED;
break;
default:
if ( c == mDelimeter )
{
/* field is empty. */
fields << "";
state = DELIM;
}
else
{
/* begining of a simple field. */
field.append( c );
state = SIMPLE;
}
break;
}
break;
case QUOTED:
switch (c)
{
case '"':
/* Possible end of field, but could be 1st of a pair. */
state = QUOTED_QUOTE1;
break;
case '\\':
/* Escape next character, or special escape, e.g. \n. */
state = QUOTED_ESCAPED;
break;
default:
/* Use character literally. */
field.append( c );
break;
}
break;
case QUOTED_QUOTE1:
switch (c)
{
case '\n':
/* line ended after quoted item */
fields << QString( field );
state = DONE;
break;
case '"':
/* second quote, insert and stay quoted. */
field.append( c );
state = QUOTED;
break;
case '\r':
/* ignore and go to fallback */
state = SIMPLE;
break;
default:
if ( c == mDelimeter )
{
/* end of field. */
fields << QString( field );
field.clear();
state = DELIM;
}
else
{
/* fallback if not a delim or another quote. */
field.append( c );
state = SIMPLE;
}
break;
}
break;
case QUOTED_ESCAPED:
switch (c)
{
case 'n':
/* Decode "\n" as newline. */
field.append( '\n' );
state = QUOTED;
break;
case 't':
/* Decode "\t" as tab. */
field.append( '\t' );
state = QUOTED;
break;
default:
/* Use character literally. */
field.append( c );
state = QUOTED;
break;
}
break;
case SIMPLE:
switch (c)
{
case '\n':
/* line ended */
fields << QString( field );
state = DONE;
break;
case '\r':
/* ignore */
state = SIMPLE;
break;
case '\\':
/* Escape next character, or special escape, e.g. \n. */
state = SIMPLE_ESCAPED;
break;
default:
if ( c == mDelimeter )
{
/* end of field. */
fields << QString( field );
field.clear();
state = DELIM;
}
else
{
/* Use character literally. */
field.append( c );
state = SIMPLE;
}
break;
}
break;
case SIMPLE_ESCAPED:
switch (c)
{
case 'n':
/* Decode "\n" as newline. */
field.append( '\n' );
state = SIMPLE;
break;
case 't':
/* Decode "\t" as tab. */
field.append( '\t' );
state = SIMPLE;
break;
default:
/* Use character literally. */
field.append( (char)c );
state = SIMPLE;
break;
}
break;
default:
qWarning( "MergeText::parseLine()::Should not be reached! #1" );
break;
}
}
else
{
/* Handle EOF (could also be an error while reading). */
switch (state)
{
case DELIM:
/* EOF, no more lines. */
break;
case QUOTED:
/* File ended midway through quoted item. Truncate field. */
fields << QString( field );
break;
case QUOTED_QUOTE1:
/* File ended after quoted item. */
fields << QString( field );
break;
case QUOTED_ESCAPED:
/* File ended midway through quoted item. Truncate field. */
fields << QString( field );
break;
case SIMPLE:
/* File ended after simple item. */
fields << QString( field );
break;
case SIMPLE_ESCAPED:
/* File ended midway through escaped item. */
fields << QString( field );
break;
default:
qWarning( "MergeText::parseLine()::Should not be reached! #2" );
break;
}
state = DONE;
}
}
return fields;
}
-76
View File
@@ -1,76 +0,0 @@
/* MergeText.h
*
* Copyright (C) 2016 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 MergeText_h
#define MergeText_h
#include "Merge.h"
#include <QFile>
///
/// MergeText Backend
///
struct MergeText : public Merge
{
/////////////////////////////////
// Life Cycle
/////////////////////////////////
protected:
MergeText( QChar delimiter, bool line1HasKeys );
MergeText( const MergeText* merge );
virtual ~MergeText();
/////////////////////////////////
// Implementation of virtual methods
/////////////////////////////////
public:
QStringList keys() const;
QString primaryKey() const;
protected:
void open();
void close();
MergeRecord* readNextRecord();
/////////////////////////////////
// Private methods
/////////////////////////////////
QString keyFromIndex( int iField ) const;
QStringList parseLine();
/////////////////////////////////
// Private data
/////////////////////////////////
private:
QChar mDelimeter;
bool mLine1HasKeys;
QFile mFile;
QStringList mKeys;
int mNFieldsMax;
};
#endif // MergeText_h
+122
View File
@@ -0,0 +1,122 @@
/* Merge/None.cpp
*
* Copyright (C) 2015-2016 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 "None.h"
namespace merge
{
///
/// Constructor
///
None::None() : Merge()
{
mId = "None";
}
///
/// Constructor
///
None::None( const None* merge ) : Merge( merge )
{
}
///
/// Destructor
///
None::~None()
{
}
///
/// Clone
///
None* None::clone() const
{
return new None( this );
}
///
/// Get ID
///
QString None::id()
{
return "None";
}
///
/// Create
///
Merge* None::create()
{
return new None();
}
///
/// Get key list
///
QStringList None::keys() const
{
QStringList emptyList;
return emptyList;
}
///
/// Get primary key
///
QString None::primaryKey() const
{
return "";
}
///
/// Open source
///
void None::open()
{
}
///
/// Close source
///
void None::close()
{
}
///
/// Read next record
///
Record* None::readNextRecord()
{
return 0;
}
}
+74
View File
@@ -0,0 +1,74 @@
/* Merge/None.h
*
* Copyright (C) 2015-2016 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 merge_None_h
#define merge_None_h
#include "Merge.h"
namespace merge
{
///
/// None Merge Backend
///
struct None : public Merge
{
/////////////////////////////////
// Life Cycle
/////////////////////////////////
public:
None();
None( const None* merge );
virtual ~None();
/////////////////////////////////
// Object duplication
/////////////////////////////////
None* clone() const;
/////////////////////////////////
// Static methods
/////////////////////////////////
public:
static QString id();
static Merge* create();
/////////////////////////////////
// Implementation of virtual methods
/////////////////////////////////
public:
QStringList keys() const;
QString primaryKey() const;
protected:
void open();
void close();
Record* readNextRecord();
};
}
#endif // merge_None_h
@@ -1,4 +1,4 @@
/* MergeRecord.cpp
/* Merge/Record.cpp
*
* Copyright (C) 2013-2016 Jim Evins <evins@snaught.com>
*
@@ -18,48 +18,53 @@
* along with gLabels-qt. If not, see <http://www.gnu.org/licenses/>.
*/
#include "MergeRecord.h"
#include "Record.h"
///
/// Constructor
///
MergeRecord::MergeRecord() : mSelected( true )
namespace merge
{
}
///
/// Constructor
///
MergeRecord::MergeRecord( const MergeRecord* record )
: QMap<QString,QString>(*record), mSelected(record->mSelected)
{
}
///
/// Clone
///
MergeRecord* MergeRecord::clone() const
{
return new MergeRecord( this );
}
///
/// Is record selected?
///
bool MergeRecord::isSelected() const
{
return mSelected;
}
///
/// Set selected on not selected
///
void MergeRecord::setSelected( bool value )
{
mSelected = value;
///
/// Constructor
///
Record::Record() : mSelected( true )
{
}
///
/// Constructor
///
Record::Record( const Record* record )
: QMap<QString,QString>(*record), mSelected(record->mSelected)
{
}
///
/// Clone
///
Record* Record::clone() const
{
return new Record( this );
}
///
/// Is record selected?
///
bool Record::isSelected() const
{
return mSelected;
}
///
/// Set selected on not selected
///
void Record::setSelected( bool value )
{
mSelected = value;
}
}
@@ -1,4 +1,4 @@
/* MergeRecord.h
/* Merge/Record.h
*
* Copyright (C) 2013-2016 Jim Evins <evins@snaught.com>
*
@@ -18,48 +18,52 @@
* along with gLabels-qt. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef MergeRecord_h
#define MergeRecord_h
#ifndef merge_Record_h
#define merge_Record_h
#include <QString>
#include <QMap>
///
/// Merge Record
///
struct MergeRecord : public QMap<QString,QString>
namespace merge
{
///
/// Merge Record
///
struct Record : public QMap<QString,QString>
{
/////////////////////////////////
// Life Cycle
/////////////////////////////////
public:
MergeRecord();
MergeRecord( const MergeRecord* record );
/////////////////////////////////
// Life Cycle
/////////////////////////////////
public:
Record();
Record( const Record* record );
/////////////////////////////////
// Object duplication
/////////////////////////////////
MergeRecord* clone() const;
/////////////////////////////////
// Object duplication
/////////////////////////////////
Record* clone() const;
/////////////////////////////////
// Properties
/////////////////////////////////
public:
bool isSelected() const;
void setSelected( bool value );
/////////////////////////////////
// Properties
/////////////////////////////////
public:
bool isSelected() const;
void setSelected( bool value );
/////////////////////////////////
// Private data
/////////////////////////////////
private:
bool mSelected;
/////////////////////////////////
// Private data
/////////////////////////////////
private:
bool mSelected;
};
};
}
#endif // MergeRecord_h
#endif // merge_Record_h
+416
View File
@@ -0,0 +1,416 @@
/* Merge/Text.cpp
*
* Copyright (C) 2016 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 "Text.h"
#include "Record.h"
#include <algorithm>
#include <QtDebug>
namespace merge
{
///
/// Constructor
///
Text::Text( QChar delimiter, bool line1HasKeys )
: mNFieldsMax(0), mDelimeter(delimiter), mLine1HasKeys(line1HasKeys)
{
}
///
/// Constructor
///
Text::Text( const Text* merge )
: Merge( merge ),
mNFieldsMax(merge->mNFieldsMax),
mDelimeter(merge->mDelimeter), mLine1HasKeys(merge->mLine1HasKeys)
{
}
///
/// Destructor
///
Text::~Text()
{
}
///
/// Get key list
///
QStringList Text::keys() const
{
QStringList keys;
for ( int iField = 0; iField < mNFieldsMax; iField++ )
{
keys << keyFromIndex(iField);
}
return keys;
}
///
/// Get primary key
///
QString Text::primaryKey() const
{
return keyFromIndex(0);
}
///
/// Open source
///
void Text::open()
{
mFile.setFileName( source() );
mFile.open( QIODevice::ReadOnly|QIODevice::Text );
mKeys.clear();
mNFieldsMax = 0;
if ( mLine1HasKeys && mFile.isOpen() )
{
mKeys = parseLine();
if ( (mKeys.size() == 1) && (mKeys[0] == "") )
{
mKeys.clear();
}
else
{
mNFieldsMax = mKeys.size();
}
}
}
///
/// Close source
///
void Text::close()
{
if ( mFile.isOpen() )
{
mFile.close();
}
}
///
/// Read next record
///
Record* Text::readNextRecord()
{
QStringList values = parseLine();
if ( !values.isEmpty() )
{
Record* record = new Record();
int iField = 0;
foreach ( QString value, values )
{
(*record)[ keyFromIndex(iField) ] = value;
iField++;
}
mNFieldsMax = std::max( mNFieldsMax, iField );
return record;
}
return 0;
}
///
/// Key from field index
///
QString Text::keyFromIndex( int iField ) const
{
if ( mLine1HasKeys && ( iField < mKeys.size() ) )
{
return mKeys[iField];
}
else
{
return QString::number( iField+1 );
}
}
///
/// Parse line.
///
/// Attempt to be a robust parser of various CSV (and similar) formats.
///
/// Based on CSV format described in RFC 4180 section 2.
///
/// Additions to RFC 4180 rules:
/// - delimeters and other special characters may be "escaped" by a leading
/// backslash (\)
/// - C escape sequences for newline (\n) and tab (\t) are also translated.
/// - if quoted text is not followed by a delimeter, any additional text is
/// concatenated with quoted portion.
///
/// Returns a list of fields. A blank line is considered a line with one
/// empty field. Returns an empty list when done.
///
QStringList Text::parseLine()
{
QStringList fields;
enum State
{
DELIM, QUOTED, QUOTED_QUOTE1, QUOTED_ESCAPED, SIMPLE, SIMPLE_ESCAPED, DONE
} state = DELIM;
QByteArray field;
while ( state != DONE )
{
char c;
if ( mFile.getChar( &c ) )
{
switch (state)
{
case DELIM:
switch (c)
{
case '\n':
/* last field is empty. */
fields << "";
state = DONE;
break;
case '\r':
/* ignore */
state = DELIM;
break;
case '"':
/* start a quoted field. */
state = QUOTED;
break;
case '\\':
/* simple field, but 1st character is an escape. */
state = SIMPLE_ESCAPED;
break;
default:
if ( c == mDelimeter )
{
/* field is empty. */
fields << "";
state = DELIM;
}
else
{
/* begining of a simple field. */
field.append( c );
state = SIMPLE;
}
break;
}
break;
case QUOTED:
switch (c)
{
case '"':
/* Possible end of field, but could be 1st of a pair. */
state = QUOTED_QUOTE1;
break;
case '\\':
/* Escape next character, or special escape, e.g. \n. */
state = QUOTED_ESCAPED;
break;
default:
/* Use character literally. */
field.append( c );
break;
}
break;
case QUOTED_QUOTE1:
switch (c)
{
case '\n':
/* line ended after quoted item */
fields << QString( field );
state = DONE;
break;
case '"':
/* second quote, insert and stay quoted. */
field.append( c );
state = QUOTED;
break;
case '\r':
/* ignore and go to fallback */
state = SIMPLE;
break;
default:
if ( c == mDelimeter )
{
/* end of field. */
fields << QString( field );
field.clear();
state = DELIM;
}
else
{
/* fallback if not a delim or another quote. */
field.append( c );
state = SIMPLE;
}
break;
}
break;
case QUOTED_ESCAPED:
switch (c)
{
case 'n':
/* Decode "\n" as newline. */
field.append( '\n' );
state = QUOTED;
break;
case 't':
/* Decode "\t" as tab. */
field.append( '\t' );
state = QUOTED;
break;
default:
/* Use character literally. */
field.append( c );
state = QUOTED;
break;
}
break;
case SIMPLE:
switch (c)
{
case '\n':
/* line ended */
fields << QString( field );
state = DONE;
break;
case '\r':
/* ignore */
state = SIMPLE;
break;
case '\\':
/* Escape next character, or special escape, e.g. \n. */
state = SIMPLE_ESCAPED;
break;
default:
if ( c == mDelimeter )
{
/* end of field. */
fields << QString( field );
field.clear();
state = DELIM;
}
else
{
/* Use character literally. */
field.append( c );
state = SIMPLE;
}
break;
}
break;
case SIMPLE_ESCAPED:
switch (c)
{
case 'n':
/* Decode "\n" as newline. */
field.append( '\n' );
state = SIMPLE;
break;
case 't':
/* Decode "\t" as tab. */
field.append( '\t' );
state = SIMPLE;
break;
default:
/* Use character literally. */
field.append( (char)c );
state = SIMPLE;
break;
}
break;
default:
qWarning( "merge::Text::parseLine()::Should not be reached! #1" );
break;
}
}
else
{
/* Handle EOF (could also be an error while reading). */
switch (state)
{
case DELIM:
/* EOF, no more lines. */
break;
case QUOTED:
/* File ended midway through quoted item. Truncate field. */
fields << QString( field );
break;
case QUOTED_QUOTE1:
/* File ended after quoted item. */
fields << QString( field );
break;
case QUOTED_ESCAPED:
/* File ended midway through quoted item. Truncate field. */
fields << QString( field );
break;
case SIMPLE:
/* File ended after simple item. */
fields << QString( field );
break;
case SIMPLE_ESCAPED:
/* File ended midway through escaped item. */
fields << QString( field );
break;
default:
qWarning( "merge::Text::parseLine()::Should not be reached! #2" );
break;
}
state = DONE;
}
}
return fields;
}
}
+80
View File
@@ -0,0 +1,80 @@
/* Merge/Text.h
*
* Copyright (C) 2016 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 merge_Text_h
#define merge_Text_h
#include "Merge.h"
#include <QFile>
namespace merge
{
///
/// Text Merge Backend
///
struct Text : public Merge
{
/////////////////////////////////
// Life Cycle
/////////////////////////////////
protected:
Text( QChar delimiter, bool line1HasKeys );
Text( const Text* merge );
virtual ~Text();
/////////////////////////////////
// Implementation of virtual methods
/////////////////////////////////
public:
QStringList keys() const;
QString primaryKey() const;
protected:
void open();
void close();
Record* readNextRecord();
/////////////////////////////////
// Private methods
/////////////////////////////////
QString keyFromIndex( int iField ) const;
QStringList parseLine();
/////////////////////////////////
// Private data
/////////////////////////////////
private:
QChar mDelimeter;
bool mLine1HasKeys;
QFile mFile;
QStringList mKeys;
int mNFieldsMax;
};
}
#endif // merge_Text_h
@@ -1,4 +1,4 @@
/* MergeTextCsv.cpp
/* Merge/TextCsv.cpp
*
* Copyright (C) 2016 Jim Evins <evins@snaught.com>
*
@@ -18,56 +18,61 @@
* along with gLabels-qt. If not, see <http://www.gnu.org/licenses/>.
*/
#include "MergeTextCsv.h"
#include "TextCsv.h"
///
/// Constructor
///
MergeTextCsv::MergeTextCsv() : MergeText(',',false)
namespace merge
{
mId = "Text/Comma";
}
///
/// Constructor
///
MergeTextCsv::MergeTextCsv( const MergeTextCsv* merge ) : MergeText( merge )
{
}
///
/// Destructor
///
MergeTextCsv::~MergeTextCsv()
{
}
///
/// Clone
///
MergeTextCsv* MergeTextCsv::clone() const
{
return new MergeTextCsv( this );
}
///
/// Get ID
///
QString MergeTextCsv::id()
{
return "Text/Comma";
}
///
/// Create
///
Merge* MergeTextCsv::create()
{
return new MergeTextCsv();
///
/// Constructor
///
TextCsv::TextCsv() : Text(',',false)
{
mId = "Text/Comma";
}
///
/// Constructor
///
TextCsv::TextCsv( const TextCsv* merge ) : Text( merge )
{
}
///
/// Destructor
///
TextCsv::~TextCsv()
{
}
///
/// Clone
///
TextCsv* TextCsv::clone() const
{
return new TextCsv( this );
}
///
/// Get ID
///
QString TextCsv::id()
{
return "Text/Comma";
}
///
/// Create
///
Merge* TextCsv::create()
{
return new TextCsv();
}
}
@@ -1,4 +1,4 @@
/* MergeTextCsv.h
/* Merge/TextCsv.h
*
* Copyright (C) 2016 Jim Evins <evins@snaught.com>
*
@@ -18,42 +18,46 @@
* along with gLabels-qt. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef MergeTextCsv_h
#define MergeTextCsv_h
#ifndef merge_TextCsv_h
#define merge_TextCsv_h
#include "MergeText.h"
#include "Text.h"
///
/// MergeTextCsv Backend
///
struct MergeTextCsv : public MergeText
namespace merge
{
///
/// TextCsv Merge Backend
///
struct TextCsv : public Text
{
/////////////////////////////////
// Life Cycle
/////////////////////////////////
private:
MergeTextCsv();
MergeTextCsv( const MergeTextCsv* merge );
virtual ~MergeTextCsv();
/////////////////////////////////
// Life Cycle
/////////////////////////////////
private:
TextCsv();
TextCsv( const TextCsv* merge );
virtual ~TextCsv();
/////////////////////////////////
// Object duplication
/////////////////////////////////
public:
static QString id();
MergeTextCsv* clone() const;
/////////////////////////////////
// Object duplication
/////////////////////////////////
public:
static QString id();
TextCsv* clone() const;
/////////////////////////////////
// Static methods
/////////////////////////////////
public:
static Merge* create();
/////////////////////////////////
// Static methods
/////////////////////////////////
public:
static Merge* create();
};
};
}
#endif // MergeTextCsv_h
#endif // merge_TextCsv_h
+14 -14
View File
@@ -21,7 +21,7 @@
#include "MergeView.h"
#include "LabelModel.h"
#include "Merge/MergeFactory.h"
#include "Merge/Factory.h"
#include <QFileDialog>
#include <QFileInfo>
#include <QtDebug>
@@ -35,7 +35,7 @@ MergeView::MergeView( QWidget *parent )
{
setupUi( this );
mMergeFormatNames = MergeFactory::nameList();
mMergeFormatNames = merge::Factory::nameList();
formatCombo->addItems( mMergeFormatNames );
}
@@ -76,20 +76,20 @@ void MergeView::setModel( LabelModel* model, UndoRedoModel* undoRedoModel )
///
void MergeView::onMergeChanged()
{
int index = mMergeFormatNames.indexOf( MergeFactory::idToName( mModel->merge()->id() ) );
int index = mMergeFormatNames.indexOf( merge::Factory::idToName( mModel->merge()->id() ) );
mOldFormatComboIndex = index;
formatCombo->setCurrentIndex( index );
switch ( MergeFactory::idToType( mModel->merge()->id() ) )
switch ( merge::Factory::idToType( mModel->merge()->id() ) )
{
case MergeFactory::NONE:
case MergeFactory::FIXED:
case merge::Factory::NONE:
case merge::Factory::FIXED:
locationLabel->setEnabled( false );
locationButton->setEnabled( false );
locationButton->setText( "" );
break;
case MergeFactory::FILE:
case merge::Factory::FILE:
locationLabel->setEnabled( true );
locationButton->setEnabled( true );
if ( mModel->merge()->source().isEmpty() )
@@ -140,10 +140,10 @@ void MergeView::onMergeSelectionChanged()
{
mBlock = true; // Don't recurse
const QList<MergeRecord*>& records = mModel->merge()->recordList();
const QList<merge::Record*>& records = mModel->merge()->recordList();
int iRow = 0;
foreach ( MergeRecord* record, records )
foreach ( merge::Record* record, records )
{
QTableWidgetItem* item = recordsTable->item( iRow, 0 );
item->setCheckState( record->isSelected() ? Qt::Checked : Qt::Unchecked );
@@ -164,7 +164,7 @@ void MergeView::onFormatComboActivated()
{
mOldFormatComboIndex = index;
mModel->setMerge( MergeFactory::createMerge( MergeFactory::indexToId(index) ) );
mModel->setMerge( merge::Factory::createMerge( merge::Factory::indexToId(index) ) );
}
}
@@ -223,7 +223,7 @@ void MergeView::onCellChanged( int iRow, int iCol )
///
/// Load headers
///
void MergeView::loadHeaders( Merge* merge )
void MergeView::loadHeaders( merge::Merge* merge )
{
mPrimaryKey = merge->primaryKey();
mKeys = merge->keys();
@@ -264,15 +264,15 @@ void MergeView::loadHeaders( Merge* merge )
///
/// Load table
///
void MergeView::loadTable( Merge* merge )
void MergeView::loadTable( merge::Merge* merge )
{
mBlock = true;
const QList<MergeRecord*>& records = merge->recordList();
const QList<merge::Record*>& records = merge->recordList();
recordsTable->setRowCount( records.size() );
int iRow = 0;
foreach ( MergeRecord* record, records )
foreach ( merge::Record* record, records )
{
// First column for primay field
QTableWidgetItem* item = new QTableWidgetItem();
+4 -4
View File
@@ -22,16 +22,16 @@
#define MergeView_h
#include "ui_MergeView.h"
#include "Merge/Merge.h"
// Forward references
class LabelModel;
class UndoRedoModel;
class Merge;
///
/// Merge Property Editor Widget
/// merge::Merge Property Editor Widget
///
class MergeView : public QWidget, public Ui_MergeView
{
@@ -71,8 +71,8 @@ private slots:
// Private methods
/////////////////////////////////
private:
void loadHeaders( Merge* merge );
void loadTable( Merge* merge );
void loadHeaders( merge::Merge* merge );
void loadTable( merge::Merge* merge );
/////////////////////////////////
+5 -5
View File
@@ -22,8 +22,8 @@
#include "LabelModel.h"
#include "Merge/Merge.h"
#include "Merge/MergeNone.h"
#include "Merge/MergeRecord.h"
#include "Merge/None.h"
#include "Merge/Record.h"
#include <QPainter>
#include <QtDebug>
@@ -52,7 +52,7 @@ void PageRenderer::setModel( const LabelModel* model )
mMerge = mModel->merge();
mOrigins = mModel->frame()->getOrigins();
mNLabelsPerPage = mModel->frame()->nLabels();
mIsMerge = ( dynamic_cast<const MergeNone*>(mMerge) == 0 );
mIsMerge = ( dynamic_cast<const merge::None*>(mMerge) == 0 );
updateNPages();
}
@@ -226,7 +226,7 @@ void PageRenderer::printMergePage( QPainter* painter, int iPage ) const
iEnd = mLastLabel % mNLabelsPerPage;
}
const QList<MergeRecord*> records = mMerge->selectedRecords();
const QList<merge::Record*> records = mMerge->selectedRecords();
int iRecord = (iPage*mNLabelsPerPage + iStart - mStartLabel) % records.size();
printCropMarks( painter );
@@ -336,7 +336,7 @@ void PageRenderer::clipLabel( QPainter* painter ) const
}
void PageRenderer::printLabel( QPainter* painter, MergeRecord* record ) const
void PageRenderer::printLabel( QPainter* painter, merge::Record* record ) const
{
painter->save();
+6 -5
View File
@@ -24,14 +24,15 @@
#include "libglabels/Point.h"
#include "Merge/Merge.h"
#include "Merge/Record.h"
#include <QVector>
#include <QRect>
// Forward references
class QPainter;
class LabelModel;
class Merge;
class MergeRecord;
///
@@ -74,15 +75,15 @@ private:
void printCropMarks( QPainter* painter ) const;
void printOutline( QPainter* painter ) const;
void clipLabel( QPainter* painter ) const;
void printLabel( QPainter* painter, MergeRecord* record ) const;
void printLabel( QPainter* painter, merge::Record* record ) const;
/////////////////////////////////
// Private Data
/////////////////////////////////
private:
const LabelModel* mModel;
const Merge* mMerge;
const LabelModel* mModel;
const merge::Merge* mMerge;
int mNCopies;
int mStartLabel;
+2 -2
View File
@@ -27,7 +27,7 @@
//#include "LabelObjectLine.h"
//#include "LabelObjectImage.h"
//#include "LabelObjectBarcode.h"
#include "Merge/MergeNone.h"
#include "Merge/None.h"
#include "libglabels/XmlTemplateCreator.h"
#include "libglabels/XmlUtil.h"
@@ -97,7 +97,7 @@ XmlLabelCreator::createDoc( QDomDocument& doc, const LabelModel* label )
createObjectsNode( root, label );
if ( label->merge() && !dynamic_cast<MergeNone*>(label->merge()) )
if ( label->merge() && !dynamic_cast<merge::None*>(label->merge()) )
{
createMergeNode( root, label );
}
+2 -2
View File
@@ -27,7 +27,7 @@
//#include "LabelObjectLine.h"
//#include "LabelObjectImage.h"
//#include "LabelObjectBarcode.h"
#include "Merge/MergeFactory.h"
#include "Merge/Factory.h"
#include "libglabels/XmlTemplateParser.h"
#include "libglabels/XmlUtil.h"
@@ -441,7 +441,7 @@ XmlLabelParser::parseMergeNode( const QDomElement &node, LabelModel* label )
QString type = XmlUtil::getStringAttr( node, "type", "None" );
QString src = XmlUtil::getStringAttr( node, "src", "" );
Merge* merge = MergeFactory::createMerge( type );
merge::Merge* merge = merge::Factory::createMerge( type );
merge->setSource( src );
label->setMerge( merge );
+2 -2
View File
@@ -22,7 +22,7 @@
#include <QApplication>
#include "libglabels/Db.h"
#include "Merge/MergeFactory.h"
#include "Merge/Factory.h"
#include "Settings.h"
#include "MainWindow.h"
@@ -37,7 +37,7 @@ int main( int argc, char **argv )
Settings::init();
glabels::Db::init();
MergeFactory::init();
merge::Factory::init();
////// TEMPORARY TESTING ////////
#if 0
glabels::Db::printKnownPapers();