home *** CD-ROM | disk | FTP | other *** search
/ Tools / WinSN5.0Ver.iso / NETSCAP.50 / WIN1998.ZIP / ns / cmd / macfe / Composer / CEditorWindow.cp < prev    next >
Encoding:
Text File  |  1998-04-08  |  17.8 KB  |  611 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 "CEditorWindow.h"
  20. #include "CBrowserContext.h"
  21. #include "resgui.h"
  22. #include "CFormattingToolBar.h"
  23. #include "CFontMenuAttachment.h"
  24. #include "CToolbarPopup.h"
  25. #include "CPatternButtonPopupText.h"
  26. #include "COpenRecentlyEditedPopup.h"
  27. #include "CColorPopup.h"
  28.  
  29. #include "CEditDictionary.h"
  30.  
  31. #include "CTextTable.h"
  32. #include "CTableKeySingleSelector.h"
  33.  
  34.     // macfe
  35. #include "mversion.h"    // ID_STRINGS
  36. #include "URobustCreateWindow.h"
  37. #include "uprefd.h"
  38. #include "uerrmgr.h"
  39. #include "uapp.h"
  40. #include "meditdlg.h"    // CTabbedDialog
  41. #include "meditor.h"    // HandleModalDialog
  42. #include "CEditView.h"
  43.  
  44.     // Netscape
  45. #include "net.h"    // NET_cinfo_find_type
  46. #include "proto.h"    // XP_IsContextBusy
  47. #include "edt.h"
  48. #include "shist.h"
  49. #include "prefapi.h"    // PREF_GetBoolPref
  50.  
  51. #ifdef PROFILE
  52. #pragma profile on
  53. #endif
  54.  
  55. // pane id constants - for ShowOneDragBar
  56. const PaneIDT Paragraph_Bar_PaneID = 'DBar';
  57. const PaneIDT Character_Bar_PaneID = 'NBar';
  58.  
  59. const char* Pref_ShowParagraphBar = "editor.show_paragraph_toolbar";
  60. const char* Pref_ShowCharacterBar = "editor.show_character_toolbar";
  61.  
  62. enum {  eParagraphBar,
  63.         eCharacterBar    };
  64.  
  65. CEditorWindow::CEditorWindow( LStream* inStream )
  66.     :CBrowserWindow(inStream)
  67. {
  68.     SetWindowType( WindowType_Editor );
  69. }
  70.  
  71.  
  72. static    // PRIVATE
  73. CMediatedWindow* GetFrontWindowByType( OSType windowType )
  74. {
  75.     CMediatedWindow* theWindow = NULL;
  76.     CWindowIterator iter(windowType);
  77.     iter.Next(theWindow);
  78.     return theWindow;
  79. }
  80.  
  81. // given an mwcontext (non-busy, with a history), select the matching editor window
  82. // or open an editor window based on that mwcontext
  83. // if all else fails (and memory is not low), create an empty editor window
  84. void CEditorWindow::MakeEditWindowFromBrowser( MWContext* mwcontext )
  85. {
  86.     if ( Memory_MemoryIsLow() )
  87.         return;
  88.     
  89.     History_entry*    entry = NULL;
  90.     if ( mwcontext && !XP_IsContextBusy( mwcontext ) )
  91.         entry = SHIST_GetCurrent(&mwcontext->hist);
  92.     
  93.     if ( entry && entry->address)
  94.     {
  95.         // If there is already an editor window open for this url 
  96.         // just switch to it and keep this browser window open.
  97.         CMediatedWindow * win;
  98.         CWindowIterator iter(WindowType_Editor);
  99.         while (iter.Next(win))
  100.         {
  101.             CNSContext* curContext = ((CBrowserWindow *)win)->GetWindowContext();
  102.             MWContext*    context;
  103.             
  104.             context = curContext ? curContext->operator MWContext*() : NULL;
  105.             if (context && EDT_IS_EDITOR(context))
  106.             {
  107.                 History_entry*    newEntry = SHIST_GetCurrent(&context->hist);
  108.                 if (newEntry && newEntry->address && !strcmp(newEntry->address, entry->address))
  109.                 {
  110.                     win->Show();
  111.                     win->Select();
  112.                     return;
  113.                 }
  114.             }
  115.         }
  116.         
  117.         if (CEditorWindow::MakeEditWindow(mwcontext, NULL) == NULL)     // new window based on history of this window
  118.             return;        // don't close this one on error.
  119.     }
  120.     else
  121.     {
  122.         CEditorWindow::MakeEditWindow(NULL, NULL);    // make a completely new window
  123.     }
  124. }
  125.  
  126.  
  127. // EDT_PreOpenCallbackFn 
  128. static void createEditorWindowCallback( XP_Bool userCanceled, char* pURL, void* hook )
  129. {
  130.     if ( !userCanceled )
  131.     {
  132.         EditorCreationStruct *edtCreatePtr = (EditorCreationStruct *)hook;
  133.         
  134.         if ( hook )
  135.         {
  136.             if ( edtCreatePtr->existingURLstruct && edtCreatePtr->existingURLstruct->address )
  137.             {
  138.                 XP_FREE( edtCreatePtr->existingURLstruct->address );
  139.                 edtCreatePtr->existingURLstruct->address = XP_STRDUP( pURL );
  140.             }
  141.         }
  142.         
  143.         // substitute new URL
  144.         CEditorWindow::CreateEditorWindowStage2( edtCreatePtr );
  145.     }
  146. }
  147.  
  148.  
  149. CEditorWindow* CEditorWindow::MakeEditWindow( MWContext* old_context, URL_Struct* url )
  150. {
  151.     Boolean urlCameInNULL = (url == NULL);
  152.     
  153.     // if we don't have an URL, try to get it from the old_context's window history
  154.     if (url == NULL && old_context != NULL)
  155.     {
  156.         CBrowserContext *browserContext = (CBrowserContext *)old_context->fe.newContext;
  157.         History_entry*    entry = browserContext->GetCurrentHistoryEntry();    // Take the last instead of the first history entry.
  158.         if ( entry )
  159.         {
  160.             url = SHIST_CreateURLStructFromHistoryEntry( old_context, entry );
  161.             if ( url )
  162.                 url->force_reload = NET_NORMAL_RELOAD;
  163.         }
  164.         // if we don't have a history entry, we're kind of screwed-->just load a blank page
  165.     }
  166.  
  167.     // we want to open a new blank edit window
  168.     // or we are still having troubles... fall back to our old tried and true blank page
  169.     if (url == NULL)
  170.         url = NET_CreateURLStruct ("about:editfilenew", NET_NORMAL_RELOAD );
  171.                 // FIX THIS!!! the above line should use "XP_GetString(XP_EDIT_NEW_DOC_NAME)"
  172.  
  173.     // time of reckoning. We really, really need an URL and address at this point...
  174.     // I don't know what an url without an address is anyway...
  175.     if (url == NULL || url->address == NULL)
  176.         return NULL;
  177.     
  178.     // now make sure that the url is a valid type to edit.
  179.     NET_cinfo *cinfo = NET_cinfo_find_type (url->address);
  180.     
  181.     if (cinfo == NULL || cinfo->type == NULL ||
  182.           (strcasecomp (cinfo->type, TEXT_HTML)
  183.         && strcasecomp (cinfo->type, UNKNOWN_CONTENT_TYPE)
  184.         && strcasecomp (cinfo->type, TEXT_PLAIN)))
  185.     {
  186.         ErrorManager::PlainAlert( NOT_HTML );
  187.         return NULL;
  188.     }
  189.  
  190.     EditorCreationStruct *edtCreatePtr = (EditorCreationStruct *)XP_ALLOC( sizeof( EditorCreationStruct ) );
  191.     if ( edtCreatePtr )
  192.     {
  193.         edtCreatePtr->context = old_context;
  194.         edtCreatePtr->existingURLstruct = url;
  195.         edtCreatePtr->isEmptyPage = old_context == NULL && urlCameInNULL;
  196.     }
  197.         
  198.     if ( urlCameInNULL && old_context == NULL )
  199.     {
  200.         return CreateEditorWindowStage2( edtCreatePtr );
  201.     }
  202.     else
  203.     {
  204.         EDT_PreOpen( old_context, url->address, createEditorWindowCallback, edtCreatePtr );
  205.         return NULL;
  206.     }
  207. }
  208.  
  209.  
  210. CEditorWindow *CEditorWindow::CreateEditorWindowStage2( EditorCreationStruct *edtCreatePtr )
  211. {
  212.     // now we can create an editor window since we don't already have one for this url.
  213.     
  214.     /* instead of just calling LWindow::CreateWindow(), we do it ourselves by hand here 
  215.      * so that we can set the window bounds before we call FinishCreate().
  216.      */
  217.     
  218.     if ( edtCreatePtr == NULL )
  219.         return NULL;
  220.     
  221.     CEditorWindow* newWindow = NULL;
  222.     SetDefaultCommander(CFrontApp::GetApplication());
  223.     try {
  224.         OSErr    error;
  225.         URobustCreateWindow::ReadObjects( 'PPob', CEditorWindow::res_ID, &newWindow, &error );
  226.         Assert_(newWindow);
  227.         FailOSErr_(error);
  228.         if (newWindow == NULL)
  229.         {
  230.             XP_FREE( edtCreatePtr );
  231.             return NULL;
  232.         }
  233.  
  234.         newWindow->FinishCreate();
  235.         if (newWindow->HasAttribute(windAttr_ShowNew))
  236.             newWindow->Show();
  237.  
  238.         UReanimator::LinkListenerToControls( newWindow, newWindow, CEditorWindow::res_ID );
  239.     }
  240.     catch(...)
  241.     {
  242.         if ( newWindow )
  243.             delete newWindow;
  244.         
  245.         XP_FREE( edtCreatePtr );
  246.         
  247.         return NULL;
  248.     }
  249.     
  250.     Boolean hasURLstruct = edtCreatePtr->existingURLstruct && edtCreatePtr->existingURLstruct->address;
  251.     CBrowserContext *nscontext = new CBrowserContext();
  252.     newWindow->SetWindowContext( nscontext );
  253.     
  254.     CURLDispatcher::DispatchURL( edtCreatePtr->existingURLstruct, nscontext, false, false, CEditorWindow::res_ID );
  255.     
  256.     if ( edtCreatePtr->context )
  257.     {
  258.         nscontext->InitHistoryFromContext( (CBrowserContext *)edtCreatePtr->context->fe.newContext );
  259.     }
  260.     else
  261.     {
  262.         // the url will eventually be freed when the load is complete.
  263.     }
  264.  
  265.     // set window title here (esp. for "open")
  266.     if ( !edtCreatePtr->isEmptyPage
  267.     && edtCreatePtr->existingURLstruct && edtCreatePtr->existingURLstruct->address )
  268.     {
  269.         char *pSlash = strrchr( edtCreatePtr->existingURLstruct->address, '/' );
  270.         if ( pSlash )
  271.             pSlash += 1;    // move past '/'
  272.         newWindow->NoteDocTitleChanged( pSlash );
  273.     }
  274.     
  275.     XP_FREE( edtCreatePtr );
  276.     
  277.     return newWindow;
  278. }
  279.  
  280.         
  281. void CEditorWindow::SetWindowContext(CBrowserContext* inContext)
  282. {
  283.     if ( inContext )
  284.     {
  285.         MWContext *context;
  286.         context = inContext->operator MWContext*();
  287.         if ( context )
  288.         {
  289.             context->is_editor = true;
  290.             NET_CheckForTimeBomb( context );
  291.         }
  292.     }
  293.  
  294.     CBrowserWindow::SetWindowContext( inContext );
  295. }
  296.  
  297.  
  298. void CEditorWindow::NoteDocTitleChanged( const char* inNewTitle )
  299. {
  300.     // there is one bogus set-title from layout that we want to skip...
  301.     // We are hard coding "editfilenew" here because it is already hardcoded 
  302.     // a million other places...
  303.     if ( inNewTitle && XP_STRCMP( inNewTitle, "editfilenew" ) == 0 )
  304.         return;
  305.  
  306.     CNSContext *theContext = GetWindowContext();
  307.     
  308.     CStr255     title( inNewTitle );
  309.     char *baseName = LO_GetBaseURL( theContext->operator MWContext*() );    // don't free this...
  310.     // strip out username and password so user doesn't see them in window title
  311.     char *location = NULL;
  312.     if ( baseName )
  313.         NET_ParseUploadURL( baseName, &location, NULL, NULL );
  314.     CStr255    csBaseURL(location);
  315.     // if this page has a local "file:" url, then just show the file name (skip the url and directory crap.)
  316.     
  317.     if ( location && NET_IsLocalFileURL(location) )
  318.     {
  319.         char *localName = NULL;
  320.         XP_ConvertUrlToLocalFile( location, &localName );
  321.         
  322.         if (localName)
  323.         {
  324. #if 0
  325.             char *pSlash = strrchr(localName, '/');
  326.             if (pSlash)
  327.             {        // is there is a slash, move everything AFTER the last slash to the front
  328.                 pSlash++;
  329.                 XP_STRCPY(localName, pSlash);
  330.             }
  331. #endif
  332.  
  333.             csBaseURL = localName;
  334.             XP_FREE(localName);
  335.         }
  336.     }
  337.     
  338.     CStr255     netscapeTitle;
  339.     CStr255        subTitle;
  340.     
  341.     ::GetIndString( netscapeTitle, ID_STRINGS, APPNAME_STRING_INDEX );
  342.     ::GetIndString( subTitle, WINDOW_TITLES_RESID, 3 );
  343.     
  344.     netscapeTitle += " ";
  345.     netscapeTitle += subTitle;
  346.     netscapeTitle += " - [";
  347.     if ( inNewTitle && *inNewTitle )
  348.     {
  349.         netscapeTitle += title;
  350.         if (csBaseURL.Length())
  351.             netscapeTitle += " : ";
  352.     }
  353.     netscapeTitle += csBaseURL;
  354.     netscapeTitle += "]";
  355.  
  356.     SetDescriptor( netscapeTitle );
  357.  
  358.     if ( location )
  359.         XP_FREE( location );
  360. }
  361.  
  362.  
  363. void CEditorWindow::RegisterViewTypes()
  364. {
  365.     // Registers all its view types
  366.     RegisterClass_( CEditorWindow);
  367.     RegisterClass_( CEditView);
  368.     RegisterClass_( MultipleSelectionSingleColumn);    // newer, better class?
  369.     RegisterClass_( CTarget);
  370.     RegisterClass_( CLineProp);
  371.     RegisterClass_( CFormattingToolBar);
  372.     
  373.     RegisterClass_( CToolbarPopup);                    // newer, better class?
  374.     RegisterClass_( CIconToolbarPopup);                // newer, better class?
  375.     RegisterClass_( CColorPopup);
  376.     RegisterClass_( CFontMenuPopup );
  377.     
  378.     RegisterClass_( CChameleonCaption);                // newer, better class?
  379.     RegisterClass_( CChameleonView);                // newer, better class?
  380.     CTabbedDialog::RegisterViewTypes();
  381.     
  382.     RegisterClass_( CTextTable);                    // newer, better class?
  383.     RegisterClass_( CTableKeySingleSelector);        // newer, better class?
  384.  
  385.     RegisterClass_( CPatternButtonPopupText);        // newer, better class?
  386.     RegisterClass_( LOffscreenView);
  387.     RegisterClass_( COpenRecentlyEditedPopup );
  388.     
  389.     RegisterClass_( CEditDictionary);
  390.     RegisterClass_( CEditDictionaryTable);    
  391. }
  392.  
  393.  
  394. void CEditorWindow::FinishCreateSelf()
  395. {
  396.     CBrowserWindow::FinishCreateSelf();
  397.  
  398.     // Show/hide toolbars based on preference settings
  399.     XP_Bool    value;
  400.     PREF_GetBoolPref(Pref_ShowParagraphBar, &value);
  401.     mToolbarShown[eParagraphBar] = value;
  402.     ShowOneDragBar(Paragraph_Bar_PaneID, value);
  403.     PREF_GetBoolPref(Pref_ShowCharacterBar, &value);
  404.     mToolbarShown[eCharacterBar] = value;
  405.     ShowOneDragBar(Character_Bar_PaneID, value);
  406. }
  407.  
  408.  
  409. void CEditorWindow::ListenToMessage( MessageT inMessage, void* ioParam )
  410. {
  411.     switch (inMessage)
  412.     {
  413.         case msg_NSCDocTitleChanged:
  414.             NoteDocTitleChanged((const char*)ioParam);
  415.             break;
  416.     
  417.         default:
  418.         {
  419.             if ( inMessage == 'Para' )
  420.             {
  421.                 switch  (*(long*)ioParam)
  422.                 {
  423.                     case 1:        inMessage = cmd_Format_Paragraph_Normal;        break;
  424.                     case 2:        inMessage = cmd_Format_Paragraph_Head1;            break;
  425.                     case 3:        inMessage = cmd_Format_Paragraph_Head2;            break;
  426.                     case 4:        inMessage = cmd_Format_Paragraph_Head3;            break;
  427.                     case 5:        inMessage = cmd_Format_Paragraph_Head4;            break;
  428.                     case 6:        inMessage = cmd_Format_Paragraph_Head5;            break;
  429.                     case 7:        inMessage = cmd_Format_Paragraph_Head6;            break;
  430.                     case 8:        inMessage = cmd_Format_Paragraph_Address;        break;
  431.                     case 9:        inMessage = cmd_Format_Paragraph_Formatted;        break;
  432.                     case 10:    inMessage = cmd_Format_Paragraph_List_Item;        break;
  433.                     case 11:    inMessage = cmd_Format_Paragraph_Desc_Title;    break;
  434.                     case 12:    inMessage = cmd_Format_Paragraph_Desc_Text;        break;
  435.                 }
  436.             }
  437.             else if ( inMessage == 'Size' )
  438.             {
  439.                 switch  (*(long*)ioParam)
  440.                 {
  441.                     case 1:        inMessage = cmd_Format_Font_Size_N2;    break;
  442.                     case 2:        inMessage = cmd_Format_Font_Size_N1;    break;
  443.                     case 3:        inMessage = cmd_Format_Font_Size_0;        break;
  444.                     case 4:        inMessage = cmd_Format_Font_Size_P1;    break;
  445.                     case 5:        inMessage = cmd_Format_Font_Size_P2;    break;
  446.                     case 6:        inMessage = cmd_Format_Font_Size_P3;    break;
  447.                     case 7:        inMessage = cmd_Format_Font_Size_P4;    break;
  448.                 }
  449.             }
  450.             else if ( inMessage == 'Algn' )
  451.             {
  452.                 switch  (*(long*)ioParam)
  453.                 {
  454.                     case 1:        inMessage = cmd_JustifyLeft;    break;
  455.                     case 2:        inMessage = cmd_JustifyCenter;    break;
  456.                     case 3:        inMessage = cmd_JustifyRight;    break;
  457.                 }
  458.             }
  459.  
  460.             // GetHTMLView() guaranteed not to fail
  461.             GetHTMLView()->ObeyCommand( inMessage, ioParam );
  462.             break;
  463.         }
  464.     }
  465. }
  466.  
  467.  
  468. // EDT_PreCloseCallbackFn 
  469. static void closeEditorWindowCallback( void* hook )
  470. {
  471.     CEditorWindow *editorWindow = (CEditorWindow *)hook;
  472.     if ( editorWindow )
  473.         editorWindow->SetPluginDoneClosing();
  474. }
  475.  
  476.  
  477. Boolean CEditorWindow::ObeyCommand( CommandT inCommand, void *ioParam )
  478. {
  479.     switch ( inCommand )
  480.     {
  481.         case cmd_NewWindowEditor:
  482.             CEditorWindow::MakeEditWindow( NULL, NULL );
  483.             break;
  484.         
  485.         case cmd_ViewSource:
  486.             // Delegate this to the view.
  487.             if ( ((CEditView *)GetHTMLView())->IsDoneLoading() )
  488.                 GetHTMLView()->ObeyCommand(inCommand, ioParam);
  489.             break;
  490.                 
  491.         case cmd_Toggle_Paragraph_Toolbar:
  492.             ToggleDragBar(Paragraph_Bar_PaneID, eParagraphBar, Pref_ShowParagraphBar);
  493.             break;
  494.         
  495.         case cmd_Toggle_Character_Toolbar:
  496.             ToggleDragBar(Character_Bar_PaneID, eCharacterBar, Pref_ShowCharacterBar);
  497.             break;
  498.  
  499.         case cmd_Close:
  500.         case cmd_Quit:                // we'll just intercept these and then send them on to the default case
  501.             MWContext *mwcontext = GetWindowContext()->operator MWContext*();
  502.             History_entry*    newEntry = SHIST_GetCurrent(&mwcontext->hist);
  503.             CStr255 fileName;
  504.             if ( newEntry && newEntry->address )
  505.                 fileName = newEntry->address;
  506.                 
  507.             if ( ((CEditView *)GetHTMLView())->IsDoneLoading() && EDT_DirtyFlag( *GetWindowContext() ) )
  508.             {
  509.                 Select(); // This helps during a quit or "close all"
  510.                 
  511.                 MessageT itemHit = HandleModalDialog( EDITDLG_SAVE_BEFORE_QUIT, fileName, NULL );
  512.                 if (itemHit == cancel)
  513.                     return true;
  514.                 
  515.                 if (itemHit == ok)
  516.                 {                // save
  517.                     if ( !((CEditView *)GetHTMLView())->SaveDocument() )
  518.                         return true;            
  519.                 }
  520.                 EDT_SetDirtyFlag( mwcontext, false );        // we have to do this or else when we quit, we will be asked twice to save
  521.             }
  522.             
  523.             // need to let this work asynchronously; make our own internal loop
  524.             if ( ((CEditView *)GetHTMLView())->IsDoneLoading() && newEntry && newEntry->address )
  525.             {
  526.                 mPluginDoneClosing = false;
  527.                 EDT_PreClose( mwcontext, newEntry->address, closeEditorWindowCallback, this );
  528.                 
  529.                 do
  530.                 {
  531.                     CFrontApp::GetApplication()->ProcessNextEvent();
  532.                 } while ( !mPluginDoneClosing );
  533.             }
  534.  
  535.         // fall through
  536.  
  537.         default:
  538.         {
  539.             return CBrowserWindow::ObeyCommand (inCommand, ioParam);
  540.         }
  541.     }
  542.     return TRUE;
  543. }
  544.  
  545.  
  546. void CEditorWindow::FindCommandStatus( CommandT inCommand,
  547.     Boolean& outEnabled, Boolean& outUsesMark, Char16& outMark,
  548.     Str255 outName )
  549. {
  550.     short index;
  551.     outUsesMark = FALSE;
  552.     outEnabled = false;
  553.  
  554.     switch ( inCommand )
  555.     {
  556.         case cmd_ViewSource:
  557.             // Delegate this to the view.
  558.             if ( ((CEditView *)GetHTMLView())->IsDoneLoading() )
  559.                 GetHTMLView()->FindCommandStatus(inCommand, outEnabled, outUsesMark, outMark, outName);
  560.             break;
  561.  
  562.         case cmd_Toggle_Character_Toolbar:
  563.             outEnabled = ((CEditView *)GetHTMLView())->IsDoneLoading();
  564.             index = mToolbarShown[eCharacterBar] ? CEditView::EDITOR_MENU_HIDE_COMP_TOOLBAR 
  565.                                             : CEditView::EDITOR_MENU_SHOW_COMP_TOOLBAR;
  566.             ::GetIndString( outName, CEditView::STRPOUND_EDITOR_MENUS, index );
  567.             break;
  568.  
  569.         case cmd_Toggle_Paragraph_Toolbar:
  570.             outEnabled = ((CEditView *)GetHTMLView())->IsDoneLoading();
  571.             index = mToolbarShown[eParagraphBar] ? CEditView::EDITOR_MENU_HIDE_FORMAT_TOOLBAR 
  572.                                             : CEditView::EDITOR_MENU_SHOW_FORMAT_TOOLBAR;
  573.             ::GetIndString( outName, CEditView::STRPOUND_EDITOR_MENUS, index );
  574.             break;
  575.  
  576.         default:
  577.             CBrowserWindow::FindCommandStatus(inCommand, outEnabled, outUsesMark, outMark, outName );
  578.     }
  579. }
  580.  
  581.  
  582. // Called when we are trying to quit the application
  583. Boolean    CEditorWindow::AttemptQuitSelf( long inSaveOption )
  584. {
  585.     MWContext *mwcontext = GetWindowContext()->operator MWContext*();
  586.     if ( EDT_DirtyFlag( mwcontext ) )
  587.     {
  588.         History_entry*    newEntry = SHIST_GetCurrent(&mwcontext->hist);
  589.         CStr255 fileName;
  590.         if ( newEntry && newEntry->address )
  591.             fileName = newEntry->address;
  592.  
  593.         if ( kAEAsk == inSaveOption )
  594.         {
  595.             MessageT itemHit = HandleModalDialog( EDITDLG_SAVE_BEFORE_QUIT, fileName, NULL );
  596.             if ( cancel == itemHit )
  597.                 return false;
  598.         }
  599.         
  600.         // save
  601.         if ( !((CEditView *)GetHTMLView())->SaveDocument() ) 
  602.             return false;            
  603.     }
  604.     
  605.     return true;
  606. }
  607.  
  608. #ifdef PROFILE
  609. #pragma profile off
  610. #endif
  611.