1/* 2 Copyright (C) 2000-2005 SKYRIX Software AG 3 4 This file is part of SOPE. 5 6 SOPE is free software; you can redistribute it and/or modify it under 7 the terms of the GNU Lesser General Public License as published by the 8 Free Software Foundation; either version 2, or (at your option) any 9 later version. 10 11 SOPE is distributed in the hope that it will be useful, but WITHOUT ANY 12 WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 14 License for more details. 15 16 You should have received a copy of the GNU Lesser General Public 17 License along with SOPE; see the file COPYING. If not, write to the 18 Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 19 02111-1307, USA. 20*/ 21 22#include <NGObjWeb/WODynamicElement.h> 23 24/* 25 renders this: 26 27 <...small script...> 28 <SPAN onDragStart="fnSetInfo($tag,$effectsAllowed)"> 29 $content 30 </SPAN> 31 32*/ 33 34@interface WEDragContainer : WODynamicElement 35{ 36 WOElement *template; 37 WOAssociation *tag; 38 WOAssociation *effectsAllowed; 39 WOAssociation *elementName; 40 WOAssociation *isDraggable; 41 42 WOAssociation *object; 43 WOAssociation *droppedObject; 44} 45@end 46 47@interface WEDragScript : WODynamicElement 48+ (void)appendDragScriptToResponse:(WOResponse *)_response 49 inContext:(WOContext *)_ctx; 50@end 51 52#include <NGObjWeb/WEClientCapabilities.h> 53#include "common.h" 54 55//#define DEBUG_TAKEVALUES 1 56 57@implementation WEDragContainer 58 59static BOOL debugTakeValues = NO; 60 61- (id)initWithName:(NSString *)_name 62 associations:(NSDictionary *)_config 63 template:(WOElement *)_t 64{ 65 if ((self = [super initWithName:_name associations:_config template:_t])) { 66 self->tag = WOExtGetProperty(_config, @"tag"); 67 self->effectsAllowed = WOExtGetProperty(_config, @"effectsAllowed"); 68 self->elementName = WOExtGetProperty(_config, @"elementName"); 69 self->isDraggable = WOExtGetProperty(_config, @"isDraggable"); 70 71 self->object = WOExtGetProperty(_config, @"object"); 72 self->droppedObject = WOExtGetProperty(_config, @"droppedObject"); 73 74 self->template = [_t retain]; 75 } 76 return self; 77} 78 79- (void)dealloc { 80 [self->isDraggable release]; 81 [self->object release]; 82 [self->droppedObject release]; 83 [self->tag release]; 84 [self->elementName release]; 85 [self->effectsAllowed release]; 86 [self->template release]; 87 [super dealloc]; 88} 89 90/* processing request values */ 91 92- (void)takeValuesFromRequest:(WORequest *)_rq inContext:(WOContext *)_ctx { 93 id formValue; 94 95 if ((formValue = [_rq formValueForKey:[_ctx elementID]]) != nil) { 96 id obj; 97 98 if (debugTakeValues) { 99 [[_ctx component] 100 debugWithFormat:@"WEDragContainer: got value '%@' for id '%@'", 101 formValue, [_ctx elementID]]; 102 } 103 104 obj = [self->object valueInComponent:[_ctx component]]; 105 106 if (debugTakeValues) 107 NSLog(@"DRAG MATCH => ok, obj is %@",obj); 108 109 if ([self->droppedObject isValueSettable]) 110 [self->droppedObject setValue:obj inComponent:[_ctx component]]; 111 112 if (obj) { 113 [_ctx takeValue:obj forKey:@"WEDragContainer_DropObject"]; 114 } 115 } 116 else if (debugTakeValues) { 117 [[_ctx component] 118 debugWithFormat:@"WEDragContainer: got no value for id '%@'", 119 [_ctx elementID]]; 120 } 121 122 [self->template takeValuesFromRequest:_rq inContext:_ctx]; 123} 124 125- (id)invokeActionForRequest:(WORequest *)_rq inContext:(WOContext *)_ctx { 126 return [self->template invokeActionForRequest:_rq inContext:_ctx]; 127} 128 129/* generating response */ 130 131- (void)appendToResponse:(WOResponse *)_response inContext:(WOContext *)_ctx { 132 NSString *tmp = nil; 133 NSString *ttag; 134 BOOL doDnD; 135 136 if ([_ctx isRenderingDisabled]) { 137 [self->template appendToResponse:_response inContext:_ctx]; 138 return; 139 } 140 141 doDnD = [[[_ctx request] clientCapabilities] doesSupportDHTMLDragAndDrop]; 142 143 if (doDnD) { 144 if (self->isDraggable) 145 doDnD = [self->isDraggable boolValueInComponent:[_ctx component]]; 146 } 147 148 [WEDragScript appendDragScriptToResponse:_response inContext:_ctx]; 149 150 ttag = [self->tag stringValueInComponent:[_ctx component]]; 151 152 if (doDnD) { 153 NSString *teffect, *tdragContent; 154 155 teffect = self->effectsAllowed 156 ? [self->effectsAllowed stringValueInComponent:[_ctx component]] 157 : (NSString *)@"all"; 158 159 tdragContent = @"this.innerHTML"; 160 161 tmp = @"fnSetInfo('%@?%@','%@', %@)"; 162 tmp = [NSString stringWithFormat:tmp, 163 [_ctx elementID], ttag, 164 teffect, 165 tdragContent]; 166 } 167 168 if (self->elementName || doDnD) { 169 /* Note: not using lowercase names since this might break JS? */ 170 [_response appendContentString:@"<SPAN "]; 171 [_response appendContentString:@"ID=\"span_"]; 172 [_response appendContentString:[_ctx elementID]]; 173 [_response appendContentString:@"\" "]; 174 } 175 176 if (doDnD) { 177 [_response appendContentString:@" onDragStart=\""]; 178 [_response appendContentString:tmp]; 179 [_response appendContentString: @"\""]; 180 [_response appendContentString:@" onDrag=\"fnDrag()\""]; 181 [_response appendContentString:@" onDragEnd=\"fnDragEnd()\""]; 182 } 183 184 if (self->elementName || doDnD) { 185 [self appendExtraAttributesToResponse:_response inContext:_ctx]; 186 [_response appendContentString:@">"]; 187 } 188 189 /* add template */ 190 [self->template appendToResponse:_response inContext:_ctx]; 191 192 /* close container */ 193 if (self->elementName || doDnD) 194 [_response appendContentString:@"</SPAN>"]; 195} 196 197/* accessors */ 198 199- (id)template { 200 return self->template; 201} 202 203@end /* WEDragContainer */ 204 205 206@implementation WEDragScript 207 208+ (void)appendDragScriptToResponse:(WOResponse *)_response 209 inContext:(WOContext *)_ctx 210{ 211 NSString *dragScript; 212 BOOL doDnD; 213 214 doDnD = [[[_ctx request] clientCapabilities] doesSupportDHTMLDragAndDrop]; 215 216 if (![[_ctx objectForKey: @"WEDragContainerScriptDone"] boolValue] && doDnD) { 217 dragScript = 218 @"<DIV ID=\"DragDIV\" STYLE=\"position: absolute; visibility: hidden; width: 150;\"></DIV>" 219 @"<SCRIPT LANGUAGE=\"JScript\">\n" 220 @"<!--\n" 221 @"function fnSetInfo(objData, effects, dragContent) {\n" 222 @" event.dataTransfer.clearData(\"Text\");\n" 223 @" event.dataTransfer.setData(\"Text\", objData);\n" 224 @" event.dataTransfer.effectAllowed = effects;\n " 225 @" DragDIV.innerHTML = dragContent;\n" 226 @" DragDIV.style.visibility = \"visible\";\n " 227 @" DragDIV.style.top =window.event.clientY+document.body.scrollTop;\n" 228 @" DragDIV.style.left =window.event.clientX+document.body.scrollLeft;\n" 229 @" DragDIV.style.zIndex += 20; \n" 230 @"}\n" 231 @"function fnDrag() {\n" 232 @" DragDIV.style.top =window.event.clientY+document.body.scrollTop;\n" 233 @" DragDIV.style.left =window.event.clientX+document.body.scrollLeft;\n" 234 @"}\n" 235 @"function fnDragEnd() {\n" 236 @" DragDIV.innerHTML = \"\";\n" 237 @" DragDIV.style.visibility = \"hidden\";\n" 238 @"}\n" 239 @"// -->\n" 240 @"</SCRIPT>"; 241 242 [_response appendContentString: dragScript]; 243 244 [_ctx takeValue: [NSNumber numberWithBool: YES] forKey: 245 @"WEDragContainerScriptDone"]; 246 } 247} 248 249- (void)appendToResponse:(WOResponse *)_response inContext:(WOContext *)_ctx { 250 [[self class] appendDragScriptToResponse:_response inContext:_ctx]; 251} 252 253@end /* WEDragScript */ 254