Exemple #1
0
Template* Template::loadTemplateConfiguration(QXmlStreamReader& xml, Map& map, bool& open)
{
	Q_ASSERT(xml.name() == "template");
	
	QXmlStreamAttributes attributes = xml.attributes();
	if (attributes.hasAttribute("open"))
		open = (attributes.value("open") == "true");
	
	QString path = attributes.value("path").toString();
	Template* temp = templateForFile(path, &map);
	temp->setTemplateRelativePath(attributes.value("relpath").toString());
	if (attributes.hasAttribute("name"))
		temp->template_file = attributes.value("name").toString();
	temp->is_georeferenced = (attributes.value("georef") == "true");
	if (!temp->is_georeferenced)
		temp->template_group = attributes.value("group").toString().toInt();
		
	while (xml.readNextStartElement())
	{
		if (!temp->is_georeferenced && xml.name() == "transformations")
		{
			temp->adjusted = (xml.attributes().value("adjusted") == "true");
			temp->adjustment_dirty = (xml.attributes().value("adjustment_dirty") == "true");
			int num_passpoints = xml.attributes().value("passpoints").toString().toInt();
Q_ASSERT(temp->passpoints.size() == 0);
			temp->passpoints.reserve(qMin(num_passpoints, 10)); // 10 is not a limit
			
			while (xml.readNextStartElement())
			{
				QStringRef role = xml.attributes().value("role");
				if (xml.name() == "transformation")
				{
					if (role == "active")
						temp->transform.load(xml);
					else if (xml.attributes().value("role") == "other")
						temp->other_transform.load(xml);
					else
					{
						qDebug() << xml.qualifiedName();
						xml.skipCurrentElement(); // unsupported
					}
				}
				else if (xml.name() == "passpoint")
				{
					temp->passpoints.push_back(PassPoint::load(xml));
				}
				else if (xml.name() == "matrix")
				{
					if (role == "map_to_template")
						temp->map_to_template.load(xml);
					else if (role == "template_to_map")
						temp->template_to_map.load(xml);
					else if (role == "template_to_map_other")
						temp->template_to_map_other.load(xml);
					else
					{
						qDebug() << xml.qualifiedName();
						xml.skipCurrentElement(); // unsupported
					}
				}
				else
				{
					qDebug() << xml.qualifiedName();
					xml.skipCurrentElement(); // unsupported
				}
			}
		}
		else if (!temp->loadTypeSpecificTemplateConfiguration(xml))
		{
			delete temp;
			return NULL;
		}
	}
	
	if (!temp->is_georeferenced)
	{
		// Fix template adjustment after moving objects during import (cf. #513)
		const auto offset = MapCoord::boundsOffset();
		if (!offset.isZero())
		{
			temp->template_to_map.set(0, 2, temp->template_to_map_other.get(0, 2) - offset.x / 1000.0);
			temp->template_to_map.set(1, 2, temp->template_to_map_other.get(1, 2) - offset.y / 1000.0);
			temp->template_to_map.invert(temp->map_to_template);
			temp->template_to_map_other.set(0, 2, temp->template_to_map_other.get(0, 2) - offset.x / 1000.0);
			temp->template_to_map_other.set(1, 2, temp->template_to_map_other.get(1, 2) - offset.y / 1000.0);
		}
		
		// Fix template alignment problems caused by grivation rounding since version 0.6
		const double correction = map.getGeoreferencing().getGrivationError();
		if (qAbs(correction) != 0.0 && temp->getTemplateType() == "TemplateTrack")
		{
			temp->setTemplateRotation(temp->getTemplateRotation() + Georeferencing::degToRad(correction));
		}
	}
	
	return temp;
}
Exemple #2
0
void PageViewportControllerClientQt::zoomToAreaGestureEnded(const QPointF& touchPoint, const QRectF& targetArea)
{
    // This can only happen as a result of a user interaction.
    ASSERT(m_controller->hadUserInteraction());

    if (!targetArea.isValid())
        return;

    if (m_scrollChange.inProgress() || m_scaleChange.inProgress())
        return;

    const float margin = 10; // We want at least a little bit of margin.
    QRectF endArea = targetArea.adjusted(-margin, -margin, margin, margin);

    const QRectF viewportRect = m_viewportItem->boundingRect();

    qreal minViewportScale = qreal(2.5);
    qreal targetScale = viewportRect.size().width() / endArea.size().width();
    targetScale = m_controller->innerBoundedViewportScale(qMin(minViewportScale, targetScale));
    qreal currentScale = m_pageItem->contentsScale();

    // We want to end up with the target area filling the whole width of the viewport (if possible),
    // and centralized vertically where the user requested zoom. Thus our hotspot is the center of
    // the targetArea x-wise and the requested zoom position, y-wise.
    const QPointF hotspot = QPointF(endArea.center().x(), touchPoint.y());
    const QPointF viewportHotspot = viewportRect.center();

    QPointF endPosition = hotspot - viewportHotspot / targetScale;
    endPosition = m_controller->clampViewportToContents(endPosition, targetScale);
    QRectF endVisibleContentRect(endPosition, viewportRect.size() / targetScale);

    enum { ZoomIn, ZoomBack, ZoomOut, NoZoom } zoomAction = ZoomIn;

    // Zoom back out if attempting to scale to the same current scale, or
    // attempting to continue scaling out from the inner most level.
    // Use fuzzy compare with a fixed error to be able to deal with largish differences due to pixel rounding.
    if (!m_scaleStack.isEmpty() && fuzzyCompare(targetScale, currentScale, 0.01)) {
        // If moving the viewport would expose more of the targetRect and move at least 40 pixels, update position but do not scale out.
        QRectF currentContentRect(m_viewportItem->mapRectToWebContent(viewportRect));
        QRectF targetIntersection = endVisibleContentRect.intersected(targetArea);
        if (!currentContentRect.contains(targetIntersection)
            && (qAbs(endVisibleContentRect.top() - currentContentRect.top()) >= 40
            || qAbs(endVisibleContentRect.left() - currentContentRect.left()) >= 40))
            zoomAction = NoZoom;
        else
            zoomAction = ZoomBack;
    } else if (fuzzyCompare(targetScale, m_zoomOutScale, 0.01))
        zoomAction = ZoomBack;
    else if (targetScale < currentScale)
        zoomAction = ZoomOut;

    switch (zoomAction) {
    case ZoomIn:
        m_scaleStack.append(ScaleStackItem(currentScale, m_viewportItem->contentPos().x() / currentScale));
        m_zoomOutScale = targetScale;
        break;
    case ZoomBack: {
        if (m_scaleStack.isEmpty()) {
            targetScale = m_controller->minimumContentsScale();
            endPosition.setY(hotspot.y() - viewportHotspot.y() / targetScale);
            endPosition.setX(0);
            m_zoomOutScale = 0;
        } else {
            ScaleStackItem lastScale = m_scaleStack.takeLast();
            targetScale = lastScale.scale;
            // Recalculate endPosition and clamp it according to the new scale.
            endPosition.setY(hotspot.y() - viewportHotspot.y() / targetScale);
            endPosition.setX(lastScale.xPosition);
        }
        endPosition = m_controller->clampViewportToContents(endPosition, targetScale);
        endVisibleContentRect = QRectF(endPosition, viewportRect.size() / targetScale);
        break;
    }
    case ZoomOut:
        // Unstack all scale-levels deeper than the new level, so a zoom-back won't end up zooming in.
        while (!m_scaleStack.isEmpty() && m_scaleStack.last().scale >= targetScale)
            m_scaleStack.removeLast();
        m_zoomOutScale = targetScale;
        break;
    case NoZoom:
        break;
    }

    animateContentRectVisible(endVisibleContentRect);
}
void QgsDecorationScaleBar::render( QPainter * theQPainter )
{
  QgsMapCanvas* canvas = QgisApp::instance()->mapCanvas();

  int myBufferSize = 1; //softcode this later

  //Get canvas dimensions
  int myCanvasHeight = theQPainter->device()->height();
  int myCanvasWidth = theQPainter->device()->width();

  //Get map units per pixel. This can be negative at times (to do with
  //projections) and that just confuses the rest of the code in this
  //function, so force to a positive number.
  double myMapUnitsPerPixelDouble = qAbs( canvas->mapUnitsPerPixel() );
  double myActualSize = mPreferredSize;

  // Exit if the canvas width is 0 or layercount is 0 or QGIS will freeze
  int myLayerCount = canvas->layerCount();
  if ( !myLayerCount || !myCanvasWidth || !myMapUnitsPerPixelDouble )
    return;

  //Large if statement which determines whether to render the scale bar
  if ( enabled() )
  {
    // Hard coded sizes
    int myMajorTickSize = 8;
    int myTextOffsetX = 3;
    int myMargin = 20;

    QSettings settings;
    QGis::UnitType myPreferredUnits = QGis::fromLiteral( settings.value( "/qgis/measure/displayunits", QGis::toLiteral( QGis::Meters ) ).toString() );
    QGis::UnitType myMapUnits = canvas->mapUnits();

    // Adjust units meter/feet or vice versa
    if ( myMapUnits == QGis::Meters && myPreferredUnits == QGis::Feet )
    {
      // From meter to feet
      myMapUnits = QGis::Feet;
      myMapUnitsPerPixelDouble /= 0.3084;
    }
    else if ( myMapUnits == QGis::Feet && myPreferredUnits == QGis::Meters )
    {
      // From feet to meter
      myMapUnits = QGis::Meters;
      myMapUnitsPerPixelDouble *= 0.3084;
    }
    //Calculate size of scale bar for preferred number of map units
    double myScaleBarWidth = mPreferredSize / myMapUnitsPerPixelDouble;

    //If scale bar is very small reset to 1/4 of the canvas wide
    if ( myScaleBarWidth < 30 )
    {
      myScaleBarWidth = myCanvasWidth / 4; // pixels
      myActualSize = myScaleBarWidth * myMapUnitsPerPixelDouble; // map units
    };

    //if scale bar is more than half the canvas wide keep halving until not
    while ( myScaleBarWidth > myCanvasWidth / 3 )
    {
      myScaleBarWidth = myScaleBarWidth / 3;
    };
    myActualSize = myScaleBarWidth * myMapUnitsPerPixelDouble;

    // Work out the exponent for the number - e.g, 1234 will give 3,
    // and .001234 will give -3
    double myPowerOf10 = floor( log10( myActualSize ) );

    // snap to integer < 10 times power of 10
    if ( mSnapping )
    {
      double scaler = pow( 10.0, myPowerOf10 );
      myActualSize = qRound( myActualSize / scaler ) * scaler;
      myScaleBarWidth = myActualSize / myMapUnitsPerPixelDouble;
    }

    //Get type of map units and set scale bar unit label text
    QString myScaleBarUnitLabel;
    switch ( myMapUnits )
    {
      case QGis::Meters:
        if ( myActualSize > 1000.0 )
        {
          myScaleBarUnitLabel = tr( " km" );
          myActualSize = myActualSize / 1000;
        }
        else if ( myActualSize < 0.01 )
        {
          myScaleBarUnitLabel = tr( " mm" );
          myActualSize = myActualSize * 1000;
        }
        else if ( myActualSize < 0.1 )
        {
          myScaleBarUnitLabel = tr( " cm" );
          myActualSize = myActualSize * 100;
        }
        else
          myScaleBarUnitLabel = tr( " m" );
        break;
      case QGis::Feet:
        if ( myActualSize > 5280.0 ) //5280 feet to the mile
        {
          myScaleBarUnitLabel = tr( " miles" );
          // Adjust scale bar width to get even numbers
          myActualSize = myActualSize / 5000;
          myScaleBarWidth = ( myScaleBarWidth * 5280 ) / 5000;
        }
        else if ( myActualSize == 5280.0 ) //5280 feet to the mile
        {
          myScaleBarUnitLabel = tr( " mile" );
          // Adjust scale bar width to get even numbers
          myActualSize = myActualSize / 5000;
          myScaleBarWidth = ( myScaleBarWidth * 5280 ) / 5000;
        }
        else if ( myActualSize < 1 )
        {
          myScaleBarUnitLabel = tr( " inches" );
          myActualSize = myActualSize * 10;
          myScaleBarWidth = ( myScaleBarWidth * 10 ) / 12;
        }
        else if ( myActualSize == 1.0 )
        {
          myScaleBarUnitLabel = tr( " foot" );
        }
        else
        {
          myScaleBarUnitLabel = tr( " feet" );
        }
        break;
      case QGis::Degrees:
        if ( myActualSize == 1.0 )
          myScaleBarUnitLabel = tr( " degree" );
        else
          myScaleBarUnitLabel = tr( " degrees" );
        break;
      case QGis::UnknownUnit:
        myScaleBarUnitLabel = tr( " unknown" );
      default:
        QgsDebugMsg( QString( "Error: not picked up map units - actual value = %1" ).arg( myMapUnits ) );
    };

    //Set font and calculate width of unit label
    int myFontSize = 10; //we use this later for buffering
    QFont myFont( "helvetica", myFontSize );
    theQPainter->setFont( myFont );
    QFontMetrics myFontMetrics( myFont );
    double myFontWidth = myFontMetrics.width( myScaleBarUnitLabel );
    double myFontHeight = myFontMetrics.height();

    //Set the maximum label
    QString myScaleBarMaxLabel = QLocale::system().toString( myActualSize );

    //Calculate total width of scale bar and label
    double myTotalScaleBarWidth = myScaleBarWidth + myFontWidth;

    //determine the origin of scale bar depending on placement selected
    int myOriginX = myMargin;
    int myOriginY = myMargin;
    switch ( mPlacementIndex )
    {
      case 0: // Bottom Left
        myOriginX = myMargin;
        myOriginY = myCanvasHeight - myMargin;
        break;
      case 1: // Top Left
        myOriginX = myMargin;
        myOriginY = myMargin;
        break;
      case 2: // Top Right
        myOriginX = myCanvasWidth - (( int ) myTotalScaleBarWidth ) - myMargin;
        myOriginY = myMargin;
        break;
      case 3: // Bottom Right
        myOriginX = myCanvasWidth - (( int ) myTotalScaleBarWidth ) - myMargin;
        myOriginY = myCanvasHeight - myMargin;
        break;
      default:
        QgsDebugMsg( "Unable to determine where to put scale bar so defaulting to top left" );
    }

    //Set pen to draw with
    QPen myForegroundPen( mColor, 2 );
    QPen myBackgroundPen( Qt::white, 4 );

    //Cast myScaleBarWidth to int for drawing
    int myScaleBarWidthInt = ( int ) myScaleBarWidth;

    //Create array of vertices for scale bar depending on style
    switch ( mStyleIndex )
    {
      case 0: // Tick Down
      {
        QPolygon myTickDownArray( 4 );
        //draw a buffer first so bar shows up on dark images
        theQPainter->setPen( myBackgroundPen );
        myTickDownArray.putPoints( 0, 4,
                                   myOriginX                    , ( myOriginY + myMajorTickSize ) ,
                                   myOriginX                    ,  myOriginY                    ,
                                   ( myScaleBarWidthInt + myOriginX ),  myOriginY                    ,
                                   ( myScaleBarWidthInt + myOriginX ), ( myOriginY + myMajorTickSize )
                                 );
        theQPainter->drawPolyline( myTickDownArray );
        //now draw the bar itself in user selected color
        theQPainter->setPen( myForegroundPen );
        myTickDownArray.putPoints( 0, 4,
                                   myOriginX                    , ( myOriginY + myMajorTickSize ) ,
                                   myOriginX                    ,  myOriginY                    ,
                                   ( myScaleBarWidthInt + myOriginX ),  myOriginY                    ,
                                   ( myScaleBarWidthInt + myOriginX ), ( myOriginY + myMajorTickSize )
                                 );
        theQPainter->drawPolyline( myTickDownArray );
        break;
      }
      case 1: // tick up
      {
        QPolygon myTickUpArray( 4 );
        //draw a buffer first so bar shows up on dark images
        theQPainter->setPen( myBackgroundPen );
        myTickUpArray.putPoints( 0, 4,
                                 myOriginX                    ,  myOriginY                    ,
                                 myOriginX                    ,  myOriginY + myMajorTickSize  ,
                                 ( myScaleBarWidthInt + myOriginX ),  myOriginY + myMajorTickSize  ,
                                 ( myScaleBarWidthInt + myOriginX ),  myOriginY
                               );
        theQPainter->drawPolyline( myTickUpArray );
        //now draw the bar itself in user selected color
        theQPainter->setPen( myForegroundPen );
        myTickUpArray.putPoints( 0, 4,
                                 myOriginX                    ,  myOriginY                    ,
                                 myOriginX                    ,  myOriginY + myMajorTickSize  ,
                                 ( myScaleBarWidthInt + myOriginX ),  myOriginY + myMajorTickSize  ,
                                 ( myScaleBarWidthInt + myOriginX ),  myOriginY
                               );
        theQPainter->drawPolyline( myTickUpArray );
        break;
      }
      case 2: // Bar
      {
        QPolygon myBarArray( 2 );
        //draw a buffer first so bar shows up on dark images
        theQPainter->setPen( myBackgroundPen );
        myBarArray.putPoints( 0, 2,
                              myOriginX                    , ( myOriginY + ( myMajorTickSize / 2 ) ),
                              ( myScaleBarWidthInt + myOriginX ), ( myOriginY + ( myMajorTickSize / 2 ) )
                            );
        theQPainter->drawPolyline( myBarArray );
        //now draw the bar itself in user selected color
        theQPainter->setPen( myForegroundPen );
        myBarArray.putPoints( 0, 2,
                              myOriginX                    , ( myOriginY + ( myMajorTickSize / 2 ) ),
                              ( myScaleBarWidthInt + myOriginX ), ( myOriginY + ( myMajorTickSize / 2 ) )
                            );
        theQPainter->drawPolyline( myBarArray );
        break;
      }
      case 3: // box
      {
        // Want square corners for a box
        myBackgroundPen.setJoinStyle( Qt::MiterJoin );
        myForegroundPen.setJoinStyle( Qt::MiterJoin );
        QPolygon myBoxArray( 5 );
        //draw a buffer first so bar shows up on dark images
        theQPainter->setPen( myBackgroundPen );
        myBoxArray.putPoints( 0, 5,
                              myOriginX                    ,  myOriginY,
                              ( myScaleBarWidthInt + myOriginX ),  myOriginY,
                              ( myScaleBarWidthInt + myOriginX ), ( myOriginY + myMajorTickSize ),
                              myOriginX                    , ( myOriginY + myMajorTickSize ),
                              myOriginX                    ,  myOriginY
                            );
        theQPainter->drawPolyline( myBoxArray );
        //now draw the bar itself in user selected color
        theQPainter->setPen( myForegroundPen );
        theQPainter->setBrush( QBrush( mColor, Qt::SolidPattern ) );
        int midPointX = myScaleBarWidthInt / 2 + myOriginX;
        myBoxArray.putPoints( 0, 5,
                              myOriginX                    ,  myOriginY,
                              midPointX,  myOriginY,
                              midPointX, ( myOriginY + myMajorTickSize ),
                              myOriginX                    , ( myOriginY + myMajorTickSize ),
                              myOriginX                    ,  myOriginY
                            );
        theQPainter->drawPolygon( myBoxArray );

        theQPainter->setBrush( Qt::NoBrush );
        myBoxArray.putPoints( 0, 5,
                              midPointX                    ,  myOriginY,
                              ( myScaleBarWidthInt + myOriginX ),  myOriginY,
                              ( myScaleBarWidthInt + myOriginX ), ( myOriginY + myMajorTickSize ),
                              midPointX                    , ( myOriginY + myMajorTickSize ),
                              midPointX                    ,  myOriginY
                            );
        theQPainter->drawPolygon( myBoxArray );
        break;
      }
      default:
        QgsDebugMsg( "Unknown style" );
    }

    //Do actual drawing of scale bar

    //
    //Do drawing of scale bar text
    //

    QColor myBackColor = Qt::white;
    QColor myForeColor = Qt::black;

    //Draw the minimum label buffer
    theQPainter->setPen( myBackColor );
    myFontWidth = myFontMetrics.width( "0" );
    myFontHeight = myFontMetrics.height();

    for ( int i = 0 - myBufferSize; i <= myBufferSize; i++ )
    {
      for ( int j = 0 - myBufferSize; j <= myBufferSize; j++ )
      {
        theQPainter->drawText( int( i + ( myOriginX - ( myFontWidth / 2 ) ) ),
                               int( j + ( myOriginY - ( myFontHeight / 4 ) ) ),
                               "0" );
      }
    }

    //Draw minimum label
    theQPainter->setPen( myForeColor );

    theQPainter->drawText(
      int( myOriginX - ( myFontWidth / 2 ) ),
      int( myOriginY - ( myFontHeight / 4 ) ),
      "0"
    );

    //
    //Draw maximum label
    //
    theQPainter->setPen( myBackColor );
    myFontWidth = myFontMetrics.width( myScaleBarMaxLabel );
    myFontHeight = myFontMetrics.height();
    //first the buffer
    for ( int i = 0 - myBufferSize; i <= myBufferSize; i++ )
    {
      for ( int j = 0 - myBufferSize; j <= myBufferSize; j++ )
      {
        theQPainter->drawText( int( i + ( myOriginX + myScaleBarWidthInt - ( myFontWidth / 2 ) ) ),
                               int( j + ( myOriginY - ( myFontHeight / 4 ) ) ),
                               myScaleBarMaxLabel );
      }
    }
    //then the text itself
    theQPainter->setPen( myForeColor );
    theQPainter->drawText(
      int( myOriginX + myScaleBarWidthInt - ( myFontWidth / 2 ) ),
      int( myOriginY - ( myFontHeight / 4 ) ),
      myScaleBarMaxLabel
    );

    //
    //Draw unit label
    //
    theQPainter->setPen( myBackColor );
    myFontWidth = myFontMetrics.width( myScaleBarUnitLabel );
    myFontHeight = myFontMetrics.height();
    //first the buffer
    for ( int i = 0 - myBufferSize; i <= myBufferSize; i++ )
    {
      for ( int j = 0 - myBufferSize; j <= myBufferSize; j++ )
      {
        theQPainter->drawText( i + ( myOriginX + myScaleBarWidthInt + myTextOffsetX ),
                               j + ( myOriginY + myMajorTickSize ),
                               myScaleBarUnitLabel );
      }
    }
    //then the text itself
    theQPainter->setPen( myForeColor );
    theQPainter->drawText(
      ( myOriginX + myScaleBarWidthInt + myTextOffsetX ), ( myOriginY + myMajorTickSize ),
      myScaleBarUnitLabel
    );
  }
}
inline bool checkDifference(qreal a, qreal b, qreal portionTolerance)
{
    return qAbs(a) > 1e-10 ?
        qAbs(a - b) / qAbs(a) < portionTolerance :
        qAbs(a - b) < 1e-10;
}
void ShapeResizeStrategy::resizeBy( const QPointF &center, qreal zoomX, qreal zoomY )
{
    QTransform matrix;
    matrix.translate(center.x(), center.y()); // translate to 
    matrix.scale(zoomX, zoomY);
    matrix.translate(-center.x(), -center.y()); // and back

    // that is the transformation we want to apply to the shapes
    matrix = m_unwindMatrix * matrix * m_windMatrix;

    // the resizing transformation without the mirroring part
    QTransform resizeMatrix;
    resizeMatrix.translate(center.x(), center.y()); // translate to 
    resizeMatrix.scale( qAbs(zoomX), qAbs(zoomY) );
    resizeMatrix.translate(-center.x(), -center.y()); // and back

    // the mirroring part of the resizing transformation
    QTransform mirrorMatrix;
    mirrorMatrix.translate(center.x(), center.y()); // translate to 
    mirrorMatrix.scale( zoomX < 0 ? -1 : 1, zoomY < 0 ? -1 : 1 );
    mirrorMatrix.translate(-center.x(), -center.y()); // and back

    int i = 0;
    foreach(KoShape *shape, m_selectedShapes)
    {
        shape->update();

        // this uses resize for the zooming part
        shape->applyAbsoluteTransformation( m_unwindMatrix );

        /*
         normally we would just apply the resizeMatrix now and be done with it, but
         we want to resize instead of scale, so we have to separate the scaling part
         of that transformation which can then be used to resize
        */

        // undo the last resize transformation
        shape->applyAbsoluteTransformation( m_transformations[i].inverted() );

        // save the shapes transformation matrix
        QTransform shapeMatrix = shape->absoluteTransformation(0);

        // calculate the matrix we would apply to the local shape matrix
        // that tells us the effective scale values we have to use for the resizing
        QTransform localMatrix = shapeMatrix * resizeMatrix * shapeMatrix.inverted();
        // save the effective scale values
        qreal scaleX = localMatrix.m11();
        qreal scaleY = localMatrix.m22();

        // calculate the scale matrix which is equivalent to our resizing above
        QTransform scaleMatrix = (QTransform().scale( scaleX, scaleY ));
        scaleMatrix =  shapeMatrix.inverted() * scaleMatrix * shapeMatrix;

        // calculate the new size of the shape, using the effective scale values
        QSizeF size( scaleX * m_startSizes[i].width(), scaleY * m_startSizes[i].height() );

        // apply the transformation
        shape->setSize( size );
        // apply the rest of the transformation without the resizing part
        shape->applyAbsoluteTransformation( scaleMatrix.inverted() * resizeMatrix );
        shape->applyAbsoluteTransformation( mirrorMatrix );

        // and remember the applied transformation later for later undoing
        m_transformations[i] = shapeMatrix.inverted() * shape->absoluteTransformation(0);

        shape->applyAbsoluteTransformation( m_windMatrix );

        shape->update();
        i++;
    }
QGeometryData MgGeometriesData::cylinder(const QGLCylinder & cylinder,const QVector3D & orientation)
{
	QGeometryData my_geometry;

	qreal x(.0),y(.0);
	int n = cylinder.slices();
	qreal d_angle = 2.0 * M_PI/n;
	qreal angle=0;
	qreal z=cylinder.height();


	qreal scale_bottom,scale_top;
	QVector3D current_point;
	QQuaternion rotation = rotationFromZ(orientation);

	for(int i =0;i<n+1;++i)
	{
		x = cos(angle);
		y = sin(angle);
		if(z!=cylinder.height())
		{
			scale_bottom = cylinder.diameterTop();
			scale_top = cylinder.diameterBottom();
		}
		else
		{
			scale_bottom = cylinder.diameterBottom();
			scale_top = cylinder.diameterTop();
		}


		//bottom point;
		x = cos(angle) * scale_bottom;
		y = sin(angle) * scale_bottom;

		current_point = QVector3D(x,y,z);
		my_geometry.appendVertex(rotation.rotatedVector(current_point));
		my_geometry.appendNormal(rotation.rotatedVector(current_point));

		//top point
		x = scale_top * cos(angle);
		y = scale_top * sin(angle);
		z = qAbs(z-cylinder.height());

		current_point = QVector3D(x,y,z);
		my_geometry.appendVertex(rotation.rotatedVector(current_point));
		my_geometry.appendNormal(rotation.rotatedVector(current_point));

		// next point
		x = scale_top * cos((angle+d_angle));
		y = scale_top * sin(angle+d_angle);
		z = qAbs(z-cylinder.height());

		current_point = QVector3D(x,y,z);
		my_geometry.appendVertex(rotation.rotatedVector(current_point));
		my_geometry.appendNormal(rotation.rotatedVector(current_point));


		z = qAbs(z-cylinder.height());
		angle+=d_angle;
	}
    return my_geometry;
}
Exemple #7
0
void QgsGrassNewMapset::drawRegion()
{

  QPixmap pm = mPixmap;
  mRegionMap->setPixmap( pm );

  if ( mCellHead.proj == PROJECTION_XY )
    return;

  QgsDebugMsg( QString( "pm.isNull() = %1" ).arg( pm.isNull() ) );
  QPainter p( &pm );
  p.setPen( QPen( QColor( 255, 0, 0 ), 3 ) );

  double n = mNorthLineEdit->text().toDouble();
  double s = mSouthLineEdit->text().toDouble();
  double e = mEastLineEdit->text().toDouble();
  double w = mWestLineEdit->text().toDouble();

  // Shift if LL and W > E
  if ( mCellHead.proj == PROJECTION_LL && w > e )
  {
    if (( 180 - w ) < ( e + 180 ) )
    {
      w -= 360;
    }
    else
    {
      e += 360;
    }
  }

  QList<QgsPoint> tpoints; // ll lr ur ul ll
  tpoints << QgsPoint( w, s );
  tpoints << QgsPoint( e, s );
  tpoints << QgsPoint( e, n );
  tpoints << QgsPoint( w, n );
  tpoints << QgsPoint( w, s );


  // Because of possible shift +/- 360 in LL we have to split
  // the lines at least in 3 parts
  QList<QgsPoint> points; //
  for ( int i = 0; i < 4; i++ )
  {
    for ( int j = 0; j < 3; j++ )
    {
      double x = tpoints[i].x();
      double y = tpoints[i].y();
      double dx = ( tpoints[i+1].x() - x ) / 3;
      double dy = ( tpoints[i+1].y() - y ) / 3;
      QgsDebugMsg( QString( "dx = %1 x = %2" ).arg( dx ).arg( x + j*dx ) );
      points << QgsPoint( x + j*dx, y + j*dy );

    }
  }
  points << points[0]; // close polygon

  // Warning: seems that crashes if source == dest
  if ( mProjectionSelector->selectedCrsId() != GEOCRS_ID )
  {
    QgsCoordinateReferenceSystem source = QgsCoordinateReferenceSystem::fromSrsId( mProjectionSelector->selectedCrsId() );

    if ( !source.isValid() )
    {
      QgsGrass::warning( tr( "Cannot create QgsCoordinateReferenceSystem" ) );
      return;
    }

    QgsCoordinateReferenceSystem dest = QgsCoordinateReferenceSystem::fromSrsId( GEOCRS_ID );

    if ( !dest.isValid() )
    {
      QgsGrass::warning( tr( "Cannot create QgsCoordinateReferenceSystem" ) );
      return;
    }

    QgsCoordinateTransform trans( source, dest );

    for ( int i = points.size() - 1; i >= 0; i-- )
    {
      // Warning: I found that with some projections (e.g. Abidjan 1987)
      // if N = 90 or S = -90 the coordinate projected to
      // WGS84 is nonsense (156.983,89.9988 regardless x) ->
      // use 89.9 - for draw it is not so important
      if ( mCellHead.proj == PROJECTION_LL )
      {
        if ( points[i].y() >= 89.9 )
          points[i].setY( 89.9 );
        if ( points[i].y() <= -89.9 )
          points[i].setY( -89.9 );
      }

      QgsDebugMsg( QString( "%1,%2" ).arg( points[i].x() ).arg( points[i].y() ) );

      // exclude points if transformation failed
      try
      {
        points[i] = trans.transform( points[i] );
        QgsDebugMsg( QString( " --> %1,%2" ).arg( points[i].x() ).arg( points[i].y() ) );
      }
      catch ( QgsCsException &cse )
      {
        Q_UNUSED( cse );
        QgsDebugMsg( "Cannot transform point" );
        points.removeAt( i );
      }
    }

    if ( points.size() < 3 )
    {
      QgsDebugMsg( "Cannot reproject region." );
      return;
    }
  }

  for ( int shift = -360; shift <= 360; shift += 360 )
  {
    for ( int i = 0; i < 12; i++ )
    {
      double x1 = points[i].x();
      double x2 = points[i+1].x();

      if ( qAbs( x2 - x1 ) > 150 )
      {
        if ( x2 < x1 )
        {
          x2 += 360;
        }
        else
        {
          x2 -= 360;
        }
      }
      p.drawLine( 180 + shift + ( int )x1, 90 - ( int )points[i].y(),
                  180 + shift + ( int )x2, 90 - ( int )points[i+1].y() );
    }
  }

  p.end();

  mRegionMap->setPixmap( pm );
}
void QgsComposerView::mouseReleaseEvent( QMouseEvent* e )
{
  if ( !composition() )
  {
    return;
  }

  QPoint mousePressStopPoint = e->pos();
  int diffX = mousePressStopPoint.x() - mMousePressStartPos.x();
  int diffY = mousePressStopPoint.y() - mMousePressStartPos.y();

  //was this just a click? or a click and drag?
  bool clickOnly = false;
  if ( qAbs( diffX ) < 2 && qAbs( diffY ) < 2 )
  {
    clickOnly = true;
  }

  QPointF scenePoint = mapToScene( e->pos() );

  if ( mPanning )
  {
    mPanning = false;

    if ( clickOnly && e->button() == Qt::MidButton )
    {
      //middle mouse button click = recenter on point

      //get current visible part of scene
      QRect viewportRect( 0, 0, viewport()->width(), viewport()->height() );
      QgsRectangle visibleRect = QgsRectangle( mapToScene( viewportRect ).boundingRect() );
      visibleRect.scale( 1, scenePoint.x(), scenePoint.y() );
      QRectF boundsRect = visibleRect.toRectF();

      //zoom view to fit desired bounds
      fitInView( boundsRect, Qt::KeepAspectRatio );
    }

    //set new cursor
    if ( mCurrentTool == Pan )
    {
      viewport()->setCursor( Qt::OpenHandCursor );
    }
    else
    {
      if ( composition() )
      {
        //allow composer items to change cursor
        composition()->setPreventCursorChange( false );
      }
      viewport()->setCursor( Qt::ArrowCursor );
    }
  }

  if ( mMarqueeSelect )
  {
    endMarqueeSelect( e );
    return;
  }

  switch ( mCurrentTool )
  {
    case Select:
    {
      QGraphicsView::mouseReleaseEvent( e );
      break;
    }

    case Zoom:
    {
      if ( mMarqueeZoom )
      {
        endMarqueeZoom( e );
      }
      break;
    }

    case MoveItemContent:
    {
      if ( mMoveContentItem )
      {
        //update map preview if composer map
        QgsComposerMap* composerMap = dynamic_cast<QgsComposerMap *>( mMoveContentItem );
        if ( composerMap )
        {
          composerMap->setOffset( 0, 0 );
        }

        double moveX = scenePoint.x() - mMoveContentStartPos.x();
        double moveY = scenePoint.y() - mMoveContentStartPos.y();

        composition()->beginCommand( mMoveContentItem, tr( "Move item content" ) );
        mMoveContentItem->moveContent( -moveX, -moveY );
        composition()->endCommand();
        mMoveContentItem = 0;
      }
      break;
    }
    case AddArrow:
      if ( composition() )
      {
        QPointF scenePoint = mapToScene( e->pos() );
        QPointF snappedScenePoint = composition()->snapPointToGrid( scenePoint );
        QgsComposerArrow* composerArrow = new QgsComposerArrow( mRubberBandStartPos, QPointF( snappedScenePoint.x(), snappedScenePoint.y() ), composition() );
        composition()->addComposerArrow( composerArrow );
        scene()->removeItem( mRubberBandLineItem );
        delete mRubberBandLineItem;
        mRubberBandLineItem = 0;
        emit actionFinished();
        composition()->pushAddRemoveCommand( composerArrow, tr( "Arrow added" ) );
      }
      break;

    case AddRectangle:
    case AddTriangle:
    case AddEllipse:
      addShape( mCurrentTool );
      break;

    case AddMap:
      if ( !mRubberBandItem || ( mRubberBandItem->rect().width() < 0.1 && mRubberBandItem->rect().height() < 0.1 ) )
      {
        removeRubberBand();
        return;
      }
      if ( composition() )
      {
        QgsComposerMap* composerMap = new QgsComposerMap( composition(), mRubberBandItem->transform().dx(), mRubberBandItem->transform().dy(), mRubberBandItem->rect().width(), mRubberBandItem->rect().height() );
        composition()->addComposerMap( composerMap );
        removeRubberBand();
        emit actionFinished();
        composition()->pushAddRemoveCommand( composerMap, tr( "Map added" ) );
      }
      break;

    case AddHtml:
      if ( composition() )
      {
        QgsComposerHtml* composerHtml = new QgsComposerHtml( composition(), true );
        QgsAddRemoveMultiFrameCommand* command = new QgsAddRemoveMultiFrameCommand( QgsAddRemoveMultiFrameCommand::Added,
            composerHtml, composition(), tr( "Html item added" ) );
        composition()->undoStack()->push( command );
        QgsComposerFrame* frame = new QgsComposerFrame( composition(), composerHtml, mRubberBandItem->transform().dx(),
            mRubberBandItem->transform().dy(), mRubberBandItem->rect().width(),
            mRubberBandItem->rect().height() );
        composition()->beginMultiFrameCommand( composerHtml, tr( "Html frame added" ) );
        composerHtml->addFrame( frame );
        composition()->endMultiFrameCommand();
        removeRubberBand();
        emit actionFinished();
      }
    default:
      break;
  }
}
Exemple #9
0
void TileLayout::doLayout(const QRect& rect) const
{
	if (m_items.isEmpty())
		return;

	int left, top, right, bottom;
	getContentsMargins(&left, &top, &right, &bottom);
	QRect effectiveRect = rect.adjusted(left, top, -right, -bottom);
	int x = effectiveRect.x();
	int y = effectiveRect.y();

	QWidget* widget = m_items.first()->widget();
	int spaceX = horizontalSpacing();
	if (spaceX == -1)
		spaceX = widget->style()->layoutSpacing(QSizePolicy::DefaultType,
							QSizePolicy::DefaultType,
							Qt::Horizontal);
	int spaceY = verticalSpacing();
	if (spaceY == -1)
		spaceY = widget->style()->layoutSpacing(QSizePolicy::DefaultType,
							QSizePolicy::DefaultType,
							Qt::Vertical);

	qreal layoutAr = qreal(effectiveRect.width()) / effectiveRect.height();
	int count = m_items.size();
	QSize sh = widget->sizeHint();
	qreal pixels = sh.width() * sh.height() * count;

	// Approximation based on the layout's aspect ratio
	qreal totalWidth = qSqrt(pixels * layoutAr);
	int cols = totalWidth / sh.width() + 0.5;
	int rows = (count - 1) / cols + 1;

	// The approximation is far from perfect, so we perform some
	// additional checks to make sure we have as few rows and
	// columns as possible.
	int smallest = qMin(cols, rows);
	if (count <= smallest * smallest)
	{
		cols = smallest;
		rows = smallest;
	}
	if (count <= cols * (rows - 1))
		rows--;
	if (count <= (cols - 1) * rows)
		cols--;

	// Often the column and row counts are backwards, meaning that
	// the available space isn't being used efficiently. In that
	// case we swap the values of 'cols' and 'rows'.
	if (qAbs(cols - rows) >= 1)
	{
		qreal ar1 = qreal(cols * sh.width()) / (rows * sh.height());
		qreal ar2 = qreal(rows * sh.width()) / (cols * sh.height());
		if (qAbs(ar1 - layoutAr) > qAbs(ar2 - layoutAr))
			std::swap(cols, rows);
	}

	int itemWidth = (effectiveRect.width() - (cols - 1) * spaceX) / cols;
	int itemHeight = (effectiveRect.height() - (rows - 1) * spaceY) / rows;

	int col = 0;
	for (QLayoutItem* item : qAsConst(m_items))
	{
		int nextX = x + itemWidth + spaceX;
		if (++col > cols)
		{
			col = 1;
			x = effectiveRect.x();
			y += itemHeight + spaceY;
			nextX = x + itemWidth + spaceX;
		}

		item->setGeometry(QRect(QPoint(x, y), QSize(itemWidth, itemHeight)));

		x = nextX;
	}
}
Exemple #10
0
void EditAccount::setAccount(QMailAccount *in, AccountConfiguration* conf, bool defaultServer)
{
    account = 0;

    if (!in->id().isValid()) {
        // New account
        accountNameInput->setText("");
        emailInput->setText("");
        mailUserInput->setText("");
        mailPasswInput->setText("");
        mailServerInput->setText("");
        smtpServerInput->setText("");
        mailPortInput->setText("110");
        smtpPortInput->setText("25");
#ifndef QT_NO_OPENSSL
        smtpUsernameInput->setText("");
        smtpPasswordInput->setText("");
        encryption->setCurrentIndex(0);
        authentication->setCurrentIndex(0);
        smtpUsernameInput->setEnabled(false);
        lblSmtpUsername->setEnabled(false);
        smtpPasswordInput->setEnabled(false);
        lblSmtpPassword->setEnabled(false);
        encryptionIncoming->setCurrentIndex(0);
#endif
        pushCheckBox->setChecked(false);
        intervalCheckBox->setChecked(false);
        roamingCheckBox->setEnabled(false);
#ifdef QTOPIA_HOMEUI
        roamingCheckBox->hide();
#endif
        setWindowTitle( tr("Create new account", "translation not longer than English") );

        account = in;
        config = conf;
        typeChanged( 0 );
    } else {
        account = in;
        config = conf;

        accountNameInput->setText( config->accountName() );
        nameInput->setText( config->userName() );
        emailInput->setText( config->emailAddress() );
        mailUserInput->setText( config->mailUserName() );
        mailPasswInput->setText( config->mailPassword() );
        mailServerInput->setText( config->mailServer() );
        smtpServerInput->setText( config->smtpServer() );
        deleteCheckBox->setChecked( config->canDeleteMail() );

        sigCheckBox->setChecked( config->useSignature() );
        sig = config->signature();

        maxSize->setValue(config->maxMailSize());
        thresholdCheckBox->setChecked( config->maxMailSize() != -1 );
        smtpPortInput->setText( QString::number( config->smtpPort() ) );
        defaultMailCheckBox->setChecked( defaultServer );
#ifndef QT_NO_OPENSSL
        smtpUsernameInput->setText(config->smtpUsername());
        smtpPasswordInput->setText(config->smtpPassword());
        authentication->setItemText(3, accountType->currentText());
        authentication->setCurrentIndex(authenticationIndex(config->smtpAuthentication()));
        encryption->setCurrentIndex(static_cast<int>(config->smtpEncryption()));
        AccountConfiguration::AuthType type = authenticationType[authentication->currentIndex()];
        const bool enableCredentials(type == AccountConfiguration::Auth_LOGIN || type == AccountConfiguration::Auth_PLAIN);
        smtpUsernameInput->setEnabled(enableCredentials);
        lblSmtpUsername->setEnabled(enableCredentials);
        smtpPasswordInput->setEnabled(enableCredentials);
        lblSmtpPassword->setEnabled(enableCredentials);
        encryptionIncoming->setCurrentIndex(static_cast<int>(config->mailEncryption()));
#endif
        pushCheckBox->setChecked( config->pushEnabled() );
        intervalCheckBox->setChecked( config->checkInterval() > 0 );
        intervalPeriod->setValue( qAbs( config->checkInterval() ) );
        roamingCheckBox->setChecked( !config->intervalCheckRoamingEnabled() );
        roamingCheckBox->setEnabled( intervalCheckBox->isChecked() );
#ifdef QTOPIA_HOMEUI
        roamingCheckBox->hide();
#endif

        if ( account->messageSources().contains("pop3", Qt::CaseInsensitive)) {
            accountType->setCurrentIndex(0);
            typeChanged(0);
        } else if ( account->messageSources().contains("imap4", Qt::CaseInsensitive)) {
            accountType->setCurrentIndex(1);
            typeChanged(1);
            imapBaseDir->setText( config->baseFolder() );
        } else {
            accountType->setCurrentIndex(2);
            typeChanged(2);
        }
        mailPortInput->setText( QString::number( config->mailPort() ) );
    }

    nameInput->setText( config->userName() );
}
Exemple #11
0
static bool write_jpeg_image(const QImage &image, QIODevice *device, int sourceQuality)
{
    bool success = false;
    const QVector<QRgb> cmap = image.colorTable();

    struct jpeg_compress_struct cinfo;
    JSAMPROW row_pointer[1];
    row_pointer[0] = 0;

    struct my_jpeg_destination_mgr *iod_dest = new my_jpeg_destination_mgr(device);
    struct my_error_mgr jerr;

    cinfo.err = jpeg_std_error(&jerr);
    jerr.error_exit = my_error_exit;

    if (!setjmp(jerr.setjmp_buffer)) {
        // WARNING:
        // this if loop is inside a setjmp/longjmp branch
        // do not create C++ temporaries here because the destructor may never be called
        // if you allocate memory, make sure that you can free it (row_pointer[0])
        jpeg_create_compress(&cinfo);

        cinfo.dest = iod_dest;

        cinfo.image_width = image.width();
        cinfo.image_height = image.height();

        bool gray=false;
        switch (image.format()) {
        case QImage::Format_Mono:
        case QImage::Format_MonoLSB:
        case QImage::Format_Indexed8:
            gray = true;
            for (int i = image.colorCount(); gray && i--;) {
                gray = gray & (qRed(cmap[i]) == qGreen(cmap[i]) &&
                               qRed(cmap[i]) == qBlue(cmap[i]));
            }
            cinfo.input_components = gray ? 1 : 3;
            cinfo.in_color_space = gray ? JCS_GRAYSCALE : JCS_RGB;
            break;
        default:
            cinfo.input_components = 3;
            cinfo.in_color_space = JCS_RGB;
        }

        jpeg_set_defaults(&cinfo);

        qreal diffInch = qAbs(image.dotsPerMeterX()*2.54/100. - qRound(image.dotsPerMeterX()*2.54/100.))
                         + qAbs(image.dotsPerMeterY()*2.54/100. - qRound(image.dotsPerMeterY()*2.54/100.));
        qreal diffCm = (qAbs(image.dotsPerMeterX()/100. - qRound(image.dotsPerMeterX()/100.))
                        + qAbs(image.dotsPerMeterY()/100. - qRound(image.dotsPerMeterY()/100.)))*2.54;
        if (diffInch < diffCm) {
            cinfo.density_unit = 1; // dots/inch
            cinfo.X_density = qRound(image.dotsPerMeterX()*2.54/100.);
            cinfo.Y_density = qRound(image.dotsPerMeterY()*2.54/100.);
        } else {
            cinfo.density_unit = 2; // dots/cm
            cinfo.X_density = (image.dotsPerMeterX()+50) / 100;
            cinfo.Y_density = (image.dotsPerMeterY()+50) / 100;
        }


        int quality = sourceQuality >= 0 ? qMin(sourceQuality,100) : 75;
#if defined(Q_OS_UNIXWARE)
        jpeg_set_quality(&cinfo, quality, B_TRUE /* limit to baseline-JPEG values */);
        jpeg_start_compress(&cinfo, B_TRUE);
#else
        jpeg_set_quality(&cinfo, quality, true /* limit to baseline-JPEG values */);
        jpeg_start_compress(&cinfo, true);
#endif

        row_pointer[0] = new uchar[cinfo.image_width*cinfo.input_components];
        int w = cinfo.image_width;
        while (cinfo.next_scanline < cinfo.image_height) {
            uchar *row = row_pointer[0];
            switch (image.format()) {
            case QImage::Format_Mono:
            case QImage::Format_MonoLSB:
                if (gray) {
                    const uchar* data = image.constScanLine(cinfo.next_scanline);
                    if (image.format() == QImage::Format_MonoLSB) {
                        for (int i=0; i<w; i++) {
                            bool bit = !!(*(data + (i >> 3)) & (1 << (i & 7)));
                            row[i] = qRed(cmap[bit]);
                        }
                    } else {
                        for (int i=0; i<w; i++) {
                            bool bit = !!(*(data + (i >> 3)) & (1 << (7 -(i & 7))));
                            row[i] = qRed(cmap[bit]);
                        }
                    }
                } else {
                    const uchar* data = image.constScanLine(cinfo.next_scanline);
                    if (image.format() == QImage::Format_MonoLSB) {
                        for (int i=0; i<w; i++) {
                            bool bit = !!(*(data + (i >> 3)) & (1 << (i & 7)));
                            *row++ = qRed(cmap[bit]);
                            *row++ = qGreen(cmap[bit]);
                            *row++ = qBlue(cmap[bit]);
                        }
                    } else {
                        for (int i=0; i<w; i++) {
                            bool bit = !!(*(data + (i >> 3)) & (1 << (7 -(i & 7))));
                            *row++ = qRed(cmap[bit]);
                            *row++ = qGreen(cmap[bit]);
                            *row++ = qBlue(cmap[bit]);
                        }
                    }
                }
void QDeclarativeMouseArea::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
{
    Q_D(QDeclarativeMouseArea);
    if (!d->absorb) {
        QDeclarativeItem::mouseMoveEvent(event);
        return;
    }

    d->saveEvent(event);

    // ### we should skip this if these signals aren't used
    // ### can GV handle this for us?
    bool contains = boundingRect().contains(d->lastPos);
    if (d->hovered && !contains)
        setHovered(false);
    else if (!d->hovered && contains)
        setHovered(true);

    if (d->drag && d->drag->target()) {
        if (!d->moved) {
            d->startX = drag()->target()->x();
            d->startY = drag()->target()->y();
        }

        QPointF startLocalPos;
        QPointF curLocalPos;
        if (drag()->target()->parentItem()) {
            startLocalPos = drag()->target()->parentItem()->mapFromScene(d->startScene);
            curLocalPos = drag()->target()->parentItem()->mapFromScene(event->scenePos());
        } else {
            startLocalPos = d->startScene;
            curLocalPos = event->scenePos();
        }

        if (keepMouseGrab() && d->stealMouse)
            d->drag->setActive(true);

        bool dragX = drag()->axis() & QDeclarativeDrag::XAxis;
        bool dragY = drag()->axis() & QDeclarativeDrag::YAxis;

        const qreal x = dragX
                ? qBound(d->drag->xmin(), d->startX + curLocalPos.x() - startLocalPos.x(), d->drag->xmax())
                : d->startX;
        const qreal y = dragY
                ? qBound(d->drag->ymin(), d->startY + curLocalPos.y() - startLocalPos.y(), d->drag->ymax())
                : d->startY;

        if (d->drag->active()) {
            if (dragX && dragY)
                d->drag->target()->setPos(x, y);
            else if (dragX)
                d->drag->target()->setX(x);
            else if (dragY)
                d->drag->target()->setY(y);
        }

        if (!keepMouseGrab()) {
            const int dragThreshold = QApplication::startDragDistance();

            if (qAbs(x - d->startX) > dragThreshold || qAbs(y - d->startY) > dragThreshold) {
                setKeepMouseGrab(true);
                d->stealMouse = true;
            }
        }

        d->moved = true;
    }
    QDeclarativeMouseEvent me(d->lastPos.x(), d->lastPos.y(), d->lastButton, d->lastButtons, d->lastModifiers, false, d->longPress);
    emit mousePositionChanged(&me);
    me.setX(d->lastPos.x());
    me.setY(d->lastPos.y());
    emit positionChanged(&me);
}
Exemple #13
0
static inline void qwtDrawPolyline( QPainter *painter,
    const T *points, int pointCount, bool polylineSplitting )
{
    bool doSplit = false;
    if ( polylineSplitting && pointCount > 3 )
    {
        const QPaintEngine *pe = painter->paintEngine();
        if ( pe && pe->type() == QPaintEngine::Raster )
        {
            if ( painter->pen().width() <= 1 )
            {
#if QT_VERSION < 0x040800
                if ( painter->renderHints() & QPainter::Antialiasing )
                {
                    /*
                        all versions <= 4.7 have issues with 
                        antialiased lines
                     */

                    doSplit = true;
                }
#else
                // all version < 4.8 don't have the bug for
                // short lines below 2 pixels difference
                // in height and width

                doSplit = qwtIsRasterPaintEngineBuggy();
#endif
            }
            else
            {
                /*
                   Raster paint engine is much faster when splitting
                   the polygon, but of course we might see some issues where
                   the pieces are joining
                 */
                doSplit = true;
            }
        }
    }

    if ( doSplit )
    {
        QPen pen = painter->pen();

        const int splitSize = 6;

        if ( pen.width() <= 1 && pen.isSolid() && qwtIsRasterPaintEngineBuggy()
            && !( painter->renderHints() & QPainter::Antialiasing ) )
        {
            int k = 0;

            for ( int i = k + 1; i < pointCount; i++ )
            {
                const QPointF &p1 = points[i-1];
                const QPointF &p2 = points[i];

                const bool isBad = ( qAbs( p2.y() - p1.y() ) <= 1 )
                    &&  qAbs( p2.x() - p1.x() ) <= 1;

                if ( isBad || ( i - k >= splitSize ) )
                {
                    painter->drawPolyline( points + k, i - k + 1 );
                    k = i;
                }
            }

            painter->drawPolyline( points + k, pointCount - k );
        }
        else
        {
            for ( int i = 0; i < pointCount; i += splitSize )
            {
                const int n = qMin( splitSize + 1, pointCount - i );
                painter->drawPolyline( points + i, n );
            }
        }
    }
    else
    {
        painter->drawPolyline( points, pointCount );
    }
}
Exemple #14
0
void MythUIText::FillCutMessage()
{
    m_CutMessage.clear();

    if (m_Message != m_DefaultMessage)
    {
        bool isNumber;
        int value = m_Message.toInt(&isNumber);
        if (isNumber && m_TemplateText.contains("%n"))
        {
            m_CutMessage = qApp->translate("ThemeUI",
                                           m_TemplateText.toUtf8(), NULL,
                                           QCoreApplication::UnicodeUTF8,
                                           qAbs(value));
        }
        else if (m_TemplateText.contains("%1"))
        {
            QString tmp = qApp->translate("ThemeUI", m_TemplateText.toUtf8(),
                                          NULL, QCoreApplication::UnicodeUTF8);
            m_CutMessage = tmp.arg(m_Message);
        }
    }

    if (m_CutMessage.isEmpty())
        m_CutMessage = m_Message;
    if (m_CutMessage.isEmpty())
        return;

    QStringList templist;
    QStringList::iterator it;
    switch (m_textCase)
    {
      case CaseUpper :
        m_CutMessage = m_CutMessage.toUpper();
        break;
      case CaseLower :
        m_CutMessage = m_CutMessage.toLower();
        break;
      case CaseCapitaliseFirst :
        //m_CutMessage = m_CutMessage.toLower();
        templist = m_CutMessage.split(". ");
        for (it = templist.begin(); it != templist.end(); ++it)
            (*it).replace(0,1,(*it).left(1).toUpper());
        m_CutMessage = templist.join(". ");
        break;
      case CaseCapitaliseAll :
        //m_CutMessage = m_CutMessage.toLower();
        templist = m_CutMessage.split(" ");
        for (it = templist.begin(); it != templist.end(); ++it)
            (*it).replace(0,1,(*it).left(1).toUpper());
        m_CutMessage = templist.join(" ");
        break;
    }

    if (m_MinSize.x() > 0)
    {
        QRect rect;
        MakeNarrow(rect);

        // Record the minimal area needed for the message.
        SetMinArea(rect.size());
        if (m_MinArea.width() > 0)
            SetDrawRectSize(m_MinArea.width(), m_MinArea.height());
    }

    if (m_Cutdown)
        m_CutMessage = cutDown(m_CutMessage, m_Font, m_MultiLine);
}
void ObscuranceMainThread::run()
{
    Q_ASSERT(m_volume);

    m_stopped = false;

    vtkVolumeRayCastMapper *mapper = vtkVolumeRayCastMapper::SafeDownCast(m_volume->GetMapper());
    vtkEncodedGradientEstimator *gradientEstimator = mapper->GetGradientEstimator();
    /// \TODO fent això aquí crec que va més ràpid, però s'hauria de comprovar i provar també amb l'Update()
    gradientEstimator->GetEncodedNormals();

    // Creem els threads
    /// \todo QThread::idealThreadCount() amb Qt >= 4.3
    int numberOfThreads = vtkMultiThreader::GetGlobalDefaultNumberOfThreads();
    QVector<ObscuranceThread*> threads(numberOfThreads);

    // Variables necessàries
    vtkImageData *image = mapper->GetInput();
    unsigned short *data = reinterpret_cast<unsigned short*>(image->GetPointData()->GetScalars()->GetVoidPointer(0));
    int dataSize = image->GetPointData()->GetScalars()->GetSize();
    int dimensions[3];
    image->GetDimensions(dimensions);
    vtkIdType vtkIncrements[3];
    image->GetIncrements(vtkIncrements);

    int increments[3];
    increments[0] = vtkIncrements[0];
    increments[1] = vtkIncrements[1];
    increments[2] = vtkIncrements[2];

    m_obscurance = new Obscurance(dataSize, hasColor(), m_doublePrecision);

    for (int i = 0; i < numberOfThreads; i++)
    {
        ObscuranceThread * thread = new ObscuranceThread(i, numberOfThreads, m_transferFunction);
        thread->setGradientEstimator(gradientEstimator);
        thread->setData(data, dataSize, dimensions, increments);
        thread->setObscuranceParameters(m_maximumDistance, m_function, m_variant, m_obscurance);
        thread->setSaliency(m_saliency, m_fxSaliencyA, m_fxSaliencyB, m_fxSaliencyLow, m_fxSaliencyHigh);
        threads[i] = thread;
    }

    // Estructures de dades reaprofitables
    QVector<Vector3> lineStarts;

    const QVector<Vector3> directions = getDirections();
    int nDirections = directions.size();

    // Iterem per les direccions
    for (int i = 0; i < nDirections && !m_stopped; i++)
    {
        const Vector3 &direction = directions.at(i);

        DEBUG_LOG(QString("Direcció %1: %2").arg(i).arg(direction.toString()));

        // Direcció dominant (0 = x, 1 = y, 2 = z)
        int dominant;
        Vector3 absDirection(qAbs(direction.x), qAbs(direction.y), qAbs(direction.z));
        if (absDirection.x >= absDirection.y)
        {
            if (absDirection.x >= absDirection.z)
            {
                dominant = 0;
            }
            else
            {
                dominant = 2;
            }
        }
        else
        {
            if (absDirection.y >= absDirection.z)
            {
                dominant = 1;
            }
            else
            {
                dominant = 2;
            }
        }

        // Vector per avançar
        Vector3 forward;
        switch (dominant)
        {
            case 0:
                forward = Vector3(direction.x, direction.y, direction.z);
                break;
            case 1:
                forward = Vector3(direction.y, direction.z, direction.x);
                break;
            case 2: 
                forward = Vector3(direction.z, direction.x, direction.y);
                break;
        }
        // La direcció x passa a ser 1 o -1
        forward /= qAbs(forward.x);
        DEBUG_LOG(QString("forward = ") + forward.toString());

        // Dimensions i increments segons la direcció dominant
        int x = dominant, y = (dominant + 1) % 3, z = (dominant + 2) % 3;
        int dimX = dimensions[x], dimY = dimensions[y], dimZ = dimensions[z];
        int incX = increments[x], incY = increments[y], incZ = increments[z];
        int sX = 1, sY = 1, sZ = 1;
        qptrdiff startDelta = 0;
        if (forward.x < 0.0)
        {
            startDelta += incX * (dimX - 1);
//             incX = -incX;
            forward.x = -forward.x;
            sX = -1;
        }
        if (forward.y < 0.0)
        {
            startDelta += incY * (dimY - 1);
//             incY = -incY;
            forward.y = -forward.y;
            sY = -1;
        }
        if (forward.z < 0.0)
        {
            startDelta += incZ * (dimZ - 1);
//             incZ = -incZ;
            forward.z = -forward.z;
            sZ = -1;
        }
        DEBUG_LOG(QString("forward = ") + forward.toString());
        // Ara els 3 components són positius

        // Llista dels vòxels que són començament de línia
        getLineStarts(lineStarts, dimX, dimY, dimZ, forward);

//         int incXYZ[3] = { incX, incY, incZ };
        int xyz[3] = { x, y, z };
        int sXYZ[3] = { sX, sY, sZ };

        // Iniciem els threads
        for (int j = 0; j < numberOfThreads; j++)
        {
            ObscuranceThread * thread = threads[j];
            thread->setPerDirectionParameters(direction, forward, xyz, sXYZ, lineStarts, startDelta);
            thread->start();
        }

        // Esperem que acabin els threads
        for (int j = 0; j < numberOfThreads; j++)
        {
            threads[j]->wait();
        }

        emit progress(100 * (i + 1) / nDirections);
    }

    // Destruïm els threads
    for (int j = 0; j < numberOfThreads; j++)
    {
        delete threads[j];
    }
    // Si han cancel·lat el procés ja podem plegar
    if (m_stopped)
    {
        emit progress(0);
        delete m_obscurance; m_obscurance = 0;
        return;
    }

    m_obscurance->normalize();

    emit computed();
}
Exemple #16
0
#include "absnode.h"

#include <fugio/core/uuid.h>

#include <fugio/context_interface.h>

AbsNode::AbsNode( QSharedPointer<fugio::NodeInterface> pNode )
	: NodeControlBase( pNode )
{
	static const QUuid	PII_NUMBER1( "{c13a41c6-544b-46bb-a9f2-19dd156d236c}" );
	static const QUuid	PII_NUMBER2( "{608ac771-490b-4ae6-9c81-12b9af526d09}" );

	mPinInput = pinInput( "Number", PII_NUMBER1 );

	mValOutput = pinOutput<fugio::VariantInterface *>( "Number", mPinOutput, PID_FLOAT, PII_NUMBER2 );
}

void AbsNode::inputsUpdated( qint64 pTimeStamp )
{
	Q_UNUSED( pTimeStamp )

	float		NewVal = qAbs( variant( mPinInput ).toFloat() );

	if( NewVal != mValOutput->variant().toFloat() )
	{
		mValOutput->setVariant( NewVal );

		pinUpdated( mPinOutput );
	}
}
void ResizeGesture::doResize(bool scaleContent)
{
	PageItem* currItem = m_doc->m_Selection->itemAt(0);
	QString targetName = Um::SelectionGroup;
	QPixmap* targetIcon = Um::IGroup;
	if (!m_doc->m_Selection->isMultipleSelection())
	{
		targetName = currItem->getUName();
		targetIcon = currItem->getUPixmap();
	}
	if (!m_transactionStarted)
	{
		m_transactionStarted = new UndoTransaction(Um::instance()->beginTransaction(targetName, targetIcon,
																					Um::Resize, "", Um::IResize));
//		qDebug() << "ResizeGesture::doResize: begin transaction" << m_transactionStarted;
	}
	QRectF newBounds = m_bounds.normalized();
	double dw = (newBounds.width() - m_extraWidth) - currItem->width();
	double dh = (newBounds.height() - m_extraHeight) - currItem->height();
	double dsch = 1.0;
	double dscw = 1.0;
	if (currItem->isArc())
	{
		PageItem_Arc* item = currItem->asArc();
		if (currItem->height() != 0.0)
			dsch = item->arcHeight / currItem->height();
		if (currItem->width() != 0.0)
			dscw = item->arcWidth / currItem->width();
	}
	if (m_doc->m_Selection->isMultipleSelection())
	{
		int RotModeBack = m_doc->RotMode();
		m_doc->RotMode ( 0 );
		double gx, gy, gh, gw;
		m_doc->m_Selection->getGroupRect(&gx, &gy, &gw, &gh);
		QRectF oldBounds(gx, gy, gw, gh);
		double scx = oldBounds.width() == 0? 1.0 : (newBounds.width() - m_extraWidth) / oldBounds.width();
		double scy = oldBounds.height() == 0? 1.0 : (newBounds.height() - m_extraHeight) / oldBounds.height();
		//CB #3012 only scale text in a group if alt is pressed
		if ((currItem->itemType() == PageItem::TextFrame) && scaleContent)
			m_doc->scaleGroup(scx, scy, true);
		else
			m_doc->scaleGroup(scx, scy, false);
		double dx = newBounds.x() - oldBounds.x();
		double dy = newBounds.y() - oldBounds.y();
		if (dx != 0 || dy != 0)
			m_doc->moveGroup(dx + m_extraX, dy + m_extraY);
		m_doc->RotMode ( RotModeBack );
	}
	else
	{
		if (currItem->itemType() == PageItem::ImageFrame && scaleContent)
		{
			double divX = (currItem->width() != 0) ? currItem->width() : 1.0;
			double divY = (currItem->height() != 0) ? currItem->height() : 1.0;
			double imgScX = (newBounds.width() - m_extraWidth) / divX * currItem->imageXScale();
			double imgScY = (newBounds.height() - m_extraHeight) / divY * currItem->imageYScale();
			// The aspect ratio has been fixed, so make the modification in the direction of the larger movement.
			if (currItem->keepAspectRatio() && currItem->fitImageToFrame()) 
			{
				if (qAbs((newBounds.width() - m_extraWidth) - currItem->width()) > qAbs((newBounds.height() - m_extraHeight) - currItem->height()))
					imgScY = imgScX;
				else
					imgScX = imgScY;
			}
			currItem->setImageXYScale(imgScX, imgScY);
		}
		else if (currItem->itemType() == PageItem::ImageFrame && currItem->PictureIsAvailable)
		{
			double dx = ((newBounds.x() + m_extraX) - currItem->xPos());
			double dy = ((newBounds.y() + m_extraY) - currItem->yPos());
			double cosa = cos(currItem->rotation() * M_PI / 180.0);
			double sina = sin(currItem->rotation() * M_PI / 180.0);
			double xoff = -(cosa*dx + sina*dy);
			if (currItem->imageFlippedH())
				xoff += (currItem->width() - (newBounds.width() - m_extraWidth));
			double yoff = -(cosa*dy - sina*dx);
			if (currItem->imageFlippedV())
				yoff += (currItem->height() - (newBounds.height() - m_extraHeight));
			if (xoff != 0.0 || yoff != 0.0)
			{
				currItem->moveImageInFrame(xoff / currItem->imageXScale(), yoff / currItem->imageYScale());
			}
		}
		// We do not want to scale the text of a linked frame
		// as it would alter text in other frames of the string
		else if((currItem->itemType() == PageItem::TextFrame) 
				       && (currItem->nextInChain() == 0) 
				       && (currItem->prevInChain() == 0) 
				       && scaleContent)
		{
			double divX = (currItem->width() != 0) ? currItem->width() : 1.0;
			double divY = (currItem->height() != 0) ? currItem->height() : 1.0;
			double txtScX = (newBounds.width() - m_extraWidth) / divX;
			double txtScY = (newBounds.height() - m_extraHeight) / divY;
			if (currItem->itemText.length() != 0)
			{
				for (int aa = 0; aa < currItem->itemText.length(); ++aa)
				{
#if 0 // hard to decide if it’s batter to scale or to change font size
					currItem->itemText.item(aa)->setScaleV(
							qMax(qMin(qRound(currItem->itemText.item(aa)->scaleV()*txtScY), 4000), 100));
					currItem->itemText.item(aa)->setScaleH(
							qMax(qMin(qRound(currItem->itemText.item(aa)->scaleH() * txtScX), 4000), 100));
#else
					currItem->itemText.item(aa)->setFontSize(
							qMax(qMin(currItem->itemText.item(aa)->fontSize() * txtScY, 4000.0), 1.0));
					currItem->itemText.item(aa)->setScaleH(
							qMax(qMin(qRound(currItem->itemText.item(aa)->scaleH() * txtScX / txtScY), 4000), 100));
#endif

					// We need to scale the linespacing _only once_ per paragraph.
					if((aa == 0) 
						|| ( SpecialChars::isBreak(currItem->itemText.itemText(aa - 1).at(0))))
					{
						ParagraphStyle ps(currItem->itemText.paragraphStyle(aa));
						double oldLS(currItem->itemText.paragraphStyle(aa).lineSpacing());
						ps.setLineSpacing(qMax(qRound(oldLS * txtScY), 1));
						currItem->itemText.setStyle(aa,ps);
					}
				}
			}
		}
		currItem->setXYPos(newBounds.x() + m_extraX, newBounds.y() + m_extraY);
		currItem->setWidth(newBounds.width() - m_extraWidth);
		currItem->setHeight(newBounds.height() - m_extraHeight);
		currItem->updateClip();
		if (currItem->isArc())
		{
			PageItem_Arc* item = currItem->asArc();
			item->arcWidth += dw * dscw;
			item->arcHeight += dh * dsch;
			item->recalcPath();
			FPoint tp2(getMinClipF(&currItem->PoLine));
			currItem->PoLine.translate(-tp2.x(), -tp2.y());
			m_doc->AdjustItemSize(currItem);
		}
		if (currItem->isSpiral())
		{
			PageItem_Spiral* item = currItem->asSpiral();
			item->recalcPath();
		}
		// rotation does not change
	}
	m_origBounds = m_bounds;
}
Exemple #18
0
/**
 * \return True if this vector and the given vector are almost equal
 * (see RS::PointTolerance) in 2D space (x,y).
 *
 * \param tol Tolerance in X, Y.
 */
bool RVector::equalsFuzzy2D(const RVector& v, double tol) const {
    return (qAbs(x-v.x)<tol &&
            qAbs(y-v.y)<tol &&
            valid==v.valid);
}
Exemple #19
0
void QgsComposerPicture::setSceneRect( const QRectF& rectangle )
{
  QSizeF currentPictureSize = pictureSize();

  if ( mResizeMode == QgsComposerPicture::Clip )
  {
    QgsComposerItem::setSceneRect( rectangle );
    mPictureWidth = rectangle.width();
    mPictureHeight = rectangle.height();
  }
  else
  {
    QRectF newRect = rectangle;

    if ( mResizeMode == ZoomResizeFrame && !rect().isEmpty() && !( currentPictureSize.isEmpty() ) )
    {
      QSizeF targetImageSize;
      if ( qgsDoubleNear( mPictureRotation, 0.0 ) )
      {
        targetImageSize = currentPictureSize;
      }
      else
      {
        //calculate aspect ratio of bounds of rotated image
        QTransform tr;
        tr.rotate( mPictureRotation );
        QRectF rotatedBounds = tr.mapRect( QRectF( 0, 0, currentPictureSize.width(), currentPictureSize.height() ) );
        targetImageSize = QSizeF( rotatedBounds.width(), rotatedBounds.height() );
      }

      //if height has changed more than width, then fix width and set height correspondingly
      //else, do the opposite
      if ( qAbs( rect().width() - rectangle.width() ) <
           qAbs( rect().height() - rectangle.height() ) )
      {
        newRect.setHeight( targetImageSize.height() * newRect.width() / targetImageSize.width() );
      }
      else
      {
        newRect.setWidth( targetImageSize.width() * newRect.height() / targetImageSize.height() );
      }
    }
    else if ( mResizeMode == FrameToImageSize )
    {
      if ( !( currentPictureSize.isEmpty() ) )
      {
        newRect.setWidth( currentPictureSize.width() * 25.4 / mComposition->printResolution() );
        newRect.setHeight( currentPictureSize.height() * 25.4 / mComposition->printResolution() );
      }
    }

    //find largest scaling of picture with this rotation which fits in item
    if ( mResizeMode == Zoom || mResizeMode == ZoomResizeFrame )
    {
      QRectF rotatedImageRect = QgsComposerUtils::largestRotatedRectWithinBounds( QRectF( 0, 0, currentPictureSize.width(), currentPictureSize.height() ), newRect, mPictureRotation );
      mPictureWidth = rotatedImageRect.width();
      mPictureHeight = rotatedImageRect.height();
    }
    else
    {
      mPictureWidth = newRect.width();
      mPictureHeight = newRect.height();
    }

    QgsComposerItem::setSceneRect( newRect );
    emit itemChanged();
  }

  if ( mMode == SVG && !mLoadingSvg )
  {
    mLoadingSvg = true;
    refreshPicture();
    mLoadingSvg = false;
  }
}
Exemple #20
0
void NzmqtTest::testPubSub()
{
    try {
        QScopedPointer<ZMQContext> context(nzmqt::createDefaultContext());

        // Create publisher.
        samples::pubsub::Publisher* publisher = new samples::pubsub::Publisher(*context, "inproc://pubsub", "ping");
        QSignalSpy spyPublisherPingSent(publisher, SIGNAL(pingSent(const QList<QByteArray>&)));
        QSignalSpy spyPublisherFailure(publisher, SIGNAL(failure(const QString&)));
        QSignalSpy spyPublisherFinished(publisher, SIGNAL(finished()));
        // Create publisher execution thread.
        QThread* publisherThread = makeExecutionThread(*publisher);
        QSignalSpy spyPublisherThreadFinished(publisherThread, SIGNAL(finished()));

        // Create subscriber.
        samples::pubsub::Subscriber* subscriber = new samples::pubsub::Subscriber(*context, "inproc://pubsub", "ping");
        QSignalSpy spySubscriberPingReceived(subscriber, SIGNAL(pingReceived(const QList<QByteArray>&)));
        QSignalSpy spySubscriberFailure(subscriber, SIGNAL(failure(const QString&)));
        QSignalSpy spySubscriberFinished(subscriber, SIGNAL(finished()));
        // Create subscriber execution thread.
        QThread* subscriberThread = makeExecutionThread(*subscriber);
        QSignalSpy spySubscriberThreadFinished(subscriberThread, SIGNAL(finished()));

        //
        // START TEST
        //

        context->start();

        publisherThread->start();
        QTest::qWait(500);
        subscriberThread->start();

        QTimer::singleShot(6000, publisher, SLOT(stop()));
        QTimer::singleShot(6000, subscriber, SLOT(stop()));

        QTest::qWait(8000);

        //
        // CHECK POSTCONDITIONS
        //

        qDebug() << "Publisher pings sent:" << spyPublisherPingSent.size();
        qDebug() << "Subscriber pings received:" << spySubscriberPingReceived.size();

        QCOMPARE(spyPublisherFailure.size(), 0);
        QCOMPARE(spySubscriberFailure.size(), 0);

        QVERIFY2(spyPublisherPingSent.size() > 3, "Server didn't send any/enough pings.");
        QVERIFY2(spySubscriberPingReceived.size() > 3, "Client didn't receive any/enough pings.");

        QVERIFY2(qAbs(spyPublisherPingSent.size() - spySubscriberPingReceived.size()) < 3, "Publisher and subscriber communication flawed.");

        QCOMPARE(spyPublisherFinished.size(), 1);
        QCOMPARE(spySubscriberFinished.size(), 1);

        QCOMPARE(spyPublisherThreadFinished.size(), 1);
        QCOMPARE(spySubscriberThreadFinished.size(), 1);
    }
    catch (std::exception& ex)
    {
        QFAIL(ex.what());
    }
}
Exemple #21
0
bool navproCore::getStdDeviation(int rangeX, int rangeY, int *hue, int *sat, int *cb, int *cr)
{
    QColor hsv;
    int i,j;

    *hue = 0;
    *sat = 0;
    *cb  = 0;
    *cr  = 0;

    if (rangeX < 0 || rangeX > image.width()) return false;
    if (rangeY < 0 || rangeY > image.height()) return false;

    for (i = posX; i < rangeX + posX; ++i)
    {
        for (j = posY; j < rangeY + posY; ++j)
        {
            hsv = QColor::fromRgb(image.pixel(i,j));

            *hue += hsv.hue();
            *sat += hsv.saturation();

            *cb += RGB2CB(image.pixel(i,j));
            *cr += RGB2CR(image.pixel(i,j));
        }
    }

    //mean == average value
    int meanHue = *hue/(rangeX * rangeY); 
    int meanSat = *sat/(rangeX * rangeY); 
    int meanCb  = *cb/(rangeX * rangeY); 
    int meanCr  = *cr/(rangeX * rangeY); 

    //std::cout<<"mean: H: "<<meanHue<<" S: "<<meanSat<<" cb: "<<meanCb<<" cr: "<<meanCr<<std::endl;

    quint32 varianceHue = 0;
    quint32 varianceSat = 0;
    quint32 varianceCb  = 0;
    quint32 varianceCr  = 0;

    for (i = 0; i < rangeX; ++i)
    {
        for (j = 0; j < rangeY; ++j)
        {
            hsv = QColor::fromRgb(image.pixel(i,j));

            varianceHue += qAbs(meanHue - hsv.hue()) * qAbs(meanHue - hsv.hue());
            varianceSat += qAbs(meanSat - hsv.saturation()) * qAbs(meanSat - hsv.saturation());

            varianceCb  += qAbs(meanCb - RGB2CB(image.pixel(i,j))) * qAbs(meanHue - RGB2CB(image.pixel(i,j)));
            varianceCr  += qAbs(meanCr - RGB2CR(image.pixel(i,j))) * qAbs(meanHue - RGB2CR(image.pixel(i,j)));
        }
    }

    *hue = qSqrt(varianceHue/(rangeX * rangeY));
    *sat = qSqrt(varianceSat/(rangeX * rangeY));
    *cb = qSqrt(varianceCb/(rangeX * rangeY));
    *cr = qSqrt(varianceCr/(rangeX * rangeY));

    //std::cout<<"variance: H: "<<varianceHue<<" S: "<<varianceSat<<" cb: "<<varianceCb<<" cr: "<<varianceCr<<std::endl;
    //std::cout<<"SD: H: "<<*hue<<" S: "<<*sat<<" cb: "<<*cb<<" cr: "<<*cr<<std::endl;

    return true;
}
int KicadModule2Svg::drawDArc(const QString & ds, QString & arc) {
    //DA x0 y0 x1 y1 angle width layer

    QStringList params = ds.split(" ");
    if (params.count() < 8) return -1;

    int cx = params.at(1).toInt();
    int cy = params.at(2).toInt();
    int x2 = params.at(3).toInt();
    int y2 = params.at(4).toInt();
    int width = params.at(6).toInt();
    double diffAngle = (params.at(5).toInt() % 3600) / 10.0;
    double radius = qSqrt((cx - x2) * (cx - x2) + (cy - y2) * (cy - y2));
    double endAngle = asin((y2 - cy) / radius);
    if (x2 < cx) {
        endAngle += M_PI;
    }
    double startAngle = endAngle + (diffAngle * M_PI / 180.0);
    double x1 = (radius * cos(startAngle)) + cx;
    double y1 = (radius * sin(startAngle)) + cy;

    // TODO: figure out bounding box for circular arc and set min and max accordingly

    /*
    You have radius R, start angle S, end angle T, and I'll
    assume that the arc is swept counterclockwise from S to T.

    start.x = R * cos(S)
    start.y = R * sin(S)
    end.x = R * cos(T)
    end.y = R * sin(T)

    Determine the axis crossings by analyzing the start and
    end angles. For discussion sake, I'll describe angles
    using degrees. Provide a function, wrap(angle), that
    returns an angle in the range [0 to 360).

    cross0 = wrap(S) > wrap(T)
    cross90 = wrap(S-90) > wrap(T-90)
    cross180 = wrap(S-180) > wrap(T-180)
    cross270 = wrap(S-270) > wrap(T-270)

    Now the axis aligned bounding box is defined by:

    right = cross0 ? +R : max(start.x, end.x)
    top = cross90 ? +R : max(start.y, end.y)
    left = cross180 ? -R : min(start.x, end.x)
    bottom = cross270 ? -R : min(start.y, end.y)

    */


    checkXLimit(cx + radius);
    checkXLimit(cx - radius);
    checkYLimit(cy + radius);
    checkYLimit(cy - radius);

    int layer = params.at(7).toInt();

    arc = QString("<path stroke-width='%1' stroke='white' d='M%2,%3a%4,%5 0 %6,%7 %8,%9' fill='none' />")
          .arg(checkStrokeWidth(width / 2.0))
          .arg(x1)
          .arg(y1)
          .arg(radius)
          .arg(radius)
          .arg(qAbs(diffAngle) >= 180 ? 1 : 0)
          .arg(diffAngle > 0 ? 0 : 1)
          .arg(x2 - x1)
          .arg(y2 - y1);

    return layer;
}
Exemple #23
0
/*!
    Returns true if this sphere intersects \a plane; false otherwise.
*/
bool QSphere3D::intersects(const QPlane3D &plane) const
{
    return qAbs(plane.distanceTo(m_center)) <= m_radius;
}
Exemple #24
0
// QTBUG-36192, GetSystemMetrics(SM_CYSIZEFRAME) returns bogus values
// for MSVC2012 which leads to the custom margin having no effect since
// that only works when removing the entire margin.
static inline int getWindowBottomMargin()
{
    RECT rect = {0, 0, 0, 0};
    AdjustWindowRectEx(&rect, WS_POPUP | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_THICKFRAME | WS_DLGFRAME, FALSE, 0);
    return qAbs(rect.bottom);
}
Exemple #25
0
QList<Number> Gauss::findSolution(QList<QList<Number> > coefficients)
{
	int variablesCount = coefficients.size();
	int columnsCount = variablesCount + 1;
	int rowsCount = variablesCount;

	// Save initial order of variables.
	QList<int> orderOfVariables;
	for (int i = 0; i < variablesCount; ++i) {
		orderOfVariables << i;
	}


	// Direct pass

	for (int i = 0; i < rowsCount; ++i) {

		int mainElementIndex = i;
		Number mainElement = coefficients[i][i];

		// Find main element of the current row
		for (int j = i + 1; j < columnsCount - 1; ++j) {
			if (qAbs(mainElement) < qAbs(coefficients[i][j])) {
				mainElementIndex = j;
				mainElement = coefficients[i][j];
			}
		}

		if (MathUtils::isNull(mainElement)) {
			THROW(ENoSolution());
		}

		// Swap columns
		if (mainElementIndex != i) {
			swapColumns(coefficients, i, mainElementIndex);
			orderOfVariables.swap(i, mainElementIndex);
		}

		// Divide the row by the main element
		coefficients[i] = MathUtils::divideVectorByNumber(coefficients[i], mainElement);

		// Subtract current row (multiplied before) from rows below.
		for (int j = i + 1; j < rowsCount; ++j) {
			QList<Number> multipliedRow = MathUtils::multiplyVectorByNumber(coefficients[i], coefficients[j][i]);
			coefficients[j] = MathUtils::subtractVectorFromVector(coefficients[j], multipliedRow);
		}
	}


	// Reverse pass

	for (int i = rowsCount - 1; i >= 0; --i) {
		for (int j = i - 1; j >= 0; --j) {
			// subtract current row (multiplied before) from rows above.
			QList<Number> multipliedRow = MathUtils::multiplyVectorByNumber(coefficients[i], coefficients[j][i]);
			coefficients[j] = MathUtils::subtractVectorFromVector(coefficients[j], multipliedRow);
		}
	}


	// Form result

	QList<Number> result = sizedVector(variablesCount);
	for (int i = 0; i < rowsCount; ++i) {
		result[orderOfVariables[i]] = coefficients[i][columnsCount - 1];
	}
	return result;
}
Exemple #26
0
void KoTextShapeContainerModel::proposeMove(KoShape *child, QPointF &move)
{
    Relation *relation = d->children.value(child);
    if (relation == 0 || relation->anchor == 0)
        return;

    QPointF newPosition = child->position() + move;
    QRectF parentShapeRect(QPointF(0, 0), child->parent()->size());
//kDebug(32500) <<"proposeMove:" << move <<" |" << newPosition <<" |" << parentShapeRect;

    if (qAbs(newPosition.x()) < 10) // align left
        relation->anchor->setAlignment(KoTextAnchor::Left);
    else if (qAbs(parentShapeRect.width() - newPosition.x()) < 10.0)
        relation->anchor->setAlignment(KoTextAnchor::Right);
    else if (qAbs(parentShapeRect.width() / 2.0 - newPosition.x()) < 10.0)
        relation->anchor->setAlignment(KoTextAnchor::Center);
    /*else {
        relation->anchor->setAlignment(KoTextAnchor::HorizontalOffset);
        // TODO
        //QPointF offset = relation->anchor->offset();
        //offset.setX(offset.x() + move.x());
        //relation->anchor->setOffset(offset);
    } */

    if (qAbs(newPosition.y()) < 10.0) // TopOfFrame
    {
        kDebug(32500) <<"  TopOfFrame";
        relation->anchor->setAlignment(KoTextAnchor::TopOfFrame);
    } else if (qAbs(parentShapeRect.height() - newPosition.y()) < 10.0) {
        kDebug(32500) <<"  BottomOfFrame";
        relation->anchor->setAlignment(KoTextAnchor::BottomOfFrame); // TODO
    } else { // need layout info..
        QTextBlock block = relation->anchor->document()->findBlock(relation->anchor->positionInDocument());
        QTextLayout *layout = block.layout();
        if (layout->lineCount() > 0) {
            KoTextShapeData *data = dynamic_cast<KoTextShapeData*>(child->parent()->userData());
            Q_ASSERT(data);
            QTextLine tl = layout->lineAt(0);
            qreal y = tl.y() - data->documentOffset() - newPosition.y();
            if (y >= 0 && y < 10) {
                kDebug(32500) <<"  TopOfParagraph" << y <<"";
                relation->anchor->setAlignment(KoTextAnchor::TopOfParagraph);
            } else {
                tl = layout->lineAt(layout->lineCount() - 1);
                y = newPosition.y() - tl.y() - data->documentOffset() - tl.ascent();
                if (y >= 0 && y < 10) {
                    kDebug(32500) <<"  BottomOfParagraph" << y;
                    relation->anchor->setAlignment(KoTextAnchor::BottomOfParagraph); // TODO
                } else {
                    tl = layout->lineForTextPosition(relation->anchor->positionInDocument() - block.position());
                    y = tl.y() - data->documentOffset() - newPosition.y();
                    if (y >= 0 && y < 10) {
                        kDebug(32500) <<"  AboveCurrentLine";
                        relation->anchor->setAlignment(KoTextAnchor::AboveCurrentLine);
                    }
                    //else  do VerticalOffset here as well?
                }
            }
        }
    }

    move.setX(0); // let the text layout move it.
    move.setY(0);
}
Exemple #27
0
// --- Internal Methods ---------------------------------------------------- //
// Reads and returns the scalar field data from a .cube file.
chemkit::ScalarField* CubeViewerExample::readVolumeData(const QString &fileName) const
{
    QFile file(fileName);
    bool ok = file.open(QFile::ReadOnly);
    if(!ok){
        qDebug() << "Error: failed to read cube file: " << file.errorString();
        return 0;
    }

    // title line
    QString line = file.readLine();

    // comment line
    line = file.readLine();

    // atom count and origin coordinates line
    line = file.readLine();
    QStringList lineItems = line.split(" ", QString::SkipEmptyParts);
    if(lineItems.size() < 4){
        qDebug() << "Error: Cube file counts line too short.";
        return 0;
    }

    bool negativeAtomCount = false;
    int atomCount = lineItems[0].toInt();
    if(atomCount < 0){
        negativeAtomCount = true;
        atomCount = qAbs(atomCount);
    }

    chemkit::Point3 origin(lineItems[1].toDouble(),
                           lineItems[2].toDouble(),
                           lineItems[3].toDouble());

    // voxel count and axes
    std::vector<int> dimensions(3);
    std::vector<chemkit::Vector3f> axes(3);
    for(int i = 0; i < 3; i++){
        line = file.readLine();
        lineItems = line.split(" ", QString::SkipEmptyParts);

        if(lineItems.size() < 4){
            continue;
        }

        dimensions[i] = lineItems[0].toInt();
        axes[i] = chemkit::Vector3(lineItems[1].toDouble(),
                                   lineItems[2].toDouble(),
                                   lineItems[3].toDouble());
    }

    // read past atoms
    for(int i = 0; i < atomCount; i++){
        line = file.readLine();
    }

    // a negative atom count indicates that the next line will
    // contain the orbital count and orbital number
    int orbitalCount = 0;
    int orbitalNumber = 0;
    if(negativeAtomCount){
        line = file.readLine();
        lineItems = line.split(" ", QString::SkipEmptyParts);
        if(lineItems.size() >= 2){
            orbitalCount = lineItems[0].toInt();
            orbitalNumber = lineItems[1].toInt();
        }
    }

    // read volume data
    std::vector<chemkit::Float> volumeData;
    while(!file.atEnd()){
        line = file.readLine();
        lineItems = line.split(" ", QString::SkipEmptyParts);

        for(int i = 0; i < lineItems.size(); i++){
            volumeData.push_back(lineItems[i].toFloat());
        }
    }

    std::vector<chemkit::Float> cellLengths(3);
    for(int i = 0; i < 3; i++){
        cellLengths[i] = axes[i].length();
    }

    chemkit::ScalarField *scalarField = new chemkit::ScalarField(dimensions, cellLengths, volumeData);
    scalarField->setOrigin(origin);

    return scalarField;
}
Exemple #28
0
void BrushTool::drawStroke()
{
    StrokeTool::drawStroke();
    QList<QPointF> p = m_pStrokeManager->interpolateStroke(currentWidth);

    Layer *layer = m_pEditor->getCurrentLayer();

    if (layer->type == Layer::BITMAP)
    {
        for (int i = 0; i < p.size(); i++) {
            p[i] = m_pScribbleArea->pixelToPoint(p[i]);
        }

        qreal opacity = 1.0;
        qreal brushWidth = currentWidth +  0.5 * properties.feather;
        qreal offset = qMax(0.0, currentWidth - 0.5 * properties.feather) / brushWidth;
        opacity = currentPressure;
        brushWidth = brushWidth * currentPressure;

        //        if (tabletInUse) { opacity = tabletPressure; }
        //        if (usePressure) { brushWidth = brushWidth * tabletPressure; }

        qreal brushStep = 0.5 * currentWidth + 0.5 * properties.feather;
        brushStep = brushStep * currentPressure;

        //        if (usePressure) { brushStep = brushStep * tabletPressure; }
        brushStep = qMax(1.0, brushStep);

        currentWidth = properties.width;
        BlitRect rect;

        QRadialGradient radialGrad(QPointF(0,0), 0.5 * brushWidth);
        m_pScribbleArea->setGaussianGradient(radialGrad,
            m_pEditor->colorManager()->frontColor(),
            opacity,
            offset);

        QPointF a = lastBrushPoint;
        QPointF b = getCurrentPoint();

        //        foreach (QSegment segment, calculateStroke(brushWidth))
        //        {
        //            QPointF a = lastBrushPoint;
        //            QPointF b = m_pScribbleArea->pixelToPoint(segment.second);

        qreal distance = 4 * QLineF(b, a).length();
        int steps = qRound(distance) / brushStep;

        for (int i = 0; i < steps; i++)
        {
            QPointF point = lastBrushPoint + (i + 1) * (brushStep) * (b - lastBrushPoint) / distance;
            rect.extend(point.toPoint());
            m_pScribbleArea->drawBrush( point,
                brushWidth,
                offset,
                m_pEditor->colorManager()->frontColor(),
                opacity);

            if (i == (steps - 1))
            {
                lastBrushPoint = point;
            }
        }
        //        }

        int rad = qRound(brushWidth) / 2 + 2;
        m_pScribbleArea->refreshBitmap(rect, rad);
    }
    else if (layer->type == Layer::VECTOR)
    {
        QPen pen(Qt::gray, 1, Qt::DashLine, Qt::RoundCap, Qt::RoundJoin);
        int rad = qRound((currentWidth / 2 + 2) * qAbs(m_pScribbleArea->getTempViewScaleX()));

        //        foreach (QSegment segment, calculateStroke(currentWidth))
        //        {
        //            QPointF a = segment.first;
        //            QPointF b = segment.second;
        //            m_pScribbleArea->drawLine(a, b, pen, QPainter::CompositionMode_SourceOver);
        //            m_pScribbleArea->refreshVector(QRect(a.toPoint(), b.toPoint()), rad);
        //        }
        if (p.size() == 4) {
            QSizeF size(2,2);
            QPainterPath path(p[0]);
            path.cubicTo(p[1],
                p[2],
                p[3]);
            m_pScribbleArea->drawPath(path, pen, Qt::NoBrush, QPainter::CompositionMode_Source);
            m_pScribbleArea->refreshVector(path.boundingRect().toRect(), rad);
        }
    }
}
Exemple #29
0
void ObjWidget::paintEvent(QPaintEvent *event)
{
    if(graphicsViewMode_->isChecked())
    {
        QWidget::paintEvent(event);
    }
    else
    {
        if(!pixmap_.isNull())
        {
            //Scale
            float ratio, offsetX, offsetY;
            this->computeScaleOffsets(ratio, offsetX, offsetY);
            QPainter painter(this);

            if(mirrorView_->isChecked())
            {
                painter.translate(offsetX+pixmap_.width()*ratio, offsetY);
                painter.scale(-ratio, ratio);
            }
            else
            {
                painter.translate(offsetX, offsetY);
                painter.scale(ratio, ratio);
            }

            if(showImage_->isChecked())
            {
                painter.drawPixmap(QPoint(0,0), pixmap_);
            }

            if(showFeatures_->isChecked())
            {
                //drawKeypoints(&painter);
            }

            for(int i=0; i<rectItems_.size(); ++i)
            {
                painter.save();
                painter.setTransform(rectItems_.at(i)->transform(), true);
                painter.setPen(rectItems_.at(i)->pen());
                painter.drawRect(rectItems_.at(i)->rect());
                painter.restore();
            }

            if(mouseCurrentPos_ != mousePressedPos_)
            {
                painter.save();
                int left, top, right, bottom;
                left = mousePressedPos_.x() < mouseCurrentPos_.x() ? mousePressedPos_.x():mouseCurrentPos_.x();
                top = mousePressedPos_.y() < mouseCurrentPos_.y() ? mousePressedPos_.y():mouseCurrentPos_.y();
                right = mousePressedPos_.x() > mouseCurrentPos_.x() ? mousePressedPos_.x():mouseCurrentPos_.x();
                bottom = mousePressedPos_.y() > mouseCurrentPos_.y() ? mousePressedPos_.y():mouseCurrentPos_.y();
                if(mirrorView_->isChecked())
                {
                    int l = left;
                    left = qAbs(right - pixmap_.width());
                    right = qAbs(l - pixmap_.width());
                }
                painter.setPen(Qt::NoPen);
                painter.setBrush(QBrush(QColor(0,0,0,100)));
                painter.drawRect(0, 0, pixmap_.width(), top-1);
                painter.drawRect(0, top, left, bottom-top);
                painter.drawRect(right, top, pixmap_.width()-right, bottom-top);
                painter.drawRect(0, bottom, pixmap_.width(), pixmap_.height()-bottom);
                painter.restore();
            }
        }
    }
}
Exemple #30
0
void EffectWidgetPrivate::autogenerateUi()
{
    Q_Q(EffectWidget);
    QVBoxLayout *mainLayout = new QVBoxLayout(q);
    mainLayout->setMargin(0);
    foreach (const EffectParameter &para, effect->parameters()) {
        QVariant value = effect->parameterValue(para);
        QHBoxLayout *pLayout = new QHBoxLayout;
        mainLayout->addLayout(pLayout);

        QLabel *label = new QLabel(q);
        pLayout->addWidget(label);
        label->setText(para.name());
#ifndef QT_NO_TOOLTIP
        label->setToolTip(para.description());
#endif

        QWidget *control = 0;
        switch (para.type()) {
        case QVariant::String:
            {
                QComboBox *cb = new QComboBox(q);
                control = cb;
                if (value.type() == QVariant::Int) {
                    //value just defines the item index
                    foreach (const QVariant &item, para.possibleValues()) {
                        cb->addItem(item.toString());
                    }
                    cb->setCurrentIndex(value.toInt());
                    QObject::connect(cb, SIGNAL(currentIndexChanged(int)), q, SLOT(_k_setIntParameter(int)));
                } else {
                    foreach (const QVariant &item, para.possibleValues()) {
                        cb->addItem(item.toString());
                        if (item == value) {
                            cb->setCurrentIndex(cb->count() - 1);
                        }
                    }
                    QObject::connect(cb, SIGNAL(currentIndexChanged(QString)), q, SLOT(_k_setStringParameter(QString)));
                }
            }
            break;
        case QVariant::Bool:
            {
                QCheckBox *cb = new QCheckBox(q);
                control = cb;
                cb->setChecked(value.toBool());
                QObject::connect(cb, SIGNAL(toggled(bool)), q, SLOT(_k_setToggleParameter(bool)));
            }
            break;
        case QVariant::Int:
            {
                QSpinBox *sb = new QSpinBox(q);
                control = sb;
                bool minValueOk = false;
                bool maxValueOk = false;
                const int minValue = para.minimumValue().toInt(&minValueOk);
                const int maxValue = para.minimumValue().toInt(&maxValueOk);

                sb->setRange(minValueOk ? minValue : DEFAULT_MIN_INT, maxValueOk ? maxValue : DEFAULT_MAX_INT);
                sb->setValue(value.toInt());
                QObject::connect(sb, SIGNAL(valueChanged(int)), q, SLOT(_k_setIntParameter(int)));
            }
            break;
        case QVariant::Double:
            {
                const double minValue = (para.minimumValue().type() == QVariant::Double ?
                    para.minimumValue().toDouble() : DEFAULT_MIN);
                const double maxValue = (para.maximumValue().type() == QVariant::Double ?
                    para.maximumValue().toDouble() : DEFAULT_MAX);

                if (minValue == -1. && maxValue == 1.) {
                    //Special case values between -1 and 1.0 to use a slider for improved usability
                    QSlider *slider = new QSlider(Qt::Horizontal, q);
                    slider->setRange(-SLIDER_RANGE, +SLIDER_RANGE);
                    slider->setValue(int(SLIDER_RANGE * value.toDouble()));
                    slider->setTickPosition(QSlider::TicksBelow);
                    slider->setTickInterval(TICKINTERVAL);
                    QObject::connect(slider, SIGNAL(valueChanged(int)), q, SLOT(_k_setSliderParameter(int)));
                } else {
                    double step = 0.1;
                    if (qAbs(maxValue - minValue) > 50)
                        step = 1.0;
                    QDoubleSpinBox *sb = new QDoubleSpinBox(q);
                    control = sb;
                    sb->setRange(minValue, maxValue);
                    sb->setValue(value.toDouble());
                    sb->setSingleStep(step);
                    QObject::connect(sb, SIGNAL(valueChanged(double)), q,
                        SLOT(_k_setDoubleParameter(double)));
                }
            }
            break;
        default:
            break;
        }