BListView: complete scripting support

Change-Id: Iff4b5cb775d1c0b0e588459429d6df7fb93a760e
Reviewed-on: https://review.haiku-os.org/c/haiku/+/2945
Reviewed-by: Adrien Destugues <pulkomandy@gmail.com>
This commit is contained in:
X512 2020-06-23 17:29:22 +09:00 committed by waddlesplash
parent 8fbce87334
commit 079e9eef15

View File

@ -296,48 +296,72 @@ BListView::WindowActivated(bool active)
void void
BListView::MessageReceived(BMessage* message) BListView::MessageReceived(BMessage* message)
{ {
switch (message->what) { if (message->HasSpecifiers()) {
case B_MOUSE_WHEEL_CHANGED: BMessage reply(B_REPLY);
if (!fTrack->is_dragging) status_t err = B_BAD_SCRIPT_SYNTAX;
BView::MessageReceived(message); int32 index;
break;
case B_COUNT_PROPERTIES:
case B_EXECUTE_PROPERTY:
case B_GET_PROPERTY:
case B_SET_PROPERTY:
{
BPropertyInfo propInfo(sProperties);
BMessage specifier; BMessage specifier;
int32 what;
const char* property; const char* property;
if (message->GetCurrentSpecifier(NULL, &specifier) != B_OK if (message->GetCurrentSpecifier(&index, &specifier, &what, &property)
|| specifier.FindString("property", &property) != B_OK) { != B_OK) {
BView::MessageReceived(message); return BView::MessageReceived(message);
return;
} }
switch (propInfo.FindMatch(message, 0, &specifier, message->what, BPropertyInfo propInfo(sProperties);
switch (propInfo.FindMatch(message, index, &specifier, what,
property)) { property)) {
case B_ERROR: case 0: // Item: Count
BView::MessageReceived(message); err = reply.AddInt32("result", CountItems());
break; break;
case 0: case 1: { // Item: EXECUTE
{ switch (what) {
BMessage reply(B_REPLY); case B_INDEX_SPECIFIER:
reply.AddInt32("result", CountItems()); case B_REVERSE_INDEX_SPECIFIER: {
reply.AddInt32("error", B_OK); int32 index;
err = specifier.FindInt32("index", &index);
message->SendReply(&reply); if (err >= B_OK) {
if (what == B_REVERSE_INDEX_SPECIFIER)
index = CountItems() - index;
if (index < 0 || index >= CountItems())
err = B_BAD_INDEX;
}
if (err >= B_OK) {
Select(index, false);
Invoke();
}
break; break;
} }
case B_RANGE_SPECIFIER: {
case 1: case B_REVERSE_RANGE_SPECIFIER:
int32 beg, end, range;
err = specifier.FindInt32("index", &beg);
if (err >= B_OK)
err = specifier.FindInt32("range", &range);
if (err >= B_OK) {
if (what == B_REVERSE_RANGE_SPECIFIER)
beg = CountItems() - beg;
end = beg + range;
if (!(beg >= 0 && beg <= end && end < CountItems()))
err = B_BAD_INDEX;
if (err >= B_OK) {
if (fListType != B_MULTIPLE_SELECTION_LIST
&& end - beg > 1)
err = B_BAD_VALUE;
if (err >= B_OK) {
Select(beg, end - 1, false);
Invoke();
}
}
}
break; break;
}
case 2: }
{ break;
}
case 2: { // Selection: COUNT
int32 count = 0; int32 count = 0;
for (int32 i = 0; i < CountItems(); i++) { for (int32 i = 0; i < CountItems(); i++) {
@ -345,53 +369,107 @@ BListView::MessageReceived(BMessage* message)
count++; count++;
} }
BMessage reply(B_REPLY); err = reply.AddInt32("result", count);
reply.AddInt32("result", count);
reply.AddInt32("error", B_OK);
message->SendReply(&reply);
break; break;
} }
case 3: // Selection: EXECUTE
case 3: err = Invoke();
break; break;
case 4: case 4: // Selection: GET
{ err = B_OK;
BMessage reply (B_REPLY); for (int32 i = 0; err >= B_OK && i < CountItems(); i++) {
for (int32 i = 0; i < CountItems(); i++) {
if (ItemAt(i)->IsSelected()) if (ItemAt(i)->IsSelected())
reply.AddInt32("result", i); err = reply.AddInt32("result", i);
} }
reply.AddInt32("error", B_OK);
message->SendReply(&reply);
break;
}
case 5:
break; break;
case 6: case 5: { // Selection: SET
{ bool doSelect;
BMessage reply(B_REPLY); err = message->FindBool("data", &doSelect);
if (err >= B_OK) {
bool select; switch (what) {
if (message->FindBool("data", &select) == B_OK && select) case B_INDEX_SPECIFIER:
Select(0, CountItems() - 1, false); case B_REVERSE_INDEX_SPECIFIER: {
int32 index;
err = specifier.FindInt32("index", &index);
if (err >= B_OK) {
if (what == B_REVERSE_INDEX_SPECIFIER)
index = CountItems() - index;
if (index < 0 || index >= CountItems())
err = B_BAD_INDEX;
}
if (err >= B_OK) {
if (doSelect)
Select(index,
fListType == B_MULTIPLE_SELECTION_LIST);
else
Deselect(index);
}
break;
}
case B_RANGE_SPECIFIER: {
case B_REVERSE_RANGE_SPECIFIER:
int32 beg, end, range;
err = specifier.FindInt32("index", &beg);
if (err >= B_OK)
err = specifier.FindInt32("range", &range);
if (err >= B_OK) {
if (what == B_REVERSE_RANGE_SPECIFIER)
beg = CountItems() - beg;
end = beg + range;
if (!(beg >= 0 && beg <= end
&& end < CountItems()))
err = B_BAD_INDEX;
if (err >= B_OK) {
if (fListType != B_MULTIPLE_SELECTION_LIST
&& end - beg > 1)
err = B_BAD_VALUE;
if (doSelect)
Select(beg, end - 1, fListType
== B_MULTIPLE_SELECTION_LIST);
else {
for (int32 i = beg; i < end; i++)
Deselect(i);
}
}
}
break;
}
}
}
break;
}
case 6: // Selection: SET (select/deselect all)
bool doSelect;
err = message->FindBool("data", &doSelect);
if (err >= B_OK) {
if (doSelect)
Select(0, CountItems() - 1, true);
else else
DeselectAll(); DeselectAll();
}
break;
reply.AddInt32("error", B_OK); default:
return BView::MessageReceived(message);
}
if (err != B_OK) {
reply.what = B_MESSAGE_NOT_UNDERSTOOD;
reply.AddString("message", strerror(err));
}
reply.AddInt32("error", err);
message->SendReply(&reply); message->SendReply(&reply);
return;
}
switch (message->what) {
case B_MOUSE_WHEEL_CHANGED:
if (!fTrack->is_dragging)
BView::MessageReceived(message);
break; break;
}
}
break;
}
case B_SELECT_ALL: case B_SELECT_ALL:
if (fListType == B_MULTIPLE_SELECTION_LIST) if (fListType == B_MULTIPLE_SELECTION_LIST)