Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added 'Revision Issue' component. #1112

Merged
merged 1 commit into from
May 3, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions docs/pages/_en/1.0/reference/release-notes.md
Original file line number Diff line number Diff line change
@@ -12,6 +12,8 @@ group: Deployment & Configs

### RC

- Added 'Issue Revision' component.

{% endcapture %}
{% include ltr/release_header_next.html title="Upcoming Changes" note=rc_release_notes %}

165 changes: 137 additions & 28 deletions src/RhinoInside.Revit.GH/Components/Sheets/AddRevision.cs
Original file line number Diff line number Diff line change
@@ -5,7 +5,7 @@

namespace RhinoInside.Revit.GH.Components.Sheets
{
[ComponentVersion(introduced: "1.8")]
[ComponentVersion(introduced: "1.8", updated: "1.21")]
public class AddRevision : ElementTrackerComponent
{
public override Guid ComponentGuid => new Guid("221E53A6-54A2-45FB-82B1-220D6E5BE884");
@@ -56,16 +56,6 @@ public AddRevision() : base
}, ParamRelevance.Primary
),
new ParamDefinition
(
new Param_Boolean()
{
Name = "Issued",
NickName = "I",
Description = "Indicates whether this revision has been issued.",
Optional = true
}, ParamRelevance.Secondary
),
new ParamDefinition
(
new Param_String()
{
@@ -85,6 +75,16 @@ public AddRevision() : base
Optional = true
}, ParamRelevance.Secondary
),
new ParamDefinition
(
new Param_Boolean()
{
Name = "Issued",
NickName = "I",
Description = "Indicates whether this revision has been issued.",
Optional = true
}, ParamRelevance.Secondary
),
};

protected override ParamDefinition[] Outputs => outputs;
@@ -106,7 +106,7 @@ public AddRevision() : base
Name = "Revision Number",
NickName = "RN",
Description = "Revision number.",
}, ParamRelevance.Primary
}, ParamRelevance.Secondary
),
new ParamDefinition
(
@@ -132,18 +132,18 @@ protected override void TrySolveInstance(IGH_DataAccess DA)
// Input
if (!Params.TryGetData(DA, "Revision Date", out string date)) return null;
if (!Params.TryGetData(DA, "Revision Description", out string description)) return null;
if (!Params.TryGetData(DA, "Issued", out bool? issued)) return null;
if (!Params.TryGetData(DA, "Issued by", out string issuedBy)) return null;
if (!Params.TryGetData(DA, "Issued to", out string issuedTo)) return null;
if (!Params.TryGetData(DA, "Issued", out bool? issued)) return null;

// Compute
revision = Reconstruct
(
revision,
doc.Value,
description, date,
issued,
issuedBy, issuedTo,
issued,
ARDB.RevisionVisibility.CloudAndTagVisible
);

@@ -161,34 +161,143 @@ ARDB.Revision Reconstruct
ARDB.Document document,
string description,
string date,
bool? issued,
string issuedBy,
string issuedTo,
bool? issued,
ARDB.RevisionVisibility? visibility
)
{
if (revision is null)
revision = ARDB.Revision.Create(document);

if (description is object && description != revision.Description)
revision.Description = description;
RevisionIssue.Invoke(this, revision, description, date, issuedBy, issuedTo, issued);

if (date is object && date != revision.RevisionDate)
revision.RevisionDate = date;
if (visibility is object && visibility.Value != revision.Visibility)
revision.Visibility = visibility.Value;

if (issued is object && issued.Value != revision.Issued)
revision.Issued = issued.Value;
return revision;
}
}

if (issuedBy is object && issuedBy != revision.IssuedBy)
revision.IssuedBy = issuedBy;
[ComponentVersion(introduced: "1.21")]
public class RevisionIssue : TransactionalChainComponent
{
public override Guid ComponentGuid => new Guid("504CB82C-FA96-4506-8F3B-6ADE2DFFF6F0");
public override GH_Exposure Exposure => GH_Exposure.quarternary;

if (issuedTo is object && issuedTo != revision.IssuedTo)
revision.IssuedTo = issuedTo;
public RevisionIssue()
: base
(
name: "Revision Issue",
nickname: "R-Issue",
description: "Get-Set revision issue status.",
category: "Revit",
subCategory: "View"
)
{ }

if (visibility is object && visibility.Value != revision.Visibility)
revision.Visibility = visibility.Value;
protected override ParamDefinition[] Inputs => inputs;
static readonly ParamDefinition[] inputs =
{
ParamDefinition.Create<Parameters.Revision>("Revision", "R"),

return revision;
ParamDefinition.Create<Param_String>("Revision Date", "RD", optional: true, relevance: ParamRelevance.Primary),
ParamDefinition.Create<Param_String>("Revision Description", "RDN", optional: true, relevance: ParamRelevance.Primary),

ParamDefinition.Create<Param_String>("Issued By", "IB", optional: true, relevance: ParamRelevance.Primary),
ParamDefinition.Create<Param_String>("Issued To", "IT", optional: true, relevance: ParamRelevance.Primary),
ParamDefinition.Create<Param_Boolean>("Issued", "I", optional: true, relevance: ParamRelevance.Primary),
};

protected override ParamDefinition[] Outputs => outputs;
static readonly ParamDefinition[] outputs =
{
ParamDefinition.Create<Parameters.Revision>("Revision", "R", relevance: ParamRelevance.Occasional),

ParamDefinition.Create<Param_String>("Revision Date", "RD", relevance: ParamRelevance.Primary),
ParamDefinition.Create<Param_String>("Revision Description", "RDN", relevance: ParamRelevance.Primary),

ParamDefinition.Create<Param_String>("Issued By", "IB", relevance: ParamRelevance.Primary),
ParamDefinition.Create<Param_String>("Issued To", "IT", relevance: ParamRelevance.Primary),
ParamDefinition.Create<Param_Boolean>("Issued", "I", relevance: ParamRelevance.Primary),
};

protected override void TrySolveInstance(IGH_DataAccess DA)
{
if (!Params.GetData(DA, "Revision", out Types.Revision revision, x => x.IsValid))
return;

bool update = false;
update |= Params.GetData(DA, "Revision Date", out string date);
update |= Params.GetData(DA, "Revision Description", out string description);
update |= Params.GetData(DA, "Issued By", out string issuedBy);
update |= Params.GetData(DA, "Issued To", out string issuedTo);
update |= Params.GetData(DA, "Issued", out bool? issued);

if (update) Invoke(this, revision.Value, date, description, issuedBy, issuedTo, issued);

Params.TrySetData(DA, "Revision", () => revision);

Params.TrySetData(DA, "Revision Date", () => revision.RevisionDate);
Params.TrySetData(DA, "Revision Description", () => revision.Description);

Params.TrySetData(DA, "Issued By", () => revision.IssuedBy);
Params.TrySetData(DA, "Issued To", () => revision.IssuedTo);
Params.TrySetData(DA, "Issued", () => revision.Issued);
}

internal static void Invoke(TransactionalChainComponent component, ARDB.Revision revision, string date, string description, string issuedBy, string issuedTo, bool? issued)
{
var updateDate = date is object && revision.RevisionDate != date;
var updateDescription = description is object && revision.Description != description;
var updateIssuedBy = issuedBy is object && revision.IssuedBy != issuedBy;
var updateIssuedTo = issuedTo is object && revision.IssuedTo != issuedTo;
var updateIssued = issued is object && revision.Issued != issued;

if (updateDate || updateDescription || updateIssuedBy || updateIssuedTo || updateIssued)
{
component.StartTransaction(revision.Document);

issued = issued ?? revision.Issued;
if (issued is false && revision.Issued) revision.Issued = false;

if (revision.Issued)
{
switch (component.FailureProcessingMode)
{
case ARDB.FailureProcessingResult.Continue:
if (updateDate) component.AddContinuableFailure($"Can't set 'Revision Date' parameter. Revision '{revision.Description}' is already issued. {{{revision.Id}}}");
if (updateDescription) component.AddContinuableFailure($"Can't set 'Revision Description' parameter. Revision '{revision.Description}' is already issued. {{{revision.Id}}}");
if (updateIssuedBy) component.AddContinuableFailure($"Can't set 'Issued By' parameter. Revision '{revision.Description}' is already issued. {{{revision.Id}}}");
if (updateIssuedTo) component.AddContinuableFailure($"Can't set 'Issued To' parameter. Revision '{revision.Description}' is already issued. {{{revision.Id}}}");
return;

case ARDB.FailureProcessingResult.ProceedWithCommit:
revision.Issued = false;
issued = true;
updateIssued = true;
component.AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, $"Updating the already issued revision '{revision.Description}'. {{{revision.Id}}}");
break;

case ARDB.FailureProcessingResult.WaitForUserInput:
using (var failure = new ARDB.FailureMessage(ARDB.BuiltInFailures.GeneralFailures.CannotSetParameter))
{
failure.SetFailingElement(revision.Id);
revision.Document.PostFailure(failure);
}
break;

default:
throw new Exceptions.RuntimeException($"Can't set the parameter. Revision '{revision.Description}' is already issued. {{{revision.Id}}}");
}
}
if (updateDate) revision.RevisionDate = date;
if (updateDescription) revision.Description = description;
if (updateIssuedBy) revision.IssuedBy = issuedBy;
if (updateIssuedTo) revision.IssuedTo = issuedTo;
if (updateIssued) revision.Issued = issued.Value;
}
}
}

}
45 changes: 39 additions & 6 deletions src/RhinoInside.Revit.GH/Components/TransactionalComponent.cs
Original file line number Diff line number Diff line change
@@ -19,6 +19,7 @@ namespace RhinoInside.Revit.GH.Components
using Convert.Geometry;
using ElementTracking;
using External.DB.Extensions;
using Grasshopper.GUI;

class TransactionalComponentFailuresPreprocessor : ARDB.IFailuresPreprocessor
{
@@ -267,9 +268,31 @@ protected ARDB.TransactionStatus CommitTransaction(ARDB.Document doc, ARDB.Trans
#endregion

#region Attributes
internal new class Attributes : ZuiAttributes
internal class TransactionalComponentAttributes : ExpireButtonAttributes
{
public Attributes(TransactionalComponent owner) : base(owner) { }
public TransactionalComponentAttributes(TransactionalComponent owner) : base(owner) { }
private new TransactionalChainComponent Owner => (TransactionalChainComponent) base.Owner;

internal static string IssuePrefix => "⏯";

protected override bool Top => true;
protected override string DisplayText => "✅ Continue";
protected override bool Visible => Owner.RuntimeMessageLevel == GH_RuntimeMessageLevel.Error &&
Owner.RuntimeMessages(GH_RuntimeMessageLevel.Error).Any(x => x.StartsWith(IssuePrefix));

public override void SetupTooltip(PointF canvasPoint, GH_TooltipDisplayEventArgs e)
{
if (Visible && ButtonBounds.Contains(new Point((int) Math.Round(canvasPoint.X), (int) Math.Round(canvasPoint.Y))))
{
e.Title = "Continue";
e.Icon = Owner.Icon_24x24;
e.Description = "If you don't want to be asked again set component 'Error Mode' to 'Continue'.";
e.Text = $"If suitable, a default resolution will be applied.";
return;
}

base.SetupTooltip(canvasPoint, e);
}

protected override void Render(GH_Canvas canvas, Graphics graphics, GH_CanvasChannel channel)
{
@@ -325,7 +348,12 @@ protected override void Render(GH_Canvas canvas, Graphics graphics, GH_CanvasCha
}
}

public override void CreateAttributes() => m_attributes = new Attributes(this);
public override void CreateAttributes() => m_attributes = new TransactionalComponentAttributes(this);

protected internal void AddContinuableFailure(string message)
{
AddRuntimeMessage(GH_RuntimeMessageLevel.Error, $"{TransactionalComponentAttributes.IssuePrefix} {message}");
}
#endregion

// Setp 1.
@@ -341,7 +369,12 @@ protected override void Render(GH_Canvas canvas, Graphics graphics, GH_CanvasCha
// Override to add handled failures to your component (Order is important).
protected virtual IEnumerable<ARDB.FailureDefinitionId> FailureDefinitionIdsToFix => null;

public ARDB.FailureProcessingResult FailureProcessingMode { get; set; } = ARDB.FailureProcessingResult.Continue;
ARDB.FailureProcessingResult _FailureProcessingMode = ARDB.FailureProcessingResult.Continue;
public ARDB.FailureProcessingResult FailureProcessingMode
{
get => (Attributes as TransactionalComponentAttributes).Pressed ? ARDB.FailureProcessingResult.ProceedWithCommit : _FailureProcessingMode;
set => _FailureProcessingMode = value;
}

protected override bool AbortOnContinuableException => FailureProcessingMode > ARDB.FailureProcessingResult.ProceedWithCommit;

@@ -937,13 +970,13 @@ protected T PostNomenAlreadyInUse<T>(T existing)

if (FailureProcessingMode == ARDB.FailureProcessingResult.Continue)
{
AddRuntimeMessage(GH_RuntimeMessageLevel.Error, $"{message}\nSet 'Error Mode' to 'Continue' to use the existing one.");
AddRuntimeMessage(GH_RuntimeMessageLevel.Error, $"{TransactionalComponentAttributes.IssuePrefix} {message}\nUse 'Continue' to reference the existing one.");
return null;
}

if (FailureProcessingMode == ARDB.FailureProcessingResult.ProceedWithCommit)
{
AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, $"{message}\nUsing existing.");
AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, $"{message} Using already existing one.");
return existing;
}

25 changes: 19 additions & 6 deletions src/RhinoInside.Revit.GH/Components/ZuiComponent.cs
Original file line number Diff line number Diff line change
@@ -524,10 +524,11 @@ public override void SetupTooltip(PointF canvasPoint, GH_TooltipDisplayEventArgs

internal abstract class ExpireButtonAttributes : ZuiAttributes
{
Rectangle ButtonBounds { get; set; }
protected Rectangle ButtonBounds { get; private set; }

public bool Pressed { get; private set; } = false;

protected virtual bool Top { get; }
protected abstract string DisplayText { get; }
protected abstract bool Visible { get; }

@@ -540,10 +541,19 @@ protected override void Layout()
if (Visible)
{
var newBounds = GH_Convert.ToRectangle(Bounds);
newBounds.Height += 22;

var buttonBounds = newBounds;
buttonBounds.Y = buttonBounds.Bottom - 22;

if (Top)
{
newBounds.Y -= 22;
newBounds.Height += 22;
buttonBounds.Y = newBounds.Top;
}
else
{
buttonBounds.Y = newBounds.Bottom;
newBounds.Height += 22;
}
buttonBounds.Height = 22;
buttonBounds.Inflate(-2, -2);

@@ -583,9 +593,12 @@ public override GH_ObjectResponse RespondToMouseUp(GH_Canvas sender, GH_CanvasMo
}
Owner.ExpireSolution(true);
}
else
{
Pressed = false;
sender.Refresh();
}

Pressed = false;
sender.Refresh();
return GH_ObjectResponse.Release;
}

32 changes: 32 additions & 0 deletions src/RhinoInside.Revit.GH/Types/Annotations/Revision.cs
Original file line number Diff line number Diff line change
@@ -11,5 +11,37 @@ public class Revision : Element

public Revision() { }
public Revision(ARDB.Revision element) : base(element) { }

public string RevisionNumber => Value?.get_Parameter(ARDB.BuiltInParameter.PROJECT_REVISION_REVISION_NUM)?.AsString();
public int? SequenceNumber => Value?.get_Parameter(ARDB.BuiltInParameter.PROJECT_REVISION_SEQUENCE_NUM)?.AsInteger();

public string Description
{
get => Value?.Description;
set { if (value is object && Value is ARDB.Revision revision && revision.Description != value) revision.Description = value; }
}

public string RevisionDate
{
get => Value?.RevisionDate;
set { if (value is object && Value is ARDB.Revision revision && revision.RevisionDate != value) revision.RevisionDate = value; }
}

public string IssuedBy
{
get => Value?.IssuedBy;
set { if (value is object && Value is ARDB.Revision revision && revision.IssuedBy != value) revision.IssuedBy = value; }
}

public string IssuedTo
{
get => Value?.IssuedTo;
set { if (value is object && Value is ARDB.Revision revision && revision.IssuedTo != value) revision.IssuedTo = value; }
}
public bool? Issued
{
get => Value?.Issued;
set { if (value is object && Value is ARDB.Revision revision && revision.Issued != value) revision.Issued = value.Value; }
}
}
}