Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / ui / app_list / app_list_model.cc
index f72d73f..c2c8237 100644 (file)
@@ -10,7 +10,6 @@
 #include "ui/app_list/app_list_item.h"
 #include "ui/app_list/app_list_model_observer.h"
 #include "ui/app_list/search_box_model.h"
-#include "ui/app_list/search_result.h"
 
 namespace app_list {
 
@@ -18,7 +17,9 @@ AppListModel::AppListModel()
     : top_level_item_list_(new AppListItemList),
       search_box_(new SearchBoxModel),
       results_(new SearchResults),
-      status_(STATUS_NORMAL) {
+      status_(STATUS_NORMAL),
+      state_(INVALID_STATE),
+      folders_enabled_(false) {
   top_level_item_list_->AddObserver(this);
 }
 
@@ -42,6 +43,19 @@ void AppListModel::SetStatus(Status status) {
                     OnAppListModelStatusChanged());
 }
 
+void AppListModel::SetState(State state) {
+  if (state_ == state)
+    return;
+
+  State old_state = state_;
+
+  state_ = state;
+
+  FOR_EACH_OBSERVER(AppListModelObserver,
+                    observers_,
+                    OnAppListModelStateChanged(old_state, state_));
+}
+
 AppListItem* AppListModel::FindItem(const std::string& id) {
   AppListItem* item = top_level_item_list_->FindItem(id);
   if (item)
@@ -74,9 +88,11 @@ AppListItem* AppListModel::AddItemToFolder(scoped_ptr<AppListItem> item,
   if (folder_id.empty())
     return AddItem(item.Pass());
   DVLOG(2) << "AddItemToFolder: " << item->id() << ": " << folder_id;
-  DCHECK(!item->IsInFolder() || item->folder_id() == folder_id);
-  DCHECK(item->GetItemType() != AppListFolderItem::kItemType);
+  CHECK_NE(folder_id, item->folder_id());
+  DCHECK_NE(AppListFolderItem::kItemType, item->GetItemType());
   AppListFolderItem* dest_folder = FindOrCreateFolderItem(folder_id);
+  if (!dest_folder)
+    return NULL;
   DCHECK(!dest_folder->item_list()->FindItem(item->id()))
       << "Already in folder: " << dest_folder->id();
   return AddItemToFolderItemAndNotify(dest_folder, item.Pass());
@@ -84,14 +100,24 @@ AppListItem* AppListModel::AddItemToFolder(scoped_ptr<AppListItem> item,
 
 const std::string AppListModel::MergeItems(const std::string& target_item_id,
                                            const std::string& source_item_id) {
+  if (!folders_enabled()) {
+    LOG(ERROR) << "MergeItems called with folders disabled.";
+    return "";
+  }
   DVLOG(2) << "MergeItems: " << source_item_id << " -> " << target_item_id;
+
+  if (target_item_id == source_item_id) {
+    LOG(WARNING) << "MergeItems tried to drop item onto itself ("
+                 << source_item_id << " -> " << target_item_id << ").";
+    return "";
+  }
+
   // Find the target item.
-  AppListItem* target_item = FindItem(target_item_id);
+  AppListItem* target_item = top_level_item_list_->FindItem(target_item_id);
   if (!target_item) {
     LOG(ERROR) << "MergeItems: Target no longer exists.";
     return "";
   }
-  CHECK(target_item->folder_id().empty());
 
   AppListItem* source_item = FindItem(source_item_id);
   if (!source_item) {
@@ -119,6 +145,8 @@ const std::string AppListModel::MergeItems(const std::string& target_item_id,
   // location, they will become owned by the new folder.
   scoped_ptr<AppListItem> source_item_ptr = RemoveItem(source_item);
   CHECK(source_item_ptr);
+  // Note: This would fail if |target_item_id == source_item_id|, except we
+  // checked that they are distinct at the top of this method.
   scoped_ptr<AppListItem> target_item_ptr =
       top_level_item_list_->RemoveItem(target_item_id);
   CHECK(target_item_ptr);
@@ -153,10 +181,12 @@ void AppListModel::MoveItemToFolder(AppListItem* item,
     return;
   AppListFolderItem* dest_folder = FindOrCreateFolderItem(folder_id);
   scoped_ptr<AppListItem> item_ptr = RemoveItem(item);
-  if (dest_folder)
+  if (dest_folder) {
+    CHECK(!item->IsInFolder());
     AddItemToFolderItemAndNotify(dest_folder, item_ptr.Pass());
-  else
+  } else {
     AddItemToItemListAndNotifyUpdate(item_ptr.Pass());
+  }
 }
 
 bool AppListModel::MoveItemToFolderAt(AppListItem* item,
@@ -234,6 +264,7 @@ void AppListModel::DeleteItem(const std::string& id) {
                       observers_,
                       OnAppListItemWillBeDeleted(item));
     top_level_item_list_->DeleteItem(id);
+    FOR_EACH_OBSERVER(AppListModelObserver, observers_, OnAppListItemDeleted());
     return;
   }
   AppListFolderItem* folder = FindFolderItem(item->folder_id());
@@ -244,6 +275,7 @@ void AppListModel::DeleteItem(const std::string& id) {
                     observers_,
                     OnAppListItemWillBeDeleted(item));
   child_item.reset();  // Deletes item.
+  FOR_EACH_OBSERVER(AppListModelObserver, observers_, OnAppListItemDeleted());
 }
 
 void AppListModel::NotifyExtensionPreferenceChanged() {
@@ -251,6 +283,47 @@ void AppListModel::NotifyExtensionPreferenceChanged() {
     top_level_item_list_->item_at(i)->OnExtensionPreferenceChanged();
 }
 
+void AppListModel::SetFoldersEnabled(bool folders_enabled) {
+  folders_enabled_ = folders_enabled;
+  if (folders_enabled)
+    return;
+  // Remove child items from folders.
+  std::vector<std::string> folder_ids;
+  for (size_t i = 0; i < top_level_item_list_->item_count(); ++i) {
+    AppListItem* item = top_level_item_list_->item_at(i);
+    if (item->GetItemType() != AppListFolderItem::kItemType)
+      continue;
+    AppListFolderItem* folder = static_cast<AppListFolderItem*>(item);
+    if (folder->folder_type() == AppListFolderItem::FOLDER_TYPE_OEM)
+      continue;  // Do not remove OEM folders.
+    while (folder->item_list()->item_count()) {
+      scoped_ptr<AppListItem> child = folder->item_list()->RemoveItemAt(0);
+      child->set_folder_id("");
+      AddItemToItemListAndNotifyUpdate(child.Pass());
+    }
+    folder_ids.push_back(folder->id());
+  }
+  // Delete folders.
+  for (size_t i = 0; i < folder_ids.size(); ++i)
+    DeleteItem(folder_ids[i]);
+}
+
+std::vector<SearchResult*> AppListModel::FilterSearchResultsByDisplayType(
+    SearchResults* results,
+    SearchResult::DisplayType display_type,
+    size_t max_results) {
+  std::vector<SearchResult*> matches;
+  for (size_t i = 0; i < results->item_count(); ++i) {
+    SearchResult* item = results->GetItemAt(i);
+    if (item->display_type() == display_type) {
+      matches.push_back(item);
+      if (matches.size() == max_results)
+        break;
+    }
+  }
+  return matches;
+}
+
 // Private methods
 
 void AppListModel::OnListItemMoved(size_t from_index,
@@ -270,13 +343,17 @@ AppListFolderItem* AppListModel::FindOrCreateFolderItem(
   if (dest_folder)
     return dest_folder;
 
+  if (!folders_enabled()) {
+    LOG(ERROR) << "Attempt to create folder item when disabled: " << folder_id;
+    return NULL;
+  }
+
   DVLOG(2) << "Creating new folder: " << folder_id;
   scoped_ptr<AppListFolderItem> new_folder(
       new AppListFolderItem(folder_id, AppListFolderItem::FOLDER_TYPE_NORMAL));
   new_folder->set_position(
       top_level_item_list_->CreatePositionBefore(syncer::StringOrdinal()));
-  AppListItem* new_folder_item =
-      AddItemToItemListAndNotify(new_folder.PassAs<AppListItem>());
+  AppListItem* new_folder_item = AddItemToItemListAndNotify(new_folder.Pass());
   return static_cast<AppListFolderItem*>(new_folder_item);
 }
 
@@ -303,6 +380,7 @@ AppListItem* AppListModel::AddItemToItemListAndNotifyUpdate(
 AppListItem* AppListModel::AddItemToFolderItemAndNotify(
     AppListFolderItem* folder,
     scoped_ptr<AppListItem> item_ptr) {
+  CHECK_NE(folder->id(), item_ptr->folder_id());
   AppListItem* item = folder->item_list()->AddItem(item_ptr.Pass());
   item->set_folder_id(folder->id());
   FOR_EACH_OBSERVER(AppListModelObserver,
@@ -323,7 +401,7 @@ scoped_ptr<AppListItem> AppListModel::RemoveItemFromFolder(
     AppListFolderItem* folder,
     AppListItem* item) {
   std::string folder_id = folder->id();
-  DCHECK_EQ(item->folder_id(), folder_id);
+  CHECK_EQ(item->folder_id(), folder_id);
   scoped_ptr<AppListItem> result = folder->item_list()->RemoveItem(item->id());
   result->set_folder_id("");
   if (folder->item_list()->item_count() == 0) {