blob: f316d144adf6069ccb74cd656c3c875d4235eb24 [file] [log] [blame]
// Copyright 2019 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_UI_TABS_TAB_GROUP_H_
#define CHROME_BROWSER_UI_TABS_TAB_GROUP_H_
#include <stddef.h>
#include <stdint.h>
#include <map>
#include <memory>
#include <string>
#include <vector>
#include "base/memory/raw_ptr.h"
#include "components/tab_groups/tab_group_id.h"
#include "components/tab_groups/tab_group_visual_data.h"
#include "third_party/abseil-cpp/absl/types/optional.h"
#include "ui/gfx/range/range.h"
class SavedTabGroupModel;
class TabGroupController;
// The metadata and state of a tab group. This handles state changes that are
// specific to tab groups and not grouped tabs. The latter (i.e. the groupness
// state of a tab) is handled by TabStripModel, which also notifies TabStrip of
// any grouped tab state changes that need to be reflected in the view. TabGroup
// handles similar notifications for tab group state changes.
class TabGroup {
public:
TabGroup(TabGroupController* controller,
const tab_groups::TabGroupId& id,
const tab_groups::TabGroupVisualData& visual_data);
~TabGroup();
const tab_groups::TabGroupId& id() const { return id_; }
const tab_groups::TabGroupVisualData* visual_data() const {
return visual_data_.get();
}
// Sets the visual data of the tab group. |is_customized| is true when this
// method is called from the user explicitly setting the data and defaults to
// false for callsites that may set the data such as tab restore. Once set to
// true, |is_customized| cannot be reset to false.
void SetVisualData(const tab_groups::TabGroupVisualData& visual_data,
bool is_customized = false);
// Returns a user-visible string describing the contents of the group, such as
// "Google Search and 3 other tabs". Used for accessibly describing the group,
// as well as for displaying in context menu items and tooltips when the group
// is unnamed.
std::u16string GetContentString() const;
// Updates internal bookkeeping for group contents, and notifies the
// controller that contents changed when a tab is added.
void AddTab();
// Updates internal bookkeeping for group contents, and notifies the
// controller that contents changed when a tab is removed.
void RemoveTab();
// The number of tabs in this group, determined by AddTab() and
// RemoveTab() calls.
int tab_count() const { return tab_count_; }
// Returns whether the group has no tabs.
bool IsEmpty() const;
// Returns whether the user has explicitly set the visual data themselves.
bool IsCustomized() const;
// Returns whether the user set the group as saved or not.
bool IsSaved() const;
// Gets the model index of this group's first tab, or nullopt if it is
// empty. Similar to ListTabs() it traverses through TabStripModel's
// tabs. Unlike ListTabs() this is always safe to call.
absl::optional<int> GetFirstTab() const;
// Gets the model index of this group's last tab, or nullopt if it is
// empty. Similar to ListTabs() it traverses through TabStripModel's
// tabs. Unlike ListTabs() this is always safe to call.
absl::optional<int> GetLastTab() const;
// Returns the range of tab model indices this group contains. Notably
// does not rely on the TabGroup's internal metadata, but rather
// traverses directly through the tabs in TabStripModel.
//
// The returned range will never be a reverse range. It will always be
// a forward range, or the empty range {0,0}.
//
// This method can only be called when a group is contiguous. A group
// may not be contiguous in some TabStripModel intermediate states.
// Notably, any operation that groups tabs then moves them into
// position exposes these states.
//
// This is only a concern for TabStripModelObservers who query
// TabStripModel after observer notifications. While each call to
// TabStripModel's public API leaves groups in a contiguous state,
// observers are notified of some changes in during intermediate
// steps.
gfx::Range ListTabs() const;
// Currently only sets is_saved_ to true but in the future should also
// place the group into the bookmarks bar.
void SaveGroup();
// Currently only sets is_saved_ to false but in the future should also
// take the group out of the bookmakrs bar.
void UnsaveGroup();
private:
raw_ptr<TabGroupController> controller_;
// Used to check if `id_` is saved in the `SavedTabGroupModel`.
// `SavedTabGroupModel` is tied to the Profile and should outlive this.
const raw_ptr<SavedTabGroupModel> saved_tab_group_model_;
tab_groups::TabGroupId id_;
std::unique_ptr<tab_groups::TabGroupVisualData> visual_data_;
int tab_count_ = 0;
bool is_customized_ = false;
bool is_saved_ = false;
};
#endif // CHROME_BROWSER_UI_TABS_TAB_GROUP_H_