/* LabelModel.cpp * * Copyright (C) 2013 Jim Evins * * 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 . */ #include "LabelModel.h" #include namespace glabels { /** * Default constructor. */ LabelModel::LabelModel() : mModified(true) { } /** * Add object. */ void LabelModel::addObject( LabelModelObject* object ) { object->setParent( this ); mObjectList << object; connect( object, SIGNAL(changed()), this, SLOT(objectChanged(LabelModelObject*)) ); connect( object, SIGNAL(moved()), this, SLOT(objectMoved(LabelModelObject*)) ); mModified = true; emit objectAdded( object ); emit changed(); } void LabelModel::onObjectChanged( LabelModelObject* object ) { mModified = true; emit objectChanged( object ); emit changed(); } void LabelModel::onObjectMoved( LabelModelObject* object ) { mModified = true; emit objectMoved( object ); emit changed(); } void LabelModel::deleteObject( LabelModelObject* object ) { object->unselect(); mObjectList.removeOne( object ); disconnect( object, 0, this, 0 ); mModified = true; emit objectDeleted( object ); emit changed(); } /** * Select object. */ void LabelModel::selectObject( LabelModelObject* object ) { object->select(); emit selectionChanged(); } /** * Unselect object. */ void LabelModel::unselectObject( LabelModelObject* object ) { object->unselect(); emit selectionChanged(); } /** * Select all objects. */ void LabelModel::selectAll() { foreach ( LabelModelObject* object, mObjectList ) { object->select(); } emit selectionChanged(); } /** * Unselect object all objects. */ void LabelModel::unselectAll() { foreach ( LabelModelObject* object, mObjectList ) { object->unselect(); } emit selectionChanged(); } void LabelModel::selectRegion( const LabelRegion ®ion ) { double rX1 = std::min( region.x1(), region.x2() ); double rY1 = std::min( region.y1(), region.y2() ); double rX2 = std::max( region.x1(), region.x2() ); double rY2 = std::max( region.y1(), region.y2() ); foreach ( LabelModelObject* object, mObjectList ) { LabelRegion objectExtent = object->getExtent(); if ( (objectExtent.x1() >= rX1) && (objectExtent.x2() <= rX2) && (objectExtent.y1() >= rY1) && (objectExtent.y2() <= rY2) ) { object->select(); } } emit selectionChanged(); } bool LabelModel::isSelectionEmpty() { foreach ( LabelModelObject* object, mObjectList ) { if ( object->isSelected() ) { return false; } } return true; } bool LabelModel::isSelectionAtomic() { int nSelected = 0; foreach ( LabelModelObject* object, mObjectList ) { if ( object->isSelected() ) { nSelected++; if ( nSelected > 1 ) { return false; } } } return (nSelected == 1); } QList LabelModel::getSelection() { QList selectedList; foreach ( LabelModelObject* object, mObjectList ) { if ( object->isSelected() ) { selectedList << object; } } } LabelModelObject* LabelModel::getFirstSelectedObject() { foreach ( LabelModelObject* object, mObjectList ) { if ( object->isSelected() ) { return object; } } } bool LabelModel::canSelectionText() { foreach ( LabelModelObject* object, mObjectList ) { if ( object->isSelected() && object->canText() ) { return true; } } return false; } bool LabelModel::canSelectionFill() { foreach ( LabelModelObject* object, mObjectList ) { if ( object->isSelected() && object->canFill() ) { return true; } } return false; } bool LabelModel::canSelectionLineColor() { foreach ( LabelModelObject* object, mObjectList ) { if ( object->isSelected() && object->canLineColor() ) { return true; } } return false; } bool LabelModel::canSelectionLineWidth() { foreach ( LabelModelObject* object, mObjectList ) { if ( object->isSelected() && object->canLineWidth() ) { return true; } } return false; } void LabelModel::deleteSelection() { QList selectedList = getSelection(); foreach ( LabelModelObject* object, selectedList ) { deleteObject( object ); } mModified = true; emit changed(); emit selectionChanged(); } void LabelModel::raiseSelectionToTop() { QList selectedList = getSelection(); foreach ( LabelModelObject* object, selectedList ) { mObjectList.removeOne( object ); } /* Move to end of list, representing top most object. */ foreach ( LabelModelObject* object, selectedList ) { mObjectList.push_back( object ); emit objectToTop( object ); } mModified = true; emit changed(); } void LabelModel::lowerSelectionToBottom() { QList selectedList = getSelection(); foreach ( LabelModelObject* object, selectedList ) { mObjectList.removeOne( object ); } /* Move to front of list, representing bottom most object. */ foreach ( LabelModelObject* object, selectedList ) { mObjectList.push_front( object ); emit objectToBottom( object ); } mModified = true; emit changed(); } void LabelModel::rotateSelection( double thetaDegs ) { foreach ( LabelModelObject* object, mObjectList ) { if ( object->isSelected() ) { object->rotate( thetaDegs ); } } mModified = true; emit changed(); } void LabelModel::rotateSelectionLeft() { rotateSelection( -90.0 ); } void LabelModel::rotateSelectionRight() { rotateSelection( 90.0 ); } void LabelModel::flipSelectionHoriz() { foreach ( LabelModelObject* object, mObjectList ) { if ( object->isSelected() ) { object->flipHoriz(); } } mModified = true; emit changed(); } void LabelModel::flipSelectionVert() { foreach ( LabelModelObject* object, mObjectList ) { if ( object->isSelected() ) { object->flipVert(); } } mModified = true; emit changed(); } void LabelModel::alignSelectionLeft() { if ( isSelectionEmpty() || isSelectionAtomic() ) { return; } QList selectedList = getSelection(); /* Find left-most edge. */ double x1_min = 7200; /* Start with a very large value: 7200pts = 100in */ foreach ( LabelModelObject* object, selectedList ) { LabelRegion r = object->getExtent(); if ( r.x1() < x1_min ) x1_min = r.x1(); } /* Now adjust the object positions to line up the left edges at left-most edge. */ foreach ( LabelModelObject* object, selectedList ) { LabelRegion r = object->getExtent(); double dx = x1_min - r.x1(); object->setPositionRelative( dx, 0 ); } mModified = true; emit changed(); } void LabelModel::alignSelectionRight() { if ( isSelectionEmpty() || isSelectionAtomic() ) { return; } QList selectedList = getSelection(); /* Find right-most edge. */ double x1_max = -7200; /* Start with a very large negative value: 7200pts = 100in */ foreach ( LabelModelObject* object, selectedList ) { LabelRegion r = object->getExtent(); if ( r.x1() > x1_max ) x1_max = r.x1(); } /* Now adjust the object positions to line up the right edges at right-most edge. */ foreach ( LabelModelObject* object, selectedList ) { LabelRegion r = object->getExtent(); double dx = x1_max - r.x1(); object->setPositionRelative( dx, 0 ); } mModified = true; emit changed(); } void LabelModel::alignSelectionHCenter() { if ( isSelectionEmpty() || isSelectionAtomic() ) { return; } QList selectedList = getSelection(); /* Find average center of objects. */ double xsum = 0; int n = 0; foreach ( LabelModelObject* object, selectedList ) { LabelRegion r = object->getExtent(); xsum += (r.x1() + r.x2()) / 2.0; n++; } double xavg = xsum / n; /* Find object closest to average center of objects. */ double xcenter = 7200; /* Start with very large value. */ double dxmin = fabs( xavg - xcenter ); foreach ( LabelModelObject* object, selectedList ) { LabelRegion r = object->getExtent(); double dx = fabs( xavg - (r.x1() + r.x2())/2.0 ); if ( dx < dxmin ) { dxmin = dx; xcenter = (r.x1() + r.x2()) / 2.0; } } /* Now adjust the object positions to line up with the center of this object. */ foreach ( LabelModelObject* object, selectedList ) { LabelRegion r = object->getExtent(); double dx = xcenter - (r.x1() + r.x2())/2.0; object->setPositionRelative( dx, 0 ); } mModified = true; emit changed(); } void LabelModel::alignSelectionTop() { if ( isSelectionEmpty() || isSelectionAtomic() ) { return; } QList selectedList = getSelection(); /* Find top-most edge. */ double y1_min = 7200; /* Start with a very large value: 7200pts = 100in */ foreach ( LabelModelObject* object, selectedList ) { LabelRegion r = object->getExtent(); if ( r.y1() < y1_min ) y1_min = r.y1(); } /* Now adjust the object positions to line up the top edges at top-most edge. */ foreach ( LabelModelObject* object, selectedList ) { LabelRegion r = object->getExtent(); double dy = y1_min - r.y1(); object->setPositionRelative( 0, dy ); } mModified = true; emit changed(); } void LabelModel::alignSelectionBottom() { if ( isSelectionEmpty() || isSelectionAtomic() ) { return; } QList selectedList = getSelection(); /* Find bottom-most edge. */ double y1_max = -7200; /* Start with a very large negative value: 7200pts = 100in */ foreach ( LabelModelObject* object, selectedList ) { LabelRegion r = object->getExtent(); if ( r.y1() > y1_max ) y1_max = r.y1(); } /* Now adjust the object positions to line up the bottom edges at bottom-most edge. */ foreach ( LabelModelObject* object, selectedList ) { LabelRegion r = object->getExtent(); double dy = y1_max - r.y1(); object->setPositionRelative( 0, dy ); } mModified = true; emit changed(); } void LabelModel::alignSelectionVCenter() { if ( isSelectionEmpty() || isSelectionAtomic() ) { return; } QList selectedList = getSelection(); /* Find average center of objects. */ double ysum = 0; int n = 0; foreach ( LabelModelObject* object, selectedList ) { LabelRegion r = object->getExtent(); ysum += (r.y1() + r.y2()) / 2.0; n++; } double yavg = ysum / n; /* Find object closest to average center of objects. */ double ycenter = 7200; /* Start with very large value. */ double dymin = fabs( yavg - ycenter ); foreach ( LabelModelObject* object, selectedList ) { LabelRegion r = object->getExtent(); double dy = fabs( yavg - (r.y1() + r.y2())/2.0 ); if ( dy < dymin ) { dymin = dy; ycenter = (r.y1() + r.y2()) / 2.0; } } /* Now adjust the object positions to line up with the center of this object. */ foreach ( LabelModelObject* object, selectedList ) { LabelRegion r = object->getExtent(); double dy = ycenter - (r.y1() + r.y2())/2.0; object->setPositionRelative( 0, dy ); } mModified = true; emit changed(); } void LabelModel::centerSelectionHoriz() { double xLabelCenter = w() / 2.0; foreach ( LabelModelObject* object, mObjectList ) { if ( object->isSelected() ) { LabelRegion r = object->getExtent(); double xObjectCenter = (r.x1() + r.x2()) / 2.0; double dx = xLabelCenter - xObjectCenter; object->setPositionRelative( dx, 0 ); } } mModified = true; emit changed(); } void LabelModel::centerSelectionVert() { double yLabelCenter = h() / 2.0; foreach ( LabelModelObject* object, mObjectList ) { if ( object->isSelected() ) { LabelRegion r = object->getExtent(); double yObjectCenter = (r.y1() + r.y2()) / 2.0; double dy = yLabelCenter - yObjectCenter; object->setPositionRelative( 0, dy ); } } mModified = true; emit changed(); } void LabelModel::moveSelection( double dx, double dy ) { foreach ( LabelModelObject* object, mObjectList ) { if ( object->isSelected() ) { object->setPositionRelative( dx, dy ); } } mModified = true; emit changed(); } void LabelModel::setSelectionFontFamily( const QString &fontFamily ) { foreach ( LabelModelObject* object, mObjectList ) { if ( object->isSelected() ) { object->setFontFamily( fontFamily ); } } mModified = true; emit changed(); } void LabelModel::setSelectionFontSize( double fontSize ) { foreach ( LabelModelObject* object, mObjectList ) { if ( object->isSelected() ) { object->setFontSize( fontSize ); } } mModified = true; emit changed(); } void LabelModel::setSelectionFontWeight( QFont::Weight fontWeight ) { foreach ( LabelModelObject* object, mObjectList ) { if ( object->isSelected() ) { object->setFontWeight( fontWeight ); } } mModified = true; emit changed(); } void LabelModel::setSelectionFontItalicFlag( bool fontItalicFlag ) { foreach ( LabelModelObject* object, mObjectList ) { if ( object->isSelected() ) { object->setFontItalicFlag( fontItalicFlag ); } } mModified = true; emit changed(); } void LabelModel::setSelectionTextHAlign( Qt::Alignment textHAlign ) { foreach ( LabelModelObject* object, mObjectList ) { if ( object->isSelected() ) { object->setTextHAlign( textHAlign ); } } mModified = true; emit changed(); } void LabelModel::setSelectionTextVAlign( Qt::Alignment textVAlign ) { foreach ( LabelModelObject* object, mObjectList ) { if ( object->isSelected() ) { object->setTextVAlign( textVAlign ); } } mModified = true; emit changed(); } void LabelModel::setSelectionTextLineSpacing( double textLineSpacing ) { foreach ( LabelModelObject* object, mObjectList ) { if ( object->isSelected() ) { object->setTextLineSpacing( textLineSpacing ); } } mModified = true; emit changed(); } void LabelModel::setSelectionTextColorNode( ColorNode textColorNode ) { foreach ( LabelModelObject* object, mObjectList ) { if ( object->isSelected() ) { object->setTextColorNode( textColorNode ); } } mModified = true; emit changed(); } void LabelModel::setSelectionLineWidth( double lineWidth ) { foreach ( LabelModelObject* object, mObjectList ) { if ( object->isSelected() ) { object->setLineWidth( lineWidth ); } } mModified = true; emit changed(); } void LabelModel::setSelectionLineColorNode( ColorNode lineColorNode ) { foreach ( LabelModelObject* object, mObjectList ) { if ( object->isSelected() ) { object->setLineColorNode( lineColorNode ); } } mModified = true; emit changed(); } void LabelModel::setSelectionFillColorNode( ColorNode fillColorNode ) { foreach ( LabelModelObject* object, mObjectList ) { if ( object->isSelected() ) { object->setFillColorNode( fillColorNode ); } } mModified = true; emit changed(); } }