15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/command_updater.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <algorithm>
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/observer_list.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/stl_util.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/command_observer.h"
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/command_updater_delegate.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class CommandUpdater::Command {
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool enabled;
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ObserverList<CommandObserver> observers;
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Command() : enabled(true) {}
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)CommandUpdater::CommandUpdater(CommandUpdaterDelegate* delegate)
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : delegate_(delegate) {
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CommandUpdater::~CommandUpdater() {
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  STLDeleteContainerPairSecondPointers(commands_.begin(), commands_.end());
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool CommandUpdater::SupportsCommand(int id) const {
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return commands_.find(id) != commands_.end();
332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool CommandUpdater::IsCommandEnabled(int id) const {
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const CommandMap::const_iterator command(commands_.find(id));
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (command == commands_.end())
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return command->second->enabled;
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool CommandUpdater::ExecuteCommand(int id) {
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return ExecuteCommandWithDisposition(id, CURRENT_TAB);
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool CommandUpdater::ExecuteCommandWithDisposition(
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int id,
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WindowOpenDisposition disposition) {
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (SupportsCommand(id) && IsCommandEnabled(id)) {
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    delegate_->ExecuteCommandWithDisposition(id, disposition);
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void CommandUpdater::AddCommandObserver(int id, CommandObserver* observer) {
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  GetCommand(id, true)->observers.AddObserver(observer);
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void CommandUpdater::RemoveCommandObserver(int id, CommandObserver* observer) {
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  GetCommand(id, false)->observers.RemoveObserver(observer);
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void CommandUpdater::RemoveCommandObserver(CommandObserver* observer) {
652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (CommandMap::const_iterator it = commands_.begin();
662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       it != commands_.end();
672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       ++it) {
682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Command* command = it->second;
692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (command)
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      command->observers.RemoveObserver(observer);
712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CommandUpdater::UpdateCommandEnabled(int id, bool enabled) {
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Command* command = GetCommand(id, true);
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (command->enabled == enabled)
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;  // Nothing to do.
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  command->enabled = enabled;
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FOR_EACH_OBSERVER(CommandObserver, command->observers,
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    EnabledStateChangedForCommand(id, enabled));
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CommandUpdater::Command* CommandUpdater::GetCommand(int id, bool create) {
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool supported = SupportsCommand(id);
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (supported)
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return commands_[id];
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(create);
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Command* command = new Command;
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  commands_[id] = command;
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return command;
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
92