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:
@@ -1593,11 +1593,17 @@ VariablesView::MessageReceived(BMessage* message)
|
|||||||
->SelectionModel()->NodeAt(0);
|
->SelectionModel()->NodeAt(0);
|
||||||
int32 lowerBound, upperBound;
|
int32 lowerBound, upperBound;
|
||||||
ValueNode* valueNode = node->NodeChild()->Node();
|
ValueNode* valueNode = node->NodeChild()->Node();
|
||||||
if (!valueNode->IsRangedContainer())
|
if (!valueNode->IsRangedContainer()) {
|
||||||
valueNode = node->ChildAt(0)->NodeChild()->Node();
|
valueNode = node->ChildAt(0)->NodeChild()->Node();
|
||||||
|
if (!valueNode->IsRangedContainer())
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if (valueNode->SupportedChildRange(lowerBound, upperBound) != B_OK)
|
bool fixedRange = valueNode->IsContainerRangeFixed();
|
||||||
|
if (valueNode->SupportedChildRange(lowerBound, upperBound)
|
||||||
|
!= B_OK) {
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
BMessage* promptMessage = new(std::nothrow) BMessage(
|
BMessage* promptMessage = new(std::nothrow) BMessage(
|
||||||
MSG_SET_CONTAINER_RANGE);
|
MSG_SET_CONTAINER_RANGE);
|
||||||
@@ -1606,9 +1612,16 @@ VariablesView::MessageReceived(BMessage* message)
|
|||||||
|
|
||||||
ObjectDeleter<BMessage> messageDeleter(promptMessage);
|
ObjectDeleter<BMessage> messageDeleter(promptMessage);
|
||||||
promptMessage->AddPointer("node", node);
|
promptMessage->AddPointer("node", node);
|
||||||
|
promptMessage->AddBool("fixedRange", fixedRange);
|
||||||
BString infoText;
|
BString infoText;
|
||||||
infoText.SetToFormat("Allowed range: %" B_PRId32
|
if (fixedRange) {
|
||||||
"-%" B_PRId32 ".", lowerBound, upperBound);
|
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(
|
PromptWindow* promptWindow = new(std::nothrow) PromptWindow(
|
||||||
"Set Range", "Range: ", infoText.String(), BMessenger(this),
|
"Set Range", "Range: ", infoText.String(), BMessenger(this),
|
||||||
promptMessage);
|
promptMessage);
|
||||||
@@ -1631,13 +1644,15 @@ VariablesView::MessageReceived(BMessage* message)
|
|||||||
if (valueNode->SupportedChildRange(lowerBound, upperBound) != B_OK)
|
if (valueNode->SupportedChildRange(lowerBound, upperBound) != B_OK)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
bool fixedRange = message->FindBool("fixedRange");
|
||||||
|
|
||||||
BString rangeExpression = message->FindString("text");
|
BString rangeExpression = message->FindString("text");
|
||||||
if (rangeExpression.Length() == 0)
|
if (rangeExpression.Length() == 0)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
RangeList ranges;
|
RangeList ranges;
|
||||||
status_t result = UiUtils::ParseRangeExpression(
|
status_t result = UiUtils::ParseRangeExpression(
|
||||||
rangeExpression, lowerBound, upperBound, ranges);
|
rangeExpression, lowerBound, upperBound, fixedRange, ranges);
|
||||||
if (result != B_OK)
|
if (result != B_OK)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|||||||
@@ -411,7 +411,7 @@ static status_t ParseRangeString(BString& rangeString, int32& lowerBound,
|
|||||||
|
|
||||||
/*static*/ status_t
|
/*static*/ status_t
|
||||||
UiUtils::ParseRangeExpression(const BString& rangeExpression, int32 lowerBound,
|
UiUtils::ParseRangeExpression(const BString& rangeExpression, int32 lowerBound,
|
||||||
int32 upperBound, RangeList& _output)
|
int32 upperBound, bool fixedRange, RangeList& _output)
|
||||||
{
|
{
|
||||||
if (rangeExpression.IsEmpty())
|
if (rangeExpression.IsEmpty())
|
||||||
return B_BAD_DATA;
|
return B_BAD_DATA;
|
||||||
@@ -440,7 +440,8 @@ UiUtils::ParseRangeExpression(const BString& rangeExpression, int32 lowerBound,
|
|||||||
if (result != B_OK)
|
if (result != B_OK)
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
if (lowValue < lowerBound || highValue > upperBound)
|
|
||||||
|
if (fixedRange && (lowValue < lowerBound || highValue > upperBound))
|
||||||
return B_BAD_VALUE;
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
result = _output.AddRange(lowValue, highValue);
|
result = _output.AddRange(lowValue, highValue);
|
||||||
|
|||||||
@@ -55,6 +55,7 @@ public:
|
|||||||
static status_t ParseRangeExpression(
|
static status_t ParseRangeExpression(
|
||||||
const BString& rangeString,
|
const BString& rangeString,
|
||||||
int32 lowerBound, int32 upperBound,
|
int32 lowerBound, int32 upperBound,
|
||||||
|
bool fixedRange,
|
||||||
RangeList& _output);
|
RangeList& _output);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -31,7 +31,10 @@ AbstractArrayValueNode::AbstractArrayValueNode(ValueNodeChild* nodeChild,
|
|||||||
:
|
:
|
||||||
ValueNode(nodeChild),
|
ValueNode(nodeChild),
|
||||||
fType(type),
|
fType(type),
|
||||||
fDimension(dimension)
|
fDimension(dimension),
|
||||||
|
fLowerBound(0),
|
||||||
|
fUpperBound(0),
|
||||||
|
fBoundsInitialized(false)
|
||||||
{
|
{
|
||||||
fType->AcquireReference();
|
fType->AcquireReference();
|
||||||
}
|
}
|
||||||
@@ -106,6 +109,8 @@ void
|
|||||||
AbstractArrayValueNode::ClearChildren()
|
AbstractArrayValueNode::ClearChildren()
|
||||||
{
|
{
|
||||||
fChildren.MakeEmpty();
|
fChildren.MakeEmpty();
|
||||||
|
fLowerBound = 0;
|
||||||
|
fUpperBound = 0;
|
||||||
if (fContainer != NULL)
|
if (fContainer != NULL)
|
||||||
fContainer->NotifyValueNodeChildrenDeleted(this);
|
fContainer->NotifyValueNodeChildrenDeleted(this);
|
||||||
}
|
}
|
||||||
@@ -121,14 +126,22 @@ AbstractArrayValueNode::CreateChildrenInRange(int32 lowIndex,
|
|||||||
|
|
||||||
int32 dimensionCount = fType->CountDimensions();
|
int32 dimensionCount = fType->CountDimensions();
|
||||||
bool isFinalDimension = fDimension + 1 == dimensionCount;
|
bool isFinalDimension = fDimension + 1 == dimensionCount;
|
||||||
|
status_t error = B_OK;
|
||||||
|
|
||||||
int32 lowerBound, upperBound;
|
if (!fBoundsInitialized) {
|
||||||
if (SupportedChildRange(lowerBound, upperBound) == B_OK) {
|
int32 lowerBound, upperBound;
|
||||||
// clamp inputs to supported range.
|
error = SupportedChildRange(lowerBound, upperBound);
|
||||||
if (lowIndex < lowerBound)
|
if (error != B_OK)
|
||||||
lowIndex = lowerBound;
|
return error;
|
||||||
if (highIndex > upperBound)
|
|
||||||
highIndex = upperBound;
|
fLowerBound = lowerBound;
|
||||||
|
fUpperBound = upperBound;
|
||||||
|
fBoundsInitialized = true;
|
||||||
|
} else {
|
||||||
|
if (lowIndex < fLowerBound)
|
||||||
|
fLowerBound = lowIndex;
|
||||||
|
if (highIndex > fUpperBound)
|
||||||
|
fUpperBound = highIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
// create children for the array elements
|
// create children for the array elements
|
||||||
@@ -166,19 +179,23 @@ status_t
|
|||||||
AbstractArrayValueNode::SupportedChildRange(int32& lowIndex,
|
AbstractArrayValueNode::SupportedChildRange(int32& lowIndex,
|
||||||
int32& highIndex) const
|
int32& highIndex) const
|
||||||
{
|
{
|
||||||
ArrayDimension* dimension = fType->DimensionAt(fDimension);
|
if (!fBoundsInitialized) {
|
||||||
|
ArrayDimension* dimension = fType->DimensionAt(fDimension);
|
||||||
|
|
||||||
SubrangeType* dimensionType = dynamic_cast<SubrangeType*>(
|
SubrangeType* dimensionType = dynamic_cast<SubrangeType*>(
|
||||||
dimension->GetType());
|
dimension->GetType());
|
||||||
|
|
||||||
if (dimensionType != NULL) {
|
if (dimensionType != NULL) {
|
||||||
lowIndex = dimensionType->LowerBound().ToInt32();
|
lowIndex = dimensionType->LowerBound().ToInt32();
|
||||||
highIndex = dimensionType->UpperBound().ToInt32();
|
highIndex = dimensionType->UpperBound().ToInt32();
|
||||||
|
} else
|
||||||
return B_OK;
|
return B_UNSUPPORTED;
|
||||||
|
} else {
|
||||||
|
lowIndex = fLowerBound;
|
||||||
|
highIndex = fUpperBound;
|
||||||
}
|
}
|
||||||
|
|
||||||
return B_UNSUPPORTED;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -54,6 +54,9 @@ protected:
|
|||||||
ArrayType* fType;
|
ArrayType* fType;
|
||||||
ChildList fChildren;
|
ChildList fChildren;
|
||||||
int32 fDimension;
|
int32 fDimension;
|
||||||
|
int32 fLowerBound;
|
||||||
|
int32 fUpperBound;
|
||||||
|
bool fBoundsInitialized;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user