home *** CD-ROM | disk | FTP | other *** search
/ Tools / WinSN5.0Ver.iso / NETSCAP.50 / WIN1998.ZIP / ns / cmd / macfe / gui / CURLDragHelper.cp < prev    next >
Encoding:
Text File  |  1998-04-08  |  7.0 KB  |  260 lines

  1. /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
  2.  *
  3.  * The contents of this file are subject to the Netscape Public License
  4.  * Version 1.0 (the "NPL"); you may not use this file except in
  5.  * compliance with the NPL.  You may obtain a copy of the NPL at
  6.  * http://www.mozilla.org/NPL/
  7.  *
  8.  * Software distributed under the NPL is distributed on an "AS IS" basis,
  9.  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
  10.  * for the specific language governing rights and limitations under the
  11.  * NPL.
  12.  *
  13.  * The Initial Developer of this code under the NPL is Netscape
  14.  * Communications Corporation.  Portions created by Netscape are
  15.  * Copyright (C) 1998 Netscape Communications Corporation.  All Rights
  16.  * Reserved.
  17.  */
  18.  
  19. //
  20. // Implementaion of a class that contains code common to classes that have to do drag and
  21. // drop for items w/ urls (bookmarks, etc).
  22. //
  23.  
  24. #include "CURLDragHelper.h"
  25. #include "CNetscapeWindow.h"
  26. #include "libi18n.h"
  27. #include "shist.h"
  28. #include "resgui.h"
  29. #include "ufilemgr.h"
  30. #include "mkgeturl.h"
  31. #include "CURLDispatcher.h"
  32. #include "macutil.h"
  33. #include "FSpCompat.h"
  34.  
  35. //
  36. // DoDragSendData
  37. //
  38. // call after a drop. Handles sending the data or creating files.
  39. //
  40. void
  41. CURLDragHelper :: DoDragSendData( const char* inURL, char* inTitle, FlavorType inFlavor, 
  42.                                     ItemReference inItemRef, DragReference inDragRef )
  43. {
  44.     OSErr err = noErr;
  45.     
  46.     if (!inURL)
  47.         return;
  48.     
  49.     switch (inFlavor)
  50.     {
  51.         case 'TEXT':
  52.             {
  53.                 // Just send the URL text
  54.  
  55.                 err = ::SetDragItemFlavorData(
  56.                                                 inDragRef,
  57.                                                 inItemRef,
  58.                                                 inFlavor,
  59.                                                 inURL,
  60.                                                 strlen(inURL),
  61.                                                 0);
  62.                 if (err != noErr)
  63.                     goto Cleanup;
  64.             }
  65.             break;
  66.         
  67.         case emBookmarkFileDrag:
  68.             {
  69.                     // Get the target drop location
  70.                 AEDesc dropLocation;
  71.                 
  72.                 err = ::GetDropLocation(inDragRef, &dropLocation);
  73.                 if (err != noErr)
  74.                 {
  75.                     goto Cleanup;
  76.                 }
  77.                 
  78.                     // Get the directory ID and volume reference number from the drop location
  79.                 SInt16     volume;
  80.                 SInt32     directory;
  81.                 
  82.                 err = GetDropLocationDirectory(&dropLocation, &directory, &volume);
  83.                 //ThrowIfOSErr_(err);    
  84.             
  85.                     // Ok, this is a hack, and here's why:  This flavor type is sent with the
  86.                     // FlavorFlag 'flavorSenderTranslated' which means that this send data routine
  87.                     // will get called whenever someone accepts this flavor.  The problem is that 
  88.                     // it is also called whenever someone calls GetFlavorDataSize().  This routine
  89.                     // assumes that the drop location is something HFS related, but it's perfectly
  90.                     // valid for something to query the data size, and not be a HFS derivative (like
  91.                     // the text widget for example).
  92.                     // So, if the coercion to HFS thingy fails, then we just punt to the textual
  93.                     // representation.
  94.                 if (err == errAECoercionFail)
  95.                 {
  96.                     ::SetDragItemFlavorData(inDragRef, inItemRef,
  97.                             inFlavor, inURL, strlen(inURL), 0);
  98.                     err = noErr;
  99.                     goto Cleanup;
  100.                 }
  101.         
  102.                 if (err != noErr)
  103.                 {
  104.                     goto Cleanup;
  105.                 }
  106.  
  107.                     // Combine with the unique name to make an FSSpec to the new file
  108.                 FSSpec        prototypeFilespec;
  109.                 FSSpec        locationSpec;
  110.                 prototypeFilespec.vRefNum = volume;
  111.                 prototypeFilespec.parID = directory;
  112.                 err = CFileMgr::NewFileSpecFromURLStruct(inURL, prototypeFilespec, locationSpec);
  113.                 if (err && err != fnfErr) // need a unique name, so we want fnfErr!
  114.                     goto Cleanup;
  115.                 
  116.                 // Clean up the title for use as a file name, and stuff it in the spec...
  117.                 do
  118.                 {
  119.                     char* colonPos = XP_STRCHR(inTitle, ':');
  120.                     if (!colonPos)
  121.                         break;
  122.                     *colonPos = '/';
  123.                     
  124.                 } while (1);
  125.                 if (strlen(inTitle) > 31)
  126.                     inTitle[31] = '\0';
  127.                 *(CStr31*)(locationSpec.name) = inTitle;
  128.  
  129.                 // Set the flavor data to our emBookmarkFileDrag flavor with an FSSpec to the new file.
  130.                 err = ::SetDragItemFlavorData(inDragRef, inItemRef, inFlavor, &locationSpec, sizeof(FSSpec), 0);
  131.                 if (err)
  132.                     goto Cleanup;
  133. #define SAVE_SOURCE 0    
  134. #if 0
  135.                 if (theElement->type == LO_IMAGE)
  136.                 {
  137.                     URL_Struct*        request;
  138.                     cstring            urlString;
  139.                     
  140.                     urlString = GetURLFromImageElement(mContext, (LO_ImageStruct*) theElement);
  141.                     if (urlString==NULL) break;
  142.                     request = NET_CreateURLStruct(urlString, NET_DONT_RELOAD);
  143.                     XP_MEMSET(&request->savedData, 0, sizeof(SHIST_SavedData));
  144.                     
  145.                     CURLDispatcher::DispatchToStorage(request, locationSpec);
  146.                     // XP_FREE(urlString);
  147.                     break;
  148.                 }
  149.                 else
  150. #elif SAVE_SOURCE
  151. // jrm 97/08/13. Currently turned off...
  152.                 {
  153.                     URL_Struct* request = NET_CreateURLStruct(inURL, NET_DONT_RELOAD);
  154.                     XP_MEMSET(&request->savedData, 0, sizeof(SHIST_SavedData));
  155.                     CURLDispatcher::DispatchToStorage(request, locationSpec);
  156.                     break;
  157.                 }
  158. #else
  159. // ... in favor of
  160.                 {
  161.                     // create file (same as dragging a bookmark).
  162.                     err = FSpCreateCompat(&locationSpec, emSignature, 'URL ', smSystemScript );
  163.                     if ( err )
  164.                         goto Cleanup;
  165.                     
  166.                     // open file
  167.                     short refNum;
  168.                     err = ::FSpOpenDFCompat( &locationSpec, fsRdWrPerm, &refNum );
  169.                     if ( err )
  170.                         goto Cleanup;
  171.                     
  172.                     // write out URL
  173.                     long actualSizeWritten = strlen(inURL);
  174.                     err = ::FSWrite(refNum, &actualSizeWritten, inURL);
  175.                     if ( err )
  176.                         goto Cleanup;
  177.                     const char foo = 0x0D;
  178.                     actualSizeWritten = sizeof(foo); 
  179.                     err = ::FSWrite(refNum, &actualSizeWritten, &foo);
  180.                     if ( err )
  181.                         goto Cleanup;
  182.  
  183.                     // close file
  184.                     ::FSClose( refNum );
  185.                     break;
  186.                 }
  187. #endif
  188.                 
  189.                 // ÑÑÑ both blocks of the if/then/else above call break, so does this get called?  96-12-17 deeje
  190.                 CFileMgr::UpdateFinderDisplay(locationSpec);
  191.             }
  192.             break;
  193.             
  194.         case emBookmarkDrag:
  195.             {
  196.                 cstring urlAndTitle(inURL);
  197. /*
  198.                 if (theElement->type == LO_IMAGE)
  199.                 {
  200.                     urlAndTitle += "\r[Image]";
  201.                 }
  202.                 else if (theElement->type == LO_TEXT)
  203. */
  204.                 {
  205.                     urlAndTitle += "\r";
  206.                     cstring title;
  207.                     
  208.                     if (inTitle)
  209.                     {
  210.                         urlAndTitle += inTitle;
  211.                     }
  212.                     else
  213.                     {
  214.                         urlAndTitle += inURL;
  215.                     }
  216.                 }            
  217.                 
  218.                 // send url<CR>title with the null terminator
  219.                 ::SetDragItemFlavorData(inDragRef, inItemRef, inFlavor, urlAndTitle, strlen(urlAndTitle) + 1, 0);
  220.             }
  221.             break;    
  222.                 
  223.         default:
  224.             {
  225.                 err = cantGetFlavorErr;
  226.             }
  227.             break;
  228.     }        
  229. Cleanup:
  230.     if (err)
  231.         Throw_(err); // caught by PP handler
  232.         
  233. } // CURLDragHelper :: DoDragSendData
  234.  
  235.  
  236. //
  237. // MakeIconTextValid
  238. //
  239. // Use this to make sure that the caption for a dragged item is not too long, and if it
  240. // is, middle truncates it to avoid the visual turdfest
  241. //
  242. cstring 
  243. CURLDragHelper :: MakeIconTextValid ( const char* inText )
  244. {
  245.     const Uint8 kMaxTitleLength = 50;
  246.     char finalText[100];
  247.     const char* result = nil;
  248.     
  249.     if ( strlen(inText) > kMaxTitleLength ) {
  250.         INTL_MidTruncateString ( 0, inText, finalText, kMaxTitleLength );
  251.         result = finalText;
  252.     }
  253.     else
  254.         result = inText;
  255.         
  256.     return result;
  257.     
  258. } // MakeIconTextValid
  259.  
  260.