Split BShelf::_AddReplicant() functionality into smaller methods. Not

yet done, but I hope it's getting better


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@23181 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Stefano Ceccherini 2007-12-28 10:49:04 +00:00
parent 0a9d19b17f
commit 898edb5ba7
2 changed files with 111 additions and 76 deletions

View File

@ -6,6 +6,7 @@
#define _SHELF_H
#include <Dragger.h>
#include <Handler.h>
#include <List.h>
@ -13,6 +14,7 @@ class BDataIO;
class BPoint;
class BView;
class BEntry;
class _BZombieReplicantView_;
struct entry_ref;
namespace BPrivate {
@ -99,8 +101,11 @@ class BShelf : public BHandler {
status_t _DeleteReplicant(BPrivate::replicant_data* replicant);
status_t _AddReplicant(BMessage* data,
BPoint* location, uint32 uniqueID);
status_t _GetProperty(BMessage* message, BMessage* reply);
_BZombieReplicantView_ *_CreateZombie(BMessage *data, BDragger *&dragger);
status_t _GetProperty(BMessage* message, BMessage* reply);
static void _GetReplicantData(BMessage *message, BView *view, BView *&replicant,
BDragger *&dragger, BDragger::relation &relation);
static BArchivable* _InstantiateObject(BMessage *archive, image_id *image);
private:

View File

@ -178,6 +178,25 @@ send_reply(BMessage* message, status_t status, uint32 uniqueID)
}
static bool
find_replicant(BList &list, const char *className, const char *addOn)
{
int32 i = 0;
replicant_data *item;
while ((item = (replicant_data *)list.ItemAt(i++)) != NULL) {
const char *replicantClassName;
const char *replicantAddOn;
if (item->message->FindString("class", &replicantClassName) == B_OK
&& item->message->FindString("add_on", &replicantAddOn) == B_OK
&& !strcmp(className, replicantClassName)
&& addOn != NULL && replicantAddOn != NULL
&& !strcmp(addOn, replicantAddOn))
return true;
}
return false;
}
// #pragma mark -
@ -1105,7 +1124,7 @@ BShelf::_AddReplicant(BMessage *data, BPoint *location, uint32 uniqueID)
// Check if we can accept this message
if (!CanAcceptReplicantMessage(data)) {
printf("Replicant was rejected by BShelf: CanAcceptReplicant() returned false");
printf("Replicant was rejected by BShelf::CanAcceptReplicantMessage()");
return send_reply(data, B_ERROR, uniqueID);
}
@ -1116,24 +1135,13 @@ BShelf::_AddReplicant(BMessage *data, BPoint *location, uint32 uniqueID)
if (data->FindString("class", &className) == B_OK
&& data->FindString("add_on", &addOn) == B_OK) {
int32 i = 0;
replicant_data *item;
const char *replicantClassName = NULL;
const char *replicantAddOn = NULL;
while ((item = (replicant_data*)fReplicants.ItemAt(i++)) != NULL) {
if (item->message->FindString("class", &replicantClassName) == B_OK
&& item->message->FindString("add_on", &replicantAddOn) == B_OK
&& !strcmp(className, replicantClassName)
&& addOn != NULL && replicantAddOn != NULL
&& !strcmp(addOn, replicantAddOn)) {
if (find_replicant(fReplicants, className, addOn)) {
printf("Replicant was rejected. Unique replicant already exists. class=%s, signature=%s",
replicantClassName, replicantAddOn);
className, addOn);
return send_reply(data, B_ERROR, uniqueID);
}
}
}
}
BDragger* dragger = NULL;
BView* replicant = NULL;
@ -1158,44 +1166,18 @@ BShelf::_AddReplicant(BMessage *data, BPoint *location, uint32 uniqueID)
// TODO: test me -- there seems to be lots of bugs parked here!
// Check if we have a dragger archived as "__widget" inside the message
BMessage widget;
if (data->FindMessage("__widget", &widget) == B_OK) {
image_id draggerImage = B_ERROR;
replicant = view;
dragger = dynamic_cast<BDragger*>(_InstantiateObject(&widget, &draggerImage));
if (dragger != NULL) {
// Replicant is either a sibling or unknown
dragger->_SetViewToDrag(replicant);
relation = BDragger::TARGET_IS_SIBLING;
}
} else {
// Replicant is child of the dragger
if ((dragger = dynamic_cast<BDragger*>(view)) != NULL) {
replicant = dragger->ChildAt(0);
dragger->_SetViewToDrag(replicant);
relation = BDragger::TARGET_IS_CHILD;
} else {
// Replicant is parent of the dragger
replicant = view;
dragger = dynamic_cast<BDragger *>(replicant->FindView("_dragger_"));
if (dragger)
dragger->_SetViewToDrag(replicant);
relation = BDragger::TARGET_IS_PARENT;
}
}
_GetReplicantData(data, view, replicant, dragger, relation);
if (dragger != NULL)
dragger->_SetShelf(this);
BRect frame;
if (relation != BDragger::TARGET_IS_CHILD) {
if (relation == BDragger::TARGET_IS_CHILD)
frame = dragger->Frame().OffsetToCopy(point);
else {
frame = replicant->Frame().OffsetToCopy(point);
fContainerView->AddChild(replicant);
} else
frame = dragger->Frame().OffsetToCopy(point);
}
if (!CanAcceptReplicantView(frame, replicant, data)) {
// the view has not been accepted
@ -1205,6 +1187,7 @@ BShelf::_AddReplicant(BMessage *data, BPoint *location, uint32 uniqueID)
replicant->RemoveSelf();
delete replicant;
}
if (relation == BDragger::TARGET_IS_CHILD
|| relation == BDragger::TARGET_IS_SIBLING) {
dragger->RemoveSelf();
@ -1226,12 +1209,39 @@ BShelf::_AddReplicant(BMessage *data, BPoint *location, uint32 uniqueID)
fContainerView->AddChild(dragger);
replicant->AddFilter(new ReplicantViewFilter(this, replicant));
} else if (fDisplayZombies && fAllowZombies) {
} else if (fDisplayZombies && fAllowZombies)
zombie = _CreateZombie(data, dragger);
else if (!fAllowZombies) {
// There was no view, and we're not allowed to have any zombies
// in the house
return send_reply(data, B_ERROR, uniqueID);
}
data->RemoveName("_drop_point_");
data->RemoveName("_drop_offset_");
replicant_data *item = new replicant_data(data, replicant, dragger,
relation, uniqueID, image);
item->error = B_OK;
item->zombie_view = zombie;
fReplicants.AddItem(item);
return send_reply(data, B_OK, uniqueID);
}
_BZombieReplicantView_ *
BShelf::_CreateZombie(BMessage *data, BDragger *&dragger)
{
// TODO: the zombies must be adjusted and moved as well!
BRect frame;
if (data->FindRect("_frame", &frame) != B_OK)
frame = BRect();
_BZombieReplicantView_ *zombie = NULL;
if (data->WasDropped()) {
BPoint dropPoint, offset;
dropPoint = data->DropPoint(&offset);
@ -1253,24 +1263,8 @@ BShelf::_AddReplicant(BMessage *data, BPoint *location, uint32 uniqueID)
fContainerView->AddChild(zombie);
}
} else if (!fAllowZombies) {
// There was no view, and we're not allowed to have any zombies
// in the house
return send_reply(data, B_ERROR, uniqueID);
}
data->RemoveName("_drop_point_");
data->RemoveName("_drop_offset_");
replicant_data *item = new replicant_data(data, replicant, dragger,
relation, uniqueID, image);
item->error = B_OK;
item->zombie_view = zombie;
fReplicants.AddItem(item);
return send_reply(data, B_OK, uniqueID);
return zombie;
}
@ -1343,6 +1337,42 @@ BShelf::_GetProperty(BMessage *msg, BMessage *reply)
}
/* static */
void
BShelf::_GetReplicantData(BMessage *data, BView *view, BView *&replicant,
BDragger *&dragger, BDragger::relation &relation)
{
// Check if we have a dragger archived as "__widget" inside the message
BMessage widget;
if (data->FindMessage("__widget", &widget) == B_OK) {
image_id draggerImage = B_ERROR;
replicant = view;
dragger = dynamic_cast<BDragger*>(_InstantiateObject(&widget, &draggerImage));
if (dragger != NULL) {
// Replicant is either a sibling or unknown
dragger->_SetViewToDrag(replicant);
relation = BDragger::TARGET_IS_SIBLING;
}
} else {
// Replicant is child of the dragger
if ((dragger = dynamic_cast<BDragger*>(view)) != NULL) {
replicant = dragger->ChildAt(0);
dragger->_SetViewToDrag(replicant);
relation = BDragger::TARGET_IS_CHILD;
} else {
// Replicant is parent of the dragger
replicant = view;
dragger = dynamic_cast<BDragger *>(replicant->FindView("_dragger_"));
if (dragger)
dragger->_SetViewToDrag(replicant);
relation = BDragger::TARGET_IS_PARENT;
}
}
}
/* static */
BArchivable *
BShelf::_InstantiateObject(BMessage *archive, image_id *image)