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 "ui/views/focus/view_storage.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <algorithm>
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/singleton.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/stl_util.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace views {
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ViewStorage* ViewStorage::GetInstance() {
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return Singleton<ViewStorage>::get();
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ViewStorage::ViewStorage() : view_storage_next_id_(0) {
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ViewStorage::~ViewStorage() {
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  STLDeleteContainerPairSecondPointers(view_to_ids_.begin(),
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       view_to_ids_.end());
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int ViewStorage::CreateStorageID() {
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return view_storage_next_id_++;
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ViewStorage::StoreView(int storage_id, View* view) {
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(view);
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::map<int, View*>::iterator iter = id_to_view_.find(storage_id);
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (iter != id_to_view_.end()) {
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NOTREACHED();
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RemoveView(storage_id);
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  id_to_view_[storage_id] = view;
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<int>* ids = NULL;
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::map<View*, std::vector<int>*>::iterator id_iter =
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      view_to_ids_.find(view);
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (id_iter == view_to_ids_.end()) {
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ids = new std::vector<int>();
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    view_to_ids_[view] = ids;
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ids = id_iter->second;
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ids->push_back(storage_id);
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)View* ViewStorage::RetrieveView(int storage_id) {
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::map<int, View*>::iterator iter = id_to_view_.find(storage_id);
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (iter == id_to_view_.end())
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return NULL;
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return iter->second;
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ViewStorage::RemoveView(int storage_id) {
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EraseView(storage_id, false);
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ViewStorage::ViewRemoved(View* removed) {
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Let's first retrieve the ids for that view.
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::map<View*, std::vector<int>*>::iterator ids_iter =
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      view_to_ids_.find(removed);
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (ids_iter == view_to_ids_.end()) {
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // That view is not in the view storage.
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<int>* ids = ids_iter->second;
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!ids->empty());
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EraseView((*ids)[0], true);
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ViewStorage::EraseView(int storage_id, bool remove_all_ids) {
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Remove the view from id_to_view_location_.
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::map<int, View*>::iterator view_iter = id_to_view_.find(storage_id);
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (view_iter == id_to_view_.end())
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  View* view = view_iter->second;
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  id_to_view_.erase(view_iter);
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Also update view_to_ids_.
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::map<View*, std::vector<int>*>::iterator ids_iter =
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      view_to_ids_.find(view);
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(ids_iter != view_to_ids_.end());
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<int>* ids = ids_iter->second;
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (remove_all_ids) {
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (size_t i = 0; i < ids->size(); ++i) {
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      view_iter = id_to_view_.find((*ids)[i]);
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (view_iter != id_to_view_.end())
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        id_to_view_.erase(view_iter);
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ids->clear();
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::vector<int>::iterator id_iter =
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        std::find(ids->begin(), ids->end(), storage_id);
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK(id_iter != ids->end());
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ids->erase(id_iter);
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (ids->empty()) {
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    delete ids;
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    view_to_ids_.erase(ids_iter);
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace views
117