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 #define _SHELF_H
#include <Dragger.h>
#include <Handler.h> #include <Handler.h>
#include <List.h> #include <List.h>
@ -13,6 +14,7 @@ class BDataIO;
class BPoint; class BPoint;
class BView; class BView;
class BEntry; class BEntry;
class _BZombieReplicantView_;
struct entry_ref; struct entry_ref;
namespace BPrivate { namespace BPrivate {
@ -99,8 +101,11 @@ class BShelf : public BHandler {
status_t _DeleteReplicant(BPrivate::replicant_data* replicant); status_t _DeleteReplicant(BPrivate::replicant_data* replicant);
status_t _AddReplicant(BMessage* data, status_t _AddReplicant(BMessage* data,
BPoint* location, uint32 uniqueID); 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); static BArchivable* _InstantiateObject(BMessage *archive, image_id *image);
private: 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 - // #pragma mark -
@ -1105,7 +1124,7 @@ BShelf::_AddReplicant(BMessage *data, BPoint *location, uint32 uniqueID)
// Check if we can accept this message // Check if we can accept this message
if (!CanAcceptReplicantMessage(data)) { 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); return send_reply(data, B_ERROR, uniqueID);
} }
@ -1115,22 +1134,11 @@ BShelf::_AddReplicant(BMessage *data, BPoint *location, uint32 uniqueID)
const char *addOn = NULL; const char *addOn = NULL;
if (data->FindString("class", &className) == B_OK if (data->FindString("class", &className) == B_OK
&& data->FindString("add_on", &addOn) == B_OK) { && data->FindString("add_on", &addOn) == B_OK) {
int32 i = 0; if (find_replicant(fReplicants, className, addOn)) {
replicant_data *item; printf("Replicant was rejected. Unique replicant already exists. class=%s, signature=%s",
const char *replicantClassName = NULL; className, addOn);
const char *replicantAddOn = NULL; return send_reply(data, B_ERROR, uniqueID);
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)) {
printf("Replicant was rejected. Unique replicant already exists. class=%s, signature=%s",
replicantClassName, replicantAddOn);
return send_reply(data, B_ERROR, uniqueID);
}
} }
} }
} }
@ -1158,44 +1166,18 @@ BShelf::_AddReplicant(BMessage *data, BPoint *location, uint32 uniqueID)
// TODO: test me -- there seems to be lots of bugs parked here! // TODO: test me -- there seems to be lots of bugs parked here!
// Check if we have a dragger archived as "__widget" inside the message _GetReplicantData(data, view, replicant, dragger, relation);
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;
}
}
if (dragger != NULL) if (dragger != NULL)
dragger->_SetShelf(this); dragger->_SetShelf(this);
BRect frame; 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); frame = replicant->Frame().OffsetToCopy(point);
fContainerView->AddChild(replicant); fContainerView->AddChild(replicant);
} else }
frame = dragger->Frame().OffsetToCopy(point);
if (!CanAcceptReplicantView(frame, replicant, data)) { if (!CanAcceptReplicantView(frame, replicant, data)) {
// the view has not been accepted // the view has not been accepted
@ -1205,6 +1187,7 @@ BShelf::_AddReplicant(BMessage *data, BPoint *location, uint32 uniqueID)
replicant->RemoveSelf(); replicant->RemoveSelf();
delete replicant; delete replicant;
} }
if (relation == BDragger::TARGET_IS_CHILD if (relation == BDragger::TARGET_IS_CHILD
|| relation == BDragger::TARGET_IS_SIBLING) { || relation == BDragger::TARGET_IS_SIBLING) {
dragger->RemoveSelf(); dragger->RemoveSelf();
@ -1226,34 +1209,10 @@ BShelf::_AddReplicant(BMessage *data, BPoint *location, uint32 uniqueID)
fContainerView->AddChild(dragger); fContainerView->AddChild(dragger);
replicant->AddFilter(new ReplicantViewFilter(this, replicant)); replicant->AddFilter(new ReplicantViewFilter(this, replicant));
} else if (fDisplayZombies && fAllowZombies) { } else if (fDisplayZombies && fAllowZombies)
// TODO: the zombies must be adjusted and moved as well! zombie = _CreateZombie(data, dragger);
BRect frame;
if (data->FindRect("_frame", &frame) != B_OK)
frame = BRect();
if (data->WasDropped()) { else if (!fAllowZombies) {
BPoint dropPoint, offset;
dropPoint = data->DropPoint(&offset);
frame.OffsetTo(B_ORIGIN);
frame.OffsetTo(fContainerView->ConvertFromScreen(dropPoint) - offset);
zombie = new _BZombieReplicantView_(frame, B_ERROR);
frame.OffsetTo(B_ORIGIN);
dragger = new BDragger(frame, zombie);
dragger->_SetShelf(this);
dragger->_SetZombied(true);
zombie->AddChild(dragger);
zombie->SetArchive(data);
zombie->AddFilter(new ReplicantViewFilter(this, zombie));
fContainerView->AddChild(zombie);
}
} else if (!fAllowZombies) {
// There was no view, and we're not allowed to have any zombies // There was no view, and we're not allowed to have any zombies
// in the house // in the house
return send_reply(data, B_ERROR, uniqueID); return send_reply(data, B_ERROR, uniqueID);
@ -1274,6 +1233,41 @@ BShelf::_AddReplicant(BMessage *data, BPoint *location, uint32 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);
frame.OffsetTo(B_ORIGIN);
frame.OffsetTo(fContainerView->ConvertFromScreen(dropPoint) - offset);
zombie = new _BZombieReplicantView_(frame, B_ERROR);
frame.OffsetTo(B_ORIGIN);
dragger = new BDragger(frame, zombie);
dragger->_SetShelf(this);
dragger->_SetZombied(true);
zombie->AddChild(dragger);
zombie->SetArchive(data);
zombie->AddFilter(new ReplicantViewFilter(this, zombie));
fContainerView->AddChild(zombie);
}
return zombie;
}
status_t status_t
BShelf::_GetProperty(BMessage *msg, BMessage *reply) BShelf::_GetProperty(BMessage *msg, BMessage *reply)
{ {
@ -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 */ /* static */
BArchivable * BArchivable *
BShelf::_InstantiateObject(BMessage *archive, image_id *image) BShelf::_InstantiateObject(BMessage *archive, image_id *image)