home *** CD-ROM | disk | FTP | other *** search
/ Tools / WinSN5.0Ver.iso / NETSCAP.50 / WIN1998.ZIP / ns / cmd / macfe / central / mattach.cp < prev    next >
Encoding:
Text File  |  1998-04-08  |  19.5 KB  |  838 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. #include "mattach.h"
  20.  
  21. // PowerPlant
  22. #include <LWindow.h>
  23.  
  24. // macfe
  25. #include "ufilemgr.h"
  26. #include "macutil.h"
  27. #include "resgui.h"
  28. #include "uapp.h"
  29. #include "msgcom.h"
  30. #include "uerrmgr.h"
  31. #include "CBrowserWindow.h"
  32. #include "CBrowserContext.h"
  33. #include "UModalDialogs.h"
  34. #include "LGAEditField.h"
  35. // For TEXT_PLAIN
  36. #include "net.h"
  37.  
  38.  
  39. #define msg_SelectionChanged    'sele'
  40.  
  41. CMailAttachment::CMailAttachment(const FSSpec & spec)
  42. :    fDesiredType(nil)
  43. ,    fRealType(nil)
  44. ,    fSelected(false)
  45. ,    fRealName(nil)
  46. ,    fDescription(nil)
  47. {
  48.     fURL = CFileMgr::GetURLFromFileSpec(spec);    
  49.     FInfo fndrInfo;
  50.     FSpGetFInfo( &spec, &fndrInfo );
  51.     fFileType = fndrInfo.fdType;
  52.     fFileCreator = fndrInfo.fdCreator;
  53.     ComposeDescription();
  54. }
  55.  
  56. CMailAttachment::CMailAttachment(const MSG_AttachmentData * data)
  57. {
  58.     memset(this, 0, sizeof(CMailAttachment));
  59.     fURL = data->url ? XP_STRDUP(data->url) : nil;
  60.     fDesiredType = data->desired_type ? XP_STRDUP(data->desired_type) : nil;
  61.     fRealType = data->real_type ? XP_STRDUP(data->real_type) : nil;
  62.     fRealName = data->real_name ? XP_STRDUP(data->real_name) : nil;
  63.  
  64.     // this designates that we can enable the Source/Text radio buttons
  65.     // for this item -> we really need more help to make the decision 
  66.     fFileType = 'TEXT';        
  67.     fFileCreator = '????';
  68.  
  69.     fDescription = data->description ? XP_STRDUP(data->description) : nil;
  70. }
  71.  
  72.  
  73. void CMailAttachment::FreeMembers()
  74. {
  75.     if (fURL)            XP_FREE(fURL);            fURL             = nil;
  76.     if (fDesiredType)    XP_FREE(fDesiredType);    fDesiredType     = nil;
  77.     if (fRealType)        XP_FREE(fRealType);        fRealType         = nil;
  78.     if (fRealName)        XP_FREE(fRealName);        fRealName        = nil;
  79.     if (fDescription)    XP_FREE(fDescription);    fDescription     = nil;
  80. }
  81.  
  82. CStr255 & CMailAttachment::UrlText()
  83. {
  84.     CStr255 text;
  85.     if ( fURL && NET_IsLocalFileURL(fURL) )
  86.     {
  87.         cstring tmp = CFileMgr::FileNameFromURL ( fURL );
  88.         NET_UnEscape(tmp);
  89.         text = tmp;
  90.     }
  91.     else
  92.     {
  93.         text = fURL;    // Default
  94.         if (fURL)        // Messages get special cased
  95.             if ((XP_STRNCASECMP(fURL, "snews:",6) == 0) ||
  96.                 (XP_STRNCASECMP(fURL, "news:",5) == 0))
  97.                 text = GetPString(ATTACH_NEWS_MESSAGE);
  98.             else if (XP_STRNCASECMP(fURL, "mailbox:",8) == 0)
  99.                 text = GetPString(ATTACH_MAIL_MESSAGE);
  100.     }
  101.     return text;
  102. }
  103.  
  104.  
  105. void
  106. CMailAttachment::ComposeDescription()
  107. {
  108.     if (fFileCreator == '????' || fDescription != nil)
  109.         return;
  110.     
  111.     OSErr         err;
  112.     DTPBRec        pb;
  113.     Str255        appName;
  114.     char    *    suffix;
  115.     UInt32        suffixLen;
  116.     UInt32        descriptionLen;
  117.         
  118.     Try_
  119.     {
  120.         for (short vRefNum = -1; /**/; vRefNum --)
  121.         {
  122.             pb.ioVRefNum = vRefNum;
  123.             pb.ioNamePtr = nil;
  124.             err = ::PBDTGetPath(&pb);    // sets dt ref num in pb
  125.             if (err != noErr)
  126.                 break;
  127.  
  128.             pb.ioCompletion    =    nil;
  129.             pb.ioNamePtr    =    appName;
  130.             pb.ioIndex        =     0;
  131.             pb.ioFileCreator=    fFileCreator;
  132.             err = ::PBDTGetAPPLSync(&pb);
  133.             if (err == noErr)
  134.                 break;
  135.         }
  136.         ThrowIfOSErr_(err);
  137.  
  138.         suffix = (fFileType == 'APPL') ? nil : suffix = GetCString(DOCUMENT_SUFFIX);
  139.         suffixLen = (suffix != nil) ? strlen(suffix) + 1 : 0;    // + 1 for space and 
  140.         
  141.         // + 1 for terminator, space is taken care of in suffixLen
  142.         descriptionLen = appName[0] + 1;
  143.         if (suffix != nil) descriptionLen += suffixLen;
  144.  
  145.         fDescription = (char *) XP_ALLOC(descriptionLen);
  146.         ThrowIfNULL_(fDescription);
  147.         
  148.         if (suffix != nil)
  149.         {
  150.             p2cstr(appName);
  151.             sprintf(fDescription, "%s %s", (char *) appName, suffix);
  152.         }
  153.         else
  154.         {
  155.             ::BlockMoveData(&appName[1], fDescription, appName[0]);
  156.             fDescription[appName[0]] = '\0';
  157.         }
  158.     }    
  159.     Catch_(errNum)
  160.     {
  161.         XP_FREEIF(fDescription);
  162.         fDescription = nil;
  163.     }        
  164.     EndCatch_
  165. }
  166.  
  167. //
  168. // class CAttachmentList
  169. //
  170.  
  171. CAttachmentList::CAttachmentList() : LArray(sizeof(CMailAttachment))
  172. {
  173. }
  174.  
  175. CAttachmentList::~CAttachmentList()
  176. {
  177.     CMailAttachment attach;
  178.     LArrayIterator iter(*this);
  179.     while (iter.Next(&attach))
  180.         attach.FreeMembers();
  181. }
  182.  
  183. // Clones the list, and its elements
  184. CAttachmentList * CAttachmentList::Clone(CAttachmentList * clone)
  185. {
  186.     CAttachmentList *  newList = new CAttachmentList;
  187.     ThrowIfNil_(newList);
  188.     if (clone)    // Duplicate all the members of a list
  189.     {
  190.         LArrayIterator iter(*clone);
  191.         
  192.         CMailAttachment attach;
  193.         while (iter.Next(&attach))
  194.         {
  195.             CMailAttachment newAttach;
  196.             newAttach.fURL = attach.fURL ? XP_STRDUP(attach.fURL) : nil;
  197.             newAttach.fDesiredType = attach.fDesiredType ? XP_STRDUP(attach.fDesiredType) : nil;
  198.             newAttach.fFileType = attach.fFileType;
  199.             newAttach.fFileCreator = attach.fFileCreator;
  200.             newList->InsertItemsAt(1, 10000, &newAttach);
  201.         }
  202.     }
  203.     return newList;
  204. }
  205.  
  206. void CAttachmentList::RemoveItemsAt(Uint32    inCount, Int32    inAtIndex)
  207. {
  208.     CMailAttachment attach;
  209.     for (int i =0; i<inCount; i++)
  210.     {
  211.         if (FetchItemAt(i+inAtIndex, &attach))
  212.             attach.FreeMembers();
  213.     }
  214.     LArray::RemoveItemsAt(inCount, inAtIndex);
  215. }
  216.  
  217.  
  218.  
  219. // Creates an attachment list to be passed into MSG_SetAttachmentList
  220. // Note: we do not duplicate url/MIME strings, since msg library creates its own copy
  221. MSG_AttachmentData* CAttachmentList::NewXPAttachmentList()
  222. {
  223.     if (GetCount() == 0)
  224.         return nil;
  225.     
  226.     Size desiredSize = (GetCount()+1) * sizeof(MSG_AttachmentData);
  227.     
  228.     MSG_AttachmentData* newList = (MSG_AttachmentData*)XP_ALLOC(desiredSize);
  229.     ThrowIfNil_(newList);
  230.  
  231.     memset(newList, 0, desiredSize);
  232.     
  233.  
  234.     CMailAttachment attach;
  235.     int i = 0;    // Watch out, list starts at 1, C arrays at 0
  236.     while (FetchItemAt(i+1, &attach))
  237.     {
  238.         newList[i].url = attach.fURL;
  239.         newList[i].desired_type = attach.fDesiredType;
  240.         newList[i].real_type = attach.fRealType;
  241.         newList[i].real_name = attach.fRealName;
  242.         if (NET_IsLocalFileURL(attach.fURL))
  243.         {
  244.             char *macType = (char*) XP_ALLOC(9);    ThrowIfNil_(macType);
  245.             sprintf(macType, "%X", attach.fFileType);
  246.             newList[i].x_mac_type = macType;
  247.             
  248.             char *macCreator = (char*) XP_ALLOC(9);    ThrowIfNil_(macCreator);
  249.             sprintf(macCreator, "%X", attach.fFileCreator);
  250.             newList[i].x_mac_creator = macCreator;
  251.  
  252.             if (attach.fDescription)
  253.                 newList[i].description = XP_STRDUP(attach.fDescription);        
  254.         }
  255.         i++;
  256.     }
  257.     return newList;
  258. }
  259.  
  260. // Deletes the list created by NewXPAttachmentList
  261. void CAttachmentList::DeleteXPAttachmentList(MSG_AttachmentData* list)
  262. {
  263.     if (list == nil)
  264.         return;
  265.     int i=0;
  266.     
  267.     while (list[i].url != nil)
  268.     {
  269.         if (list[i].x_mac_type != nil)            XP_FREE(list[i].x_mac_type);
  270.         if (list[i].x_mac_creator != nil)        XP_FREE(list[i].x_mac_creator);
  271.         if (list[i].description != nil)        XP_FREE(list[i].description);        
  272.         i++;
  273.     }
  274.     XP_FREE(list);
  275. }
  276.  
  277. void CAttachmentList::InitializeFromXPAttachmentList(const MSG_AttachmentData* list)
  278. {
  279.     // Empty the list
  280.     RemoveItemsAt(mItemCount, 1);
  281.  
  282.     // Initialize from scratch
  283.     int i=0;
  284.     
  285.     while (list[i].url != nil)
  286.     {
  287.         CMailAttachment attach(&list[i]);
  288.         InsertItemsAt(1, mItemCount+1, &attach);
  289.         i++;
  290.     }
  291. }
  292.  
  293. // 
  294. // class CAttachmentView
  295. //
  296.  
  297. CAttachmentView::CAttachmentView( LStream * inStream) :
  298.     LFinderView(inStream),
  299.     mAttachList(nil),
  300.     mCurrentlyAddedToDropList(true), // cuz LDragAndDrop constructor adds us.
  301.     mSelectedItemCount(0),
  302.     mNotifyAttachmentChanges(true)
  303. {
  304.     fNumberColumns         = 1;
  305.     fHighlightRow         = false;
  306.     fColumnIDs[0]         = HIER_COLUMN;
  307.     fCellHeight         = 18;
  308. }
  309.  
  310. void CAttachmentView::FinishCreateSelf()
  311. {
  312.     LFinderView::FinishCreateSelf();
  313. }
  314.  
  315. void CAttachmentView::SelectItem( UInt32 cell, Boolean refresh )
  316. {
  317.     EventRecord        dummy;
  318.     
  319.     memset(&dummy, 0, sizeof(dummy));
  320.     this->SelectItem( dummy, cell, refresh );
  321. }
  322.  
  323. void CAttachmentView::SetAttachList(CAttachmentList * list)    
  324. {
  325.     mAttachList = list;
  326.     SyncDisplay(mAttachList ? mAttachList->GetCount() : 0);
  327.     
  328.     // Select the first item in the list
  329.     if (mAttachList != nil)
  330.         SelectItem(1, TRUE);    // tj
  331. }
  332.  
  333. Boolean    CAttachmentView::GetSelectedAttachment(CMailAttachment &attach)
  334. {
  335.     UInt32 cell = FirstSelectedCell();
  336.     if (cell > 0)
  337.     {
  338.         mAttachList->FetchItemAt(cell, &attach);
  339.         return TRUE;
  340.     }
  341.     else
  342.         return false;
  343. }
  344.  
  345.  
  346. void CAttachmentView::AddMailAttachment(CMailAttachment * attach, Boolean refresh)
  347. {
  348.     XP_ASSERT( mAttachList);
  349.  
  350.     // Insert after the first selected cell,
  351.     // if none, the end of the list
  352.     UInt32 cell = FirstSelectedCell();
  353.     if (cell == 0)
  354.         cell =  mAttachList->GetCount() + 1;
  355.     else
  356.         cell++;
  357.     
  358.     mAttachList->InsertItemsAt(1, cell, attach);
  359.     SelectItem( cell, TRUE );
  360.     if (refresh)
  361.         Refresh();
  362.     SyncDisplay(mAttachList->GetCount());
  363.     
  364.     if (mNotifyAttachmentChanges)
  365.         BroadcastMessage(msg_AttachmentsAdded, this);
  366. }
  367.  
  368. void CAttachmentView::ModifyMailAttachment(Int32 cell, CMailAttachment * attach, Boolean refresh)
  369. {
  370.     CMailAttachment dummy;
  371.     if (cell == SELECTED_CELL)
  372.         cell = FirstSelectedCell();
  373.  
  374.     XP_ASSERT(mAttachList->FetchItemAt(cell, &attach));
  375.  
  376.     mAttachList->AssignItemsAt(1, cell, &attach);
  377.     if (refresh)
  378.         Refresh();
  379. }
  380.  
  381. void CAttachmentView::SetMimeType(char * type)
  382. {
  383.     Boolean needRefresh = false;
  384.     LArrayIterator iter(*mAttachList);
  385.     CMailAttachment attach;
  386.     
  387.     for (int i=1; i<= mAttachList->GetCount(); i++)
  388.     {
  389.         if (mAttachList->FetchItemAt(i, &attach))
  390.         {
  391.             if ( attach.fSelected )
  392.             {
  393.                 if (attach.fDesiredType != nil)
  394.                     XP_FREE(attach.fDesiredType);
  395.             
  396.                 if (type)
  397.                     attach.fDesiredType = XP_STRDUP(type);
  398.                 else
  399.                     attach.fDesiredType = nil;
  400.             
  401.                 mAttachList->AssignItemsAt(1, i, &attach);    
  402.                 
  403.                 needRefresh = true;            
  404.             }
  405.         }
  406.     }
  407.     
  408.     if (needRefresh)
  409.         Refresh();
  410. }
  411.  
  412. void CAttachmentView::AddFile(const FSSpec& spec)
  413. {
  414.     if (CmdPeriod())    // If we drop the whole HD, allow bailout
  415.         return;
  416.     
  417.     if (CFileMgr::IsFolder(spec))
  418.     {
  419.         FSSpec newSpec;
  420.         FInfo     dummy;
  421.         Boolean dummy2;
  422.         CFileIter    iter(spec);
  423.         while (iter.Next(newSpec, dummy, dummy2))
  424.             AddFile(newSpec);
  425.     }
  426.     else
  427.     {
  428.         CMailAttachment attach(spec);
  429.         AddMailAttachment(&attach, false);
  430.     }
  431.     Refresh();
  432. }
  433.  
  434. void CAttachmentView::DeleteSelection(Boolean refresh)
  435. {
  436.     CMailAttachment attach;
  437.     LArrayIterator iter(*mAttachList);
  438.     Boolean needRefresh = false;
  439.     Int32 itemToSelect = 0;
  440.     
  441.     while (iter.Next(&attach))
  442.     {
  443.         if (attach.fSelected)
  444.         {
  445.             needRefresh = TRUE;
  446.             itemToSelect = mAttachList->FetchIndexOf(&attach);
  447.             mAttachList->Remove(&attach);
  448.         }
  449.     }
  450.     if (itemToSelect != 0)
  451.         SelectItem(itemToSelect, TRUE);
  452.     if (refresh && needRefresh)
  453.         Refresh();
  454.     if (needRefresh)
  455.         BroadcastMessage(msg_SelectionChanged, nil);
  456.     if (needRefresh)
  457.         SyncDisplay(mAttachList->GetCount());
  458.         
  459.     
  460.     if (mNotifyAttachmentChanges)
  461.         BroadcastMessage(msg_AttachmentsRemoved, this);    
  462. }
  463.  
  464. Boolean CAttachmentView::SyncDisplay( UInt32 visCells )
  465. {
  466.     return LFinderView::ResizeTo( fCellHeight * visCells, mImageSize.width );
  467. }
  468.  
  469. void CAttachmentView::DrawCellColumn( UInt32 cell, UInt16 /*column*/ )
  470. {
  471.     DrawHierarchy( cell );
  472. }
  473.  
  474. Boolean CAttachmentView::IsCellSelected( Int32 cell )
  475. {
  476. //    XP_ASSERT( mAttachList);
  477.     if (mAttachList)
  478.     {
  479.         CMailAttachment attach;
  480.         if (mAttachList->FetchItemAt(cell, &attach))
  481.             return attach.fSelected;
  482.         else
  483.             return false;
  484.     }
  485.     else
  486.         return false;
  487. }
  488.  
  489. void CAttachmentView::CellText( Int32 cell, CStr255& text )
  490. {
  491. //    XP_ASSERT( mAttachList);
  492.     if (mAttachList)
  493.     {
  494.         CMailAttachment attach;
  495.         if (mAttachList->FetchItemAt(cell, &attach))
  496.             text = attach.UrlText();        
  497.         else
  498.     #ifdef DEBUG
  499.             text = "What's up";
  500.     #else
  501.             text = CStr255::sEmptyString;
  502.     #endif
  503.     }
  504. }
  505.  
  506. void CAttachmentView::GetTextRect( UInt32 cell, Rect& where ) 
  507. {
  508.     where.top = ( ( cell - 1 ) * fCellHeight ) +
  509.         mPortOrigin.v + mImageLocation.v;
  510.     where.bottom = where.top + fCellHeight;
  511.     where.left = ( this->CellIndentLevel( cell ) * LEVEL_OFFSET ) + 
  512.         mPortOrigin.h + mImageLocation.h + ICON_WIDTH;
  513.     
  514.     CStr255    text;
  515.     
  516.     CellText(cell, text);
  517.     where.right = where.left + StringWidth(text) + 4;
  518.     // where.right = where.left + mImageSize.width;
  519. }
  520.  
  521. void CAttachmentView::GetIconRect( UInt32 cell, Rect& where )
  522. {
  523.     where.top = ( ( cell - 1 ) * fCellHeight ) + mPortOrigin.v + mImageLocation.v;
  524.     where.bottom = where.top + ICON_HEIGHT;
  525.     where.left = ( this->CellIndentLevel( cell ) * LEVEL_OFFSET ) +
  526.         + mPortOrigin.h + mImageLocation.h;
  527.     where.right = where.left + ICON_WIDTH;
  528. }
  529.  
  530. void CAttachmentView::GetWiglyRect( UInt32 /*cell*/, Rect& rect )
  531. {
  532.     rect.top = rect.bottom = rect.left = rect.right = 0;
  533. }
  534.  
  535. void CAttachmentView::SelectItem( const EventRecord& event, UInt32 cell, Boolean refresh )
  536. {
  537.     Boolean        shift = ( event.modifiers & shiftKey ) != 0;
  538.  
  539.     if (  !shift )
  540.         ClearSelection();
  541.  
  542.     CMailAttachment attach;
  543.     if (mAttachList->FetchItemAt(cell, &attach))
  544.     {
  545.         if ( !shift )
  546.             attach.fSelected = TRUE;
  547.         else
  548.             attach.fSelected = !attach.fSelected;
  549.             
  550.         if (attach.fSelected)
  551.             mSelectedItemCount++;
  552.         else
  553.             mSelectedItemCount--;
  554.         
  555.         mAttachList->AssignItemsAt(1, cell, &attach);
  556.     }
  557.  
  558.     BroadcastMessage(msg_SelectionChanged, nil);
  559.  
  560.     if (refresh)
  561.         Refresh();
  562. }
  563.  
  564. void CAttachmentView::ClearSelection()
  565. {
  566. //    XP_ASSERT(mAttachList);
  567.     if (mAttachList)
  568.     {
  569.         CMailAttachment attach;
  570.         int i=1;
  571.         while (mAttachList->FetchItemAt(i, &attach))
  572.         {
  573.             if (attach.fSelected)
  574.             {
  575.                 attach.fSelected = false;
  576.                 mAttachList->AssignItemsAt(1, i, &attach);
  577.                 
  578.                 RefreshCells(i, i, false);
  579.             }
  580.             
  581.             i++;
  582.         }
  583.         
  584.     }
  585.     mSelectedItemCount = 0;
  586. }
  587.  
  588. UInt32 CAttachmentView::GetVisibleCount()
  589. {
  590. //    XP_ASSERT(mAttachList != nil);
  591.     if (mAttachList)
  592.         return mAttachList->GetCount();
  593.     else
  594.         return 0;
  595. }
  596.  
  597. UInt32 CAttachmentView::FirstSelectedCell()
  598. {
  599.     CMailAttachment attach;
  600.     if (!mAttachList)
  601.         return 0;
  602.  
  603.     LArrayIterator iter(*mAttachList);
  604.     int i = 0;
  605.     while (iter.Next(&attach))
  606.     {
  607.         i++;
  608.         if (attach.fSelected)
  609.             return i;
  610.     }
  611.     return 0;
  612. }
  613.  
  614. Boolean CAttachmentView::HandleKeyPress( const EventRecord& inEvent )
  615. {
  616.     Char16        key = inEvent.message;
  617.     Char16        character = key & charCodeMask;
  618.     switch ( character )
  619.     {
  620.         case char_Backspace:
  621.         case char_FwdDelete:
  622.             DeleteSelection();
  623.             return TRUE;
  624.         default:
  625.             return LFinderView::HandleKeyPress( inEvent );
  626.     }
  627.     return false;
  628. }
  629.  
  630. Boolean CAttachmentView::ItemIsAcceptable(    DragReference    inDragRef,
  631.                                             ItemReference    inItemRef    )
  632. {
  633.     FlavorFlags flavorFlags;
  634.     
  635.     if (::GetFlavorFlags( inDragRef, inItemRef, flavorTypeHFS, &flavorFlags) == noErr)
  636.         return true;
  637.  
  638.         
  639.     return (::GetFlavorFlags(inDragRef, inItemRef, 'TEXT', &flavorFlags) == noErr);
  640. }    
  641.  
  642. void    
  643. CAttachmentView::DoDragReceive(DragReference inDragRef)
  644. {
  645.     Boolean    saveFlag;
  646.     Boolean success = false; // so we don't broadcast if it fails
  647.     saveFlag = mNotifyAttachmentChanges; 
  648.     mNotifyAttachmentChanges = false;
  649.     Try_
  650.     {
  651.         // Put this in a try block, because this is called
  652.         // from the Finder!  So it fixes bug with nasty hang attaching certain files.
  653.         LFinderView::DoDragReceive(inDragRef);
  654.         success = true;
  655.     }
  656.     Catch_(err)
  657.     {
  658.     }
  659.     EndCatch_
  660.     mNotifyAttachmentChanges = saveFlag;
  661.     
  662.     if (success & saveFlag)
  663.         BroadcastMessage(msg_AttachmentsAdded, this);
  664. }
  665.  
  666.  
  667. void CAttachmentView::ReceiveDragItem(    DragReference     inDragRef, 
  668.                                         DragAttributes    /*flags*/, 
  669.                                         ItemReference     inItemRef, 
  670.                                         Rect&             /*itemBounds*/)
  671. {
  672.     OSErr        err;
  673.     HFSFlavor    itemFile;
  674.     Size        itemSize = sizeof(itemFile);
  675.     
  676.     ClearSelection();
  677.         
  678.     // Get the HFS data
  679.     err = ::GetFlavorData( inDragRef, inItemRef, flavorTypeHFS, &itemFile, &itemSize, 0);
  680.     if (err == noErr)
  681.         AddFile(itemFile.fileSpec);    
  682.     else if(err == badDragFlavorErr )
  683.     {
  684.         err = GetHFSFlavorFromPromise (inDragRef, inItemRef, &itemFile, true);
  685.         if( err == noErr )
  686.             AddFile( itemFile.fileSpec );
  687.         else
  688.         {            
  689.             char *url = nil;
  690.             itemSize = 0;
  691.         
  692.             err = GetFlavorDataSize(inDragRef, inItemRef, 'TEXT', &itemSize);
  693.             if (err == noErr)
  694.             {
  695.                 char *title;
  696.                 
  697.                 url = (char *) XP_ALLOC(itemSize+1); ThrowIfNil_(url);
  698.                 err = ::GetFlavorData( inDragRef, inItemRef, 'TEXT', url, &itemSize, 0);
  699.                 url[itemSize] = '\0';
  700.                 
  701.                 if (err == noErr)
  702.                 {
  703.                     title = strchr(url, '\r');
  704.                     if (title != nil)
  705.                         *title = '\0';
  706.                                 
  707.                     CMailAttachment attach(url, nil, nil, nil);
  708.                     AddMailAttachment(&attach, false);
  709.                 }
  710.             }
  711.         }        
  712.         // Back to PP
  713.         ThrowIfOSErr_(err);
  714.     }    
  715. }    
  716.  
  717. void CAttachmentView::TakeOffDuty()
  718. {
  719.     if (mAttachList != nil)
  720.         LFinderView::TakeOffDuty();
  721. }
  722.  
  723. void CAttachmentView::InsideDropArea( DragReference /*inDragRef*/ )
  724. {
  725.     // don't do the Finder insert highlighting 
  726. }
  727.     
  728.  
  729. void CAttachmentView::ListenToMessage(MessageT inMessage, void* ioParam)
  730. {
  731.     switch(inMessage)
  732.     {
  733.         case msg_AttachFile:
  734.             StandardFileReply myReply;
  735.             SFTypeList dummy;
  736.             Point myPoint;
  737.             ::SetPt(&myPoint,-1,-1); // Center window
  738.             UDesktop::Deactivate();    // Always bracket this
  739.               CustomGetFile ( nil, -1, dummy, &myReply, kSFAttachFile, myPoint, 
  740.                       nil, nil, nil, nil, nil);            
  741.             UDesktop::Activate();
  742.             if (myReply.sfGood)
  743.                 AddFile(myReply.sfFile);
  744.             break;
  745.             
  746.         case msg_AttachWeb:
  747.             AddWebPageWithUI((unsigned char *)ioParam);
  748.             break;
  749.             
  750.         case msg_RemoveAttach:
  751.             DeleteSelection();
  752.             break;
  753.         
  754.         default:
  755.             break;
  756.     }
  757. }
  758.  
  759. void CAttachmentView::AddWebPageWithUI(unsigned char *defaultText)
  760. {
  761.     // Put up dialog
  762.     StDialogHandler handler(10616, nil);
  763.     // Select the "URL" edit field
  764.     LWindow* dialog = handler.GetDialog();
  765.     LGAEditField *urlfield = (LGAEditField*)dialog->FindPaneByID('edit');
  766.     SignalIf_(!urlfield);
  767.     if (!urlfield)
  768.         return;
  769.     urlfield->SetDescriptor(defaultText);
  770.     urlfield->SelectAll();
  771.     dialog->SetLatentSub(urlfield);
  772.     // Run the dialog
  773.     MessageT message;
  774.             
  775.     do {
  776.         message = handler.DoDialog();
  777.     } while (message != msg_OK && message != msg_Cancel);
  778.     
  779.     // Use the result.
  780.     if (message == msg_OK)
  781.     {
  782.         CStr255 result;
  783.         char* url=nil;
  784.         urlfield->GetDescriptor(result);
  785.         if (result.Length() > 0)
  786.         {
  787.             url = (char*)XP_ALLOC(result.Length() + 1);
  788.             ThrowIfNULL_(result);
  789.             ::BlockMoveData(&result[1], url, result.Length());
  790.             url[result.Length()] = '\0';
  791.         }
  792.         CMailAttachment attach(url, nil, nil, nil);
  793.         AddMailAttachment(&attach, false);
  794.     }
  795. };
  796.  
  797. void CAttachmentView::HiliteDropArea(DragReference inDragRef)
  798. {
  799.     LDragAndDrop::HiliteDropArea(inDragRef);
  800. }
  801.  
  802.  
  803. Boolean
  804. CAttachmentView::ProcessCommand(CommandT inCommand, void *ioParam)
  805. {
  806.     if (inCommand == msg_TabSelect)
  807.         return (GetVisibleCount() > 0);
  808.     else
  809.         return LFinderView::ProcessCommand(inCommand, ioParam);
  810. }
  811.  
  812.  
  813. void
  814. CAttachmentView::BeTarget()
  815. {
  816.     if ( FirstSelectedCell() == 0)
  817.     {
  818.         if ( this->GetVisibleCount() > 0 )
  819.             this->SelectItem( 1, TRUE );
  820.     }
  821. }
  822.  
  823. void
  824. CAttachmentView::AddDropAreaToWindow(LWindow* inWindow)
  825. {
  826.     if (!mCurrentlyAddedToDropList)
  827.         LDropArea::AddDropArea(this, inWindow->GetMacPort());
  828.     mCurrentlyAddedToDropList = true;
  829. }
  830.  
  831. void
  832. CAttachmentView::RemoveDropAreaFromWindow(LWindow* inWindow)
  833. {
  834.     if (mCurrentlyAddedToDropList)
  835.         LDropArea::RemoveDropArea(this, inWindow->GetMacPort());
  836.     mCurrentlyAddedToDropList = false;
  837. }
  838.