tab_strip_model.h revision 1320f92c476a1ad9d19dba2a48c72b75566198e9
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 CHROME_BROWSER_UI_TABS_TAB_STRIP_MODEL_H_
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define CHROME_BROWSER_UI_TABS_TAB_STRIP_MODEL_H_
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <vector>
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/observer_list.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/tabs/tab_strip_model_observer.h"
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/base/models/list_selection_model.h"
141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "ui/base/page_transition_types.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class Profile;
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class TabStripModelDelegate;
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class TabStripModelOrderController;
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace content {
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class WebContents;
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// TabStripModel
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//  A model & low level controller of a Browser Window tabstrip. Holds a vector
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//  of WebContentses, and provides an API for adding, removing and
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//  shuffling them, as well as a higher level API for doing specific Browser-
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//  related tasks like adding new Tabs from just a URL, etc.
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Each tab may be any one of the following states:
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// . Mini-tab. Mini tabs are locked to the left side of the tab strip and
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   rendered differently (small tabs with only a favicon). The model makes
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   sure all mini-tabs are at the beginning of the tab strip. For example,
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   if a non-mini tab is added it is forced to be with non-mini tabs. Requests
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   to move tabs outside the range of the tab type are ignored. For example,
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   a request to move a mini-tab after non-mini-tabs is ignored.
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   You'll notice there is no explicit api for making a tab a mini-tab, rather
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   there are two tab types that are implicitly mini-tabs:
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   . App. Corresponds to an extension that wants an app tab. App tabs are
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//     identified by extensions::TabHelper::is_app().
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//     App tabs are always pinned (you can't unpin them).
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   . Pinned. Any tab can be pinned. Non-app tabs whose pinned state is changed
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//     are moved to be with other mini-tabs or non-mini tabs.
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//  A TabStripModel has one delegate that it relies on to perform certain tasks
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//  like creating new TabStripModels (probably hosted in Browser windows) when
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//  required. See TabStripDelegate above for more information.
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//  A TabStripModel also has N observers (see TabStripModelObserver above),
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//  which can be registered via Add/RemoveObserver. An Observer is notified of
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//  tab creations, removals, moves, and other interesting events. The
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//  TabStrip implements this interface to know when to create new tabs in
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//  the View, and the Browser object likewise implements to be able to update
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//  its bookkeeping when such events happen.
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
600f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)class TabStripModel {
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Used to specify what should happen when the tab is closed.
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  enum CloseTypes {
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CLOSE_NONE                     = 0,
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Indicates the tab was closed by the user. If true,
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // WebContents::SetClosedByUserGesture(true) is invoked.
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CLOSE_USER_GESTURE             = 1 << 0,
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // If true the history is recorded so that the tab can be reopened later.
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // You almost always want to set this.
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CLOSE_CREATE_HISTORICAL_TAB    = 1 << 1,
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Constants used when adding tabs.
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  enum AddTabTypes {
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Used to indicate nothing special should happen to the newly inserted
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // tab.
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ADD_NONE          = 0,
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // The tab should be active.
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ADD_ACTIVE        = 1 << 0,
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // The tab should be pinned.
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ADD_PINNED        = 1 << 1,
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // If not set the insertion index of the WebContents is left up to
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // the Order Controller associated, so the final insertion index may differ
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // from the specified index. Otherwise the index supplied is used.
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ADD_FORCE_INDEX   = 1 << 2,
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // If set the newly inserted tab inherits the group of the currently
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // selected tab. If not set the tab may still inherit the group under
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // certain situations.
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ADD_INHERIT_GROUP = 1 << 3,
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // If set the newly inserted tab's opener is set to the active tab. If not
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // set the tab may still inherit the group/opener under certain situations.
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // NOTE: this is ignored if ADD_INHERIT_GROUP is set.
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ADD_INHERIT_OPENER = 1 << 4,
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Enumerates different ways to open a new tab. Does not apply to opening
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // existing links or searches in a new tab, only to brand new empty tabs.
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  enum NewTab {
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // New tab was opened using the new tab button on the tab strip.
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NEW_TAB_BUTTON,
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // New tab was opened using the menu command - either through the keyboard
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // shortcut, or by opening the menu and selecting the command. Applies to
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // both Wrench menu and the menu bar's File menu (on platforms that have
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // one).
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NEW_TAB_COMMAND,
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // New tab was opened through the context menu on the tab strip.
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NEW_TAB_CONTEXT_MENU,
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Number of enum entries, used for UMA histogram reporting macros.
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NEW_TAB_ENUM_COUNT,
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const int kNoTab = -1;
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Construct a TabStripModel with a delegate to help it do certain things
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // (see the TabStripModelDelegate documentation). |delegate| cannot be NULL.
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TabStripModel(TabStripModelDelegate* delegate, Profile* profile);
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~TabStripModel();
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Retrieves the TabStripModelDelegate associated with this TabStripModel.
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TabStripModelDelegate* delegate() const { return delegate_; }
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Add and remove observers to changes within this TabStripModel.
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void AddObserver(TabStripModelObserver* observer);
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void RemoveObserver(TabStripModelObserver* observer);
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Retrieve the number of WebContentses/emptiness of the TabStripModel.
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int count() const { return static_cast<int>(contents_data_.size()); }
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool empty() const { return contents_data_.empty(); }
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Retrieve the Profile associated with this TabStripModel.
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Profile* profile() const { return profile_; }
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Retrieve the index of the currently active WebContents.
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int active_index() const { return selection_model_.active(); }
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns true if the tabstrip is currently closing all open tabs (via a
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // call to CloseAllTabs). As tabs close, the selection in the tabstrip
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // changes which notifies observers, which can use this as an optimization to
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // avoid doing meaningless or unhelpful work.
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool closing_all() const { return closing_all_; }
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Access the order controller. Exposed only for unit tests.
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TabStripModelOrderController* order_controller() const {
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return order_controller_.get();
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Basic API /////////////////////////////////////////////////////////////////
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Determines if the specified index is contained within the TabStripModel.
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool ContainsIndex(int index) const;
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Adds the specified WebContents in the default location. Tabs opened
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // in the foreground inherit the group of the previously active tab.
1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void AppendWebContents(content::WebContents* contents, bool foreground);
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Adds the specified WebContents at the specified location.
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // |add_types| is a bitmask of AddTabTypes; see it for details.
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // All append/insert methods end up in this method.
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // NOTE: adding a tab using this method does NOT query the order controller,
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // as such the ADD_FORCE_INDEX AddTabTypes is meaningless here.  The only time
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the |index| is changed is if using the index would result in breaking the
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // constraint that all mini-tabs occur before non-mini-tabs.
1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // See also AddWebContents.
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void InsertWebContentsAt(int index,
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           content::WebContents* contents,
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           int add_types);
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Closes the WebContents at the specified index. This causes the
1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // WebContents to be destroyed, but it may not happen immediately.
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // |close_types| is a bitmask of CloseTypes. Returns true if the
1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // WebContents was closed immediately, false if it was not closed (we
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // may be waiting for a response from an onunload handler, or waiting for the
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // user to confirm closure).
1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool CloseWebContentsAt(int index, uint32 close_types);
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Replaces the WebContents at |index| with |new_contents|. The
1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // WebContents that was at |index| is returned and its ownership returns
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // to the caller.
1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  content::WebContents* ReplaceWebContentsAt(
1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      int index,
1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      content::WebContents* new_contents);
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Destroys the WebContents at the specified index, but keeps the tab
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // visible in the tab strip. Used to free memory in low-memory conditions,
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // especially on Chrome OS. The tab reloads if the user clicks on it.
1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Returns the new empty WebContents, used only for testing.
1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  content::WebContents* DiscardWebContentsAt(int index);
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Detaches the WebContents at the specified index from this strip. The
2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // WebContents is not destroyed, just removed from display. The caller
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // is responsible for doing something with it (e.g. stuffing it into another
2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // strip). Returns the detached WebContents.
2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  content::WebContents* DetachWebContentsAt(int index);
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Makes the tab at the specified index the active tab. |user_gesture| is true
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // if the user actually clicked on the tab or navigated to it using a keyboard
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // command, false if the tab was activated as a by-product of some other
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // action.
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void ActivateTabAt(int index, bool user_gesture);
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Adds tab at |index| to the currently selected tabs, without changing the
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // active tab index.
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void AddTabAtToSelection(int index);
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Move the WebContents at the specified index to another index. This
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // method does NOT send Detached/Attached notifications, rather it moves the
2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // WebContents inline and sends a Moved notification instead.
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If |select_after_move| is false, whatever tab was selected before the move
2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // will still be selected, but its index may have incremented or decremented
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // one slot.
2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // NOTE: This respects basic ordering constraints and thus does nothing if the
2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // move would result in app tabs and non-app tabs mixing.
2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void MoveWebContentsAt(int index, int to_position, bool select_after_move);
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Moves the selected tabs to |index|. |index| is treated as if the tab strip
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // did not contain any of the selected tabs. For example, if the tabstrip
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // contains [A b c D E f] (upper case selected) and this is invoked with 1 the
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // result is [b A D E c f].
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This method maintains that all mini-tabs occur before non-mini-tabs.  When
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // mini-tabs are selected the move is processed in two chunks: first mini-tabs
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // are moved, then non-mini-tabs are moved. If the index is after
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // (mini-tab-count - selected-mini-tab-count), then the index the non-mini
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // selected tabs are moved to is (index + selected-mini-tab-count). For
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // example, if the model consists of [A b c D E f] (A b c are mini) and this
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // is invoked with 2, the result is [b c A D E f]. In this example nothing
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // special happened because the target index was <= (mini-tab-count -
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // selected-mini-tab-count). If the target index were 3, then the result would
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // be [b c A f D F]. A, being mini, can move no further than index 2. The
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // non-mini-tabs are moved to the target index + selected-mini-tab-count (3 +
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // 1)
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void MoveSelectedTabsTo(int index);
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns the currently active WebContents, or NULL if there is none.
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::WebContents* GetActiveWebContents() const;
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns the WebContents at the specified index, or NULL if there is
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // none.
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::WebContents* GetWebContentsAt(int index) const;
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns the index of the specified WebContents, or TabStripModel::kNoTab
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // if the WebContents is not in this TabStripModel.
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int GetIndexOfWebContents(const content::WebContents* contents) const;
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Notify any observers that the WebContents at the specified index has
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // changed in some way. See TabChangeType for details of |change_type|.
2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void UpdateWebContentsStateAt(
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      int index,
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      TabStripModelObserver::TabChangeType change_type);
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Close all tabs at once. Code can use closing_all() above to defer
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // operations that might otherwise by invoked by the flurry of detach/select
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // notifications this method causes.
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void CloseAllTabs();
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns true if there are any WebContentses that are currently loading.
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool TabsAreLoading() const;
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns the WebContents that opened the WebContents at |index|, or NULL if
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // there is no opener on record.
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::WebContents* GetOpenerOfWebContentsAt(int index);
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Changes the |opener| of the WebContents at |index|.
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Note: |opener| must be in this tab strip.
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void SetOpenerOfWebContentsAt(int index, content::WebContents* opener);
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns the index of the next WebContents in the sequence of WebContentses
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // spawned by the specified WebContents after |start_index|. If |use_group| is
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // true, the group property of the tab is used instead of the opener to find
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the next tab. Under some circumstances the group relationship may exist but
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the opener may not.
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int GetIndexOfNextWebContentsOpenedBy(const content::WebContents* opener,
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        int start_index,
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        bool use_group) const;
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns the index of the last WebContents in the model opened by the
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // specified opener, starting at |start_index|.
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int GetIndexOfLastWebContentsOpenedBy(const content::WebContents* opener,
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        int start_index) const;
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // To be called when a navigation is about to occur in the specified
2932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // WebContents. Depending on the tab, and the transition type of the
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // navigation, the TabStripModel may adjust its selection and grouping
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // behavior.
2962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void TabNavigating(content::WebContents* contents,
2971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                     ui::PageTransition transition);
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Forget all Opener relationships that are stored (but _not_ group
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // relationships!) This is to reduce unpredictable tab switching behavior
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // in complex session states. The exact circumstances under which this method
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // is called are left up to the implementation of the selected
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TabStripModelOrderController.
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void ForgetAllOpeners();
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Forgets the group affiliation of the specified WebContents. This
3072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // should be called when a WebContents that is part of a logical group
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // of tabs is moved to a new logical context by the user (e.g. by typing a new
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // URL or selecting a bookmark). This also forgets the opener, which is
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // considered a weaker relationship than group.
3112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void ForgetGroup(content::WebContents* contents);
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns true if the group/opener relationships present for |contents|
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // should be reset when _any_ selection change occurs in the model.
3152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool ShouldResetGroupOnSelect(content::WebContents* contents) const;
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Changes the blocked state of the tab at |index|.
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void SetTabBlocked(int index, bool blocked);
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Changes the pinned state of the tab at |index|. See description above
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // class for details on this.
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void SetTabPinned(int index, bool pinned);
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns true if the tab at |index| is pinned.
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // See description above class for details on pinned tabs.
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool IsTabPinned(int index) const;
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Is the tab a mini-tab?
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // See description above class for details on this.
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool IsMiniTab(int index) const;
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Is the tab at |index| an app?
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // See description above class for details on app tabs.
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool IsAppTab(int index) const;
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns true if the tab at |index| is blocked by a tab modal dialog.
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool IsTabBlocked(int index) const;
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns true if the WebContents at |index| has been discarded to
3402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // save memory.  See DiscardWebContentsAt() for details.
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool IsTabDiscarded(int index) const;
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns the index of the first tab that is not a mini-tab. This returns
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // |count()| if all of the tabs are mini-tabs, and 0 if none of the tabs are
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // mini-tabs.
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int IndexOfFirstNonMiniTab() const;
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns a valid index for inserting a new tab into this model. |index| is
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the proposed index and |mini_tab| is true if inserting a tab will become
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // mini (pinned or app). If |mini_tab| is true, the returned index is between
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // 0 and IndexOfFirstNonMiniTab. If |mini_tab| is false, the returned index
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // is between IndexOfFirstNonMiniTab and count().
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int ConstrainInsertionIndex(int index, bool mini_tab);
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Extends the selection from the anchor to |index|.
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void ExtendSelectionTo(int index);
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Toggles the selection at |index|. This does nothing if |index| is selected
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // and there are no other selected tabs.
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void ToggleSelectionAt(int index);
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Makes sure the tabs from the anchor to |index| are selected. This only
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // adds to the selection.
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void AddSelectionFromAnchorTo(int index);
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns true if the tab at |index| is selected.
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool IsTabSelected(int index) const;
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Sets the selection to match that of |source|.
3702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void SetSelectionFromModel(const ui::ListSelectionModel& source);
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const ui::ListSelectionModel& selection_model() const {
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return selection_model_;
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Command level API /////////////////////////////////////////////////////////
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Adds a WebContents at the best position in the TabStripModel given
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the specified insertion index, transition, etc. |add_types| is a bitmask of
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // AddTabTypes; see it for details. This method ends up calling into
3812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // InsertWebContentsAt to do the actual insertion. Pass kNoTab for |index| to
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // append the contents to the end of the tab strip.
3832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void AddWebContents(content::WebContents* contents,
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      int index,
3851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                      ui::PageTransition transition,
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      int add_types);
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Closes the selected tabs.
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void CloseSelectedTabs();
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Select adjacent tabs
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void SelectNextTab();
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void SelectPreviousTab();
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Selects the last tab in the tab strip.
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void SelectLastTab();
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Swap adjacent tabs.
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void MoveTabNext();
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void MoveTabPrevious();
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // View API //////////////////////////////////////////////////////////////////
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Context menu functions.
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  enum ContextMenuCommand {
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CommandFirst = 0,
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CommandNewTab,
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CommandReload,
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CommandDuplicate,
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CommandCloseTab,
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CommandCloseOtherTabs,
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CommandCloseTabsToRight,
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CommandRestoreTab,
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CommandTogglePinned,
4151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    CommandToggleTabAudioMuted,
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CommandBookmarkAllTabs,
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CommandSelectByDomain,
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CommandSelectByOpener,
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CommandLast
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns true if the specified command is enabled. If |context_index| is
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // selected the response applies to all selected tabs.
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool IsContextMenuCommandEnabled(int context_index,
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   ContextMenuCommand command_id) const;
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Performs the action associated with the specified command for the given
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TabStripModel index |context_index|.  If |context_index| is selected the
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // command applies to all selected tabs.
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void ExecuteContextMenuCommand(int context_index,
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 ContextMenuCommand command_id);
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns a vector of indices of the tabs that will close when executing the
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // command |id| for the tab at |index|. The returned indices are sorted in
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // descending order.
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<int> GetIndicesClosedByCommand(int index,
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                             ContextMenuCommand id) const;
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns true if 'CommandTogglePinned' will pin. |index| is the index
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // supplied to |ExecuteContextMenuCommand|.
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool WillContextMenuPin(int index);
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Convert a ContextMenuCommand into a browser command. Returns true if a
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // corresponding browser command exists, false otherwise.
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static bool ContextMenuCommandToBrowserCommand(int cmd_id, int* browser_cmd);
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
4480f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  class WebContentsData;
4490f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Used when making selection notifications.
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  enum NotifyTypes {
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NOTIFY_DEFAULT,
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // The selection is changing from a user gesture.
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NOTIFY_USER_GESTURE,
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
458868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Convenience for converting a vector of indices into a vector of
459868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // WebContents.
460868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  std::vector<content::WebContents*> GetWebContentsFromIndices(
461868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      const std::vector<int>& indices) const;
462868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Gets the set of tab indices whose domain matches the tab at |index|.
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void GetIndicesWithSameDomain(int index, std::vector<int>* indices);
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Gets the set of tab indices that have the same opener as the tab at
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // |index|.
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void GetIndicesWithSameOpener(int index, std::vector<int>* indices);
4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If |index| is selected all the selected indices are returned, otherwise a
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // vector with |index| is returned. This is used when executing commands to
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // determine which indices the command applies to.
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<int> GetIndicesForCommand(int index) const;
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Returns true if the specified WebContents is a New Tab at the end of
4762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // the tabstrip. We check for this because opener relationships are _not_
4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // forgotten for the New Tab page opened as a result of a New Tab gesture
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // (e.g. Ctrl+T, etc) since the user may open a tab transiently to look up
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // something related to their current activity.
4802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool IsNewTabAtEndOfTabStrip(content::WebContents* contents) const;
4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Closes the WebContentses at the specified indices. This causes the
4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // WebContentses to be destroyed, but it may not happen immediately. If
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the page in question has an unload event the WebContents will not be
4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // destroyed until after the event has completed, which will then call back
4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // into this method.
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns true if the WebContentses were closed immediately, false if we
4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // are waiting for the result of an onunload handler.
4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool InternalCloseTabs(const std::vector<int>& indices,
4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         uint32 close_types);
4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Invoked from InternalCloseTabs and when an extension is removed for an app
4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // tab. Notifies observers of TabClosingAt and deletes |contents|. If
4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // |create_historical_tabs| is true, CreateHistoricalTab is invoked on the
4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // delegate.
4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The boolean parameter create_historical_tab controls whether to
4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // record these tabs and their history for reopening recently closed
5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // tabs.
5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void InternalCloseTab(content::WebContents* contents,
5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        int index,
5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        bool create_historical_tabs);
5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Gets the WebContents at an index. Does no bounds checking.
5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::WebContents* GetWebContentsAtImpl(int index) const;
5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Notifies the observers if the active tab is being deactivated.
5092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void NotifyIfTabDeactivated(content::WebContents* contents);
5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Notifies the observers if the active tab has changed.
5122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void NotifyIfActiveTabChanged(content::WebContents* old_contents,
5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                NotifyTypes notify_types);
5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Notifies the observers if the active tab or the tab selection has changed.
5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // |old_model| is a snapshot of |selection_model_| before the change.
5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Note: This function might end up sending 0 to 2 notifications in the
5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // following order: ActiveTabChanged, TabSelectionChanged.
5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void NotifyIfActiveOrSelectionChanged(
5202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      content::WebContents* old_contents,
5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NotifyTypes notify_types,
5222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const ui::ListSelectionModel& old_model);
5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Sets the selection to |new_model| and notifies any observers.
5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Note: This function might end up sending 0 to 3 notifications in the
5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // following order: TabDeactivated, ActiveTabChanged, TabSelectionChanged.
5272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void SetSelection(const ui::ListSelectionModel& new_model,
5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    NotifyTypes notify_types);
5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Selects either the next tab (|forward| is true), or the previous tab
5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // (|forward| is false).
5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void SelectRelativeTab(bool forward);
5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Does the work of MoveWebContentsAt. This has no checks to make sure the
5352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // position is valid, those are done in MoveWebContentsAt.
5362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void MoveWebContentsAtImpl(int index,
5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             int to_position,
5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             bool select_after_move);
5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Implementation of MoveSelectedTabsTo. Moves |length| of the selected tabs
5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // starting at |start| to |index|. See MoveSelectedTabsTo for more details.
5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void MoveSelectedTabsToImpl(int index, size_t start, size_t length);
5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns true if the tab represented by the specified data has an opener
5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // that matches the specified one. If |use_group| is true, then this will
5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // fall back to check the group relationship as well.
5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static bool OpenerMatches(const WebContentsData* data,
5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            const content::WebContents* opener,
5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            bool use_group);
5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Sets the group/opener of any tabs that reference |tab| to NULL.
5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void ForgetOpenersAndGroupsReferencing(const content::WebContents* tab);
5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Our delegate.
5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TabStripModelDelegate* delegate_;
5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The WebContents data currently hosted within this TabStripModel.
5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef std::vector<WebContentsData*> WebContentsDataVector;
5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WebContentsDataVector contents_data_;
5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // A profile associated with this TabStripModel.
5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Profile* profile_;
5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // True if all tabs are currently being closed via CloseAllTabs.
5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool closing_all_;
5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // An object that determines where new Tabs should be inserted and where
5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // selection should move when a Tab is closed.
5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<TabStripModelOrderController> order_controller_;
5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Our observers.
5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef ObserverList<TabStripModelObserver> TabStripModelObservers;
5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TabStripModelObservers observers_;
5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ui::ListSelectionModel selection_model_;
5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
577d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // TODO(sky): remove this; used for debugging 291265.
578d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  bool in_notify_;
579d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
580c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  base::WeakPtrFactory<TabStripModel> weak_factory_;
581c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_IMPLICIT_CONSTRUCTORS(TabStripModel);
5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // CHROME_BROWSER_UI_TABS_TAB_STRIP_MODEL_H_
586