Skip to content

Commit

Permalink
Merge pull request #9425 from 3nids/scope_base_enum
Browse files Browse the repository at this point in the history
Scope based enum
  • Loading branch information
3nids committed Mar 8, 2019
2 parents 237e13c + 1281bcc commit d0fceef
Show file tree
Hide file tree
Showing 7 changed files with 57 additions and 22 deletions.
9 changes: 9 additions & 0 deletions python/gui/auto_additions/qgsadvanceddigitizingdockwidget.py
@@ -1,3 +1,12 @@
# The following has been generated automatically from src/gui/qgsadvanceddigitizingdockwidget.h
QgsAdvancedDigitizingDockWidget.CadCapacities.baseClass = QgsAdvancedDigitizingDockWidget
CadCapacities = QgsAdvancedDigitizingDockWidget # dirty hack since SIP seems to introduce the flags in module
# monkey patching scoped based enum
QgsAdvancedDigitizingDockWidget.AdditionalConstraint.NoConstraint.__doc__ = "No additional constraint"
QgsAdvancedDigitizingDockWidget.NoConstraint = QgsAdvancedDigitizingDockWidget.AdditionalConstraint.NoConstraint
QgsAdvancedDigitizingDockWidget.AdditionalConstraint.Perpendicular.__doc__ = "Perpendicular"
QgsAdvancedDigitizingDockWidget.Perpendicular = QgsAdvancedDigitizingDockWidget.AdditionalConstraint.Perpendicular
QgsAdvancedDigitizingDockWidget.AdditionalConstraint.Parallel.__doc__ = "Parallel"
QgsAdvancedDigitizingDockWidget.Parallel = QgsAdvancedDigitizingDockWidget.AdditionalConstraint.Parallel
QgsAdvancedDigitizingDockWidget.AdditionalConstraint.__doc__ = 'Additional constraints which can be enabled\n' + '* NoConstraint: ' + QgsAdvancedDigitizingDockWidget.AdditionalConstraint.NoConstraint.__doc__ + '\n' + '* Perpendicular: ' + QgsAdvancedDigitizingDockWidget.AdditionalConstraint.Perpendicular.__doc__ + '\n' + '* Parallel: ' + QgsAdvancedDigitizingDockWidget.AdditionalConstraint.Parallel.__doc__
# --
Expand Up @@ -35,13 +35,14 @@ by implementing filters called from QgsMapToolAdvancedDigitizing.
typedef QFlags<QgsAdvancedDigitizingDockWidget::CadCapacity> CadCapacities;


enum AdditionalConstraint
enum class AdditionalConstraint
{
NoConstraint,
Perpendicular,
Parallel
};


class CadConstraint
{
%Docstring
Expand Down
22 changes: 19 additions & 3 deletions scripts/sipify.pl
Expand Up @@ -950,8 +950,16 @@ sub detect_non_method_member{
}

# Enum declaration
if ( $LINE =~ m/^\s*enum\s+\w+.*?$/ ){
write_output("ENU1", "$LINE\n");
# For scoped and type based enum, the type has to be removed
if ( $LINE =~ m/^(\s*enum\s+(class\s+)?(\w+))(:?\s+SIP_.*)?(\s*:\s*\w+)?(?<oneliner>.*)$/ ){
write_output("ENU1", "$1");
write_output("ENU1", $+{oneliner}) if defined $+{oneliner};
write_output("ENU1", "\n");
my $enum_qualname = $3;
my $is_scope_based = "0";
$is_scope_based = "1" if defined $2;
my $monkeypatch = "0";
$monkeypatch = "1" if defined $is_scope_based eq "1" and $LINE =~ m/SIP_MONKEYPATCH_SCOPEENUM/;
if ($LINE =~ m/\{((\s*\w+)(\s*=\s*[\w\s\d<|]+.*?)?(,?))+\s*\}/){
# one line declaration
$LINE !~ m/=/ or exit_with_error("spify.pl does not handle enum one liners with value assignment. Use multiple lines instead.");
Expand All @@ -962,6 +970,8 @@ sub detect_non_method_member{
$LINE = read_line();
$LINE =~ m/^\s*\{\s*$/ or exit_with_error('Unexpected content: enum should be followed by {');
write_output("ENU2", "$LINE\n");
push @OUTPUT_PYTHON, "# monkey patching scoped based enum\n" if $is_scope_based eq "1";
my @enum_members_doc = ();
while ($LINE_IDX < $LINE_COUNT){
$LINE = read_line();
if (detect_comment_block()){
Expand All @@ -971,13 +981,19 @@ sub detect_non_method_member{
next if ($LINE =~ m/^\s*\w+\s*\|/); # multi line declaration as sum of enums

do {no warnings 'uninitialized';
my $enum_decl = $LINE =~ s/^(\s*\w+)(\s+SIP_\w+(?:\([^()]+\))?)?(?:\s*=\s*(?:[\w\s\d|+-]|::|<<)+)?(,?).*$/$1$2$3/r;
my $enum_decl = $LINE =~ s/^(\s*(?<em>\w+))(\s+SIP_\w+(?:\([^()]+\))?)?(?:\s*=\s*(?:[\w\s\d|+-]|::|<<)+)?(,?)(:?\s*\/\/!<\s*(?<co>.*)|.*)$/$1$3$4/r;
my $enum_member = $+{em};
push @enum_members_doc, "'* $enum_member: ' + $ACTUAL_CLASS.$enum_qualname.$2.__doc__";
my $comment = $+{co};
push @OUTPUT_PYTHON, "$ACTUAL_CLASS.$enum_qualname.$enum_member.__doc__ = \"$comment\"\n" if $is_scope_based eq "1";
push @OUTPUT_PYTHON, "$ACTUAL_CLASS.$enum_member = $ACTUAL_CLASS.$enum_qualname.$enum_member\n" if $monkeypatch eq "1";
$enum_decl = fix_annotations($enum_decl);
write_output("ENU3", "$enum_decl\n");
};
detect_comment_block(strict_mode => UNSTRICT);
}
write_output("ENU4", "$LINE\n");
push @OUTPUT_PYTHON, "$ACTUAL_CLASS.$enum_qualname.__doc__ = '$COMMENT\\n' + " . join(" + '\\n' + ", @enum_members_doc) . "\n# --\n" if $is_scope_based eq "1";
# enums don't have Docstring apparently
$COMMENT = '';
next;
Expand Down
8 changes: 8 additions & 0 deletions src/core/qgis_sip.h
Expand Up @@ -232,4 +232,12 @@
#define SIP_PYTHON_SPECIAL_BOOL(method_or_code)
#define SIP_PYTHON_SPECIAL_REPR(method_or_code)

/*
* If one reformat an enum to a scope based enum
* sipify will take care of monkey patching to keep
* API compatibility
*/
#define SIP_MONKEYPATCH_SCOPEENUM


#endif // QGIS_SIP_H
4 changes: 2 additions & 2 deletions src/gui/qgsadvanceddigitizingcanvasitem.cpp
Expand Up @@ -116,7 +116,7 @@ void QgsAdvancedDigitizingCanvasItem::paint( QPainter *painter )
}

// Draw segment par/per input
if ( mAdvancedDigitizingDockWidget->additionalConstraint() != QgsAdvancedDigitizingDockWidget::NoConstraint && hasSnappedSegment )
if ( mAdvancedDigitizingDockWidget->additionalConstraint() != QgsAdvancedDigitizingDockWidget::AdditionalConstraint::NoConstraint && hasSnappedSegment )
{
painter->setPen( mConstruction2Pen );
painter->drawLine( snapSegmentPix1, snapSegmentPix2 );
Expand Down Expand Up @@ -230,7 +230,7 @@ void QgsAdvancedDigitizingCanvasItem::paint( QPainter *painter )
}

// Draw constr
if ( mAdvancedDigitizingDockWidget->additionalConstraint() == QgsAdvancedDigitizingDockWidget::NoConstraint )
if ( mAdvancedDigitizingDockWidget->additionalConstraint() == QgsAdvancedDigitizingDockWidget::AdditionalConstraint::NoConstraint )
{
if ( curPointExist && previousPointExist )
{
Expand Down
30 changes: 15 additions & 15 deletions src/gui/qgsadvanceddigitizingdockwidget.cpp
Expand Up @@ -48,7 +48,7 @@ QgsAdvancedDigitizingDockWidget::QgsAdvancedDigitizingDockWidget( QgsMapCanvas *
mDistanceConstraint.reset( new CadConstraint( mDistanceLineEdit, mLockDistanceButton, nullptr, mRepeatingLockDistanceButton ) );
mXConstraint.reset( new CadConstraint( mXLineEdit, mLockXButton, mRelativeXButton, mRepeatingLockXButton ) );
mYConstraint.reset( new CadConstraint( mYLineEdit, mLockYButton, mRelativeYButton, mRepeatingLockYButton ) );
mAdditionalConstraint = NoConstraint;
mAdditionalConstraint = AdditionalConstraint::NoConstraint;

mMapCanvas->installEventFilter( this );
mAngleLineEdit->installEventFilter( this );
Expand Down Expand Up @@ -187,15 +187,15 @@ void QgsAdvancedDigitizingDockWidget::additionalConstraintClicked( bool activate
{
if ( !activated )
{
lockAdditionalConstraint( NoConstraint );
lockAdditionalConstraint( AdditionalConstraint::NoConstraint );
}
if ( sender() == mParallelAction )
{
lockAdditionalConstraint( Parallel );
lockAdditionalConstraint( AdditionalConstraint::Parallel );
}
else if ( sender() == mPerpendicularAction )
{
lockAdditionalConstraint( Perpendicular );
lockAdditionalConstraint( AdditionalConstraint::Perpendicular );
}
}

Expand Down Expand Up @@ -258,7 +258,7 @@ void QgsAdvancedDigitizingDockWidget::releaseLocks( bool releaseRepeatingLocks )
{
// release all locks except construction mode

lockAdditionalConstraint( NoConstraint );
lockAdditionalConstraint( AdditionalConstraint::NoConstraint );

if ( releaseRepeatingLocks || !mAngleConstraint->isRepeatingLock() )
mAngleConstraint->setLockMode( CadConstraint::NoLock );
Expand Down Expand Up @@ -380,7 +380,7 @@ void QgsAdvancedDigitizingDockWidget::lockConstraint( bool activate /* default t
// deactivate perpendicular/parallel if angle has been activated
if ( constraint == mAngleConstraint.get() )
{
lockAdditionalConstraint( NoConstraint );
lockAdditionalConstraint( AdditionalConstraint::NoConstraint );
}

// run a fake map mouse event to update the paint item
Expand Down Expand Up @@ -417,8 +417,8 @@ void QgsAdvancedDigitizingDockWidget::constraintFocusOut()
void QgsAdvancedDigitizingDockWidget::lockAdditionalConstraint( AdditionalConstraint constraint )
{
mAdditionalConstraint = constraint;
mPerpendicularAction->setChecked( constraint == Perpendicular );
mParallelAction->setChecked( constraint == Parallel );
mPerpendicularAction->setChecked( constraint == AdditionalConstraint::Perpendicular );
mParallelAction->setChecked( constraint == AdditionalConstraint::Parallel );
}

void QgsAdvancedDigitizingDockWidget::updateCapacity( bool updateUIwithoutChange )
Expand Down Expand Up @@ -465,7 +465,7 @@ void QgsAdvancedDigitizingDockWidget::updateCapacity( bool updateUIwithoutChange

if ( !absoluteAngle )
{
lockAdditionalConstraint( NoConstraint );
lockAdditionalConstraint( AdditionalConstraint::NoConstraint );
}

// absolute angle = azimuth, relative = from previous line
Expand Down Expand Up @@ -663,7 +663,7 @@ QList<QgsPointXY> QgsAdvancedDigitizingDockWidget::snapSegmentToAllLayers( const

bool QgsAdvancedDigitizingDockWidget::alignToSegment( QgsMapMouseEvent *e, CadConstraint::LockMode lockMode )
{
if ( mAdditionalConstraint == NoConstraint )
if ( mAdditionalConstraint == AdditionalConstraint::NoConstraint )
{
return false;
}
Expand All @@ -685,7 +685,7 @@ bool QgsAdvancedDigitizingDockWidget::alignToSegment( QgsMapMouseEvent *e, CadCo
angle -= std::atan2( previousPt.y() - penultimatePt.y(), previousPt.x() - penultimatePt.x() );
}

if ( mAdditionalConstraint == Perpendicular )
if ( mAdditionalConstraint == AdditionalConstraint::Perpendicular )
{
angle += M_PI_2;
}
Expand All @@ -696,7 +696,7 @@ bool QgsAdvancedDigitizingDockWidget::alignToSegment( QgsMapMouseEvent *e, CadCo
mAngleConstraint->setLockMode( lockMode );
if ( lockMode == CadConstraint::HardLock )
{
mAdditionalConstraint = NoConstraint;
mAdditionalConstraint = AdditionalConstraint::NoConstraint;
}

return true;
Expand Down Expand Up @@ -931,15 +931,15 @@ bool QgsAdvancedDigitizingDockWidget::filterKeyPress( QKeyEvent *e )

if ( !parallel && !perpendicular )
{
lockAdditionalConstraint( Perpendicular );
lockAdditionalConstraint( AdditionalConstraint::Perpendicular );
}
else if ( perpendicular )
{
lockAdditionalConstraint( Parallel );
lockAdditionalConstraint( AdditionalConstraint::Parallel );
}
else
{
lockAdditionalConstraint( NoConstraint );
lockAdditionalConstraint( AdditionalConstraint::NoConstraint );
}
e->accept();
}
Expand Down
3 changes: 2 additions & 1 deletion src/gui/qgsadvanceddigitizingdockwidget.h
Expand Up @@ -65,13 +65,14 @@ class GUI_EXPORT QgsAdvancedDigitizingDockWidget : public QgsDockWidget, private
/**
* Additional constraints which can be enabled
*/
enum AdditionalConstraint
enum class AdditionalConstraint SIP_MONKEYPATCH_SCOPEENUM : int
{
NoConstraint, //!< No additional constraint
Perpendicular, //!< Perpendicular
Parallel //!< Parallel
};


/**
* \ingroup gui
* \brief The CadConstraint is an abstract class for all basic constraints (angle/distance/x/y).
Expand Down

0 comments on commit d0fceef

Please sign in to comment.