Relax range setting constraints for arrays.

- VariablesView now detects if a container's range is fixed or not,
and uses that to adjust both the prompt it displays and whether or not
the parsed ranges are bounds checked.
- ArrayValueNode now returns the currently user-set range rather than
the dimension constraints, since those might not always be accurate.
This commit is contained in:
Rene Gollent 2013-05-20 19:01:51 -04:00
parent 570241e8b7
commit f297d6591d
5 changed files with 61 additions and 24 deletions

View File

@ -1593,11 +1593,17 @@ VariablesView::MessageReceived(BMessage* message)
->SelectionModel()->NodeAt(0);
int32 lowerBound, upperBound;
ValueNode* valueNode = node->NodeChild()->Node();
if (!valueNode->IsRangedContainer())
if (!valueNode->IsRangedContainer()) {
valueNode = node->ChildAt(0)->NodeChild()->Node();
if (valueNode->SupportedChildRange(lowerBound, upperBound) != B_OK)
if (!valueNode->IsRangedContainer())
break;
}
bool fixedRange = valueNode->IsContainerRangeFixed();
if (valueNode->SupportedChildRange(lowerBound, upperBound)
!= B_OK) {
break;
}
BMessage* promptMessage = new(std::nothrow) BMessage(
MSG_SET_CONTAINER_RANGE);
@ -1606,9 +1612,16 @@ VariablesView::MessageReceived(BMessage* message)
ObjectDeleter<BMessage> messageDeleter(promptMessage);
promptMessage->AddPointer("node", node);
promptMessage->AddBool("fixedRange", fixedRange);
BString infoText;
if (fixedRange) {
infoText.SetToFormat("Allowed range: %" B_PRId32
"-%" B_PRId32 ".", lowerBound, upperBound);
} else {
infoText.SetToFormat("Current range: %" B_PRId32
"-%" B_PRId32 ".", lowerBound, upperBound);
}
PromptWindow* promptWindow = new(std::nothrow) PromptWindow(
"Set Range", "Range: ", infoText.String(), BMessenger(this),
promptMessage);
@ -1631,13 +1644,15 @@ VariablesView::MessageReceived(BMessage* message)
if (valueNode->SupportedChildRange(lowerBound, upperBound) != B_OK)
break;
bool fixedRange = message->FindBool("fixedRange");
BString rangeExpression = message->FindString("text");
if (rangeExpression.Length() == 0)
break;
RangeList ranges;
status_t result = UiUtils::ParseRangeExpression(
rangeExpression, lowerBound, upperBound, ranges);
rangeExpression, lowerBound, upperBound, fixedRange, ranges);
if (result != B_OK)
break;

View File

@ -411,7 +411,7 @@ static status_t ParseRangeString(BString& rangeString, int32& lowerBound,
/*static*/ status_t
UiUtils::ParseRangeExpression(const BString& rangeExpression, int32 lowerBound,
int32 upperBound, RangeList& _output)
int32 upperBound, bool fixedRange, RangeList& _output)
{
if (rangeExpression.IsEmpty())
return B_BAD_DATA;
@ -440,7 +440,8 @@ UiUtils::ParseRangeExpression(const BString& rangeExpression, int32 lowerBound,
if (result != B_OK)
return result;
if (lowValue < lowerBound || highValue > upperBound)
if (fixedRange && (lowValue < lowerBound || highValue > upperBound))
return B_BAD_VALUE;
result = _output.AddRange(lowValue, highValue);

View File

@ -55,6 +55,7 @@ public:
static status_t ParseRangeExpression(
const BString& rangeString,
int32 lowerBound, int32 upperBound,
bool fixedRange,
RangeList& _output);
};

View File

@ -31,7 +31,10 @@ AbstractArrayValueNode::AbstractArrayValueNode(ValueNodeChild* nodeChild,
:
ValueNode(nodeChild),
fType(type),
fDimension(dimension)
fDimension(dimension),
fLowerBound(0),
fUpperBound(0),
fBoundsInitialized(false)
{
fType->AcquireReference();
}
@ -106,6 +109,8 @@ void
AbstractArrayValueNode::ClearChildren()
{
fChildren.MakeEmpty();
fLowerBound = 0;
fUpperBound = 0;
if (fContainer != NULL)
fContainer->NotifyValueNodeChildrenDeleted(this);
}
@ -121,14 +126,22 @@ AbstractArrayValueNode::CreateChildrenInRange(int32 lowIndex,
int32 dimensionCount = fType->CountDimensions();
bool isFinalDimension = fDimension + 1 == dimensionCount;
status_t error = B_OK;
if (!fBoundsInitialized) {
int32 lowerBound, upperBound;
if (SupportedChildRange(lowerBound, upperBound) == B_OK) {
// clamp inputs to supported range.
if (lowIndex < lowerBound)
lowIndex = lowerBound;
if (highIndex > upperBound)
highIndex = upperBound;
error = SupportedChildRange(lowerBound, upperBound);
if (error != B_OK)
return error;
fLowerBound = lowerBound;
fUpperBound = upperBound;
fBoundsInitialized = true;
} else {
if (lowIndex < fLowerBound)
fLowerBound = lowIndex;
if (highIndex > fUpperBound)
fUpperBound = highIndex;
}
// create children for the array elements
@ -166,6 +179,7 @@ status_t
AbstractArrayValueNode::SupportedChildRange(int32& lowIndex,
int32& highIndex) const
{
if (!fBoundsInitialized) {
ArrayDimension* dimension = fType->DimensionAt(fDimension);
SubrangeType* dimensionType = dynamic_cast<SubrangeType*>(
@ -174,11 +188,14 @@ AbstractArrayValueNode::SupportedChildRange(int32& lowIndex,
if (dimensionType != NULL) {
lowIndex = dimensionType->LowerBound().ToInt32();
highIndex = dimensionType->UpperBound().ToInt32();
return B_OK;
} else
return B_UNSUPPORTED;
} else {
lowIndex = fLowerBound;
highIndex = fUpperBound;
}
return B_UNSUPPORTED;
return B_OK;
}

View File

@ -54,6 +54,9 @@ protected:
ArrayType* fType;
ChildList fChildren;
int32 fDimension;
int32 fLowerBound;
int32 fUpperBound;
bool fBoundsInitialized;
};