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)#ifndef UI_APP_LIST_APP_LIST_MODEL_H_
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define UI_APP_LIST_APP_LIST_MODEL_H_
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include <string>
96e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include <vector>
10010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/basictypes.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/observer_list.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/app_list/app_list_export.h"
151e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "ui/app_list/app_list_item_list.h"
165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ui/app_list/app_list_item_list_observer.h"
176e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "ui/app_list/search_result.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/models/list_model.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace app_list {
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class AppListFolderItem;
235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class AppListItem;
241e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)class AppListItemList;
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class AppListModelObserver;
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class SearchBoxModel;
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
281e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// Master model of app list that consists of three sub models: AppListItemList,
291e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// SearchBoxModel and SearchResults. The AppListItemList sub model owns a list
305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// of AppListItems and is displayed in the grid view. SearchBoxModel is
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the model for SearchBoxView. SearchResults owns a list of SearchResult.
32a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// NOTE: Currently this class observes |top_level_item_list_|. The View code may
335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// move entries in the item list directly (but can not add or remove them) and
345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// the model needs to notify its observers when this occurs.
355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class APP_LIST_EXPORT AppListModel : public AppListItemListObserver {
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  enum Status {
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    STATUS_NORMAL,
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    STATUS_SYNCING,  // Syncing apps or installing synced apps.
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef ui::ListModel<SearchResult> SearchResults;
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AppListModel();
455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual ~AppListModel();
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void AddObserver(AppListModelObserver* observer);
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void RemoveObserver(AppListModelObserver* observer);
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void SetStatus(Status status);
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Finds the item matching |id|.
535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  AppListItem* FindItem(const std::string& id);
545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Find a folder item matching |id|.
565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  AppListFolderItem* FindFolderItem(const std::string& id);
575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Adds |item| to the model. The model takes ownership of |item|. Returns a
595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // pointer to the item that is safe to use (e.g. after passing ownership).
605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  AppListItem* AddItem(scoped_ptr<AppListItem> item);
615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Adds |item| to an existing folder or creates a new folder. If |folder_id|
635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // is empty, adds the item to the top level model instead. The model takes
645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // ownership of |item|. Returns a pointer to the item that is safe to use.
655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  AppListItem* AddItemToFolder(scoped_ptr<AppListItem> item,
665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                               const std::string& folder_id);
675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Merges two items. If the target item is a folder, the source item is added
695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // to the end of the target folder. Otherwise a new folder is created in the
705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // same position as the target item with the target item as the first item in
715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // the new folder and the source item as the second item. Returns the id of
7223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  // the target folder, or an empty string if the merge failed. The source item
7323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  // may already be in a folder. See also the comment for RemoveItemFromFolder.
7423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  // NOTE: This should only be called by the View code (not the sync code); it
7523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  // enforces folder restrictions (e.g. the target can not be an OEM folder).
7623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  const std::string MergeItems(const std::string& target_item_id,
7723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)                               const std::string& source_item_id);
785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Move |item| to the folder matching |folder_id| or to the top level if
805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // |folder_id| is empty. |item|->position will determine where the item
815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // is positioned. See also the comment for RemoveItemFromFolder.
825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void MoveItemToFolder(AppListItem* item, const std::string& folder_id);
835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Move |item| to the folder matching |folder_id| or to the top level if
855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // |folder_id| is empty. The item will be inserted before |position| or at
865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // the end of the list if |position| is invalid. Note: |position| is copied
875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // in case it refers to the containing folder which may get deleted. See also
8823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  // the comment for RemoveItemFromFolder. Returns true if the item was moved.
8923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  // NOTE: This should only be called by the View code (not the sync code); it
9023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  // enforces folder restrictions (e.g. the source folder can not be type OEM).
9123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  bool MoveItemToFolderAt(AppListItem* item,
925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                          const std::string& folder_id,
935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                          syncer::StringOrdinal position);
945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
95a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Sets the position of |item| either in |top_level_item_list_| or the folder
96e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  // specified by |item|->folder_id(). If |new_position| is invalid, move the
97e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  // item to the end of the list.
985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void SetItemPosition(AppListItem* item,
995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                       const syncer::StringOrdinal& new_position);
1005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
101a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Sets the name of |item| and notifies observers.
102a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  void SetItemName(AppListItem* item, const std::string& name);
103a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
104a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Sets the name and short name of |item| and notifies observers.
105a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  void SetItemNameAndShortName(AppListItem* item,
106a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                               const std::string& name,
107a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                               const std::string& short_name);
108a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
109a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Deletes the item matching |id| from |top_level_item_list_| or from the
110a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // appropriate folder.
1115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void DeleteItem(const std::string& id);
1125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
113a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Call OnExtensionPreferenceChanged() for all items in the model.
114a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  void NotifyExtensionPreferenceChanged();
115a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
11646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Sets wither or not folder UI should be enabled. If |folders_enabled| is
11746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // false, removes any non-OEM folders.
11846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  void SetFoldersEnabled(bool folders_enabled);
11946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
1206e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // Filters the given |results| by |display_type|. The returned list is
1216e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // truncated to |max_results|.
1226e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  static std::vector<SearchResult*> FilterSearchResultsByDisplayType(
1236e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      SearchResults* results,
1246e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      SearchResult::DisplayType display_type,
1256e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      size_t max_results);
1266e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
127a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  AppListItemList* top_level_item_list() { return top_level_item_list_.get(); }
128a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SearchBoxModel* search_box() { return search_box_.get(); }
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SearchResults* results() { return results_.get(); }
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Status status() const { return status_; }
13246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  bool folders_enabled() const { return folders_enabled_; }
13368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
1355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // AppListItemListObserver
1365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual void OnListItemMoved(size_t from_index,
1375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                               size_t to_index,
1385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                               AppListItem* item) OVERRIDE;
1395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Returns an existing folder matching |folder_id| or creates a new folder.
1415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  AppListFolderItem* FindOrCreateFolderItem(const std::string& folder_id);
1425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
143a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Adds |item_ptr| to |top_level_item_list_| and notifies observers.
1445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  AppListItem* AddItemToItemListAndNotify(
1455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      scoped_ptr<AppListItem> item_ptr);
1465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
147a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Adds |item_ptr| to |top_level_item_list_| and notifies observers that an
148a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Update occured (e.g. item moved from a folder).
1495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  AppListItem* AddItemToItemListAndNotifyUpdate(
1505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      scoped_ptr<AppListItem> item_ptr);
1515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Adds |item_ptr| to |folder| and notifies observers.
1535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  AppListItem* AddItemToFolderItemAndNotify(AppListFolderItem* folder,
1545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                            scoped_ptr<AppListItem> item_ptr);
1555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
156a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Removes |item| from |top_level_item_list_| or calls RemoveItemFromFolder if
1575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // |item|->folder_id is set.
1585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  scoped_ptr<AppListItem> RemoveItem(AppListItem* item);
1595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Removes |item| from |folder|. If |folder| becomes empty, deletes |folder|
161a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // from |top_level_item_list_|. Does NOT trigger observers, calling function
162a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // must do so.
1635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  scoped_ptr<AppListItem> RemoveItemFromFolder(AppListFolderItem* folder,
1645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                               AppListItem* item);
1655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
166a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  scoped_ptr<AppListItemList> top_level_item_list_;
167a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SearchBoxModel> search_box_;
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SearchResults> results_;
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Status status_;
1721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ObserverList<AppListModelObserver, true> observers_;
17346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  bool folders_enabled_;
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(AppListModel);
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace app_list
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // UI_APP_LIST_APP_LIST_MODEL_H_
181