/* * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. * Copyright (C) 2007 Trolltech ASA * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "config.h" #include "CommandByName.h" #include #include "Document.h" #include "Editor.h" #include "Frame.h" #include "Page.h" #include "PlatformString.h" #include "SelectionController.h" #include "Settings.h" #include "StringHash.h" #include "TypingCommand.h" namespace WebCore { class Frame; namespace { struct CommandImp { bool (*execFn)(Frame* frame); bool (*enabledFn)(Frame* frame); }; typedef HashMap > CommandMap; CommandMap* createCommandDictionary(); const CommandImp* commandImp(const String& command) { static CommandMap* commandDictionary = createCommandDictionary(); return commandDictionary->get(command.impl()); } // ============================================================================ // // execCommand function implementations // bool execCopy(Frame* frame) { frame->editor()->copy(); return true; } bool execCut(Frame* frame) { frame->editor()->cut(); return true; } bool execDelete(Frame* frame) { TypingCommand::deleteKeyPressed(frame->document(), frame->selectionGranularity() == WordGranularity); return true; } bool execForwardDelete(Frame* frame) { TypingCommand::forwardDeleteKeyPressed(frame->document()); return true; } bool execPaste(Frame* frame) { frame->editor()->paste(); return true; } bool execMoveLeft(Frame* frame) { frame->selectionController()->modify(SelectionController::MOVE, SelectionController::LEFT, CharacterGranularity, true); return true; } bool execMoveRight(Frame* frame) { frame->selectionController()->modify(SelectionController::MOVE, SelectionController::RIGHT, CharacterGranularity, true); return true; } bool execMoveUp(Frame* frame) { frame->selectionController()->modify(SelectionController::MOVE, SelectionController::BACKWARD, LineGranularity, true); return true; } bool execMoveDown(Frame* frame) { frame->selectionController()->modify(SelectionController::MOVE, SelectionController::FORWARD, LineGranularity, true); return true; } bool execSelectAll(Frame* frame) { frame->selectionController()->selectAll(); return true; } bool execSelectLeft(Frame* frame) { frame->selectionController()->modify(SelectionController::EXTEND, SelectionController::LEFT, CharacterGranularity, true); return true; } bool execSelectRight(Frame* frame) { frame->selectionController()->modify(SelectionController::EXTEND, SelectionController::RIGHT, CharacterGranularity, true); return true; } bool execSelectUp(Frame* frame) { frame->selectionController()->modify(SelectionController::EXTEND, SelectionController::BACKWARD, LineGranularity, true); return true; } bool execSelectDown(Frame* frame) { frame->selectionController()->modify(SelectionController::EXTEND, SelectionController::FORWARD, LineGranularity, true); return true; } // ============================================================================ // // enabled functions implementations // bool enabled(Frame*) { return true; } bool enabledAnySelection(Frame* frame) { return frame->selectionController()->isCaretOrRange(); } bool enabledAnyEditableSelection(Frame* frame) { return frame->selectionController()->isCaretOrRange() && frame->selectionController()->isContentEditable(); } bool enabledPaste(Frame* frame) { Settings* settings = frame ? frame->settings() : 0; return settings && settings->isDOMPasteAllowed() && frame->editor()->canPaste(); } bool enabledAnyRangeSelection(Frame* frame) { return frame->selectionController()->isRange(); } bool enabledAnyEditableRangeSelection(Frame* frame) { return frame->selectionController()->isRange() && frame->selectionController()->isContentEditable(); } CommandMap* createCommandDictionary() { struct Command { const char* name; CommandImp imp; }; static const Command commands[] = { { "Copy", { execCopy, enabledAnyRangeSelection } }, { "Cut", { execCut, enabledAnyEditableRangeSelection } }, { "Delete", { execDelete, enabledAnyEditableSelection } }, { "ForwardDelete", { execForwardDelete, enabledAnyEditableSelection } }, { "Paste", { execPaste, enabledPaste } }, { "SelectAll", { execSelectAll, enabled } }, { "MoveLeft", { execMoveLeft, enabledAnySelection } }, { "MoveRight", { execMoveRight, enabledAnySelection } }, { "MoveUp", { execMoveUp, enabledAnySelection } }, { "MoveDown", { execMoveDown, enabledAnySelection } }, { "SelectLeft", { execSelectLeft, enabledAnySelection } }, { "SelectRight", { execSelectRight, enabledAnySelection } }, { "SelectUp", { execSelectUp, enabledAnySelection } }, { "SelectDown", { execSelectDown, enabledAnySelection } } }; CommandMap* commandMap = new CommandMap; const int numCommands = sizeof(commands) / sizeof(commands[0]); for (int i = 0; i < numCommands; ++i) { StringImpl *name = new StringImpl(commands[i].name); name->ref(); commandMap->set(name, &commands[i].imp); } return commandMap; } } // anonymous namespace CommandByName::CommandByName(Frame* frame) : m_frame(frame) { } const bool CommandByName::execCommand(const String& command) { bool handled = false; const CommandImp* cmd = commandImp(command); if (!cmd) return false; if (!m_frame) return false; if (cmd->enabledFn(m_frame)) { m_frame->document()->updateLayoutIgnorePendingStylesheets(); handled = cmd->execFn(m_frame); } return handled; } } // namespace WebCore