Initial implementation of text object.

This commit is contained in:
Jim Evins
2016-12-29 14:59:22 -05:00
parent 63adfab2a5
commit 27306808fb
16 changed files with 1202 additions and 51 deletions
+3
View File
@@ -25,6 +25,7 @@ set (glabels_sources
ColorPaletteButtonItem.cpp
ColorSwatch.cpp
Cursors.cpp
EnumUtil.cpp
FieldButton.cpp
FieldMenu.cpp
FieldMenuItem.cpp
@@ -40,6 +41,7 @@ set (glabels_sources
LabelModelImageObject.cpp
LabelModelLineObject.cpp
LabelModelShapeObject.cpp
LabelModelTextObject.cpp
LabelRegion.cpp
MainWindow.cpp
MergeView.cpp
@@ -85,6 +87,7 @@ set (glabels_qobject_headers
LabelModelImageObject.h
LabelModelLineObject.h
LabelModelShapeObject.h
LabelModelTextObject.h
MainWindow.h
MergeView.h
ObjectEditor.h
+121
View File
@@ -0,0 +1,121 @@
/* EnumUtil.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 "EnumUtil.h"
namespace EnumUtil
{
QString weightToString( QFont::Weight weight )
{
switch (weight)
{
case QFont::Bold:
return "bold";
break;
default:
return "normal";
break;
}
}
QFont::Weight stringToWeight( const QString& string )
{
if ( string == "bold" )
{
return QFont::Bold;
}
else
{
return QFont::Normal;
}
}
QString hAlignToString( Qt::Alignment align )
{
switch (align)
{
case Qt::AlignRight:
return "right";
break;
case Qt::AlignHCenter:
return "center";
break;
default:
return "left";
break;
}
}
Qt::Alignment stringToHAlign( const QString& string )
{
if ( string == "right" )
{
return Qt::AlignRight;
}
else if ( string == "center" )
{
return Qt::AlignHCenter;
}
else
{
return Qt::AlignLeft;
}
}
QString vAlignToString( Qt::Alignment align )
{
switch (align)
{
case Qt::AlignBottom:
return "bottom";
break;
case Qt::AlignVCenter:
return "center";
break;
default:
return "top";
break;
}
}
Qt::Alignment stringToVAlign( const QString& string )
{
if ( string == "bottom" )
{
return Qt::AlignBottom;
}
else if ( string == "center" )
{
return Qt::AlignVCenter;
}
else
{
return Qt::AlignTop;
}
}
}
+44
View File
@@ -0,0 +1,44 @@
/* FileUtil.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 EnumUtil_h
#define EnumUtil_h
#include <QString>
#include <QFont>
#include <Qt>
namespace EnumUtil
{
QString weightToString( QFont::Weight weight );
QFont::Weight stringToWeight( const QString& string );
QString hAlignToString( Qt::Alignment align );
Qt::Alignment stringToHAlign( const QString& string );
QString vAlignToString( Qt::Alignment align );
Qt::Alignment stringToVAlign( const QString& string );
}
#endif // EnumUtil_h
+16 -2
View File
@@ -30,6 +30,7 @@
#include "LabelModelEllipseObject.h"
#include "LabelModelImageObject.h"
#include "LabelModelLineObject.h"
#include "LabelModelTextObject.h"
#include "UndoRedoModel.h"
#include "Settings.h"
#include "Cursors.h"
@@ -363,6 +364,19 @@ LabelEditor::createLineMode()
}
///
/// Create text mode
///
void
LabelEditor::createTextMode()
{
setCursor( Cursors::Text() );
mCreateObjectType = Text;
mState = CreateIdle;
}
///
/// Resize Event Handler
///
@@ -505,7 +519,7 @@ LabelEditor::mousePressEvent( QMouseEvent* event )
mCreateObject = new LabelModelImageObject();
break;
case Text:
// mCreateObject = new LabelModelTextObject();
mCreateObject = new LabelModelTextObject();
break;
case Barcode:
// mCreateObject = new LabelModelBarcodeObject();
@@ -705,7 +719,7 @@ LabelEditor::mouseReleaseEvent( QMouseEvent* event )
switch (mCreateObjectType)
{
case Text:
mCreateObject->setSize( 0, 0 );
mCreateObject->setSize( 72, 36 );
break;
case Line:
mCreateObject->setSize( 72, 0 );
+32
View File
@@ -203,6 +203,7 @@ void LabelModelObject::setW( const glabels::Distance& value )
if ( mW != value )
{
mW = value;
sizeUpdated();
emit changed();
}
}
@@ -225,6 +226,7 @@ void LabelModelObject::setH( const glabels::Distance& value )
if ( mH != value )
{
mH = value;
sizeUpdated();
emit changed();
}
}
@@ -362,6 +364,25 @@ void LabelModelObject::setShadowColorNode( const ColorNode& value )
}
///
/// Virtual Text Property Default Getter
/// (Overridden by concrete class)
///
QString LabelModelObject::text() const
{
return "";
}
///
/// Virtual Text Property Default Setter
/// (Overridden by concrete class)
///
void LabelModelObject::setText( const QString& value )
{
}
///
/// Virtual Font Family Property Default Getter
/// (Overridden by concrete class)
@@ -804,6 +825,7 @@ void LabelModelObject::setSize( const glabels::Distance& w,
mW = w;
mH = h;
sizeUpdated();
emit changed();
}
@@ -844,6 +866,7 @@ void LabelModelObject::setWHonorAspect( const glabels::Distance& w )
mW = w;
mH = h;
sizeUpdated();
emit changed();
}
}
@@ -862,6 +885,7 @@ void LabelModelObject::setHHonorAspect( const glabels::Distance& h )
mW = w;
mH = h;
sizeUpdated();
emit changed();
}
}
@@ -1039,3 +1063,11 @@ void LabelModelObject::drawSelectionHighlight( QPainter* painter, double scale )
painter->restore();
}
///
/// Default sizeUpdated implementation.
///
void LabelModelObject::sizeUpdated()
{
}
+9
View File
@@ -161,6 +161,13 @@ public:
// Text Properties Virtual Interface
///////////////////////////////////////////////////////////////
public:
//
// Virtual Text Property: text
//
virtual QString text() const;
virtual void setText( const QString &value );
//
// Virtual Text Property: fontFamily
//
@@ -346,6 +353,8 @@ protected:
virtual void drawObject( QPainter* painter, bool inEditor, merge::Record* record ) const = 0;
virtual QPainterPath hoverPath( double scale ) const = 0;
virtual void sizeUpdated();
///////////////////////////////////////////////////////////////
// Protected Members
+502
View File
@@ -0,0 +1,502 @@
/* LabelModelTextObject.cpp
*
* Copyright (C) 2013-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 "LabelModelTextObject.h"
#include <QBrush>
#include <QPen>
#include <QTextDocument>
#include <QTextBlock>
#include <QtDebug>
namespace
{
const double marginPts = 3;
}
///
/// Constructor
///
LabelModelTextObject::LabelModelTextObject()
{
mOutline = new Outline( this );
mHandles << new HandleNorthWest( this );
mHandles << new HandleNorth( this );
mHandles << new HandleNorthEast( this );
mHandles << new HandleEast( this );
mHandles << new HandleSouthEast( this );
mHandles << new HandleSouth( this );
mHandles << new HandleSouthWest( this );
mHandles << new HandleWest( this );
mText = "";
mFontFamily = "Sans";
mFontSize = 10;
mFontWeight = QFont::Normal;
mFontItalicFlag = false;
mFontUnderlineFlag = false;
mTextColorNode = ColorNode( QColor( 0, 0, 0 ) );
mTextHAlign = Qt::AlignLeft;
mTextVAlign = Qt::AlignTop;
mTextLineSpacing = 1;
}
///
/// Copy constructor
///
LabelModelTextObject::LabelModelTextObject( const LabelModelTextObject* object ) : LabelModelObject(object)
{
mText = object->mText;
mFontFamily = object->mFontFamily;
mFontSize = object->mFontSize;
mFontWeight = object->mFontWeight;
mFontItalicFlag = object->mFontItalicFlag;
mFontUnderlineFlag = object->mFontUnderlineFlag;
mTextColorNode = object->mTextColorNode;
mTextHAlign = object->mTextHAlign;
mTextVAlign = object->mTextVAlign;
mTextLineSpacing = object->mTextLineSpacing;
}
///
/// Destructor
///
LabelModelTextObject::~LabelModelTextObject()
{
delete mOutline;
foreach( Handle* handle, mHandles )
{
delete handle;
}
mHandles.clear();
}
///
/// Clone
///
LabelModelTextObject* LabelModelTextObject::clone() const
{
return new LabelModelTextObject( this );
}
///
/// Text Property Getter
///
QString LabelModelTextObject::text( void ) const
{
return mText;
}
///
/// Text Property Setter
///
void LabelModelTextObject::setText( const QString& value )
{
if ( mText != value )
{
mText = value;
update();
emit changed();
}
}
///
/// FontFamily Property Getter
///
QString LabelModelTextObject::fontFamily( void ) const
{
return mFontFamily;
}
///
/// FontFamily Property Setter
///
void LabelModelTextObject::setFontFamily( const QString& value )
{
if ( mFontFamily != value )
{
mFontFamily = value;
update();
emit changed();
}
}
///
/// FontSize Property Getter
///
double LabelModelTextObject::fontSize( void ) const
{
return mFontSize;
}
///
/// FontSize Property Setter
///
void LabelModelTextObject::setFontSize( double value )
{
if ( mFontSize != value )
{
mFontSize = value;
update();
emit changed();
}
}
///
/// FontWeight Property Getter
///
QFont::Weight LabelModelTextObject::fontWeight( void ) const
{
return mFontWeight;
}
///
/// FontWeight Property Setter
///
void LabelModelTextObject::setFontWeight( QFont::Weight value )
{
if ( mFontWeight != value )
{
mFontWeight = value;
update();
emit changed();
}
}
///
/// FontItalicFlag Property Getter
///
bool LabelModelTextObject::fontItalicFlag( void ) const
{
return mFontItalicFlag;
}
///
/// FontItalicFlag Property Setter
///
void LabelModelTextObject::setFontItalicFlag( bool value )
{
if ( mFontItalicFlag != value )
{
mFontItalicFlag = value;
update();
emit changed();
}
}
///
/// FontUnderlineFlag Property Getter
///
bool LabelModelTextObject::fontUnderlineFlag( void ) const
{
return mFontUnderlineFlag;
}
///
/// FontUnderlineFlag Property Setter
///
void LabelModelTextObject::setFontUnderlineFlag( bool value )
{
if ( mFontUnderlineFlag != value )
{
mFontUnderlineFlag = value;
update();
emit changed();
}
}
///
/// Text Color Node Property Getter
///
ColorNode LabelModelTextObject::textColorNode( void ) const
{
return mTextColorNode;
}
///
/// Text Color Node Property Setter
///
void LabelModelTextObject::setTextColorNode( const ColorNode& value )
{
if ( mTextColorNode != value )
{
mTextColorNode = value;
update();
emit changed();
}
}
///
/// TextHAlign Property Getter
///
Qt::Alignment LabelModelTextObject::textHAlign( void ) const
{
return mTextHAlign;
}
///
/// TextHAlign Property Setter
///
void LabelModelTextObject::setTextHAlign( Qt::Alignment value )
{
if ( mTextHAlign != value )
{
mTextHAlign = value;
update();
emit changed();
}
}
///
/// TextVAlign Property Getter
///
Qt::Alignment LabelModelTextObject::textVAlign( void ) const
{
return mTextVAlign;
}
///
/// TextVAlign Property Setter
///
void LabelModelTextObject::setTextVAlign( Qt::Alignment value )
{
if ( mTextVAlign != value )
{
mTextVAlign = value;
update();
emit changed();
}
}
///
/// TextLineSpacing Property Getter
///
double LabelModelTextObject::textLineSpacing( void ) const
{
return mTextLineSpacing;
}
///
/// TextLineSpacing Property Setter
///
void LabelModelTextObject::setTextLineSpacing( double value )
{
if ( mTextLineSpacing != value )
{
mTextLineSpacing = value;
update();
emit changed();
}
}
///
// Can Text Capability Implementation
///
bool LabelModelTextObject::canText()
{
return true;
}
///
/// Draw shadow of object
///
void LabelModelTextObject::drawShadow( QPainter* painter, bool inEditor, merge::Record* record ) const
{
QColor textColor = mTextColorNode.color( record );
if ( textColor.alpha() )
{
QColor shadowColor = mShadowColorNode.color( record );
shadowColor.setAlphaF( mShadowOpacity );
if ( inEditor )
{
drawTextReal( painter, shadowColor );
}
}
}
///
/// Draw object itself
///
void LabelModelTextObject::drawObject( QPainter* painter, bool inEditor, merge::Record* record ) const
{
QColor textColor = mTextColorNode.color( record );
if ( inEditor )
{
drawTextReal( painter, textColor );
}
}
///
/// Path to test for hover condition
///
QPainterPath LabelModelTextObject::hoverPath( double scale ) const
{
return mHoverPath;
}
///
/// Size updated
///
void LabelModelTextObject::sizeUpdated()
{
update();
}
///
/// Update cached information
///
void LabelModelTextObject::update()
{
QFont font;
font.setFamily( mFontFamily );
font.setPointSizeF( mFontSize );
font.setWeight( mFontWeight );
font.setItalic( mFontItalicFlag );
font.setUnderline( mFontUnderlineFlag );
QTextOption textOption;
textOption.setAlignment( mTextHAlign );
textOption.setWrapMode( QTextOption::WordWrap );
QFontMetricsF fontMetrics( font );
double dy = fontMetrics.lineSpacing() * mTextLineSpacing;
QString displayText = mText.isEmpty() ? tr("Text") : mText;
QTextDocument document( displayText );
qDeleteAll( mEditorLayouts );
mEditorLayouts.clear();
// Pass #1 -- do initial layouts
double x = 0;
double y = 0;
QRectF boundingRect;
for ( int i = 0; i < document.blockCount(); i++ )
{
QTextLayout* layout = new QTextLayout( document.findBlockByNumber(i).text() );
layout->setFont( font );
layout->setTextOption( textOption );
layout->setCacheEnabled(true);
layout->beginLayout();
for ( QTextLine l = layout->createLine(); l.isValid(); l = layout->createLine() )
{
l.setLineWidth( mW.pt() - 2*marginPts );
l.setPosition( QPointF( x, y ) );
y += dy;
}
layout->endLayout();
mEditorLayouts.append( layout );
boundingRect = layout->boundingRect().united( boundingRect );
}
double h = boundingRect.height();
// Pass #2 -- adjust layout positions for vertical alignment and create hover path
x = marginPts;
switch ( mTextVAlign )
{
case Qt::AlignVCenter:
y = mH.pt()/2 - h/2;
break;
case Qt::AlignBottom:
y = mH.pt() - h - marginPts;
break;
default:
y = marginPts;
break;
}
QPainterPath hoverPath; // new empty hover path
foreach ( QTextLayout* layout, mEditorLayouts )
{
for ( int j = 0; j < layout->lineCount(); j++ )
{
QTextLine l = layout->lineAt(j);
l.setPosition( QPointF( x, y ) );
y += dy;
hoverPath.addRect( l.naturalTextRect() ); // add to new hover path
}
}
mHoverPath = hoverPath; // save new hover path
}
///
/// Actually draw text
///
void LabelModelTextObject::drawTextReal( QPainter* painter, const QColor& color ) const
{
if ( mText.isEmpty() )
{
QColor mutedColor = color;
mutedColor.setAlphaF( 0.5 * color.alphaF() );
painter->setPen( QPen( mutedColor ) );
}
else
{
painter->setPen( QPen( color ) );
}
foreach ( QTextLayout* layout, mEditorLayouts )
{
layout->draw( painter, QPointF( 0, 0 ) );
}
}
+171
View File
@@ -0,0 +1,171 @@
/* LabelModelTextObject.h
*
* Copyright (C) 2013-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 LabelModelTextObject_h
#define LabelModelTextObject_h
#include "LabelModelObject.h"
#include <QTextLayout>
///
/// Label Model Line Object
///
class LabelModelTextObject : public LabelModelObject
{
Q_OBJECT
///////////////////////////////////////////////////////////////
// Lifecycle Methods
///////////////////////////////////////////////////////////////
public:
LabelModelTextObject();
LabelModelTextObject( const LabelModelTextObject* object );
virtual ~LabelModelTextObject();
///////////////////////////////////////////////////////////////
// Object duplication
///////////////////////////////////////////////////////////////
virtual LabelModelTextObject* clone() const;
///////////////////////////////////////////////////////////////
// Property Implementations
///////////////////////////////////////////////////////////////
public:
//
// Text Property: text
//
virtual QString text() const;
virtual void setText( const QString &value );
//
// Text Property: fontFamily
//
virtual QString fontFamily() const;
virtual void setFontFamily( const QString &value );
//
// Text Property: fontSize
//
virtual double fontSize() const;
virtual void setFontSize( double value );
//
// Text Property: fontWeight
//
virtual QFont::Weight fontWeight() const;
virtual void setFontWeight( QFont::Weight value );
//
// Text Property: fontItalicFlag
//
virtual bool fontItalicFlag() const;
virtual void setFontItalicFlag( bool value );
//
// Text Property: fontUnderlineFlag
//
virtual bool fontUnderlineFlag() const;
virtual void setFontUnderlineFlag( bool value );
//
// Text Property: textColorNode
//
virtual ColorNode textColorNode() const;
virtual void setTextColorNode( const ColorNode &value );
//
// Text Property: textHAlign
//
virtual Qt::Alignment textHAlign() const;
virtual void setTextHAlign( Qt::Alignment value );
//
// Text Property: textVAlign
//
virtual Qt::Alignment textVAlign() const;
virtual void setTextVAlign( Qt::Alignment value );
//
// Text Property: textLineSpacing
//
virtual double textLineSpacing() const;
virtual void setTextLineSpacing( double value );
///////////////////////////////////////////////////////////////
// Capability Implementations
///////////////////////////////////////////////////////////////
public:
virtual bool canText();
///////////////////////////////////////////////////////////////
// Drawing operations
///////////////////////////////////////////////////////////////
protected:
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;
///////////////////////////////////////////////////////////////
// Private methods
///////////////////////////////////////////////////////////////
private:
virtual void sizeUpdated();
void update();
void drawTextReal( QPainter* painter, const QColor& color ) const;
///////////////////////////////////////////////////////////////
// Private Members
///////////////////////////////////////////////////////////////
private:
QString mText;
QString mFontFamily;
double mFontSize;
QFont::Weight mFontWeight;
bool mFontItalicFlag;
bool mFontUnderlineFlag;
ColorNode mTextColorNode;
Qt::Alignment mTextHAlign;
Qt::Alignment mTextVAlign;
double mTextLineSpacing;
QList<QTextLayout*> mEditorLayouts;
QPainterPath mHoverPath;
};
#endif // LabelModelTextObject_h
+2 -1
View File
@@ -1231,7 +1231,8 @@ void MainWindow::objectsArrowMode()
///
void MainWindow::objectsCreateText()
{
qDebug() << "ACTION: objects->Create->Text";
mUndoRedoModel->checkpoint( tr("Create Text") );
mLabelEditor->createTextMode();
}
+77
View File
@@ -27,6 +27,7 @@
#include "LabelModelEllipseObject.h"
#include "LabelModelImageObject.h"
#include "LabelModelLineObject.h"
#include "LabelModelTextObject.h"
#include "UndoRedoModel.h"
#include "Merge/Merge.h"
@@ -46,8 +47,19 @@ ObjectEditor::ObjectEditor( QWidget *parent )
{
setupUi( this );
textHAlignGroup = new QButtonGroup( this );
textHAlignGroup->addButton( textHAlignLeftToggle, Qt::AlignLeft );
textHAlignGroup->addButton( textHAlignCenterToggle, Qt::AlignHCenter );
textHAlignGroup->addButton( textHAlignRightToggle, Qt::AlignRight );
textVAlignGroup = new QButtonGroup( this );
textVAlignGroup->addButton( textVAlignTopToggle, Qt::AlignTop );
textVAlignGroup->addButton( textVAlignMiddleToggle, Qt::AlignVCenter );
textVAlignGroup->addButton( textVAlignBottomToggle, Qt::AlignBottom );
lineColorButton->init( "No line", QColor(0,0,0,0), QColor(0,0,0,255) );
fillColorButton->init( "No fill", QColor(0,0,0,0), QColor(0,0,0,255) );
textColorButton->init( "Default", QColor(0,0,0,255), QColor(0,0,0,255) );
shadowColorButton->init( "Default", QColor(0,0,0,255), QColor(0,0,0,255) );
imageFieldCombo->setName( "Key" );
@@ -187,6 +199,28 @@ void ObjectEditor::loadLineSizePage()
}
void ObjectEditor::loadTextPage()
{
if ( mObject )
{
mBlocked = true;
textFontFamilyCombo->setCurrentText( mObject->fontFamily() );
textFontSizeSpin->setValue( mObject->fontSize() );
textFontBoldToggle->setChecked( mObject->fontWeight() == QFont::Bold );
textFontItalicToggle->setChecked( mObject->fontItalicFlag() );
textFontUnderlineToggle->setChecked( mObject->fontUnderlineFlag() );
textColorButton->setColorNode( mObject->textColorNode() );
textHAlignGroup->button( mObject->textHAlign() )->setChecked( true );
textVAlignGroup->button( mObject->textVAlign() )->setChecked( true );
textLineSpacingSpin->setValue( mObject->textLineSpacing() );
textEdit->setText( mObject->text() );
mBlocked = false;
}
}
void ObjectEditor::loadShadowPage()
{
if ( mObject )
@@ -339,6 +373,25 @@ void ObjectEditor::onSelectionChanged()
setEnabled( true );
}
else if ( dynamic_cast<LabelModelTextObject*>(mObject) )
{
titleImageLabel->setPixmap( QPixmap(":icons/24x24/actions/glabels-text.png") );
titleLabel->setText( tr("Text object properties") );
notebook->addTab( textPage, "text" );
notebook->addTab( posSizePage, "position/size" );
notebook->addTab( shadowPage, "shadow" );
sizeRectFrame->setVisible( true );
sizeResetImageButton->setVisible( false );
sizeLineFrame->setVisible( false );
loadTextPage();
loadPositionPage();
loadShadowPage();
setEnabled( true );
}
else
{
Q_ASSERT_X( false, "ObjectEditor::onSelectionChanged", "Invalid object" );
@@ -524,6 +577,30 @@ void ObjectEditor::onLineSizeControlsChanged()
}
void ObjectEditor::onTextControlsChanged()
{
if ( !mBlocked )
{
mBlocked = true;
mUndoRedoModel->checkpoint( tr("Text") );
mObject->setFontFamily( textFontFamilyCombo->currentText() );
mObject->setFontSize( textFontSizeSpin->value() );
mObject->setFontWeight( textFontBoldToggle->isChecked() ? QFont::Bold : QFont::Normal );
mObject->setFontItalicFlag( textFontItalicToggle->isChecked() );
mObject->setFontUnderlineFlag( textFontUnderlineToggle->isChecked() );
mObject->setTextColorNode( textColorButton->colorNode() );
mObject->setTextHAlign( Qt::AlignmentFlag( textHAlignGroup->checkedId() ) );
mObject->setTextVAlign( Qt::AlignmentFlag( textVAlignGroup->checkedId() ) );
mObject->setTextLineSpacing( textLineSpacingSpin->value() );
mObject->setText( textEdit->toPlainText() );
mBlocked = false;
}
}
void ObjectEditor::onShadowControlsChanged()
{
if ( !mBlocked )
+7
View File
@@ -23,6 +23,8 @@
#include "ui_ObjectEditor.h"
#include "libglabels/Distance.h"
#include <QButtonGroup>
// Forward references
class LabelModel;
@@ -61,6 +63,7 @@ private:
void loadPositionPage();
void loadRectSizePage();
void loadLineSizePage();
void loadTextPage();
void loadShadowPage();
@@ -82,6 +85,7 @@ private slots:
void onPositionControlsChanged();
void onRectSizeControlsChanged();
void onLineSizeControlsChanged();
void onTextControlsChanged();
void onShadowControlsChanged();
void onChanged();
@@ -98,6 +102,9 @@ private:
int mSpinDigits;
double mSpinStep;
QButtonGroup* textHAlignGroup;
QButtonGroup* textVAlignGroup;
bool mBlocked;
};
+64 -5
View File
@@ -25,14 +25,18 @@
#include "LabelModelBoxObject.h"
#include "LabelModelEllipseObject.h"
#include "LabelModelLineObject.h"
//#include "LabelObjectImage.h"
//#include "LabelObjectBarcode.h"
#include "LabelModelImageObject.h"
#include "LabelModelTextObject.h"
//#include "LabelModelBarcodeObject.h"
#include "EnumUtil.h"
#include "Merge/None.h"
#include "libglabels/XmlTemplateCreator.h"
#include "libglabels/XmlUtil.h"
#include <QFile>
#include <QByteArray>
#include <QTextDocument>
#include <QTextBlock>
#include <QtDebug>
@@ -92,6 +96,7 @@ XmlLabelCreator::createDoc( QDomDocument& doc, const LabelModel* label )
QDomElement root = doc.createElement( "Glabels-document" );
doc.appendChild( root );
glabels::XmlUtil::setStringAttr( root, "version", "4.0" );
glabels::XmlTemplateCreator().createTemplateNode( root, label->tmplate() );
@@ -137,6 +142,10 @@ XmlLabelCreator::addObjectsToNode( QDomElement &parent, const QList<LabelModelOb
{
createObjectLineNode( parent, lineObject );
}
else if ( LabelModelTextObject* textObject = dynamic_cast<LabelModelTextObject*>(object) )
{
createObjectTextNode( parent, textObject );
}
// TODO: other object types
else
{
@@ -285,14 +294,64 @@ XmlLabelCreator::createObjectBarcodeNode( QDomElement &parent, const LabelModelB
void
XmlLabelCreator::createObjectTextNode( QDomElement &parent, const LabelModelTextObject* object )
{
// TODO
QDomDocument doc = parent.ownerDocument();
QDomElement node = doc.createElement( "Object-text" );
parent.appendChild( node );
/* position attrs */
glabels::XmlUtil::setLengthAttr( node, "x", object->x0() );
glabels::XmlUtil::setLengthAttr( node, "y", object->y0() );
/* size attrs */
glabels::XmlUtil::setLengthAttr( node, "w", object->w() );
glabels::XmlUtil::setLengthAttr( node, "h", object->h() );
/* color attr */
if ( object->textColorNode().fieldFlag() )
{
glabels::XmlUtil::setStringAttr( node, "color_field", object->textColorNode().key() );
}
else
{
glabels::XmlUtil::setUIntAttr( node, "color", object->textColorNode().rgba() );
}
/* font attrs */
glabels::XmlUtil::setStringAttr( node, "font_family", object->fontFamily() );
glabels::XmlUtil::setDoubleAttr( node, "font_size", object->fontSize() );
glabels::XmlUtil::setStringAttr( node, "font_weight", EnumUtil::weightToString( object->fontWeight() ) );
glabels::XmlUtil::setBoolAttr( node, "font_italic", object->fontItalicFlag() );
glabels::XmlUtil::setBoolAttr( node, "font_underline", object->fontUnderlineFlag() );
/* text attrs */
glabels::XmlUtil::setDoubleAttr( node, "line_spacing", object->textLineSpacing() );
glabels::XmlUtil::setStringAttr( node, "align", EnumUtil::hAlignToString( object->textHAlign() ) );
glabels::XmlUtil::setStringAttr( node, "valign", EnumUtil::vAlignToString( object->textVAlign() ) );
/* affine attrs */
createAffineAttrs( node, object );
/* shadow attrs */
createShadowAttrs( node, object );
/* serialize text contents */
QTextDocument document( object->text() );
int nBlocks = document.blockCount();
for ( int iBlock = 0; iBlock < nBlocks; iBlock++ )
{
createPNode( node, document.findBlockByNumber(iBlock).text() );
}
}
void
XmlLabelCreator::createObjectTopLevelSpanNode( QDomElement &parent, const LabelModelTextObject* object )
XmlLabelCreator::createPNode( QDomElement &parent, const QString& blockText )
{
// TODO
QDomDocument doc = parent.ownerDocument();
QDomElement node = doc.createElement( "p" );
parent.appendChild( node );
node.appendChild( doc.createTextNode( blockText ) );
}
+1 -1
View File
@@ -59,7 +59,7 @@ private:
static void createObjectImageNode( QDomElement &parent, const LabelModelImageObject* object );
static void createObjectBarcodeNode( QDomElement &parent, const LabelModelBarcodeObject* object );
static void createObjectTextNode( QDomElement &parent, const LabelModelTextObject* object );
static void createObjectTopLevelSpanNode( QDomElement &parent, const LabelModelTextObject* object );
static void createPNode( QDomElement &parent, const QString& blockText );
static void createAffineAttrs( QDomElement &node, const LabelModelObject* object );
static void createShadowAttrs( QDomElement &node, const LabelModelObject* object );
static void createMergeNode( QDomElement &parent, const LabelModel* label );
+82 -7
View File
@@ -25,8 +25,10 @@
#include "LabelModelBoxObject.h"
#include "LabelModelEllipseObject.h"
#include "LabelModelLineObject.h"
#include "LabelModelTextObject.h"
//#include "LabelObjectImage.h"
//#include "LabelObjectBarcode.h"
#include "EnumUtil.h"
#include "Merge/Factory.h"
#include "libglabels/XmlTemplateParser.h"
#include "libglabels/XmlUtil.h"
@@ -34,6 +36,8 @@
#include <QFile>
#include <QByteArray>
#include <zlib.h>
#include <QTextDocument>
#include <QTextCursor>
#include <QtDebug>
@@ -200,6 +204,12 @@ XmlLabelParser::parseRootNode( const QDomElement &node )
{
using namespace glabels;
QString version = XmlUtil::getStringAttr( node, "version", "" );
if ( version != "4.0" )
{
qWarning() << "TODO: compatability mode.";
}
LabelModel* label = new LabelModel();
/* Pass 1, extract data nodes to pre-load cache. */
@@ -270,6 +280,10 @@ XmlLabelParser::parseObjects( const QDomElement &node )
{
list.append( parseObjectLineNode( child.toElement() ) );
}
else if ( tagName == "Object-text" )
{
list.append( parseObjectTextNode( child.toElement() ) );
}
#if 0
else if ( tagName == "Object-image" )
{
@@ -279,10 +293,6 @@ XmlLabelParser::parseObjects( const QDomElement &node )
{
list.append( parseObjectBarcodeNode( child.toElement() ) );
}
else if ( tagName == "Object-text" )
{
list.append( parseObjectTextNode( child.toElement() ) );
}
#endif
else if ( !child.isComment() )
{
@@ -449,13 +459,78 @@ XmlLabelParser::parseObjectBarcodeNode( const QDomElement &node )
LabelModelTextObject*
XmlLabelParser::parseObjectTextNode( const QDomElement &node )
{
return 0;
using namespace glabels;
LabelModelTextObject* object = new LabelModelTextObject();
/* position attrs */
object->setX0( XmlUtil::getLengthAttr( node, "x", 0.0 ) );
object->setY0( XmlUtil::getLengthAttr( node, "y", 0.0 ) );
/* size attrs */
object->setW( XmlUtil::getLengthAttr( node, "w", 0 ) );
object->setH( XmlUtil::getLengthAttr( node, "h", 0 ) );
/* color attr */
{
QString key = XmlUtil::getStringAttr( node, "color_field", "" );
bool field_flag = !key.isEmpty();
uint32_t color = XmlUtil::getUIntAttr( node, "color", 0 );
object->setTextColorNode( ColorNode( field_flag, color, key ) );
}
/* font attrs */
object->setFontFamily( XmlUtil::getStringAttr( node, "font_family", "Sans" ) );
object->setFontSize( XmlUtil::getDoubleAttr( node, "font_size", 10 ) );
object->setFontWeight( EnumUtil::stringToWeight( XmlUtil::getStringAttr( node, "font_weight", "normal" ) ) );
object->setFontItalicFlag( XmlUtil::getBoolAttr( node, "font_italic", false ) );
object->setFontUnderlineFlag( XmlUtil::getBoolAttr( node, "font_underline", false ) );
/* text attrs */
object->setTextLineSpacing( XmlUtil::getDoubleAttr( node, "line_spacing", 1 ) );
object->setTextHAlign( EnumUtil::stringToHAlign( XmlUtil::getStringAttr( node, "align", "left" ) ) );
object->setTextVAlign( EnumUtil::stringToVAlign( XmlUtil::getStringAttr( node, "valign", "top" ) ) );
/* affine attrs */
parseAffineAttrs( node, object );
/* shadow attrs */
parseShadowAttrs( node, object );
/* deserialize contents. */
QTextDocument document;
QTextCursor cursor( &document );
bool firstBlock = true;
for ( QDomNode child = node.firstChild(); !child.isNull(); child = child.nextSibling() )
{
QString tagName = child.toElement().tagName();
if ( tagName == "p" )
{
if ( !firstBlock )
{
cursor.insertBlock();
}
firstBlock = false;
cursor.insertText( parsePNode( child.toElement() ) );
}
else if ( !child.isComment() )
{
qWarning() << "Unexpected" << node.tagName() << "child:" << tagName;
}
}
object->setText( document.toPlainText() );
return object;
}
void
XmlLabelParser::parseTopLevelSpanNode( const QDomElement &node, LabelModelTextObject* object )
QString
XmlLabelParser::parsePNode( const QDomElement &node )
{
return node.text();
}
+1 -1
View File
@@ -59,7 +59,7 @@ private:
static LabelModelImageObject* parseObjectImageNode( const QDomElement &node );
static LabelModelBarcodeObject* parseObjectBarcodeNode( const QDomElement &node );
static LabelModelTextObject* parseObjectTextNode( const QDomElement &node );
static void parseTopLevelSpanNode( const QDomElement &node, LabelModelTextObject* object );
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 );
+70 -34
View File
@@ -70,7 +70,7 @@
<item row="1" column="0">
<widget class="QTabWidget" name="notebook">
<property name="currentIndex">
<number>2</number>
<number>0</number>
</property>
<widget class="QWidget" name="textPage">
<attribute name="title">
@@ -106,6 +106,9 @@
<property name="checkable">
<bool>true</bool>
</property>
<property name="autoExclusive">
<bool>true</bool>
</property>
<property name="flat">
<bool>false</bool>
</property>
@@ -123,6 +126,9 @@
<property name="checkable">
<bool>true</bool>
</property>
<property name="autoExclusive">
<bool>true</bool>
</property>
</widget>
</item>
<item>
@@ -137,6 +143,9 @@
<property name="checkable">
<bool>true</bool>
</property>
<property name="autoExclusive">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
@@ -162,6 +171,9 @@
<property name="checkable">
<bool>true</bool>
</property>
<property name="autoExclusive">
<bool>true</bool>
</property>
<property name="flat">
<bool>false</bool>
</property>
@@ -179,6 +191,9 @@
<property name="checkable">
<bool>true</bool>
</property>
<property name="autoExclusive">
<bool>true</bool>
</property>
</widget>
</item>
<item>
@@ -193,6 +208,9 @@
<property name="checkable">
<bool>true</bool>
</property>
<property name="autoExclusive">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
@@ -207,7 +225,14 @@
<item row="2" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_19">
<item>
<widget class="QDoubleSpinBox" name="textLineSpacingSpin"/>
<widget class="QDoubleSpinBox" name="textLineSpacingSpin">
<property name="maximum">
<double>3.000000000000000</double>
</property>
<property name="singleStep">
<double>0.010000000000000</double>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_16">
@@ -352,7 +377,17 @@
<item row="1" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_18">
<item>
<widget class="QDoubleSpinBox" name="textFontSizeSpin"/>
<widget class="QDoubleSpinBox" name="textFontSizeSpin">
<property name="decimals">
<number>0</number>
</property>
<property name="minimum">
<double>1.000000000000000</double>
</property>
<property name="singleStep">
<double>1.000000000000000</double>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_15">
@@ -1519,7 +1554,7 @@
<sender>textFontFamilyCombo</sender>
<signal>currentIndexChanged(int)</signal>
<receiver>ObjectEditor</receiver>
<slot>onChanged()</slot>
<slot>onTextControlsChanged()</slot>
<hints>
<hint type="sourcelabel">
<x>254</x>
@@ -1535,7 +1570,7 @@
<sender>textFontSizeSpin</sender>
<signal>valueChanged(double)</signal>
<receiver>ObjectEditor</receiver>
<slot>onChanged()</slot>
<slot>onTextControlsChanged()</slot>
<hints>
<hint type="sourcelabel">
<x>128</x>
@@ -1551,7 +1586,7 @@
<sender>textFontBoldToggle</sender>
<signal>toggled(bool)</signal>
<receiver>ObjectEditor</receiver>
<slot>onChanged()</slot>
<slot>onTextControlsChanged()</slot>
<hints>
<hint type="sourcelabel">
<x>125</x>
@@ -1567,7 +1602,7 @@
<sender>textFontItalicToggle</sender>
<signal>toggled(bool)</signal>
<receiver>ObjectEditor</receiver>
<slot>onChanged()</slot>
<slot>onTextControlsChanged()</slot>
<hints>
<hint type="sourcelabel">
<x>172</x>
@@ -1583,7 +1618,7 @@
<sender>textFontUnderlineToggle</sender>
<signal>toggled(bool)</signal>
<receiver>ObjectEditor</receiver>
<slot>onChanged()</slot>
<slot>onTextControlsChanged()</slot>
<hints>
<hint type="sourcelabel">
<x>236</x>
@@ -1599,7 +1634,7 @@
<sender>textColorButton</sender>
<signal>colorChanged()</signal>
<receiver>ObjectEditor</receiver>
<slot>onChanged()</slot>
<slot>onTextControlsChanged()</slot>
<hints>
<hint type="sourcelabel">
<x>138</x>
@@ -1615,7 +1650,7 @@
<sender>textHAlignLeftToggle</sender>
<signal>toggled(bool)</signal>
<receiver>ObjectEditor</receiver>
<slot>onChanged()</slot>
<slot>onTextControlsChanged()</slot>
<hints>
<hint type="sourcelabel">
<x>154</x>
@@ -1631,7 +1666,7 @@
<sender>textHAlignCenterToggle</sender>
<signal>toggled(bool)</signal>
<receiver>ObjectEditor</receiver>
<slot>onChanged()</slot>
<slot>onTextControlsChanged()</slot>
<hints>
<hint type="sourcelabel">
<x>219</x>
@@ -1647,7 +1682,7 @@
<sender>textHAlignRightToggle</sender>
<signal>toggled(bool)</signal>
<receiver>ObjectEditor</receiver>
<slot>onChanged()</slot>
<slot>onTextControlsChanged()</slot>
<hints>
<hint type="sourcelabel">
<x>271</x>
@@ -1663,7 +1698,7 @@
<sender>textVAlignTopToggle</sender>
<signal>toggled(bool)</signal>
<receiver>ObjectEditor</receiver>
<slot>onChanged()</slot>
<slot>onTextControlsChanged()</slot>
<hints>
<hint type="sourcelabel">
<x>161</x>
@@ -1679,7 +1714,7 @@
<sender>textVAlignMiddleToggle</sender>
<signal>toggled(bool)</signal>
<receiver>ObjectEditor</receiver>
<slot>onChanged()</slot>
<slot>onTextControlsChanged()</slot>
<hints>
<hint type="sourcelabel">
<x>209</x>
@@ -1695,7 +1730,7 @@
<sender>textVAlignBottomToggle</sender>
<signal>toggled(bool)</signal>
<receiver>ObjectEditor</receiver>
<slot>onChanged()</slot>
<slot>onTextControlsChanged()</slot>
<hints>
<hint type="sourcelabel">
<x>271</x>
@@ -1711,7 +1746,7 @@
<sender>textLineSpacingSpin</sender>
<signal>valueChanged(double)</signal>
<receiver>ObjectEditor</receiver>
<slot>onChanged()</slot>
<slot>onTextControlsChanged()</slot>
<hints>
<hint type="sourcelabel">
<x>180</x>
@@ -1723,22 +1758,6 @@
</hint>
</hints>
</connection>
<connection>
<sender>textEdit</sender>
<signal>textChanged()</signal>
<receiver>ObjectEditor</receiver>
<slot>onChanged()</slot>
<hints>
<hint type="sourcelabel">
<x>271</x>
<y>538</y>
</hint>
<hint type="destinationlabel">
<x>394</x>
<y>543</y>
</hint>
</hints>
</connection>
<connection>
<sender>textInsertFieldButton</sender>
<signal>keySelected()</signal>
@@ -2130,8 +2149,8 @@
<slot>onImageFileButtonClicked()</slot>
<hints>
<hint type="sourcelabel">
<x>321</x>
<y>119</y>
<x>190</x>
<y>161</y>
</hint>
<hint type="destinationlabel">
<x>394</x>
@@ -2155,6 +2174,22 @@
</hint>
</hints>
</connection>
<connection>
<sender>textEdit</sender>
<signal>textChanged()</signal>
<receiver>ObjectEditor</receiver>
<slot>onTextControlsChanged()</slot>
<hints>
<hint type="sourcelabel">
<x>341</x>
<y>539</y>
</hint>
<hint type="destinationlabel">
<x>398</x>
<y>553</y>
</hint>
</hints>
</connection>
</connections>
<slots>
<slot>onChanged()</slot>
@@ -2167,5 +2202,6 @@
<slot>onLineSizeControlsChanged()</slot>
<slot>onImageFileButtonClicked()</slot>
<slot>onImageKeySelected(QString)</slot>
<slot>onTextControlsChanged()</slot>
</slots>
</ui>