~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Frontier Kernel
Frontier/Common/source/claybrowservalidate.c

Version: ~ [ 10.0 ] ~

** Warning: Cannot open xref database.

1 2 /* $Id: claybrowservalidate.c,v 1.5 2005/09/30 15:29:18 icreedon Exp $ */ 3 4 /****************************************************************************** 5 6 UserLand Frontier(tm) -- High performance Web content management, 7 object database, system-level and Internet scripting environment, 8 including source code editing and debugging. 9 10 Copyright (C) 1992-2004 UserLand Software, Inc. 11 12 This program is free software; you can redistribute it and/or modify 13 it under the terms of the GNU General Public License as published by 14 the Free Software Foundation; either version 2 of the License, or 15 (at your option) any later version. 16 17 This program is distributed in the hope that it will be useful, 18 but WITHOUT ANY WARRANTY; without even the implied warranty of 19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 GNU General Public License for more details. 21 22 You should have received a copy of the GNU General Public License 23 along with this program; if not, write to the Free Software 24 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 25 26 ******************************************************************************/ 27 28 #include "frontier.h" 29 #include "standard.h" 30 31 #include "dialogs.h" 32 #include "error.h" 33 #include "strings.h" 34 #include "opinternal.h" 35 #include "claybrowserstruc.h" 36 #include "claybrowservalidate.h" 37 #include "langinternal.h" /* 2005-09-26 creedon */ 38 #include "tablestructure.h" /* 2005-09-26 creedon */ 39 40 #define collidewithequal 0x0001 41 #define collidewitholder 0x0002 42 #define collidewithnewer 0x0004 43 44 #define nocollisions 0 45 46 #define bilateralcollision (collidewitholder + collidewithnewer) 47 48 static long dragmodified; 49 50 //static char *pastefname; 51 52 typedef enum tyaction { 53 54 validatemove, 55 56 validatepaste 57 } tyaction; 58 59 60 byte * actionstrings [] = { 61 62 "\x06" "moving", 63 "\x07" "pasting" 64 }; 65 66 67 enum { 68 ixsomeitems, 69 ixan, 70 ixanewer, 71 ixanolder, 72 ixitemnamed, 73 ixalreadyexists 74 }; 75 76 77 byte * dialogstrings [] = { 78 "\x40" "Some items in this location have the same names as items you're ", 79 "\x02" "An", 80 "\x07" "A newer", 81 "\x08" "An older", 82 #ifdef MACVERSION 83 "\x0d" " item named Ň", 84 "\x22" "Ó already exists in this location." 85 #else 86 "\x0d" " item named \"", 87 "\x22" "\" already exists in this location." 88 #endif 89 }; 90 91 typedef struct tydraginfo { 92 93 long ctcollisions; 94 95 short collisiontype; 96 97 tyaction action; 98 99 hdlheadrecord hdrag; 100 101 hdlheadrecord hdest; 102 103 tydirection dir; 104 105 hdlheadrecord hcollided; 106 107 hdlheadrecord hcompare; 108 } tydraginfo, *ptrdraginfo; 109 110 111 boolean browservalidatedrag (hdlheadrecord hsource, hdlheadrecord hdest, tydirection dir) { 112 113 /* 114 5.0a5 dmb: same level, resort check is bogus; headlink lefts can be the same for a 115 summit and its child, and two summits have different headlinklefts. but we don't 116 want to enforce this anyway, so I just commented it out 117 118 5.0b15 dmb: removed vestigal sourceinfo code 119 */ 120 121 tybrowserinfo destinfo; 122 123 browsergetrefcon (hdest, &destinfo); 124 125 if (destinfo.flvolume) { 126 127 if (dir == down) 128 return (false); 129 130 #if filebrowser 131 if (destinfo.fllocked || destinfo.flhardwarelock) 132 return (false); 133 #endif 134 } 135 136 if ((!destinfo.flfolder) && (dir == right)) /*can't move to the right of a file*/ 137 return (false); 138 139 /* 140 if ((**hsource).headlinkleft == (**hdest).headlinkleft) { //they're at the same level 141 142 if ((dir == up) || (dir == down)) //can't re-sort the list with dragging move 143 return (false); 144 } 145 146 browsergetrefcon (hsource, &sourceinfo); 147 */ 148 149 return (true); 150 } /*browservalidatedrag*/ 151 152 153 static boolean browsercompareforcollision (hdlheadrecord hnode, long dragmodified, bigstring bs1, bigstring bs2, ptrdraginfo draginfo) { 154 155 /* 156 5.0.2b18 dmb: set tmpbit of subs too, so we can detect illegal moves 157 */ 158 159 tybrowserinfo info; 160 161 if (equalidentifiers (bs1, bs2)) { 162 163 opsettmpbitvisit (hnode, (ptrvoid) true); 164 165 oprecursivelyvisit (hnode, infinity, &opsettmpbitvisit, (ptrvoid) true); // set subs too 166 167 ++(*draginfo).ctcollisions; 168 169 (*draginfo).hcollided = hnode; /*last collision*/ 170 171 if ((*draginfo).collisiontype < bilateralcollision) { /*still useful to check dates*/ 172 173 browsergetrefcon (hnode, &info); 174 175 switch (sgn (dragmodified - info.timemodified)) { 176 177 case +1: 178 (*draginfo).collisiontype |= collidewitholder; break; 179 180 case 0: 181 (*draginfo).collisiontype |= collidewithequal; break; 182 183 case -1: 184 (*draginfo).collisiontype |= collidewithnewer; break; 185 } /*switch*/ 186 } 187 } 188 189 return (true); 190 } /*browsercompareforcollision*/ 191 192 193 static boolean collisionvisit (hdlheadrecord hnode, ptrvoid refcon) { 194 195 /* 196 5.0b9 dmb: don't conflict with ourself 197 */ 198 199 bigstring bsnode, bsdrag; 200 ptrdraginfo draginfo = (ptrdraginfo) refcon; 201 202 if (hnode == (*draginfo).hdrag) 203 return (true); 204 205 opgetheadstring (hnode, bsnode); 206 207 opgetheadstring ((*draginfo).hdrag, bsdrag); 208 209 return (browsercompareforcollision (hnode, dragmodified, bsnode, bsdrag, draginfo)); 210 } /*collisionvisit*/ 211 212 213 static boolean browsercollisiondialog (hdlheadrecord hdest, ptrdraginfo draginfo) { 214 215 /* 216 2005-09-26 creedon: changed default order of buttons, default is Duplicate which is the safe option, checks user.prefs.flReplaceDialogExpertMode and if true Replace is the default option 217 */ 218 219 bigstring bs, bscollided, prompt; 220 bigstring nobutton, yesbutton; 221 short itemhit; 222 boolean fl, flExpertMode = false; 223 224 if ((*draginfo).collisiontype == nocollisions) /*no confirmation or deletions needed*/ 225 return (true); 226 227 if ((*draginfo).ctcollisions > 1) { 228 229 copystring (dialogstrings [ixsomeitems], prompt); 230 231 pushstring (actionstrings [(*draginfo).action], prompt); 232 233 pushchar ('.', prompt); 234 } 235 else { 236 copystring (dialogstrings [ixan], prompt); 237 238 switch ((*draginfo).collisiontype) { 239 240 case collidewithnewer: 241 copystring (dialogstrings [ixanewer], prompt); 242 243 break; 244 245 case collidewitholder: 246 copystring (dialogstrings [ixanolder], prompt); 247 248 break; 249 } /*switch*/ 250 251 pushstring (dialogstrings [ixitemnamed], prompt); 252 253 opgetheadstring ((*draginfo).hcollided, bscollided); 254 255 pushstring (bscollided, prompt); 256 257 pushstring (dialogstrings [ixalreadyexists], prompt); 258 } 259 260 getsystemtablescript (idreplacedialogexpertmode, bs); // "user.prefs.flReplaceDialogExpertMode" 261 262 disablelangerror (); 263 264 fl = langrunstring (bs, bs); 265 266 enablelangerror (); 267 268 if (fl) 269 stringisboolean (bs, &flExpertMode); 270 271 if (flExpertMode) { 272 copystring (duplicatebuttontext, nobutton); 273 copystring (replacebuttontext, yesbutton); 274 } 275 else { 276 copystring (duplicatebuttontext, yesbutton); 277 copystring (replacebuttontext, nobutton); 278 } 279 280 itemhit = threewaydialog (prompt, yesbutton, nobutton, cancelbuttontext); 281 282 if (flExpertMode) 283 switch (itemhit) { 284 285 case 1: 286 itemhit = 2; 287 288 break; 289 290 case 2: 291 itemhit = 1; 292 break; 293 294 } 295 296 switch (itemhit) { 297 298 case 1: 299 opcleartmpbits (); 300 301 /*caller should rename items where conflicts occur*/ 302 303 return (true); 304 305 case 2: 306 /*caller should delete all files with their tmpbit set*/ 307 308 return (true); 309 310 default: 311 opcleartmpbits (); 312 313 return (false); 314 } /* switch */ 315 316 } /*browsercollisiondialog*/ 317 318 319 static boolean validatemovevisit (hdlheadrecord hnode, ptrvoid refcon) { 320 321 tybrowserinfo info; 322 ptrdraginfo draginfo = (ptrdraginfo) refcon; 323 hdlheadrecord hdest = (*draginfo).hdest; 324 325 (*draginfo).hdrag = hnode; 326 327 browsergetrefcon (hnode, &info); 328 329 dragmodified = info.timemodified; 330 331 if ((*draginfo).dir == right) 332 return (oprecursivelyvisit (hdest, 1, &collisionvisit, draginfo)); 333 else 334 return (oplistvisit (opfirstatlevel (hdest), &collisionvisit, draginfo)); 335 } /*validatemovevisit*/ 336 337 338 static boolean browservalidateinsertion (hdlheadrecord hdest, hdlheadrecord hscrap, tydirection dir, tyaction action) { 339 340 /* 341 confirm that the user wants to overwrite existing files, 342 we return false to cancel the operation. 343 */ 344 345 tydraginfo draginfo; 346 347 draginfo.hdest = hdest; 348 349 draginfo.dir = dir; 350 351 draginfo.ctcollisions = draginfo.collisiontype = 0; 352 353 draginfo.action = action; 354 355 opcleartmpbits (); 356 357 if (hscrap == nil) 358 opvisitmarked (down, &validatemovevisit, &draginfo); 359 else 360 oplistvisit (hscrap, &validatemovevisit, &draginfo); 361 362 return (browsercollisiondialog (hdest, &draginfo)); 363 } /*browservalidateinsertion*/ 364 365 366 boolean browservalidatemove (hdlheadrecord hdest, hdlheadrecord hscrap, tydirection dir) { 367 368 return (browservalidateinsertion (hdest, hscrap, dir, validatemove)); 369 } /*browservalidatemove*/ 370 371 372 boolean browservalidatepaste (hdlheadrecord hscrap, hdlheadrecord hdest, tydirection dir) { 373 374 /* 375 return false to cancel the paste. 376 377 assume that paste always happens in the list of the cursor's parent. 378 */ 379 380 #if filebrowser 381 382 hdlheadrecord hfolder = (**hdest).headlinkleft; 383 384 if (hfolder == hdest) { 385 386 alertdialog ("\x32" "CanŐt paste at the top level of a browser outline."); 387 388 return (false); 389 } 390 391 #endif 392 393 if (!browservalidateinsertion (hdest, hscrap, dir, validatepaste)) /*user declined to replace already-existing files*/ 394 return (false); 395 396 browserdeletenodeswithtmpbitset (); 397 398 return (true); 399 } /*browservalidatepaste*/ 400 401 402 #if 0 /*we're not doing a folder-based clipboard, but if we did, this is how you would validate a paste*/ 403 404 static boolean pastecollisionvisit (hdlheadrecord hnode, ptrdraginfo draginfo) { 405 406 bigstring fname; 407 bigstring bsnode; 408 409 copystring (pastefname, fname); 410 411 opgetheadstring (hnode, bsnode); 412 413 return (browsercompareforcollision (hnode, dragmodified, bsnode, fname)); 414 } /*pastecollisionvisit*/ 415 416 417 static boolean validatepastecallback (bigstring fname, tyfileinfo *info, ptrdraginfo draginfo) { 418 419 dragmodified = (*info).timemodified; 420 421 pastefname = (char *) fname; 422 423 return (oprecursivelyvisit ((*draginfo).hdest, 1, &pastecollisionvisit, draginfo)); 424 } /*validatepastecallback*/ 425 426 427 static boolean browservalidatefolderpaste (hdlheadrecord hfolder, FSSpec *clipfolderspec) { 428 429 /* 430 check for collisions -- if there already is a file in the target folder 431 with the same name as one of the items we're pasting, a dialog appears 432 confirming the replacement. all files that need to be deleted have their 433 tmpbits set. the caller should delete them. we don't do the deletion 434 here so that the deletions can be undoable. 435 */ 436 437 tydraginfo; 438 439 if ((**hfolder).headlinkleft == hfolder) { 440 441 alertdialog ("\x32" "CanŐt paste at the top level of a browser outline."); 442 443 return (false); 444 } 445 446 draginfo.hdest = hfolder; 447 448 draginfo.ctcollisions = draginfo.collisiontype = 0; 449 450 opcleartmpbits (); 451 452 folderloop (clipfolderspec, false, &validatepastecallback, &draginfo); 453 454 return (browsercollisiondialog (hfolder, "\x07" "pasting")); 455 } /*browservalidatefolderpaste*/ 456 457 #endif 458 459 460 static ptrstring pcommand; 461 462 463 static boolean compareforcopyvisit (hdlheadrecord hnode, ptrvoid refcon) { 464 465 bigstring bs, bsnode; 466 ptrdraginfo draginfo = (ptrdraginfo) refcon; 467 468 if (hnode == (*draginfo).hcompare) 469 return (true); 470 471 opgetheadstring (hnode, bsnode); 472 473 opgetheadstring ((*draginfo).hcompare, bs); 474 475 if (!equalidentifiers (bsnode, bs)) 476 return (true); 477 478 copystring ("\x06" "CanŐt ", bs); 479 480 pushstring (pcommand, bs); 481 482 pushstring ("\x35" " because there are two or more selected items named Ň", bs); 483 484 pushstring (bsnode, bs); 485 486 pushstring ("\x02" "Ó.", bs); 487 488 alertdialog (bs); 489 490 return (false); /*stop both traversals*/ 491 } /*compareforcopyvisit*/ 492 493 494 static boolean validatecopyvisit (hdlheadrecord hnode, ptrvoid refcon) { 495 496 tydraginfo draginfo; 497 498 draginfo.hcompare = hnode; 499 500 return (opvisitmarked (down, &compareforcopyvisit, &draginfo)); 501 } /*validatecopyvisit*/ 502 503 504 boolean browservalidatecopy (bigstring bscommand) { 505 506 /* 507 don't allow a copy if there's a node selected that has the 508 same name as another node that's selected. we do the dialog 509 here, the caller should just exit if we return false. 510 */ 511 512 pcommand = bscommand; /*set static to point to string*/ 513 514 return (opvisitmarked (down, &validatecopyvisit, nil)); 515 } /*browservalidatecopy*/ 516 517 518

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.