WebCore:
authorbdakin <bdakin@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 16 Dec 2006 09:33:51 +0000 (09:33 +0000)
committerbdakin <bdakin@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 16 Dec 2006 09:33:51 +0000 (09:33 +0000)
        Reviewed by Adam (and partially Geoff).

        Primarily, this patch gives WebCore context menus the ability to
        enable/disable and set state. It does a few other things along the
        way, though. Some of the more noticeable things:
               -Re-architects the ContextMenuItem class a bit so that the
                ownership model is a bit less confusing. ContextMenuItem is
                now *purely* a wrapper for the platformDescription. There
                are no other member variables. If you ever need the
                platformDescription outside of the MenuItem class, you have
                to call releasePlatformDescription(), which transfers
                ownership of the platformDescription to the caller.
               -Moves fontForSelection() from FrameMac into Editor.cpp.
                Turns out I don't need to use this function for my patch
                after all, but it doesn't seem like a terrible idea to move
                it anyway since we seem to be moving things from FrameMac
                into Editor these days anyway.
WebKit:
        Reviewed by Adam.

        WebKit side of making WebCore context menus support state and
        enabled/disabled.

        * WebCoreSupport/WebContextMenuClient.h: contextMenuItemSelected
        takes a pointer to the parentMenu now since menu items no longer
        hold onto it.
        * WebCoreSupport/WebContextMenuClient.mm: Same.
        (WebContextMenuClient::contextMenuItemSelected): Same.
        * WebView/WebHTMLView.m: Must call setAutoenablesItems:NO on our
        menu.
        (-[NSArray menuForEvent:]):
        * WebView/WebUIDelegatePrivate.h: No need for if-def.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@18245 268f45cc-cd09-0410-ab3c-d52691b4dbfc

21 files changed:
WebCore/ChangeLog
WebCore/WebCore.exp
WebCore/editing/Editor.cpp
WebCore/editing/Editor.h
WebCore/editing/mac/EditorMac.mm
WebCore/page/ContextMenuClient.h
WebCore/page/ContextMenuController.cpp
WebCore/page/mac/FrameMac.h
WebCore/page/mac/FrameMac.mm
WebCore/page/mac/WebCoreFrameBridge.mm
WebCore/platform/ContextMenu.cpp
WebCore/platform/ContextMenu.h
WebCore/platform/ContextMenuItem.h
WebCore/platform/cf/RetainPtr.h
WebCore/platform/mac/ContextMenuItemMac.mm
WebCore/platform/mac/ContextMenuMac.mm
WebKit/ChangeLog
WebKit/WebCoreSupport/WebContextMenuClient.h
WebKit/WebCoreSupport/WebContextMenuClient.mm
WebKit/WebView/WebHTMLView.m
WebKit/WebView/WebUIDelegatePrivate.h

index 9abc3819fbaed4c84d711b4ccda8e51bdac5bfa0..417b2159ca2553e2138cd85f20163dd40ddd4bed 100644 (file)
@@ -1,3 +1,73 @@
+2006-12-16  Beth Dakin  <bdakin@apple.com>
+
+        Reviewed by Adam (and partially Geoff).
+
+        Primarily, this patch gives WebCore context menus the ability to
+        enable/disable and set state. It does a few other things along the
+        way, though. Some of the more noticeable things:
+               -Re-architects the ContextMenuItem class a bit so that the
+                ownership model is a bit less confusing. ContextMenuItem is
+                now *purely* a wrapper for the platformDescription. There
+                are no other member variables. If you ever need the
+                platformDescription outside of the MenuItem class, you have
+                to call releasePlatformDescription(), which transfers
+                ownership of the platformDescription to the caller.
+               -Moves fontForSelection() from FrameMac into Editor.cpp.
+                Turns out I don't need to use this function for my patch
+                after all, but it doesn't seem like a terrible idea to move
+                it anyway since we seem to be moving things from FrameMac
+                into Editor these days anyway.
+
+        * WebCore.exp:
+        * editing/Editor.cpp:
+        (WebCore::Editor::fontForSelection): Moved in from FrameMac.
+        * editing/Editor.h: Same, and name change.
+        * editing/mac/EditorMac.mm: Name change.
+        * page/ContextMenuClient.h: contextMenuItemSelected() has to take a
+        pointer to the parent context menu since ContextMenuItem no longer
+        holds on to it.
+        * page/ContextMenuController.cpp: Same.
+        (WebCore::ContextMenuController::contextMenuItemSelected): Same.
+        * page/mac/FrameMac.h: Move fontForSelection to Editor
+        * page/mac/FrameMac.mm: Same.
+        * page/mac/WebCoreFrameBridge.mm:
+        (-[WebCoreFrameBridge fontForSelection:]): Account for above.
+        * platform/ContextMenu.cpp:
+        (WebCore::separatorItem): Can't be const because appendItem now
+        expects a non-const menu item.
+        (WebCore::createAndAppendFontSubMenu): Change name for clarity.
+        (WebCore::createAndAppendSpellingAndGrammarSubMenu): Same.
+        (WebCore::createAndAppendSpellingSubMenu): Same.
+        (WebCore::createAndAppendSpeechSubMenu): Same.
+        (WebCore::createAndAppendWritingDirectionSubMenu): Same.
+        (WebCore::ContextMenu::populate): Account for above.
+        (WebCore::triStateToBool): New helper.
+        (WebCore::ContextMenu::checkOrEnableIfNeeded): Transfers
+        logic from WebHTMLView into WebCore to determine if menu items are
+        enabled or disabled and to determine if they require a check.
+        * platform/ContextMenu.h:
+        * platform/ContextMenuItem.h: Re-factored stuff so that our only
+        member variable is the platform description.
+        (WebCore::): Get rid of if-def.
+        * platform/cf/RetainPtr.h: Add releaseRef like in PassRefPtr.
+        (WebCore::RetainPtr::releaseRef):
+        * platform/mac/ContextMenuItemMac.mm: Same as .h
+        (WebCore::ContextMenuItem::ContextMenuItem): Same.
+        (WebCore::ContextMenuItem::releasePlatformDescription): Same.
+        (WebCore::ContextMenuItem::type): Same.
+        (WebCore::ContextMenuItem::platformSubMenu): Same.
+        (WebCore::ContextMenuItem::setType): Same.
+        (WebCore::ContextMenuItem::setTitle): Same.
+        (WebCore::ContextMenuItem::setSubMenu): Same.
+        (WebCore::ContextMenuItem::setChecked): Same.
+        (WebCore::ContextMenuItem::setEnabled): Same.
+        * platform/mac/ContextMenuMac.mm:
+        (-[WebCoreMenuTarget forwardContextMenuAction:]): Don't set the
+        parent menu.
+        (WebCore::setMenuItemTarget):
+        (WebCore::ContextMenu::appendItem): Call releasePlatformDescription
+        (WebCore::ContextMenu::insertItem): Same.
+
 2006-12-15  MorganL  <morganl.webkit@yahoo.com>
 
         Reviewed by Oliver.
 2006-12-15  MorganL  <morganl.webkit@yahoo.com>
 
         Reviewed by Oliver.
index 08bc6d1f31879eddbaaad13da1da00b56ce4f8ef..bf8bcbdd63c4ae2f8467733d87a70582216dfc3f 100644 (file)
@@ -206,6 +206,7 @@ __ZN7WebCore14DocumentLoaderD2Ev
 __ZN7WebCore14RenderListItem17markerStringValueEv
 __ZN7WebCore14ResourceHandle12releaseProxyEv
 __ZN7WebCore14ResourceLoader14cancelledErrorEv
 __ZN7WebCore14RenderListItem17markerStringValueEv
 __ZN7WebCore14ResourceHandle12releaseProxyEv
 __ZN7WebCore14ResourceLoader14cancelledErrorEv
+__ZN7WebCore15ContextMenuItem26releasePlatformDescriptionEv
 __ZN7WebCore16DeprecatedString6appendENS_14DeprecatedCharE
 __ZN7WebCore16DeprecatedString6appendERKS0_
 __ZN7WebCore16DeprecatedString6appendEc
 __ZN7WebCore16DeprecatedString6appendENS_14DeprecatedCharE
 __ZN7WebCore16DeprecatedString6appendERKS0_
 __ZN7WebCore16DeprecatedString6appendEc
@@ -265,8 +266,8 @@ __ZN7WebCore6Editor32guessesForUngrammaticalSelectionEv
 __ZN7WebCore6Editor3cutEv
 __ZN7WebCore6Editor4copyEv
 __ZN7WebCore6Editor5pasteEv
 __ZN7WebCore6Editor3cutEv
 __ZN7WebCore6Editor4copyEv
 __ZN7WebCore6Editor5pasteEv
-__ZN7WebCore6Editor7copyURLERKNS_4KURLERKNS_6StringE
 __ZN7WebCore6Editor6indentEv
 __ZN7WebCore6Editor6indentEv
+__ZN7WebCore6Editor7copyURLERKNS_4KURLERKNS_6StringE
 __ZN7WebCore6Editor7outdentEv
 __ZN7WebCore6StringC1EP8NSString
 __ZN7WebCore6StringC1EPKc
 __ZN7WebCore6Editor7outdentEv
 __ZN7WebCore6StringC1EP8NSString
 __ZN7WebCore6StringC1EPKc
@@ -368,7 +369,6 @@ __ZNK7WebCore14DocumentLoader8responseEv
 __ZNK7WebCore14DocumentLoader9isLoadingEv
 __ZNK7WebCore14ResourceHandle10connectionEv
 __ZNK7WebCore14ResourceLoader11frameLoaderEv
 __ZNK7WebCore14DocumentLoader9isLoadingEv
 __ZNK7WebCore14ResourceHandle10connectionEv
 __ZNK7WebCore14ResourceLoader11frameLoaderEv
-__ZNK7WebCore15ContextMenuItem19platformDescriptionEv
 __ZNK7WebCore15ResourceRequest12nsURLRequestEv
 __ZNK7WebCore15ResourceRequest3urlEv
 __ZNK7WebCore15ResourceRequest7isEmptyEv
 __ZNK7WebCore15ResourceRequest12nsURLRequestEv
 __ZNK7WebCore15ResourceRequest3urlEv
 __ZNK7WebCore15ResourceRequest7isEmptyEv
@@ -444,8 +444,8 @@ _wkClearGlyphVector
 _wkConvertCharToGlyphs
 _wkCreateCustomCFReadStream
 _wkCreateNSURLConnectionDelegateProxy
 _wkConvertCharToGlyphs
 _wkCreateCustomCFReadStream
 _wkCreateNSURLConnectionDelegateProxy
-_wkCreateURLPasteboardFlavorTypeName
 _wkCreateURLNPasteboardFlavorTypeName
 _wkCreateURLNPasteboardFlavorTypeName
+_wkCreateURLPasteboardFlavorTypeName
 _wkDrawBezeledTextArea
 _wkDrawBezeledTextFieldCell
 _wkDrawFocusRing
 _wkDrawBezeledTextArea
 _wkDrawBezeledTextFieldCell
 _wkDrawFocusRing
index c608d3deb0f513037d2a3cc128072655ad69d3fc..3b3c67f7ed08040c5d98c2df90bbc8a86f5e741f 100644 (file)
@@ -43,6 +43,7 @@
 #include "EditorClient.h"
 #include "Event.h"
 #include "EventNames.h"
 #include "EditorClient.h"
 #include "Event.h"
 #include "EventNames.h"
+#include "FontData.h"
 #include "HTMLElement.h"
 #include "HTMLNames.h"
 #include "HitTestResult.h"
 #include "HTMLElement.h"
 #include "HTMLNames.h"
 #include "HitTestResult.h"
@@ -300,6 +301,56 @@ void Editor::respondToChangedContents(const Selection& endingSelection)
     m_deleteButtonController->respondToChangedContents();
 }
 
     m_deleteButtonController->respondToChangedContents();
 }
 
+const FontData* Editor::fontForSelection(bool& hasMultipleFonts) const
+{
+    if (hasMultipleFonts)
+        hasMultipleFonts = false;
+
+    if (!m_frame->selectionController()->isRange()) {
+        Node* nodeToRemove;
+        RenderStyle* style = m_frame->styleForSelectionStart(nodeToRemove); // sets nodeToRemove
+
+        const FontData* result = 0;
+        if (style)
+            result = style->font().primaryFont();
+        
+        if (nodeToRemove) {
+            ExceptionCode ec;
+            nodeToRemove->remove(ec);
+            ASSERT(ec == 0);
+        }
+
+        return result;
+    }
+
+    const FontData* font = 0;
+
+    RefPtr<Range> range = m_frame->selectionController()->toRange();
+    Node* startNode = range->editingStartPosition().node();
+    if (startNode) {
+        Node* pastEnd = range->pastEndNode();
+        // In the loop below, n should eventually match pastEnd and not become nil, but we've seen at least one
+        // unreproducible case where this didn't happen, so check for nil also.
+        for (Node* n = startNode; n && n != pastEnd; n = n->traverseNextNode()) {
+            RenderObject *renderer = n->renderer();
+            if (!renderer)
+                continue;
+            // FIXME: Are there any node types that have renderers, but that we should be skipping?
+            const FontData* f = renderer->style()->font().primaryFont();
+            if (!font) {
+                font = f;
+                if (!hasMultipleFonts)
+                    break;
+            } else if (font != f) {
+                hasMultipleFonts = true;
+                break;
+            }
+        }
+    }
+
+    return font;
+}
+
 Frame::TriState Editor::selectionUnorderedListState() const
 {
     if (m_frame->selectionController()->isCaret()) {
 Frame::TriState Editor::selectionUnorderedListState() const
 {
     if (m_frame->selectionController()->isCaret()) {
index 130deb95d6fd6bd6a52c62cf6e3f6041ee17af10..22dd95b9ffd7e609c3fbcd8b45343dfd05754433 100644 (file)
@@ -39,6 +39,7 @@ namespace WebCore {
 class Clipboard;
 class DeleteButtonController;
 class DocumentFragment;
 class Clipboard;
 class DeleteButtonController;
 class DocumentFragment;
+class FontData;
 class Frame;
 class HTMLElement;
 class Pasteboard;
 class Frame;
 class HTMLElement;
 class Pasteboard;
@@ -87,6 +88,8 @@ public:
     void respondToChangedSelection(const Selection& oldSelection);
     void respondToChangedContents(const Selection& endingSelection);
     
     void respondToChangedSelection(const Selection& oldSelection);
     void respondToChangedContents(const Selection& endingSelection);
     
+    const FontData* fontForSelection(bool&) const;
+    
     Frame::TriState selectionUnorderedListState() const;
     Frame::TriState selectionOrderedListState() const;
     
     Frame::TriState selectionUnorderedListState() const;
     Frame::TriState selectionOrderedListState() const;
     
@@ -129,10 +132,11 @@ public:
     bool isSelectionMisspelled();
     Vector<String> guessesForMisspelledSelection();
     Vector<String> guessesForUngrammaticalSelection();
     bool isSelectionMisspelled();
     Vector<String> guessesForMisspelledSelection();
     Vector<String> guessesForUngrammaticalSelection();
-    void showGuessPanel();
     void markMisspellingsInAdjacentWords(const VisiblePosition&);
     void markMisspellings(const Selection&);
     void advanceToNextMisspelling(bool startBeforeSelection = false);
     void markMisspellingsInAdjacentWords(const VisiblePosition&);
     void markMisspellings(const Selection&);
     void advanceToNextMisspelling(bool startBeforeSelection = false);
+    void showSpellingGuessPanel();
+    bool spellingPanelIsShowing();
 
     bool shouldBeginEditing(Range* range);
     bool shouldEndEditing(Range* range);
 
     bool shouldBeginEditing(Range* range);
     bool shouldEndEditing(Range* range);
index 44fff7f0e716dd75ec55c2e92b690f126423dbca..928a5936bdf93b7ed31a5ef6340d08d4f0804f35 100644 (file)
@@ -508,7 +508,7 @@ Vector<String> Editor::guessesForMisspelledSelection()
     return core([[NSSpellChecker sharedSpellChecker] guessesForWord:selectedString]);
 }
 
     return core([[NSSpellChecker sharedSpellChecker] guessesForWord:selectedString]);
 }
 
-void Editor::showGuessPanel()
+void Editor::showSpellingGuessPanel()
 {
     NSSpellChecker *checker = [NSSpellChecker sharedSpellChecker];
     if (!checker) {
 {
     NSSpellChecker *checker = [NSSpellChecker sharedSpellChecker];
     if (!checker) {
@@ -530,6 +530,11 @@ void Editor::showGuessPanel()
     [spellingPanel orderFront:nil];
 }
 
     [spellingPanel orderFront:nil];
 }
 
+bool Editor::spellingPanelIsShowing()
+{
+    return [[[NSSpellChecker sharedSpellChecker] spellingPanel] isVisible];
+}
+
 void Editor::markMisspellingsInAdjacentWords(const VisiblePosition &p)
 {
     if (!isContinuousSpellCheckingEnabled())
 void Editor::markMisspellingsInAdjacentWords(const VisiblePosition &p)
 {
     if (!isContinuousSpellCheckingEnabled())
index db9740c8721b1ec373dbb475a8b0c130c58d9d86..d743a56ed09e65599f9448d7d16b3b7f68791496 100644 (file)
@@ -40,7 +40,7 @@ namespace WebCore {
         virtual void contextMenuDestroyed() = 0;
         
         virtual void addCustomContextMenuItems(ContextMenu*) = 0;
         virtual void contextMenuDestroyed() = 0;
         
         virtual void addCustomContextMenuItems(ContextMenu*) = 0;
-        virtual void contextMenuItemSelected(const ContextMenuItem*) = 0;
+        virtual void contextMenuItemSelected(ContextMenuItem*, const ContextMenu*) = 0;
 
         virtual void downloadURL(const KURL& url) = 0;
         virtual void copyImageToClipboard(const HitTestResult&) = 0;
 
         virtual void downloadURL(const KURL& url) = 0;
         virtual void copyImageToClipboard(const HitTestResult&) = 0;
index 7d7bc5c7cb36c2a8e6d15379cb6b3e530efc8232..f79003485262f8835358e7929f4c5e8ca9f392b7 100644 (file)
@@ -111,11 +111,10 @@ static void openNewWindow(const KURL& urlToLoad, const Frame* frame)
 
 void ContextMenuController::contextMenuItemSelected(ContextMenuItem* item)
 {
 
 void ContextMenuController::contextMenuItemSelected(ContextMenuItem* item)
 {
-    ASSERT(item->parentMenu() == contextMenu());
     ASSERT(item->type() == ActionType);
 
     if (item->action() >= ContextMenuItemBaseApplicationTag) {
     ASSERT(item->type() == ActionType);
 
     if (item->action() >= ContextMenuItemBaseApplicationTag) {
-        m_client->contextMenuItemSelected(item);
+        m_client->contextMenuItemSelected(item, m_contextMenu.get());
         return;
     }
 
         return;
     }
 
@@ -253,7 +252,7 @@ void ContextMenuController::contextMenuItemSelected(ContextMenuItem* item)
             m_client->searchWithSpotlight();
             break;
         case ContextMenuItemTagShowSpellingPanel:
             m_client->searchWithSpotlight();
             break;
         case ContextMenuItemTagShowSpellingPanel:
-            frame->editor()->showGuessPanel();
+            frame->editor()->showSpellingGuessPanel();
             break;
         case ContextMenuItemTagCheckSpelling:
             frame->editor()->advanceToNextMisspelling();
             break;
         case ContextMenuItemTagCheckSpelling:
             frame->editor()->advanceToNextMisspelling();
index 9019ee23337d8d3255ef0e40873fd9c16280685c..2a7d3ce59d77bc081bb410f28cb003ccdad5cec9 100644 (file)
@@ -152,7 +152,6 @@ public:
 
 public:
 
 
 public:
 
-    NSFont* fontForSelection(bool* hasMultipleFonts) const;
     NSDictionary* fontAttributesForSelectionStart() const;
     
     NSWritingDirection baseWritingDirectionForSelectionStart() const;
     NSDictionary* fontAttributesForSelectionStart() const;
     
     NSWritingDirection baseWritingDirectionForSelectionStart() const;
index 8d7d4a0585f88a189c99037510d5381cd4fa82a9..3af5d21c22981391128792d27fd9a08db9d98172 100644 (file)
@@ -619,56 +619,6 @@ NSImage *FrameMac::snapshotDragImage(Node *node, NSRect *imageRect, NSRect *elem
     return result;
 }
 
     return result;
 }
 
-NSFont *FrameMac::fontForSelection(bool *hasMultipleFonts) const
-{
-    if (hasMultipleFonts)
-        *hasMultipleFonts = false;
-
-    if (!selectionController()->isRange()) {
-        Node *nodeToRemove;
-        RenderStyle *style = styleForSelectionStart(nodeToRemove); // sets nodeToRemove
-
-        NSFont *result = 0;
-        if (style)
-            result = style->font().primaryFont()->getNSFont();
-        
-        if (nodeToRemove) {
-            ExceptionCode ec;
-            nodeToRemove->remove(ec);
-            ASSERT(ec == 0);
-        }
-
-        return result;
-    }
-
-    NSFont *font = nil;
-
-    RefPtr<Range> range = selectionController()->toRange();
-    Node *startNode = range->editingStartPosition().node();
-    if (startNode != nil) {
-        Node *pastEnd = range->pastEndNode();
-        // In the loop below, n should eventually match pastEnd and not become nil, but we've seen at least one
-        // unreproducible case where this didn't happen, so check for nil also.
-        for (Node *n = startNode; n && n != pastEnd; n = n->traverseNextNode()) {
-            RenderObject *renderer = n->renderer();
-            if (!renderer)
-                continue;
-            // FIXME: Are there any node types that have renderers, but that we should be skipping?
-            NSFont *f = renderer->style()->font().primaryFont()->getNSFont();
-            if (!font) {
-                font = f;
-                if (!hasMultipleFonts)
-                    break;
-            } else if (font != f) {
-                *hasMultipleFonts = true;
-                break;
-            }
-        }
-    }
-
-    return font;
-}
-
 NSDictionary *FrameMac::fontAttributesForSelectionStart() const
 {
     Node *nodeToRemove;
 NSDictionary *FrameMac::fontAttributesForSelectionStart() const
 {
     Node *nodeToRemove;
index 59d7d35e4bbf9df12c46b6a59129a0abed22fc3e..bc6fc3a6bbf229ca812d449d2b8f6dbd14b8d37d 100644 (file)
 #import "DocLoader.h"
 #import "DocumentFragment.h"
 #import "DocumentType.h"
 #import "DocLoader.h"
 #import "DocumentFragment.h"
 #import "DocumentType.h"
+#import "Editor.h"
 #import "EditorClient.h"
 #import "EventHandler.h"
 #import "FloatRect.h"
 #import "EditorClient.h"
 #import "EventHandler.h"
 #import "FloatRect.h"
+#import "FontData.h"
 #import "FrameLoader.h"
 #import "FrameLoaderClient.h"
 #import "FrameMac.h"
 #import "FrameLoader.h"
 #import "FrameLoaderClient.h"
 #import "FrameMac.h"
@@ -1423,7 +1425,7 @@ static HTMLFormElement *formElementFromDOMElement(DOMElement *element)
     bool multipleFonts = false;
     NSFont *font = nil;
     if (m_frame)
     bool multipleFonts = false;
     NSFont *font = nil;
     if (m_frame)
-        font = m_frame->fontForSelection(hasMultipleFonts ? &multipleFonts : 0);
+        font = m_frame->editor()->fontForSelection(multipleFonts)->getNSFont();
     if (hasMultipleFonts)
         *hasMultipleFonts = multipleFonts;
     return font;
     if (hasMultipleFonts)
         *hasMultipleFonts = multipleFonts;
     return font;
index 7554ecbe5ffc82cda386269998eead7bd715c488..ffff79ce535bed63825d7c8dfeba9a5f30bd4eb7 100644 (file)
@@ -26,6 +26,9 @@
 #include "config.h"
 #include "ContextMenu.h"
 
 #include "config.h"
 #include "ContextMenu.h"
 
+#include "CSSComputedStyleDeclaration.h"
+#include "CSSProperty.h"
+#include "CSSPropertyNames.h"
 #include "ContextMenuController.h"
 #include "Document.h"
 #include "Editor.h"
 #include "ContextMenuController.h"
 #include "Document.h"
 #include "Editor.h"
@@ -37,6 +40,7 @@
 #include "ResourceRequest.h"
 #include "SelectionController.h"
 
 #include "ResourceRequest.h"
 #include "SelectionController.h"
 
+
 namespace WebCore {
 
 ContextMenuController* ContextMenu::controller() const
 namespace WebCore {
 
 ContextMenuController* ContextMenu::controller() const
@@ -48,13 +52,14 @@ ContextMenuController* ContextMenu::controller() const
     return 0;
 }
 
     return 0;
 }
 
-static const ContextMenuItem* separatorItem()
+static ContextMenuItem* separatorItem()
 {
     return new ContextMenuItem(SeparatorType, ContextMenuItemTagNoAction, String());
 }
 
 {
     return new ContextMenuItem(SeparatorType, ContextMenuItemTagNoAction, String());
 }
 
-static void createFontSubMenu(const HitTestResult& result, ContextMenuItem& fontMenuItem)
+static void createAndAppendFontSubMenu(const HitTestResult& result, ContextMenuItem& fontMenuItem)
 {
 {
+    ContextMenu* fontMenu = new ContextMenu(result);
 #if PLATFORM(MAC)
     ContextMenuItem showFonts(ActionType, ContextMenuItemTagShowFonts, "Show Fonts");
 #endif
 #if PLATFORM(MAC)
     ContextMenuItem showFonts(ActionType, ContextMenuItemTagShowFonts, "Show Fonts");
 #endif
@@ -67,7 +72,6 @@ static void createFontSubMenu(const HitTestResult& result, ContextMenuItem& font
     ContextMenuItem showColors(ActionType, ContextMenuItemTagShowColors, "Show Colors");
 #endif
 
     ContextMenuItem showColors(ActionType, ContextMenuItemTagShowColors, "Show Colors");
 #endif
 
-    ContextMenu* fontMenu = new ContextMenu(result);
 #if PLATFORM(MAC)
     fontMenu->appendItem(showFonts);
 #endif
 #if PLATFORM(MAC)
     fontMenu->appendItem(showFonts);
 #endif
@@ -85,14 +89,14 @@ static void createFontSubMenu(const HitTestResult& result, ContextMenuItem& font
 }
 
 #ifndef BUILDING_ON_TIGER
 }
 
 #ifndef BUILDING_ON_TIGER
-static void createSpellingAndGrammarSubMenu(const HitTestResult& result, ContextMenuItem& spellingAndGrammarMenuItem)
+static void createAndAppendSpellingAndGrammarSubMenu(const HitTestResult& result, ContextMenuItem& spellingAndGrammarMenuItem)
 {
 {
+    ContextMenu* spellingAndGrammarMenu = new ContextMenu(result);
     ContextMenuItem showSpellingPanel(ActionType, ContextMenuItemTagShowSpellingPanel, "Show Spelling and Grammar");
     ContextMenuItem checkSpelling(ActionType, ContextMenuItemTagCheckSpelling, "Check Document Now");
     ContextMenuItem checkAsYouType(ActionType, ContextMenuItemTagCheckSpellingWhileTyping, "Check Spelling While Typing");
     ContextMenuItem grammarWithSpelling(ActionType, ContextMenuItemTagCheckGrammarWithSpelling, "Check Grammar With Spelling");
 
     ContextMenuItem showSpellingPanel(ActionType, ContextMenuItemTagShowSpellingPanel, "Show Spelling and Grammar");
     ContextMenuItem checkSpelling(ActionType, ContextMenuItemTagCheckSpelling, "Check Document Now");
     ContextMenuItem checkAsYouType(ActionType, ContextMenuItemTagCheckSpellingWhileTyping, "Check Spelling While Typing");
     ContextMenuItem grammarWithSpelling(ActionType, ContextMenuItemTagCheckGrammarWithSpelling, "Check Grammar With Spelling");
 
-    ContextMenu* spellingAndGrammarMenu = new ContextMenu(result);
     spellingAndGrammarMenu->appendItem(showSpellingPanel);
     spellingAndGrammarMenu->appendItem(checkSpelling);
     spellingAndGrammarMenu->appendItem(checkAsYouType);
     spellingAndGrammarMenu->appendItem(showSpellingPanel);
     spellingAndGrammarMenu->appendItem(checkSpelling);
     spellingAndGrammarMenu->appendItem(checkAsYouType);
@@ -100,43 +104,41 @@ static void createSpellingAndGrammarSubMenu(const HitTestResult& result, Context
 
     spellingAndGrammarMenuItem.setSubMenu(spellingAndGrammarMenu);
 }
 
     spellingAndGrammarMenuItem.setSubMenu(spellingAndGrammarMenu);
 }
-#else
-static void createSpellingSubMenu(const HitTestResult& result, ContextMenuItem& spellingMenuItem)
+#endif
+
+static void createAndAppendSpellingSubMenu(const HitTestResult& result, ContextMenuItem& spellingMenuItem)
 {
 {
+    ContextMenu* spellingMenu = new ContextMenu(result);
     ContextMenuItem showSpellingPanel(ActionType, ContextMenuItemTagShowSpellingPanel, "Spelling...");
     ContextMenuItem checkSpelling(ActionType, ContextMenuItemTagCheckSpelling, "Check Spelling");
     ContextMenuItem checkAsYouType(ActionType, ContextMenuItemTagCheckSpellingWhileTyping, "Check Spelling as You Type");
 
     ContextMenuItem showSpellingPanel(ActionType, ContextMenuItemTagShowSpellingPanel, "Spelling...");
     ContextMenuItem checkSpelling(ActionType, ContextMenuItemTagCheckSpelling, "Check Spelling");
     ContextMenuItem checkAsYouType(ActionType, ContextMenuItemTagCheckSpellingWhileTyping, "Check Spelling as You Type");
 
-    ContextMenu* spellingMenu = new ContextMenu(result);
     spellingMenu->appendItem(showSpellingPanel);
     spellingMenu->appendItem(checkSpelling);
     spellingMenu->appendItem(checkAsYouType);
 
     spellingMenuItem.setSubMenu(spellingMenu);
 }
     spellingMenu->appendItem(showSpellingPanel);
     spellingMenu->appendItem(checkSpelling);
     spellingMenu->appendItem(checkAsYouType);
 
     spellingMenuItem.setSubMenu(spellingMenu);
 }
-#endif
 
 
-#if PLATFORM(MAC)
-static void createSpeechSubMenu(const HitTestResult& result, ContextMenuItem& speechMenuItem)
+static void createAndAppendSpeechSubMenu(const HitTestResult& result, ContextMenuItem& speechMenuItem)
 {
 {
+    ContextMenu* speechMenu = new ContextMenu(result);
     ContextMenuItem start(ActionType, ContextMenuItemTagStartSpeaking, "Start Speaking");
     ContextMenuItem stop(ActionType, ContextMenuItemTagStartSpeaking, "Stop Speaking");
 
     ContextMenuItem start(ActionType, ContextMenuItemTagStartSpeaking, "Start Speaking");
     ContextMenuItem stop(ActionType, ContextMenuItemTagStartSpeaking, "Stop Speaking");
 
-    ContextMenu* speechMenu = new ContextMenu(result);
     speechMenu->appendItem(start);
     speechMenu->appendItem(stop);
 
     speechMenuItem.setSubMenu(speechMenu);
 }
     speechMenu->appendItem(start);
     speechMenu->appendItem(stop);
 
     speechMenuItem.setSubMenu(speechMenu);
 }
-#endif
 
 
-static void createWritingDirectionSubMenu(const HitTestResult& result, ContextMenuItem& writingDirectionMenuItem)
+static void createAndAppendWritingDirectionSubMenu(const HitTestResult& result, ContextMenuItem& writingDirectionMenuItem)
 {
 {
+    ContextMenu* writingDirectionMenu = new ContextMenu(result);
     ContextMenuItem defaultItem(ActionType, ContextMenuItemTagDefaultDirection, "Default");
     ContextMenuItem ltr(ActionType, ContextMenuItemTagLeftToRight, "Left to Right");
     ContextMenuItem rtl(ActionType, ContextMenuItemTagRightToLeft, "Right to Left");
 
     ContextMenuItem defaultItem(ActionType, ContextMenuItemTagDefaultDirection, "Default");
     ContextMenuItem ltr(ActionType, ContextMenuItemTagLeftToRight, "Left to Right");
     ContextMenuItem rtl(ActionType, ContextMenuItemTagRightToLeft, "Right to Left");
 
-    ContextMenu* writingDirectionMenu = new ContextMenu(result);
     writingDirectionMenu->appendItem(defaultItem);
     writingDirectionMenu->appendItem(ltr);
     writingDirectionMenu->appendItem(rtl);
     writingDirectionMenu->appendItem(defaultItem);
     writingDirectionMenu->appendItem(ltr);
     writingDirectionMenu->appendItem(rtl);
@@ -289,26 +291,135 @@ void ContextMenu::populate()
             appendItem(*separatorItem());
 #ifndef BUILDING_ON_TIGER
             ContextMenuItem SpellingAndGrammarMenuItem(SubmenuType, ContextMenuItemTagSpellingMenu, "Spelling and Grammar");
             appendItem(*separatorItem());
 #ifndef BUILDING_ON_TIGER
             ContextMenuItem SpellingAndGrammarMenuItem(SubmenuType, ContextMenuItemTagSpellingMenu, "Spelling and Grammar");
-            createSpellingAndGrammarSubMenu(m_hitTestResult, SpellingAndGrammarMenuItem);
+            createAndAppendSpellingAndGrammarSubMenu(m_hitTestResult, SpellingAndGrammarMenuItem);
             appendItem(SpellingAndGrammarMenuItem);
 #else
             ContextMenuItem SpellingMenuItem(SubmenuType, ContextMenuItemTagSpellingMenu, "Spelling");
             appendItem(SpellingAndGrammarMenuItem);
 #else
             ContextMenuItem SpellingMenuItem(SubmenuType, ContextMenuItemTagSpellingMenu, "Spelling");
-            createSpellingSubMenu(m_hitTestResult, SpellingMenuItem);
+            createAndAppendSpellingSubMenu(m_hitTestResult, SpellingMenuItem);
             appendItem(SpellingMenuItem);
 #endif
             ContextMenuItem  FontMenuItem(SubmenuType, ContextMenuItemTagFontMenu, "Font");
             appendItem(SpellingMenuItem);
 #endif
             ContextMenuItem  FontMenuItem(SubmenuType, ContextMenuItemTagFontMenu, "Font");
-            createFontSubMenu(m_hitTestResult, FontMenuItem);
+            createAndAppendFontSubMenu(m_hitTestResult, FontMenuItem);
             appendItem(FontMenuItem);
 #if PLATFORM(MAC)
             ContextMenuItem SpeechMenuItem(SubmenuType, ContextMenuItemTagSpeechMenu, "Speech");
             appendItem(FontMenuItem);
 #if PLATFORM(MAC)
             ContextMenuItem SpeechMenuItem(SubmenuType, ContextMenuItemTagSpeechMenu, "Speech");
-            createSpeechSubMenu(m_hitTestResult, SpeechMenuItem);
+            createAndAppendSpeechSubMenu(m_hitTestResult, SpeechMenuItem);
             appendItem(SpeechMenuItem);
 #endif
             ContextMenuItem WritingDirectionMenuItem(SubmenuType, ContextMenuItemTagWritingDirectionMenu, "Writing Direction");
             appendItem(SpeechMenuItem);
 #endif
             ContextMenuItem WritingDirectionMenuItem(SubmenuType, ContextMenuItemTagWritingDirectionMenu, "Writing Direction");
-            createWritingDirectionSubMenu(m_hitTestResult, WritingDirectionMenuItem);
+            createAndAppendWritingDirectionSubMenu(m_hitTestResult, WritingDirectionMenuItem);
             appendItem(WritingDirectionMenuItem);
         }
     }
 }
 
             appendItem(WritingDirectionMenuItem);
         }
     }
 }
 
+static bool triStateToBool(Frame::TriState state)
+{
+    return state == Frame::trueTriState;
+}
+
+void ContextMenu::checkOrEnableIfNeeded(ContextMenuItem& item) const
+{
+    if (item.type() == SeparatorType)
+        return;
+    
+    Document* document = m_hitTestResult.innerNonSharedNode()->document();
+    if (!document)
+        return;
+
+    Frame* frame = document->frame();
+    if (!frame)
+        return;
+
+    bool shouldEnable = true;
+    bool shouldCheck = false; 
+
+    switch (item.action()) {
+        case ContextMenuItemTagCheckSpelling:
+            shouldEnable = frame->editor()->canEdit();
+            break;
+        case ContextMenuItemTagDefaultDirection:
+            shouldCheck = false;
+            shouldEnable = false;
+            break;
+        case ContextMenuItemTagLeftToRight:
+        case ContextMenuItemTagRightToLeft: {
+            ExceptionCode ec = 0;
+            RefPtr<CSSStyleDeclaration> style = frame->document()->createCSSStyleDeclaration();
+            String direction = item.action() == ContextMenuItemTagLeftToRight ? "ltr" : "rtl";
+            style->setProperty(CSS_PROP_DIRECTION, direction, false, ec);
+            shouldCheck = triStateToBool(frame->selectionHasStyle(style.get()));
+            shouldEnable = true;
+            break;
+        }
+        case ContextMenuItemTagCopy:
+            shouldEnable = frame->editor()->canDHTMLCopy() || frame->editor()->canCopy();
+            break;
+        case ContextMenuItemTagCut:
+            shouldEnable = frame->editor()->canDHTMLCut() || frame->editor()->canCut();
+            break;
+        case ContextMenuItemTagIgnoreSpelling:
+        case ContextMenuItemTagLearnSpelling:
+            shouldEnable = frame->selectionController()->isRange();
+            break;
+        case ContextMenuItemTagPaste:
+            shouldEnable = frame->editor()->canDHTMLPaste() || (frame->editor()->canPaste() && 
+                frame->selectionController()->isContentRichlyEditable());
+            break;
+        case ContextMenuItemTagUnderline: {
+            ExceptionCode ec = 0;
+            RefPtr<CSSStyleDeclaration> style = frame->document()->createCSSStyleDeclaration();
+            style->setProperty(CSS_PROP__WEBKIT_TEXT_DECORATIONS_IN_EFFECT, "underline", false, ec);
+            shouldCheck = triStateToBool(frame->selectionHasStyle(style.get()));
+            shouldEnable = frame->editor()->canEditRichly();
+            break;
+        }
+        case ContextMenuItemTagLookUpInDictionary:
+            shouldEnable = frame->selectionController()->isRange();
+            break;
+#ifndef BUILDING_ON_TIGER
+        case ContextMenuItemTagCheckGrammarWithSpelling:
+            if (frame->editor()->isGrammarCheckingEnabled())
+                shouldCheck = true;
+            shouldEnable = true;
+            break;
+#endif
+        case ContextMenuItemTagItalic: {
+            ExceptionCode ec = 0;
+            RefPtr<CSSStyleDeclaration> style = frame->document()->createCSSStyleDeclaration();
+            style->setProperty(CSS_PROP_FONT_STYLE, "italic", false, ec);
+            shouldCheck = triStateToBool(frame->selectionHasStyle(style.get()));
+            shouldEnable = frame->editor()->canEditRichly();
+            break;
+        }
+        case ContextMenuItemTagBold: {
+            ExceptionCode ec = 0;
+            RefPtr<CSSStyleDeclaration> style = frame->document()->createCSSStyleDeclaration();
+            style->setProperty(CSS_PROP_FONT_WEIGHT, "bold", false, ec);
+            shouldCheck = triStateToBool(frame->selectionHasStyle(style.get()));
+            shouldEnable = frame->editor()->canEditRichly();
+            break;
+        }
+        case ContextMenuItemTagOutline:
+            shouldEnable = false;
+            break;
+#if PLATFORM(MAC)
+        case ContextMenuItemTagShowSpellingPanel:
+#ifndef BUILDING_ON_TIGER
+            if (frame->editor()->spellingPanelIsShowing())
+                setTitle(String("Hide Spelling and Grammar")); // With UI_STRING this also sends "menu item title" as a parameter
+            else
+                setTitle(String("Show Spelling and Grammar")); // With UI_STRING this also sends "menu item title" as a parameter
+#endif
+            shouldEnable = frame->editor()->canEdit();
+            break;
+#endif
+        default:
+            break;
+    }
+
+    item.setChecked(shouldCheck);
+    item.setEnabled(shouldEnable);
+}
+
 }
 }
index c55039f9877127a00e239d91e2cf4cd301f74468..df2048f4b1dccc35f4bbde33d855dc3f042dc56d 100644 (file)
@@ -51,14 +51,15 @@ namespace WebCore {
         ~ContextMenu();
 
         void populate();
         ~ContextMenu();
 
         void populate();
+        void checkOrEnableIfNeeded(ContextMenuItem&) const;
 
         void show();
         void hide();
 
 
         void show();
         void hide();
 
-        void insertItem(unsigned position, const ContextMenuItem&);
-        void appendItem(const ContextMenuItem&);
+        void insertItem(unsigned position, ContextMenuItem&);
+        void appendItem(ContextMenuItem&);
         
         
-        ContextMenuItem at(unsigned index);
+        ContextMenuItem* itemWithAction(unsigned);
 
         unsigned itemCount() const;
 
 
         unsigned itemCount() const;
 
@@ -70,7 +71,7 @@ namespace WebCore {
 
     private:
         HitTestResult m_hitTestResult;
 
     private:
         HitTestResult m_hitTestResult;
-        
+
 #if PLATFORM(MAC)
         // Keep this in sync with the PlatformMenuDescription typedef
         RetainPtr<NSMutableArray> m_platformDescription;
 #if PLATFORM(MAC)
         // Keep this in sync with the PlatformMenuDescription typedef
         RetainPtr<NSMutableArray> m_platformDescription;
index 675c501b818f2dd543234a0687fdd2d58dc1c77e..bd5f23d73214e70d0c8e018c3b8dcc6d4b815129 100644 (file)
@@ -97,9 +97,7 @@ namespace WebCore {
         ContextMenuItemTagShowSpellingPanel,
         ContextMenuItemTagCheckSpelling,
         ContextMenuItemTagCheckSpellingWhileTyping,
         ContextMenuItemTagShowSpellingPanel,
         ContextMenuItemTagCheckSpelling,
         ContextMenuItemTagCheckSpellingWhileTyping,
-#ifndef BUILDING_ON_TIGER
         ContextMenuItemTagCheckGrammarWithSpelling,
         ContextMenuItemTagCheckGrammarWithSpelling,
-#endif
         ContextMenuItemTagFontMenu, // Font sub-menu
         ContextMenuItemTagShowFonts,
         ContextMenuItemTagBold,
         ContextMenuItemTagFontMenu, // Font sub-menu
         ContextMenuItemTagShowFonts,
         ContextMenuItemTagBold,
@@ -126,38 +124,36 @@ namespace WebCore {
 
     class ContextMenuItem {
     public:
 
     class ContextMenuItem {
     public:
-        ContextMenuItem(PlatformMenuItemDescription, ContextMenu*);
-        ContextMenuItem(ContextMenu* parentMenu = 0, ContextMenu* subMenu = 0);
-        ContextMenuItem(ContextMenuItemType type, ContextMenuAction action, const String& title, ContextMenu* parentMenu = 0, 
-            ContextMenu* subMenu = 0);
+        ContextMenuItem(PlatformMenuItemDescription);
+        ContextMenuItem(ContextMenu* subMenu = 0);
+        ContextMenuItem(ContextMenuItemType type, ContextMenuAction action, const String& title, ContextMenu* subMenu = 0);
         ~ContextMenuItem();
 
         ~ContextMenuItem();
 
-        ContextMenu* parentMenu() const { return m_parentMenu; }
-        PlatformMenuItemDescription platformDescription() const;
+        PlatformMenuItemDescription releasePlatformDescription();
 
 
-        ContextMenuItemType type() const { return m_type; }
-        void setType(ContextMenuItemType type) { m_type = type; }
+        ContextMenuItemType type();
+        void setType(ContextMenuItemType);
 
         ContextMenuAction action() const;
 
         ContextMenuAction action() const;
-        void setAction(ContextMenuAction action);
+        void setAction(ContextMenuAction);
 
         String title() const;
 
         String title() const;
-        void setTitle(String title);
+        void setTitle(const String&) const;
 
         PlatformMenuDescription platformSubMenu() const;
 
         PlatformMenuDescription platformSubMenu() const;
-        void setSubMenu(ContextMenu* subMenu);
+        void setSubMenu(ContextMenu*);
+
+        void setChecked(bool) const;
+        void setEnabled(bool) const;
 
         // FIXME: Do we need a keyboard accelerator here?
 
     private:
 
         // FIXME: Do we need a keyboard accelerator here?
 
     private:
-        ContextMenu* m_parentMenu;
 #if PLATFORM(MAC)
         RetainPtr<NSMenuItem> m_platformDescription;
 #else
         PlatformMenuItemDescription m_platformDescription;
 #endif
 #if PLATFORM(MAC)
         RetainPtr<NSMenuItem> m_platformDescription;
 #else
         PlatformMenuItemDescription m_platformDescription;
 #endif
-        OwnPtr<ContextMenu> m_subMenu;
-        ContextMenuItemType m_type;
     };
 
 }
     };
 
 }
index a352906f6c06f4dd27ec11b65b3fb08f1c1a089d..3996a643e2f64e9eaac3b4a1410de468464795be 100644 (file)
@@ -73,6 +73,8 @@ namespace WebCore {
         
         PtrType get() const { return m_ptr; }
         
         
         PtrType get() const { return m_ptr; }
         
+        T* releaseRef() { T* tmp = m_ptr; m_ptr = 0; return tmp; }
+        
         RefType operator*() const { return *m_ptr; }
         PtrType operator->() const { return m_ptr; }
         
         RefType operator*() const { return *m_ptr; }
         PtrType operator->() const { return m_ptr; }
         
index 40ce792361d36996ed903996958743fe6aef84a0..fa7846212de30c8dafc59a25a872ffa01a58175a 100644 (file)
@@ -40,30 +40,13 @@ static NSMutableArray* menuToArray(NSMenu* menu)
     return itemsArray;
 }
 
     return itemsArray;
 }
 
-ContextMenuItem::ContextMenuItem(NSMenuItem* item, ContextMenu* parentMenu)
-    : m_parentMenu(parentMenu)
-    , m_platformDescription(item)
-    , m_subMenu(0)
+ContextMenuItem::ContextMenuItem(NSMenuItem* item)
 {
 {
-    if ([item isSeparatorItem])
-        m_type = SeparatorType;
-    else if ([item hasSubmenu]) {
-        m_type = SubmenuType;
-        m_subMenu.set(new ContextMenu(m_parentMenu->hitTestResult(), menuToArray([item submenu])));
-    } else
-        m_type = ActionType;
-}
-
-ContextMenuItem::ContextMenuItem(ContextMenu* parentMenu, ContextMenu* subMenu)
-    : m_parentMenu(parentMenu)
-    , m_subMenu(subMenu)
-    , m_type(SeparatorType)
-{
-    if (m_type == SeparatorType) {
-        m_platformDescription = [NSMenuItem separatorItem];
-        return;
-    }
+    m_platformDescription = item;
+}
 
 
+ContextMenuItem::ContextMenuItem(ContextMenu* subMenu)
+{
     NSMenuItem* item = [[NSMenuItem alloc] initWithTitle:@"" action:nil keyEquivalent:@""];
     m_platformDescription = item;
     [item release];
     NSMenuItem* item = [[NSMenuItem alloc] initWithTitle:@"" action:nil keyEquivalent:@""];
     m_platformDescription = item;
     [item release];
@@ -73,13 +56,9 @@ ContextMenuItem::ContextMenuItem(ContextMenu* parentMenu, ContextMenu* subMenu)
         setSubMenu(subMenu);
 }
 
         setSubMenu(subMenu);
 }
 
-ContextMenuItem::ContextMenuItem(ContextMenuItemType type, ContextMenuAction action, const String& title, ContextMenu* parentMenu, 
-    ContextMenu* subMenu)
-    : m_parentMenu(parentMenu)
-    , m_subMenu(subMenu)
-    , m_type(type)
+ContextMenuItem::ContextMenuItem(ContextMenuItemType type, ContextMenuAction action, const String& title, ContextMenu* subMenu)
 {
 {
-    if (m_type == SeparatorType) {
+    if (type == SeparatorType) {
         m_platformDescription = [NSMenuItem separatorItem];
         return;
     }
         m_platformDescription = [NSMenuItem separatorItem];
         return;
     }
@@ -97,9 +76,18 @@ ContextMenuItem::~ContextMenuItem()
 {
 }
 
 {
 }
 
-PlatformMenuItemDescription ContextMenuItem::platformDescription() const
+NSMenuItem* ContextMenuItem::releasePlatformDescription()
 {
 {
-    return m_platformDescription.get();
+    return m_platformDescription.releaseRef();
+}
+
+ContextMenuItemType ContextMenuItem::type()
+{
+    if ([m_platformDescription.get() isSeparatorItem])
+        return SeparatorType;
+    if ([m_platformDescription.get() hasSubmenu])
+        return SubmenuType;
+    return ActionType;
 }
 
 ContextMenuAction ContextMenuItem::action() const
 }
 
 ContextMenuAction ContextMenuItem::action() const
@@ -114,9 +102,13 @@ String ContextMenuItem::title() const
 
 NSMutableArray* ContextMenuItem::platformSubMenu() const
 {
 
 NSMutableArray* ContextMenuItem::platformSubMenu() const
 {
-    if (!m_subMenu)
-        return nil;
-    return m_subMenu->platformDescription();
+    return menuToArray([m_platformDescription.get() submenu]);
+}
+
+void ContextMenuItem::setType(ContextMenuItemType type)
+{
+    if (type == SeparatorType)
+        m_platformDescription = [NSMenuItem separatorItem];
 }
 
 void ContextMenuItem::setAction(ContextMenuAction action)
 }
 
 void ContextMenuItem::setAction(ContextMenuAction action)
@@ -124,21 +116,33 @@ void ContextMenuItem::setAction(ContextMenuAction action)
     [m_platformDescription.get() setTag:action]; 
 }
 
     [m_platformDescription.get() setTag:action]; 
 }
 
-void ContextMenuItem::setTitle(String title)
+void ContextMenuItem::setTitle(const String& title) const
 {
     [m_platformDescription.get() setTitle:title];
 }
 
 void ContextMenuItem::setSubMenu(ContextMenu* menu)
 {
 {
     [m_platformDescription.get() setTitle:title];
 }
 
 void ContextMenuItem::setSubMenu(ContextMenu* menu)
 {
-    m_subMenu.set(menu);
-
     NSArray* subMenuArray = menu->platformDescription();
     NSMenu* subMenu = [[NSMenu alloc] init];
     NSArray* subMenuArray = menu->platformDescription();
     NSMenu* subMenu = [[NSMenu alloc] init];
+    [subMenu setAutoenablesItems:NO];
     for (unsigned i = 0; i < [subMenuArray count]; i++)
         [subMenu insertItem:[subMenuArray objectAtIndex:i] atIndex:i];
     [m_platformDescription.get() setSubmenu:subMenu];
     [subMenu release];
 }
 
     for (unsigned i = 0; i < [subMenuArray count]; i++)
         [subMenu insertItem:[subMenuArray objectAtIndex:i] atIndex:i];
     [m_platformDescription.get() setSubmenu:subMenu];
     [subMenu release];
 }
 
+void ContextMenuItem::setChecked(bool checked) const
+{
+    if (checked)
+        [m_platformDescription.get() setState:NSOnState];
+    else
+        [m_platformDescription.get() setState:NSOffState];
+}
+
+void ContextMenuItem::setEnabled(bool enable) const
+{
+    [m_platformDescription.get() setEnabled:enable];
+}
+
 }
 }
index 1317e3713beeb1113d14f4ed35677af7af047a36..5d4b1c138042aa421484dc306319585e1f8b92d2 100644 (file)
@@ -60,7 +60,7 @@ static WebCoreMenuTarget* target;
 
 - (void)forwardContextMenuAction:(id)sender
 {
 
 - (void)forwardContextMenuAction:(id)sender
 {
-    WebCore::ContextMenuItem item(WebCore::ActionType, static_cast<WebCore::ContextMenuAction>([sender tag]), [sender title], _menuController->contextMenu());
+    WebCore::ContextMenuItem item(WebCore::ActionType, static_cast<WebCore::ContextMenuAction>([sender tag]), [sender title]);
     _menuController->contextMenuItemSelected(&item);
 }
 
     _menuController->contextMenuItemSelected(&item);
 }
 
@@ -89,29 +89,34 @@ ContextMenu::~ContextMenu()
 {
 }
  
 {
 }
  
-static void setMenuItemTarget(const ContextMenuItem& item)
+static void setMenuItemTarget(NSMenuItem* menuItem)
 {
 {
-    NSMenuItem* menuItem = item.platformDescription();
-    if (item.type() == ActionType) {
-        [menuItem setTarget:[WebCoreMenuTarget sharedMenuTarget]];
-        [menuItem setAction:@selector(forwardContextMenuAction:)];
-    }
+    [menuItem setTarget:[WebCoreMenuTarget sharedMenuTarget]];
+    [menuItem setAction:@selector(forwardContextMenuAction:)];
 }
 
 }
 
-void ContextMenu::appendItem(const ContextMenuItem& item)
+void ContextMenu::appendItem(ContextMenuItem& item)
 {
 {
-    if (!item.platformDescription())
-        return;
-    setMenuItemTarget(item);
-    [m_platformDescription.get() addObject:item.platformDescription()];
+    checkOrEnableIfNeeded(item);
+
+    ContextMenuItemType type = item.type();
+    NSMenuItem* platformItem = item.releasePlatformDescription();
+    if (type == ActionType)
+        setMenuItemTarget(platformItem);
+
+    [m_platformDescription.get() addObject:platformItem];
 }
 
 }
 
-void ContextMenu::insertItem(unsigned position, const ContextMenuItem& item)
+void ContextMenu::insertItem(unsigned position, ContextMenuItem& item)
 {
 {
-    if (!item.platformDescription())
-        return;
-    setMenuItemTarget(item);
-    [m_platformDescription.get() insertObject:item.platformDescription() atIndex:position];
+    checkOrEnableIfNeeded(item);
+
+    ContextMenuItemType type = item.type();
+    NSMenuItem* platformItem = item.releasePlatformDescription();
+    if (type == ActionType)
+        setMenuItemTarget(platformItem);
+
+    [m_platformDescription.get() insertObject:platformItem atIndex:position];
 }
 
 unsigned ContextMenu::itemCount() const
 }
 
 unsigned ContextMenu::itemCount() const
index 6309dd91bb5aee559e06af1997bcea93ac0c5bff..7d628d4e149aac79b6af110cb4783b73be2ee80c 100644 (file)
@@ -1,3 +1,20 @@
+2006-12-16  Beth Dakin  <bdakin@apple.com>
+
+        Reviewed by Adam.
+
+        WebKit side of making WebCore context menus support state and
+        enabled/disabled.
+
+        * WebCoreSupport/WebContextMenuClient.h: contextMenuItemSelected
+        takes a pointer to the parentMenu now since menu items no longer
+        hold onto it.
+        * WebCoreSupport/WebContextMenuClient.mm: Same.
+        (WebContextMenuClient::contextMenuItemSelected): Same.
+        * WebView/WebHTMLView.m: Must call setAutoenablesItems:NO on our
+        menu.
+        (-[NSArray menuForEvent:]):
+        * WebView/WebUIDelegatePrivate.h: No need for if-def.
+
 2006-12-15  Anders Carlsson  <acarlsson@apple.com>
 
         Reviewed by Geoff.
 2006-12-15  Anders Carlsson  <acarlsson@apple.com>
 
         Reviewed by Geoff.
index aa7fa020be8981f591f37f83dbf5969f590712c7..6bb619e830de039a640bcde5f7281593d759b7c5 100644 (file)
@@ -39,7 +39,7 @@ public:
     virtual void contextMenuDestroyed();
     
     virtual void addCustomContextMenuItems(WebCore::ContextMenu*);
     virtual void contextMenuDestroyed();
     
     virtual void addCustomContextMenuItems(WebCore::ContextMenu*);
-    virtual void contextMenuItemSelected(const WebCore::ContextMenuItem*);
+    virtual void contextMenuItemSelected(WebCore::ContextMenuItem*, const WebCore::ContextMenu*);
     
     virtual void copyLinkToClipboard(const WebCore::HitTestResult&);
     virtual void downloadURL(const WebCore::KURL&);
     
     virtual void copyLinkToClipboard(const WebCore::HitTestResult&);
     virtual void downloadURL(const WebCore::KURL&);
index 872aa5b7b285c118eb6f277448682c57fffcf03c..f016d2801a8df1960daee7576f5d8a86a10c8166 100644 (file)
@@ -67,14 +67,13 @@ void WebContextMenuClient::addCustomContextMenuItems(ContextMenu* menu)
     }
 }
 
     }
 }
 
-void WebContextMenuClient::contextMenuItemSelected(const ContextMenuItem* item)
+void WebContextMenuClient::contextMenuItemSelected(ContextMenuItem* item, const ContextMenu* parentMenu)
 {
 {
-    ASSERT(item->parentMenu());
-    
     id delegate = [m_webView UIDelegate];
     if ([delegate respondsToSelector:@selector(webView:contextMenuItemSelected:forElement:)]) {
     id delegate = [m_webView UIDelegate];
     if ([delegate respondsToSelector:@selector(webView:contextMenuItemSelected:forElement:)]) {
-        NSDictionary *element = [[[WebElementDictionary alloc] initWithHitTestResult:item->parentMenu()->hitTestResult()] autorelease];
-        [delegate webView:m_webView contextMenuItemSelected:item->platformDescription() forElement:element];
+        NSDictionary *element = [[WebElementDictionary alloc] initWithHitTestResult:parentMenu->hitTestResult()];
+        [delegate webView:m_webView contextMenuItemSelected:item->releasePlatformDescription() forElement:element];
+        [element release];
     }
 }
 
     }
 }
 
index f97049e1e02e08d464d2a84565268b15b63063a6..88dcc75666658bf29dfddc493f51cf860b2c2d29 100644 (file)
@@ -2670,9 +2670,8 @@ static WebHTMLView *lastHitView = nil;
             NSMenu* menu = nil;
             if (menuItems && [menuItems count] > 0) {
                 menu = [[NSMenu alloc] init];
             NSMenu* menu = nil;
             if (menuItems && [menuItems count] > 0) {
                 menu = [[NSMenu alloc] init];
-                
-                unsigned i;
-                for (i = 0; i < [menuItems count]; i++)
+                [menu setAutoenablesItems:NO];
+                for (unsigned i = 0; i < [menuItems count]; i++)
                     [menu addItem:[menuItems objectAtIndex:i]];
             }
             return [menu autorelease];
                     [menu addItem:[menuItems objectAtIndex:i]];
             }
             return [menu autorelease];
index 4bef7b44cdb2c5e9c0d2c448d0c5fa3a566d35e7..2359c975eab4a8611e22bcc0701e2ca013cd6061 100644 (file)
@@ -36,9 +36,7 @@ enum {
     WebMenuItemTagShowSpellingPanel,
     WebMenuItemTagCheckSpelling,
     WebMenuItemTagCheckSpellingWhileTyping,
     WebMenuItemTagShowSpellingPanel,
     WebMenuItemTagCheckSpelling,
     WebMenuItemTagCheckSpellingWhileTyping,
-#ifndef BUILDING_ON_TIGER
     WebMenuItemTagCheckGrammarWithSpelling,
     WebMenuItemTagCheckGrammarWithSpelling,
-#endif
     WebMenuItemTagFontMenu,
     WebMenuItemTagShowFonts,
     WebMenuItemTagBold,
     WebMenuItemTagFontMenu,
     WebMenuItemTagShowFonts,
     WebMenuItemTagBold,