blob: d61613ee2b5ff2c327821ad442453b2442dc8bec [file] [log] [blame]
// Copyright (c) 2009 The Chromium Authors. All rights reserved.TIT
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_GTK_BOOKMARK_MANAGER_GTK_H_
#define CHROME_BROWSER_GTK_BOOKMARK_MANAGER_GTK_H_
#include <gtk/gtk.h>
#include <vector>
#include "base/basictypes.h"
#include "base/gfx/rect.h"
#include "base/ref_counted.h"
#include "base/task.h"
#include "chrome/browser/bookmarks/bookmark_model_observer.h"
#include "chrome/browser/gtk/bookmark_context_menu.h"
#include "chrome/browser/shell_dialogs.h"
#include "chrome/common/gtk_tree.h"
class BookmarkModel;
class BookmarkTableModel;
class Profile;
class BookmarkManagerGtk : public BookmarkModelObserver,
public gtk_tree::ModelAdapter::Delegate,
public SelectFileDialog::Listener {
public:
virtual ~BookmarkManagerGtk();
Profile* profile() { return profile_; }
// Show the node in the tree.
void SelectInTree(const BookmarkNode* node, bool expand);
// Shows the bookmark manager. Only one bookmark manager exists.
static void Show(Profile* profile);
// BookmarkModelObserver implementation.
// The implementations of these functions only affect the left side tree view
// as changes to the right side are handled via TableModelObserver callbacks.
virtual void Loaded(BookmarkModel* model);
virtual void BookmarkModelBeingDeleted(BookmarkModel* model);
virtual void BookmarkNodeMoved(BookmarkModel* model,
const BookmarkNode* old_parent,
int old_index,
const BookmarkNode* new_parent,
int new_index);
virtual void BookmarkNodeAdded(BookmarkModel* model,
const BookmarkNode* parent,
int index);
virtual void BookmarkNodeRemoved(BookmarkModel* model,
const BookmarkNode* parent,
int old_index,
const BookmarkNode* node);
virtual void BookmarkNodeChanged(BookmarkModel* model,
const BookmarkNode* node);
virtual void BookmarkNodeChildrenReordered(BookmarkModel* model,
const BookmarkNode* node);
virtual void BookmarkNodeFavIconLoaded(BookmarkModel* model,
const BookmarkNode* node);
// gtk_tree::ModelAdapter::Delegate implementation.
virtual void SetColumnValues(int row, GtkTreeIter* iter);
virtual void OnModelChanged();
// SelectFileDialog::Listener implemenation.
virtual void FileSelected(const FilePath& path,
int index, void* params);
private:
explicit BookmarkManagerGtk(Profile* profile);
void InitWidgets();
GtkWidget* MakeLeftPane();
GtkWidget* MakeRightPane();
// Set |window_|'s initial size, using its previous size if that was saved.
void SetInitialWindowSize();
// Connects the ctrl-w accelerator to the window.
void ConnectAccelerators();
// If |left|, then make the organize menu refer to that which is selected in
// the left pane, otherwise use the right pane selection.
void ResetOrganizeMenu(bool left);
// Pack the data from the bookmark model into the stores. This does not
// create the stores, which is done in Make{Left,Right}Pane().
// This one should only be called once (when the bookmark model is loaded).
void BuildLeftStore();
// This one clears the old right pane and refills it with the contents of
// whatever folder is selected on the left. It can be called multiple times.
void BuildRightStore();
// Reset the TableModel backing the right pane.
void ResetRightStoreModel();
// Get the ID of the item at |iter|.
int64 GetRowIDAt(GtkTreeModel* model, GtkTreeIter* iter);
// Get the node from |model| at |iter|. If the item is not a node, return
// NULL.
const BookmarkNode* GetNodeAt(GtkTreeModel* model, GtkTreeIter* iter);
// Get the node that is selected in the left tree view.
const BookmarkNode* GetFolder();
// Get the ID of the selected row.
int GetSelectedRowID();
// Get the nodes that are selected in the right tree view.
std::vector<const BookmarkNode*> GetRightSelection();
// Set the size of a column based on the user prefs, and also sets the sizing
// properties of the column.
void SizeColumn(GtkTreeViewColumn* column,
const wchar_t* prefname);
// Calls SizeColumn() on each of the right tree view columns.
void SizeColumns();
// Save the column widths into the pref service. Column widths are stored
// separately depending on whether the path column is showing.
void SaveColumnConfiguration();
// Flush the saved mousedown. Should only be called when |delaying_mousedown_|
// is true.
void SendDelayedMousedown();
GtkTreeSelection* left_selection() {
return gtk_tree_view_get_selection(GTK_TREE_VIEW(left_tree_view_));
}
GtkTreeSelection* right_selection() {
return gtk_tree_view_get_selection(GTK_TREE_VIEW(right_tree_view_));
}
// Use these to temporarily disable updating the right store. You can stack
// calls to Suppress(), but they should always be matched by an equal number
// of calls to Allow().
void SuppressUpdatesToRightStore();
void AllowUpdatesToRightStore();
// Tries to find the node with id |target_id|. If found, returns true and set
// |iter| to point to the entry. If you pass a |iter| with stamp of 0, then it
// will be treated as the first row of |model|.
bool RecursiveFind(GtkTreeModel* model, GtkTreeIter* iter, int64 target_id);
// Search helpers.
void PerformSearch();
void OnSearchTextChanged();
static void OnSearchTextChangedThunk(GtkWidget* search_entry,
BookmarkManagerGtk* bookmark_manager) {
bookmark_manager->OnSearchTextChanged();
}
// TreeView signal handlers.
static void OnLeftSelectionChanged(GtkTreeSelection* selection,
BookmarkManagerGtk* bm);
static void OnRightSelectionChanged(GtkTreeSelection* selection,
BookmarkManagerGtk* bm);
static void OnLeftTreeViewDragReceived(GtkWidget* tree_view,
GdkDragContext* context,
gint x,
gint y,
GtkSelectionData* selection_data,
guint target_type,
guint time,
BookmarkManagerGtk* bm);
static gboolean OnLeftTreeViewDragMotion(GtkWidget* tree_view,
GdkDragContext* context,
gint x,
gint y,
guint time,
BookmarkManagerGtk* bm);
static void OnLeftTreeViewRowCollapsed(GtkTreeView* tree_view,
GtkTreeIter* iter,
GtkTreePath* path,
BookmarkManagerGtk* bm);
static void OnRightTreeViewDragGet(GtkWidget* tree_view,
GdkDragContext* context,
GtkSelectionData* selection_data,
guint target_type,
guint time,
BookmarkManagerGtk* bm);
static void OnRightTreeViewDragReceived(GtkWidget* tree_view,
GdkDragContext* context,
gint x,
gint y,
GtkSelectionData* selection_data,
guint target_type,
guint time,
BookmarkManagerGtk* bm);
static void OnRightTreeViewDragBegin(GtkWidget* tree_view,
GdkDragContext* drag_context,
BookmarkManagerGtk* bm);
static gboolean OnRightTreeViewDragMotion(GtkWidget* tree_view,
GdkDragContext* context,
gint x,
gint y,
guint time,
BookmarkManagerGtk* bm);
static void OnRightTreeViewRowActivated(GtkTreeView* tree_view,
GtkTreePath* path,
GtkTreeViewColumn* column,
BookmarkManagerGtk* bm);
static void OnRightTreeViewFocusIn(GtkTreeView* tree_view,
GdkEventFocus* event,
BookmarkManagerGtk* bm);
static void OnLeftTreeViewFocusIn(GtkTreeView* tree_view,
GdkEventFocus* event,
BookmarkManagerGtk* bm);
static gboolean OnRightTreeViewButtonPress(GtkWidget* tree_view,
GdkEventButton* event,
BookmarkManagerGtk* bm);
static gboolean OnRightTreeViewMotion(GtkWidget* tree_view,
GdkEventMotion* event,
BookmarkManagerGtk* bm);
static gboolean OnTreeViewButtonPress(GtkWidget* tree_view,
GdkEventButton* button,
BookmarkManagerGtk* bm);
static gboolean OnTreeViewButtonRelease(GtkWidget* tree_view,
GdkEventButton* button,
BookmarkManagerGtk* bm);
static gboolean OnTreeViewKeyPress(GtkWidget* tree_view,
GdkEventKey* key,
BookmarkManagerGtk* bm);
// Tools menu item callbacks.
static void OnImportItemActivated(GtkMenuItem* menuitem,
BookmarkManagerGtk* bm);
static void OnExportItemActivated(GtkMenuItem* menuitem,
BookmarkManagerGtk* bm);
// Window callbacks.
static gboolean OnWindowDestroyedThunk(GtkWidget* window, gpointer self) {
return reinterpret_cast<BookmarkManagerGtk*>(self)->
OnWindowDestroyed(window);
}
gboolean OnWindowDestroyed(GtkWidget* window);
static gboolean OnWindowStateChangedThunk(GtkWidget* window,
GdkEventWindowState* event,
gpointer self) {
return reinterpret_cast<BookmarkManagerGtk*>(self)->
OnWindowStateChanged(window, event);
}
gboolean OnWindowStateChanged(GtkWidget* window, GdkEventWindowState* event);
static gboolean OnWindowConfiguredThunk(GtkWidget* window,
GdkEventConfigure* event,
gpointer self) {
return reinterpret_cast<BookmarkManagerGtk*>(self)->
OnWindowConfigured(window, event);
}
gboolean OnWindowConfigured(GtkWidget* window, GdkEventConfigure* event);
// Handles an accelerator being pressed.
static gboolean OnGtkAccelerator(GtkAccelGroup* accel_group,
GObject* acceleratable,
guint keyval,
GdkModifierType modifier,
BookmarkManagerGtk* bookmark_manager);
GtkWidget* window_;
GtkWidget* search_entry_;
Profile* profile_;
BookmarkModel* model_;
GtkWidget* paned_;
GtkWidget* left_tree_view_;
GtkWidget* right_tree_view_;
enum {
RIGHT_PANE_PIXBUF,
RIGHT_PANE_TITLE,
RIGHT_PANE_URL,
RIGHT_PANE_PATH,
RIGHT_PANE_ID,
RIGHT_PANE_NUM
};
GtkTreeStore* left_store_;
GtkListStore* right_store_;
GtkTreeViewColumn* title_column_;
GtkTreeViewColumn* url_column_;
GtkTreeViewColumn* path_column_;
scoped_ptr<BookmarkTableModel> right_tree_model_;
scoped_ptr<gtk_tree::ModelAdapter> right_tree_adapter_;
// |window_|'s current position and size.
gfx::Rect window_bounds_;
// Flags describing |window_|'s current state.
GdkWindowState window_state_;
// The Organize menu item.
GtkWidget* organize_;
// The submenu the item pops up.
scoped_ptr<BookmarkContextMenu> organize_menu_;
// Whether the menu refers to the left selection.
bool organize_is_for_left_;
// Factory used for delaying search.
ScopedRunnableMethodFactory<BookmarkManagerGtk> search_factory_;
scoped_refptr<SelectFileDialog> select_file_dialog_;
// These variables are used for the workaround for http://crbug.com/15240.
// The last mouse down we got. Only valid while |delaying_mousedown| is true.
GdkEventButton mousedown_event_;
bool delaying_mousedown_;
// This is true while we are propagating a delayed mousedown. It is used to
// tell the button press handler to ignore the event.
bool sending_delayed_mousedown_;
// This is used to avoid recursively calling our right click handler. It is
// only true when a right click is already being handled.
bool ignore_rightclicks_;
};
#endif // CHROME_BROWSER_GTK_BOOKMARK_MANAGER_GTK_H_