Esempio n. 1
0
void ScrPainter::drawBitmap(const libwpg::WPGBitmap& bitmap, double hres, double vres)
{
	QImage image = QImage(bitmap.width(), bitmap.height(), QImage::Format_RGB32);
	for(int x = 0; x < bitmap.width(); x++)
	{
		for(int y = 0; y < bitmap.height(); y++)
		{
			libwpg::WPGColor color = bitmap.pixel(x, y);
			image.setPixel(x, y, qRgb(color.red, color.green, color.blue));
		}
	}
	double w = (bitmap.rect.x2 - bitmap.rect.x1) * 72.0;
	double h = (bitmap.rect.y2 - bitmap.rect.y1) * 72.0;
	int z = m_Doc->itemAdd(PageItem::ImageFrame, PageItem::Unspecified, bitmap.rect.x1 * 72 + baseX, bitmap.rect.y1 * 72 + baseY, w, h, 1, m_Doc->itemToolPrefs().imageFillColor, CommonStrings::None, true);
	PageItem *ite = m_Doc->Items->at(z);
	ite->tempImageFile = new QTemporaryFile(QDir::tempPath() + "/scribus_temp_wpg_XXXXXX.png");
	ite->tempImageFile->open();
	QString fileName = getLongPathName(ite->tempImageFile->fileName());
	ite->tempImageFile->close();
	ite->isInlineImage = true;
	image.setDotsPerMeterX ((int) (hres / 0.0254));
	image.setDotsPerMeterY ((int) (vres / 0.0254));
	image.save(fileName, "PNG");
	m_Doc->LoadPict(fileName, z);
	ite->setImageScalingMode(false, false);
	ite->moveBy(m_Doc->currentPage()->xOffset(), m_Doc->currentPage()->yOffset());
	finishItem(ite);
//	qDebug() << "drawBitmap";
}
Esempio n. 2
0
void ScrPainter::drawPolygon(const libwpg::WPGPointArray& vertices, bool closed)
{
	if(vertices.count() < 2)
		return;
	Coords.resize(0);
	Coords.svgInit();
	PageItem *ite;
	Coords.svgMoveTo(72 * vertices[0].x, 72 * vertices[0].y);
	for(unsigned i = 1; i < vertices.count(); i++)
	{
		Coords.svgLineTo(72 * vertices[i].x, 72 * vertices[i].y);
	}
	if (closed)
		Coords.svgClosePath();
	if (Coords.size() > 0)
	{
		int z;
		if (closed)
			z = m_Doc->itemAdd(PageItem::Polygon, PageItem::Unspecified, baseX, baseY, 10, 10, LineW, CurrColorFill, CurrColorStroke, true);
		else
			z = m_Doc->itemAdd(PageItem::PolyLine, PageItem::Unspecified, baseX, baseY, 10, 10, LineW, CommonStrings::None, CurrColorStroke, true);
		ite = m_Doc->Items->at(z);
		ite->PoLine = Coords.copy();
		ite->PoLine.translate(m_Doc->currentPage()->xOffset(), m_Doc->currentPage()->yOffset());
		finishItem(ite);
	}
//	qDebug() << "draw Polygon";
}
Esempio n. 3
0
void ScrPainter::drawEllipse(const libwpg::WPGPoint& center, double rx, double ry)
{
	int z = m_Doc->itemAdd(PageItem::Polygon, PageItem::Ellipse, baseX, baseY, rx * 144.0, ry * 144.0, LineW, CurrColorFill, CurrColorStroke, true);
	PageItem *ite = m_Doc->Items->at(z);
	QTransform mm = QTransform();
	mm.translate(72*(center.x - rx), 72*(center.y - ry));
	ite->PoLine.map(mm);
	ite->PoLine.translate(m_Doc->currentPage()->xOffset(), m_Doc->currentPage()->yOffset());
	finishItem(ite);
//	qDebug() << "draw Ellipse";
}
Esempio n. 4
0
void ScrPainter::drawPath(const libwpg::WPGPath& path)
{
	Coords.resize(0);
	Coords.svgInit();
	PageItem *ite;
	for(unsigned i = 0; i < path.count(); i++)
	{
		libwpg::WPGPathElement element = path.element(i);
		libwpg::WPGPoint point = element.point;
		switch(element.type)
		{
			case libwpg::WPGPathElement::MoveToElement:
				Coords.svgMoveTo(72 * point.x, 72 * point.y);
				break;
			case libwpg::WPGPathElement::LineToElement:
				Coords.svgLineTo(72 * point.x, 72 * point.y);
				break;
			case libwpg::WPGPathElement::CurveToElement:
				Coords.svgCurveToCubic(72*element.extra1.x, 72*element.extra1.y, 72*element.extra2.x, 72*element.extra2.y, 72 * point.x, 72 * point.y);
				break;
			default:
				break;
		}
	}
	if (Coords.size() > 0)
	{
		int z;
		if (fillSet)
		{
			if (!path.filled)
				CurrColorFill = CommonStrings::None;
		}
		if (strokeSet)
		{
			if (!path.framed)
				CurrColorStroke = CommonStrings::None;
		}
		if(path.closed)
		{
			Coords.svgClosePath();
			z = m_Doc->itemAdd(PageItem::Polygon, PageItem::Unspecified, baseX, baseY, 10, 10, LineW, CurrColorFill, CurrColorStroke, true);
		}
		else
			z = m_Doc->itemAdd(PageItem::PolyLine, PageItem::Unspecified, baseX, baseY, 10, 10, LineW, CurrColorFill, CurrColorStroke, true);
		ite = m_Doc->Items->at(z);
		ite->PoLine = Coords.copy();
		ite->PoLine.translate(m_Doc->currentPage()->xOffset(), m_Doc->currentPage()->yOffset());
		finishItem(ite);
	}
//	qDebug() << "draw Path" << CurrFillTrans;
}
Esempio n. 5
0
void ScrPainter::drawRectangle(const libwpg::WPGRect& rect, double rx, double ry)
{
	int z = m_Doc->itemAdd(PageItem::Polygon, PageItem::Rectangle, baseX, baseY, rect.width() * 72.0, rect.height() * 72.0, LineW, CurrColorFill, CurrColorStroke, true);
	PageItem *ite = m_Doc->Items->at(z);
	if ((rx > 0) && (ry > 0))
	{
		ite->setCornerRadius(qMax(72*rx, 72*ry));
		ite->SetFrameRound();
		m_Doc->setRedrawBounding(ite);
	}
	QTransform mm = QTransform();
	mm.translate(72*rect.x1, 72*rect.y1);
	ite->PoLine.map(mm);
	ite->PoLine.translate(m_Doc->currentPage()->xOffset(), m_Doc->currentPage()->yOffset());
	finishItem(ite);
//	qDebug() << "draw Rect";
}
Esempio n. 6
0
void SmlPlug::processShapeNode(QDomElement &elem)
{
	Coords.resize(0);
	Coords.svgInit();
	currx = 0.0;
	curry = 0.0;
	startx = 0.0;
	starty = 0.0;
	count = 0;
	first = true;
	if (elem.hasChildNodes())
	{
		QDomNode node = elem.firstChild();
		while(!node.isNull())
		{
			QDomElement pg = node.toElement();
			if (pg.tagName() == "KivioLineStyle")
				processStrokeNode(pg);
			else if (pg.tagName() == "KivioFillStyle")
				processFillNode(pg);
			else if (pg.tagName() == "KivioPoint")
				processPointNode(pg);
			else if (pg.tagName() == "Line")
				processLineNode(pg);
			node = node.nextSibling();
		}
	}
	QString typ = elem.attribute("type");
	if (typ == "Rectangle")
	{
		double x = ScCLocale::toDoubleC(elem.attribute("x"));
		double y = ScCLocale::toDoubleC(elem.attribute("y"));
		double w = ScCLocale::toDoubleC(elem.attribute("w"));
		double h = ScCLocale::toDoubleC(elem.attribute("h"));
		int z = m_Doc->itemAdd(PageItem::Polygon, PageItem::Rectangle, baseX + x, baseY + y, w, h, LineW, CurrColorFill, CurrColorStroke, true);
		finishItem(elem, m_Doc->Items->at(z));
	}
	else if (typ == "RoundRectangle")
	{
		double x = ScCLocale::toDoubleC(elem.attribute("x"));
		double y = ScCLocale::toDoubleC(elem.attribute("y"));
		double w = ScCLocale::toDoubleC(elem.attribute("w"));
		double h = ScCLocale::toDoubleC(elem.attribute("h"));
		int z = m_Doc->itemAdd(PageItem::Polygon, PageItem::Rectangle, baseX + x, baseY + y, w, h, LineW, CurrColorFill, CurrColorStroke, true);
		m_Doc->Items->at(z)->setCornerRadius(qMax(ScCLocale::toDoubleC(elem.attribute("r1")), ScCLocale::toDoubleC(elem.attribute("r2"))));
		m_Doc->Items->at(z)->SetFrameRound();
		finishItem(elem, m_Doc->Items->at(z));
	}
	else if (typ == "Ellipse")
	{
		double x = ScCLocale::toDoubleC(elem.attribute("x"));
		double y = ScCLocale::toDoubleC(elem.attribute("y"));
		double w = ScCLocale::toDoubleC(elem.attribute("w"));
		double h = ScCLocale::toDoubleC(elem.attribute("h"));
		int z = m_Doc->itemAdd(PageItem::Polygon, PageItem::Ellipse, baseX + x, baseY + y, w, h, LineW, CurrColorFill, CurrColorStroke, true);
		finishItem(elem, m_Doc->Items->at(z));
	}
	else if ((typ == "Polygon") || (typ == "ClosedPath"))
	{
		int z;
		FPoint s = Coords.point(0);
		FPoint e = Coords.point(Coords.count() - 1);
		if (s == e)
			z = m_Doc->itemAdd(PageItem::Polygon, PageItem::Unspecified, baseX, baseY, 10, 10, LineW, CurrColorFill, CurrColorStroke, true);
		else
			z = m_Doc->itemAdd(PageItem::PolyLine, PageItem::Unspecified, baseX, baseY, 10, 10, LineW, CurrColorFill, CurrColorStroke, true);
		m_Doc->Items->at(z)->PoLine = Coords.copy();
		finishItem(elem, m_Doc->Items->at(z));
	}
	else if ((typ == "Bezier") || (typ == "OpenPath") || (typ == "LineArray") || (typ == "Polyline"))
	{
		int	z = m_Doc->itemAdd(PageItem::PolyLine, PageItem::Unspecified, baseX, baseY, 10, 10, LineW, CurrColorFill, CurrColorStroke, true);
		m_Doc->Items->at(z)->PoLine = Coords.copy();
		finishItem(elem, m_Doc->Items->at(z));
	}
	if (typ == "TextBox")
	{
		double x = ScCLocale::toDoubleC(elem.attribute("x"));
		double y = ScCLocale::toDoubleC(elem.attribute("y"));
		double w = ScCLocale::toDoubleC(elem.attribute("w"));
		double h = ScCLocale::toDoubleC(elem.attribute("h"));
		int z = m_Doc->itemAdd(PageItem::TextFrame, PageItem::Rectangle, baseX + x, baseY + y, w, h, 0, CommonStrings::None, CommonStrings::None, true);
		finishItem(elem, m_Doc->Items->at(z));
	}
	else if (typ == "Line")
	{
		double x = ScCLocale::toDoubleC(elem.attribute("x1"));
		double y = ScCLocale::toDoubleC(elem.attribute("y1"));
		double x1 = ScCLocale::toDoubleC(elem.attribute("x2"));
		double y1 = ScCLocale::toDoubleC(elem.attribute("y2"));
		Coords.addPoint(x, y);
		Coords.addPoint(x, y);
		Coords.addPoint(x1, y1);
		Coords.addPoint(x1, y1);
		int z = m_Doc->itemAdd(PageItem::PolyLine, PageItem::Unspecified, baseX, baseY, 10, 10, LineW, CommonStrings::None, CurrColorStroke, true);
		m_Doc->Items->at(z)->PoLine = Coords.copy();
		finishItem(elem, m_Doc->Items->at(z));
	}
}
Esempio n. 7
0
int POINT_EDITOR::OnSelectionChange( const TOOL_EVENT& aEvent )
{
    const SELECTION& selection = m_selectionTool->GetSelection();

    if( selection.Size() == 1 )
    {
        Activate();

        KIGFX::VIEW_CONTROLS* controls = getViewControls();
        KIGFX::VIEW* view = getView();
        PCB_BASE_EDIT_FRAME* editFrame = getEditFrame<PCB_BASE_EDIT_FRAME>();
        EDA_ITEM* item = selection.items.GetPickedItem( 0 );

        m_editPoints = EDIT_POINTS_FACTORY::Make( item, getView()->GetGAL() );

        if( !m_editPoints )
            return 0;

        view->Add( m_editPoints.get() );
        m_editedPoint = NULL;
        bool modified = false;

        // Main loop: keep receiving events
        while( OPT_TOOL_EVENT evt = Wait() )
        {
            if( !m_editPoints ||
                evt->Matches( m_selectionTool->ClearedEvent ) ||
                evt->Matches( m_selectionTool->UnselectedEvent ) ||
                evt->Matches( m_selectionTool->SelectedEvent ) )
            {
                break;
            }

            if( evt->IsMotion() )
            {
                EDIT_POINT* point = m_editPoints->FindPoint( evt->Position() );

                if( m_editedPoint != point )
                    setEditedPoint( point );
            }

            else if( evt->IsAction( &COMMON_ACTIONS::pointEditorAddCorner ) )
            {
                addCorner( controls->GetCursorPosition() );
                updatePoints();
            }

            else if( evt->IsAction( &COMMON_ACTIONS::pointEditorRemoveCorner ) )
            {
                if( m_editedPoint )
                {
                    removeCorner( m_editedPoint );
                    updatePoints();
                }
            }

            else if( evt->IsDrag( BUT_LEFT ) && m_editedPoint )
            {
                if( !modified )
                {
                    // Save items, so changes can be undone
                    editFrame->OnModify();
                    editFrame->SaveCopyInUndoList( selection.items, UR_CHANGED );
                    controls->ForceCursorPosition( false );
                    m_original = *m_editedPoint;    // Save the original position
                    controls->SetAutoPan( true );
                    modified = true;
                }

                bool enableAltConstraint = !!evt->Modifier( MD_CTRL );
                if( enableAltConstraint != (bool) m_altConstraint )  // alternative constraint
                    setAltConstraint( enableAltConstraint );

                m_editedPoint->SetPosition( controls->GetCursorPosition() );

                if( m_altConstraint )
                    m_altConstraint->Apply();
                else
                    m_editedPoint->ApplyConstraint();

                updateItem();
                updatePoints();

                m_editPoints->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
            }

            else if( evt->IsAction( &COMMON_ACTIONS::pointEditorUpdate ) )
            {
                updatePoints();
            }

            else if( evt->IsMouseUp( BUT_LEFT ) )
            {
                controls->SetAutoPan( false );
                setAltConstraint( false );
                modified = false;
                m_toolMgr->PassEvent();
            }

            else if( evt->IsCancel() )
            {
                if( modified )      // Restore the last change
                {
                    wxCommandEvent dummy;
                    editFrame->RestoreCopyFromUndoList( dummy );

                    updatePoints();
                    modified = false;
                }

                // Let the selection tool receive the event too
                m_toolMgr->PassEvent();

                break;
            }

            else
            {
                m_toolMgr->PassEvent();
            }
        }

        if( m_editPoints )
        {
            finishItem();
            item->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
            view->Remove( m_editPoints.get() );
            m_editPoints.reset();
        }

        controls->ShowCursor( false );
        controls->SetAutoPan( false );
        controls->SetSnapping( false );
        controls->ForceCursorPosition( false );
    }

    return 0;
}
Esempio n. 8
0
void ShapePlug::parseGroup(QDomNode &DOC)
{
    QString tmp = "";
    QString FillCol = "White";
    QString StrokeCol = "Black";
    QString defFillCol = "White";
    QString defStrokeCol = "Black";
    QColor stroke = Qt::black;
    QColor fill = Qt::white;
//	Qt::PenStyle Dash = Qt::SolidLine;
    Qt::PenCapStyle LineEnd = Qt::FlatCap;
    Qt::PenJoinStyle LineJoin = Qt::MiterJoin;
//	int fillStyle = 1;
    double strokewidth = 0.1;
//	bool poly = false;
    while(!DOC.isNull())
    {
        double x1, y1, x2, y2;
        StrokeCol = defStrokeCol;
        FillCol = defFillCol;
        stroke = Qt::black;
        fill = Qt::white;
        //	fillStyle = 1;
        strokewidth = 1.0;
        //	Dash = Qt::SolidLine;
        LineEnd = Qt::FlatCap;
        LineJoin = Qt::MiterJoin;
        FPointArray PoLine;
        PoLine.resize(0);
        QDomElement pg = DOC.toElement();
        QString STag = pg.tagName();
        QString style = pg.attribute( "style", "" ).simplified();
        if (style.isEmpty())
            style = pg.attribute( "svg:style", "" ).simplified();
        QStringList substyles = style.split(';', QString::SkipEmptyParts);
        for( QStringList::Iterator it = substyles.begin(); it != substyles.end(); ++it )
        {
            QStringList substyle = (*it).split(':', QString::SkipEmptyParts);
            QString command(substyle[0].trimmed());
            QString params(substyle[1].trimmed());
            if (command == "fill")
            {
                if (!((params == "foreground") || (params == "background") || (params == "fg") || (params == "bg") || (params == "none") || (params == "default") || (params == "inverse")))
                {
                    if (params == "nofill")
                        FillCol = CommonStrings::None;
                    else
                    {
                        fill.setNamedColor( params );
                        FillCol = "FromDia"+fill.name();
                        ScColor tmp;
                        tmp.fromQColor(fill);
                        tmp.setSpotColor(false);
                        tmp.setRegistrationColor(false);
                        QString fNam = m_Doc->PageColors.tryAddColor(FillCol, tmp);
                        if (fNam == FillCol)
                            importedColors.append(FillCol);
                        FillCol = fNam;
                    }
                }
            }
            else if (command == "stroke")
            {
                if (!((params == "foreground") || (params == "background") || (params == "fg") || (params == "bg") || (params == "none") || (params == "default")) || (params == "inverse"))
                {
                    stroke.setNamedColor( params );
                    StrokeCol = "FromDia"+stroke.name();
                    ScColor tmp;
                    tmp.fromQColor(stroke);
                    tmp.setSpotColor(false);
                    tmp.setRegistrationColor(false);
                    QString fNam = m_Doc->PageColors.tryAddColor(StrokeCol, tmp);
                    if (fNam == StrokeCol)
                        importedColors.append(StrokeCol);
                    StrokeCol = fNam;
                }
            }
            else if (command == "stroke-width")
                strokewidth = ScCLocale::toDoubleC(params);
            else if( command == "stroke-linejoin" )
            {
                if( params == "miter" )
                    LineJoin = Qt::MiterJoin;
                else if( params == "round" )
                    LineJoin = Qt::RoundJoin;
                else if( params == "bevel" )
                    LineJoin = Qt::BevelJoin;
            }
            else if( command == "stroke-linecap" )
            {
                if( params == "butt" )
                    LineEnd = Qt::FlatCap;
                else if( params == "round" )
                    LineEnd = Qt::RoundCap;
                else if( params == "square" )
                    LineEnd = Qt::SquareCap;
            }
        }
        if (STag == "svg:line")
        {
            x1 = ScCLocale::toDoubleC(pg.attribute("x1")) * Conversion;
            y1 = ScCLocale::toDoubleC(pg.attribute("y1")) * Conversion;
            x2 = ScCLocale::toDoubleC(pg.attribute("x2")) * Conversion;
            y2 = ScCLocale::toDoubleC(pg.attribute("y2")) * Conversion;
            PoLine.addPoint(x1, y1);
            PoLine.addPoint(x1, y1);
            PoLine.addPoint(x2, y2);
            PoLine.addPoint(x2, y2);
            int z = m_Doc->itemAdd(PageItem::PolyLine, PageItem::Unspecified, baseX, baseY, 10, 10, strokewidth, CommonStrings::None, StrokeCol);
            m_Doc->Items->at(z)->PoLine = PoLine.copy();
            finishItem(m_Doc->Items->at(z));
        }
        else if (STag == "svg:rect")
        {
            x1 = ScCLocale::toDoubleC(pg.attribute("x")) * Conversion;
            y1 = ScCLocale::toDoubleC(pg.attribute("y")) * Conversion;
            x2 = ScCLocale::toDoubleC(pg.attribute("width")) * Conversion;
            y2 = ScCLocale::toDoubleC(pg.attribute("height")) * Conversion;
            int z = m_Doc->itemAdd(PageItem::Polygon, PageItem::Rectangle, baseX + x1, baseY + y1, x2, y2, strokewidth, FillCol, StrokeCol);
            m_Doc->Items->at(z)->setLineJoin(LineJoin);
            m_Doc->Items->at(z)->setLineEnd(LineEnd);
            finishItem(m_Doc->Items->at(z));
        }
        else if ((STag == "svg:polygon") || (STag == "svg:polyline"))
        {
            bool bFirst = true;
            double x = 0.0;
            double y = 0.0;
            QString points = pg.attribute( "points" ).simplified().replace(',', " ");
            QStringList pointList = points.split(' ', QString::SkipEmptyParts);
            FirstM = true;
            for( QStringList::Iterator it = pointList.begin(); it != pointList.end(); it++ )
            {
                x = ScCLocale::toDoubleC(*(it++));
                y = ScCLocale::toDoubleC(*it);
                if( bFirst )
                {
                    svgMoveTo(x * Conversion, y * Conversion);
                    bFirst = false;
                    WasM = true;
                }
                else
                {
                    svgLineTo(&PoLine, x * Conversion, y * Conversion);
                }
            }
            if (STag == "svg:polygon")
                svgClosePath(&PoLine);
            if (PoLine.size() < 4)
            {
                DOC = DOC.nextSibling();
                continue;
            }
            int z;
            if (STag == "svg:polygon")
                z = m_Doc->itemAdd(PageItem::Polygon, PageItem::Unspecified, baseX, baseY, 10, 10, strokewidth, FillCol, StrokeCol);
            else
                z = m_Doc->itemAdd(PageItem::PolyLine, PageItem::Unspecified, baseX, baseY, 10, 10, strokewidth, CommonStrings::None, StrokeCol);
            m_Doc->Items->at(z)->PoLine = PoLine.copy();
            finishItem(m_Doc->Items->at(z));
        }
        else if ((STag == "svg:circle") || (STag == "svg:ellipse"))
        {
            x1 = ScCLocale::toDoubleC(pg.attribute("r")) * Conversion;
            y1 = ScCLocale::toDoubleC(pg.attribute("r")) * Conversion;
            x2 = ScCLocale::toDoubleC(pg.attribute("cx")) * Conversion - x1;
            y2 = ScCLocale::toDoubleC(pg.attribute("cy")) * Conversion - y1;
            x1 *= 2.0;
            y1 *= 2.0;
            int z = m_Doc->itemAdd(PageItem::Polygon, PageItem::Ellipse, baseX + x1, baseY + y1, x2, y2, strokewidth, FillCol, StrokeCol);
            m_Doc->Items->at(z)->setLineJoin(LineJoin);
            m_Doc->Items->at(z)->setLineEnd(LineEnd);
            finishItem(m_Doc->Items->at(z));
        }
        else if (STag == "svg:path")
        {
            //	poly =
            parseSVG( pg.attribute( "d" ), &PoLine );
            if (PoLine.size() < 4)
            {
                DOC = DOC.nextSibling();
                continue;
            }
            int z = m_Doc->itemAdd(PageItem::Polygon, PageItem::Unspecified, baseX, baseY, 10, 10, strokewidth, FillCol, StrokeCol);
            m_Doc->Items->at(z)->PoLine = PoLine.copy();
            finishItem(m_Doc->Items->at(z));
        }
        else if (STag == "svg:g")
        {
            int z = m_Doc->itemAdd(PageItem::Group, PageItem::Rectangle, baseX, baseX, 1, 1, 0, CommonStrings::None, CommonStrings::None);
            PageItem *neu = m_Doc->Items->at(z);
            Elements.append(neu);
            if (groupStack.count() > 0)
                groupStack.top().append(neu);
            QList<PageItem*> gElements;
            groupStack.push(gElements);
            QDomNode child = DOC.firstChild();
            parseGroup(child);
            if (gElements.count() == 0)
            {
                groupStack.pop();
                Elements.removeAll(neu);
                groupStack.top().removeAll(neu);
                Selection tmpSelection(m_Doc, false);
                tmpSelection.addItem(neu);
                m_Doc->itemSelection_DeleteItem(&tmpSelection);
            }
            else
            {
                QList<PageItem*> gElem = groupStack.pop();
                double minx =  std::numeric_limits<double>::max();
                double miny =  std::numeric_limits<double>::max();
                double maxx = -std::numeric_limits<double>::max();
                double maxy = -std::numeric_limits<double>::max();
                for (int gr = 0; gr < gElements.count(); ++gr)
                {
                    PageItem* currItem = gElem.at(gr);
                    double x1, x2, y1, y2;
                    currItem->getVisualBoundingRect(&x1, &y1, &x2, &y2);
                    minx = qMin(minx, x1);
                    miny = qMin(miny, y1);
                    maxx = qMax(maxx, x2);
                    maxy = qMax(maxy, y2);
                }
                double gx = minx;
                double gy = miny;
                double gw = maxx - minx;
                double gh = maxy - miny;
                neu->setXYPos(gx, gy, true);
                neu->setWidthHeight(gw, gh, true);
                neu->SetRectFrame();
                neu->Clip = FlattenPath(neu->PoLine, neu->Segments);
                neu->setItemName( tr("Group%1").arg(m_Doc->GroupCounter));
                neu->AutoName = false;
                neu->gXpos = neu->xPos() - gx;
                neu->gYpos = neu->yPos() - gy;
                neu->groupWidth = gw;
                neu->groupHeight = gh;
                for (int gr = 0; gr < gElem.count(); ++gr)
                {
                    PageItem* currItem = gElem.at(gr);
                    currItem->gXpos = currItem->xPos() - gx;
                    currItem->gYpos = currItem->yPos() - gy;
                    currItem->gWidth = gw;
                    currItem->gHeight = gh;
                    currItem->Parent = neu;
                    neu->groupItemList.append(currItem);
                    m_Doc->Items->removeAll(currItem);
                    Elements.removeAll(currItem);
                }
                neu->setRedrawBounding();
                neu->setTextFlowMode(PageItem::TextFlowDisabled);
                m_Doc->GroupCounter++;
            }
        }
        DOC = DOC.nextSibling();
    }
}