home *** CD-ROM | disk | FTP | other *** search
/ Tools / WinSN5.0Ver.iso / NETSCAP.50 / WIN1998.ZIP / ns / cmd / macfe / Composer / meditdlg.cp < prev    next >
Encoding:
Text File  |  1998-04-08  |  154.5 KB  |  5,560 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 "meditdlg.h"
  20. #include "meditor.h"     // HandleModalDialog
  21. #include "shist.h"
  22. #include "CEditView.h"
  23. #include "edt.h"
  24. #include "pa_tags.h"
  25. #include "secnav.h"        // SECNAV_MungeString, SECNAV_UnMungeString (password munging calls for publishing)
  26.  
  27. // macfe
  28. #include "ulaunch.h"    // StartDocInApp
  29. #include "macgui.h"        // StPrepareForDialog, UGraphics
  30. #include "resgui.h"        // msg_Help, msg_Apply, CLOSE_STR_RESID, EDITOR_PERCENT_PARENT_CELL
  31. #include "uerrmgr.h"
  32. #include "uapp.h"        // CFrontApp::DoGetURL
  33. #include "macutil.h"
  34. #include "ufilemgr.h"
  35. #include "CPrefsDialog.h"
  36. #include "prefapi.h"
  37. #include "prefwutil.h"    // SetColor
  38. #include "CNSContext.h"    // ExtractHyperView
  39. #include "CLargeEditField.h"
  40. #include "CPrefsMediator.h"
  41. #include "URobustCreateWindow.h"
  42. #include "UGraphicGizmos.h"
  43.  
  44. // powerplant
  45. #include "CTabControl.h"
  46. #include "LToggleButton.h"
  47. #include "StBlockingDialogHandler.h"
  48. #include "UMenuUtils.h"
  49. #include "LGAEditField.h"
  50. #include "LGAPopup.h"
  51. #include "CTabSwitcher.h"
  52. #include <LStdControl.h>
  53. #include <UDesktop.h>
  54. #include <UReanimator.h>
  55. #include <URegistrar.h>
  56. #include <UTextTraits.h>
  57.  
  58. #include "CCaption.h"    // new location for CCaptionDisable ( renamed to CCaption )
  59. #include "xp_help.h"
  60.  
  61.  
  62. extern char *XP_NEW_DOC_NAME;
  63.  
  64. static Boolean IsEditFieldWithinLimits(LGAEditField* editField, int minVal, int maxVal );
  65.  
  66.  
  67. static void SetTextTraitsIDByCsid(LEditField* pane, int16 win_csid)
  68. {
  69.     ThrowIfNil_(pane);
  70.     static int16 res_csid = -1;
  71.     if(-1 == res_csid)    // un-initialized
  72.         res_csid = INTL_CharSetNameToID(INTL_ResourceCharSet());
  73.     if(win_csid != res_csid)
  74.         pane->SetTextTraitsID(CPrefs::GetTextFieldTextResIDs(win_csid));
  75. }
  76.  
  77.  
  78. // input: c-string; output: c-string
  79. // returns true if the user clicked ok
  80. static Boolean GetExtraHTML( char *pExtra, char **newExtraHTML , int16 win_csid)
  81. {
  82.     StBlockingDialogHandler    handler(5114, LCommander::GetTopCommander());
  83.     LWindow *dlog = (LWindow *)handler.GetDialog();
  84.     
  85.     LControl *okButton = (LControl *)dlog->FindPaneByID( 'OKOK' );
  86.     if ( okButton == NULL )
  87.         return false;
  88.     
  89.     CLargeEditField *editField = (CLargeEditField *)dlog->FindPaneByID( 'Xhtm' );
  90.     if ( editField == NULL )
  91.         return false;
  92.     SetTextTraitsIDByCsid( editField, win_csid );
  93.     
  94.     dlog->SetLatentSub( editField );
  95.     if ( pExtra )
  96.     {
  97.         editField->SetLongDescriptor( pExtra );
  98.         editField->SelectAll();
  99.     }
  100.     
  101.     MessageT theMessage;
  102.     do
  103.     {
  104.         char *pCurrent = editField->GetLongDescriptor(); 
  105.         if ( pCurrent == NULL || ( pExtra && XP_STRCMP( pExtra, pCurrent ) == 0 ) )
  106.             okButton->Disable();
  107.         else
  108.             okButton->Enable();
  109.         
  110.         if ( pCurrent )
  111.             XP_FREE( pCurrent );
  112.         
  113.         theMessage = handler.DoDialog();
  114. //            case msg_Help:
  115. //                newWindow->Help();
  116. //                break;
  117.     } while ( theMessage != msg_OK && theMessage != msg_Cancel );
  118.     
  119.     if ( theMessage == msg_OK )
  120.         *newExtraHTML = editField->GetLongDescriptor();
  121.     
  122.     return theMessage == msg_OK;
  123. }
  124.  
  125.  
  126. void CChameleonView::SetColor(RGBColor textColor)
  127. {
  128.     fTextColor.red = textColor.red;
  129.     fTextColor.green = textColor.green;
  130.     fTextColor.blue = textColor.blue;
  131. }
  132.  
  133. void CChameleonView::DrawSelf()
  134. {
  135.     Rect    frame;
  136.     CalcLocalFrameRect(frame);
  137.     
  138.     ApplyForeAndBackColors();
  139.     ::RGBBackColor(&fTextColor);
  140.     
  141.     EraseRect(&frame);
  142. }
  143.  
  144.  
  145. void CChameleonCaption::SetColor(RGBColor textColor, RGBColor backColor)
  146. {
  147.     fTextColor.red = textColor.red;
  148.     fTextColor.green = textColor.green;
  149.     fTextColor.blue = textColor.blue;
  150.     
  151.     fBackColor.red = backColor.red;
  152.     fBackColor.green = backColor.green;
  153.     fBackColor.blue = backColor.blue;
  154. }
  155.  
  156.  
  157. void CChameleonCaption::DrawSelf()
  158. {
  159.     Rect    frame;
  160.     CalcLocalFrameRect(frame);
  161.     
  162.     Int16    just = UTextTraits::SetPortTextTraits(mTxtrID);
  163.     
  164.     ::RGBForeColor(&fTextColor);
  165.     ::RGBBackColor(&fBackColor);
  166.     
  167.     UTextDrawing::DrawWithJustification((Ptr)&mText[1], mText[0], frame, just);
  168. }
  169.  
  170.  
  171. void CEditorPrefContain::DrawSelf()
  172. {
  173.     Rect theFrame;
  174.     if (CalcLocalFrameRect(theFrame))
  175.         {
  176.         StColorPenState theSaver;
  177.         theSaver.Normalize();
  178.         
  179.         SBevelColorDesc theDesc;
  180.         UGraphicGizmos::LoadBevelTraits(5000, theDesc);
  181.     
  182.         ::PmForeColor(theDesc.fillColor);
  183.         ::PaintRect(&theFrame);
  184.     
  185.         StClipRgnState theClipSaver(theFrame);
  186.         StColorState::Normalize();
  187.         
  188.         theFrame.top -= 5;
  189.         ::FrameRect(&theFrame);
  190.  
  191.         SBooleanRect theBevelSides = { true, true, true, true };    
  192.         UGraphicGizmos::BevelTintPartialRect(theFrame, 3, 0x4000, 0x4000, theBevelSides);
  193.         }
  194. }
  195.  
  196.  
  197. #pragma mark -
  198. /**********************************************************/
  199. // This is probably stupid. This just allows all the dialogs I'm creating
  200. // to remember who created them. Also the creator can specify which tab the
  201. // Tab control should start on, if there is a tab control. Also, if this
  202. // is an image, link, or HRule dialog, the creator can specify whether the
  203. // final action should be to insert or modify a selected element.
  204.  
  205. Boolean CEditDialog::Start(ResIDT inWindowID, MWContext * context, short initTabValue, Boolean insert)
  206. {
  207.     CEditDialog *dlog = (CEditDialog *)URobustCreateWindow::CreateWindow( inWindowID, LCommander::GetTopCommander() );
  208.     if ( dlog == NULL )
  209.         return false;
  210.  
  211.     UReanimator::LinkListenerToControls( dlog, dlog, inWindowID );        // the handler is listening; but we want a crack at the messages also...
  212.     dlog->SetContext( context );
  213.     dlog->SetInitTabValue( initTabValue );
  214.     dlog->SetInWindowID( inWindowID );
  215.     dlog->SetInsertFlag( insert );
  216.     dlog->InitializeDialogControls();
  217.     dlog->Show();
  218.     
  219.     return true;
  220. }
  221.  
  222.  
  223. void CEditDialog::ListenToMessage( MessageT inMessage, void* ioParam )
  224. {
  225.     switch ( inMessage )
  226.     {
  227.         case msg_Help:
  228.             Help();
  229.             break;
  230.         
  231.         case 'Xtra':
  232.             char * newExtraHTML = NULL;
  233.             INTL_CharSetInfo csi = LO_GetDocumentCharacterSetInfo( GetContext() );
  234.             Boolean canceled = !GetExtraHTML( pExtra, &newExtraHTML ,INTL_GetCSIWinCSID(csi) );
  235.             if (!canceled)
  236.             {
  237.                 if ( pExtra )
  238.                     XP_FREE( pExtra );
  239.                 pExtra = newExtraHTML;
  240.             }
  241.             break;
  242.  
  243.         case msg_OK:
  244.         case msg_Apply:
  245.             LCommander* theTarget = GetTarget();
  246.             if ( theTarget == NULL || theTarget->SwitchTarget(this) )
  247.             {
  248.                 if ( CommitChanges( true ) )
  249.                 {
  250.                     if ( inMessage == msg_OK )
  251.                     {
  252.                         if ( mUndoInited )
  253.                             EDT_EndBatchChanges( fContext );
  254.                         
  255.                         LDialogBox::ListenToMessage( cmd_Close, ioParam );
  256.                         return;
  257.                     }
  258.                     
  259.                     LStdControl* cancel = (LStdControl*)FindPaneByID( 'CANC' );
  260.                     if (cancel)
  261.                     {
  262.                         StringHandle CloseHandle = GetString(CLOSE_STR_RESID);
  263.                         CStr255 Close = **( (CStr255**)CloseHandle );    // Lock it? I don't think so.
  264.                         cancel->SetDescriptor(Close);
  265.                     }
  266.                 }
  267.             }
  268.             break;
  269.         
  270.         case msg_Cancel:
  271.             if ( mUndoInited )
  272.                 EDT_EndBatchChanges( fContext );
  273.             
  274.             LDialogBox::ListenToMessage( cmd_Close, ioParam );
  275.             break;
  276.         
  277.         default:
  278.             LDialogBox::ListenToMessage( inMessage, ioParam );
  279.     }
  280. }
  281.  
  282.  
  283. Boolean CEditDialog::AllowSubRemoval( LCommander * /* inSub */ )
  284. {
  285.     // don't allow removal
  286.     return false;
  287. }
  288.  
  289.  
  290. // copied from StDialogHandler
  291. void CEditDialog::FindCommandStatus(
  292.     CommandT    /* inCommand */,
  293.     Boolean        &outEnabled,
  294.     Boolean&    /* outUsesMark */,
  295.     Char16&        /* outMark */,
  296.     Str255        /* outName */)
  297. {
  298.         // Don't enable any commands except cmd_About, which will keep
  299.         // the Apple menu enabled. This function purposely does not
  300.         // call the inherited FindCommandStatus, thereby suppressing
  301.         // commands that are handled by SuperCommanders. Only those
  302.         // commands enabled by SubCommanders will be active.
  303.         //
  304.         // This is usually what you want for a moveable modal dialog.
  305.         // Commands such as "New", "Open" and "Quit" that are handled
  306.         // by the Applcation are disabled, but items within the dialog
  307.         // can enable commands. For example, an EditField would enable
  308.         // items in the "Edit" menu.
  309.         
  310.     outEnabled = false;
  311.     // actually we don't want to enable "about" either as it might open
  312.     // a browser window or ??? which would be very bad
  313. }
  314.  
  315.  
  316. void CEditDialog::ChooseImageFile(CLargeEditField* editField)
  317. {
  318.     if ( editField == NULL )
  319.         return;
  320.     
  321.     StPrepareForDialog    preparer;    
  322.     StandardFileReply    reply;
  323.     Point                loc = { -1, -1 };
  324.     OSType                types[ 4 ];
  325.  
  326.     types[ 0 ] = 'GIFf';
  327.     types[ 1 ] = 'TEXT';
  328.     types[ 2 ] = 'JPEG';
  329.     types[ 3 ] = 'JFIF';
  330.  
  331.     ::StandardGetFile( NULL, 4, types, &reply );
  332.  
  333.     if ( !reply.sfGood ) 
  334.         return;
  335.  
  336.     char *fileLink = CFileMgr::GetURLFromFileSpec( reply.sfFile );
  337.     if ( fileLink == NULL )
  338.         return;
  339.     
  340.     editField->SetDescriptor( CStr255(/*NET_UnEscape*/(fileLink)) );
  341.     XP_FREE(fileLink);
  342. }
  343.  
  344.  
  345. /**********************************************************/
  346. #pragma mark -
  347. #pragma mark CTarget
  348.  
  349.  
  350. CTarget::CTarget( LStream* inStream ) : CEditDialog( inStream )
  351. {
  352.     fOriginalTarget = NULL;
  353.     fTargetName = NULL;
  354.     
  355.     ErrorManager::PrepareToInteract();
  356.     UDesktop::Deactivate();
  357. }
  358.  
  359. CTarget::~CTarget()
  360. {
  361.     UDesktop::Activate();
  362.     
  363.     if ( fOriginalTarget )
  364.         XP_FREE( fOriginalTarget );
  365.     fOriginalTarget = NULL;
  366.     fTargetName = NULL;
  367. }
  368.  
  369.  
  370. void CTarget::InitializeDialogControls()
  371. {
  372.     // Create Controls
  373.     ThrowIfNil_(fTargetName = (CLargeEditField*)FindPaneByID( 'tgnm' ));
  374.     
  375.     if ( EDT_GetCurrentElementType(fContext) == ED_ELEMENT_TARGET )
  376.         StrAllocCopy( fOriginalTarget, EDT_GetTargetData(fContext) );
  377.     else
  378.     {
  379.         StrAllocCopy( fOriginalTarget, (char *)LO_GetSelectionText(fContext) );
  380.         CleanUpTargetString( fOriginalTarget );
  381.     }
  382.     
  383.     if ( fOriginalTarget )
  384.         fTargetName->SetDescriptor( CStr255(fOriginalTarget) );
  385.  
  386.     this->SetLatentSub( fTargetName );
  387.     fTargetName->SelectAll();
  388. }
  389.  
  390. void CTarget::CleanUpTargetString(char *target)
  391. {
  392.     if ( target == NULL )
  393.         return;
  394.     
  395.     // move temp past spaces and leading # and strcpy from new location over target
  396.     // remove leading spaces
  397.     char *temp = target;
  398.     while ( *temp == ' ' )
  399.         temp++;
  400.     
  401.     // remove a leading pound, if any
  402.     if ( *temp == '#' )
  403.         temp++;
  404.     
  405.     // strcpy now that we have temp correctly positioned
  406.     XP_STRCPY( target, temp );
  407.     
  408.     // truncate at the first return character
  409.     char *ret = XP_STRCHR( target, '\r' );
  410.     if ( ret )
  411.         *ret = '\0';
  412. }
  413.  
  414.  
  415. Boolean CTarget::AlreadyExistsInDocument(char *anchor)
  416. {
  417.     char *targs = EDT_GetAllDocumentTargets( fContext );
  418.     if ( targs == NULL )
  419.         return FALSE;
  420.     
  421.     char *parse = targs;
  422.     if ( parse )
  423.     {
  424.         while ( *parse )
  425.         {
  426.             if ( XP_STRCMP( anchor, parse ) == 0 )
  427.             {
  428.                 XP_FREE( targs );
  429.                 return TRUE;
  430.             }
  431.             parse += XP_STRLEN( parse ) + 1;
  432.         }
  433.     }
  434.     
  435.     XP_FREE(targs);
  436.     return FALSE;
  437. }
  438.  
  439.  
  440. Boolean CTarget::CommitChanges( Boolean /* isAllPanes */ )
  441. {
  442.     char *anchor = fTargetName->GetLongDescriptor();
  443.     if ( anchor == NULL )
  444.         return true;
  445.     
  446.     CleanUpTargetString( anchor );
  447.     
  448.     if ( AlreadyExistsInDocument(anchor) && (fInsert || XP_STRCMP(anchor, fOriginalTarget)) )
  449.     {
  450.         ErrorManager::PlainAlert( DUPLICATE_TARGET );
  451.         XP_FREE( anchor );
  452.         return false;
  453.     }
  454.     
  455.     if ( !mUndoInited )
  456.     {
  457.         EDT_BeginBatchChanges( fContext );
  458.         mUndoInited = true;
  459.     }
  460.     
  461.     if ( fInsert )
  462.         EDT_InsertTarget( fContext, anchor );
  463.     else
  464.         EDT_SetTargetData( fContext, anchor );
  465.         
  466.     XP_FREE( anchor );
  467.     return true;
  468. }
  469.  
  470.  
  471. /**********************************************************/
  472. #pragma mark CUnknownTag
  473.  
  474.  
  475. CUnknownTag::CUnknownTag( LStream* inStream ) : CEditDialog( inStream )
  476. {
  477.     ErrorManager::PrepareToInteract();
  478.     UDesktop::Deactivate();
  479. }
  480.  
  481.  
  482. CUnknownTag::~CUnknownTag()
  483. {
  484.     UDesktop::Activate();
  485. }
  486.  
  487.  
  488. void CUnknownTag::FinishCreateSelf()
  489. {
  490.     fTargetName = NULL;
  491.     
  492.     CEditDialog::FinishCreateSelf();
  493. }
  494.  
  495.  
  496. void CUnknownTag::InitializeDialogControls()
  497. {
  498.     fTargetName = (CLargeEditField *)FindPaneByID( 'tgnm' );
  499.     SetTextTraitsIDByCsid(fTargetName, GetWinCSID());
  500.     
  501.     if ( !fInsert )
  502.     {
  503.         char *tag = EDT_GetUnknownTagData( fContext );
  504.         if ( tag )
  505.         {
  506.             fTargetName->SetLongDescriptor( tag );
  507.             XP_FREE( tag );
  508.         }
  509.     }
  510.     
  511.     this->SetLatentSub( fTargetName );
  512.     fTargetName->SelectAll();
  513. }
  514.  
  515.  
  516. Boolean CUnknownTag::CommitChanges( Boolean /* isAllPanes */ )
  517. {
  518.     // HACK!!!  CUnknownTag is used (unfortunately) by both "Insert HTML Tag" and "Extra HTMLâ•”"
  519.     // This is bad and should be corrected as soon as possible (after 4.0 ships)
  520.     
  521.     // in the case of extra HTML we can end up here but fTargetName will be NULL
  522.     // let's just bail out and handle this in the extraHTML dlog code (by returning false)
  523.     if ( fTargetName == NULL )
  524.         return false;
  525.     
  526.     char *anchor = fTargetName->GetLongDescriptor();
  527.     if ( anchor == NULL )
  528.         return true;
  529.         
  530.     if ( EDT_ValidateTag(anchor, FALSE) != ED_TAG_OK )
  531.     {
  532.         ErrorManager::PlainAlert( BAD_TAG );
  533.         XP_FREE( anchor );
  534.         return false;
  535.     }
  536.     
  537.     if ( mUndoInited )
  538.     {
  539.         EDT_BeginBatchChanges( fContext );
  540.         mUndoInited = true;
  541.     }
  542.     
  543.     if ( fInsert )
  544.         EDT_InsertUnknownTag( fContext, anchor );
  545.     else
  546.         EDT_SetUnknownTagData( fContext, anchor );
  547.         
  548.     XP_FREE( anchor );
  549.     return true;
  550. }
  551.  
  552.  
  553. void CUnknownTag::Help()
  554. {
  555.     ShowHelp( HELP_HTML_TAG );
  556. }
  557.  
  558.  
  559. void CUnknownTag::ListenToMessage( MessageT inMessage, void* ioParam )
  560. {
  561.     switch ( inMessage )
  562.     {
  563.         case 'vrfy':
  564.             char *anchor = fTargetName->GetLongDescriptor();
  565.             if (anchor)
  566.             {
  567.                 if (EDT_ValidateTag( anchor, false ) != ED_TAG_OK)
  568.                     ErrorManager::PlainAlert( BAD_TAG );
  569.                 
  570.                 XP_FREE( anchor );
  571.             }
  572.         break;
  573.         
  574.         default:
  575.             CEditDialog::ListenToMessage( inMessage, ioParam );
  576.         break;
  577.     }
  578. }
  579.  
  580.  
  581. /**********************************************************/
  582. #pragma mark -
  583. // Does PowerPlant now have a better class?  Can we replace this homebrew class?
  584. // This is a single column LListBox which allows multiple things to be selected.
  585.  
  586. MultipleSelectionSingleColumn::MultipleSelectionSingleColumn( LStream* inStream ) : LListBox( inStream )
  587. {
  588.     FocusDraw();
  589.     if((*mMacListH)->dataBounds.right == 0)
  590.         ::LAddColumn(1 , 0, mMacListH);
  591.     (*mMacListH)->selFlags &= ~lOnlyOne;            // make sure this bit is cleared.
  592. }
  593.  
  594.  
  595. int16 MultipleSelectionSingleColumn::NumItems() 
  596.     return ((**mMacListH).dataBounds.bottom);
  597. }
  598.  
  599.  
  600. void MultipleSelectionSingleColumn::DeselectAll() 
  601.     Cell    theCell;
  602.     int16    count = NumItems();
  603.     theCell.h = 0;
  604.     
  605.     FocusDraw();
  606.  
  607.     for (theCell.v = 0; theCell.v < count; theCell.v++)
  608.         LSetSelect(false, theCell, mMacListH);
  609. }
  610.  
  611.  
  612. void MultipleSelectionSingleColumn::SelectAll() 
  613.     Cell    theCell;
  614.     int16    count = NumItems();
  615.     theCell.h = 0;
  616.     
  617.     FocusDraw();
  618.  
  619.     for (theCell.v = 0; theCell.v < count; theCell.v++)
  620.         LSetSelect(true, theCell, mMacListH);
  621. }
  622.  
  623.  
  624. void MultipleSelectionSingleColumn::AddItem( char* data, Boolean isSelected )
  625. {
  626.     if(SwitchTarget(this))
  627.     {
  628.         int16    rowNum = 0;
  629.         FocusDraw();
  630.         Cell theCell;
  631.         theCell.h = 0;
  632.         rowNum = ::LAddRow(1 , (**mMacListH).dataBounds.bottom, mMacListH);
  633.         theCell.v = rowNum;
  634.         ::LSetCell(data, strlen(data) + 1 ,theCell, mMacListH);
  635.         ::LSetSelect( isSelected, theCell, mMacListH );
  636.     }
  637. }
  638.  
  639.  
  640. StringPtr MultipleSelectionSingleColumn::GetItem(Str255    outDescriptor, int32 rowNum) const
  641. {
  642.     outDescriptor[0] = 0;
  643.     Cell    theCell = {0, 0};
  644.     theCell.h = 0;
  645.     theCell.v = rowNum;
  646.     Int16    dataLen = 255;
  647.     ::LGetCell(outDescriptor + 1, &dataLen, theCell, mMacListH);
  648.     outDescriptor[0] = dataLen;
  649.     return outDescriptor;
  650. }
  651.  
  652.  
  653. Boolean MultipleSelectionSingleColumn::IsSelected(int32 rowNum)    // rowNum is zero based
  654. {
  655.     FocusDraw();
  656.     Cell theCell;
  657.     theCell.h = 0;
  658.     theCell.v = rowNum;
  659.     return ::LGetSelect(false, &theCell, mMacListH);        // false means to only look at this one item...
  660. }
  661.  
  662.  
  663. void MultipleSelectionSingleColumn::RemoveAllItems()
  664. {
  665.     FocusDraw();
  666.     if ((**mMacListH).dataBounds.bottom)
  667.         ::LDelRow((**mMacListH).dataBounds.bottom, 0, mMacListH);
  668. }
  669.  
  670.  
  671. /**********************************************************/
  672. #pragma mark CPublishHistory
  673.  
  674. char* CPublishHistory::GetPublishHistoryCharPtr(short whichone)
  675. {
  676.     switch (whichone) {
  677.         case 0: return CPrefs::GetCharPtr(CPrefs::PublishHistory0);
  678.         case 1: return CPrefs::GetCharPtr(CPrefs::PublishHistory1);
  679.         case 2: return CPrefs::GetCharPtr(CPrefs::PublishHistory2);
  680.         case 3: return CPrefs::GetCharPtr(CPrefs::PublishHistory3);
  681.         case 4: return CPrefs::GetCharPtr(CPrefs::PublishHistory4);
  682.         case 5: return CPrefs::GetCharPtr(CPrefs::PublishHistory5);
  683.         case 6: return CPrefs::GetCharPtr(CPrefs::PublishHistory6);
  684.         case 7: return CPrefs::GetCharPtr(CPrefs::PublishHistory7);
  685.         case 8: return CPrefs::GetCharPtr(CPrefs::PublishHistory8);
  686.         case 9: return CPrefs::GetCharPtr(CPrefs::PublishHistory9);
  687.     }
  688.     return CPrefs::GetCharPtr(CPrefs::PublishHistory0);
  689. }
  690.  
  691.  
  692. void CPublishHistory::SetPublishHistoryCharPtr(char* entry, short whichone)
  693. {
  694.     switch (whichone) {
  695.         case 0:    CPrefs::SetString( entry, CPrefs::PublishHistory0); break;
  696.         case 1:    CPrefs::SetString( entry, CPrefs::PublishHistory1); break;
  697.         case 2:    CPrefs::SetString( entry, CPrefs::PublishHistory2); break;
  698.         case 3:    CPrefs::SetString( entry, CPrefs::PublishHistory3); break;
  699.         case 4:    CPrefs::SetString( entry, CPrefs::PublishHistory4); break;
  700.         case 5:    CPrefs::SetString( entry, CPrefs::PublishHistory5); break;
  701.         case 6:    CPrefs::SetString( entry, CPrefs::PublishHistory6); break;
  702.         case 7:    CPrefs::SetString( entry, CPrefs::PublishHistory7); break;
  703.         case 8:    CPrefs::SetString( entry, CPrefs::PublishHistory8); break;
  704.         case 9:    CPrefs::SetString( entry, CPrefs::PublishHistory9); break;
  705.     }
  706. }
  707.  
  708.  
  709. Boolean CPublishHistory::IsTherePublishHistory()
  710. {
  711.     char *lowest = GetPublishHistoryCharPtr(0);
  712.     
  713.     if (lowest == NULL) return FALSE;
  714.     if (*lowest == '\0') return FALSE;
  715.     return TRUE;
  716. }
  717.  
  718.  
  719. void CPublishHistory::AddPublishHistoryEntry(char *entry)
  720. {
  721.     if (entry == NULL) return;
  722.     
  723.     short highestcopy = 9;
  724.     short i;
  725.     
  726.     for (i = 0; i < 9 ; i++)  {
  727.         char * hist = GetPublishHistoryCharPtr(i);
  728.         if (hist && strcmp(hist, entry) == NULL) highestcopy = i;
  729.     }
  730.     
  731.     while (highestcopy > 0) {
  732.         SetPublishHistoryCharPtr(GetPublishHistoryCharPtr(highestcopy - 1), highestcopy);
  733.         highestcopy--;
  734.     }
  735.         
  736.     SetPublishHistoryCharPtr(entry, 0);
  737. }
  738.  
  739.  
  740. #pragma mark CPublish
  741.  
  742. CPublish::CPublish( LStream* inStream ) : CEditDialog( inStream )
  743. {
  744.     ErrorManager::PrepareToInteract();
  745.     UDesktop::Deactivate();
  746. }
  747.  
  748.  
  749. CPublish::~CPublish()
  750. {
  751.     UDesktop::Activate();
  752. }
  753.  
  754.  
  755. void CPublish::FinishCreateSelf()
  756. {
  757.     // Create Controls
  758.     
  759.     fLocalLocation = NULL;
  760.     
  761.     fImageFiles = NULL;
  762.     fFolderFiles = NULL;
  763.     fDefaultLocation = NULL;
  764.     
  765.     fFileList = NULL;
  766.     
  767.     fPublishLocation = NULL;
  768.     fUserID = NULL;
  769.     fPassword = NULL;
  770.  
  771.     fSavePassword = NULL;
  772.     mHistoryList = NULL;
  773.  
  774.     CEditDialog::FinishCreateSelf();
  775. }
  776.  
  777.  
  778. void CPublish::InitializeDialogControls()
  779. {
  780.     fLocalLocation = (LCaption*)this->FindPaneByID( 'Pub0' );
  781.     
  782.     fImageFiles = (LControl*)this->FindPaneByID( 'Pub1' );
  783.     fFolderFiles = (LControl*)this->FindPaneByID( 'Pub2' );
  784.     
  785.     History_entry * pEntry = SHIST_GetCurrent(&fContext->hist);
  786.     if (pEntry && pEntry->address && NET_IsLocalFileURL(pEntry->address))
  787.         fFolderFiles->Enable();
  788.     else
  789.         fFolderFiles->Disable();
  790.     
  791.     fFileList = (MultipleSelectionSingleColumn*)this->FindPaneByID( 'Pub3' );
  792.         
  793.     fPublishLocation = (LGAEditField*)this->FindPaneByID( 'Pub4' );
  794.     fUserID = (LGAEditField*)this->FindPaneByID( 'user' );
  795.     fPassword = (LGAEditField*)this->FindPaneByID( 'Pass' );
  796.     
  797.     fDefaultLocation = (LControl*)this->FindPaneByID( 'Dflt' );
  798.     
  799.     fSavePassword = (LControl*)this->FindPaneByID( 'Pub5' );
  800.     mHistoryList = (LGAPopup *)this->FindPaneByID( 'Pub6' );
  801.     
  802.     MenuHandle menu = mHistoryList->GetMacMenuH();
  803.     
  804.     if (menu && CPublishHistory::IsTherePublishHistory()) {
  805.     
  806.         ::SetMenuItemText(menu, 1, "\p ");
  807.         mHistoryList->SetMaxValue(10);                // maximum of 10 entries.
  808.         
  809.         int i;
  810.         
  811.         for (i = 0; i < 10; i++) {
  812.             char *entry = CPublishHistory::GetPublishHistoryCharPtr(i);
  813.             if (entry == NULL || *entry == '\0') break;
  814.             
  815.             char *location = NULL;
  816.             char *user = NULL;
  817.             char *pass = NULL;
  818.  
  819.             if (NET_ParseUploadURL(entry, &location, &user, &pass)) {
  820.                 
  821.                 UMenuUtils::InsertMenuItem(menu, CStr255(location), i + 2);
  822.                 
  823.                 XP_FREE(location);
  824.                 XP_FREE(user);
  825.                 XP_FREE(pass);
  826.             }
  827.         }
  828.     }
  829.  
  830.     CStr255 location = EDT_GetDefaultPublishURL( fContext, NULL, NULL, NULL );
  831.     fPublishLocation->SetDescriptor( location );
  832.     this->SetLatentSub( fPublishLocation );
  833.     
  834.     char *localDir = DocName();
  835.     if (localDir) {
  836.     
  837.         char *pSlash = strrchr(localDir, '/');
  838.         if (pSlash)    {                // if there is a slash, only keep everything AFTER the last slash
  839.             pSlash++;                // go past the slash
  840.             XP_STRCPY(localDir, pSlash);
  841.         }
  842.         
  843.         fLocalLocation->SetDescriptor(CStr255(localDir));
  844.         
  845.         XP_FREE( localDir );
  846.     }
  847.  
  848.     CLargeEditField *titleField = (CLargeEditField *)FindPaneByID( 'Titl' );
  849.     if ( titleField )
  850.     {
  851.         int16 res_csid = INTL_CharSetNameToID(INTL_ResourceCharSet());
  852.         int16 win_csid = GetWinCSID();
  853.         if(win_csid != res_csid)
  854.             titleField->SetTextTraitsID(CPrefs::GetTextFieldTextResIDs(win_csid));
  855.  
  856.         EDT_PageData *pageData = EDT_GetPageData( fContext );
  857.         if ( pageData )
  858.         {
  859.             titleField->SetDescriptor( CStr255(pageData->pTitle) );
  860.             EDT_FreePageData( pageData );
  861.         }
  862.     }
  863.     
  864.     location = CPrefs::GetString(CPrefs::PublishLocation);
  865.     if (location.Length())
  866.         fDefaultLocation->Enable();
  867.     else
  868.         fDefaultLocation->Disable();
  869.         
  870.     TurnOn(fImageFiles);
  871.     
  872. }
  873.  
  874. char *CPublish::DocName()
  875. {
  876.      History_entry * pEntry = SHIST_GetCurrent(&fContext->hist);
  877.  
  878.     if (pEntry == NULL || pEntry->address == NULL) return NULL;
  879.     
  880.     if (!NET_IsLocalFileURL(pEntry->address)) return NULL;
  881.     
  882.     char *filename = NULL;
  883.     XP_ConvertUrlToLocalFile( pEntry->address, &filename );
  884.     
  885.     return filename;
  886. }
  887.  
  888. Boolean CPublish::CommitChanges( Boolean /* isAllPanes */ )
  889. {
  890.     char *BrowseLoc = NULL;
  891.     
  892.     CStr255    outText;
  893.     
  894.     fPublishLocation->GetDescriptor( outText );
  895.     
  896.     int type = NET_URL_Type(outText);
  897.     if (type != FTP_TYPE_URL && type != HTTP_TYPE_URL && type != SECURE_HTTP_TYPE_URL) {
  898.         ErrorManager::PlainAlert( INVALID_PUBLISH_LOC );
  899.         return FALSE;
  900.     }
  901.     
  902.         // Tell user the URL they are publishing to looks like it might be wrong.
  903.         // e.g. ends in a slash or does not have a file extension.
  904.         // Give the user the option of attempting to publish to the
  905.         // specified URL even if it looks suspicious.
  906.     if ( !EDT_CheckPublishURL( fContext, (char*)outText ) ) {
  907.         // XP will put up alert
  908.         return FALSE;
  909.     }
  910.     
  911.  
  912.     /* set the page title */
  913.     EDT_PageData *pageData = EDT_GetPageData( fContext );
  914.     if ( pageData )
  915.     {
  916.         CLargeEditField *titleField = (CLargeEditField *)FindPaneByID( 'Titl' );
  917.         if ( titleField )
  918.             pageData->pTitle = titleField->GetLongDescriptor();
  919.         
  920.         EDT_SetPageData( fContext, pageData );
  921.         EDT_FreePageData( pageData );
  922.     }
  923.  
  924.     /* get the userID and password to create the internal URL */
  925.     CStr255        user;
  926.     CStr255        pass;
  927.     fUserID->GetDescriptor( user );
  928.     fPassword->GetDescriptor( pass );
  929.  
  930.     if (!NET_MakeUploadURL(&BrowseLoc, outText, user, pass) || BrowseLoc == NULL)
  931.         return TRUE;        // must be an out of memory problem, but we return TRUE so the user can try to recover
  932.  
  933.     /* look for related files to also publish */
  934.     int count = 0;
  935.     int i;
  936.     for (i = fFileList->NumItems() - 1; i >= 0; i--)
  937.         if (fFileList->IsSelected(i))
  938.             count++;
  939.  
  940.     char **allFiles = (char **) XP_CALLOC((count + 2), sizeof(char *));
  941.     if (allFiles == NULL) {
  942.         XP_FREE(BrowseLoc);
  943.         return TRUE;        // must be an out of memory problem, but we return TRUE so the user can try to recover
  944.     }
  945.     
  946.     allFiles[count + 1] = NULL;
  947.     allFiles[0] = XP_STRDUP(outText);    // we are actually copying the doc name as well as the localDir here
  948.  
  949.     int    allFilesIndex = 1;
  950.     for (i = 0; i < count; i++)
  951.     {
  952.         if (fFileList->IsSelected(i))
  953.         {
  954.             CStr255 lookFor;
  955.             fFileList->GetItem(lookFor, i);
  956.             if (allFilesIndex < count + 1)        // sanity check
  957.                 allFiles[ allFilesIndex ] = XP_STRDUP( lookFor );
  958.             else
  959.                 XP_ASSERT(0);
  960.             
  961.             allFilesIndex++;
  962.         }
  963.     }
  964.  
  965.     /* get preferences and current URL */
  966.     XP_Bool bKeepImages;
  967.     PREF_GetBoolPref("editor.publish_keep_images",&bKeepImages);
  968.     XP_Bool bKeepLinks;
  969.     PREF_GetBoolPref("editor.publish_keep_links",&bKeepLinks);
  970.  
  971.     char *pSrcURL;
  972.     History_entry * pEntry = SHIST_GetCurrent(&fContext->hist);
  973.     if (pEntry && pEntry->address && *pEntry->address) {
  974.       pSrcURL = pEntry->address;
  975.     }
  976.     else {
  977.       // no source name.
  978.       pSrcURL = XP_NEW_DOC_NAME;
  979.     }
  980.  
  981.     /* actually publish--finally! */
  982.     EDT_PublishFile( fContext, ED_FINISHED_REVERT_BUFFER, pSrcURL, 
  983.                     allFiles, BrowseLoc, bKeepImages, bKeepLinks, false );    // this will eventually free allFiles, when we are done publishing....
  984.     XP_FREE(BrowseLoc);
  985.     BrowseLoc = NULL;
  986.     
  987.     // add this new location to our history...known bugs in this area
  988.     if (fSavePassword->GetValue())
  989.     {
  990.         char *result;
  991.         result = SECNAV_MungeString(pass);
  992.         if ( result && (strcmp( result, pass ) == 0) )
  993.         {
  994.             // munging didn't do anything so we'll write out ""
  995.             pass = "";
  996.         }
  997.         else
  998.             pass = result;
  999.     }
  1000.     else
  1001.         pass = "";
  1002.     
  1003.     if (NET_MakeUploadURL(&BrowseLoc, outText, user, pass) && BrowseLoc) {
  1004.         CPublishHistory::AddPublishHistoryEntry(BrowseLoc);
  1005.         XP_FREE(BrowseLoc);
  1006.     }
  1007.             
  1008.     // finally, show them what we've done!
  1009.     CStr255        urlString = CPrefs::GetString( CPrefs::PublishBrowseLocation );
  1010.     if ( urlString != CStr255::sEmptyString )
  1011.         CFrontApp::DoGetURL( (unsigned char*)urlString );
  1012.     
  1013.     return TRUE;
  1014. }
  1015.  
  1016.  
  1017. void CPublish::Help()
  1018. {
  1019.     ShowHelp( HELP_PUBLISH_FILES );
  1020. }
  1021.  
  1022.  
  1023. void CPublish::ListenToMessage( MessageT inMessage, void* ioParam )
  1024. {
  1025.     switch ( inMessage )
  1026.     {
  1027.         case 'None':    // deselect everything in file list
  1028.             fFileList->DeselectAll();
  1029.             break;
  1030.         
  1031.         case 'SAll':    // select everything in file list
  1032.             fFileList->SelectAll();
  1033.             break;
  1034.         
  1035.         case 'Pub1':    // add all document images to list
  1036.             if (fImageFiles->GetValue()) {
  1037.                 fFileList->RemoveAllItems();
  1038.                 
  1039.                 XP_Bool bKeepImages;
  1040.                 PREF_GetBoolPref("editor.publish_keep_images",&bKeepImages);
  1041.                 XP_Bool *bSelectionArray = NULL;
  1042.                 char *images = EDT_GetAllDocumentFilesSelected( fContext, 
  1043.                                             &bSelectionArray, bKeepImages );
  1044.                 if (images) {
  1045.                     char *next = images;
  1046.                     
  1047.                     int index = 0;
  1048.                     while (*next) {
  1049.                         fFileList->AddItem(next, bSelectionArray[ index++ ]);
  1050.                         next += strlen(next) + 1;
  1051.                     }
  1052.                     
  1053.                     XP_FREE(images);
  1054.                 }
  1055.                 if ( bSelectionArray )
  1056.                     XP_FREE( bSelectionArray );
  1057.             }
  1058.             break;
  1059.         
  1060.         case 'Pub2':    // add all images in folder to list
  1061.         /* this should not be enabled if remote document or new document (file:///Untitled) */
  1062.             if (fFolderFiles->GetValue())
  1063.             {
  1064.                 fFileList->RemoveAllItems();
  1065.             
  1066.                 History_entry * pEntry = SHIST_GetCurrent(&fContext->hist);
  1067.                 if (pEntry && pEntry->address && NET_IsLocalFileURL(pEntry->address))
  1068.                 {
  1069.                     char *URLDir = XP_STRDUP( pEntry->address );
  1070.                     if ( URLDir )
  1071.                     {
  1072.                         char *pSlash = strrchr(URLDir, '/');
  1073.                         if (pSlash)        // is there is a slash, chop off everything after the last slash
  1074.                             *++pSlash = '\0';
  1075.                             
  1076.                         char **images = NET_AssembleAllFilesInDirectory( fContext, URLDir );
  1077.                         if (images)
  1078.                         {
  1079.                             char **next = images;                // go through the list and add them all
  1080.                             while (*next)
  1081.                             {
  1082.                                 if (strcmp(*next, pEntry->address))    // don't add current file
  1083.                                 {
  1084. //                                    char *path = strstr(*next, URLDir);
  1085. //                                    if (path) 
  1086. //                                        fFileList->AddItem( path + strlen(URLDir), false );
  1087. //                                    else
  1088. //                                        fFileList->AddItem( *next, false );
  1089.                     
  1090. //                                    char *absURL = NET_MakeAbsoluteURL( pEntry->address, *next );
  1091.                                     fFileList->AddItem( *next, false );    
  1092.                                 }
  1093.                                     
  1094.                                 next++;
  1095.                             }
  1096.                             
  1097.                             next = images;                        // now free them all... what a waste
  1098.                             while (*next) XP_FREE(*next++);
  1099.                             XP_FREE(images);
  1100.                     
  1101.                         }
  1102.                             
  1103.                         XP_FREE( URLDir );
  1104.                     }
  1105.                 }
  1106.             }
  1107.         break;
  1108.         
  1109.         case 'Pub6':    // extract one of the history entries and put in publish location
  1110.             CStr255 text = CPublishHistory::GetPublishHistoryCharPtr(mHistoryList->GetValue() - 2);
  1111.             
  1112.             // reset it now, because we don't know when the user might modify the textedit 
  1113.             // field making the selected menu item no longer valid.
  1114.             mHistoryList->SetValue(1);
  1115.                         
  1116.             if ((char *) text && *(char *)text) {
  1117.                 
  1118.                 char *location = NULL;
  1119.                 char *user = NULL;
  1120.                 char *pass = NULL;
  1121.  
  1122.                 if (NET_ParseUploadURL(text, &location, &user, &pass)) {
  1123.                     if (pass && *pass) {
  1124.                         char *newpass = SECNAV_UnMungeString(pass);
  1125.                         XP_FREE(pass);
  1126.                         pass = newpass;
  1127.                     }
  1128.                     
  1129.                     fPublishLocation->SetDescriptor(CStr255(location));
  1130.                     fUserID->SetDescriptor(CStr255(user));
  1131.                     fPassword->SetDescriptor(CStr255(pass));
  1132.                     
  1133.                     if (pass && *pass)
  1134.                         fSavePassword->SetValue(1);
  1135.                     else
  1136.                         fSavePassword->SetValue(0);
  1137.                     
  1138.                     XP_FREE(location);
  1139.                     XP_FREE(user);
  1140.                     XP_FREE(pass);
  1141.                 }
  1142.             }
  1143.  
  1144.         break;
  1145.         
  1146.         case 'Dflt':    // put in default publish location
  1147.             char *BrowseLoc = CPrefs::GetString(CPrefs::PublishLocation);
  1148.             if (BrowseLoc && *BrowseLoc) {
  1149.                 
  1150.                 char *location = NULL;
  1151.                 char *user = NULL;
  1152.                 char *pass = NULL;
  1153.  
  1154.                 if (NET_ParseUploadURL(BrowseLoc, &location, &user, &pass)) {
  1155.                     if (pass && *pass) {
  1156.                         char *newpass = SECNAV_UnMungeString(pass);
  1157.                         XP_FREE(pass);
  1158.                         pass = newpass;
  1159.                     }
  1160.                     
  1161.                     fPublishLocation->SetDescriptor(CStr255(location));
  1162.                     fUserID->SetDescriptor(CStr255(user));
  1163.                     fPassword->SetDescriptor(CStr255(pass));
  1164.                     
  1165.                     XP_FREE(location);
  1166.                     XP_FREE(user);
  1167.                     XP_FREE(pass);
  1168.                 }
  1169.             }
  1170.         break;
  1171.         
  1172.         case msg_ControlClicked:
  1173.             if ( ioParam )
  1174.             {
  1175.                 LControl *c = (LControl *)ioParam;
  1176.                 if ( c )
  1177.                     ListenToMessage( c->GetValueMessage(), NULL );
  1178.             }
  1179.             break;
  1180.         
  1181.         default:
  1182.             CEditDialog::ListenToMessage( inMessage, ioParam );
  1183.         break;
  1184.     }
  1185. }
  1186.  
  1187.  
  1188. /**********************************************************/
  1189. #pragma mark CLineProp
  1190.  
  1191. CLineProp::CLineProp( LStream* inStream ): CEditDialog( inStream )
  1192. {
  1193.     ErrorManager::PrepareToInteract();
  1194.     UDesktop::Deactivate();
  1195. }
  1196.  
  1197.  
  1198. CLineProp::~CLineProp()
  1199. {
  1200.     UDesktop::Activate();
  1201. }
  1202.  
  1203.  
  1204. #define    kPixelsItem                1
  1205. #define kPercentOfWindowItem    2
  1206.  
  1207. void CLineProp::FinishCreateSelf()
  1208. {
  1209.     fLeftAlign = NULL;
  1210.     fCenterAlign = NULL;
  1211.     fRightAlign = NULL;
  1212.     
  1213.     fHeightEditText = NULL;
  1214.     fWidthEditText = NULL;
  1215.     fPixelPercent = NULL;
  1216.     fShading = NULL;
  1217.         
  1218.     CEditDialog::FinishCreateSelf();
  1219. }
  1220.  
  1221. void CLineProp::InitializeDialogControls()
  1222. {
  1223.     // Find Controls
  1224.     fHeightEditText = (LGAEditField*)this->FindPaneByID( 'ELPh' );
  1225.     fWidthEditText = (LGAEditField*)this->FindPaneByID( 'ELPw' );
  1226.     
  1227.     fLeftAlign = (LControl*)this->FindPaneByID( 'Left' );
  1228.     fCenterAlign = (LControl*)this->FindPaneByID( 'Cntr' );
  1229.     fRightAlign = (LControl*)this->FindPaneByID( 'Rght' );
  1230.  
  1231.     fPixelPercent = (LControl*)this->FindPaneByID( 'eppp' );
  1232.  
  1233.     fShading = (LControl*)this->FindPaneByID( 'ELPs' );
  1234.     this->SetLatentSub( fHeightEditText );
  1235.     fHeightEditText->SelectAll();
  1236.     
  1237.     // Set control values
  1238.     
  1239.     EDT_HorizRuleData*    fData;    
  1240.     if (EDT_GetCurrentElementType(fContext) == ED_ELEMENT_HRULE)
  1241.          fData = EDT_GetHorizRuleData(fContext);
  1242.      else
  1243.          fData = EDT_NewHorizRuleData();
  1244.      
  1245.     ThrowIfNil_(fData);
  1246.      
  1247.      fHeightEditText->SetValue(fData->size);
  1248.      fWidthEditText->SetValue(fData->iWidth);
  1249.      
  1250.     if (fData->align == ED_ALIGN_LEFT)
  1251.         TurnOn( fLeftAlign );
  1252.     else if ( fData->align ==  ED_ALIGN_RIGHT)
  1253.         TurnOn( fRightAlign );
  1254.     else
  1255.         TurnOn( fCenterAlign );
  1256.  
  1257.      fPixelPercent->SetValue( (fData->bWidthPercent) ? kPercentOfWindowItem : kPixelsItem );
  1258.      
  1259.      fShading->SetValue(fData->bNoShade == FALSE);
  1260.      
  1261.      pExtra = fData->pExtra;    // we'll reuse this pointer
  1262.      fData->pExtra = NULL;    // don't want to free it!
  1263.  
  1264.     EDT_FreeHorizRuleData(fData);
  1265. }
  1266.  
  1267.  
  1268. Boolean CLineProp::CommitChanges( Boolean /* allPanes */ )
  1269. {
  1270.     if ( !IsEditFieldWithinLimits(fHeightEditText, 1, 100))
  1271.     {
  1272.         SwitchTarget( fHeightEditText );
  1273.         fHeightEditText->SelectAll();
  1274.         return false;
  1275.     }
  1276.     
  1277.     if ( fPixelPercent->GetValue() != kPercentOfWindowItem 
  1278.     && !IsEditFieldWithinLimits(fWidthEditText, 1, 10000))
  1279.     {
  1280.         SwitchTarget( fWidthEditText );
  1281.         fWidthEditText->SelectAll();
  1282.         return false;
  1283.     }
  1284.  
  1285.     if (fPixelPercent->GetValue() == kPercentOfWindowItem 
  1286.     && !IsEditFieldWithinLimits(fWidthEditText, 1, 100))
  1287.     {
  1288.         SwitchTarget( fWidthEditText );
  1289.         fWidthEditText->SelectAll();
  1290.         return false;
  1291.     }
  1292.  
  1293.     if ( !mUndoInited )
  1294.     {
  1295.         EDT_BeginBatchChanges( fContext );
  1296.         mUndoInited = true;
  1297.     }
  1298.     
  1299.     EDT_HorizRuleData*    fData;    
  1300.     if (EDT_GetCurrentElementType(fContext) == ED_ELEMENT_HRULE)
  1301.          fData = EDT_GetHorizRuleData(fContext);
  1302.      else
  1303.          fData = EDT_NewHorizRuleData();
  1304.          
  1305.     ThrowIfNil_(fData);
  1306.      
  1307.     if (fLeftAlign->GetValue())
  1308.         fData->align = ED_ALIGN_LEFT;
  1309.     else if (fCenterAlign->GetValue())
  1310.         fData->align = ED_ALIGN_DEFAULT;
  1311.     else if (fRightAlign->GetValue())
  1312.         fData->align = ED_ALIGN_RIGHT;
  1313.  
  1314.     fData->size = fHeightEditText->GetValue();
  1315.     fData->iWidth = fWidthEditText->GetValue();
  1316.     
  1317.     fData->bWidthPercent = (fPixelPercent->GetValue() == kPercentOfWindowItem);
  1318.     
  1319.     fData->bNoShade = !fShading->GetValue();
  1320.     
  1321.     if ( fData->pExtra )
  1322.         XP_FREE( fData->pExtra );
  1323.     fData->pExtra = ( pExtra ) ? XP_STRDUP( pExtra ) : NULL;
  1324.         
  1325.     if (EDT_GetCurrentElementType(fContext) == ED_ELEMENT_HRULE)
  1326.          EDT_SetHorizRuleData( fContext, fData );
  1327.      else
  1328.          EDT_InsertHorizRule( fContext, fData );
  1329.     
  1330.     EDT_FreeHorizRuleData(fData);
  1331.  
  1332.     return true;
  1333. }
  1334.  
  1335.  
  1336. void CLineProp::Help()
  1337. {
  1338.     ShowHelp( HELP_PROPS_HRULE );
  1339. }
  1340.  
  1341.  
  1342. /**********************************************************/
  1343. #pragma mark -
  1344. #pragma mark CEditTabSwitcher
  1345.  
  1346. CEditTabSwitcher::CEditTabSwitcher(LStream* inStream) : CTabSwitcher(inStream)
  1347. {
  1348.     fLinkName = NULL;
  1349. }
  1350.  
  1351.  
  1352. CEditTabSwitcher::~CEditTabSwitcher()
  1353. {
  1354.     XP_FREEIF(fLinkName);
  1355. }
  1356.  
  1357.  
  1358. void CEditTabSwitcher::SetData(MWContext* context, Boolean insert)
  1359. {
  1360.     fContext = context;
  1361.     fInsert = insert;
  1362. }
  1363.  
  1364.  
  1365. void CEditTabSwitcher::Help()
  1366. {
  1367.     CEditContain* page = (CEditContain*)mCurrentPage;
  1368.     if ( page )
  1369.         page->Help();
  1370. }
  1371.  
  1372.  
  1373. void CEditTabSwitcher::DoPostLoad(LView* inLoadedPage, Boolean inFromCache)
  1374. {
  1375.     CEditContain * freshPane = (CEditContain*) inLoadedPage;
  1376.     XP_ASSERT(freshPane);
  1377.     freshPane->SetContext(fContext);
  1378.     freshPane->SetInsertFlag(fInsert);
  1379.     freshPane->SetLinkToLinkName(&fLinkName);
  1380.     freshPane->SetExtraHTMLString( NULL );
  1381.     if (!inFromCache)            // don't blast the contents of the text edit fields if there is something already there.
  1382.         freshPane->ControlsFromPref();
  1383. }
  1384.  
  1385.  
  1386. /**********************************************************/
  1387. #pragma mark -
  1388. #pragma mark CTabbedDialog
  1389.  
  1390. CTabbedDialog::CTabbedDialog( LStream* inStream ): CEditDialog( inStream )
  1391. {
  1392.     ErrorManager::PrepareToInteract();
  1393.     UDesktop::Deactivate();
  1394. }
  1395.  
  1396.  
  1397. CTabbedDialog::~CTabbedDialog()
  1398. {
  1399.     UDesktop::Activate();
  1400. }
  1401.  
  1402.  
  1403. void CTabbedDialog::FinishCreateSelf()
  1404. {
  1405.     mTabControl = NULL;
  1406.     mTabSwitcher = NULL;
  1407.  
  1408.     LDialogBox::FinishCreateSelf();
  1409. }
  1410.  
  1411.  
  1412. void CTabbedDialog::InitializeDialogControls()
  1413. {
  1414.     LControl *ApplyButton = (LControl*)FindPaneByID('APPY');
  1415.     if (fInsert && ApplyButton)
  1416.         ApplyButton->Disable();
  1417.     SetDefaultButton('OKOK');
  1418.     
  1419.     mTabControl = (CTabControl*)FindPaneByID(CTabControl::class_ID);
  1420.     ThrowIfNULL_(mTabControl);
  1421.  
  1422.     mTabSwitcher = (CEditTabSwitcher*)FindPaneByID(CTabSwitcher::class_ID);
  1423.     ThrowIfNULL_(mTabSwitcher);
  1424.     
  1425.     mTabSwitcher->SetData(fContext, fInsert);
  1426.     
  1427.     mTabControl->DoLoadTabs(fInWindowID);
  1428.     mTabControl->SetValue(fInitTabValue);
  1429. }
  1430.  
  1431.  
  1432. void CTabbedDialog::RegisterViewTypes()
  1433. {
  1434. #ifdef COOL_IMAGE_RADIO_BUTTONS
  1435.     RegisterClass_( CImageAlignButton);
  1436. #endif
  1437.     RegisterClass_( CLargeEditField);
  1438.     RegisterClass_( CLargeEditFieldBroadcast);
  1439.     RegisterClass_( CCaption);
  1440.  
  1441.     RegisterClass_( CTabControl);
  1442.     RegisterClass_( CTabbedDialog);
  1443.     RegisterClass_( CEDCharacterContain);
  1444.     RegisterClass_( CEDParagraphContain);
  1445.     RegisterClass_( CEDLinkContain);
  1446.     RegisterClass_( CEDImageContain);
  1447.     RegisterClass_( CEDDocPropGeneralContain);
  1448.     RegisterClass_( CEDDocPropAppearanceContain);
  1449.     RegisterClass_( CEDDocPropAdvancedContain);
  1450.     RegisterClass_( LToggleButton);
  1451.     RegisterClass_( CUnknownTag);
  1452.     RegisterClass_( CPublish);
  1453.     RegisterClass_( CTableInsertDialog);
  1454.     RegisterClass_( CEditTabSwitcher);
  1455.     RegisterClass_( CEDTableContain);
  1456.     RegisterClass_( CEDTableCellContain);
  1457.  
  1458.     RegisterClass_( CEDDocAppearanceNoTab);
  1459.     RegisterClass_( CFormatMsgColorAndImageDlog);
  1460.     
  1461. }
  1462.  
  1463.  
  1464. Boolean CTabbedDialog::CommitChanges(Boolean allPanes)
  1465. {
  1466.     if ( !allPanes )
  1467.     {
  1468.         MessageT thePageMessage = mTabControl->GetMessageForValue(mTabControl->GetValue());
  1469.         CEditContain* thePage = (CEditContain*)mTabSwitcher->FindPageByID(thePageMessage);
  1470.         if (thePage && !thePage->AllFieldsOK())
  1471.             return FALSE;
  1472.         
  1473.         if (thePage != NULL)
  1474.         {
  1475.             if ( !mUndoInited )
  1476.             {
  1477.                 EDT_BeginBatchChanges( fContext );
  1478.                 mUndoInited = true;
  1479.             }
  1480.             
  1481.             thePage->PrefsFromControls();
  1482.         }
  1483.         return true;
  1484.     }
  1485.         
  1486.     Int32    start = 1;
  1487.     Int32    end = mTabControl->GetMaxValue();
  1488.  
  1489.     // First, lets make sure that all the panes are happy.
  1490.     for (int i = start; i <= end; i ++ ) {
  1491.     
  1492.         MessageT thePageMessage = mTabControl->GetMessageForValue(i);
  1493.         CEditContain* thePage = (CEditContain*)mTabSwitcher->FindPageByID(thePageMessage);
  1494.  
  1495.         if (thePage && !thePage->AllFieldsOK())
  1496.         {
  1497.             mTabControl->SetValue(i);            // go to the offending pane.
  1498.             return FALSE;
  1499.         }
  1500.     }
  1501.     
  1502.     // If the CImagesLocal pane is up, commit that one first (in case we are doing an insert)
  1503.     if ( !mUndoInited )
  1504.     {
  1505.         EDT_BeginBatchChanges( fContext );
  1506.         mUndoInited = true;
  1507.     }
  1508.     
  1509.     for (int i = start; i <= end; i ++ )
  1510.     {
  1511.         MessageT thePageMessage = mTabControl->GetMessageForValue(i);
  1512.         CEditContain* thePage = (CEditContain*)mTabSwitcher->FindPageByID(thePageMessage);
  1513.  
  1514.         if (thePage && (thePage->GetUserCon() == CEDImageContain::class_ID ))
  1515.             thePage->PrefsFromControls();
  1516.     }
  1517.     
  1518.     // If the CEDLinkContain pane is up, commit that one next (in case we are doing an insert)
  1519.     for (int i = start; i <= end; i ++ )
  1520.     {
  1521.         MessageT thePageMessage = mTabControl->GetMessageForValue(i);
  1522.         CEditContain* thePage = (CEditContain*)mTabSwitcher->FindPageByID(thePageMessage);
  1523.  
  1524.         if (thePage && (thePage->GetUserCon() == CEDLinkContain::class_ID ))
  1525.             thePage->PrefsFromControls();
  1526.     }
  1527.     
  1528.     // If the CEDDocPropAppearanceContain pane is up, commit that one first (in case we are doing a doc properties)
  1529.     for (int i = start; i <= end; i ++ )
  1530.     {
  1531.         MessageT thePageMessage = mTabControl->GetMessageForValue(i);
  1532.         CEditContain* thePage = (CEditContain*)mTabSwitcher->FindPageByID(thePageMessage);
  1533.  
  1534.         if (thePage && (thePage->GetUserCon() == CEDDocPropAppearanceContain::class_ID ))
  1535.             thePage->PrefsFromControls();
  1536.     }
  1537.     
  1538.     // If the CEDDocPropGeneralContain pane is up, commit that one next (in case we are doing a doc properties)
  1539.     for (int i = start; i <= end; i ++ )
  1540.     {
  1541.         MessageT thePageMessage = mTabControl->GetMessageForValue(i);
  1542.         CEditContain* thePage = (CEditContain*)mTabSwitcher->FindPageByID(thePageMessage);
  1543.  
  1544.         if (thePage && (thePage->GetUserCon() == CEDDocPropGeneralContain::class_ID ))
  1545.             thePage->PrefsFromControls();
  1546.     }
  1547.     
  1548.     // commit the rest
  1549.     for (int i = start; i <= end; i ++ )
  1550.     {
  1551.         MessageT thePageMessage = mTabControl->GetMessageForValue(i);
  1552.         CEditContain* thePage = (CEditContain*)mTabSwitcher->FindPageByID(thePageMessage);
  1553.         if (thePage && (thePage->GetUserCon() != CEDImageContain::class_ID ) && (thePage->GetUserCon() != CEDLinkContain::class_ID ) &&
  1554.             (thePage->GetUserCon() != CEDDocPropAppearanceContain::class_ID ) && (thePage->GetUserCon() != CEDDocPropGeneralContain::class_ID ))
  1555.             thePage->PrefsFromControls();
  1556.     }
  1557.     
  1558.  
  1559. // I admit this is not a very clean design... May cause button flicker when you hit "Insert"
  1560. //
  1561. // When you are inserting an image or a link and you hit "Apply", the "Insert" button should change to "OK"
  1562. // For simplicity, we do it anytime the user hits "Apply", "Insert" or "OK" since the other 2 times the dlog will soon disappear anyway.
  1563.  
  1564.     LControl *OKButton = (LControl*)FindPaneByID('OKOK');
  1565.     if (OKButton)
  1566.         OKButton->Show();
  1567.  
  1568.     return TRUE;
  1569. }
  1570.  
  1571.  
  1572. void CTabbedDialog::Help()
  1573. {
  1574.     mTabSwitcher->Help();
  1575. }
  1576.  
  1577.  
  1578. /**********************************************************/
  1579. #pragma mark -
  1580. #pragma mark Table Dialogs
  1581.  
  1582. static void GetTableDataFromControls( EDT_TableData *fData, LControl *borderCheckBox, LGAEditField *borderWidth,
  1583.                             LGAEditField *cellSpacing, LGAEditField *cellPadding, 
  1584.                             LControl *customWidth, LControl *isWPercent, LGAEditField *widthSize,
  1585.                             LControl *customHeight, LControl *isHPercent, LGAEditField *heightSize,
  1586.                             LControl *hasColor, CColorButton *customColor, LO_Color *backgroundColor,
  1587.                             LControl *fastLayout, LGAPopup *alignmentMenu,
  1588.                             LControl *useImage, CLargeEditField *imageName, LControl *leaveImage, char *pExtra )
  1589. {
  1590.     fData->bBorderWidthDefined = borderCheckBox->GetValue();
  1591.     if ( fData->bBorderWidthDefined )
  1592.         fData->iBorderWidth = borderWidth->GetValue();
  1593.     else
  1594.         fData->iBorderWidth = 0;
  1595.     
  1596.     fData->iCellSpacing = cellSpacing->GetValue();
  1597.     fData->iCellPadding = cellPadding->GetValue();
  1598.     
  1599.     if ( customWidth->GetValue() )
  1600.     {
  1601.         fData->bWidthDefined = TRUE;
  1602.         fData->bWidthPercent = isWPercent->GetValue() == kPercentOfWindowItem;
  1603.         fData->iWidth = widthSize->GetValue();
  1604.     }
  1605.     else
  1606.         fData->bWidthDefined = FALSE;
  1607.     
  1608.     if (customHeight->GetValue())
  1609.     {
  1610.         fData->bHeightDefined = TRUE;
  1611.         fData->bHeightPercent = isHPercent->GetValue() == kPercentOfWindowItem;
  1612.         fData->iHeight = heightSize->GetValue();
  1613.     }
  1614.     else
  1615.         fData->bHeightDefined = FALSE;
  1616.     
  1617.     if (fData->pColorBackground)
  1618.         XP_FREE(fData->pColorBackground);            // we'll replace it with our own if we use it at all.
  1619.     fData->pColorBackground = NULL;
  1620.     if (hasColor->GetValue())
  1621.     {
  1622.         *backgroundColor = UGraphics::MakeLOColor(customColor->GetColor());
  1623.         fData->pColorBackground = backgroundColor;        // I hope that EDT_SetTableData() doesn't hang onto this pointer for long...
  1624.     }
  1625.  
  1626.     switch ( alignmentMenu->GetValue() )
  1627.     {
  1628.         default:
  1629.         case 1:    fData->align = ED_ALIGN_LEFT;        break;
  1630.         case 2:    fData->align = ED_ALIGN_ABSCENTER;    break;
  1631.         case 3:    fData->align = ED_ALIGN_RIGHT;        break;
  1632.     }
  1633.  
  1634.     fData->bUseCols = fastLayout->GetValue();
  1635.     
  1636.     if ( fData->pBackgroundImage )
  1637.     {
  1638.         XP_FREE( fData->pBackgroundImage );
  1639.         fData->pBackgroundImage = NULL;
  1640.     }
  1641.     if ( useImage->GetValue() )
  1642.         fData->pBackgroundImage = imageName->GetLongDescriptor();
  1643.     fData->bBackgroundNoSave = leaveImage->GetValue();
  1644.  
  1645.     if ( fData->pExtra )
  1646.         XP_FREE( fData->pExtra );
  1647.      fData->pExtra = pExtra;    // temporarily assign; we don't want to free it though!
  1648. }
  1649.  
  1650.  
  1651. CTableInsertDialog::CTableInsertDialog( LStream* inStream ) : CEditDialog( inStream )
  1652. {
  1653.     ErrorManager::PrepareToInteract();
  1654.     UDesktop::Deactivate();
  1655. }
  1656.  
  1657.  
  1658. CTableInsertDialog::~CTableInsertDialog()
  1659. {
  1660.     UDesktop::Activate();
  1661. }
  1662.  
  1663.  
  1664. void CTableInsertDialog::FinishCreateSelf()
  1665. {
  1666.     // Create Controls
  1667.     CEditDialog::FinishCreateSelf();
  1668.     
  1669.     UReanimator::LinkListenerToControls( this, this, 5115 );        // the table guts are in RIDL 5115
  1670.     
  1671.     // Find Controls
  1672.     fNumRowsEditText = (LGAEditField*)FindPaneByID( 'rows' );
  1673.     fNumColsEditText = (LGAEditField*)FindPaneByID( 'cols' );
  1674.     
  1675.     fBorderCheckBox = (LControl*)FindPaneByID( 'BrdW' );
  1676.     fBorderCheckBox->SetValueMessage( 'BrdW' );
  1677.     
  1678.     fBorderWidthEditText = (LGAEditField*)FindPaneByID( 'brdw' );
  1679.     fCellSpacingEditText = (LGAEditField*)FindPaneByID( 'clsp' );
  1680.     fCellPaddingEditText = (LGAEditField*)FindPaneByID( 'clpd' );
  1681.     
  1682.     fCustomWidth = (LControl*)FindPaneByID( 'twth' );
  1683.     fWidthEditText = (LGAEditField*)FindPaneByID( 'wdth' );
  1684.     fWidthPopup = (LControl*)FindPaneByID( 'WdPU' );
  1685.     
  1686.     fCustomHeight = (LControl*)FindPaneByID( 'thgt' );
  1687.     fHeightEditText = (LGAEditField*)FindPaneByID( 'hght' );
  1688.     fHeightPopup = (LControl*)FindPaneByID( 'HtPU' );
  1689.     
  1690.     fCustomColor = (LControl*)FindPaneByID( 'tclr' );
  1691.     fColorCustomColor = (CColorButton*)FindPaneByID( 'Colo' );
  1692.     
  1693.     fIncludeCaption = (LControl*)FindPaneByID( 'cptn' );
  1694.     fCaptionAboveBelow = (LControl*)FindPaneByID( 'cPop' );
  1695.  
  1696.     mTableAlignment = (LGAPopup *)FindPaneByID( 'HzPU' );
  1697.     
  1698.     mFastLayout = (LControl *)FindPaneByID( 'FLay' );
  1699.     mUseImage = (LControl*)FindPaneByID( 'UseI' );
  1700.     mImageFileName = (CLargeEditField *)FindPaneByID( 'TImg' );
  1701.     mImageFileName->AddListener(this);
  1702.     mLeaveImage = (LControl *)FindPaneByID( 'LvIm' );
  1703.  
  1704.     SetLatentSub( fNumRowsEditText );
  1705.     fNumRowsEditText->SelectAll();
  1706.     
  1707.     // Set control values
  1708.     EDT_TableData *fData = EDT_NewTableData();
  1709.     if (fData != NULL)
  1710.     {
  1711.          fNumRowsEditText->SetValue( fData->iRows );
  1712.          fNumColsEditText->SetValue( fData->iColumns );
  1713.          
  1714.          fBorderCheckBox->SetValue( fData->bBorderWidthDefined );
  1715.          fBorderWidthEditText->SetValue( fData->iBorderWidth );
  1716.          fCellSpacingEditText->SetValue( fData->iCellSpacing );
  1717.          fCellPaddingEditText->SetValue( fData->iCellPadding );
  1718.  
  1719.         fCustomWidth->SetValue( fData->bWidthDefined );
  1720.         fWidthEditText->SetValue( fData->iWidth );
  1721.         fWidthPopup->SetValue( fData->bWidthPercent ? kPercentOfWindowItem : kPixelsItem );
  1722.         
  1723.         fCustomHeight->SetValue( fData->bHeightDefined );
  1724.         fHeightEditText->SetValue( fData->iHeight );
  1725.         fHeightPopup->SetValue( fData->bHeightPercent ? kPercentOfWindowItem : kPixelsItem );
  1726.         
  1727.         mUseImage->SetValue( fData->pBackgroundImage != NULL );
  1728.         if ( fData->pBackgroundImage )
  1729.             mImageFileName->SetLongDescriptor( fData->pBackgroundImage );
  1730.         mLeaveImage->SetValue( fData->bBackgroundNoSave );
  1731.  
  1732.         int value;
  1733.         switch ( fData->align )
  1734.         {
  1735.             default:
  1736.             case ED_ALIGN_LEFT:            value = 1;    break;
  1737.             case ED_ALIGN_ABSCENTER:    value = 2;    break;
  1738.             case ED_ALIGN_RIGHT:        value = 3;    break;
  1739.         }
  1740.         mTableAlignment->SetValue( value );
  1741.         
  1742.         mFastLayout->SetValue( fData->bUseCols );
  1743.         pExtra = fData->pExtra;        // don't bother to make our own copy
  1744.         fData->pExtra = NULL;        // set to NULL so backend doesn't delete
  1745.         
  1746.         EDT_FreeTableData( fData );
  1747.     }
  1748.  
  1749.     RGBColor macColor;
  1750.     fCustomColor->SetValue(FALSE);                // no custom color
  1751.     macColor.red = 0xFFFF;                        // but start with white if they pick one.
  1752.     macColor.green = 0xFFFF;
  1753.     macColor.blue = 0xFFFF;
  1754.     fColorCustomColor->SetColor(macColor);
  1755.  
  1756.     fIncludeCaption->SetValue(FALSE);            //assume no caption
  1757.     fCaptionAboveBelow->SetValue( 1 );
  1758.  
  1759.     AdjustEnable();
  1760. }
  1761.  
  1762.  
  1763. void CTableInsertDialog::InitializeDialogControls()
  1764. {
  1765.     short             ResID;
  1766.     CStr255            title;
  1767.     StringHandle    titleH;
  1768.  
  1769.     if (EDT_IsInsertPointInTable(fContext))
  1770.         ResID = EDITOR_PERCENT_PARENT_CELL;
  1771.     else
  1772.         ResID = EDITOR_PERCENT_WINDOW;
  1773.  
  1774.     titleH = GetString( ResID );
  1775.     if (titleH)
  1776.     {
  1777.         title = ** (CStr255**)titleH;
  1778.         MenuHandle menuh = ((LGAPopup *)fWidthPopup)->GetMacMenuH();
  1779.         if (menuh)
  1780.         {
  1781.             SetMenuItemText( menuh, kPercentOfWindowItem, title );
  1782.             ((LGAPopup *)fWidthPopup)->SetMacMenuH( menuh );    // resets menu width
  1783.         }
  1784.         
  1785.         menuh = ((LGAPopup *)fHeightPopup)->GetMacMenuH();
  1786.         if (menuh)
  1787.         {
  1788.             SetMenuItemText( menuh, kPercentOfWindowItem, title );
  1789.             ((LGAPopup *)fHeightPopup)->SetMacMenuH( menuh );    // resets menu width
  1790.         }
  1791.     }
  1792. }
  1793.  
  1794.  
  1795. void CTableInsertDialog::AdjustEnable()
  1796. {
  1797.     LView *bordercaption = (LView *)FindPaneByID(1);
  1798.     if ( fBorderCheckBox->GetValue() )
  1799.     {
  1800.         bordercaption->Enable();
  1801.         fBorderWidthEditText->Enable();
  1802.     }
  1803.     else
  1804.     {
  1805.         bordercaption->Disable();
  1806.         fBorderWidthEditText->Disable();
  1807.     }
  1808.     
  1809.     if (fCustomWidth->GetValue()) {
  1810.         fWidthEditText->Enable();
  1811.         fWidthPopup->Enable();
  1812.     } else {
  1813.         fWidthEditText->Disable();
  1814.         fWidthPopup->Disable();
  1815.     }
  1816.  
  1817.     if (fCustomHeight->GetValue()) {
  1818.         fHeightEditText->Enable();
  1819.         fHeightPopup->Enable();
  1820.     } else {
  1821.         fHeightEditText->Disable();
  1822.         fHeightPopup->Disable();
  1823.     }
  1824.  
  1825.     if (fIncludeCaption->GetValue())
  1826.         fCaptionAboveBelow->Enable();
  1827.     else
  1828.         fCaptionAboveBelow->Disable();
  1829.     
  1830.     if ( mUseImage->GetValue() )
  1831.         mLeaveImage->Enable();
  1832.     else
  1833.         mLeaveImage->Disable();
  1834. }
  1835.  
  1836.  
  1837. Boolean CTableInsertDialog::CommitChanges(Boolean /* allPanes */ )
  1838. {
  1839.     if (!IsEditFieldWithinLimits(fNumRowsEditText, 1, 100)) {
  1840.         SwitchTarget( fNumRowsEditText );
  1841.         fNumRowsEditText->SelectAll();
  1842.         return FALSE;
  1843.     }
  1844.  
  1845.     if (!IsEditFieldWithinLimits(fNumColsEditText, 1, 100)) {
  1846.         SwitchTarget( fNumColsEditText );
  1847.         fNumColsEditText->SelectAll();
  1848.         return FALSE;
  1849.     }
  1850.  
  1851.     if ( fBorderCheckBox->GetValue() )
  1852.     {
  1853.         if (!IsEditFieldWithinLimits(fBorderWidthEditText, 0, 10000)) {
  1854.             SwitchTarget( fBorderWidthEditText );
  1855.             fBorderWidthEditText->SelectAll();
  1856.             return FALSE;
  1857.         }
  1858.     }
  1859.  
  1860.     if (!IsEditFieldWithinLimits(fCellSpacingEditText, 0, 10000)) {
  1861.         SwitchTarget( fCellSpacingEditText );
  1862.         fCellSpacingEditText->SelectAll();
  1863.         return FALSE;
  1864.     }
  1865.  
  1866.     if (!IsEditFieldWithinLimits(fCellPaddingEditText, 0, 10000)) {
  1867.         SwitchTarget( fCellPaddingEditText );
  1868.         fCellPaddingEditText->SelectAll();
  1869.         return FALSE;
  1870.     }
  1871.  
  1872.     if (fCustomWidth->GetValue()) {
  1873.         if (fWidthPopup->GetValue() == kPixelsItem && !IsEditFieldWithinLimits(fWidthEditText, 1, 10000)) {
  1874.             SwitchTarget( fWidthEditText );
  1875.             fWidthEditText->SelectAll();
  1876.             return FALSE;
  1877.         }
  1878.  
  1879.         if (fWidthPopup->GetValue() == kPercentOfWindowItem && !IsEditFieldWithinLimits(fWidthEditText, 1, 100)) {
  1880.             SwitchTarget( fWidthEditText );
  1881.             fWidthEditText->SelectAll();
  1882.             return FALSE;
  1883.         }
  1884.     }
  1885.  
  1886.     if (fCustomHeight->GetValue()) {
  1887.         if (fHeightPopup->GetValue() == kPixelsItem && !IsEditFieldWithinLimits(fHeightEditText, 1, 10000)) {
  1888.             SwitchTarget( fHeightEditText );
  1889.             fHeightEditText->SelectAll();
  1890.             return FALSE;
  1891.         }
  1892.  
  1893.         if (fHeightPopup->GetValue() == kPercentOfWindowItem && !IsEditFieldWithinLimits(fHeightEditText, 1, 100)) {
  1894.             SwitchTarget( fHeightEditText );
  1895.             fHeightEditText->SelectAll();
  1896.             return FALSE;
  1897.         }
  1898.     }
  1899.  
  1900.     LO_Color backgroundColor;
  1901.     EDT_TableData *fData = EDT_NewTableData();
  1902.     if (fData == NULL)
  1903.         return FALSE;
  1904.     
  1905.     EDT_BeginBatchChanges( fContext );
  1906.  
  1907.     fData->iRows = fNumRowsEditText->GetValue();
  1908.     fData->iColumns = fNumColsEditText->GetValue();
  1909.     
  1910.     GetTableDataFromControls( fData, fBorderCheckBox, fBorderWidthEditText,
  1911.                             fCellSpacingEditText, fCellPaddingEditText, 
  1912.                             fCustomWidth, fWidthPopup, fWidthEditText,
  1913.                             fCustomHeight, fHeightPopup, fHeightEditText,
  1914.                             fCustomColor, fColorCustomColor, &backgroundColor,
  1915.                             mFastLayout, mTableAlignment,
  1916.                             mUseImage, mImageFileName, mLeaveImage, pExtra );
  1917.     
  1918.      EDT_InsertTable( fContext, fData );
  1919.      
  1920.      fData->pExtra = NULL;                // don't free this! we still use it!
  1921.      fData->pColorBackground = NULL;        // no need to free this, it is our local variable!
  1922.     EDT_FreeTableData(fData);
  1923.     
  1924.     
  1925.     // clean this up later after we're sure the XP interfaces aren't improving.
  1926.     if (fIncludeCaption->GetValue())
  1927.     {
  1928.         EDT_TableCaptionData* fCaptionData;
  1929.         fCaptionData = EDT_NewTableCaptionData();
  1930.         if (fCaptionData)
  1931.         {
  1932.             if ( fCaptionAboveBelow->GetValue() == 1 )
  1933.                 fCaptionData->align = ED_ALIGN_ABSTOP;
  1934.             else
  1935.                 fCaptionData->align = ED_ALIGN_ABSBOTTOM;    // got this constant from CEditTableElement::SetCaption();
  1936.                 
  1937.             EDT_InsertTableCaption( fContext, fCaptionData );
  1938.             EDT_FreeTableCaptionData( fCaptionData );
  1939.         }
  1940.     }
  1941.  
  1942.     EDT_EndBatchChanges( fContext );
  1943.  
  1944.     return TRUE;
  1945. }
  1946.  
  1947.  
  1948. void CTableInsertDialog::Help()
  1949. {
  1950.     ShowHelp( HELP_NEW_TABLE_PROPS );
  1951. }
  1952.  
  1953.  
  1954. void CTableInsertDialog::ListenToMessage( MessageT inMessage, void* ioParam )
  1955. {
  1956.     switch ( inMessage )
  1957.     {
  1958.         case 'BrdW':
  1959.         case 'twth':
  1960.         case 'thgt':
  1961.         case 'tclr':
  1962.         case 'cptn':
  1963.             AdjustEnable();
  1964.             break;
  1965.         
  1966.         case msg_LinkColorChange:
  1967.             fCustomColor->SetValue(TRUE);
  1968.             break;
  1969.         
  1970.         case 'UseI':
  1971.             if (mUseImage->GetValue() == 1)
  1972.             {                // we are trying to set the image
  1973.                 CStr255 url;
  1974.                 mImageFileName->GetDescriptor(url);
  1975.                 if (url == CStr255::sEmptyString)
  1976.                 {        // but it doesn't exist
  1977.                     ChooseImageFile( mImageFileName );    // so try to get it
  1978.                     mImageFileName->GetDescriptor( url );
  1979.                     if (url == CStr255::sEmptyString)     // but, if we were unsuccessful
  1980.                         mUseImage->SetValue( 0 );        // revert back.
  1981.                 }
  1982.             }
  1983.             AdjustEnable();
  1984.             break;
  1985.         
  1986.         case 'wst1':
  1987.             {
  1988.             ChooseImageFile( mImageFileName );    // try to get it
  1989.             CStr255 url2;
  1990.             mImageFileName->GetDescriptor( url2 );
  1991.             if (url2 == CStr255::sEmptyString)     // if we were unsuccessful
  1992.                 mUseImage->SetValue( 0 );        // don't try to use image
  1993.             else
  1994.                 mUseImage->SetValue( 1 );
  1995.             }
  1996.             AdjustEnable();
  1997.             break;
  1998.         
  1999.         case msg_EditField2:
  2000.             {
  2001.             CStr255 url3;
  2002.             mImageFileName->GetDescriptor( url3 );
  2003.             mUseImage->SetValue( url3[ 0 ] ? Button_On : Button_Off );
  2004.             }
  2005.             break;
  2006.                 
  2007.         case 'Xtra':
  2008.             char * newExtraHTML = NULL;
  2009.             Boolean canceled = !GetExtraHTML( pExtra, &newExtraHTML  ,GetWinCSID() );
  2010.             if (!canceled)
  2011.             {
  2012.                 if ( pExtra )
  2013.                     XP_FREE( pExtra );
  2014.                 pExtra = newExtraHTML;
  2015.             }
  2016.             break;
  2017.         
  2018.         default:
  2019.             CEditDialog::ListenToMessage( inMessage, ioParam );
  2020.             break;
  2021.     }
  2022. }
  2023.  
  2024.  
  2025. void CEDTableContain::FinishCreateSelf()
  2026. {
  2027.     // Find Controls
  2028.     fBorderCheckBox = (LControl*)FindPaneByID( 'BrdW' );
  2029.     fBorderCheckBox->SetValueMessage( 'BrdW' );
  2030.     
  2031.     fBorderWidthEditText = (LGAEditField*)this->FindPaneByID( 'brdw' );
  2032.     fCellSpacingEditText = (LGAEditField*)this->FindPaneByID( 'clsp' );
  2033.     fCellPaddingEditText = (LGAEditField*)this->FindPaneByID( 'clpd' );
  2034.     
  2035.     fCustomWidth = (LControl*)this->FindPaneByID( 'twth' );
  2036.     fWidthEditText = (LGAEditField*)this->FindPaneByID( 'wdth' );
  2037.     fWidthPopup = (LControl*)this->FindPaneByID( 'WdPU' );
  2038.     
  2039.     fCustomHeight = (LControl*)this->FindPaneByID( 'thgt' );
  2040.     fHeightEditText = (LGAEditField*)this->FindPaneByID( 'hght' );
  2041.     fHeightPopup = (LControl*)this->FindPaneByID( 'HtPU' );
  2042.     
  2043.     fCustomColor = (LControl*)this->FindPaneByID( 'tclr' );
  2044.     fColorCustomColor = (CColorButton*)FindPaneByID( 'Colo' );
  2045.     
  2046.     fIncludeCaption = (LControl*)this->FindPaneByID( 'cptn' );
  2047.     fCaptionAboveBelow = (LControl*)this->FindPaneByID( 'cPop' );
  2048.  
  2049.     mTableAlignment = (LGAPopup *)FindPaneByID( 'HzPU' );
  2050.  
  2051.     mFastLayout = (LControl *)FindPaneByID( 'FLay' );
  2052.     mUseImage = (LControl*)FindPaneByID( 'UseI' );
  2053.     mImageFileName = (CLargeEditField *)FindPaneByID( 'TImg' );
  2054.     mImageFileName->AddListener(this);
  2055.     mLeaveImage = (LControl *)FindPaneByID( 'LvIm' );
  2056.     pExtra = NULL;
  2057.  
  2058.     UReanimator::LinkListenerToControls( this, this, 5115 );
  2059.     SetLatentSub( fBorderWidthEditText );
  2060.     fBorderWidthEditText->SelectAll();
  2061. }
  2062.  
  2063.  
  2064. void CEDTableContain::Help()
  2065. {
  2066.     ShowHelp( HELP_TABLE_PROPS_TABLE );
  2067. }
  2068.  
  2069.  
  2070. void CEDTableContain::AdjustEnable()
  2071. {
  2072.     LView *bordercaption = (LView *)FindPaneByID(1);
  2073.     if ( fBorderCheckBox->GetValue() )
  2074.     {
  2075.         bordercaption->Enable();
  2076.         fBorderWidthEditText->Enable();
  2077.     }
  2078.     else
  2079.     {
  2080.         bordercaption->Disable();
  2081.         fBorderWidthEditText->Disable();
  2082.     }
  2083.     
  2084.     if (fCustomWidth->GetValue()) {
  2085.         fWidthEditText->Enable();
  2086.         fWidthPopup->Enable();
  2087.     } else {
  2088.         fWidthEditText->Disable();
  2089.         fWidthPopup->Disable();
  2090.     }
  2091.  
  2092.     if (fCustomHeight->GetValue()) {
  2093.         fHeightEditText->Enable();
  2094.         fHeightPopup->Enable();
  2095.     } else {
  2096.         fHeightEditText->Disable();
  2097.         fHeightPopup->Disable();
  2098.     }
  2099.  
  2100.     if (fIncludeCaption->GetValue())
  2101.         fCaptionAboveBelow->Enable();
  2102.     else
  2103.         fCaptionAboveBelow->Disable();
  2104.     
  2105.     if ( mUseImage->GetValue() )
  2106.         mLeaveImage->Enable();
  2107.     else
  2108.         mLeaveImage->Disable();
  2109. }
  2110.  
  2111.  
  2112. void CEDTableContain::PrefsFromControls()
  2113. {
  2114.     EDT_TableData *fData = EDT_GetTableData(fContext);
  2115.     if (fData == NULL)
  2116.         return;
  2117.     
  2118.     LO_Color backgroundColor;
  2119.     GetTableDataFromControls( fData, fBorderCheckBox, fBorderWidthEditText,
  2120.                             fCellSpacingEditText, fCellPaddingEditText, 
  2121.                             fCustomWidth, fWidthPopup, fWidthEditText,
  2122.                             fCustomHeight, fHeightPopup, fHeightEditText,
  2123.                             fCustomColor, fColorCustomColor, &backgroundColor,
  2124.                             mFastLayout, mTableAlignment,
  2125.                             mUseImage, mImageFileName, mLeaveImage, pExtra );
  2126.  
  2127.      EDT_SetTableData( fContext, fData );
  2128.      
  2129.      fData->pExtra = NULL;                    // don't free this! we still use it!
  2130.      fData->pColorBackground = NULL;            // no need to free this, it is our local variable!
  2131.     EDT_FreeTableData(fData);
  2132.     
  2133. // deal with caption
  2134.     EDT_TableCaptionData* fCaptionData = EDT_GetTableCaptionData(fContext);                // find out if we have a caption....
  2135.     if (fIncludeCaption->GetValue() == FALSE)
  2136.     {
  2137.         if (fCaptionData)
  2138.         {
  2139.             EDT_DeleteTableCaption(fContext);                // there is one, but we don't want it.
  2140.             EDT_FreeTableCaptionData(fCaptionData);
  2141.         }
  2142.     }
  2143.     else
  2144.     {
  2145.         if (fCaptionData)
  2146.         {                                    // we want one, and there is one!!!
  2147.             if ( fCaptionAboveBelow->GetValue() == 1 )
  2148.                 fCaptionData->align = ED_ALIGN_ABSTOP;
  2149.             else
  2150.                 fCaptionData->align = ED_ALIGN_ABSBOTTOM;
  2151.                 
  2152.             EDT_SetTableCaptionData( fContext, fCaptionData );
  2153.         }
  2154.         else
  2155.         {
  2156.             fCaptionData = EDT_NewTableCaptionData();        // we want one and there isn't one!!
  2157.             if (fCaptionData)
  2158.             {
  2159.                 if ( fCaptionAboveBelow->GetValue() == 1 )
  2160.                     fCaptionData->align = ED_ALIGN_ABSTOP;
  2161.                 else
  2162.                     fCaptionData->align = ED_ALIGN_ABSBOTTOM;
  2163.                     
  2164.                 EDT_InsertTableCaption( fContext, fCaptionData );
  2165.             }
  2166.         }
  2167.         
  2168.         if (fCaptionData)
  2169.             EDT_FreeTableCaptionData(fCaptionData);        // we have to check this, because EDT_NewTableCaptionData() may have returned NULL
  2170.     }
  2171. }
  2172.  
  2173.  
  2174. // Initialize from preferences
  2175. void CEDTableContain::ControlsFromPref()
  2176. {
  2177.     short             ResID;
  2178.     CStr255            title;
  2179.     StringHandle    titleH;
  2180.  
  2181.     if (EDT_IsInsertPointInNestedTable(fContext))
  2182.         ResID = EDITOR_PERCENT_PARENT_CELL;
  2183.     else
  2184.         ResID = EDITOR_PERCENT_WINDOW;
  2185.  
  2186.     titleH = GetString( ResID );
  2187.     if (titleH)
  2188.     {
  2189.         title = ** (CStr255**)titleH;
  2190.         MenuHandle menuh = ((LGAPopup *)fWidthPopup)->GetMacMenuH();
  2191.         if (menuh)
  2192.         {
  2193.             SetMenuItemText( menuh, kPercentOfWindowItem, title );
  2194.             ((LGAPopup *)fWidthPopup)->SetMacMenuH( menuh );    // resets menu width
  2195.         }
  2196.         
  2197.         menuh = ((LGAPopup *)fHeightPopup)->GetMacMenuH();
  2198.         if (menuh)
  2199.         {
  2200.             SetMenuItemText( menuh, kPercentOfWindowItem, title );
  2201.             ((LGAPopup *)fHeightPopup)->SetMacMenuH( menuh );    // resets menu width
  2202.         }
  2203.     }
  2204.  
  2205.      EDT_TableData* fData = EDT_GetTableData(fContext);
  2206.      if (fData == NULL)
  2207.          return;
  2208.  
  2209.     switch (fData->align)
  2210.     {
  2211.         default:
  2212.         case ED_ALIGN_LEFT:     mTableAlignment->SetValue( 1 ); break;
  2213.         case ED_ALIGN_ABSCENTER: mTableAlignment->SetValue( 2 ); break;
  2214.         case ED_ALIGN_RIGHT:     mTableAlignment->SetValue( 3 );    break;
  2215.     }
  2216.     
  2217.     mFastLayout->SetValue( fData->bUseCols );
  2218.     
  2219.     fBorderCheckBox->SetValue( fData->bBorderWidthDefined );
  2220.     fBorderWidthEditText->SetValue( fData->iBorderWidth );
  2221.      fCellSpacingEditText->SetValue( fData->iCellSpacing );
  2222.      fCellPaddingEditText->SetValue( fData->iCellPadding );
  2223.  
  2224.     fCustomWidth->SetValue( fData->bWidthDefined );
  2225.     fWidthEditText->SetValue( fData->iWidth );
  2226.     fWidthPopup->SetValue( fData->bWidthPercent ? kPercentOfWindowItem : kPixelsItem );
  2227.     
  2228.     fCustomHeight->SetValue( fData->bHeightDefined );
  2229.     fHeightEditText->SetValue( fData->iHeight );
  2230.     fHeightPopup->SetValue( fData->bHeightPercent ? kPercentOfWindowItem : kPixelsItem );
  2231.     
  2232.     RGBColor macColor;
  2233.     fCustomColor->SetValue( fData->pColorBackground != NULL );
  2234.      if (fData->pColorBackground)
  2235.         macColor = UGraphics::MakeRGBColor(*fData->pColorBackground);
  2236.     else
  2237.         macColor = UGraphics::MakeRGBColor(255, 255, 255);
  2238.     fColorCustomColor->SetColor( macColor );
  2239.  
  2240.     if ( fData->pBackgroundImage )
  2241.     {
  2242.         mImageFileName->SetLongDescriptor( fData->pBackgroundImage );
  2243.         // turn on after we set the descriptor so we don't handle as click when msg is broadcast
  2244.         TurnOn( mUseImage );
  2245.     }
  2246.     mLeaveImage->SetValue( fData->bBackgroundNoSave );
  2247.     
  2248.     pExtra = fData->pExtra;
  2249.     fData->pExtra = NULL;        // we'll take over this copy; don't let backend dispose of it
  2250.     EDT_FreeTableData(fData);
  2251.  
  2252. // check the caption....
  2253.     EDT_TableCaptionData* fCaptionData = EDT_GetTableCaptionData( fContext );
  2254.     if (fCaptionData)
  2255.     {
  2256.         fIncludeCaption->SetValue(TRUE);
  2257.         if (fCaptionData->align != ED_ALIGN_ABSBOTTOM)
  2258.             fCaptionAboveBelow->SetValue( 1 );
  2259.         else
  2260.             fCaptionAboveBelow->SetValue( 2 );
  2261.         EDT_FreeTableCaptionData(fCaptionData);
  2262.     }
  2263.     else
  2264.     {
  2265.         fIncludeCaption->SetValue(FALSE);
  2266.         fCaptionAboveBelow->SetValue( 1 );
  2267.     }
  2268.     
  2269.     AdjustEnable();
  2270. }
  2271.  
  2272.  
  2273. Boolean CEDTableContain::AllFieldsOK()
  2274. {
  2275.     if ( fBorderCheckBox->GetValue() )
  2276.     {
  2277.         if (!IsEditFieldWithinLimits(fBorderWidthEditText, 0, 10000)) {
  2278.             SwitchTarget( fBorderWidthEditText );
  2279.             fBorderWidthEditText->SelectAll();
  2280.             return FALSE;
  2281.         }
  2282.     }
  2283.     
  2284.     if (!IsEditFieldWithinLimits(fCellSpacingEditText, 0, 10000)) {
  2285.         SwitchTarget( fCellSpacingEditText );
  2286.         fCellSpacingEditText->SelectAll();
  2287.         return FALSE;
  2288.     }
  2289.  
  2290.     if (!IsEditFieldWithinLimits(fCellPaddingEditText, 0, 10000)) {
  2291.         SwitchTarget( fCellPaddingEditText );
  2292.         fCellPaddingEditText->SelectAll();
  2293.         return FALSE;
  2294.     }
  2295.  
  2296.     if (fCustomWidth->GetValue()) {
  2297.         if (fWidthPopup->GetValue() == kPixelsItem && !IsEditFieldWithinLimits(fWidthEditText, 1, 10000)) {
  2298.             SwitchTarget( fWidthEditText );
  2299.             fWidthEditText->SelectAll();
  2300.             return FALSE;
  2301.         }
  2302.  
  2303.         if (fWidthPopup->GetValue() == kPercentOfWindowItem && !IsEditFieldWithinLimits(fWidthEditText, 1, 100)) {
  2304.             SwitchTarget( fWidthEditText );
  2305.             fWidthEditText->SelectAll();
  2306.             return FALSE;
  2307.         }
  2308.     }
  2309.  
  2310.     if (fCustomHeight->GetValue()) {
  2311.         if (fHeightPopup->GetValue() == kPixelsItem && !IsEditFieldWithinLimits(fHeightEditText, 1, 10000)) {
  2312.             SwitchTarget( fHeightEditText );
  2313.             fHeightEditText->SelectAll();
  2314.             return FALSE;
  2315.         }
  2316.  
  2317.         if (fHeightPopup->GetValue() == kPercentOfWindowItem && !IsEditFieldWithinLimits(fHeightEditText, 1, 100)) {
  2318.             SwitchTarget( fHeightEditText );
  2319.             fHeightEditText->SelectAll();
  2320.             return FALSE;
  2321.         }
  2322.     }
  2323.  
  2324.     return TRUE;
  2325. }
  2326.  
  2327.  
  2328. void CEDTableContain::ListenToMessage( MessageT inMessage, void* /* ioParam */ )
  2329. {
  2330.     //Intercept messages we should act on....
  2331.     switch (inMessage)
  2332.     {
  2333.         case 'BrdW':
  2334.         case 'twth':
  2335.         case 'thgt':
  2336.         case 'tclr':
  2337.         case 'cptn':
  2338.             AdjustEnable();
  2339.             break;
  2340.         
  2341.         case msg_LinkColorChange:
  2342.             fCustomColor->SetValue(TRUE);
  2343.             break;
  2344.         
  2345.         case 'UseI':
  2346.             if (mUseImage->GetValue() == 1)
  2347.             {                // we are trying to set the image
  2348.                 CStr255 url;
  2349.                 mImageFileName->GetDescriptor(url);
  2350.                 if (url == CStr255::sEmptyString)
  2351.                 {        // but it doesn't exist
  2352.                     CEditDialog::ChooseImageFile( mImageFileName );    // so try to get it
  2353.                     mImageFileName->GetDescriptor( url );
  2354.                     if (url == CStr255::sEmptyString)     // but, if we were unsuccessful
  2355.                         mUseImage->SetValue( 0 );        // revert back.
  2356.                 }
  2357.             }
  2358.             AdjustEnable();
  2359.             break;
  2360.         
  2361.         case 'wst1':
  2362.             {
  2363.             CEditDialog::ChooseImageFile( mImageFileName );    // try to get it
  2364.             CStr255 url2;
  2365.             mImageFileName->GetDescriptor( url2 );
  2366.             if (url2 == CStr255::sEmptyString)     // if we were unsuccessful
  2367.                 mUseImage->SetValue( 0 );        // don't try to use image
  2368.             else
  2369.                 mUseImage->SetValue( 1 );
  2370.             }
  2371.             AdjustEnable();
  2372.             break;
  2373.                 
  2374.         case msg_EditField2:
  2375.             {
  2376.             CStr255 url3;
  2377.             mImageFileName->GetDescriptor( url3 );
  2378.             mUseImage->SetValue( url3[ 0 ] ? Button_On : Button_Off );
  2379.             }
  2380.             break;
  2381.                 
  2382.          case 'Xtra':
  2383.             char * newExtraHTML = NULL;
  2384.             Boolean canceled = !GetExtraHTML( pExtra, &newExtraHTML  ,GetWinCSID() );
  2385.             if (!canceled)
  2386.             {
  2387.                 if ( pExtra )
  2388.                     XP_FREE( pExtra );
  2389.                 pExtra = newExtraHTML;
  2390.             }
  2391.             break;
  2392.     }
  2393.     // Pass all messages on...
  2394. }
  2395.  
  2396.  
  2397. void CEDTableCellContain::FinishCreateSelf()
  2398. {
  2399.     fRowSpanEditText = (LGAEditField*)this->FindPaneByID( 'rows' );
  2400.     fColSpanEditText = (LGAEditField*)this->FindPaneByID( 'cols' );
  2401.  
  2402.     fHorizontalAlignment = (LGAPopup *)this->FindPaneByID( 'HzPU' );
  2403.     fVerticalAlignment = (LGAPopup *)this->FindPaneByID( 'VtPU' );
  2404.  
  2405.     fHeaderStyle = (LControl*)this->FindPaneByID( 'head' );
  2406.     fWrapText = (LControl*)this->FindPaneByID( 'wrap' );
  2407.  
  2408.     fCustomWidth = (LControl*)this->FindPaneByID( 'cwth' );
  2409.     fWidthEditText = (LGAEditField*)this->FindPaneByID( 'wdth' );
  2410.     fWidthPopup = (LControl*)this->FindPaneByID( 'WdPU' );    // popup menu
  2411.     
  2412.     fCustomHeight = (LControl*)this->FindPaneByID( 'chgt' );
  2413.     fHeightEditText = (LGAEditField*)this->FindPaneByID( 'hght' );
  2414.     fHeightPopup = (LControl*)this->FindPaneByID( 'HtPU' );    // popup menu
  2415.     
  2416.     fCustomColor = (LControl*)this->FindPaneByID( 'cclr' );
  2417.     fColorCustomColor = (CColorButton*)FindPaneByID( 'Colo' );
  2418.     
  2419.     mUseImage = (LControl*)FindPaneByID( 'UseI' );
  2420.     mImageFileName = (CLargeEditField *)FindPaneByID( 'TImg' );
  2421.     mImageFileName->AddListener(this);
  2422.     mLeaveImage = (LControl *)FindPaneByID( 'LvIm' );
  2423.     pExtra = NULL;
  2424.     
  2425.     UReanimator::LinkListenerToControls( this, this, mPaneID );
  2426. }
  2427.  
  2428.  
  2429. void CEDTableCellContain::Help()
  2430. {
  2431.     ShowHelp( HELP_TABLE_PROPS_CELL );
  2432. }
  2433.  
  2434.  
  2435. void CEDTableCellContain::AdjustEnable()
  2436. {
  2437.     if (fCustomWidth->GetValue())
  2438.     {
  2439.         fWidthEditText->Enable();
  2440.         fWidthPopup->Enable();
  2441.     }
  2442.     else
  2443.     {
  2444.         fWidthEditText->Disable();
  2445.         fWidthPopup->Disable();
  2446.     }
  2447.  
  2448.     if (fCustomHeight->GetValue())
  2449.     {
  2450.         fHeightEditText->Enable();
  2451.         fHeightPopup->Enable();
  2452.     }
  2453.     else
  2454.     {
  2455.         fHeightEditText->Disable();
  2456.         fHeightPopup->Disable();
  2457.     }
  2458.  
  2459.     if ( mUseImage->GetValue() )
  2460.         mLeaveImage->Enable();
  2461.     else
  2462.         mLeaveImage->Disable();
  2463. }
  2464.  
  2465.  
  2466. void CEDTableCellContain::PrefsFromControls()
  2467. {
  2468.     EDT_TableCellData* cellData = EDT_GetTableCellData( fContext );
  2469.     if (cellData == NULL)
  2470.         return;
  2471.     
  2472.     if ( fRowSpanEditText->IsEnabled() )
  2473.         cellData->iRowSpan = fRowSpanEditText->GetValue();
  2474.     if ( fColSpanEditText->IsEnabled() )
  2475.         cellData->iColSpan = fColSpanEditText->GetValue();
  2476.     
  2477.     switch ( fHorizontalAlignment->GetValue() )
  2478.     {
  2479.         default:
  2480.         case 1: cellData->align = ED_ALIGN_LEFT;        break;
  2481.         case 2: cellData->align = ED_ALIGN_ABSCENTER;    break;
  2482.         case 3: cellData->align = ED_ALIGN_RIGHT;        break;
  2483.         case 4:    break; // mixed state; don't reset
  2484.     }
  2485.     
  2486.     switch ( fVerticalAlignment->GetValue() )
  2487.     {
  2488.         default:
  2489.         case 1: cellData->valign = ED_ALIGN_ABSTOP;
  2490.         case 2: cellData->valign = ED_ALIGN_ABSCENTER;
  2491.         case 3: cellData->valign = ED_ALIGN_BASELINE;
  2492.         case 4: cellData->valign = ED_ALIGN_ABSBOTTOM;
  2493.         case 5:    break;    // mixed state; don't reset
  2494.     }
  2495.     
  2496.     cellData->bHeader = fHeaderStyle->GetValue();
  2497.     cellData->bNoWrap = fWrapText->GetValue();
  2498.         
  2499.     if ( fCustomWidth->GetValue() )
  2500.     {
  2501.         cellData->bWidthDefined = TRUE;
  2502.         cellData->bWidthPercent = fWidthPopup->GetValue() == kPercentOfWindowItem;
  2503.         cellData->iWidth = fWidthEditText->GetValue();
  2504.     }
  2505.     else
  2506.         cellData->bWidthDefined = FALSE;
  2507.     
  2508.     if (fCustomHeight->GetValue())
  2509.     {
  2510.         cellData->bHeightDefined = TRUE;
  2511.         cellData->bHeightPercent = fHeightPopup->GetValue() == kPercentOfWindowItem;
  2512.         cellData->iHeight = fHeightEditText->GetValue();
  2513.     }
  2514.     else
  2515.         cellData->bHeightDefined = FALSE;
  2516.     
  2517.     XP_FREEIF( cellData->pColorBackground );    // we'll replace it with our own if we use it at all.
  2518.     cellData->pColorBackground = NULL;
  2519.     
  2520.     LO_Color pColor;
  2521.     if ( fCustomColor->GetValue() )
  2522.     {
  2523.         pColor = UGraphics::MakeLOColor(fColorCustomColor->GetColor());
  2524.         cellData->pColorBackground = &pColor;
  2525.     }
  2526.     else
  2527.         cellData->pColorBackground = NULL;
  2528.     
  2529.     XP_FREEIF( cellData->pBackgroundImage );
  2530.     cellData->pBackgroundImage = NULL;
  2531.     
  2532.     if ( mUseImage->GetValue() )
  2533.         cellData->pBackgroundImage = mImageFileName->GetLongDescriptor();
  2534.     cellData->bBackgroundNoSave = mLeaveImage->GetValue();
  2535.  
  2536.     LView* extrahtmlbutton = (LView *)FindPaneByID( 'Xtra' );
  2537.     XP_ASSERT( extrahtmlbutton != NULL );
  2538.     if ( extrahtmlbutton->IsEnabled() )
  2539.     {
  2540.         XP_FREEIF( cellData->pExtra );
  2541.         cellData->pExtra = pExtra;
  2542.     }
  2543.     else
  2544.         cellData->pExtra = NULL;    /* this is probably not the right thing to do but... */
  2545.     
  2546.     EDT_SetTableCellData( fContext, cellData );
  2547.     
  2548.     cellData->pColorBackground = NULL;        // don't try to free our local variable.
  2549.     cellData->pExtra = NULL;                // this is our copy; don't let backend delete!
  2550.  
  2551.     EDT_FreeTableCellData( cellData );
  2552. }
  2553.  
  2554. #if FIRST_PASS_AT_MASK
  2555. typedef enum {
  2556.     ED_ALIGN_LEFT_MASK        = 0x0001,
  2557.     ED_ALIGN_CENTER_MASK      = 0x0002,
  2558.     ED_ALIGN_RIGHT_MASK       = 0x0004,
  2559.     ED_ALIGN_ABSTOP_MASK      = 0x0010,
  2560.     ED_ALIGN_ABSCENTER_MASK   = 0x0020,
  2561.     ED_ALIGN_BASELINE_MASK    = 0x0040,
  2562.     ED_ALIGN_ABSBOTTOM_MASK   = 0x0080
  2563. } ED_AlignmentMask;
  2564.  
  2565. /* ED_AlignmentMask: add the values which are set */
  2566. /* Boolean:  true means all agree; false means selection has different values */
  2567. struct _EDT_TableCellMask {
  2568.     ED_AlignmentMask bHalign;
  2569.     ED_AlignmentMask bValign;
  2570.     Boolean bColAndRowSpan;
  2571.     Boolean bHeader;
  2572.     Boolean bNoWrap;
  2573.     Boolean bWidth;
  2574.     Boolean bHeight;
  2575.     Boolean bColor;
  2576.     Boolean bBackgroundImage;
  2577.     Boolean bExtraHTML;
  2578. };
  2579. #endif
  2580.  
  2581. // Initialize from preferences
  2582. void CEDTableCellContain::ControlsFromPref()
  2583. {
  2584.     EDT_TableCellData* cellData = EDT_GetTableCellData( fContext );
  2585.     if (cellData == NULL)
  2586.         return;
  2587.  
  2588. #if FIRST_PASS_AT_MASK
  2589.     _EDT_TableCellMask cellDataMask;
  2590.     cellDataMask.bHalign = ED_ALIGN_LEFT_MASK;
  2591.     cellDataMask.bValign = ED_ALIGN_BASELINE_MASK;
  2592.     cellDataMask.bColAndRowSpan = true;
  2593.     cellDataMask.bHeader = cellDataMask.bNoWrap = true;
  2594.     cellDataMask.bWidth = cellDataMask.bHeight = true;
  2595.     cellDataMask.bColor = cellDataMask.bBackgroundImage = true;
  2596.     cellDataMask.bExtraHTML = true;
  2597. #endif
  2598.  
  2599. // set popup menus depending if nested in another table or just in window
  2600.     short             ResID;
  2601.     CStr255            title;
  2602.     StringHandle    titleH;
  2603.     if (EDT_IsInsertPointInNestedTable(fContext))
  2604.         ResID = EDITOR_PERCENT_PARENT_CELL;
  2605.     else
  2606.         ResID = EDITOR_PERCENT_WINDOW;
  2607.  
  2608.     titleH = GetString( ResID );
  2609.     if (titleH)
  2610.     {
  2611.         title = ** (CStr255**)titleH;
  2612.         MenuHandle menuh = ((LGAPopup *)fWidthPopup)->GetMacMenuH();
  2613.         if (menuh)
  2614.         {
  2615.             SetMenuItemText( menuh, kPercentOfWindowItem, title );
  2616.             ((LGAPopup *)fWidthPopup)->SetMacMenuH( menuh );    // resets menu width
  2617.         }
  2618.         
  2619.         menuh = ((LGAPopup *)fHeightPopup)->GetMacMenuH();
  2620.         if (menuh)
  2621.         {
  2622.             SetMenuItemText( menuh, kPercentOfWindowItem, title );
  2623.             ((LGAPopup *)fHeightPopup)->SetMacMenuH( menuh );    // resets menu width
  2624.         }
  2625.     }
  2626.  
  2627. /* col and row span */
  2628. #if FIRST_PASS_AT_MASK
  2629.     if ( cellDataMask.bColAndRowSpan )
  2630. #endif
  2631.     {
  2632.         fRowSpanEditText->SetValue( cellData->iRowSpan );
  2633.         fColSpanEditText->SetValue( cellData->iColSpan );
  2634.     }
  2635. #if FIRST_PASS_AT_MASK
  2636.     else
  2637.     {
  2638.         fRowSpanEditText->Disable();
  2639.         fColSpanEditText->Disable();
  2640.         // should disable the rest of this too...
  2641.     }
  2642. #endif
  2643.     
  2644. /* horizontal alignment */
  2645.     switch ( cellData->align )
  2646.     {
  2647.         case ED_ALIGN_LEFT:            fHorizontalAlignment->SetValue( 1 );    break;
  2648.         case ED_ALIGN_ABSCENTER:    fHorizontalAlignment->SetValue( 2 );    break;
  2649.         case ED_ALIGN_RIGHT:        fHorizontalAlignment->SetValue( 3 );    break;
  2650.         default:    /* mixed */        fHorizontalAlignment->SetValue( 4 );    break;
  2651.     }
  2652.  
  2653. /* vertical alignment */
  2654.     switch ( cellData->valign )
  2655.     {
  2656.         case ED_ALIGN_ABSTOP:        fVerticalAlignment->SetValue( 1 );    break;
  2657.         case ED_ALIGN_ABSCENTER:    fVerticalAlignment->SetValue( 2 );    break;
  2658.         case ED_ALIGN_BASELINE:        fVerticalAlignment->SetValue( 3 );    break;
  2659.         case ED_ALIGN_ABSBOTTOM:    fVerticalAlignment->SetValue( 4 );    break;
  2660.         default:    /* mixed */        fVerticalAlignment->SetValue( 5 );    break;
  2661.     }
  2662.  
  2663. /* text */
  2664. #if FIRST_PASS_AT_MASK
  2665.     fHeaderStyle->SetValue( cellDataMask.bHeader ? cellData->bHeader : 2 );
  2666.     fWrapText->SetValue( cellDataMask.bNoWrap ? cellData->bNoWrap : 2 );
  2667. #else
  2668.     fHeaderStyle->SetValue( cellData->bHeader );
  2669.     fWrapText->SetValue( cellData->bNoWrap );
  2670. #endif
  2671.  
  2672. #if FIRST_PASS_AT_MASK
  2673.     fCustomWidth->SetValue( cellDataMask.bWidth ? cellData->bWidthDefined : 2 );
  2674. #else
  2675.     fCustomWidth->SetValue( cellData->bWidthDefined );
  2676. #endif
  2677.     if ( cellData->bWidthDefined )
  2678.     {
  2679.         fWidthEditText->SetValue( cellData->iWidth );
  2680.         fWidthPopup->SetValue( (cellData->bWidthPercent) ? kPercentOfWindowItem : kPixelsItem );
  2681.     } 
  2682.     else
  2683.     {
  2684.         fWidthEditText->SetValue(20);        // where do we get the default value?
  2685.         fWidthPopup->SetValue( kPercentOfWindowItem );
  2686.     }
  2687.     
  2688. #if FIRST_PASS_AT_MASK
  2689.     fCustomHeight->SetValue( cellDataMask.bHeight ? cellData->bHeightDefined : 2 );
  2690. #else
  2691.     fCustomHeight->SetValue( cellData->bHeightDefined );
  2692. #endif
  2693.     if ( cellData->bHeightDefined )
  2694.     {
  2695.         fHeightEditText->SetValue(cellData->iHeight);
  2696.         fHeightPopup->SetValue( (cellData->bHeightPercent) ? kPercentOfWindowItem : kPixelsItem );
  2697.     }
  2698.     else
  2699.     {
  2700.         fHeightEditText->SetValue(20);        // where do we get the default value?
  2701.         fHeightPopup->SetValue( kPercentOfWindowItem );
  2702.     }
  2703.         
  2704.     fCustomColor->SetValue( cellData->pColorBackground != NULL );
  2705.     RGBColor rgb;
  2706.     if ( cellData->pColorBackground )
  2707.         rgb = UGraphics::MakeRGBColor( *cellData->pColorBackground );
  2708.     else
  2709.         rgb = UGraphics::MakeRGBColor( 0xFF, 0xFF, 0xFF );    // something pretty... (or, better yet, get the default color - yeah, right!)
  2710.     fColorCustomColor->SetColor( rgb );
  2711.     
  2712.     if ( cellData->pBackgroundImage )
  2713.     {
  2714.         mImageFileName->SetLongDescriptor( cellData->pBackgroundImage );
  2715.         // turn on after we set the descriptor so we don't handle as click when msg is broadcast
  2716.         TurnOn( mUseImage );
  2717.     }
  2718.     mLeaveImage->SetValue( cellData->bBackgroundNoSave );
  2719.  
  2720.     LView* extrahtmlbutton = (LView *)FindPaneByID( 'Xtra' );
  2721.     XP_ASSERT( extrahtmlbutton != NULL );
  2722. #if FIRST_PASS_AT_MASK
  2723.     if ( cellDataMask.bExtraHTML )
  2724. #endif
  2725.     {
  2726.         extrahtmlbutton->Enable();
  2727.         pExtra = cellData->pExtra;
  2728.         cellData->pExtra = NULL;    // don't let backend free!
  2729.     }
  2730. #if FIRST_PASS_AT_MASK
  2731.     else
  2732.     {
  2733.         /* don't agree; disable for now */
  2734.         extrahtmlbutton->Disable();
  2735.         pExtra = NULL;
  2736.     }
  2737. #endif
  2738.  
  2739.     EDT_FreeTableCellData(cellData);
  2740.     AdjustEnable();
  2741. }
  2742.  
  2743.  
  2744. Boolean CEDTableCellContain::AllFieldsOK()
  2745. {
  2746.     if ( fRowSpanEditText->IsEnabled() 
  2747.     && !IsEditFieldWithinLimits( fRowSpanEditText, 1, 100 ) )
  2748.     {
  2749.         SwitchTarget( fRowSpanEditText );
  2750.         fRowSpanEditText->SelectAll();
  2751.         return FALSE;
  2752.     }
  2753.  
  2754.     if ( fColSpanEditText->IsEnabled()
  2755.     && !IsEditFieldWithinLimits(fColSpanEditText, 1, 100 ) )
  2756.     {
  2757.         SwitchTarget( fColSpanEditText );
  2758.         fColSpanEditText->SelectAll();
  2759.         return FALSE;
  2760.     }
  2761.  
  2762.     if ( fCustomWidth->GetValue() == 1 )
  2763.     {
  2764.         int    popupValue = fWidthPopup->GetValue();
  2765.         if (popupValue == kPercentOfWindowItem && !IsEditFieldWithinLimits(fWidthEditText, 1, 100)) {
  2766.             SwitchTarget( fWidthEditText );
  2767.             fWidthEditText->SelectAll();
  2768.             return FALSE;
  2769.         }
  2770.  
  2771.         if (popupValue == kPixelsItem && !IsEditFieldWithinLimits(fWidthEditText, 1, 10000)) {
  2772.             SwitchTarget( fWidthEditText );
  2773.             fWidthEditText->SelectAll();
  2774.             return FALSE;
  2775.         }
  2776.     }
  2777.  
  2778.     if ( fCustomHeight->GetValue() == 1 )
  2779.     {
  2780.         int    popupValue = fHeightPopup->GetValue();
  2781.         if (popupValue == kPercentOfWindowItem && !IsEditFieldWithinLimits(fHeightEditText, 1, 100)) {
  2782.             SwitchTarget( fHeightEditText );
  2783.             fHeightEditText->SelectAll();
  2784.             return FALSE;
  2785.         }
  2786.  
  2787.         if (popupValue == kPixelsItem && !IsEditFieldWithinLimits(fHeightEditText, 1, 10000)) {
  2788.             SwitchTarget( fHeightEditText );
  2789.             fHeightEditText->SelectAll();
  2790.             return FALSE;
  2791.         }
  2792.     }
  2793.  
  2794.     return TRUE;
  2795. }
  2796.  
  2797.  
  2798. void CEDTableCellContain::ListenToMessage( MessageT inMessage, void* /* ioParam */ )
  2799. {
  2800.     switch ( inMessage )
  2801.     {
  2802.         case 'cwth':
  2803.         case 'chgt':
  2804.         case 'cclr':
  2805.             AdjustEnable();
  2806.             break;
  2807.         
  2808.         case msg_LinkColorChange:
  2809.             fCustomColor->SetValue( TRUE );
  2810.             break;
  2811.  
  2812.         case 'UseI':
  2813.             if (mUseImage->GetValue() == 1)
  2814.             {                // we are trying to set the image
  2815.                 CStr255 url;
  2816.                 mImageFileName->GetDescriptor(url);
  2817.                 if (url == CStr255::sEmptyString)
  2818.                 {        // but it doesn't exist
  2819.                     CEditDialog::ChooseImageFile( mImageFileName );    // so try to get it
  2820.                     mImageFileName->GetDescriptor( url );
  2821.                     if (url == CStr255::sEmptyString)     // but, if we were unsuccessful
  2822.                         mUseImage->SetValue( 0 );        // revert back.
  2823.                 }
  2824.             }
  2825.             AdjustEnable();
  2826.             break;
  2827.         
  2828.         case 'wst1':
  2829.             {
  2830.             CEditDialog::ChooseImageFile( mImageFileName );    // try to get it
  2831.             CStr255 url2;
  2832.             mImageFileName->GetDescriptor( url2 );
  2833.             if (url2 == CStr255::sEmptyString)     // if we were unsuccessful
  2834.                 mUseImage->SetValue( 0 );        // don't try to use image
  2835.             else
  2836.                 mUseImage->SetValue( 1 );
  2837.             }
  2838.             AdjustEnable();
  2839.             break;
  2840.                 
  2841.         case msg_EditField2:
  2842.             {
  2843.             CStr255 url3;
  2844.             mImageFileName->GetDescriptor( url3 );
  2845.             mUseImage->SetValue( url3[ 0 ] ? Button_On : Button_Off );
  2846.             }
  2847.             break;
  2848.                 
  2849.          case 'Xtra':
  2850.             char * newExtraHTML = NULL;
  2851.             Boolean canceled = !GetExtraHTML( pExtra, &newExtraHTML  ,GetWinCSID() );
  2852.             if (!canceled)
  2853.             {
  2854.                 if ( pExtra )
  2855.                     XP_FREE( pExtra );
  2856.                 pExtra = newExtraHTML;
  2857.             }
  2858.             break;
  2859.     }
  2860. }
  2861.  
  2862.  
  2863. /**********************************************************/
  2864. #pragma mark -
  2865. #pragma mark Standard Editor Dialogs
  2866.  
  2867. void CEDCharacterContain::FinishCreateSelf()
  2868. {
  2869.     fTextSizePopup = (LControl*)FindPaneByID( 'txsz' );
  2870.     mFontMenu = (LControl*)FindPaneByID( 'Font' );
  2871.     mFontChanged = false;
  2872.     
  2873.     fColorDefaultRadio = (LControl*)FindPaneByID( 'DocD' );
  2874.     fColorCustomRadio = (LControl*)FindPaneByID( 'CstC' );
  2875.     fColorCustomColor = (CColorButton*)FindPaneByID( 'ChCr' );
  2876.     
  2877.     fTextBoldCheck = (LControl*)FindPaneByID( 'Bold' );
  2878.     fTextItalicCheck = (LControl*)FindPaneByID( 'Ital' );
  2879.     fTextSuperscriptCheck = (LControl*)FindPaneByID( 'Supe' );
  2880.     fTextSubscriptCheck = (LControl*)FindPaneByID( 'Subs' );
  2881.     fTextNoBreaksCheck = (LControl*)FindPaneByID( 'NoBR' );
  2882.     fTextUnderlineCheck = (LControl*)FindPaneByID( 'Unln' );
  2883.     fTextStrikethroughCheck = (LControl*)FindPaneByID( 'Stri' );
  2884.     fTextBlinkingCheck = (LControl*)FindPaneByID( 'Blin' );
  2885.         
  2886.     fClearTextStylesButton = (LControl*)FindPaneByID( 'CTSB' );
  2887.     fClearAllStylesButton = (LControl*)FindPaneByID( 'CASB' );
  2888.  
  2889.     LView::FinishCreateSelf();
  2890.     UReanimator::LinkListenerToControls( this, this, mPaneID );
  2891.     
  2892.     fTextSizePopup->Show();
  2893. }
  2894.  
  2895. void CEDCharacterContain::PrefsFromControls()
  2896. {
  2897.     LO_Color pColor;        // we pass EDT_SetCharacterData() a pointer to this, so it has to be around for awhile.
  2898.     
  2899.     if (EDT_GetCurrentElementType(fContext) != ED_ELEMENT_TEXT
  2900.             && EDT_GetCurrentElementType(fContext) != ED_ELEMENT_SELECTION)
  2901.         return;
  2902.     
  2903.     EDT_CharacterData* better = EDT_NewCharacterData();
  2904.     if (better == NULL)
  2905.         return;
  2906.     
  2907.     better->mask = TF_NONE;
  2908.     better->values = TF_NONE;
  2909.     
  2910.     if (fColorChanged) {
  2911.         better->mask |= TF_FONT_COLOR;
  2912.         if (fColorDefaultRadio->GetValue()) {
  2913.             better->pColor = NULL;
  2914.         } else {
  2915.             better->values |= TF_FONT_COLOR;
  2916.             pColor = UGraphics::MakeLOColor(fColorCustomColor->GetColor());
  2917.             better->pColor = &pColor;                // I hope that EDT_SetCharacterData() doesn't hang onto this pointer for long...
  2918.         }
  2919.     }
  2920.     
  2921.     if (fSizeChanged) {
  2922.         better->mask |= TF_FONT_SIZE;
  2923.         better->values |= TF_FONT_SIZE;        // I'm not supposed to set this if we are using the default font size. But how do I know? An extra menu item??
  2924.         better->iSize = fTextSizePopup->GetValue();
  2925.     }
  2926.     
  2927.     if ( mFontChanged )
  2928.     {
  2929.         better->mask |= TF_FONT_FACE;
  2930.         if ( better->pFontFace )
  2931.         {
  2932.             XP_FREE( better->pFontFace );
  2933.             better->pFontFace = NULL;
  2934.         }
  2935.         
  2936.         int menuitem = mFontMenu->GetValue();
  2937.         if ( menuitem == 1 || menuitem == 2 )    // default menu items
  2938.         {
  2939.             better->values &= ~TF_FONT_FACE;    // I'm supposed to clear TF_FONT_FACE if we are using the default font.
  2940.             if ( menuitem == 2 )                //  if fixed width, do it differently
  2941.                 better->values |= TF_FIXED;
  2942.             else
  2943.                 better->values &= ~TF_FIXED;    // not fixed if we have a font!
  2944.         }
  2945.         else
  2946.         {
  2947.             better->values |= TF_FONT_FACE;
  2948.             better->values &= ~TF_FIXED;        // not fixed if we have a font!
  2949.             
  2950.             Str255 s;
  2951.             s[ 0 ] = 0;
  2952.             ((LGAPopup *)mFontMenu)->GetCurrentItemTitle( s );
  2953.             p2cstr( s );
  2954.             better->pFontFace = XP_STRDUP( (char *)s );
  2955.         }
  2956.     }
  2957.     
  2958.     if (fTextBoldCheck->GetValue() == 1)            better->values |= TF_BOLD;        // what values to set to
  2959.     if (fTextItalicCheck->GetValue()  == 1)            better->values |= TF_ITALIC;
  2960.     if (fTextSuperscriptCheck->GetValue()  == 1)    better->values |= TF_SUPER;
  2961.     if (fTextSubscriptCheck->GetValue()  == 1)        better->values |= TF_SUB;
  2962.     if (fTextNoBreaksCheck->GetValue()  == 1)        better->values |= TF_NOBREAK;
  2963.     if (fTextUnderlineCheck->GetValue() == 1)        better->values |= TF_UNDERLINE;
  2964.     if (fTextStrikethroughCheck->GetValue()  == 1)    better->values |= TF_STRIKEOUT;
  2965.     if (fTextBlinkingCheck->GetValue()  == 1)        better->values |= TF_BLINK;
  2966.     
  2967.     if (fTextBoldCheck->GetValue() != 2)            better->mask |= TF_BOLD;        // if the checkbox is still mixed, don't set anything
  2968.     if (fTextItalicCheck->GetValue() != 2)            better->mask |= TF_ITALIC;
  2969.     if (fTextSuperscriptCheck->GetValue() != 2)        better->mask |= TF_SUPER;
  2970.     if (fTextSubscriptCheck->GetValue() != 2)        better->mask |= TF_SUB;
  2971.     if (fTextNoBreaksCheck->GetValue() != 2)        better->mask |= TF_NOBREAK;
  2972.     if (fTextUnderlineCheck->GetValue() != 2)        better->mask |= TF_UNDERLINE;
  2973.     if (fTextStrikethroughCheck->GetValue() != 2)    better->mask |= TF_STRIKEOUT;
  2974.     if (fTextBlinkingCheck->GetValue() != 2)        better->mask |= TF_BLINK;
  2975.  
  2976.     EDT_SetFontFace( fContext, better, -1, better->pFontFace );
  2977. //    EDT_SetCharacterData(fContext, better);
  2978.     better->pColor = NULL;                    // this is ours. Don't free it.
  2979.     EDT_FreeCharacterData(better);    
  2980. }
  2981.  
  2982.  
  2983. static void SetFontMenuItemByString( LGAPopup *menu, char *font )
  2984. {
  2985.     if ( font == NULL )
  2986.     {
  2987.         menu->SetValue( 1 );
  2988.         return;
  2989.     }
  2990.     
  2991.     Str255 str;
  2992.     int i, maxitem;
  2993.     maxitem = menu->GetMaxValue();
  2994.     MenuHandle    popupMenu = menu->GetMacMenuH ();
  2995.     for ( i = 1; i <= maxitem; i++ )
  2996.     {
  2997.         ::GetMenuItemText ( popupMenu, i, str );
  2998.         p2cstr(str);
  2999.         if ( XP_STRSTR( font, (char *)str ) != NULL )
  3000.         {
  3001.             menu->SetValue( i );
  3002.             ::SetItemMark( popupMenu, i, '-' );
  3003.             break;
  3004.         }
  3005.     }
  3006. }
  3007.  
  3008.  
  3009. // Initialize from preferences
  3010. void CEDCharacterContain::ControlsFromPref()
  3011. {
  3012.     if (EDT_GetCurrentElementType(fContext) != ED_ELEMENT_TEXT
  3013.         && EDT_GetCurrentElementType(fContext) != ED_ELEMENT_SELECTION) return;
  3014.     
  3015.     EDT_CharacterData* better = EDT_GetCharacterData( fContext );
  3016.     if (better == NULL) return;
  3017.     
  3018.     fTextBoldCheck->SetValue(better->values & TF_BOLD ? 1 : 0);
  3019.     fTextItalicCheck->SetValue(better->values & TF_ITALIC ? 1 : 0);
  3020.     fTextSuperscriptCheck->SetValue(better->values & TF_SUPER ? 1 : 0);
  3021.     fTextSubscriptCheck->SetValue(better->values & TF_SUB ? 1 : 0);
  3022.     fTextNoBreaksCheck->SetValue(better->values & TF_NOBREAK ? 1 : 0);
  3023.     fTextUnderlineCheck->SetValue(better->values & TF_UNDERLINE ? 1 : 0);
  3024.     fTextStrikethroughCheck->SetValue(better->values & TF_STRIKEOUT ? 1 : 0);
  3025.     fTextBlinkingCheck->SetValue(better->values & TF_BLINK ? 1 : 0);
  3026.     
  3027.     if (!(better->mask & TF_BOLD))        fTextBoldCheck->SetValue(2);
  3028.     if (!(better->mask & TF_ITALIC))    fTextItalicCheck->SetValue(2);
  3029.     if (!(better->mask & TF_SUPER))        fTextSuperscriptCheck->SetValue(2);
  3030.     if (!(better->mask & TF_SUB))        fTextSubscriptCheck->SetValue(2);
  3031.     if (!(better->mask & TF_NOBREAK))    fTextNoBreaksCheck->SetValue(2);
  3032.     if (!(better->mask & TF_UNDERLINE))    fTextUnderlineCheck->SetValue(2);
  3033.     if (!(better->mask & TF_STRIKEOUT))    fTextStrikethroughCheck->SetValue(2);
  3034.     if (!(better->mask & TF_BLINK))        fTextBlinkingCheck->SetValue(2);
  3035.     
  3036.     if (better->mask & TF_FONT_SIZE)
  3037.         fTextSizePopup->SetValue(better->iSize);
  3038.     else
  3039.         fTextSizePopup->SetValue(EDT_GetFontSize( fContext ));
  3040.     fSizeChanged = FALSE;
  3041.     
  3042.     if ( better->values & TF_FONT_FACE )
  3043.         SetFontMenuItemByString( (LGAPopup *)mFontMenu, better->pFontFace );
  3044.     else if ( better->values & TF_FIXED )
  3045.         mFontMenu->SetValue( 2 );
  3046.     else
  3047.         mFontMenu->SetValue( 1 );
  3048.     
  3049.     mFontChanged = false;
  3050.     
  3051.     LO_Color pColor = {0, 0, 0};
  3052.     
  3053.     if (better->mask & TF_FONT_COLOR) {        // consistant
  3054.         if (better->pColor) {
  3055.             pColor = *better->pColor;
  3056.             TurnOn( fColorCustomRadio );
  3057.         } else {
  3058.             TurnOn( fColorDefaultRadio );
  3059.             EDT_PageData *pagedata = EDT_GetPageData( fContext );
  3060.             if (pagedata && pagedata->pColorText)
  3061.                 pColor = *pagedata->pColorText;
  3062.             EDT_FreePageData(  pagedata );
  3063.         }
  3064.     } else {                                // inconsistant
  3065.         if (EDT_GetFontColor(fContext, &pColor))
  3066.             TurnOn( fColorCustomRadio );
  3067.         else {
  3068.             TurnOn( fColorDefaultRadio );
  3069.                 // get default color
  3070.             EDT_PageData *pagedata = EDT_GetPageData( fContext );
  3071.             pColor = *pagedata->pColorText;
  3072.             EDT_FreePageData(  pagedata );
  3073.         }
  3074.     }
  3075.     
  3076.     fColorCustomColor->SetColor(UGraphics::MakeRGBColor(pColor));
  3077.     fColorChanged = FALSE;
  3078.     
  3079.     EDT_FreeCharacterData(better);
  3080. }
  3081.  
  3082.  
  3083. void CEDCharacterContain::Help()
  3084. {
  3085.     ShowHelp( HELP_PROPS_CHARACTER );
  3086. }
  3087.  
  3088.  
  3089. void CEDCharacterContain::ListenToMessage( MessageT inMessage, void* /* ioParam */ )
  3090. {
  3091.     //Intercept messages we should act on....
  3092.     switch (inMessage)
  3093.     {
  3094.         case msg_Font_Face_Changed:
  3095.             mFontChanged = true;
  3096.             break;
  3097.         
  3098.         case 'Supe':
  3099.             if (fTextSuperscriptCheck->GetValue())
  3100.                 fTextSubscriptCheck->SetValue(0);
  3101.             break;
  3102.                 
  3103.         case 'Subs':
  3104.             if (fTextSubscriptCheck->GetValue())
  3105.                 fTextSuperscriptCheck->SetValue(0);
  3106.             break;
  3107.         
  3108.         case msg_Clear_Text_Styles:
  3109.             fTextBoldCheck->SetValue(0);
  3110.             fTextItalicCheck->SetValue(0);
  3111.             fTextSuperscriptCheck->SetValue(0);
  3112.             fTextSubscriptCheck->SetValue(0);
  3113.             fTextNoBreaksCheck->SetValue(0);
  3114.             fTextUnderlineCheck->SetValue(0);
  3115.             fTextStrikethroughCheck->SetValue(0);
  3116.             fTextBlinkingCheck->SetValue(0);
  3117.             break;
  3118.  
  3119.         case msg_Clear_All_Styles:
  3120.             fTextBoldCheck->SetValue(0);
  3121.             fTextItalicCheck->SetValue(0);
  3122.             fTextSuperscriptCheck->SetValue(0);
  3123.             fTextSubscriptCheck->SetValue(0);
  3124.             fTextNoBreaksCheck->SetValue(0);
  3125.             fTextUnderlineCheck->SetValue(0);
  3126.             fTextStrikethroughCheck->SetValue(0);
  3127.             fTextBlinkingCheck->SetValue(0);
  3128.             
  3129.             if ( fTextSizePopup->GetValue() != 3 )
  3130.             {
  3131.                 fSizeChanged = true;
  3132.                 fTextSizePopup->SetValue(3);
  3133.             }
  3134.             
  3135.             TurnOn( fColorDefaultRadio );
  3136.             fColorChanged = TRUE;
  3137.             
  3138.             if ( mFontMenu->GetValue() != 1 )
  3139.                 mFontChanged = true;
  3140.             mFontMenu->SetValue( 1 );
  3141.             break;
  3142.         
  3143.         case msg_LinkColorChange:
  3144.             fColorChanged = TRUE;
  3145.             TurnOn( fColorCustomRadio );
  3146.             break;
  3147.         
  3148.         case msg_Default_Color_Radio:
  3149.             fColorChanged = TRUE;
  3150.             break;
  3151.         
  3152.         case msg_Custom_Color_Radio:
  3153.             fColorChanged = TRUE;
  3154.             break;
  3155.         
  3156.         case msg_Font_Size_Changed:
  3157.             fSizeChanged = TRUE;
  3158.             break;
  3159.     }
  3160.     
  3161.     // Pass all messages on...
  3162. }
  3163.  
  3164. /**********************************************************/
  3165. // There is no other good place for these. These correspond to menu item numbers which are
  3166. // in a resource (not a rez file)
  3167.  
  3168. #define ED_NO_CONTAINER    1
  3169. #define ED_LIST_ITEM    2
  3170. #define ED_BLOCKQUOTE    3
  3171.  
  3172. void CEDParagraphContain::FinishCreateSelf()
  3173. {
  3174.     fParagraphStylePopup = (LControl*)FindPaneByID( 'pspu' );
  3175.     fContainerStylePopup = (LControl*)FindPaneByID( 'cspu' );
  3176.     
  3177.     fListStylePopup = (LControl*)FindPaneByID( 'lspu' );
  3178.     fNumberPopup = (LControl*)FindPaneByID( 'nobp' );
  3179.     fBulletPopup = (LControl*)FindPaneByID( 'bulp' );
  3180.     fStartNumberCaption = (LControl*)FindPaneByID( 'junk' );
  3181.     fStartNumberEditText = (LGAEditField*)FindPaneByID( 'snet' );
  3182.  
  3183.     fLeftAlignRadio = (LControl*)FindPaneByID( 'Left' );
  3184.     fCenterAlignRadio = (LControl*)FindPaneByID( 'Cent' );
  3185.     fRightAlignRadio = (LControl*)FindPaneByID( 'Righ' );
  3186.     
  3187.     LView::FinishCreateSelf();
  3188.     UReanimator::LinkListenerToControls( this, this, mPaneID );
  3189.     
  3190.     fParagraphStylePopup->Show();
  3191.     fContainerStylePopup->Show();
  3192.     fListStylePopup->Show();
  3193.     fLeftAlignRadio->Show();
  3194.     fCenterAlignRadio->Show();
  3195.     fRightAlignRadio->Show();
  3196. }
  3197.  
  3198.  
  3199. void CEDParagraphContain::PrefsFromControls()
  3200. {
  3201. // This only differs from the Windows FE code in two ways:
  3202. // 1) EDT_MorphContainer is called BEFORE the EDT_Outdent "while" loop instead of AFTER
  3203. // 2) if fContainerStylePopup->GetValue() == ED_NO_CONTAINER we NEVER call EDT_SetListData(); the windows code DOES if list != NULL.
  3204.  
  3205.     if (fLeftAlignRadio->GetValue())
  3206.         EDT_SetParagraphAlign(fContext, ED_ALIGN_LEFT);
  3207.     else if (fRightAlignRadio->GetValue())
  3208.         EDT_SetParagraphAlign(fContext, ED_ALIGN_RIGHT);
  3209.     else
  3210.         EDT_SetParagraphAlign(fContext, ED_ALIGN_CENTER);
  3211.         
  3212.     switch (fParagraphStylePopup->GetValue()) {
  3213.         case 1:  EDT_MorphContainer( fContext, P_PARAGRAPH); break;
  3214.         case 2:  EDT_MorphContainer( fContext, P_HEADER_1); break;
  3215.         case 3:  EDT_MorphContainer( fContext, P_HEADER_2); break;
  3216.         case 4:  EDT_MorphContainer( fContext, P_HEADER_3); break;
  3217.         case 5:  EDT_MorphContainer( fContext, P_HEADER_4); break;
  3218.         case 6:  EDT_MorphContainer( fContext, P_HEADER_5); break;
  3219.         case 7:  EDT_MorphContainer( fContext, P_HEADER_6); break;
  3220.         case 8:  EDT_MorphContainer( fContext, P_ADDRESS); break;
  3221.         case 9:  EDT_MorphContainer( fContext, P_PREFORMAT); break;
  3222.         case 10: EDT_MorphContainer( fContext, P_LIST_ITEM); break;
  3223.         case 11: EDT_MorphContainer( fContext, P_DESC_TITLE); break;
  3224.         case 12: EDT_MorphContainer( fContext, P_DESC_TEXT); break;
  3225.     }
  3226.     
  3227.     if (fContainerStylePopup->GetValue() == ED_NO_CONTAINER)
  3228.     {
  3229.         EDT_ListData * pListData = EDT_GetListData(fContext);                // remove 
  3230.         while (pListData) {
  3231.             EDT_FreeListData(pListData);
  3232.             EDT_Outdent(fContext);
  3233.             pListData = EDT_GetListData(fContext);
  3234.         }
  3235.     }
  3236.     else
  3237.     {
  3238.         EDT_ListData *list = EDT_GetListData( fContext );
  3239.         if (list == NULL)
  3240.         {                        // do we need to create a container?
  3241.             EDT_Indent( fContext );
  3242.             list = EDT_GetListData( fContext );
  3243.             if (list == NULL)
  3244.                 return;             // assert?
  3245.         }
  3246.         
  3247.         list->eType = ED_LIST_TYPE_DEFAULT;        // defaults
  3248.         list->iStart = 1;
  3249.         
  3250.         if (fContainerStylePopup->GetValue() == ED_BLOCKQUOTE)
  3251.         
  3252.             list->iTagType = P_BLOCKQUOTE;
  3253.             
  3254.         else
  3255.         {
  3256.             switch (fListStylePopup->GetValue()) {
  3257.                 case 1: list->iTagType = P_UNUM_LIST; break;
  3258.                 case 2: list->iTagType = P_NUM_LIST; break;
  3259.                 case 3: list->iTagType = P_DIRECTORY; break;
  3260.                 case 4: list->iTagType = P_MENU; break;
  3261.                 case 5: list->iTagType = P_DESC_LIST; break;
  3262.             }
  3263.             
  3264.             if (list->iTagType == P_UNUM_LIST) {
  3265.                 
  3266.                 switch (fBulletPopup->GetValue()) {
  3267.                     case 1: list->eType = ED_LIST_TYPE_DEFAULT; break;
  3268.                     case 2: list->eType = ED_LIST_TYPE_DISC; break;
  3269.                     case 3: list->eType = ED_LIST_TYPE_CIRCLE; break;
  3270.                     case 4: list->eType = ED_LIST_TYPE_SQUARE; break;
  3271.                 }
  3272.                 
  3273.             } else if (list->iTagType == P_NUM_LIST) {
  3274.                 
  3275.                 switch (fNumberPopup->GetValue()) {
  3276.                     case 1: list->eType = ED_LIST_TYPE_DEFAULT; break;
  3277.                     case 2: list->eType = ED_LIST_TYPE_DIGIT; break;
  3278.                     case 3: list->eType = ED_LIST_TYPE_BIG_ROMAN; break;
  3279.                     case 4: list->eType = ED_LIST_TYPE_SMALL_ROMAN; break;
  3280.                     case 5: list->eType = ED_LIST_TYPE_BIG_LETTERS; break;
  3281.                     case 6: list->eType = ED_LIST_TYPE_SMALL_LETTERS; break;
  3282.                 }
  3283.                 
  3284.                 list->iStart = fStartNumberEditText->GetValue();
  3285.             }
  3286.         }
  3287.                         
  3288.         EDT_SetListData(fContext, list);
  3289.         EDT_FreeListData(list);
  3290.     }
  3291. }
  3292.  
  3293.  
  3294. // Initialize from preferences
  3295. void CEDParagraphContain::ControlsFromPref()
  3296. {
  3297.     switch (EDT_GetParagraphAlign(fContext)) {
  3298.         case ED_ALIGN_LEFT:        TurnOn(fLeftAlignRadio); break;
  3299.         case ED_ALIGN_RIGHT:    TurnOn(fRightAlignRadio); break;
  3300.         default:                 TurnOn(fCenterAlignRadio); break;
  3301.     }
  3302.  
  3303.     fParagraphStylePopup->SetValue(1);
  3304.     switch (EDT_GetParagraphFormatting(fContext)) {
  3305.         case P_HEADER_1:    fParagraphStylePopup->SetValue(2); break;
  3306.         case P_HEADER_2:    fParagraphStylePopup->SetValue(3); break;
  3307.         case P_HEADER_3:    fParagraphStylePopup->SetValue(4); break;
  3308.         case P_HEADER_4:    fParagraphStylePopup->SetValue(5); break;
  3309.         case P_HEADER_5:    fParagraphStylePopup->SetValue(6); break;
  3310.         case P_HEADER_6:    fParagraphStylePopup->SetValue(7); break;
  3311.         case P_ADDRESS:        fParagraphStylePopup->SetValue(8); break;
  3312.         case P_PREFORMAT:    fParagraphStylePopup->SetValue(9); break;
  3313.         case P_LIST_ITEM:    fParagraphStylePopup->SetValue(10); break;
  3314.         case P_DESC_TITLE:    fParagraphStylePopup->SetValue(11); break;
  3315.         case P_DESC_TEXT:    fParagraphStylePopup->SetValue(12); break;
  3316.     }
  3317.     
  3318.     EDT_ListData *list = EDT_GetListData( fContext );
  3319.     
  3320.     fContainerStylePopup->SetValue(ED_NO_CONTAINER);
  3321.     if (list) {
  3322.         if  (list->iTagType == P_BLOCKQUOTE)
  3323.             fContainerStylePopup->SetValue(ED_BLOCKQUOTE);
  3324.         else
  3325.             fContainerStylePopup->SetValue(ED_LIST_ITEM);        // list item
  3326.     }
  3327.     
  3328.     fListStylePopup->SetValue(1);        // set up default values
  3329.     fBulletPopup->SetValue(1);
  3330.     fNumberPopup->SetValue(1);
  3331.     fStartNumberEditText->SetValue(1);
  3332.     
  3333.     if (fContainerStylePopup->GetValue() == ED_LIST_ITEM) {        // list item
  3334.     
  3335.         switch (list->iTagType) {
  3336.             case P_UNUM_LIST:    fListStylePopup->SetValue(1); break;
  3337.             case P_NUM_LIST:    fListStylePopup->SetValue(2); break;
  3338.             case P_DIRECTORY:    fListStylePopup->SetValue(3); break;
  3339.             case P_MENU:        fListStylePopup->SetValue(4); break;
  3340.             case P_DESC_LIST:    fListStylePopup->SetValue(5); break;
  3341.             default:             fListStylePopup->SetValue(1); break;    // assert?
  3342.         }
  3343.             
  3344.         if (list->iTagType == P_UNUM_LIST) {
  3345.             
  3346.             switch (list->eType) {
  3347.                 case ED_LIST_TYPE_DEFAULT:    fBulletPopup->SetValue(1); break;
  3348.                 case ED_LIST_TYPE_DISC:        fBulletPopup->SetValue(2); break;
  3349.                 case ED_LIST_TYPE_CIRCLE:    fBulletPopup->SetValue(3); break;
  3350.                 case ED_LIST_TYPE_SQUARE:    fBulletPopup->SetValue(4); break;
  3351.                 default:                    fBulletPopup->SetValue(1); break;    // assert?
  3352.             }
  3353.         }
  3354.  
  3355.         if (list->iTagType == P_NUM_LIST) {
  3356.             
  3357.             switch (list->eType) {
  3358.                 case ED_LIST_TYPE_DEFAULT:            fNumberPopup->SetValue(1); break;
  3359.                 case ED_LIST_TYPE_DIGIT:            fNumberPopup->SetValue(2); break;
  3360.                 case ED_LIST_TYPE_BIG_ROMAN:        fNumberPopup->SetValue(3); break;
  3361.                 case ED_LIST_TYPE_SMALL_ROMAN:        fNumberPopup->SetValue(4); break;
  3362.                 case ED_LIST_TYPE_BIG_LETTERS:        fNumberPopup->SetValue(5); break;
  3363.                 case ED_LIST_TYPE_SMALL_LETTERS:    fNumberPopup->SetValue(6); break;
  3364.                 default:                            fNumberPopup->SetValue(1); break;    // assert?
  3365.             }
  3366.             
  3367.             fStartNumberEditText->SetValue(list->iStart);
  3368.         }
  3369.     }
  3370.     
  3371.     if (list) EDT_FreeListData(list);
  3372.     
  3373.     AdjustPopupsVisibility();
  3374. }
  3375.  
  3376.  
  3377. void CEDParagraphContain::AdjustPopupsVisibility()
  3378. {
  3379.     if (fContainerStylePopup->GetValue() != ED_LIST_ITEM) {        // list item
  3380.     
  3381.         fListStylePopup->Disable();
  3382.         fStartNumberCaption->Hide();
  3383.         fStartNumberEditText->Hide();
  3384.         
  3385.         switch (fListStylePopup->GetValue()) {
  3386.             case 1:        // Unumbered List
  3387.                 fNumberPopup->Hide();
  3388.                 fBulletPopup->Disable();
  3389.                 fBulletPopup->Show();
  3390.             break;
  3391.             
  3392.             case 2:        // Numbered List
  3393.                 fNumberPopup->Disable();
  3394.                 fNumberPopup->Show();
  3395.                 fBulletPopup->Hide();
  3396.             break;
  3397.             
  3398.             default:
  3399.                 fNumberPopup->Hide();
  3400.                 fBulletPopup->Hide();
  3401.             break;
  3402.         }
  3403.         
  3404.     } else {
  3405.     
  3406.         fListStylePopup->Enable();
  3407.         
  3408.         switch (fListStylePopup->GetValue()) {
  3409.             case 1:        // Unnumbered List
  3410.                 fNumberPopup->Hide();
  3411.                 fBulletPopup->Enable();
  3412.                 fBulletPopup->Show();
  3413.                 fStartNumberCaption->Hide();
  3414.                 fStartNumberEditText->Hide();
  3415.             break;
  3416.             
  3417.             case 2:        // Numbered List
  3418.                 fNumberPopup->Enable();
  3419.                 fNumberPopup->Show();
  3420.                 fBulletPopup->Hide();
  3421.                 fStartNumberCaption->Show();
  3422.                 fStartNumberEditText->Show();
  3423.             break;
  3424.             
  3425.             default:
  3426.                 fNumberPopup->Hide();
  3427.                 fBulletPopup->Hide();
  3428.                 fStartNumberCaption->Hide();
  3429.                 fStartNumberEditText->Hide();
  3430.             break;
  3431.             
  3432.         }
  3433.     }
  3434. }
  3435.  
  3436.  
  3437. void CEDParagraphContain::Help()
  3438. {
  3439.     ShowHelp( HELP_PROPS_PARAGRAPH );
  3440. }
  3441.  
  3442.  
  3443. Boolean CEDParagraphContain::AllFieldsOK()
  3444. {
  3445.     if ( fStartNumberEditText->IsVisible() && fStartNumberEditText->IsEnabled()
  3446.     && !IsEditFieldWithinLimits( fStartNumberEditText, 1, 2000000000 ) )
  3447.     {
  3448.         SwitchTarget( fStartNumberEditText );
  3449.         fStartNumberEditText->SelectAll();
  3450.         return FALSE;
  3451.     }
  3452.     
  3453.     return true;
  3454. }
  3455.  
  3456.  
  3457. void CEDParagraphContain::ListenToMessage( MessageT inMessage, void* /* ioParam */ )
  3458. {
  3459.     //Intercept messages we should act on....
  3460.     
  3461.     switch (inMessage) {
  3462.         case msg_Paragraph_Style_Popup:
  3463.             if (fParagraphStylePopup->GetValue() == 10)        // "List item" menu item
  3464.                 fContainerStylePopup->SetValue(ED_LIST_ITEM);            // "List" menu item (doesn't seem to be necessary)
  3465.             else if (fContainerStylePopup->GetValue() == ED_LIST_ITEM)
  3466.                 fContainerStylePopup->SetValue(ED_NO_CONTAINER);            // (IS necessary)
  3467.             AdjustPopupsVisibility();
  3468.         break;
  3469.         
  3470.         case msg_Paragraph_Addtnl_Style_Popup:
  3471.             if (fContainerStylePopup->GetValue() == ED_LIST_ITEM)        // "List" menu item
  3472.                 fParagraphStylePopup->SetValue(10);            // "List item" menu item
  3473. //            else if (fParagraphStylePopup->GetValue() == 10)
  3474. //                fParagraphStylePopup->SetValue(1);            // windows FE doesn't do this. Do we know what we're doing?
  3475.             AdjustPopupsVisibility();
  3476.         break;
  3477.         
  3478.         case msg_List_Style_Popup:
  3479.             AdjustPopupsVisibility();
  3480.         break;
  3481.     }
  3482.     
  3483.     // Pass all messages on...
  3484. }
  3485.  
  3486.  
  3487. /**********************************************************/
  3488. void CEDLinkContain::FinishCreateSelf()
  3489. {
  3490.     fLinkedTextEdit = (CLargeEditField *)FindPaneByID( 'LTte' );
  3491.     
  3492.     fChooseFileLinkButton = (LControl*)FindPaneByID( 'CFLb' );
  3493.     fRemoveLinkButton = (LControl*)FindPaneByID( 'RLbt' );
  3494.     fLinkPageTextEdit = (CLargeEditField *)FindPaneByID( 'LPte' );
  3495.     
  3496.     fCurrentDocumentRadio = (LControl*)FindPaneByID( 'CDro' );
  3497.     fSelectedFileRadio = (LControl*)FindPaneByID( 'SFro' );
  3498.     fTargetList = (OneRowLListBox*)FindPaneByID( 'TAli' );
  3499.     
  3500.     LView::FinishCreateSelf();
  3501.     UReanimator::LinkListenerToControls( this, this, mPaneID );
  3502.     
  3503.     fTargs = NULL;
  3504. }
  3505.  
  3506.  
  3507. void CEDLinkContain::PrefsFromControls()
  3508. {
  3509.     if (fInsert && LO_GetSelectionText(fContext) == NULL)
  3510.     {
  3511.         char *link = fLinkPageTextEdit->GetLongDescriptor();
  3512.     
  3513.         if (link && XP_STRLEN(link))
  3514.         {
  3515.             char *anchor = fLinkedTextEdit->GetLongDescriptor();
  3516.             if ( anchor && XP_STRLEN(anchor) )
  3517.             {
  3518.                 if ( EDT_PasteHREF( fContext, &link, &anchor, 1 ) != EDT_COP_OK )
  3519.                     ErrorManager::PlainAlert( CUT_ACROSS_CELLS );
  3520.             }
  3521.             else if ( EDT_PasteHREF( fContext, &link, &link, 1 ) != EDT_COP_OK )
  3522.             {
  3523.                 // use the link as the anchor if there is no anchor
  3524.                 ErrorManager::PlainAlert( CUT_ACROSS_CELLS );
  3525.             }
  3526.             
  3527.             XP_FREEIF( anchor);
  3528.         }
  3529.         
  3530.         XP_FREEIF( link );
  3531.     }
  3532.     else // if ( EDT_CanSetHREF( fContext ) )    // should always be true
  3533.     {
  3534.         EDT_HREFData *linkdata = EDT_GetHREFData( fContext );
  3535.         if ( linkdata )
  3536.         {
  3537.             if ( linkdata->pURL )
  3538.             {
  3539.                 XP_FREE( linkdata->pURL );
  3540.                 linkdata->pURL = NULL;
  3541.             }
  3542.             linkdata->pURL = fLinkPageTextEdit->GetLongDescriptor();
  3543.  
  3544.             if ( linkdata->pExtra )
  3545.             {
  3546.                 XP_FREE( linkdata->pExtra );
  3547.                 linkdata->pExtra = NULL;
  3548.             }
  3549.             
  3550.             if ( pExtra )
  3551.                 linkdata->pExtra = XP_STRDUP( pExtra );
  3552.             
  3553.             EDT_SetHREFData( fContext, linkdata );
  3554.             EDT_FreeHREFData( linkdata );
  3555.         }
  3556.     }
  3557. }
  3558.  
  3559.  
  3560. void CEDLinkContain::Show()
  3561. {
  3562.     if ( *fLinkName )
  3563.         fLinkedTextEdit->SetDescriptor( CStr255(*fLinkName) );
  3564.     
  3565.     CEditContain::Show();
  3566. }
  3567.  
  3568.  
  3569. void CEDLinkContain::Hide()
  3570. {
  3571.     if ( *fLinkName )
  3572.         XP_FREE( *fLinkName );
  3573.     *fLinkName = fLinkedTextEdit->GetLongDescriptor();
  3574.     CEditContain::Hide();
  3575. }
  3576.  
  3577. #define msg_ClickOnTarget 23000
  3578. #define msg_DblClickOnTarget 23001
  3579. #define msg_ClickOnTarget2 23002                /* really should put these in resgui.h or similar */
  3580. #define msg_DblClickOnTarget2 23003
  3581.  
  3582. // Initialize from preferences
  3583. void CEDLinkContain::ControlsFromPref()
  3584. {
  3585.     SetTextTraitsIDByCsid(fLinkedTextEdit, GetWinCSID());
  3586.     if ( *fLinkName )
  3587.     {            // image pane has already been here
  3588.         fLinkedTextEdit->SetDescriptor( CStr255(*fLinkName) );
  3589.         fLinkedTextEdit->Disable();
  3590.         SwitchTarget( fLinkPageTextEdit );
  3591.         fLinkPageTextEdit->SelectAll();
  3592.     }
  3593.     else
  3594.     {
  3595.         char *selection = (char*)LO_GetSelectionText( fContext );
  3596.         if ( selection ) 
  3597.             fLinkedTextEdit->SetDescriptor( CStr255(selection) );
  3598.         
  3599.         if ( fInsert && selection == NULL )
  3600.         {
  3601.             fLinkedTextEdit->Enable();
  3602.             SwitchTarget( fLinkedTextEdit );
  3603.             fLinkedTextEdit->SelectAll();
  3604.         }
  3605.         else
  3606.         {
  3607.             fLinkedTextEdit->Disable();
  3608.             SwitchTarget( fLinkPageTextEdit );
  3609.             fLinkPageTextEdit->SelectAll();
  3610.         }
  3611.     }
  3612.  
  3613.     EDT_HREFData *linkdata = EDT_GetHREFData( fContext );
  3614.     if ( linkdata )
  3615.     {
  3616.         if ( linkdata->pURL )
  3617.             fLinkPageTextEdit->SetDescriptor( CStr255(linkdata->pURL) );
  3618.         pExtra = linkdata->pExtra;    // let's not realloc
  3619.         linkdata->pExtra = NULL;    // don't dispose of this!
  3620.         
  3621.         EDT_FreeHREFData( linkdata );
  3622.     }
  3623.     
  3624.     TurnOn( fCurrentDocumentRadio );
  3625.     CurrentFileTargs();
  3626.     
  3627.     fTargetList->FocusDraw();
  3628.     fTargetList->SetDoubleClickMessage( msg_DblClickOnTarget );
  3629.     fTargetList->SetSingleClickMessage( msg_ClickOnTarget );
  3630.     fTargetList->AddListener( this );    
  3631.     fTargetList->SetValue(-1);
  3632. }
  3633.  
  3634.  
  3635. CEDLinkContain::~CEDLinkContain()
  3636. {
  3637.     if ( fTargs )
  3638.         XP_FREE( fTargs );
  3639.     if ( pExtra )
  3640.         XP_FREE( pExtra );
  3641.     pExtra = NULL;
  3642. }
  3643.  
  3644.  
  3645. void CEDLinkContain::Help()
  3646. {
  3647.     ShowHelp( HELP_PROPS_LINK );
  3648. }
  3649.  
  3650.  
  3651. void CEDLinkContain::SelectedFileUpdate()
  3652. {
  3653.     // clear list
  3654.     while ( fTargetList->GetRows() )
  3655.         fTargetList->RemoveRow(0);
  3656.     
  3657.     if ( fTargs )
  3658.         XP_FREE(fTargs);
  3659.     fTargs = NULL;
  3660.     
  3661.     // get file to retrieve targets from
  3662.     char *link = fLinkPageTextEdit->GetLongDescriptor();
  3663.     if ( link == NULL )
  3664.         return;
  3665.     
  3666.     // I assume a pound would only confuse things; remove it if present
  3667.     char *pound = XP_STRCHR(link, '#');
  3668.     if ( pound )
  3669.         *pound = '\0';
  3670.     
  3671.     // need to pass an xpURL format "link" below ***FIX***THIS***
  3672.     fTargs = EDT_GetAllDocumentTargetsInFile( fContext, link );
  3673.     XP_FREE( link );
  3674.     char *parse = fTargs;
  3675.     
  3676.     int16 rowNum = fTargetList->GetRows();            // add to the bottom?
  3677.     
  3678.     while ( parse && *parse )
  3679.     {
  3680.         fTargetList->AddRow( rowNum++, parse, XP_STRLEN(parse) );
  3681.         parse += XP_STRLEN(parse) + 1;
  3682.     }
  3683. }
  3684.  
  3685.  
  3686. void CEDLinkContain::CurrentFileTargs()
  3687. {
  3688.     while (fTargetList->GetRows())
  3689.         fTargetList->RemoveRow(0);
  3690.     
  3691.     if ( fTargs )
  3692.         XP_FREE( fTargs );
  3693.  
  3694.     fTargs = EDT_GetAllDocumentTargets(fContext);
  3695.     char *parse = fTargs;
  3696.     
  3697.     int16 rowNum = fTargetList->GetRows();            // add to the bottom?
  3698.     
  3699.     while (parse && *parse)
  3700.     {
  3701.         fTargetList->AddRow( rowNum++, parse, XP_STRLEN(parse));
  3702.         parse += XP_STRLEN(parse) + 1;
  3703.     }
  3704. }
  3705.  
  3706.  
  3707. void CEDLinkContain::ListenToMessage( MessageT inMessage, void* /* ioParam */ )
  3708. {
  3709.     //Intercept messages we should act on....
  3710.     
  3711.     switch (inMessage)
  3712.     {
  3713.         case 'CDro':        // targets from current document radio button
  3714.             if ( fCurrentDocumentRadio->GetValue() )
  3715.                 CurrentFileTargs();
  3716.             break;
  3717.         
  3718.         case 'SFro':        // targets from selected file radio button
  3719.             if ( fSelectedFileRadio->GetValue() )
  3720.                 SelectedFileUpdate();
  3721.             break;
  3722.         
  3723.         case msg_Link_Clear_Link:
  3724.             fLinkPageTextEdit->SetDescriptor("\p");
  3725.             break;
  3726.         
  3727.         case msg_Link_Browse_File:
  3728.         {    
  3729.             StPrepareForDialog    preparer;    
  3730.             StandardFileReply    reply;
  3731.             Point                loc = { -1, -1 };
  3732.             OSType                types[ 4 ];
  3733.             
  3734.             types[ 0 ] = 'GIFf';
  3735.             types[ 1 ] = 'TEXT';
  3736.             types[ 2 ] = 'JPEG';
  3737.         
  3738.             ::StandardGetFile( NULL, 3, types, &reply );
  3739.  
  3740.             if ( reply.sfGood )
  3741.             {
  3742.                 char *fileLink = CFileMgr::GetURLFromFileSpec( reply.sfFile );
  3743.                 if ( fileLink )
  3744.                 {
  3745.                     if (CPrefs::GetBoolean( CPrefs::PublishMaintainLinks ))
  3746.                     {
  3747.                         char *abs = NULL;        // let's try making it relative
  3748.                         if (NET_MakeRelativeURL( LO_GetBaseURL( fContext ), fileLink, &abs) != NET_URL_FAIL && abs)
  3749.                         {
  3750.                             XP_FREE( fileLink );
  3751.                             fileLink = abs;
  3752.                             abs = NULL;
  3753.                         }
  3754.                         
  3755.                         XP_FREEIF( abs );
  3756.                     }
  3757.                     
  3758.                     fLinkPageTextEdit->SetLongDescriptor( fileLink );
  3759.                     XP_FREE( fileLink );
  3760.                     
  3761.                     if ( fSelectedFileRadio->GetValue() )
  3762.                         SelectedFileUpdate();
  3763.                 }
  3764.             }
  3765.         }
  3766.         break;
  3767.         
  3768.         case msg_DblClickOnTarget:
  3769.         case msg_ClickOnTarget:
  3770.             int16    index =  fTargetList->GetValue();
  3771.             
  3772.             // first take care of the case where the user tries to "deselect" the item in the list..
  3773.             if (index == -1)
  3774.             {
  3775.                 char *file = fLinkPageTextEdit->GetLongDescriptor();    // we are going to save the url if it exists
  3776.                 if ( file )
  3777.                 {
  3778.                     char *pound = XP_STRCHR( file, '#' );
  3779.                     if ( pound )
  3780.                     {
  3781.                         *pound = '\0';
  3782.                         fLinkPageTextEdit->SetLongDescriptor( file );
  3783.                     }
  3784.                     
  3785.                     XP_FREE( file );
  3786.                 }
  3787.                 break;
  3788.             }
  3789.             
  3790.             char *parse = fTargs;
  3791.             while ( parse && *parse && index-- )
  3792.                 parse += XP_STRLEN(parse) + 1;
  3793.  
  3794.             if ( parse && *parse )
  3795.             {    // why is it that I have no other way to do this?
  3796.                 CStr255    temp = "";
  3797.                 
  3798.                 if (fSelectedFileRadio->GetValue())
  3799.                 {
  3800.                     char *file2 = fLinkPageTextEdit->GetLongDescriptor();    // we are going to save the url if it exists
  3801.                     if ( file2 )
  3802.                     {
  3803.                         char *pound = XP_STRCHR(file2, '#');
  3804.                         if ( pound )
  3805.                             *pound = '\0';
  3806.                         
  3807.                         temp = file2;
  3808.                         XP_FREE( file2 );
  3809.                     }
  3810.                 }
  3811.  
  3812.                 temp += '#';
  3813.                 temp += parse;
  3814.                 fLinkPageTextEdit->SetDescriptor(temp);
  3815.  
  3816.             }
  3817.             
  3818.             if ( inMessage == msg_DblClickOnTarget )
  3819.                 ListenToMessage( msg_OK, NULL );
  3820.         break;
  3821.         
  3822.         case 'Xtra':
  3823.             char * newExtraHTML = NULL;
  3824.             Boolean canceled = !GetExtraHTML( pExtra, &newExtraHTML, GetWinCSID() );
  3825.             if (!canceled)
  3826.             {
  3827.                 XP_FREEIF( pExtra );
  3828.                 pExtra = newExtraHTML;
  3829.             }
  3830.             break;
  3831.     }    
  3832.     
  3833.     // Pass all messages on...
  3834. }
  3835.  
  3836.  
  3837. #ifdef COOL_IMAGE_RADIO_BUTTONS
  3838. #pragma mark -
  3839.  
  3840. // ---------------------------------------------------------------------------
  3841. //        Ă‘ SetValue
  3842. // ---------------------------------------------------------------------------
  3843. //    Turn a ToggleButton on or off
  3844.  
  3845. void
  3846. CImageAlignButton::SetValue( Int32 inValue )
  3847. {
  3848.     if (inValue != mValue)
  3849.     {
  3850.         LControl::SetValue(inValue);
  3851.         Refresh();
  3852.     }
  3853.  
  3854.     // If turning RadioButton on, broadcast message so that the RadioGroup
  3855.     // (if present) will turn off the other RadioButtons in the group.
  3856.     if (inValue == Button_On)
  3857.         BroadcastMessage( msg_ControlClicked, (void*) this );
  3858. }
  3859.  
  3860.  
  3861. // â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤
  3862. //    Ă‘    HotSpotAction
  3863. // â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤
  3864.  
  3865. void CImageAlignButton::HotSpotAction(short /* inHotSpot */, Boolean inCurrInside, Boolean inPrevInside)
  3866. {
  3867.     if ( GetValue() == 0 )
  3868.     {
  3869.         if ( inCurrInside != inPrevInside )
  3870.         {
  3871.             SetTrackInside( inCurrInside );
  3872.             Draw( NULL );
  3873.             SetTrackInside( false );
  3874.         }
  3875.     }
  3876. }
  3877.  
  3878. // â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤
  3879. //    Ă‘    HotSpotResult
  3880. // â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤â•¤
  3881.  
  3882. void CImageAlignButton::HotSpotResult(Int16 inHotSpot)
  3883. {
  3884.     SetValue(1);
  3885.     
  3886.     // Although value doesn't change, send message to inform Listeners
  3887.     // that button was clicked
  3888. //    BroadcastValueMessage();        
  3889. }
  3890. #endif
  3891.  
  3892.  
  3893. /**********************************************************/
  3894. CEDImageContain::CEDImageContain( LStream* inStream ) : CEditContain( inStream )
  3895. {
  3896.     fSrcStr = NULL;
  3897.     fLowSrcStr = NULL;
  3898.     fLooseImageMap = FALSE;
  3899.     mBorderUnspecified = false;
  3900. }
  3901.  
  3902. CEDImageContain::~CEDImageContain()
  3903. {
  3904.     XP_FREEIF( fSrcStr );
  3905.     XP_FREEIF( fLowSrcStr );
  3906.     XP_FREEIF( pExtra );
  3907.     pExtra = NULL;
  3908. }
  3909.  
  3910. void CEDImageContain::FinishCreateSelf()
  3911. {
  3912.     fImageFileName = (CLargeEditField *)FindPaneByID( 'WST1' );
  3913.     fImageFileName->AddListener(this);
  3914.  
  3915.     fImageAltFileName = (CLargeEditField *)FindPaneByID( 'WST3' );
  3916.     fImageAltFileName->AddListener(this);
  3917.     fImageAltTextEdit = (CLargeEditField *)FindPaneByID( 'WST5' );
  3918.     fImageAltTextEdit->AddListener(this);
  3919.     
  3920.     fHeightTextEdit = (LGAEditField*)FindPaneByID( 'WSTd' );
  3921.     fHeightTextEdit->AddListener( this );
  3922.     fWidthTextEdit = (LGAEditField*)FindPaneByID( 'WSTf' );
  3923.     fWidthTextEdit->AddListener( this );
  3924.     fImageLockedCheckBox = (LControl *)FindPaneByID( 'Lock' );    // constrain
  3925.     
  3926.     fLeftRightBorderTextEdit = (LGAEditField*)FindPaneByID( 'WSTh' );
  3927.     fTopBottomBorderTextEdit = (LGAEditField*)FindPaneByID( 'WSTi' );
  3928.     fSolidBorderTextEdit = (LGAEditField*)FindPaneByID( 'WSTj' );
  3929.     fSolidBorderTextEdit->AddListener( this );
  3930.  
  3931.     fCopyImageCheck = (LControl*)FindPaneByID( 'WSTl' );
  3932.     fBackgroundImageCheck = (LControl*)FindPaneByID( 'Bkgd' );
  3933.     fRemoveImageMapButton = (LControl*)FindPaneByID( 'WSTm' );
  3934.     fEditImageButton = (LControl*)FindPaneByID( 'WSTn' );
  3935.     
  3936.     mImageAlignmentPopup = (LControl*)FindPaneByID( 'ImgA' );
  3937.  
  3938.     LView::FinishCreateSelf();
  3939.     UReanimator::LinkListenerToControls( this, this, mPaneID );
  3940. }
  3941.  
  3942.  
  3943. void CEDImageContain::AdjustEnable()
  3944. {
  3945.     Boolean allEmpty = false;    // assume at least one has text unless proven otherwise
  3946.     Str255 str;
  3947.     fImageFileName->GetDescriptor( str );
  3948.     if ( str[0] == 0 )
  3949.     {
  3950.         fCopyImageCheck->Disable();
  3951.         fEditImageButton->Disable();
  3952.         fBackgroundImageCheck->Disable();
  3953.  
  3954.         fImageAltFileName->GetDescriptor( str );
  3955.         if ( str[0] == 0 )
  3956.         {
  3957.             fImageAltTextEdit->GetDescriptor( str );
  3958.             if ( str[0] == 0 )
  3959.                 allEmpty = true;
  3960.         }
  3961.     }
  3962.     else
  3963.     {
  3964.         fCopyImageCheck->Enable();
  3965.         fEditImageButton->Enable();
  3966.         fBackgroundImageCheck->Enable();
  3967.     }
  3968.     
  3969.     LView* dimensions = (LView *)FindPaneByID( 'C003' );
  3970.     LView* spacearound = (LView *)FindPaneByID( 'C004' );
  3971.     LView* aligncaption = (LView *)FindPaneByID( 'Cptn' );    // alignment caption
  3972.     LView* extrahtmlbutton = (LView *)FindPaneByID( 'Xtra' );
  3973.     if ( allEmpty || fBackgroundImageCheck->GetValue() )
  3974.     {
  3975.         dimensions->Disable();
  3976.         spacearound->Disable();
  3977.         extrahtmlbutton->Disable();
  3978.  
  3979.         mImageAlignmentPopup->Disable();
  3980.         if ( aligncaption )
  3981.             aligncaption->Disable();
  3982.         
  3983.         LView* altreps = (LView *)FindPaneByID( 'C002' );
  3984.         if ( fBackgroundImageCheck->GetValue() )
  3985.             altreps->Disable();
  3986.         else
  3987.             altreps->Enable();
  3988.     }
  3989.     else
  3990.     {
  3991.         LView* altreps = (LView *)FindPaneByID( 'C002' );
  3992.         altreps->Enable();
  3993.         
  3994.         dimensions->Enable();
  3995.         spacearound->Enable();
  3996.         extrahtmlbutton->Enable();
  3997.  
  3998.         mImageAlignmentPopup->Enable();
  3999.         if ( aligncaption )
  4000.             aligncaption->Enable();
  4001.  
  4002.         // can't constrain if it's original size or if either/both are "% of window"
  4003.         Boolean doEnable = false;
  4004.         LControl *control = (LControl *)FindPaneByID( 'Orig' );
  4005.         if ( control && ( control->GetValue() == 0 ) )
  4006.         {
  4007.             LGAPopup *widthPopup = (LGAPopup *)FindPaneByID( 'WdPU' );
  4008.             LGAPopup *heightPopup = (LGAPopup *)FindPaneByID( 'HtPU' );
  4009.             doEnable = ( widthPopup->GetValue() != kPercentOfWindowItem ) 
  4010.                         && ( heightPopup->GetValue() != kPercentOfWindowItem );
  4011.         }
  4012.         
  4013.         if ( doEnable )
  4014.             fImageLockedCheckBox->Enable();
  4015.         else
  4016.             fImageLockedCheckBox->Disable();
  4017.     }
  4018. }
  4019.  
  4020.  
  4021. EDT_ImageData *CEDImageContain::ImageDataFromControls()
  4022. {
  4023.     EDT_ImageData *image;
  4024.     
  4025.     if (fInsert)
  4026.         image = EDT_NewImageData();
  4027.     else
  4028.     {
  4029.         if ( EDT_GetCurrentElementType(fContext) != ED_ELEMENT_IMAGE )
  4030.             return NULL;
  4031.         image = EDT_GetImageData( fContext );
  4032.     }
  4033.         
  4034.     if (image == NULL)
  4035.         return NULL;
  4036.     
  4037.                     // what about ED_ALIGN_BOTTOM & ED_ALIGN_ABSTOP
  4038.     image->align = ED_ALIGN_DEFAULT;    
  4039.     switch (mImageAlignmentPopup->GetValue())
  4040.     {
  4041.         case 1:    image->align = ED_ALIGN_TOP;        break;
  4042.         case 2:    image->align = ED_ALIGN_ABSCENTER;    break;
  4043.         case 3:    image->align = ED_ALIGN_CENTER;        break;
  4044.         case 4:    image->align = ED_ALIGN_BASELINE;    break;
  4045.         case 5:    image->align = ED_ALIGN_ABSBOTTOM;    break;
  4046.         case 6:    image->align = ED_ALIGN_LEFT;        break;
  4047.         case 7:    image->align = ED_ALIGN_RIGHT;        break;
  4048.     }
  4049.     
  4050.     image->bNoSave = fCopyImageCheck->GetValue();
  4051.         
  4052.     XP_FREEIF( image->pSrc );
  4053.     image->pSrc = fImageFileName->GetLongDescriptor();
  4054.     
  4055.     XP_FREEIF( image->pLowSrc );
  4056.     image->pLowSrc = fImageAltFileName->GetLongDescriptor();
  4057.  
  4058.     XP_FREEIF( image->pAlt );
  4059.     image->pAlt = fImageAltTextEdit->GetLongDescriptor();
  4060.  
  4061.     XP_FREEIF( image->pExtra );
  4062.     image->pExtra = ( pExtra ) ? XP_STRDUP( pExtra ) : NULL;
  4063.  
  4064.     // we need a valid URL for this image (for instance, something that starts with 'file://'
  4065.     
  4066. /*    char *absURL;
  4067.     
  4068.     if (image->pSrc && (absURL = NET_MakeAbsoluteURL( LO_GetBaseURL( fContext ), image->pSrc ))) {
  4069.         XP_FREE(image->pSrc);
  4070.         image->pSrc = absURL;
  4071.     }
  4072.  
  4073.     if (image->pLowSrc && (absURL = NET_MakeAbsoluteURL( LO_GetBaseURL( fContext ), image->pLowSrc ))) {
  4074.         XP_FREE(image->pLowSrc);
  4075.         image->pLowSrc = absURL;
  4076.     }
  4077.  
  4078.     FSSpec    file;
  4079.     char *path;
  4080.     
  4081.     file = fImageFileName->GetFSSpec();
  4082.     if (file.vRefNum != 0 || file.parID != 0 || file.name[0] != 0) {
  4083.         char *path = CFileMgr::GetURLFromFileSpec(file);
  4084.         if (path) {
  4085.             if (fSrcStr == NULL || strcmp(path, fSrcStr)) {
  4086.                 if (image->pSrc) XP_FREE(image->pSrc);
  4087.                 image->pSrc = path;
  4088.             } else XP_FREE(path);
  4089.         }
  4090.     }
  4091.     
  4092.     file = fImageAltFileName->GetFSSpec();
  4093.     if (file.vRefNum != 0 || file.parID != 0 || file.name[0] != 0) {
  4094.         char *path = CFileMgr::GetURLFromFileSpec(file);
  4095.         if (path) {
  4096.             if (fLowSrcStr == NULL || strcmp(path, fLowSrcStr)) {
  4097.                 if (image->pLowSrc) XP_FREE(image->pLowSrc);
  4098.                 image->pLowSrc = path;
  4099.             } else XP_FREE(path);
  4100.         }
  4101.     }
  4102. */
  4103.     LControl *useCustomSize = (LControl*)FindPaneByID( 'Cust' );
  4104.     if ( useCustomSize->GetValue() )
  4105.     {
  4106.         LGAPopup *popup = (LGAPopup *)FindPaneByID( 'HtPU' );
  4107.         image->bHeightPercent = (popup ? popup->GetValue() == kPercentOfWindowItem : false);
  4108.         image->iHeight = fHeightTextEdit->GetValue();
  4109.         
  4110.         popup = (LGAPopup *)FindPaneByID( 'WdPU' );
  4111.         image->bWidthPercent = (popup ? popup->GetValue() == kPercentOfWindowItem : false);
  4112.         image->iWidth = fWidthTextEdit->GetValue();
  4113.     }
  4114.     else
  4115.     {
  4116.         image->iWidth = 0;
  4117.         image->iHeight = 0;
  4118.         image->bWidthPercent = false;
  4119.         image->bHeightPercent = false;
  4120.     }
  4121.     
  4122.     image->iHSpace = fLeftRightBorderTextEdit->GetValue();
  4123.     image->iVSpace = fTopBottomBorderTextEdit->GetValue();
  4124.     if ( mBorderUnspecified )
  4125.         image->iBorder = -1;
  4126.     else
  4127.         image->iBorder = fSolidBorderTextEdit->GetValue();
  4128.  
  4129.     // Mac "remove image map" button now removes ISMAP instead of USEMAP
  4130.     // Stupid behavior, but that's what Win and UNIX do.
  4131.     if ( fLooseImageMap && image->bIsMap )
  4132.     {
  4133.         image->bIsMap = false;
  4134.     }
  4135.     
  4136.     return image;
  4137. }
  4138.  
  4139. void CEDImageContain::PrefsFromControls()
  4140. {
  4141.     // if background image--do it and return
  4142.     if ( fBackgroundImageCheck->GetValue() )
  4143.     {
  4144.         EDT_PageData *pageData = EDT_GetPageData( fContext );
  4145.         if (pageData == NULL)
  4146.             return;
  4147.         
  4148.         if (pageData->pBackgroundImage)
  4149.         {
  4150.             XP_FREE( pageData->pBackgroundImage );
  4151.             pageData->pBackgroundImage = NULL;
  4152.         }
  4153.         
  4154.         char *url = fImageFileName->GetLongDescriptor();
  4155.         if ( url && XP_STRLEN( url ) )
  4156.             pageData->pBackgroundImage = url;
  4157.         else if ( url )
  4158.             XP_FREE( url );
  4159.         
  4160.         EDT_SetPageData(fContext, pageData);
  4161.         EDT_FreePageData(pageData);
  4162.         
  4163.         return;
  4164.     }
  4165.  
  4166.     EDT_ImageData *image = ImageDataFromControls();
  4167.     if (image)
  4168.     {
  4169.         if (fInsert)
  4170.             EDT_InsertImage( fContext, image, fCopyImageCheck->GetValue() );
  4171.         else
  4172.             EDT_SetImageData( fContext, image, fCopyImageCheck->GetValue() );
  4173.         
  4174.         EDT_FreeImageData(image);
  4175.     }
  4176. }
  4177.  
  4178.  
  4179. // Initialize from preferences
  4180. void CEDImageContain::ControlsFromPref()
  4181. {
  4182.     SetTextTraitsIDByCsid(fImageAltTextEdit, GetWinCSID());
  4183.     fCopyImageCheck->Enable();
  4184.     fCopyImageCheck->SetValue( false );
  4185.     
  4186.     fOriginalWidth = 0;
  4187.     fOriginalHeight = 0;
  4188.     
  4189.     fEditImageButton->Disable();
  4190.  
  4191.     Boolean amInsertingNewImage = ( EDT_GetCurrentElementType(fContext) != ED_ELEMENT_IMAGE );
  4192.  
  4193.     EDT_ImageData *image = ( amInsertingNewImage ) ? NULL : EDT_GetImageData( fContext );
  4194.     
  4195.     // set alignment
  4196.     int value = 4;        // default == ED_ALIGN_BASELINE
  4197.     if ( image )
  4198.     {
  4199.         switch (image->align)
  4200.         {            // what about ED_ALIGN_BOTTOM & ED_ALIGN_ABSTOP
  4201.             case ED_ALIGN_TOP:            value = 1;    break;
  4202.             case ED_ALIGN_ABSCENTER:    value = 2;    break;
  4203.             case ED_ALIGN_CENTER:        value = 3;    break;
  4204.             case ED_ALIGN_BASELINE:        value = 4;    break;
  4205.             case ED_ALIGN_ABSBOTTOM:     value = 5;    break;
  4206.             case ED_ALIGN_LEFT:            value = 6;    break;
  4207.             case ED_ALIGN_RIGHT:        value = 7;    break;
  4208.             default:    break;
  4209.         }
  4210.     }
  4211.     mImageAlignmentPopup->SetValue( value );
  4212.     
  4213.     if ( image )
  4214.     {
  4215.         fCopyImageCheck->SetValue( image->bNoSave );
  4216.         
  4217.         if (image->pSrc)
  4218.             fImageFileName->SetLongDescriptor( image->pSrc );
  4219.         
  4220.         if ( image->pLowSrc )
  4221.             fImageAltFileName->SetLongDescriptor( image->pLowSrc );
  4222.         
  4223.         if ( image->pAlt )
  4224.             fImageAltTextEdit->SetLongDescriptor( image->pAlt );
  4225.  
  4226.         LControl *customSize = (LControl *)FindPaneByID( 'Cust' );
  4227.         
  4228.         if ( image->iOriginalWidth == 0 )
  4229.         {
  4230.             // we know for sure we have custom if either h or w is %
  4231.             customSize->SetValue( image->bHeightPercent || image->bWidthPercent );
  4232.             fOriginalWidth = image->iWidth;
  4233.             fOriginalHeight = image->iHeight;
  4234.         }
  4235.         else
  4236.         {
  4237.             if ( image->iWidth == 0 && image->iHeight == 0 )
  4238.             {
  4239.                 image->iHeight = image->iOriginalHeight;
  4240.                 image->iWidth = image->iOriginalWidth;
  4241.             }
  4242.             
  4243.             customSize->SetValue( image->iOriginalWidth != image->iWidth 
  4244.                                 || image->iOriginalHeight != image->iHeight);
  4245.             fOriginalWidth = image->iOriginalWidth;        /* Width and Height we got on initial loading */
  4246.             fOriginalHeight = image->iOriginalHeight;
  4247.         }
  4248.  
  4249.         fHeightTextEdit->SetValue(image->iHeight);
  4250.         fWidthTextEdit->SetValue(image->iWidth);
  4251.  
  4252.         fLeftRightBorderTextEdit->SetValue(image->iHSpace);
  4253.         fTopBottomBorderTextEdit->SetValue(image->iVSpace);
  4254.  
  4255.         // This is weird. If the cross platform code gives us a -1, then we are "default"
  4256.         // "default" is zero if there is no link or two if there is.
  4257.         // why doesn't the XP set this up for us? I don't know...
  4258.         if (image->iBorder == -1)
  4259.         {
  4260.             mBorderUnspecified = true;
  4261.             image->iBorder = EDT_GetDefaultBorderWidth( fContext );
  4262.         }
  4263.         else
  4264.             mBorderUnspecified = false;
  4265.         fSolidBorderTextEdit->SetValue( image->iBorder );
  4266.         
  4267.         pExtra = image->pExtra;    // let's not realloc
  4268.         image->pExtra = NULL;    // don't dispose of this!
  4269.     }
  4270.     
  4271.     // assume "Original Size" radio button is default
  4272.     LGAPopup *popup = (LGAPopup *)FindPaneByID( 'HtPU' );
  4273.     if ( popup )
  4274.         popup->SetValue( image && image->bHeightPercent ? kPercentOfWindowItem : kPixelsItem );
  4275.     popup = (LGAPopup *)FindPaneByID( 'WdPU' );
  4276.     if ( popup )
  4277.         popup->SetValue( image && image->bWidthPercent ? kPercentOfWindowItem : kPixelsItem );
  4278.  
  4279.     // edit image logic
  4280.     if (image == NULL || (image->pSrc == NULL || XP_STRLEN(image->pSrc) < 1)) 
  4281.         fEditImageButton->Disable();
  4282.     else
  4283.         fEditImageButton->Enable();
  4284.  
  4285.     // image map button
  4286.     if ( image == NULL )
  4287.         fRemoveImageMapButton->Hide();
  4288.     else
  4289.     {
  4290.         // we already have image in document; don't copy to background
  4291.         fBackgroundImageCheck->Hide();
  4292.         
  4293.         if ( image->bIsMap )
  4294.             fRemoveImageMapButton->Enable();
  4295.         else
  4296.             fRemoveImageMapButton->Disable();
  4297.     }
  4298.     
  4299.     if ( image )
  4300.         EDT_FreeImageData(image);
  4301.  
  4302.     // select the editField for the main image file name
  4303.     SwitchTarget( fImageFileName );
  4304.     fImageFileName->SelectAll();
  4305.     
  4306.     AdjustEnable();
  4307. }
  4308.  
  4309. void CEDImageContain::Show()
  4310. {
  4311.     if (*fLinkName)
  4312.         fImageFileName->SetLongDescriptor( *fLinkName );
  4313.     CEditContain::Show();
  4314. }
  4315.  
  4316. void CEDImageContain::Hide()
  4317. {
  4318.     if ( *fLinkName )
  4319.         XP_FREE( *fLinkName );
  4320.     *fLinkName = fImageFileName->GetLongDescriptor();
  4321.     
  4322. /*    FSSpec    file;
  4323.     file = fImageFileName->GetFSSpec();
  4324.     if (file.vRefNum != 0 || file.parID != 0 || file.name[0] != 0) {
  4325.     
  4326.         *fLinkName = CFileMgr::GetURLFromFileSpec(file);
  4327.         if (*fLinkName) {
  4328.             char *temp = FE_URLToLocalName(NET_UnEscape(*fLinkName));
  4329.             if (temp) {
  4330.                 XP_FREE(*fLinkName);
  4331.                 *fLinkName = temp;
  4332.             }
  4333.         }
  4334.     } else {
  4335.         *fLinkName = (char *)XP_ALLOC(sizeof(char)*2);            // just fill with some filler so the link pane won't mess with us!
  4336.         if (*fLinkName) XP_STRCPY(*fLinkName, "-");
  4337.     }
  4338. */
  4339.     CEditContain::Hide();
  4340. }
  4341.  
  4342. void CEDImageContain::Help()
  4343. {
  4344.     ShowHelp( HELP_PROPS_IMAGE );
  4345. }
  4346.  
  4347. Boolean CEDImageContain::AllFieldsOK()
  4348. {
  4349.     Str255    str;
  4350.     fImageFileName->GetDescriptor( str );
  4351.     if ( str[0] == 0 )
  4352.     {
  4353.         SwitchTarget( fImageFileName );
  4354.         return false;
  4355.     }
  4356.     
  4357.     // if it's a background image we're done!
  4358.     if ( fBackgroundImageCheck->GetValue() )
  4359.         return true;
  4360.     
  4361.     LControl *customSize = (LControl *)FindPaneByID( 'Cust' );
  4362.     if ( customSize->GetValue() )
  4363.     {
  4364.         LGAPopup *popup = (LGAPopup *)FindPaneByID( 'HtPU' );
  4365.         if ( popup && popup->GetValue() == kPercentOfWindowItem )
  4366.         {
  4367.             if ( !IsEditFieldWithinLimits( fHeightTextEdit, 1, 100 ) )
  4368.             {
  4369.                 SwitchTarget( fHeightTextEdit );
  4370.                 fHeightTextEdit->SelectAll();
  4371.                 return FALSE;
  4372.             }
  4373.         }
  4374.         else
  4375.         {
  4376.             if ( !IsEditFieldWithinLimits( fHeightTextEdit, 1, 10000 ) )
  4377.             {
  4378.                 SwitchTarget( fHeightTextEdit );
  4379.                 fHeightTextEdit->SelectAll();
  4380.                 return FALSE;
  4381.             }
  4382.         }
  4383.         
  4384.         popup = (LGAPopup *)FindPaneByID( 'WdPU' );
  4385.         if ( popup && popup->GetValue() == kPercentOfWindowItem )
  4386.         {
  4387.             if ( !IsEditFieldWithinLimits( fWidthTextEdit, 1, 100 ) )
  4388.             {
  4389.                 SwitchTarget( fWidthTextEdit );
  4390.                 fWidthTextEdit->SelectAll();
  4391.                 return FALSE;
  4392.             }
  4393.         }
  4394.         else
  4395.         {
  4396.             if ( !IsEditFieldWithinLimits( fWidthTextEdit, 1, 10000 ) )
  4397.             {
  4398.                 SwitchTarget( fWidthTextEdit );
  4399.                 fWidthTextEdit->SelectAll();
  4400.                 return FALSE;
  4401.             }
  4402.         }
  4403.     }
  4404.         
  4405.     if ( !IsEditFieldWithinLimits( fLeftRightBorderTextEdit, 0, 10000 ) )
  4406.     {
  4407.         SwitchTarget( fLeftRightBorderTextEdit );
  4408.         fLeftRightBorderTextEdit->SelectAll();
  4409.         return FALSE;
  4410.     }
  4411.  
  4412.     if ( !IsEditFieldWithinLimits( fTopBottomBorderTextEdit, 0, 10000 ) )
  4413.     {
  4414.         SwitchTarget( fTopBottomBorderTextEdit );
  4415.         fTopBottomBorderTextEdit->SelectAll();
  4416.         return FALSE;
  4417.     }
  4418.  
  4419.     if ( !IsEditFieldWithinLimits( fSolidBorderTextEdit, 0, 10000 ) )
  4420.     {
  4421.         SwitchTarget( fSolidBorderTextEdit );
  4422.         fSolidBorderTextEdit->SelectAll();
  4423.         return FALSE;
  4424.     }
  4425.  
  4426.     return TRUE;
  4427. }
  4428.  
  4429.  
  4430. void CEDImageContain::ListenToMessage( MessageT inMessage, void* ioParam )
  4431. {
  4432.     switch (inMessage)
  4433.     {
  4434.         case 'HtPU':
  4435.         case 'WdPU':
  4436.             // set radio button to custom size (not original anymore)
  4437.             LControl *customSize = (LControl *)FindPaneByID( 'Cust' );
  4438.             if ( customSize && customSize->GetValue() == 0 )
  4439.                 customSize->SetValue( true );
  4440.             // continue below
  4441.             
  4442.         case 'Calc':
  4443.             AdjustEnable();
  4444.             break;
  4445.         
  4446.         case 'WSTk':        // Original Size Button
  4447.             LControl *origSizeButton = (LControl *)FindPaneByID( 'Orig' );
  4448.             if ( origSizeButton->GetValue() )
  4449.             {
  4450.                 fHeightTextEdit->SetValue(fOriginalHeight);        // these are not set by the XP yet, apparently.
  4451.                 fWidthTextEdit->SetValue(fOriginalWidth);
  4452.             }
  4453.             AdjustEnable();
  4454.             break;
  4455.         
  4456.         case 'WSTm':    // Remove Image Map Button
  4457.             fLooseImageMap = TRUE;
  4458.             fRemoveImageMapButton->Disable();
  4459.             break;
  4460.  
  4461.         case msg_EditField2:
  4462.             if ( ioParam == NULL )
  4463.                 return;
  4464.             
  4465.             if ( ioParam == fHeightTextEdit || ioParam == fWidthTextEdit )
  4466.             {
  4467.                 LControl *customSize = (LControl *)FindPaneByID( 'Cust' );
  4468.                 if ( customSize && customSize->GetValue() == 0 )
  4469.                     customSize->SetValue( true );
  4470.                 
  4471.                 // don't divide by 0!
  4472.                 if ( fOriginalWidth == 0 || fOriginalHeight == 0 )
  4473.                     return;
  4474.                 
  4475.                 if ( fImageLockedCheckBox->IsEnabled() && fImageLockedCheckBox->GetValue() )
  4476.                 {
  4477.                     int h, w;
  4478.                     
  4479.                     if ( ioParam == fHeightTextEdit )
  4480.                     {
  4481.                         h = fHeightTextEdit->GetValue();
  4482.                         w = h * fOriginalWidth / fOriginalHeight;
  4483.                         fWidthTextEdit->SetValue( w );
  4484.                     }
  4485.                     else
  4486.                     {
  4487.                         w = fWidthTextEdit->GetValue();
  4488.                         h = w * fOriginalHeight / fOriginalWidth;
  4489.                         fHeightTextEdit->SetValue( h );
  4490.                     }
  4491.                 }
  4492.             }
  4493.             else
  4494.                 AdjustEnable();    // typing in a different edit field; adjust controls appropriately
  4495.             break;
  4496.         
  4497.         case 'wst1':    // "Choose File..." image
  4498.             CEditDialog::ChooseImageFile(fImageFileName);
  4499.             AdjustEnable();
  4500.             break;
  4501.         
  4502.         case 'wst3':    // "Choose File..." Alt Image
  4503.             CEditDialog::ChooseImageFile(fImageAltFileName);
  4504.             AdjustEnable();
  4505.             break;
  4506.         
  4507.         case 'WSTn':    // Edit Image Button
  4508.             char *imageURL = fImageFileName->GetLongDescriptor();
  4509.             if ( imageURL && XP_STRLEN(imageURL) < 1 )
  4510.             {
  4511.                 XP_FREE( imageURL );
  4512.                 imageURL = NULL;
  4513.             }
  4514.             
  4515.             if ( imageURL == NULL )
  4516.                 break;
  4517.             
  4518.             char *absURL = NET_MakeAbsoluteURL( LO_GetBaseURL( fContext ), imageURL );
  4519.             XP_FREE(imageURL);
  4520.             
  4521.             Boolean isImageLocal = false;
  4522.             if (absURL && XP_STRSTR(absURL, "file://") == absURL)
  4523.             {
  4524.                 FSSpec    theImage;
  4525.                 
  4526.                 if (CFileMgr::FSSpecFromLocalUnixPath(absURL + XP_STRLEN("file://"), &theImage, FALSE) == noErr)
  4527.                 {                // Skip file://
  4528.                     isImageLocal = true;
  4529.  
  4530.                     // Get the FSSpec for the editor
  4531.                     FSSpec    theApplication;
  4532.                     XP_Bool hasEditor = false;
  4533.                     PREF_GetBoolPref( "editor.use_image_editor", &hasEditor );
  4534.                     if ( hasEditor )
  4535.                         theApplication = CPrefs::GetFolderSpec(CPrefs::ImageEditor);
  4536.                     
  4537.                     // Oops, the user has not picked an app in the preferences yet.
  4538.                     if ( !hasEditor || (theApplication.vRefNum == -1 && theApplication.parID == -1 ) )
  4539.                     {
  4540.                         ErrorManager::PlainAlert( NO_IMG_EDITOR_PREF_SET );
  4541.                         CPrefsDialog::EditPrefs(    CPrefsDialog::eExpandEditor, 
  4542.                                 PrefPaneID::eEditor_Main, CPrefsDialog::eIgnore);
  4543.                     }
  4544.                     else if ( StartDocInApp(theImage, theApplication) == noErr )
  4545.                         ;
  4546.                 }
  4547.             }
  4548.             
  4549.             if ( !isImageLocal )
  4550.                 ErrorManager::PlainAlert( EDITOR_ERROR_EDIT_REMOTE_IMAGE );
  4551.             
  4552.             XP_FREEIF(absURL);
  4553.             break;
  4554.         
  4555.         case 'WSTj':
  4556.             mBorderUnspecified = false;
  4557.             break;
  4558.         
  4559.         case 'Xtra':
  4560.             char * newExtraHTML = NULL;
  4561.             Boolean canceled = !GetExtraHTML( pExtra, &newExtraHTML  ,GetWinCSID() );
  4562.             if (!canceled)
  4563.             {
  4564.                 if ( pExtra )
  4565.                     XP_FREE( pExtra );
  4566.                 pExtra = newExtraHTML;
  4567.             }
  4568.             break;
  4569.     }
  4570. }
  4571.  
  4572. /**********************************************************/
  4573. #pragma mark -
  4574. #pragma mark Document Properties
  4575.  
  4576. void CEDDocPropGeneralContain::FinishCreateSelf()
  4577. {
  4578.     fLocation = (CLargeEditField *)FindPaneByID( 'Loca' );
  4579.     fTitle = (CLargeEditField *)FindPaneByID( 'Titl' );
  4580.     fAuthor = (CLargeEditField *)FindPaneByID( 'Auth' );
  4581.     fDescription = (CLargeEditField *)FindPaneByID( 'Desc' );
  4582.     fKeywords = (CLargeEditField *)FindPaneByID( 'Keyw' );
  4583.     fClassification = (CLargeEditField *)FindPaneByID( 'Clas' );
  4584.     
  4585.     UReanimator::LinkListenerToControls( this, this, mPaneID );
  4586. }
  4587.  
  4588.  
  4589. void CEDDocPropGeneralContain::AddMeta(char *Name, CLargeEditField* value)
  4590. {
  4591.     EDT_MetaData *metaData = EDT_NewMetaData();            // it seems like we could 
  4592.     if (metaData == NULL)
  4593.         return;
  4594.     
  4595.     metaData->bHttpEquiv = FALSE;
  4596.     metaData->pName = Name;
  4597.     metaData->pContent = value->GetLongDescriptor();
  4598.     
  4599.     /* if we try to SetMetaData with an empty string for pContent, then "(null)" is used instead; which is ugly. */
  4600.     
  4601.     if ( metaData->pContent == NULL || XP_STRLEN(metaData->pContent) == 0 )
  4602.         EDT_DeleteMetaData( fContext, metaData );             // hopefully it won't be a problem if this doesn't exist already.
  4603.     else
  4604.          EDT_SetMetaData( fContext, metaData ); 
  4605.    
  4606.     metaData->pName = NULL;            // don't free this, please
  4607.     
  4608.     EDT_FreeMetaData( metaData );
  4609. }
  4610.  
  4611.  
  4612. void CEDDocPropGeneralContain::PrefsFromControls()
  4613. {
  4614.     EDT_PageData *pageData = EDT_GetPageData(fContext);
  4615.     if ( pageData )
  4616.     {
  4617.         if ( pageData->pTitle )
  4618.             XP_FREE( pageData->pTitle );
  4619.         pageData->pTitle = fTitle->GetLongDescriptor();
  4620.  
  4621.         EDT_SetPageData(fContext, pageData);
  4622.         EDT_FreePageData(pageData);
  4623.     }
  4624.     
  4625.     AddMeta("Author", fAuthor);
  4626.     AddMeta("Description", fDescription);
  4627.     AddMeta("KeyWords", fKeywords);
  4628.     AddMeta("Classification", fClassification);
  4629. }
  4630.  
  4631.  
  4632. // Initialize from preferences
  4633. void CEDDocPropGeneralContain::ControlsFromPref()
  4634. {
  4635.     int16 win_csid = GetWinCSID();
  4636.     SetTextTraitsIDByCsid(fTitle, win_csid);
  4637.     SetTextTraitsIDByCsid(fAuthor, win_csid);
  4638.     SetTextTraitsIDByCsid(fDescription, win_csid);
  4639.     SetTextTraitsIDByCsid(fKeywords, win_csid);
  4640.     SetTextTraitsIDByCsid(fClassification, win_csid);
  4641.     History_entry * hist_ent = SHIST_GetCurrent( &fContext->hist );
  4642.     if ( hist_ent && hist_ent->address )
  4643.         fLocation->SetLongDescriptor( hist_ent->address );
  4644.         
  4645.     EDT_PageData *pageData = EDT_GetPageData( fContext );
  4646.     if ( pageData )
  4647.     {
  4648.         if ( pageData->pTitle )
  4649.             fTitle->SetLongDescriptor( pageData->pTitle );
  4650.         EDT_FreePageData( pageData );
  4651.     }
  4652.    
  4653.    
  4654.     // Get data from meta tags:
  4655.  
  4656.     int count = EDT_MetaDataCount(fContext);
  4657.     for ( int i = 0; i < count; i++ )
  4658.     {
  4659.         EDT_MetaData* pData = EDT_GetMetaData(fContext, i);
  4660.  
  4661.         if ( !pData->bHttpEquiv )
  4662.         {
  4663.             if (strcasecomp(pData->pName, "Author") == 0)
  4664.                 fAuthor->SetLongDescriptor( pData->pContent );
  4665.             else if (strcasecomp(pData->pName, "Description") == 0)
  4666.                 fDescription->SetLongDescriptor( pData->pContent );
  4667.             else if (strcasecomp(pData->pName, "KeyWords") == 0)
  4668.                 fKeywords->SetLongDescriptor( pData->pContent );
  4669.             else if (strcasecomp(pData->pName, "Classification") == 0)
  4670.                 fClassification->SetLongDescriptor( pData->pContent );
  4671.         }
  4672.  
  4673.         EDT_FreeMetaData( pData );
  4674.     }
  4675. }
  4676.  
  4677.  
  4678. void CEDDocPropGeneralContain::Help()
  4679. {
  4680.     ShowHelp( HELP_DOC_PROPS_GENERAL );
  4681. }
  4682.  
  4683.  
  4684. static void AddNewColorData( XP_List *pSchemeData, int r1, int g1, int b1, int r2, int g2, int b2, int r3, int g3, int b3, int r4, int g4, int b4, int r5, int g5, int b5 );
  4685. static void AddNewColorData( XP_List *pSchemeData, int r1, int g1, int b1, int r2, int g2, int b2, int r3, int g3, int b3, int r4, int g4, int b4, int r5, int g5, int b5 )
  4686. {
  4687.     EDT_ColorSchemeData * pColorData = XP_NEW( EDT_ColorSchemeData );
  4688.     if ( !pColorData )
  4689.         return;
  4690.     
  4691.     memset(pColorData, 0, sizeof(EDT_ColorSchemeData));
  4692.     XP_ListAddObjectToEnd( pSchemeData, pColorData );
  4693.     
  4694.     pColorData->ColorText.red = r1;
  4695.     pColorData->ColorText.green = g1;
  4696.     pColorData->ColorText.blue = b1;
  4697.     
  4698.     pColorData->ColorLink.red = r3;
  4699.     pColorData->ColorLink.green = g3;
  4700.     pColorData->ColorLink.blue = b3;
  4701.     
  4702.     pColorData->ColorActiveLink.red = r5;
  4703.     pColorData->ColorActiveLink.green = g5;
  4704.     pColorData->ColorActiveLink.blue = b5;
  4705.     
  4706.     pColorData->ColorFollowedLink.red = r4;
  4707.     pColorData->ColorFollowedLink.green = g4;
  4708.     pColorData->ColorFollowedLink.blue = b4;
  4709.     
  4710.     pColorData->ColorBackground.red = r2;
  4711.     pColorData->ColorBackground.green = g2;
  4712.     pColorData->ColorBackground.blue = b2;
  4713. }
  4714.  
  4715.  
  4716. void AppearanceContain::FinishCreateSelf()
  4717. {
  4718.     fCustomColor = (LControl*)FindPaneByID( 'Cust' );
  4719.     fBrowserColor = (LControl*)FindPaneByID( 'Brow' );
  4720.  
  4721.     fColorScheme = (LControl*)FindPaneByID( 'Sche' );
  4722.  
  4723.     fExampleView = (CChameleonView*)FindPaneByID( 'Exam' );
  4724.     fNormalText = (CColorButton*)FindPaneByID( 'Norm' );
  4725.     fLinkedText = (CColorButton*)FindPaneByID( 'Link' );
  4726.     fActiveLinkedText = (CColorButton*)FindPaneByID( 'Acti' );
  4727.     fFollowedLinkedText = (CColorButton*)FindPaneByID( 'Foll' );
  4728.  
  4729.     fExampleNormalText = (CChameleonCaption*)FindPaneByID( 'norm' );
  4730.     fExampleLinkedTex = (CChameleonCaption*)FindPaneByID( 'link' );
  4731.     fExampleActiveLinkedText = (CChameleonCaption*)FindPaneByID( 'actv' );
  4732.     fExampleFollowedLinkedText = (CChameleonCaption*)FindPaneByID( 'fllw' );
  4733.     
  4734.     fSolidColor = (CColorButton*)FindPaneByID( 'Choo' );
  4735.     
  4736.     fImageFile = (LControl*)FindPaneByID( 'Imag' );
  4737.     fImageFileName = (CLargeEditField *)FindPaneByID( 'bthr' );
  4738.     
  4739.     UReanimator::LinkListenerToControls( this, this, mPaneID );
  4740.  
  4741.     LO_Color colorBackground = UGraphics::MakeLOColor( CPrefs::GetColor( CPrefs::WindowBkgnd ) );
  4742.     LO_Color colorText = UGraphics::MakeLOColor( CPrefs::GetColor( CPrefs::Black ) );
  4743.     LO_Color colorLink = UGraphics::MakeLOColor( CPrefs::GetColor( CPrefs::Blue ) );
  4744.     LO_Color colorActiveLink = UGraphics::MakeLOColor( CPrefs::GetColor( CPrefs::Blue ) );                // this must be the same as colorLink ?!
  4745.     LO_Color colorFollowedLink = UGraphics::MakeLOColor( CPrefs::GetColor( CPrefs::Magenta ) );
  4746.  
  4747.     fSchemeData = XP_ListNew();
  4748.     AddNewColorData( fSchemeData,    
  4749.                 colorText.red, colorText.green, colorText.blue,
  4750.                 colorBackground.red, colorBackground.green, colorBackground.blue,
  4751.                 colorLink.red, colorLink.green, colorLink.blue,
  4752.                 colorFollowedLink.red, colorFollowedLink.green, colorFollowedLink.blue,
  4753.                 colorActiveLink.red, colorActiveLink.green, colorActiveLink.blue);
  4754.     AddNewColorData( fSchemeData,    0,0,0,            255,240,240,    255,0,0,        128,0,128,        0,0,255 );
  4755.     AddNewColorData( fSchemeData,    0,0,0,            255,255,192,    0,0,255,        128,0,128,        255,0,255 );
  4756.     AddNewColorData( fSchemeData,    64,0,64,        255,255,128,    0,0,255,        0,128,0,        255,0,128 );
  4757.     AddNewColorData( fSchemeData,    0,0,0,            192,192,255,    0,0,255,        128,0,128,        255,0,128 );
  4758.     AddNewColorData( fSchemeData,    0,0,0,            128,128,192,    255,255,255,    128,0,128,        255,255,0 );
  4759.     AddNewColorData( fSchemeData,    0,0,128,        255,192,64,        0,0,255,        0,128,0,        0,255,255 );
  4760.     AddNewColorData( fSchemeData,    255,255,255,    0,0,0,            255,255,0,        192,192,192,    192,255,192 );
  4761.     AddNewColorData( fSchemeData,    255,255,255,    0,64,0,            255,255,0,        128,255,128,    0,255,64 );
  4762.     AddNewColorData( fSchemeData,    255,255,255,    0,0,128,        255,255,0,        128,128,255,    255,0,255 );
  4763.     AddNewColorData( fSchemeData,    255,255,255,    128,0,128,        0,255,255,        128,255,255,    0,255,0 );
  4764.     
  4765.     fColorScheme->SetValue(2);            // Netscape default
  4766.     ListenToMessage('Sche', NULL);            
  4767. }
  4768.  
  4769.  
  4770. void AppearanceContain::UpdateTheWholeDamnDialogBox()
  4771. {
  4772.     RGBColor color;
  4773.     RGBColor backColor;
  4774.     
  4775.     backColor = fSolidColor->GetColor();            // what about the default??
  4776.     fExampleView->SetColor( backColor );
  4777.  
  4778.     color = fNormalText->GetColor();
  4779.     fExampleNormalText->SetColor( color, backColor );
  4780.     
  4781.     color = fLinkedText->GetColor();
  4782.     fExampleLinkedTex->SetColor( color, backColor );
  4783.     
  4784.     color = fActiveLinkedText->GetColor();
  4785.     fExampleActiveLinkedText->SetColor( color, backColor );
  4786.     
  4787.     color = fFollowedLinkedText->GetColor();
  4788.     fExampleFollowedLinkedText->SetColor( color, backColor );
  4789.         
  4790.     fExampleView->Refresh();
  4791.     fNormalText->Refresh();
  4792.     fLinkedText->Refresh();
  4793.     fActiveLinkedText->Refresh();
  4794.     fFollowedLinkedText->Refresh();
  4795.     fSolidColor->Refresh();    
  4796.     
  4797.     if (fBrowserColor->GetValue())
  4798.     {
  4799.         fColorScheme->Disable();
  4800.         fExampleView->Disable();
  4801.         fNormalText->Disable();
  4802.         fLinkedText->Disable();
  4803.         fActiveLinkedText->Disable();
  4804.         fFollowedLinkedText->Disable();
  4805.         fSolidColor->Disable();
  4806.     }
  4807.     else
  4808.     {
  4809.         fColorScheme->Enable();
  4810.         fExampleView->Enable();
  4811.         fNormalText->Enable();
  4812.         fLinkedText->Enable();
  4813.         fActiveLinkedText->Enable();
  4814.         fFollowedLinkedText->Enable();
  4815.         fSolidColor->Enable();
  4816.     }
  4817. }
  4818.  
  4819.  
  4820. void AppearanceContain::ListenToMessage( MessageT inMessage, void* /* ioParam */ )
  4821. {
  4822.     switch (inMessage)
  4823.     {
  4824.         case 'Norm':
  4825.         case 'Link':
  4826.         case 'Acti':
  4827.         case 'Foll':
  4828.         case 'Choo':
  4829.             fColorScheme->SetValue(1);            // custom
  4830.             ListenToMessage('Sche', NULL);            
  4831.         case 'Cust':
  4832.         case 'Brow':
  4833.             UpdateTheWholeDamnDialogBox();
  4834.             break;
  4835.         
  4836.         
  4837.         case 'Imag':
  4838.             if (fImageFile->GetValue() == 1)
  4839.             {                // we are trying to set the image
  4840.                 CStr255 url;
  4841.                 fImageFileName->GetDescriptor(url);
  4842.                 if (url == CStr255::sEmptyString)
  4843.                 {        // but it doesn't exist
  4844.                     CEditDialog::ChooseImageFile( fImageFileName );        // so try to get it
  4845.                     fImageFileName->GetDescriptor(url);
  4846.                     if (url == CStr255::sEmptyString)     // but, if we were unsuccessful
  4847.                         fImageFile->SetValue(0);                // revert back.
  4848.                 }
  4849.             }
  4850.             break;
  4851.         
  4852.         case 'wst1':
  4853.             CEditDialog::ChooseImageFile( fImageFileName );    // try to get it
  4854.             CStr255 url;
  4855.             fImageFileName->GetDescriptor(url);
  4856.             if (url == CStr255::sEmptyString)     // if we were unsuccessful
  4857.                 fImageFile->SetValue(0);                // don't try to use
  4858.             else
  4859.                 fImageFile->SetValue(1);                // ok
  4860.             break;
  4861.                 
  4862.         case 'Sche':
  4863.             int scheme = fColorScheme->GetValue();
  4864.             scheme--;
  4865.  
  4866.             if (scheme)
  4867.             {
  4868.                 EDT_ColorSchemeData * pColorData = (EDT_ColorSchemeData *)XP_ListGetObjectNum(fSchemeData, scheme);
  4869.                 if (pColorData)
  4870.                 {
  4871.                     fSolidColor->            SetColor(UGraphics::MakeRGBColor(pColorData->ColorBackground));
  4872.                     fNormalText->            SetColor(UGraphics::MakeRGBColor(pColorData->ColorText));
  4873.                     fLinkedText->            SetColor(UGraphics::MakeRGBColor(pColorData->ColorLink));
  4874.                     fActiveLinkedText->        SetColor(UGraphics::MakeRGBColor(pColorData->ColorActiveLink));
  4875.                     fFollowedLinkedText->    SetColor(UGraphics::MakeRGBColor(pColorData->ColorFollowedLink));
  4876.                 }
  4877.                 
  4878.                 fImageFile->SetValue(0);                // no background
  4879.                 UpdateTheWholeDamnDialogBox();
  4880.             }
  4881.         break;
  4882.         
  4883.     }
  4884. }
  4885.  
  4886.  
  4887. CEDDocPropAppearanceContain::~CEDDocPropAppearanceContain()
  4888. {
  4889.     if ( fSchemeData )
  4890.     {
  4891.         EDT_ColorSchemeData *pColorData;
  4892.         XP_List * list_ptr = fSchemeData;
  4893.         pColorData = (EDT_ColorSchemeData *)XP_ListNextObject(list_ptr);
  4894.         while ( pColorData )
  4895.         {
  4896.             XP_FREE(pColorData);
  4897.                pColorData = (EDT_ColorSchemeData *)XP_ListNextObject(list_ptr);
  4898.         }
  4899.         XP_ListDestroy(fSchemeData);
  4900. //        XP_FREE(fSchemeData);        already done by XP_ListDestroy()!!
  4901.     }
  4902. }
  4903.  
  4904. void CEDDocPropAppearanceContain::PrefsFromControls()
  4905. {
  4906.     LControl *prefCheckBox = (LControl *)FindPaneByID( 'Dflt' );
  4907.     if ( prefCheckBox && prefCheckBox->GetValue() && prefCheckBox->IsVisible() )
  4908.     {
  4909.         PREF_SetBoolPref( "editor.use_custom_colors", fCustomColor->GetValue() );
  4910.         if ( fCustomColor->GetValue() )
  4911.         {
  4912.             LO_Color colorBackground =        UGraphics::MakeLOColor(fSolidColor->GetColor());
  4913.             LO_Color colorText =            UGraphics::MakeLOColor(fNormalText->GetColor());
  4914.             LO_Color colorLink =            UGraphics::MakeLOColor(fLinkedText->GetColor());
  4915.             LO_Color colorActiveLink =        UGraphics::MakeLOColor(fActiveLinkedText->GetColor());
  4916.             LO_Color colorFollowedLink =    UGraphics::MakeLOColor(fFollowedLinkedText->GetColor());
  4917.  
  4918.             PREF_SetColorPref( "editor.background_color",
  4919.                                 colorBackground.red,
  4920.                                 colorBackground.green,
  4921.                                 colorBackground.blue );
  4922.             PREF_SetColorPref( "editor.text_color",
  4923.                                 colorText.red,
  4924.                                 colorText.green,
  4925.                                 colorText.blue );
  4926.             PREF_SetColorPref( "editor.link_color",
  4927.                                 colorLink.red,
  4928.                                 colorLink.green,
  4929.                                 colorLink.blue );
  4930.             PREF_SetColorPref( "editor.active_link_color",
  4931.                                 colorActiveLink.red,
  4932.                                 colorActiveLink.green,
  4933.                                 colorActiveLink.blue );
  4934.             PREF_SetColorPref( "editor.followed_link_color",
  4935.                                 colorFollowedLink.red,
  4936.                                 colorFollowedLink.green,
  4937.                                 colorFollowedLink.blue );
  4938.         }
  4939.  
  4940.         PREF_SetBoolPref( "editor.use_background_image", fImageFile->GetValue());
  4941.         if (fImageFile->GetValue())
  4942.         {
  4943.             char *url = fImageFileName->GetLongDescriptor();
  4944.             if ( url && XP_STRLEN( url ) )
  4945.                 PREF_SetCharPref("editor.background_image", url);
  4946.             XP_FREEIF( url );
  4947.         }
  4948.     }
  4949.     
  4950.     EDT_PageData *pageData = EDT_GetPageData( fContext );
  4951.     if (pageData == NULL)
  4952.         return;
  4953.     
  4954.     if (pageData->pColorBackground) XP_FREE(pageData->pColorBackground);    // don't care about the old values...
  4955.     if (pageData->pColorText) XP_FREE(pageData->pColorText);
  4956.     if (pageData->pColorLink) XP_FREE(pageData->pColorLink);
  4957.     if (pageData->pColorActiveLink) XP_FREE(pageData->pColorActiveLink);
  4958.     if (pageData->pColorFollowedLink) XP_FREE(pageData->pColorFollowedLink);
  4959.     if (pageData->pBackgroundImage)
  4960.     {
  4961.         XP_FREE( pageData->pBackgroundImage );
  4962.         pageData->pBackgroundImage = NULL;
  4963.     }
  4964.     
  4965.     if ( fImageFile->GetValue() )
  4966.     {
  4967.         char *url = fImageFileName->GetLongDescriptor();
  4968.         if ( url && XP_STRLEN( url ) )
  4969.             pageData->pBackgroundImage = url;
  4970.         else if ( url )
  4971.             XP_FREE( url );
  4972.     }
  4973.              
  4974.     if (fBrowserColor->GetValue())
  4975.     {
  4976.         pageData->pColorBackground = NULL;
  4977.         pageData->pColorText = NULL;
  4978.         pageData->pColorLink = NULL;
  4979.         pageData->pColorActiveLink = NULL;
  4980.         pageData->pColorFollowedLink = NULL;
  4981.     }
  4982.     else
  4983.     {
  4984.         LO_Color colorBackground =        UGraphics::MakeLOColor(fSolidColor->GetColor());
  4985.         LO_Color colorText =            UGraphics::MakeLOColor(fNormalText->GetColor());
  4986.         LO_Color colorLink =            UGraphics::MakeLOColor(fLinkedText->GetColor());
  4987.         LO_Color colorActiveLink =        UGraphics::MakeLOColor(fActiveLinkedText->GetColor());
  4988.         LO_Color colorFollowedLink =    UGraphics::MakeLOColor(fFollowedLinkedText->GetColor());
  4989.         
  4990.         pageData->pColorBackground =    &colorBackground;
  4991.         pageData->pColorText =            &colorText;
  4992.         pageData->pColorLink =            &colorLink;
  4993.         pageData->pColorActiveLink =    &colorActiveLink;
  4994.         pageData->pColorFollowedLink =    &colorFollowedLink;
  4995.     }
  4996.     
  4997.     EDT_SetPageData( fContext, pageData );
  4998.     
  4999.     pageData->pColorBackground = NULL;        // of course, we don't want to FREE these...
  5000.     pageData->pColorText = NULL;
  5001.     pageData->pColorLink = NULL;
  5002.     pageData->pColorActiveLink = NULL;
  5003.     pageData->pColorFollowedLink = NULL;
  5004.     
  5005.     EDT_FreePageData( pageData );
  5006. }
  5007.  
  5008.  
  5009. static
  5010. inline
  5011. bool operator==( const LO_Color& lhs, const LO_Color& rhs )
  5012. {
  5013.     return lhs.red   == rhs.red
  5014.         && lhs.green == rhs.green
  5015.         && lhs.blue  == rhs.blue;
  5016. }
  5017.  
  5018.  
  5019. void CEDDocPropAppearanceContain::ControlsFromPref()
  5020. {
  5021.     EDT_PageData *pageData = EDT_GetPageData( fContext );
  5022.     if (pageData == NULL)
  5023.         return;
  5024.     
  5025.     if (pageData->pColorBackground
  5026.         || pageData->pColorLink
  5027.         || pageData->pColorText
  5028.         || pageData->pColorFollowedLink
  5029.         || pageData->pColorActiveLink)
  5030.     {
  5031.         TurnOn(fCustomColor);
  5032.         fColorScheme->SetValue(1);            // switch to custom by default
  5033.         
  5034.         int scheme;
  5035.         for ( scheme = 0; scheme < fColorScheme->GetMaxValue(); scheme++ )
  5036.         {
  5037.             EDT_ColorSchemeData * pColorData = (EDT_ColorSchemeData *)XP_ListGetObjectNum( fSchemeData, scheme );
  5038.             if ( pColorData && (pColorData->ColorBackground == *(pageData->pColorBackground))
  5039.                             && (pColorData->ColorText == *(pageData->pColorText))
  5040.                             && (pColorData->ColorLink == *(pageData->pColorLink))
  5041.                             && (pColorData->ColorActiveLink == *(pageData->pColorActiveLink))
  5042.                             && (pColorData->ColorFollowedLink == *(pageData->pColorFollowedLink)) )
  5043.             {
  5044.                 fColorScheme->SetValue( scheme + 1 );
  5045.                 break;
  5046.             }
  5047.         }
  5048.             
  5049.     }
  5050.     else
  5051.     {
  5052.         TurnOn(fBrowserColor);
  5053.     }
  5054.  
  5055.     fImageFile->SetValue(0);
  5056.     if (pageData->pBackgroundImage && XP_STRLEN(pageData->pBackgroundImage) > 0)
  5057.     {
  5058.         fImageFileName->SetLongDescriptor( pageData->pBackgroundImage );
  5059.         fImageFile->SetValue(1);
  5060.     }
  5061.     
  5062.     if (pageData->pColorBackground)
  5063.         fSolidColor->SetColor(UGraphics::MakeRGBColor(*pageData->pColorBackground));
  5064.     if (pageData->pColorText)
  5065.         fNormalText->SetColor(UGraphics::MakeRGBColor(*pageData->pColorText));
  5066.     if (pageData->pColorLink)
  5067.         fLinkedText->SetColor(UGraphics::MakeRGBColor(*pageData->pColorLink));
  5068.     if (pageData->pColorActiveLink)
  5069.         fActiveLinkedText->SetColor(UGraphics::MakeRGBColor(*pageData->pColorActiveLink));
  5070.     if (pageData->pColorFollowedLink)
  5071.         fFollowedLinkedText->SetColor(UGraphics::MakeRGBColor(*pageData->pColorFollowedLink));
  5072.     
  5073.     EDT_FreePageData( pageData );
  5074.     UpdateTheWholeDamnDialogBox();
  5075. }
  5076.  
  5077.  
  5078. void CEDDocPropAppearanceContain::Help()
  5079. {
  5080.     ShowHelp( HELP_DOC_PROPS_APPEARANCE );
  5081. }
  5082.  
  5083.  
  5084. /* TO DO:
  5085. Well, this is somewhat of a mess because:
  5086. 1) we store the name and value together separated only by a '='. Easily screwed up if one or the other contains a '='
  5087. 2) We don't remove spaces or any other white space.
  5088. 3) we don't handle quotes at all. Shouldn't we do something about escaping '"' chanacters?
  5089. 4) The UI needs work.
  5090. 5) could use stack space for the majority of small META tags and only resort to malloc in exceptional cases
  5091. 6) when the page is reloaded, we re-blast in the meta values starting from cell number 1 without first clearing the table
  5092. 7) no UI for user who tries to insert an "Author" meta tag, etc.
  5093. 8) not too sure what we are supposed to do about case. layout uses case insensitive tags. EDT_GetMetaData() uses case sensitive tags.
  5094. */
  5095.  
  5096. CEDDocPropAdvancedContain::~CEDDocPropAdvancedContain()
  5097. {
  5098.     XP_FREEIF( fbuffer );
  5099. }
  5100.  
  5101. void CEDDocPropAdvancedContain::FinishCreateSelf()
  5102. {
  5103.     fbufferlen = 1000;
  5104.     fbuffer = (char *)malloc( fbufferlen );                    // we'll keep this fbuffer for temp use for various things as long as dlog is around.
  5105.     if ( fbuffer == NULL )
  5106.         fbufferlen = 0;
  5107.     
  5108.     fSystemVariables = (OneRowLListBox*)FindPaneByID( 'Syst' );
  5109.     fUserVariables = (OneRowLListBox*)FindPaneByID( 'User' );
  5110.     
  5111.     fName = (CLargeEditField *)FindPaneByID( 'Name' );
  5112.     fValue = (CLargeEditField *)FindPaneByID( 'Valu' );
  5113.     
  5114.     UReanimator::LinkListenerToControls( this, this, mPaneID );
  5115. }
  5116.  
  5117. void CEDDocPropAdvancedContain::PrefsFromControls()
  5118. {
  5119.     if (fbuffer == NULL)
  5120.         return;    // the fbuffer is now as big or bigger (it grows) than all MetaData and all cell entries in the table. Don't worry about the size anymore.
  5121.     
  5122.     EDT_MetaData* pData;
  5123.     int16 i, count;
  5124.     
  5125.     // First, clear METAs all out because we are going to rebuild the lists from scratch.
  5126.     count = EDT_MetaDataCount(fContext);
  5127.     for (i = count - 1; i >= 0; i-- )
  5128.     {
  5129.            pData = EDT_GetMetaData(fContext, i);
  5130.  
  5131.         if (strcasecomp(pData->pName, "Author") &&                     // Skip the fields used in General Info page
  5132.             strcasecomp(pData->pName, "Description") &&
  5133.             strcasecomp(pData->pName, "Generator") &&
  5134.             strcasecomp(pData->pName, "Last-Modified") &&
  5135.             strcasecomp(pData->pName, "Created") &&
  5136.             strcasecomp(pData->pName, "Classification") &&
  5137.             strcasecomp(pData->pName, "Keywords"))
  5138.             EDT_DeleteMetaData( fContext, pData );                    // remove all the other ones.
  5139.             
  5140.         EDT_FreeMetaData( pData );
  5141.     }
  5142.     
  5143.     pData = EDT_NewMetaData();
  5144.     
  5145.     
  5146.     // Do the system METAs first, bHttpEquiv = FALSE;
  5147.     pData->bHttpEquiv = FALSE;
  5148.     count = fSystemVariables->GetRows();
  5149.     for (i = 0; i < count; i++)
  5150.     {
  5151.         int16 len = fbufferlen;
  5152.         fSystemVariables->GetCell(i, fbuffer, &len);
  5153.         fbuffer[len] = '\0';
  5154.         
  5155.         pData->pName = fbuffer;
  5156.         
  5157.         char *equal = strchr(fbuffer, '=');        // look for the '='. Of course this screws up if the stupid user put an '=' in the TEditField
  5158.         
  5159.         if (equal)
  5160.         {
  5161.             *equal++ = '\0';
  5162.             pData->pContent = equal;
  5163.             EDT_SetMetaData( fContext, pData );
  5164.         }
  5165.         else
  5166.         {
  5167.             pData->pContent = NULL;                                // I should check if this is valid....
  5168.             EDT_DeleteMetaData( fContext, pData );                // you might wonder why I'm calling EDT_DeleteMetaData() if all Tags are supposed to be gone.... Well, what if a user wanted to delete the "Author" tag here by defining it to be NULL?!
  5169.         }
  5170.     }
  5171.     
  5172.     // Do the user METAs next, bHttpEquiv = TRUE;
  5173.     pData->bHttpEquiv = TRUE;
  5174.     count = fUserVariables->GetRows();
  5175.     for (i = 0; i < count; i++)
  5176.     {
  5177.         int16 len = fbufferlen;
  5178.         fUserVariables->GetCell(i, fbuffer, &len);
  5179.         fbuffer[len] = '\0';
  5180.         
  5181.         pData->pName = fbuffer;
  5182.         
  5183.         char *equal = strchr(fbuffer, '=');
  5184.         
  5185.         if (equal)
  5186.         {
  5187.             *equal++ = '\0';
  5188.             pData->pContent = equal;
  5189.         }
  5190.         else
  5191.             pData->pContent = NULL;                                // I should check if this is valid....
  5192.             
  5193.         EDT_SetMetaData( fContext, pData );
  5194.     }
  5195.     
  5196.     pData->pName = NULL;            // we don't want EDT_FreeMetaData() to free our fbuffer for us.
  5197.     pData->pContent = NULL;            // we don't want EDT_FreeMetaData() to free our fbuffer for us.
  5198.  
  5199.     EDT_FreeMetaData(pData);    
  5200. }
  5201.  
  5202.  
  5203. void CEDDocPropAdvancedContain::ControlsFromPref()
  5204. {
  5205.     int16 sysRowNum = fSystemVariables->GetRows();            // add to the bottom? shouldn't we clear the tables first and skip this?
  5206.     int16 usrRowNum = fUserVariables->GetRows();            // add to the bottom? shouldn't we clear the tables first and skip this?
  5207.     
  5208.     sysRowNum = 1;            // forget what is in the table now. We'll start from the beginning.
  5209.     usrRowNum = 1;
  5210.  
  5211.     int newlength;
  5212.     int count = EDT_MetaDataCount(fContext);
  5213.     for ( int i = 0; i < count; i++ )
  5214.     {
  5215.         EDT_MetaData* pData = EDT_GetMetaData(fContext, i);
  5216.         
  5217.         newlength = XP_STRLEN(pData->pName) + 1 + XP_STRLEN(pData->pContent) + 1;
  5218.         if ( fbuffer && newlength > fbufferlen )
  5219.         {        // grow fbuffer if necessary
  5220.             fbuffer = (char *) XP_REALLOC(&fbuffer, fbufferlen);
  5221.             if ( fbuffer )
  5222.                 fbufferlen = newlength;
  5223.             else
  5224.                 fbufferlen = 0;
  5225.         }
  5226.         
  5227.         if ( fbuffer )
  5228.         {
  5229.             sprintf(fbuffer, "%s=%s", pData->pName, pData->pContent);
  5230.  
  5231.             if ( pData->bHttpEquiv )
  5232.             {            // which table do we put it in?
  5233.                 fSystemVariables->AddRow( sysRowNum++, fbuffer, XP_STRLEN(fbuffer) );
  5234.             }
  5235.             else if (strcasecomp(pData->pName, "Author") &&                     // Skip the fields used in General Info page
  5236.                 strcasecomp(pData->pName, "Description") &&
  5237.                 strcasecomp(pData->pName, "Generator") &&
  5238.                 strcasecomp(pData->pName, "Last-Modified") &&
  5239.                 strcasecomp(pData->pName, "Created") &&
  5240.                 strcasecomp(pData->pName, "Classification") &&
  5241.                 strcasecomp(pData->pName, "Keywords"))
  5242.             {
  5243.                 // TODO: PUT META STRINGS IN RESOURCES?
  5244.                 fUserVariables->AddRow( usrRowNum++, fbuffer, XP_STRLEN(fbuffer) );
  5245.             }
  5246.         }
  5247.         
  5248.         EDT_FreeMetaData( pData );
  5249.     }
  5250.  
  5251.     fSystemVariables->FocusDraw();
  5252.     fSystemVariables->SetDoubleClickMessage( msg_DblClickOnTarget );
  5253.     fSystemVariables->SetSingleClickMessage(msg_ClickOnTarget);
  5254.     fSystemVariables->AddListener( this );    
  5255.     fSystemVariables->SetValue(-1);
  5256.  
  5257.     fUserVariables->FocusDraw();
  5258.     fUserVariables->SetDoubleClickMessage( msg_DblClickOnTarget2 );
  5259.     fUserVariables->SetSingleClickMessage( msg_ClickOnTarget2 );
  5260.     fUserVariables->AddListener( this );    
  5261.     fUserVariables->SetValue(-1);
  5262. }
  5263.  
  5264. void CEDDocPropAdvancedContain::PutStringsInBuffer()
  5265. {
  5266.     if (fbuffer == NULL)
  5267.         return;
  5268.     
  5269.     char *name = fName->GetLongDescriptor();
  5270.     if ( name == NULL )
  5271.         return;
  5272.     
  5273.     char *value = fValue->GetLongDescriptor();
  5274.     if ( value == NULL )
  5275.     {
  5276.         XP_FREE( name );
  5277.         return;
  5278.     }
  5279.     
  5280.     if ( XP_STRLEN(name) + 1 + XP_STRLEN(value) + 1 > fbufferlen )
  5281.     {        // grow the fbuffer if necessary
  5282.         fbuffer = (char *) XP_REALLOC(&fbuffer, fbufferlen);
  5283.         if ( fbuffer )
  5284.             fbufferlen = XP_STRLEN( name ) + 1 + XP_STRLEN( value ) + 1;
  5285.         else
  5286.             fbufferlen = 0;
  5287.     }
  5288.     
  5289.     if ( fbuffer )
  5290.         sprintf(fbuffer, "%s=%s", name, value);
  5291.     
  5292.     XP_FREE( name );
  5293.     XP_FREE( value );
  5294. }
  5295.  
  5296. Boolean CEDDocPropAdvancedContain::BufferUnique()
  5297. {
  5298.     if (fbuffer == NULL) return false;
  5299.     
  5300.     if (!fSystemVariables->IsTarget() && !fUserVariables->IsTarget())
  5301.         return false;            // we compare against the target: at least one must be target
  5302.     
  5303.     OneRowLListBox* lBox;
  5304.     if (fSystemVariables->IsTarget())
  5305.         lBox = fSystemVariables;
  5306.     else
  5307.         lBox = fUserVariables;
  5308.     
  5309.     int16 count = lBox->GetRows();
  5310.     char *tempbuff = (char *)malloc(fbufferlen);            // we need to copy the strings out of the table one at a time to compare with them. don't copy more than bufflen since they wouldn't be equal then anyway.
  5311.     if (tempbuff == NULL)
  5312.         return false;
  5313.     
  5314.     int16 i;
  5315.     for (i = 0; i < count; i++) {
  5316.         int16 len = fbufferlen;
  5317.         lBox->GetCell(i, tempbuff, &len);
  5318.         tempbuff[len] = '\0';
  5319.         if (XP_STRCMP(tempbuff, fbuffer) == NULL)
  5320.         {                // we should probably do a case insensitive compare on the Name and a case sensitive compare on the Value. What a pain.
  5321.             XP_FREE(tempbuff);
  5322.             return false;
  5323.         }
  5324.     }
  5325.     
  5326.     XP_FREE(tempbuff);
  5327.     return true;        // no matches; must be unique
  5328. }
  5329.  
  5330.  
  5331. void CEDDocPropAdvancedContain::Help()
  5332. {
  5333.     ShowHelp( HELP_DOC_PROPS_ADVANCED );
  5334. }
  5335.  
  5336.  
  5337. void CEDDocPropAdvancedContain::ListenToMessage( MessageT inMessage, void* /* ioParam */ )
  5338. {
  5339.     switch (inMessage) {
  5340.         case msg_Doc_Advanced_Prop_New_Tag:
  5341.             PutStringsInBuffer();
  5342.             if (BufferUnique()) {
  5343.                 if (fSystemVariables->IsTarget())
  5344.                     fSystemVariables->AddRow(fSystemVariables->GetRows(),fbuffer,strlen(fbuffer));
  5345.                 
  5346.                 if (fUserVariables->IsTarget())
  5347.                     fUserVariables->AddRow(fUserVariables->GetRows(),fbuffer,strlen(fbuffer));
  5348.             }            
  5349.             break;
  5350.  
  5351.         case msg_Doc_Advanced_Prop_Set_Tag:
  5352.             PutStringsInBuffer();
  5353.             if (BufferUnique()) {
  5354.             
  5355.                 if (fSystemVariables->IsTarget() && fSystemVariables->GetValue() != -1)
  5356.                         fSystemVariables->SetCell(fSystemVariables->GetValue(),fbuffer,strlen(fbuffer));
  5357.                 
  5358.                 if (fUserVariables->IsTarget() && fUserVariables->GetValue() != -1)
  5359.                         fUserVariables->SetCell(fUserVariables->GetValue(),fbuffer,strlen(fbuffer));
  5360.                 
  5361.             }            
  5362.             break;
  5363.  
  5364.         case msg_Doc_Advanced_Prop_Delete_Tag:
  5365.             if (fSystemVariables->IsTarget() && fSystemVariables->GetValue() != -1)
  5366.                 fSystemVariables->RemoveRow(fSystemVariables->GetValue());
  5367.             
  5368.             if (fUserVariables->IsTarget() && fUserVariables->GetValue() != -1)
  5369.                 fUserVariables->RemoveRow(fUserVariables->GetValue());
  5370.             break;
  5371.  
  5372.         case msg_ClickOnTarget:
  5373.         case msg_DblClickOnTarget:
  5374.             if (fbuffer && fSystemVariables->GetValue() != -1)
  5375.             {
  5376.                 int16 len = fbufferlen;
  5377.                 fSystemVariables->GetCell(fSystemVariables->GetValue(), fbuffer, &len);
  5378.                 fbuffer[len] = '\0';
  5379.                 
  5380.                 char *equal = strchr(fbuffer, '=');
  5381.                 if ( equal )
  5382.                 {
  5383.                     *equal++ = '\0';
  5384.                     fValue->SetLongDescriptor( equal );
  5385.                 } 
  5386.                 else
  5387.                     fValue->SetLongDescriptor( "" );
  5388.                 
  5389.                 fName->SetLongDescriptor( fbuffer );
  5390.             }
  5391.             break;
  5392.  
  5393.         case msg_ClickOnTarget2:
  5394.         case msg_DblClickOnTarget2:
  5395.             if (fbuffer && fUserVariables->GetValue() != -1)
  5396.             {
  5397.                 int16 len = fbufferlen;
  5398.                 fUserVariables->GetCell(fUserVariables->GetValue(), fbuffer, &len);
  5399.                 fbuffer[len] = '\0';
  5400.                 
  5401.                 char *equal = strchr(fbuffer, '=');
  5402.                 if (equal)
  5403.                 {
  5404.                     *equal++ = '\0';
  5405.                     fValue->SetLongDescriptor( equal );
  5406.                 }
  5407.                 else
  5408.                     fValue->SetLongDescriptor( "" );
  5409.                 
  5410.                 fName->SetLongDescriptor( fbuffer );
  5411.             }
  5412.             break;
  5413.     }
  5414. }
  5415.  
  5416.  
  5417. void CEDDocAppearanceNoTab::DrawSelf()
  5418. {
  5419. // we don't want to draw any frame/bevel border in this case because it is going to
  5420. // go into a dialog all by itself (not in a tabbed dialog)
  5421. // the following is copied from CPrefContain::DrawSelf() and #if'd out
  5422. #if 0
  5423.     Rect theFrame;
  5424.     if (CalcLocalFrameRect(theFrame))
  5425.         {
  5426.         StColorPenState theSaver;
  5427.         theSaver.Normalize();
  5428.         
  5429.         SBevelColorDesc theDesc;
  5430.         UGraphicGizmos::LoadBevelTraits(5000, theDesc);
  5431.     
  5432.         ::PmForeColor(theDesc.fillColor);
  5433.         ::PaintRect(&theFrame);
  5434.     
  5435.         StClipRgnState theClipSaver(theFrame);
  5436.         StColorState::Normalize();
  5437.         
  5438.         theFrame.top -= 5;
  5439.         ::FrameRect(&theFrame);
  5440.  
  5441.         SBooleanRect theBevelSides = { true, false, true, true };    
  5442.         UGraphicGizmos::BevelPartialRect(theFrame, 1, eStdGrayBlack, eStdGrayBlack, theBevelSides);
  5443.         ::InsetRect(&theFrame, 1, 1);
  5444.         UGraphicGizmos::BevelPartialRect(theFrame, 2, theDesc.topBevelColor, theDesc.bottomBevelColor, theBevelSides);
  5445.         }
  5446. #endif
  5447. }
  5448.  
  5449.  
  5450. void CFormatMsgColorAndImageDlog::InitializeDialogControls()
  5451. {
  5452.     LControl *prefCheckBox = (LControl *)FindPaneByID( 'Dflt' );
  5453.     if ( prefCheckBox )
  5454.         prefCheckBox->Hide();
  5455.     
  5456.     CEDDocPropAppearanceContain *contain = (CEDDocPropAppearanceContain *)FindPaneByID( 5210 );
  5457.     if ( contain )
  5458.     {
  5459.         contain->SetContext( GetContext() );
  5460.         contain->ControlsFromPref();
  5461.     }
  5462. }
  5463.  
  5464.  
  5465. Boolean CFormatMsgColorAndImageDlog::CommitChanges( Boolean /* allPanes */ )
  5466. {
  5467.     CEDDocPropAppearanceContain *contain = (CEDDocPropAppearanceContain *)FindPaneByID( 5210 );
  5468.     if ( contain )
  5469.     {
  5470.         EDT_BeginBatchChanges( fContext );
  5471.         contain->PrefsFromControls();
  5472.         EDT_EndBatchChanges( fContext );
  5473.     }
  5474.  
  5475.     return true;
  5476. }
  5477.  
  5478.  
  5479. void CFormatMsgColorAndImageDlog::Help()
  5480. {
  5481.     ShowHelp( HELP_DOC_PROPS_APPEARANCE );
  5482. }
  5483.  
  5484.  
  5485. /**********************************************************/
  5486. #pragma mark -
  5487. #pragma mark Modal Dialogs
  5488.  
  5489. // This is a total hack because I'm in a hurry and this has to be a modal dialog. Please rewrite soon!
  5490.  
  5491. void SetItemValue(DialogRef theDialog, short itemNo, short value);
  5492. void SetItemValue(DialogRef theDialog, short itemNo, short value)
  5493. {
  5494.     Rect so;
  5495.     ControlHandle    theControl;
  5496.     short    type;
  5497.     GetDialogItem(theDialog, itemNo, &type, (Handle *)&theControl, &so);
  5498.     if (type != kCheckBoxDialogItem) return;
  5499.     SetControlValue(theControl, value);
  5500. }
  5501.  
  5502.  
  5503. static void InformOfLimit(int min, int max)
  5504. {
  5505.     Str31 minstr, maxstr;
  5506.  
  5507.     NumToString( min, minstr );
  5508.     NumToString( max, maxstr );
  5509.     HandleModalDialog( EDITDLG_LIMITS, minstr, maxstr);
  5510. }
  5511.  
  5512.  
  5513. static Boolean IsEditFieldWithinLimits(LGAEditField* editField, int minVal, int maxVal )
  5514. {
  5515.     short value = editField->GetValue();
  5516.     if ( value < minVal || value > maxVal )
  5517.     {
  5518.         InformOfLimit( minVal, maxVal );
  5519.         return FALSE;
  5520.     }
  5521.     
  5522.     return TRUE;
  5523. }
  5524.  
  5525.  
  5526. #define ED_SAVE_OVERWRITE_THIS_BUTTON 1
  5527. #define ED_SAVE_OVERWRITE_ALL_BUTTON 2
  5528. #define ED_SAVE_DONT_OVERWRITE_THIS_BUTTON 3
  5529. #define ED_SAVE_DONT_OVERWRITE_ALL_BUTTON 4
  5530. #define ED_SAVE_CANCEL_BUTTON 5
  5531.  
  5532. ED_SaveOption FE_SaveFileExistsDialog( MWContext * /* pContext */, char* pFileName )
  5533. {
  5534.     Str255    pFileNameCopy;
  5535.     
  5536.     if ( pFileName )
  5537.     {    // should use the string classes and manipulation routines and clean up this mess!!!
  5538.         char *shorter = WH_FileName(pFileName, xpURL);
  5539.         if (!shorter)
  5540.             return ED_SAVE_CANCEL;
  5541.         BlockMoveData(shorter, pFileNameCopy, strlen(shorter) + 1);
  5542.         XP_FREE(shorter);
  5543.         c2pstr((char*)pFileNameCopy);
  5544.     }
  5545.  
  5546.     switch (HandleModalDialog( EDITDLG_SAVE_FILE_EXISTS, pFileNameCopy, NULL ))
  5547.     {
  5548.         case ED_SAVE_OVERWRITE_THIS_BUTTON:            return ED_SAVE_OVERWRITE_THIS;        break;
  5549.         case ED_SAVE_OVERWRITE_ALL_BUTTON:            return ED_SAVE_OVERWRITE_ALL;        break;
  5550.         case ED_SAVE_DONT_OVERWRITE_THIS_BUTTON:    return ED_SAVE_DONT_OVERWRITE_THIS;    break;
  5551.         case ED_SAVE_DONT_OVERWRITE_ALL_BUTTON:        return ED_SAVE_DONT_OVERWRITE_ALL;    break;
  5552.         case ED_SAVE_CANCEL_BUTTON:                    return ED_SAVE_CANCEL;                break;
  5553.     }
  5554.     
  5555.     return ED_SAVE_CANCEL;    // shouldn't get here...
  5556. }
  5557.