/* Copyright (C) 2000-2005 SKYRIX Software AG This file is part of SOPE. SOPE is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. SOPE is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with SOPE; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #import /* usage: DropContainer: WEDropContainer { elementName = "tr"; isAttached = YES; tags = ( * ); action = dropAction; droppedObject = droppedObject; swapColor = YES; activeColor = "lightblue"; bgColor = bgColor; } renders this: <$area BGCOLOR=white onDragEnter="fnCancelDefault()" onDragOver="fnCancelDefault()" onDrop="fnGetInfo()"> $content */ @interface WEDropContainer : WODynamicElement { NSDictionary *dExtraAttrs; WOAssociation *tags; WOAssociation *elementName; WOAssociation *isAttached; /* bool */ WOAssociation *effect; WOAssociation *swapColor; /* swap bgcolor if drag object is over container */ WOAssociation *action; WOAssociation *droppedObject; WOElement *template; } @end @interface WEDropScript : WODynamicElement + (void)appendDropScriptToResponse:(WOResponse *)_response inContext:(WOContext *)_ctx; @end #include #include "common.h" @implementation WEDropContainer + (int)version { return 0 + [super version]; } - (id)initWithName:(NSString *)_name associations:(NSDictionary *)_config template:(WOElement *)_subs { if ((self = [super initWithName:_name associations:_config template:_subs])) { self->tags = WOExtGetProperty(_config, @"tags"); self->elementName = WOExtGetProperty(_config, @"elementName"); self->effect = WOExtGetProperty(_config, @"effect"); self->action = WOExtGetProperty(_config, @"action"); self->droppedObject = WOExtGetProperty(_config, @"droppedObject"); self->swapColor = WOExtGetProperty(_config, @"swapColor"); self->isAttached = WOExtGetProperty(_config, @"isAttached"); self->template = RETAIN(_subs); } return self; } - (void)dealloc { RELEASE(self->dExtraAttrs); RELEASE(self->swapColor); RELEASE(self->droppedObject); RELEASE(self->action); RELEASE(self->template); RELEASE(self->effect); RELEASE(self->tags); RELEASE(self->elementName); RELEASE(self->isAttached); [super dealloc]; } - (void)setExtraAttributes:(NSDictionary *)_extras { ASSIGNCOPY(self->dExtraAttrs, _extras); } - (void)appendExtraAttributesToResponse:(WOResponse *)_response inContext:(WOContext *)_ctx { if (self->dExtraAttrs) { WOComponent *sComponent; NSEnumerator *keys; NSString *key; sComponent = [_ctx component]; keys = [self->dExtraAttrs keyEnumerator]; while ((key = [keys nextObject])) { id value; value = [self->dExtraAttrs objectForKey:key]; if (value == nil) continue; //key = [key lowercaseString]; value = [value stringValueInComponent:sComponent]; [_response appendContentCharacter:' ']; [_response appendContentString:key]; [_response appendContentString:@"=\""]; [_response appendContentHTMLAttributeValue:value]; [_response appendContentCharacter:'"']; } } } /* responder */ - (void)takeValuesFromRequest:(WORequest *)_request inContext:(WOContext *)_ctx { [_ctx appendElementIDComponent:@"p"]; [self->template takeValuesFromRequest:_request inContext:_ctx]; [_ctx deleteLastElementIDComponent]; } - (id)invokeActionForRequest:(WORequest *)_request inContext:(WOContext *)_ctx { NSString *op; id result; op = [[_ctx currentElementID] stringValue]; #if 0 NSLog(@"check DROP ACTION %@ ..", op); #endif if ([op isEqualToString:@"p"]) { /* an action inside of the component */ [_ctx consumeElementID]; // consume id [_ctx appendElementIDComponent:@"p"]; result = [self->template invokeActionForRequest:_request inContext:_ctx]; [_ctx deleteLastElementIDComponent]; } else if ([op isEqualToString:@"drop"]) { /* an action of *this* component */ [_ctx consumeElementID]; // consume id [_ctx appendElementIDComponent:@"drop"]; #if 0 NSLog(@"WILL RUN DROP ACTION .."); #endif if ([self->droppedObject isValueSettable]) { [self->droppedObject setValue: [_ctx valueForKey:@"WEDragContainer_DropObject"] inComponent:[_ctx component]]; } result = [self->action valueInComponent:[_ctx component]]; [_ctx deleteLastElementIDComponent]; } else { NSLog(@"invalid element-id: did not expect '%@' id", op); result = nil; } return result; } - (void)appendExtraAttributesAsJavaScriptToResponse:(WOResponse *)_response inContext:(WOContext *)_ctx { if (self->dExtraAttrs) { WOComponent *sComponent = [_ctx component]; NSEnumerator *keyEnum; NSString *key; [_response appendContentString: @"\n" @"\n"]; } } - (void)appendToResponse:(WOResponse *)_response inContext:(WOContext *)_ctx { NSString *htmlEl; NSString *ttag; NSString *teffect; NSString *containerID = nil; BOOL doDnD, doSwap, doAttach; doDnD = [[[_ctx request] clientCapabilities] doesSupportDHTMLDragAndDrop]; //doDnD = YES; ttag = [[self->tags valueInComponent:[_ctx component]] componentsJoinedByString:@","]; teffect = [self->effect stringValueInComponent:[_ctx component]]; if (teffect == nil) teffect = @"move"; [WEDropScript appendDropScriptToResponse:_response inContext:_ctx]; [_ctx appendElementIDComponent:@"drop"]; htmlEl = [self->elementName stringValueInComponent:[_ctx component]]; doAttach = ([self->isAttached boolValueInComponent:[_ctx component]] && (self->elementName != nil)); if (htmlEl == nil || doAttach) htmlEl = @"span"; if ((self->elementName != nil) || doDnD) { int containerIDc; [_response appendContentString: @"<"]; [_response appendContentString:htmlEl]; if (doDnD) { /* gen unique container id */ if ((containerID = [_ctx valueForKey:@"WEDropContainerSequence"])) { containerID = AUTORELEASE([containerID copy]); containerIDc = [containerID intValue]; } else { containerID = @"0"; containerIDc = 0; } [_response appendContentString:@" id=\"skydrop"]; if (doAttach) [_response appendContentString:@"dummy"]; [_response appendContentString:containerID]; [_response appendContentString:@"\""]; containerIDc++; [_ctx takeValue:[NSString stringWithFormat:@"%i", containerIDc] forKey:@"WEDropContainerSequence"]; } } if (doDnD) { NSString *swapOnAction = @""; NSString *swapOffAction = @""; NSString *cancelAction; NSString *infoAction; doSwap = self->swapColor ? [self->swapColor boolValueInComponent:[_ctx component]] : YES; cancelAction = [NSString stringWithFormat:@"fnCancelDefault('%@','%@');", ttag, teffect]; if (doSwap) { swapOnAction = [NSString stringWithFormat: @"dropFieldSwapColor(skydrop%@,true);", containerID]; swapOffAction = [NSString stringWithFormat: @"dropFieldSwapColor(skydrop%@,false);", containerID]; } infoAction = [NSString stringWithFormat:@"fnGetInfo(this, '%@');", [_ctx componentActionURL]]; if (doAttach) { NSString *tagName = nil; // doAttach==YES -> self->elementName != nil tagName = [self->elementName stringValueInComponent:[_ctx component]]; tagName = [tagName uppercaseString]; [_response appendContentCharacter:'>']; [_response appendContentString:[NSString stringWithFormat: @"\n" @"\n", containerID, cancelAction, swapOnAction, containerID, cancelAction, swapOnAction, containerID, swapOffAction, containerID, infoAction, [@"skydropdummy" stringByAppendingString:containerID], tagName, containerID, containerID, containerID, containerID, [@"skydrop" stringByAppendingString:containerID]]]; // remove bgColors of TR's sub TD: if ([tagName isEqualToString:@"TR"]) { [_response appendContentString: @"\n" @"\n"]; } /* append extra attributes by script */ [self appendExtraAttributesAsJavaScriptToResponse:_response inContext:_ctx]; } else { [_response appendContentString:@" onDragEnter=\""]; [_response appendContentString:cancelAction]; [_response appendContentString:swapOnAction]; [_response appendContentString:@"\" onDragOver=\""]; [_response appendContentString:cancelAction]; [_response appendContentString:swapOnAction]; [_response appendContentString:@"\" onDragLeave=\""]; [_response appendContentString:swapOffAction]; [_response appendContentString:@"\" onDrop=\""]; [_response appendContentString:infoAction]; [_response appendContentCharacter:'"']; [self appendExtraAttributesToResponse:_response inContext:_ctx]; [_response appendContentCharacter:'>']; } } else if (self->elementName != nil) { [self appendExtraAttributesToResponse:_response inContext:_ctx]; [_response appendContentCharacter:'>']; } [_ctx deleteLastElementIDComponent]; /* add template */ [_ctx appendElementIDComponent:@"p"]; [self->template appendToResponse:_response inContext:_ctx]; [_ctx deleteLastElementIDComponent]; /* close container */ if ((self->elementName != nil) || doDnD) { [_response appendContentString:@"']; } } // --- accessors --- - (WOElement *)template { return self->template; } @end /* WEDropContainer */ @implementation WEDropScript + (void)appendDropScriptToResponse:(WOResponse *)_response inContext:(WOContext *)_ctx { BOOL doDnD; doDnD = [[[_ctx request] clientCapabilities] doesSupportDHTMLDragAndDrop]; if (![[_ctx valueForKey:@"WEDropContainerScriptDone"] boolValue] && doDnD) { NSString *dropScript; dropScript = #include "WEDropScript.jsm" ; [_response appendContentString:dropScript]; [_ctx takeValue:[NSNumber numberWithBool:YES] forKey:@"WEDropContainerScriptDone"]; } } - (void)appendToResponse:(WOResponse *)_response inContext:(WOContext *)_ctx { [[self class] appendDropScriptToResponse:_response inContext:_ctx]; } @end /* WEDropScript */