Home | History | Annotate | Download | only in accelerators
      1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "ui/base/accelerators/accelerator_manager.h"
      6 
      7 #include <algorithm>
      8 
      9 #include "base/logging.h"
     10 
     11 namespace ui {
     12 
     13 AcceleratorManager::AcceleratorManager() {
     14 }
     15 
     16 AcceleratorManager::~AcceleratorManager() {
     17 }
     18 
     19 void AcceleratorManager::Register(const Accelerator& accelerator,
     20                                   HandlerPriority priority,
     21                                   AcceleratorTarget* target) {
     22   AcceleratorTargetList& targets = accelerators_[accelerator].second;
     23   DCHECK(std::find(targets.begin(), targets.end(), target) == targets.end())
     24       << "Registering the same target multiple times";
     25 
     26   // All priority accelerators go to the front of the line.
     27   if (priority) {
     28     DCHECK(!accelerators_[accelerator].first)
     29         << "Only one _priority_ handler can be registered";
     30     targets.push_front(target);
     31     // Mark that we have a priority accelerator at the front.
     32     accelerators_[accelerator].first = true;
     33     return;
     34   }
     35 
     36   // We are registering a normal priority handler. If no priority accelerator
     37   // handler has been registered before us, just add the new handler to the
     38   // front. Otherwise, register it after the first (only) priority handler.
     39   if (!accelerators_[accelerator].first)
     40     targets.push_front(target);
     41   else
     42     targets.insert(++targets.begin(), target);
     43 }
     44 
     45 void AcceleratorManager::Unregister(const Accelerator& accelerator,
     46                                     AcceleratorTarget* target) {
     47   AcceleratorMap::iterator map_iter = accelerators_.find(accelerator);
     48   if (map_iter == accelerators_.end()) {
     49     NOTREACHED() << "Unregistering non-existing accelerator";
     50     return;
     51   }
     52 
     53   AcceleratorTargetList* targets = &map_iter->second.second;
     54   AcceleratorTargetList::iterator target_iter =
     55       std::find(targets->begin(), targets->end(), target);
     56   if (target_iter == targets->end()) {
     57     NOTREACHED() << "Unregistering accelerator for wrong target";
     58     return;
     59   }
     60 
     61   // Check to see if we have a priority handler and whether we are removing it.
     62   if (accelerators_[accelerator].first && target_iter == targets->begin()) {
     63     // We've are taking the priority accelerator away, flip the priority flag.
     64     accelerators_[accelerator].first = false;
     65   }
     66 
     67   targets->erase(target_iter);
     68 }
     69 
     70 void AcceleratorManager::UnregisterAll(AcceleratorTarget* target) {
     71   for (AcceleratorMap::iterator map_iter = accelerators_.begin();
     72        map_iter != accelerators_.end(); ++map_iter) {
     73     AcceleratorTargetList* targets = &map_iter->second.second;
     74     targets->remove(target);
     75   }
     76 }
     77 
     78 bool AcceleratorManager::Process(const Accelerator& accelerator) {
     79   bool result = false;
     80   AcceleratorMap::iterator map_iter = accelerators_.find(accelerator);
     81   if (map_iter != accelerators_.end()) {
     82     // We have to copy the target list here, because an AcceleratorPressed
     83     // event handler may modify the list.
     84     AcceleratorTargetList targets(map_iter->second.second);
     85     for (AcceleratorTargetList::iterator iter = targets.begin();
     86          iter != targets.end(); ++iter) {
     87       if ((*iter)->CanHandleAccelerators() &&
     88           (*iter)->AcceleratorPressed(accelerator)) {
     89         result = true;
     90         break;
     91       }
     92     }
     93   }
     94   return result;
     95 }
     96 
     97 AcceleratorTarget* AcceleratorManager::GetCurrentTarget(
     98     const Accelerator& accelerator) const {
     99   AcceleratorMap::const_iterator map_iter = accelerators_.find(accelerator);
    100   if (map_iter == accelerators_.end() || map_iter->second.second.empty())
    101     return NULL;
    102   return map_iter->second.second.front();
    103 }
    104 
    105 bool AcceleratorManager::HasPriorityHandler(
    106     const Accelerator& accelerator) const {
    107   AcceleratorMap::const_iterator map_iter = accelerators_.find(accelerator);
    108   if (map_iter == accelerators_.end() || map_iter->second.second.empty())
    109     return false;
    110 
    111   // Check if we have a priority handler. If not, there's no more work needed.
    112   if (!map_iter->second.first)
    113     return false;
    114 
    115   // If the priority handler says it cannot handle the accelerator, we must not
    116   // count it as one.
    117   return map_iter->second.second.front()->CanHandleAccelerators();
    118 }
    119 
    120 }  // namespace ui
    121