• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
AcceleratorManager()13 AcceleratorManager::AcceleratorManager() {
14 }
15 
~AcceleratorManager()16 AcceleratorManager::~AcceleratorManager() {
17 }
18 
Register(const Accelerator & accelerator,HandlerPriority priority,AcceleratorTarget * target)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 
Unregister(const Accelerator & accelerator,AcceleratorTarget * target)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 
UnregisterAll(AcceleratorTarget * target)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 
Process(const Accelerator & accelerator)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 
GetCurrentTarget(const Accelerator & accelerator) const97 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 
HasPriorityHandler(const Accelerator & accelerator) const105 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