[gedit] Use of listbox widget for document panel



commit 75ad5eaa2b24550904c99a460a2c42c43f668242
Author: Sebastien Lafargue <slaf66 gmail com>
Date:   Sat Feb 8 18:06:46 2014 +0100

    Use of listbox widget for document panel
    
    https://bugzilla.gnome.org/show_bug.cgi?id=723566

 gedit/Makefile.am                  |    2 -
 gedit/gedit-cell-renderer-button.c |  102 --
 gedit/gedit-cell-renderer-button.h |   59 --
 gedit/gedit-documents-panel.c      | 1787 +++++++++++++++++++++---------------
 gedit/gedit-notebook.c             |    5 +-
 5 files changed, 1032 insertions(+), 923 deletions(-)
---
diff --git a/gedit/Makefile.am b/gedit/Makefile.am
index cc5aa17..d3f46db 100644
--- a/gedit/Makefile.am
+++ b/gedit/Makefile.am
@@ -108,7 +108,6 @@ gedit_built_sources =                       \
        gedit/gedit-marshal.h
 
 gedit_NOINST_H_FILES =                         \
-       gedit/gedit-cell-renderer-button.h      \
        gedit/gedit-close-confirmation-dialog.h \
        gedit/gedit-dirs.h                      \
        gedit/gedit-document-input-stream.h     \
@@ -174,7 +173,6 @@ gedit_libgedit_private_la_SOURCES =         \
 
 gedit_libgedit_c_files =                       \
        gedit/gedit-app.c                       \
-       gedit/gedit-cell-renderer-button.c      \
        gedit/gedit-close-confirmation-dialog.c \
        gedit/gedit-commands-documents.c        \
        gedit/gedit-commands-edit.c             \
diff --git a/gedit/gedit-documents-panel.c b/gedit/gedit-documents-panel.c
index f0e8b61..918d706 100644
--- a/gedit/gedit-documents-panel.c
+++ b/gedit/gedit-documents-panel.c
@@ -2,7 +2,7 @@
  * gedit-documents-panel.c
  * This file is part of gedit
  *
- * Copyright (C) 2005 - Paolo Maggi
+ * Copyright (C) 2014 - Sebastien Lafargue <slaf66 gmail com>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -28,24 +28,91 @@
 #include "gedit-multi-notebook.h"
 #include "gedit-notebook.h"
 #include "gedit-notebook-popup-menu.h"
-#include "gedit-cell-renderer-button.h"
 
 #include <glib/gi18n.h>
 
+typedef struct _GeditDocumentsGenericRow GeditDocumentsGenericRow;
+typedef struct _GeditDocumentsGenericRow GeditDocumentsGroupRow;
+typedef struct _GeditDocumentsGenericRow GeditDocumentsDocumentRow;
+
+struct _GeditDocumentsGenericRow
+{
+       GtkListBoxRow        parent;
+
+       GeditDocumentsPanel *panel;
+       GtkWidget           *ref;
+       gchar               *name;
+
+       GtkWidget           *row_event_box;
+       GtkWidget           *row_box;
+       GtkWidget           *label;
+
+       gint                 row_min_height;
+
+       GtkWidget           *close_button_image;
+       GtkWidget           *close_button_event_box;
+
+       /* Not used in GeditDocumentsGroupRow */
+       GtkWidget           *pixbuf_box;
+       GtkWidget           *image;
+};
+
+#define GEDIT_TYPE_DOCUMENTS_GROUP_ROW            (gedit_documents_group_row_get_type ())
+#define GEDIT_DOCUMENTS_GROUP_ROW(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), 
GEDIT_TYPE_DOCUMENTS_GROUP_ROW, GeditDocumentsGroupRow))
+#define GEDIT_DOCUMENTS_GROUP_ROW_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass),  
GEDIT_TYPE_DOCUMENTS_GROUP_ROW, GeditDocumentsGroupRowClass))
+#define GEDIT_IS_DOCUMENTS_GROUP_ROW(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), 
GEDIT_TYPE_DOCUMENTS_GROUP_ROW))
+#define GEDIT_IS_DOCUMENTS_GROUP_ROW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass),  
GEDIT_TYPE_DOCUMENTS_GROUP_ROW))
+#define GEDIT_DOCUMENTS_GROUP_ROW_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj),  
GEDIT_TYPE_DOCUMENTS_GROUP_ROW, GeditDocumentsGroupRowClass))
+
+typedef struct _GeditDocumentsGroupRowClass GeditDocumentsGroupRowClass;
+
+struct _GeditDocumentsGroupRowClass
+{
+       GtkListBoxRowClass parent_class;
+};
+
+GType gedit_documents_group_row_get_type (void) G_GNUC_CONST;
+
+G_DEFINE_TYPE (GeditDocumentsGroupRow, gedit_documents_group_row, GTK_TYPE_LIST_BOX_ROW)
+
+#define GEDIT_TYPE_DOCUMENTS_DOCUMENT_ROW            (gedit_documents_document_row_get_type ())
+#define GEDIT_DOCUMENTS_DOCUMENT_ROW(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), 
GEDIT_TYPE_DOCUMENTS_DOCUMENT_ROW, GeditDocumentsDocumentRow))
+#define GEDIT_DOCUMENTS_DOCUMENT_ROW_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass),  
GEDIT_TYPE_DOCUMENTS_DOCUMENT_ROW, GeditDocumentsDocumentRowClass))
+#define GEDIT_IS_DOCUMENTS_DOCUMENT_ROW(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), 
GEDIT_TYPE_DOCUMENTS_DOCUMENT_ROW))
+#define GEDIT_IS_DOCUMENTS_DOCUMENT_ROW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass),  
GEDIT_TYPE_DOCUMENTS_DOCUMENT_ROW))
+#define GEDIT_DOCUMENTS_DOCUMENT_ROW_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj),  
GEDIT_TYPE_DOCUMENTS_DOCUMENT_ROW, GeditDocumentsDocumentRowClass))
+
+typedef struct _GeditDocumentsDocumentRowClass GeditDocumentsDocumentRowClass;
+
+struct _GeditDocumentsDocumentRowClass
+{
+       GtkListBoxRowClass parent_class;
+};
+
+GType gedit_documents_document_row_get_type (void) G_GNUC_CONST;
+
+G_DEFINE_TYPE (GeditDocumentsDocumentRow, gedit_documents_document_row, GTK_TYPE_LIST_BOX_ROW)
+
+static GtkWidget * gedit_documents_document_row_new (GeditDocumentsPanel *panel, GeditTab *tab);
+static GtkWidget * gedit_documents_group_row_new    (GeditDocumentsPanel *panel, GeditNotebook *notebook);
+
 struct _GeditDocumentsPanelPrivate
 {
        GeditWindow        *window;
        GeditMultiNotebook *mnb;
-
-       GtkWidget          *treeview;
-       GtkTreeModel       *model;
+       GtkWidget          *listbox;
 
        guint               selection_changed_handler_id;
-       guint               refresh_idle_id;
+       guint               tab_switched_handler_id;
+       gboolean            is_in_tab_switched;
 
-       guint               adding_tab : 1;
-       guint               is_reodering : 1;
-       guint               setting_active_notebook : 1;
+       /* Flag to workaround first GroupRow selection at start ( we don't want to show it ) */
+       gboolean            first_selection;
+
+       GtkAdjustment      *adjustment;
+
+       guint               nb_row_notebook;
+       guint               nb_row_tab;
 };
 
 G_DEFINE_TYPE_WITH_PRIVATE (GeditDocumentsPanel, gedit_documents_panel, GTK_TYPE_BOX)
@@ -56,218 +123,254 @@ enum
        PROP_WINDOW
 };
 
-enum
-{
-       PIXBUF_COLUMN = 0,
-       NAME_COLUMN,
-       NOTEBOOK_COLUMN,
-       TAB_COLUMN,
-       N_COLUMNS
-};
+#define MAX_DOC_NAME_LENGTH 60
 
-#define MAX_DOC_NAME_LENGTH    60
-#define NB_NAME_DATA_KEY       "DocumentsPanelNotebookNameKey"
-#define TAB_NB_DATA_KEY                "DocumentsPanelTabNotebookKey"
+#define ROW_HEADER_SIZE 24
 
+/* Same size as GTK_ICON_SIZE_MENU used to define the close_button_image */
+#define ROW_MIN_HEIGHT 16
 
-static gchar *
-notebook_get_name (GeditMultiNotebook *mnb,
-                  GeditNotebook      *notebook)
+static guint
+get_nb_visible_rows (GeditDocumentsPanel *panel)
 {
-       guint num;
+       guint nb = 0;
 
-       num = gedit_multi_notebook_get_notebook_num (mnb, notebook);
+       if (panel->priv->nb_row_notebook > 1)
+       {
+               nb += panel->priv->nb_row_notebook;
+       }
+
+       nb += panel->priv->nb_row_tab;
 
-       return g_markup_printf_escaped ("Tab Group %i", num + 1);
+       return nb;
 }
 
-static gchar *
-tab_get_name (GeditTab *tab)
+static guint
+get_row_visible_index (GeditDocumentsPanel *panel,
+                       GtkWidget           *searched_row)
 {
-       GeditDocument *doc;
-       gchar *name;
-       gchar *docname;
-       gchar *tab_name;
-
-       gedit_debug (DEBUG_PANEL);
-
-       g_return_val_if_fail (GEDIT_IS_TAB (tab), NULL);
-
-       doc = gedit_tab_get_document (tab);
-
-       name = gedit_document_get_short_name_for_display (doc);
+       GList *children;
+       GList *l;
+       guint nb_notebook_row = 0;
+       guint nb_tab_row = 0;
 
-       /* Truncate the name so it doesn't get insanely wide. */
-       docname = gedit_utils_str_middle_truncate (name, MAX_DOC_NAME_LENGTH);
+       children = gtk_container_get_children (GTK_CONTAINER (panel->priv->listbox));
 
-       if (gtk_text_buffer_get_modified (GTK_TEXT_BUFFER (doc)))
+       for (l = children; l != NULL; l = g_list_next (l))
        {
-               if (gedit_document_get_readonly (doc))
+               GtkWidget *row = l->data;
+
+               if (GEDIT_IS_DOCUMENTS_GROUP_ROW (row))
                {
-                       tab_name = g_markup_printf_escaped ("<i>%s</i> [<i>%s</i>]",
-                                                           docname,
-                                                           _("Read-Only"));
+                       nb_notebook_row += 1;
                }
                else
                {
-                       tab_name = g_markup_printf_escaped ("<i>%s</i>",
-                                                           docname);
+                       nb_tab_row += 1;
                }
+
+               if (row == searched_row)
+               {
+                       break;
+               }
+       }
+
+       g_list_free (children);
+
+       if (panel->priv->nb_row_notebook == 1)
+       {
+               nb_notebook_row = 0;
+       }
+
+       return nb_tab_row + nb_notebook_row - 1;
+}
+
+/* We do not grab focus on the row, so scroll it into view manually */
+static void
+make_row_visible (GeditDocumentsPanel *panel,
+                  GtkWidget           *row)
+{
+       gdouble adjustment_value;
+       gdouble adjustment_lower;
+       gdouble adjustment_upper;
+       gdouble adjustment_page_size;
+       gdouble nb_visible_rows;
+       gdouble row_visible_index;
+       gdouble row_size;
+       gdouble row_position;
+       gdouble offset;
+       gdouble new_adjustment_value;
+
+       adjustment_value = gtk_adjustment_get_value (panel->priv->adjustment);
+       adjustment_lower = gtk_adjustment_get_lower (panel->priv->adjustment);
+       adjustment_upper = gtk_adjustment_get_upper (panel->priv->adjustment);
+       adjustment_page_size = gtk_adjustment_get_page_size (panel->priv->adjustment);
+
+       nb_visible_rows = get_nb_visible_rows (panel);
+       row_visible_index = get_row_visible_index (panel, GTK_WIDGET (row));
+
+       row_size = (adjustment_upper - adjustment_lower) / nb_visible_rows;
+       row_position =  row_size * row_visible_index;
+
+       if (row_position < adjustment_value)
+       {
+               new_adjustment_value = row_position;
+       }
+       else if ((row_position + row_size) > (adjustment_value + adjustment_page_size))
+       {
+               offset = (row_position + row_size) - (adjustment_value + adjustment_page_size);
+               new_adjustment_value = adjustment_value + offset;
        }
        else
        {
-               if (gedit_document_get_readonly (doc))
-               {
-                       tab_name = g_markup_printf_escaped ("%s [<i>%s</i>]",
-                                                           docname,
-                                                           _("Read-Only"));
-               }
-               else
-               {
-                       tab_name = g_markup_escape_text (docname, -1);
-               }
+               new_adjustment_value = adjustment_value;
        }
 
-       g_free (docname);
-       g_free (name);
+       gtk_adjustment_set_value (panel->priv->adjustment, new_adjustment_value);
+}
 
-       return tab_name;
+/* This function is a GCompareFunc to use with g_list_find_custom */
+static gint
+listbox_search_function (gconstpointer row,
+                         gconstpointer item)
+{
+       GeditDocumentsGenericRow *generic_row = (GeditDocumentsGenericRow *)row;
+       gpointer *searched_item = (gpointer *)generic_row->ref;
+
+       return (searched_item == item) ? 0 : -1;
 }
 
-static gboolean
-get_iter_from_tab (GeditDocumentsPanel *panel,
-                  GeditNotebook       *notebook,
-                  GeditTab            *tab,
-                  GtkTreeIter         *tab_iter)
+static GtkListBoxRow *
+get_row_from_notebook (GeditDocumentsPanel *panel,
+                       GeditNotebook       *notebook)
 {
-       GtkTreeIter parent;
-       gboolean success;
-       gboolean search_notebook;
+       GList *children;
+       GList *item;
+       GtkListBoxRow *row;
 
-       /* Note: we cannot use the functions of the MultiNotebook
-        *       because in cases where the notebook or tab has been
-        *       removed already we will fail to get an iter.
-        */
+       children = gtk_container_get_children (GTK_CONTAINER (panel->priv->listbox));
 
-       gedit_debug (DEBUG_PANEL);
+       item = g_list_find_custom (children, notebook, listbox_search_function);
+       row = item ? (item->data) : NULL;
 
-       g_assert (notebook != NULL);
-       /* tab may be NULL if just the notebook is specified */
-       g_assert (tab_iter != NULL);
+       g_list_free (children);
 
-       search_notebook = (gedit_multi_notebook_get_n_notebooks (panel->priv->mnb) > 1);
+       return row;
+}
 
-       if (!gtk_tree_model_get_iter_first (panel->priv->model, &parent))
-               return FALSE;
+static GtkListBoxRow *
+get_row_from_tab (GeditDocumentsPanel *panel,
+                  GeditTab            *tab)
+{
+       GList *children;
+       GList *item;
+       GtkListBoxRow *row;
+
+       children = gtk_container_get_children (GTK_CONTAINER (panel->priv->listbox));
 
-       success = FALSE;
-       do
+       item = g_list_find_custom (children, tab, listbox_search_function);
+       row = item ? (item->data) : NULL;
+
+       g_list_free (children);
+       return row;
+}
+
+static void
+row_select (GeditDocumentsPanel *panel,
+            GtkListBox          *listbox,
+            GtkListBoxRow       *row)
+{
+       GtkListBoxRow *selected_row = gtk_list_box_get_selected_row (listbox);
+
+       if (row != selected_row)
        {
-               GtkTreeIter iter;
+               g_signal_handler_block (listbox, panel->priv->selection_changed_handler_id);
+               gtk_list_box_select_row (listbox, row);
+               g_signal_handler_unblock (listbox, panel->priv->selection_changed_handler_id);
+       }
 
-               if (search_notebook)
-               {
-                       GeditNotebook *current_notebook;
-
-                       gtk_tree_model_get (panel->priv->model,
-                                           &parent,
-                                           NOTEBOOK_COLUMN, &current_notebook,
-                                           -1);
-
-                       if (current_notebook != NULL)
-                       {
-                               gboolean is_cur;
-                               is_cur = (current_notebook == notebook);
-
-                               g_object_unref (current_notebook);
-
-                               if (is_cur)
-                               {
-                                       /* notebook found */
-                                       search_notebook = FALSE;
-                                       gtk_tree_model_iter_children (panel->priv->model, &iter, &parent);
-                               }
-                       }
-               }
-               else
-               {
-                       iter = parent;
-               }
+       make_row_visible (panel, GTK_WIDGET (row));
+}
 
-               if (!search_notebook)
-               {
-                       if (tab == NULL)
-                       {
-                               success = TRUE;
-                               break;
-                       }
-
-                       g_assert (gtk_tree_store_iter_is_valid (GTK_TREE_STORE (panel->priv->model),
-                                                               &iter));
-
-                       do
-                       {
-                               GeditTab *current_tab;
-
-                               gtk_tree_model_get (panel->priv->model,
-                                                   &iter,
-                                                   TAB_COLUMN, &current_tab,
-                                                   -1);
-
-                               if (current_tab != NULL)
-                               {
-                                       gboolean is_cur;
-
-                                       is_cur = (current_tab == tab);
-                                       g_object_unref (current_tab);
-
-                                       if (is_cur)
-                                       {
-                                               *tab_iter = iter;
-                                               success = TRUE;
-
-                                               /* break 2; */
-                                               goto out;
-                                       }
-                               }
-                       } while (gtk_tree_model_iter_next (panel->priv->model, &iter));
-
-                       /* We already found the notebook and the tab was not found */
-                       g_assert (!success);
-               }
-       } while (gtk_tree_model_iter_next (panel->priv->model, &parent));
+static void
+menu_position (GtkMenu   *menu,
+               gint      *x,
+               gint      *y,
+               gboolean  *push_in,
+               GtkWidget *row)
+{
+       gint menu_y;
+       GtkRequisition requisition;
+       GtkAllocation allocation;
+
+       gdk_window_get_origin (gtk_widget_get_window (row), x, y);
+       gtk_widget_get_preferred_size (GTK_WIDGET (menu), &requisition, NULL);
+       gtk_widget_get_allocation (row, &allocation);
+
+       if (gtk_widget_get_direction (row) == GTK_TEXT_DIR_RTL)
+       {
+               *x += allocation.x + allocation.width - requisition.width - 10;
+       }
+       else
+       {
+               *x += allocation.x + 10;
+       }
+
+       menu_y = *y + (allocation.y) + 5;
+       menu_y = MIN (menu_y, *y + allocation.height - requisition.height - 5);
 
-out:
+       *y = menu_y;
 
-       return success;
+       *push_in = TRUE;
 }
 
 static void
-select_iter (GeditDocumentsPanel *panel,
-            GtkTreeIter         *iter)
+row_state_changed (GtkWidget           *row,
+                   GtkStateFlags        previous_flags,
+                   GeditDocumentsPanel *panel)
 {
-       GtkTreeView *treeview = GTK_TREE_VIEW (panel->priv->treeview);
-       GtkTreeSelection *selection;
-       GtkTreePath *path;
+       GtkStateFlags flags;
+       GeditDocumentsGenericRow *generic_row = (GeditDocumentsGenericRow *)row;
 
-       selection = gtk_tree_view_get_selection (treeview);
+       flags = gtk_widget_get_state_flags (row);
 
-       gtk_tree_selection_select_iter (selection, iter);
+       gtk_widget_set_visible (generic_row->close_button_image,
+                               flags & GTK_STATE_FLAG_PRELIGHT);
 
-       path = gtk_tree_model_get_path (panel->priv->model, iter);
-       gtk_tree_view_scroll_to_cell (treeview,
-                                     path, NULL,
-                                     FALSE,
-                                     0, 0);
-       gtk_tree_path_free (path);
+       if (GEDIT_IS_DOCUMENTS_GROUP_ROW (row))
+       {
+               GTK_WIDGET_CLASS (gedit_documents_group_row_parent_class)->state_flags_changed (row, 
previous_flags);
+       }
+       else
+       {
+               GTK_WIDGET_CLASS (gedit_documents_document_row_parent_class)->state_flags_changed (row, 
previous_flags);
+       }
+}
+
+static void
+insert_row (GeditDocumentsPanel *panel,
+            GtkListBox          *listbox,
+            GtkWidget           *row,
+            gint                 position)
+{
+       g_signal_handler_block (listbox, panel->priv->selection_changed_handler_id);
+
+       gtk_list_box_insert (listbox, row, position);
+
+       g_signal_connect (row,
+                         "state-flags-changed",
+                         G_CALLBACK (row_state_changed),
+                         panel);
+
+       g_signal_handler_unblock (listbox, panel->priv->selection_changed_handler_id);
 }
 
 static void
 select_active_tab (GeditDocumentsPanel *panel)
 {
        GeditNotebook *notebook;
-       GeditTab *tab;
        gboolean have_tabs;
+       GeditTab *tab;
 
        notebook = gedit_multi_notebook_get_active_notebook (panel->priv->mnb);
        have_tabs = gtk_notebook_get_n_pages (GTK_NOTEBOOK (notebook)) > 0;
@@ -275,259 +378,299 @@ select_active_tab (GeditDocumentsPanel *panel)
 
        if (notebook != NULL && tab != NULL && have_tabs)
        {
-               GtkTreeIter iter;
+               GtkListBoxRow *row = get_row_from_tab (panel, tab);
 
-               if (get_iter_from_tab (panel, notebook, tab, &iter))
-                       select_iter (panel, &iter);
+               if (row)
+               {
+                       row_select (panel, GTK_LIST_BOX (panel->priv->listbox), row);
+               }
        }
 }
 
-static void
-multi_notebook_tab_switched (GeditMultiNotebook  *mnb,
-                            GeditNotebook       *old_notebook,
-                            GeditTab            *old_tab,
-                            GeditNotebook       *new_notebook,
-                            GeditTab            *new_tab,
-                            GeditDocumentsPanel *panel)
+static GtkListBoxRow *
+get_first_notebook_found (GeditDocumentsPanel *panel)
 {
-       gedit_debug (DEBUG_PANEL);
+       GList *children;
+       GList *l;
+       GtkListBoxRow *row = NULL;
 
-       if (!panel->priv->setting_active_notebook &&
-           !_gedit_window_is_removing_tabs (panel->priv->window))
-       {
-               GtkTreeIter iter;
+       children = gtk_container_get_children (GTK_CONTAINER (panel->priv->listbox));
 
-               if (get_iter_from_tab (panel, new_notebook, new_tab, &iter) &&
-                   gtk_tree_store_iter_is_valid (GTK_TREE_STORE (panel->priv->model), &iter))
+       for (l = children; l != NULL; l = g_list_next (l))
+       {
+               if (GEDIT_IS_DOCUMENTS_GROUP_ROW (l->data))
                {
-                       select_iter (panel, &iter);
+                       row = l->data;
+                       break;
                }
        }
+
+       g_list_free (children);
+
+       return row;
 }
 
 static void
-refresh_notebook (GeditDocumentsPanel *panel,
-                 GeditNotebook       *notebook,
-                 GtkTreeIter         *parent)
+multi_notebook_tab_switched (GeditMultiNotebook  *mnb,
+                             GeditNotebook       *old_notebook,
+                             GeditTab            *old_tab,
+                             GeditNotebook       *new_notebook,
+                             GeditTab            *new_tab,
+                             GeditDocumentsPanel *panel)
 {
-       GList *tabs;
-       GList *l;
-       GtkTreeStore *tree_store;
-       GeditTab *active_tab;
-
        gedit_debug (DEBUG_PANEL);
 
-       tree_store = GTK_TREE_STORE (panel->priv->model);
+       if (!_gedit_window_is_removing_tabs (panel->priv->window) &&
+           (panel->priv->is_in_tab_switched == FALSE))
+       {
+               GtkListBoxRow *row;
 
-       active_tab = gedit_window_get_active_tab (panel->priv->window);
+               panel->priv->is_in_tab_switched = TRUE;
 
-       tabs = gtk_container_get_children (GTK_CONTAINER (notebook));
+               row = get_row_from_tab (panel, new_tab);
 
-       for (l = tabs; l != NULL; l = g_list_next (l))
-       {
-               GdkPixbuf *pixbuf;
-               gchar *name;
-               GtkTreeIter iter;
-
-               name = tab_get_name (GEDIT_TAB (l->data));
-               pixbuf = _gedit_tab_get_icon (GEDIT_TAB (l->data));
-
-               /* Add a new row to the model */
-               gtk_tree_store_append (tree_store, &iter, parent);
-               gtk_tree_store_set (tree_store,
-                                   &iter,
-                                   PIXBUF_COLUMN, pixbuf,
-                                   NAME_COLUMN, name,
-                                   NOTEBOOK_COLUMN, notebook,
-                                   TAB_COLUMN, l->data,
-                                   -1);
-
-               g_free (name);
-               if (pixbuf != NULL)
+               if (row)
                {
-                       g_object_unref (pixbuf);
+                       row_select (panel, GTK_LIST_BOX (panel->priv->listbox), row);
                }
 
-               if (l->data == active_tab)
-               {
-                       select_iter (panel, &iter);
-               }
+               panel->priv->is_in_tab_switched = FALSE;
        }
-
-       g_list_free (tabs);
 }
 
 static void
-refresh_notebook_foreach (GeditNotebook       *notebook,
-                         GeditDocumentsPanel *panel)
+group_row_set_notebook_name (GtkWidget *row)
 {
-       gboolean add_notebook;
+       GeditNotebook *notebook;
+       GeditMultiNotebook *mnb;
+       guint num;
+       gchar *name;
 
-       /* If we have only one notebook we don't want to show the notebook
-          header */
-       add_notebook = (gedit_multi_notebook_get_n_notebooks (panel->priv->mnb) > 1);
+       GeditDocumentsGroupRow *group_row = GEDIT_DOCUMENTS_GROUP_ROW (row);
 
-       if (add_notebook)
-       {
-               GtkTreeIter iter;
-               gchar *name;
+       notebook = GEDIT_NOTEBOOK (group_row->ref);
+
+       mnb = group_row->panel->priv->mnb;
+       num = gedit_multi_notebook_get_notebook_num (mnb, notebook);
+
+       name = g_strdup_printf (_("Tab Group %i"), num + 1);
 
-               name = notebook_get_name (panel->priv->mnb, notebook);
+       gtk_label_set_markup (GTK_LABEL (group_row->label), name);
 
-               gtk_tree_store_append (GTK_TREE_STORE (panel->priv->model),
-                                      &iter, NULL);
+       g_free (group_row->name);
+       group_row->name = name;
+}
 
-               gtk_tree_store_set (GTK_TREE_STORE (panel->priv->model),
-                                   &iter,
-                                   PIXBUF_COLUMN, NULL,
-                                   NAME_COLUMN, name,
-                                   NOTEBOOK_COLUMN, notebook,
-                                   TAB_COLUMN, NULL,
-                                   -1);
+static void
+group_row_update_names (GeditDocumentsPanel *panel,
+                        GtkWidget           *listbox)
+{
+       GList *children;
+       GList *l;
+       GtkWidget *row;
 
-               refresh_notebook (panel, notebook, &iter);
+       children = gtk_container_get_children (GTK_CONTAINER (listbox));
 
-               g_free (name);
-       }
-       else
+       for (l = children; l != NULL; l = g_list_next (l))
        {
-               refresh_notebook (panel, notebook, NULL);
+               row = l->data;
+
+               if (GEDIT_IS_DOCUMENTS_GROUP_ROW (row))
+               {
+                       group_row_set_notebook_name (row);
+               }
        }
+
+       g_list_free (children);
 }
 
-static gboolean
-refresh_list_idle (GeditDocumentsPanel *panel)
+static void
+group_row_refresh_visibility (GeditDocumentsPanel *panel)
 {
-       GtkTreeSelection *selection;
+       gint notebook_is_unique;
+       GtkWidget *first_group_row;
 
-       gedit_debug (DEBUG_PANEL);
+       notebook_is_unique = gedit_multi_notebook_get_n_notebooks (panel->priv->mnb) <= 1;
+       first_group_row = GTK_WIDGET (get_first_notebook_found (panel));
+
+       gtk_widget_set_no_show_all (first_group_row, notebook_is_unique);
+       gtk_widget_set_visible (first_group_row, !notebook_is_unique);
+}
 
-       selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (panel->priv->treeview));
-       g_signal_handler_block (selection, panel->priv->selection_changed_handler_id);
+static void
+refresh_notebook (GeditDocumentsPanel *panel,
+                  GeditNotebook       *notebook)
+{
+       GList *tabs;
+       GList *l;
 
-       gtk_tree_store_clear (GTK_TREE_STORE (panel->priv->model));
+       tabs = gtk_container_get_children (GTK_CONTAINER (notebook));
 
-       panel->priv->adding_tab = TRUE;
-       gedit_multi_notebook_foreach_notebook (panel->priv->mnb,
-                                              (GtkCallback)refresh_notebook_foreach,
-                                              panel);
-       panel->priv->adding_tab = FALSE;
+       for (l = tabs; l != NULL; l = g_list_next (l))
+       {
+               GtkWidget *row;
 
-       gtk_tree_view_expand_all (GTK_TREE_VIEW (panel->priv->treeview));
+               row = gedit_documents_document_row_new (panel, GEDIT_TAB (l->data));
+               insert_row (panel, GTK_LIST_BOX (panel->priv->listbox), row, -1);
+               panel->priv->nb_row_tab += 1;
+       }
 
-       select_active_tab (panel);
+       g_list_free (tabs);
+}
 
-       panel->priv->refresh_idle_id = 0;
+static void
+refresh_notebook_foreach (GeditNotebook       *notebook,
+                          GeditDocumentsPanel *panel)
+{
+       GtkWidget *row;
 
-       g_signal_handler_unblock (selection, panel->priv->selection_changed_handler_id);
+       row = gedit_documents_group_row_new (panel, notebook);
+       insert_row (panel, GTK_LIST_BOX (panel->priv->listbox), row, -1);
+       panel->priv->nb_row_notebook += 1;
 
-       return FALSE;
+       group_row_refresh_visibility (panel);
+       refresh_notebook (panel, notebook);
 }
 
 static void
 refresh_list (GeditDocumentsPanel *panel)
 {
-       /* refresh in an idle so that when adding/removing many tabs
-        * the model is repopulated just once */
-       if (panel->priv->refresh_idle_id == 0)
+       GList *children;
+       GList *l;
+
+       /* Clear the listbox */
+       children = gtk_container_get_children (GTK_CONTAINER (panel->priv->listbox));
+
+       for (l = children; l != NULL; l = g_list_next (l))
        {
-               panel->priv->refresh_idle_id = gdk_threads_add_idle ((GSourceFunc) refresh_list_idle,
-                                                                    panel);
+               gtk_widget_destroy (GTK_WIDGET (l->data));
        }
+       g_list_free (children);
+
+       gedit_multi_notebook_foreach_notebook (panel->priv->mnb,
+                                              (GtkCallback)refresh_notebook_foreach,
+                                              panel);
+       select_active_tab (panel);
 }
 
 static void
-document_changed (GtkTextBuffer       *buffer,
-                 GeditDocumentsPanel *panel)
+multi_notebook_tab_removed (GeditMultiNotebook  *mnb,
+                            GeditNotebook       *notebook,
+                            GeditTab            *tab,
+                            GeditDocumentsPanel *panel)
 {
+       GtkListBoxRow *row;
+
        gedit_debug (DEBUG_PANEL);
 
-       select_active_tab (panel);
+       row = get_row_from_tab (panel, tab);
+       gtk_widget_destroy (GTK_WIDGET (row));
+       panel->priv->nb_row_tab -= 1;
+}
+
+static gint
+get_dest_position_for_tab (GeditDocumentsPanel *panel,
+                           GeditNotebook       *notebook,
+                           GeditTab            *tab)
+{
+       gint page_num;
+       GList *children;
+       GList *item;
+       gint res = -1;
+
+       /* Get tab's position in notebook and notebook's position in GtkListBox
+        * then return future tab's position in GtkListBox */
+
+       page_num = gtk_notebook_page_num (GTK_NOTEBOOK (notebook), GTK_WIDGET (tab));
 
-       g_signal_handlers_disconnect_by_func (buffer,
-                                             G_CALLBACK (document_changed),
-                                             panel);
+       children = gtk_container_get_children (GTK_CONTAINER (panel->priv->listbox));
+       item = g_list_find_custom (children, notebook, listbox_search_function);
+       if (item)
+       {
+               res = 1 + page_num + g_list_position (children, item);
+       }
+
+       g_list_free (children);
+
+       return res;
 }
 
 static void
-sync_name_and_icon (GeditTab            *tab,
-                   GParamSpec          *pspec,
-                   GeditDocumentsPanel *panel)
+multi_notebook_tab_added (GeditMultiNotebook  *mnb,
+                          GeditNotebook       *notebook,
+                          GeditTab            *tab,
+                          GeditDocumentsPanel *panel)
 {
-       GtkTreeIter iter;
+       gint position;
+       GtkWidget *row;
 
        gedit_debug (DEBUG_PANEL);
 
-       if (get_iter_from_tab (panel,
-                              gedit_multi_notebook_get_active_notebook (panel->priv->mnb),
-                              tab,
-                              &iter))
+       position = get_dest_position_for_tab (panel, notebook, tab);
+
+       if (position == -1)
        {
-               gchar *name;
-               GdkPixbuf *pixbuf;
+               /* Notebook doesn't exit in GtkListBox, so create it */
+               row = gedit_documents_group_row_new (panel, notebook);
+               insert_row (panel, GTK_LIST_BOX (panel->priv->listbox), row, -1);
 
-               name = tab_get_name (tab);
-               pixbuf = _gedit_tab_get_icon (tab);
+               panel->priv->nb_row_notebook += 1;
 
-               gtk_tree_store_set (GTK_TREE_STORE (panel->priv->model),
-                                   &iter,
-                                   PIXBUF_COLUMN, pixbuf,
-                                   NAME_COLUMN, name,
-                                   -1);
+               /* Now, we have a correct position */
+               position = get_dest_position_for_tab (panel, notebook, tab);
 
-               g_free (name);
-               if (pixbuf != NULL)
-               {
-                       g_object_unref (pixbuf);
-               }
+               group_row_refresh_visibility (panel);
        }
+
+       /* Add a new tab's row to the listbox */
+       row = gedit_documents_document_row_new (panel, tab);
+       insert_row (panel, GTK_LIST_BOX (panel->priv->listbox), row, position);
+
+       panel->priv->nb_row_tab += 1;
+
+       row_select (panel, GTK_LIST_BOX (panel->priv->listbox), GTK_LIST_BOX_ROW (row));
 }
 
 static void
-multi_notebook_tab_removed (GeditMultiNotebook  *mnb,
-                           GeditNotebook       *notebook,
-                           GeditTab            *tab,
-                           GeditDocumentsPanel *panel)
+multi_notebook_notebook_removed (GeditMultiNotebook  *mnb,
+                                 GeditNotebook       *notebook,
+                                 GeditDocumentsPanel *panel)
 {
+       GtkListBoxRow *row;
+
        gedit_debug (DEBUG_PANEL);
 
-       g_signal_handlers_disconnect_by_func (gedit_tab_get_document (tab),
-                                             G_CALLBACK (document_changed),
-                                             panel);
+       row = get_row_from_notebook (panel, notebook);
+       gtk_container_remove (GTK_CONTAINER (panel->priv->listbox), GTK_WIDGET (row));
 
-       g_signal_handlers_disconnect_by_func (tab,
-                                             G_CALLBACK (sync_name_and_icon),
-                                             panel);
+       panel->priv->nb_row_notebook -= 1;
 
-       refresh_list (panel);
+       group_row_refresh_visibility (panel);
+       group_row_update_names (panel, panel->priv->listbox);
 }
 
 static void
-multi_notebook_tab_added (GeditMultiNotebook  *mnb,
-                         GeditNotebook       *notebook,
-                         GeditTab            *tab,
-                         GeditDocumentsPanel *panel)
+row_move (GeditDocumentsPanel *panel,
+          GeditNotebook       *notebook,
+          GtkWidget           *tab,
+          GtkWidget           *row)
 {
-       gedit_debug (DEBUG_PANEL);
+       gint position;
 
-       g_signal_connect (tab,
-                        "notify::name",
-                         G_CALLBACK (sync_name_and_icon),
-                         panel);
-       g_signal_connect (tab,
-                        "notify::state",
-                         G_CALLBACK (sync_name_and_icon),
-                         panel);
+       g_object_ref (row);
 
-       refresh_list (panel);
-}
+       gtk_container_remove (GTK_CONTAINER (panel->priv->listbox), GTK_WIDGET (row));
+       position = get_dest_position_for_tab (panel, notebook, GEDIT_TAB (tab));
 
-static void
-multi_notebook_notebook_removed (GeditMultiNotebook  *mnb,
-                                GeditNotebook       *notebook,
-                                GeditDocumentsPanel *panel)
-{
-       refresh_list (panel);
+       g_signal_handler_block (panel->priv->listbox,
+                               panel->priv->selection_changed_handler_id);
+
+       gtk_list_box_insert (GTK_LIST_BOX (panel->priv->listbox), row, position);
+
+       g_object_unref (row);
+
+       g_signal_handler_unblock (GTK_LIST_BOX (panel->priv->listbox),
+                                 panel->priv->selection_changed_handler_id);
 }
 
 static void
@@ -537,102 +680,104 @@ multi_notebook_tabs_reordered (GeditMultiNotebook  *mnb,
                                gint                 page_num,
                                GeditDocumentsPanel *panel)
 {
+       GtkListBoxRow *row;
+
        gedit_debug (DEBUG_PANEL);
 
-       if (panel->priv->is_reodering)
-               return;
+       row = get_row_from_tab (panel, GEDIT_TAB (page));
 
-       refresh_list (panel);
+       row_move (panel, notebook, page, GTK_WIDGET (row));
+
+       row_select (panel, GTK_LIST_BOX (panel->priv->listbox), GTK_LIST_BOX_ROW (row));
 }
 
 static void
 set_window (GeditDocumentsPanel *panel,
-           GeditWindow         *window)
+            GeditWindow         *window)
 {
-       gedit_debug (DEBUG_PANEL);
-
-       g_return_if_fail (panel->priv->window == NULL);
-       g_return_if_fail (GEDIT_IS_WINDOW (window));
-
        panel->priv->window = g_object_ref (window);
        panel->priv->mnb = GEDIT_MULTI_NOTEBOOK (_gedit_window_get_multi_notebook (window));
 
        g_signal_connect (panel->priv->mnb,
-                         "notebook-removed",
-                         G_CALLBACK (multi_notebook_notebook_removed),
-                         panel);
-       g_signal_connect (panel->priv->mnb,
-                         "tab-added",
-                         G_CALLBACK (multi_notebook_tab_added),
-                         panel);
+                         "notebook-removed",
+                         G_CALLBACK (multi_notebook_notebook_removed),
+                         panel);
        g_signal_connect (panel->priv->mnb,
-                         "tab-removed",
-                         G_CALLBACK (multi_notebook_tab_removed),
-                         panel);
+                         "tab-added",
+                         G_CALLBACK (multi_notebook_tab_added),
+                         panel);
        g_signal_connect (panel->priv->mnb,
-                         "page-reordered",
-                         G_CALLBACK (multi_notebook_tabs_reordered),
-                         panel);
+                         "tab-removed",
+                         G_CALLBACK (multi_notebook_tab_removed),
+                         panel);
        g_signal_connect (panel->priv->mnb,
-                         "switch-tab",
-                         G_CALLBACK (multi_notebook_tab_switched),
-                         panel);
+                         "page-reordered",
+                         G_CALLBACK (multi_notebook_tabs_reordered),
+                         panel);
+
+       panel->priv->tab_switched_handler_id = g_signal_connect (panel->priv->mnb,
+                                                                "switch-tab",
+                                                                G_CALLBACK (multi_notebook_tab_switched),
+                                                                panel);
+
+       panel->priv->first_selection = TRUE;
 
        refresh_list (panel);
+       group_row_refresh_visibility (panel);
 }
 
 static void
-treeview_selection_changed (GtkTreeSelection    *selection,
-                           GeditDocumentsPanel *panel)
+listbox_selection_changed (GtkListBox          *listbox,
+                           GtkListBoxRow       *row,
+                           GeditDocumentsPanel *panel)
 {
-       GtkTreeIter iter;
+       if (row == NULL)
+       {
+               /* No selection on document panel */
+               return;
+       }
 
-       gedit_debug (DEBUG_PANEL);
+       /* When the window is shown, the first notebook row is selected
+        * and therefore also shown - we don't want this */
 
-       if (gtk_tree_selection_get_selected (selection, NULL, &iter))
+       if (panel->priv->first_selection)
        {
-               GeditNotebook *notebook;
-               GeditTab *tab;
+               panel->priv->first_selection = FALSE;
+               group_row_refresh_visibility (panel);
+       }
 
-               gtk_tree_model_get (panel->priv->model,
-                                   &iter,
-                                   NOTEBOOK_COLUMN, &notebook,
-                                   TAB_COLUMN, &tab,
-                                   -1);
+       if (GEDIT_IS_DOCUMENTS_DOCUMENT_ROW (row))
+       {
+               g_signal_handler_block (panel->priv->mnb,
+                                       panel->priv->tab_switched_handler_id);
 
-               if (tab != NULL)
-               {
-                       gedit_multi_notebook_set_active_tab (panel->priv->mnb,
-                                                            tab);
-                       if (notebook != NULL)
-                               g_object_unref (notebook);
-                       g_object_unref (tab);
-               }
-               else if (notebook != NULL)
-               {
-                       panel->priv->setting_active_notebook = TRUE;
-                       gtk_widget_grab_focus (GTK_WIDGET (notebook));
-                       panel->priv->setting_active_notebook = FALSE;
-
-                       tab = gedit_multi_notebook_get_active_tab (panel->priv->mnb);
-                       if (tab != NULL)
-                       {
-                               g_signal_connect (gedit_tab_get_document (tab),
-                                                 "changed",
-                                                 G_CALLBACK (document_changed),
-                                                 panel);
-                       }
-
-                       g_object_unref (notebook);
-               }
+               gedit_multi_notebook_set_active_tab (panel->priv->mnb,
+                                                    GEDIT_TAB (GEDIT_DOCUMENTS_DOCUMENT_ROW (row)->ref));
+
+               g_signal_handler_unblock (panel->priv->mnb,
+                                         panel->priv->tab_switched_handler_id);
+       }
+       else if (GEDIT_IS_DOCUMENTS_GROUP_ROW (row))
+       {
+               g_signal_handler_block (panel->priv->mnb,
+                                       panel->priv->tab_switched_handler_id);
+
+               gtk_widget_grab_focus (GTK_WIDGET (GEDIT_DOCUMENTS_GROUP_ROW (row)->ref));
+
+               g_signal_handler_unblock (panel->priv->mnb,
+                                         panel->priv->tab_switched_handler_id);
+       }
+       else
+       {
+               g_assert_not_reached ();
        }
 }
 
 static void
 gedit_documents_panel_set_property (GObject      *object,
-                                   guint         prop_id,
-                                   const GValue *value,
-                                   GParamSpec   *pspec)
+                                    guint         prop_id,
+                                    const GValue *value,
+                                    GParamSpec   *pspec)
 {
        GeditDocumentsPanel *panel = GEDIT_DOCUMENTS_PANEL (object);
 
@@ -650,9 +795,9 @@ gedit_documents_panel_set_property (GObject      *object,
 
 static void
 gedit_documents_panel_get_property (GObject    *object,
-                                   guint       prop_id,
-                                   GValue     *value,
-                                   GParamSpec *pspec)
+                                    guint       prop_id,
+                                    GValue     *value,
+                                    GParamSpec *pspec)
 {
        GeditDocumentsPanel *panel = GEDIT_DOCUMENTS_PANEL (object);
 
@@ -671,11 +816,23 @@ gedit_documents_panel_get_property (GObject    *object,
 static void
 gedit_documents_panel_finalize (GObject *object)
 {
-       /* GeditDocumentsPanel *tab = GEDIT_DOCUMENTS_PANEL (object); */
-
-       /* TODO disconnect signal with window */
+       GeditDocumentsPanel *panel = GEDIT_DOCUMENTS_PANEL (object);
 
-       gedit_debug (DEBUG_PANEL);
+       g_signal_handlers_disconnect_by_func (panel->priv->mnb,
+                                             G_CALLBACK (multi_notebook_notebook_removed),
+                                             panel);
+       g_signal_handlers_disconnect_by_func (panel->priv->mnb,
+                                             G_CALLBACK (multi_notebook_tab_added),
+                                             panel);
+       g_signal_handlers_disconnect_by_func (panel->priv->mnb,
+                                             G_CALLBACK (multi_notebook_tab_removed),
+                                             panel);
+       g_signal_handlers_disconnect_by_func (panel->priv->mnb,
+                                             G_CALLBACK (multi_notebook_tabs_reordered),
+                                             panel);
+       g_signal_handlers_disconnect_by_func (panel->priv->mnb,
+                                             G_CALLBACK (multi_notebook_tab_switched),
+                                             panel);
 
        G_OBJECT_CLASS (gedit_documents_panel_parent_class)->finalize (object);
 }
@@ -685,14 +842,6 @@ gedit_documents_panel_dispose (GObject *object)
 {
        GeditDocumentsPanel *panel = GEDIT_DOCUMENTS_PANEL (object);
 
-       gedit_debug (DEBUG_PANEL);
-
-       if (panel->priv->refresh_idle_id != 0)
-       {
-               g_source_remove (panel->priv->refresh_idle_id);
-               panel->priv->refresh_idle_id = 0;
-       }
-
        g_clear_object (&panel->priv->window);
 
        G_OBJECT_CLASS (gedit_documents_panel_parent_class)->dispose (object);
@@ -709,483 +858,603 @@ gedit_documents_panel_class_init (GeditDocumentsPanelClass *klass)
        object_class->set_property = gedit_documents_panel_set_property;
 
        g_object_class_install_property (object_class,
-                                        PROP_WINDOW,
-                                        g_param_spec_object ("window",
-                                                             "Window",
-                                                             "The GeditWindow this GeditDocumentsPanel is 
associated with",
-                                                             GEDIT_TYPE_WINDOW,
-                                                             G_PARAM_READWRITE |
-                                                             G_PARAM_CONSTRUCT_ONLY |
-                                                             G_PARAM_STATIC_STRINGS));
+                                        PROP_WINDOW,
+                                        g_param_spec_object ("window",
+                                                             "Window",
+                                                             "The GeditWindow this GeditDocumentsPanel is 
associated with",
+                                                             GEDIT_TYPE_WINDOW,
+                                                             G_PARAM_READWRITE |
+                                                             G_PARAM_CONSTRUCT_ONLY |
+                                                             G_PARAM_STATIC_STRINGS));
 }
 
-static GtkTreePath *
-get_current_path (GeditDocumentsPanel *panel)
+static void
+gedit_documents_panel_init (GeditDocumentsPanel *panel)
 {
-       gint notebook_num;
-       gint page_num;
-       GtkWidget *notebook;
+       GtkWidget *sw;
+       GtkStyleContext *context;
 
        gedit_debug (DEBUG_PANEL);
 
-       notebook = _gedit_window_get_notebook (panel->priv->window);
+       panel->priv = gedit_documents_panel_get_instance_private (panel);
+
+       gtk_orientable_set_orientation (GTK_ORIENTABLE (panel),
+                                       GTK_ORIENTATION_VERTICAL);
+
+       /* Create the scrolled window */
+       sw = gtk_scrolled_window_new (NULL, NULL);
+
+       gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
+                                       GTK_POLICY_AUTOMATIC,
+                                       GTK_POLICY_AUTOMATIC);
+       gtk_widget_show (sw);
+       gtk_box_pack_start (GTK_BOX (panel), sw, TRUE, TRUE, 0);
 
-       notebook_num = gedit_multi_notebook_get_notebook_num (panel->priv->mnb,
-                                                             GEDIT_NOTEBOOK (notebook));
-       page_num = gtk_notebook_get_current_page (GTK_NOTEBOOK (notebook));
+       /* Create the listbox */
+       panel->priv->listbox = gtk_list_box_new ();
 
-       return gtk_tree_path_new_from_indices (notebook_num, page_num, -1);
+       gtk_container_add (GTK_CONTAINER (sw), panel->priv->listbox);
+
+       panel->priv->adjustment = gtk_list_box_get_adjustment (GTK_LIST_BOX (panel->priv->listbox));
+
+       /* Disable focus so it doesn't steal focus each time from the view */
+       gtk_widget_set_can_focus (panel->priv->listbox, FALSE);
+
+       /* Css style */
+       context = gtk_widget_get_style_context (panel->priv->listbox);
+       gtk_style_context_add_class(context, "gedit-document-panel");
+
+       panel->priv->selection_changed_handler_id = g_signal_connect (panel->priv->listbox,
+                                                                     "row-selected",
+                                                                     G_CALLBACK (listbox_selection_changed),
+                                                                     panel);
+       panel->priv->is_in_tab_switched = FALSE;
+       panel->priv->nb_row_notebook = 0;
+       panel->priv->nb_row_tab = 0;
 }
 
-static void
-menu_position (GtkMenu             *menu,
-              gint                *x,
-              gint                *y,
-              gboolean            *push_in,
-              GeditDocumentsPanel *panel)
+GtkWidget *
+gedit_documents_panel_new (GeditWindow *window)
 {
-       GtkTreePath *path;
-       GdkRectangle rect;
-       gint wy;
-       GtkRequisition requisition;
-       GtkWidget *w;
-       GtkAllocation allocation;
+       g_return_val_if_fail (GEDIT_IS_WINDOW (window), NULL);
 
-       gedit_debug (DEBUG_PANEL);
+       return g_object_new (GEDIT_TYPE_DOCUMENTS_PANEL,
+                            "window", window,
+                            NULL);
+}
 
-       w = panel->priv->treeview;
+static gchar *
+tab_get_name (GeditTab *tab)
+{
+       GeditDocument *doc;
+       gchar *name;
+       gchar *docname;
+       gchar *tab_name;
 
-       path = get_current_path (panel);
-       gtk_tree_view_get_cell_area (GTK_TREE_VIEW (w),
-                                    path,
-                                    NULL,
-                                    &rect);
-       gtk_tree_path_free (path);
+       doc = gedit_tab_get_document (tab);
 
-       wy = rect.y;
+       name = gedit_document_get_short_name_for_display (doc);
 
-       gdk_window_get_origin (gtk_widget_get_window (w), x, y);
-       gtk_widget_get_preferred_size (GTK_WIDGET (menu), &requisition, NULL);
-       gtk_widget_get_allocation (w, &allocation);
+       /* Truncate the name so it doesn't get insanely wide. */
+       docname = gedit_utils_str_middle_truncate (name, MAX_DOC_NAME_LENGTH);
 
-       if (gtk_widget_get_direction (w) == GTK_TEXT_DIR_RTL)
+       if (gtk_text_buffer_get_modified (GTK_TEXT_BUFFER (doc)))
        {
-               *x += allocation.x + allocation.width - requisition.width - 10;
+               if (gedit_document_get_readonly (doc))
+               {
+                       tab_name = g_markup_printf_escaped ("<i>%s</i> [<i>%s</i>]",
+                                                           docname,
+                                                           _("Read-Only"));
+               }
+               else
+               {
+                       tab_name = g_markup_printf_escaped ("<i>%s</i>",
+                                                           docname);
+               }
        }
        else
        {
-               *x += allocation.x + 10;
+               if (gedit_document_get_readonly (doc))
+               {
+                       tab_name = g_markup_printf_escaped ("%s [<i>%s</i>]",
+                                                           docname,
+                                                           _("Read-Only"));
+               }
+               else
+               {
+                       tab_name = g_markup_escape_text (docname, -1);
+               }
        }
 
-       wy = MAX (*y + 5, *y + wy + 5);
-       wy = MIN (wy, *y + allocation.height - requisition.height - 5);
+       g_free (docname);
+       g_free (name);
 
-       *y = wy;
+       return tab_name;
+}
 
-       *push_in = TRUE;
+static gboolean
+row_on_close_button_clicked (GtkWidget *close_button_event_box,
+                             GdkEvent  *event,
+                             GtkWidget *row)
+{
+       guint button_number;
+
+       if (!gdk_event_get_button (event, &button_number))
+       {
+               return FALSE;
+       }
+
+       if (gdk_event_get_event_type (event) == GDK_BUTTON_PRESS &&
+           button_number == GDK_BUTTON_PRIMARY)
+       {
+               GtkWidget *ref;
+               GeditNotebook *notebook;
+
+               if (GEDIT_IS_DOCUMENTS_GROUP_ROW (row))
+               {
+                       /* Removes all tabs, then the tab group */
+                       ref = GEDIT_DOCUMENTS_GROUP_ROW (row)->ref;
+
+                       gedit_notebook_remove_all_tabs (GEDIT_NOTEBOOK (ref));
+
+                       return TRUE;
+               }
+               else if (GEDIT_IS_DOCUMENTS_DOCUMENT_ROW (row))
+               {
+                       /* Removes the tab */
+                       ref = GEDIT_DOCUMENTS_DOCUMENT_ROW (row)->ref;
+
+                       notebook = GEDIT_NOTEBOOK (gtk_widget_get_parent (GTK_WIDGET (ref)));
+                       gtk_container_remove (GTK_CONTAINER (notebook), GTK_WIDGET (ref));
+
+                       return TRUE;
+               }
+               else
+               {
+                       g_assert_not_reached ();
+               }
+
+               return TRUE;
+       }
+
+       return FALSE;
 }
 
 static gboolean
-show_tab_popup_menu (GeditDocumentsPanel *panel,
-                    GeditTab            *tab,
-                    GdkEventButton      *event)
+row_on_button_pressed (GtkWidget      *row_event_box,
+                       GdkEventButton *event,
+                       GtkWidget      *row)
 {
-       GtkWidget *menu;
+       if ((event->type == GDK_BUTTON_PRESS) &&
+           (gdk_event_triggers_context_menu ((GdkEvent *)event)) &&
+           GEDIT_IS_DOCUMENTS_DOCUMENT_ROW (row) )
+       {
+               GeditDocumentsGenericRow *generic_row = (GeditDocumentsGenericRow *)row;
+               GeditWindow *window = generic_row->panel->priv->window;
 
-       gedit_debug (DEBUG_PANEL);
+               GeditTab *tab = GEDIT_TAB (generic_row->ref);
+               GtkWidget *menu = gedit_notebook_popup_menu_new (window, tab);
+
+               if (event != NULL)
+               {
+                       gtk_menu_popup (GTK_MENU (menu),
+                                       NULL,
+                                       NULL,
+                                       NULL,
+                                       NULL,
+                                       event->button,
+                                       event->time);
+               }
+               else
+               {
+                       gtk_menu_popup (GTK_MENU (menu),
+                                       NULL,
+                                       NULL,
+                                       (GtkMenuPositionFunc)menu_position,
+                                       row,
+                                       0,
+                                       gtk_get_current_event_time ());
+
+                       gtk_menu_shell_select_first (GTK_MENU_SHELL (menu), FALSE);
+               }
+
+               return TRUE;
+       }
 
-       menu = gedit_notebook_popup_menu_new (panel->priv->window, tab);
+       return FALSE;
+}
 
-       if (event != NULL)
+static void
+document_row_sync_tab_name_and_icon (GeditTab   *tab,
+                                     GParamSpec *pspec,
+                                     GtkWidget  *row)
+{
+       gchar *name;
+       GeditDocumentsDocumentRow *document_row = GEDIT_DOCUMENTS_DOCUMENT_ROW (row);
+       GdkPixbuf *pixbuf;
+
+       name = tab_get_name (tab);
+       gtk_label_set_markup (GTK_LABEL (document_row->label), name);
+       g_free (document_row->name);
+       document_row->name = name;
+
+       /* Update header of the row */
+       pixbuf = _gedit_tab_get_icon (tab);
+
+       if (pixbuf)
        {
-               gtk_menu_popup (GTK_MENU (menu),
-                               NULL,
-                               NULL,
-                               NULL,
-                               NULL,
-                               event->button,
-                               event->time);
+               gtk_image_set_from_pixbuf (GTK_IMAGE (document_row->image), pixbuf);
        }
        else
        {
-               gtk_menu_popup (GTK_MENU (menu),
-                               NULL,
-                               NULL,
-                               (GtkMenuPositionFunc)menu_position,
-                               panel,
-                               0,
-                               gtk_get_current_event_time ());
-
-               gtk_menu_shell_select_first (GTK_MENU_SHELL (menu), FALSE);
+               gtk_image_clear (GTK_IMAGE (document_row->image));
        }
+}
 
-       return TRUE;
+static void
+document_row_create_header (GtkWidget *row)
+{
+       GeditDocumentsDocumentRow *document_row = GEDIT_DOCUMENTS_DOCUMENT_ROW (row);
+
+       document_row->pixbuf_box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
+       gtk_widget_set_size_request (document_row->pixbuf_box, ROW_HEADER_SIZE, -1);
+
+       document_row->image = gtk_image_new ();
+       gtk_widget_set_halign (document_row->image, GTK_ALIGN_CENTER);
+
+       gtk_box_pack_start (GTK_BOX (document_row->pixbuf_box),
+                           document_row->image, FALSE, FALSE, 0);
+
+       gtk_box_pack_start (GTK_BOX (document_row->row_box),
+                           document_row->pixbuf_box, FALSE, FALSE, 0);
+
+       /* Set the header on front of all other widget in the row */
+       gtk_box_reorder_child (GTK_BOX (document_row->row_box),
+                              document_row->pixbuf_box, 0);
+
+       gtk_widget_show_all (document_row->pixbuf_box);
 }
 
-static gboolean
-panel_button_press_event (GtkTreeView         *treeview,
-                         GdkEventButton      *event,
-                         GeditDocumentsPanel *panel)
+static GtkWidget *
+row_create (GtkWidget *row)
 {
-       gboolean ret = FALSE;
+       GeditDocumentsGenericRow *generic_row = (GeditDocumentsGenericRow *)row;
+       GIcon *close_button_icon;
 
        gedit_debug (DEBUG_PANEL);
 
-       if ((event->type == GDK_BUTTON_PRESS) &&
-           (gdk_event_triggers_context_menu ((GdkEvent *) event)) &&
-           (event->window == gtk_tree_view_get_bin_window (treeview)))
-       {
-               GtkTreePath *path = NULL;
-
-               /* Change the cursor position */
-               if (gtk_tree_view_get_path_at_pos (treeview,
-                                                  event->x,
-                                                  event->y,
-                                                  &path,
-                                                  NULL,
-                                                  NULL,
-                                                  NULL))
-               {
-                       GtkTreeIter iter;
-                       gchar *path_string;
-
-                       path_string = gtk_tree_path_to_string (path);
-
-                       if (gtk_tree_model_get_iter_from_string (panel->priv->model,
-                                                                &iter,
-                                                                path_string))
-                       {
-                               GeditTab *tab;
-
-                               gtk_tree_model_get (panel->priv->model,
-                                                   &iter,
-                                                   TAB_COLUMN, &tab,
-                                                   -1);
-
-                               if (tab != NULL)
-                               {
-                                       gtk_tree_view_set_cursor (treeview,
-                                                                 path,
-                                                                 NULL,
-                                                                 FALSE);
-
-                                       /* A row exists at the mouse position */
-                                       ret = show_tab_popup_menu (panel, tab, event);
-
-                                       g_object_unref (tab);
-                               }
-                       }
-
-                       g_free (path_string);
-                       gtk_tree_path_free (path);
-               }
-       }
+       generic_row->row_event_box = gtk_event_box_new ();
+       generic_row->row_box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
+
+       gtk_container_add (GTK_CONTAINER (generic_row->row_event_box), generic_row->row_box);
+
+       generic_row->label = gtk_label_new (NULL);
+       gtk_label_set_ellipsize (GTK_LABEL (generic_row->label), PANGO_ELLIPSIZE_END);
+
+       /* setup close button */
+       close_button_icon = g_themed_icon_new_with_default_fallbacks ("window-close-symbolic");
+
+       generic_row->close_button_image = gtk_image_new_from_gicon (G_ICON (close_button_icon),
+                                                                   GTK_ICON_SIZE_MENU);
+       g_object_unref (close_button_icon);
+
+       generic_row->close_button_event_box = gtk_event_box_new ();
+
+       gtk_container_add (GTK_CONTAINER (generic_row->close_button_event_box),
+                                         generic_row->close_button_image);
 
-       return ret;
+       gtk_box_pack_start (GTK_BOX (generic_row->row_box),
+                           generic_row->label, FALSE, FALSE, 0);
+
+       gtk_box_pack_end (GTK_BOX (generic_row->row_box),
+                         generic_row->close_button_event_box, FALSE, FALSE, 0);
+
+       g_signal_connect (generic_row->row_event_box,
+                         "button-press-event",
+                         G_CALLBACK (row_on_button_pressed),
+                         row);
+
+       g_signal_connect (generic_row->close_button_event_box,
+                         "button-press-event",
+                         G_CALLBACK (row_on_close_button_clicked),
+                         row);
+
+       gtk_widget_set_no_show_all (generic_row->close_button_image, TRUE);
+       gtk_widget_show_all (generic_row->row_event_box);
+
+       return generic_row->row_event_box;
 }
 
 static gchar *
-notebook_get_tooltip (GeditMultiNotebook *mnb,
-                     GeditNotebook      *notebook)
+notebook_get_tooltip (GtkWidget     *row,
+                      GeditNotebook *notebook)
 {
-       gchar *tooltip;
-       gchar *notebook_name;
+       const gchar *notebook_name;
        gint num_pages;
+       gchar *tooltip;
 
+       notebook_name = GEDIT_DOCUMENTS_GROUP_ROW (row)->name;
 
-       notebook_name = notebook_get_name (mnb, notebook);
        num_pages = gtk_notebook_get_n_pages (GTK_NOTEBOOK (notebook));
 
        tooltip = g_markup_printf_escaped ("<b>Name:</b> %s\n\n"
-                                          "<b>Number of Tabs:</b> %i",
-                                          notebook_name,
-                                          num_pages);
-
-       g_free (notebook_name);
-
+                                          "<b>Number of Tabs:</b> %i",
+                                          notebook_name,
+                                          num_pages);
        return tooltip;
 }
 
 static gboolean
-treeview_query_tooltip (GtkWidget           *widget,
-                       gint                 x,
-                       gint                 y,
-                       gboolean             keyboard_tip,
-                       GtkTooltip          *tooltip,
-                       GeditDocumentsPanel *panel)
+row_query_tooltip (GtkWidget   *row,
+                   gint         x,
+                   gint         y,
+                   gboolean     keyboard_tip,
+                   GtkTooltip  *tooltip,
+                   gpointer   **adr_ref)
 {
-       GtkTreeIter iter;
-       GtkTreeView *tree_view = GTK_TREE_VIEW (widget);
-       GtkTreeModel *model = gtk_tree_view_get_model (tree_view);
-       GtkTreePath *path = NULL;
-       GeditNotebook *notebook;
-       GeditTab *tab;
        gchar *tip;
+       gpointer ref = *adr_ref;
 
-       gedit_debug (DEBUG_PANEL);
-
-       if (keyboard_tip)
-       {
-               gtk_tree_view_get_cursor (tree_view, &path, NULL);
-
-               if (path == NULL)
-               {
-                       return FALSE;
-               }
-       }
-       else
+       if (GEDIT_IS_DOCUMENTS_DOCUMENT_ROW (row))
        {
-               gint bin_x, bin_y;
-
-               gtk_tree_view_convert_widget_to_bin_window_coords (tree_view,
-                                                                  x, y,
-                                                                  &bin_x, &bin_y);
-
-               if (!gtk_tree_view_get_path_at_pos (tree_view,
-                                                   bin_x, bin_y,
-                                                   &path,
-                                                   NULL, NULL, NULL))
-               {
-                       return FALSE;
-               }
+               tip = _gedit_tab_get_tooltip (GEDIT_TAB (ref));
        }
-
-       gtk_tree_model_get_iter (model, &iter, path);
-       gtk_tree_model_get (model,
-                           &iter,
-                           NOTEBOOK_COLUMN, &notebook,
-                           TAB_COLUMN, &tab,
-                           -1);
-
-       if (tab != NULL)
+       else if (GEDIT_IS_DOCUMENTS_GROUP_ROW (row))
        {
-               tip = _gedit_tab_get_tooltip (tab);
-               g_object_unref (tab);
+               tip = notebook_get_tooltip (GTK_WIDGET (row), GEDIT_NOTEBOOK (ref));
        }
        else
        {
-               tip = notebook_get_tooltip (panel->priv->mnb, notebook);
+               g_assert_not_reached();
        }
 
        gtk_tooltip_set_markup (tooltip, tip);
 
-       g_object_unref (notebook);
        g_free (tip);
-       gtk_tree_path_free (path);
 
        return TRUE;
 }
 
-/* TODO
 static void
-treeview_row_inserted (GtkTreeModel        *tree_model,
-                      GtkTreePath         *path,
-                      GtkTreeIter         *iter,
-                      GeditDocumentsPanel *panel)
+get_padding_and_border (GtkWidget *widget,
+                        GtkBorder *border)
 {
-       GeditTab *tab;
-       gint *indeces;
-       gchar *path_string;
-       GeditNotebook *notebook;
+       GtkStyleContext *context;
+       GtkStateFlags state;
+       GtkBorder tmp;
 
-       gedit_debug (DEBUG_PANEL);
+       context = gtk_widget_get_style_context (widget);
+       state = gtk_widget_get_state_flags (widget);
 
-       if (panel->priv->adding_tab)
-               return;
+       gtk_style_context_get_padding (context, state, border);
+       gtk_style_context_get_border (context, state, &tmp);
+
+       border->top += tmp.top;
+       border->right += tmp.right;
+       border->bottom += tmp.bottom;
+       border->left += tmp.left;
+}
+
+/* Gedit Document Row */
+static void
+gedit_documents_document_row_get_preferred_height (GtkWidget *widget,
+                                                   gint      *minimum_height,
+                                                   gint      *natural_height)
+{
+       GeditDocumentsDocumentRow *row;
+       GtkBorder border;
+       gint used_min_height;
+       gint used_nat_height;
+       gint row_min_height;
 
-       panel->priv->is_reodering = TRUE;
+       get_padding_and_border (widget, &border);
 
-       path_string = gtk_tree_path_to_string (path);
+       GTK_WIDGET_CLASS (gedit_documents_document_row_parent_class)->get_preferred_height (widget,
+                                                                                           minimum_height,
+                                                                                           natural_height);
 
-       gedit_debug_message (DEBUG_PANEL, "New Path: %s", path_string);
+       row = GEDIT_DOCUMENTS_DOCUMENT_ROW (widget);
+       row_min_height = row->row_min_height;
 
-       g_message ("%s", path_string);
+       if (!row_min_height)
+       {
+               row_min_height = ROW_MIN_HEIGHT + border.top + border.bottom + 6;
+       }
 
-       gtk_tree_model_get (panel->priv->model,
-                           iter,
-                           NOTEBOOK_COLUMN, &notebook,
-                           TAB_COLUMN, &tab,
-                           -1);
+       used_min_height = MAX (row_min_height, *minimum_height);
+       used_nat_height = used_min_height;
 
-       panel->priv->is_reodering = FALSE;
+       row->row_min_height = used_min_height;
 
-       g_free (path_string);
+       *minimum_height = used_min_height;
+       *natural_height = used_nat_height;
 }
-*/
 
 static void
-close_button_clicked (GtkCellRenderer     *cell,
-                      const gchar         *path,
-                      GeditDocumentsPanel *panel)
+gedit_documents_document_row_finalize (GObject *object)
 {
-       GtkTreeIter iter;
-       GeditTab *tab;
-       GeditNotebook *notebook;
+       GeditDocumentsDocumentRow *row = GEDIT_DOCUMENTS_DOCUMENT_ROW (object);
 
-       if (!gtk_tree_model_get_iter_from_string (panel->priv->model,
-                                                 &iter, path))
-       {
-               return;
-       }
+       g_free (row->name);
 
-       gtk_tree_model_get (panel->priv->model,
-                           &iter,
-                           NOTEBOOK_COLUMN, &notebook,
-                           TAB_COLUMN, &tab,
-                           -1);
+       G_OBJECT_CLASS (gedit_documents_document_row_parent_class)->finalize (object);
+}
 
-       if (tab == NULL)
-       {
-               gedit_notebook_remove_all_tabs (notebook);
-       }
-       else
-       {
-               gtk_container_remove (GTK_CONTAINER (notebook),
-                                     GTK_WIDGET (tab));
-               g_object_unref (tab);
-       }
+static void
+gedit_documents_document_row_class_init (GeditDocumentsDocumentRowClass *klass)
+{
+       GObjectClass *object_class = G_OBJECT_CLASS (klass);
+       GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
 
-       g_object_unref (notebook);
+       object_class->finalize = gedit_documents_document_row_finalize;
+
+       widget_class->get_preferred_height = gedit_documents_document_row_get_preferred_height;
 }
 
 static void
-pixbuf_data_func (GtkTreeViewColumn   *column,
-                 GtkCellRenderer     *cell,
-                 GtkTreeModel        *model,
-                 GtkTreeIter         *iter,
-                 GeditDocumentsPanel *panel)
+gedit_documents_document_row_init (GeditDocumentsDocumentRow *row)
 {
-       GeditTab *tab;
+       GtkWidget *row_widget;
+       GtkStyleContext *context;
+
+       gedit_debug (DEBUG_PANEL);
+
+       row->row_min_height = 0;
+       row->name = NULL;
+
+       row_widget = row_create (GTK_WIDGET (row));
+       gtk_container_add (GTK_CONTAINER (row), row_widget);
+
+       document_row_create_header (GTK_WIDGET (row));
+
+       gtk_widget_set_has_tooltip (GTK_WIDGET (row), TRUE);
 
-       gtk_tree_model_get (model,
-                           iter,
-                           TAB_COLUMN, &tab,
-                           -1);
+       /* Css style */
+       context = gtk_widget_get_style_context (GTK_WIDGET (row));
+       gtk_style_context_add_class (context, "gedit-document-panel-document-row");
 
-       gtk_cell_renderer_set_visible (cell, tab != NULL);
+       gtk_widget_show_all (GTK_WIDGET (row));
+       gtk_widget_hide (row->close_button_image);
 
-       if (tab != NULL)
+       gtk_widget_set_can_focus (GTK_WIDGET (row), FALSE);
+}
+
+/* Gedit Group Row */
+static void
+gedit_documents_group_row_get_preferred_height (GtkWidget *widget,
+                                                gint      *minimum_height,
+                                                gint      *natural_height)
+{
+       GtkBorder border;
+       GeditDocumentsGroupRow *row;
+       gint row_min_height;
+       gint used_min_height;
+       gint used_nat_height;
+
+       get_padding_and_border (widget, &border);
+
+       GTK_WIDGET_CLASS (gedit_documents_group_row_parent_class)->get_preferred_height (widget,
+                                                                                        minimum_height,
+                                                                                        natural_height);
+
+       row = GEDIT_DOCUMENTS_GROUP_ROW (widget);
+       row_min_height = row->row_min_height;
+
+       if (!row_min_height)
        {
-               g_object_unref (tab);
+               row_min_height = ROW_MIN_HEIGHT + border.top + border.bottom + 6;
        }
+
+       used_min_height = MAX (row_min_height, *minimum_height);
+       used_nat_height = used_min_height;
+
+       row->row_min_height = used_min_height;
+
+       *minimum_height = used_min_height;
+       *natural_height = used_nat_height;
 }
 
 static void
-gedit_documents_panel_init (GeditDocumentsPanel *panel)
+gedit_documents_group_row_finalize (GObject *object)
 {
-       GtkWidget *sw;
-       GtkTreeViewColumn *column;
-       GtkCellRenderer *cell;
-       GtkTreeSelection *selection;
-       GIcon *icon;
+       GeditDocumentsGroupRow *row = GEDIT_DOCUMENTS_GROUP_ROW (object);
+
+       g_free (row->name);
+
+       G_OBJECT_CLASS (gedit_documents_group_row_parent_class)->finalize (object);
+}
+
+static void
+gedit_documents_group_row_class_init (GeditDocumentsGroupRowClass *klass)
+{
+       GObjectClass *object_class = G_OBJECT_CLASS (klass);
+       GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+
+       object_class->finalize = gedit_documents_group_row_finalize;
+
+       widget_class->get_preferred_height = gedit_documents_group_row_get_preferred_height;
+}
+
+static void
+gedit_documents_group_row_init (GeditDocumentsGroupRow *row)
+{
+       GtkWidget *row_widget;
+       GtkStyleContext *context;
 
        gedit_debug (DEBUG_PANEL);
 
-       panel->priv = gedit_documents_panel_get_instance_private (panel);
+       row->row_min_height = 0;
+       row->name = NULL;
 
-       panel->priv->adding_tab = FALSE;
-       panel->priv->is_reodering = FALSE;
+       row_widget = row_create (GTK_WIDGET (row));
+       gtk_container_add (GTK_CONTAINER (row), row_widget);
 
-       gtk_orientable_set_orientation (GTK_ORIENTABLE (panel),
-                                       GTK_ORIENTATION_VERTICAL);
+       gtk_widget_set_has_tooltip (GTK_WIDGET (row), TRUE);
 
-       /* Create the scrolled window */
-       sw = gtk_scrolled_window_new (NULL, NULL);
+       /* Css style */
+       context = gtk_widget_get_style_context (GTK_WIDGET (row));
+       gtk_style_context_add_class (context, "gedit-document-panel-group-row");
 
-       gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
-                                       GTK_POLICY_AUTOMATIC,
-                                       GTK_POLICY_AUTOMATIC);
-       gtk_widget_show (sw);
-       gtk_box_pack_start (GTK_BOX (panel), sw, TRUE, TRUE, 0);
+       gtk_widget_show_all (GTK_WIDGET (row));
+       gtk_widget_hide (row->close_button_image);
 
-       /* Create the empty model */
-       panel->priv->model = GTK_TREE_MODEL (gtk_tree_store_new (N_COLUMNS,
-                                                                GDK_TYPE_PIXBUF,
-                                                                G_TYPE_STRING,
-                                                                G_TYPE_OBJECT,
-                                                                G_TYPE_OBJECT));
-
-       /* Create the treeview */
-       panel->priv->treeview = gtk_tree_view_new_with_model (panel->priv->model);
-       g_object_unref (G_OBJECT (panel->priv->model));
-       gtk_container_add (GTK_CONTAINER (sw), panel->priv->treeview);
-       gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (panel->priv->treeview), FALSE);
-       gtk_tree_view_set_reorderable (GTK_TREE_VIEW (panel->priv->treeview), FALSE); /* TODO */
-       gtk_tree_view_set_show_expanders (GTK_TREE_VIEW (panel->priv->treeview), FALSE);
-       gtk_tree_view_set_level_indentation (GTK_TREE_VIEW (panel->priv->treeview), 18);
-
-       /* Disable search because each time the selection is changed, the
-          active tab is changed which focuses the view, and thus would remove
-          the search entry, rendering it useless */
-       gtk_tree_view_set_enable_search (GTK_TREE_VIEW (panel->priv->treeview), FALSE);
+       gtk_widget_set_can_focus (GTK_WIDGET (row), FALSE);
+}
 
-       /* Disable focus so it doesn't steal focus each time from the view */
-       gtk_widget_set_can_focus (panel->priv->treeview, FALSE);
+static GtkWidget *
+gedit_documents_document_row_new (GeditDocumentsPanel *panel,
+                                  GeditTab *tab)
+{
+       GeditDocumentsDocumentRow *row = g_object_new (GEDIT_TYPE_DOCUMENTS_DOCUMENT_ROW, NULL);
 
-       gtk_widget_set_has_tooltip (panel->priv->treeview, TRUE);
+       gedit_debug (DEBUG_PANEL);
 
-       gtk_widget_show (panel->priv->treeview);
+       g_return_val_if_fail (GEDIT_IS_DOCUMENTS_PANEL (panel), NULL);
+       g_return_val_if_fail (GEDIT_IS_TAB (tab), NULL);
 
-       column = gtk_tree_view_column_new ();
-       gtk_tree_view_column_set_title (column, _("Documents"));
+       row->ref = GTK_WIDGET (tab);
+       row->panel = panel;
 
-       cell = gtk_cell_renderer_pixbuf_new ();
-       gtk_tree_view_column_pack_start (column, cell, FALSE);
-       gtk_tree_view_column_add_attribute (column, cell, "pixbuf", PIXBUF_COLUMN);
-       gtk_tree_view_column_set_cell_data_func (column, cell,
-                                                (GtkTreeCellDataFunc)pixbuf_data_func,
-                                                panel, NULL);
+       g_signal_connect (row->ref,
+                         "notify::name",
+                         G_CALLBACK (document_row_sync_tab_name_and_icon), row);
 
-       cell = gtk_cell_renderer_text_new ();
-       gtk_tree_view_column_pack_start (column, cell, TRUE);
-       gtk_tree_view_column_add_attribute (column, cell, "markup", NAME_COLUMN);
-       gtk_tree_view_append_column (GTK_TREE_VIEW (panel->priv->treeview),
-                                    column);
+       g_signal_connect (row->ref,
+                         "notify::state",
+                         G_CALLBACK (document_row_sync_tab_name_and_icon), row);
 
-       cell = gedit_cell_renderer_button_new ();
+       g_signal_connect (row,
+                         "query-tooltip",
+                         G_CALLBACK (row_query_tooltip),
+                         &(row->ref));
 
-       icon = g_themed_icon_new_with_default_fallbacks ("window-close-symbolic");
-       g_object_set (cell, "gicon", icon, NULL);
-       g_object_unref (icon);
-       gtk_tree_view_column_pack_end (column, cell, FALSE);
-       g_signal_connect (cell,
-                         "clicked",
-                         G_CALLBACK (close_button_clicked),
-                         panel);
+       document_row_sync_tab_name_and_icon (GEDIT_TAB (row->ref), NULL, GTK_WIDGET (row));
 
-       selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (panel->priv->treeview));
-       gtk_tree_selection_set_mode (selection, GTK_SELECTION_SINGLE);
-       panel->priv->selection_changed_handler_id = g_signal_connect (selection,
-                                                                     "changed",
-                                                                      G_CALLBACK 
(treeview_selection_changed),
-                                                                      panel);
-
-       g_signal_connect (panel->priv->treeview,
-                         "button-press-event",
-                         G_CALLBACK (panel_button_press_event),
-                         panel);
-       g_signal_connect (panel->priv->treeview,
-                         "query-tooltip",
-                         G_CALLBACK (treeview_query_tooltip),
-                         panel);
-
-       /*
-       g_signal_connect (panel->priv->model,
-                         "row-inserted",
-                         G_CALLBACK (treeview_row_inserted),
-                         panel);*/
+       return GTK_WIDGET (row);
 }
 
-GtkWidget *
-gedit_documents_panel_new (GeditWindow *window)
+static GtkWidget *
+gedit_documents_group_row_new (GeditDocumentsPanel *panel,
+                               GeditNotebook *notebook)
 {
+       GeditDocumentsGroupRow *row = g_object_new (GEDIT_TYPE_DOCUMENTS_GROUP_ROW, NULL);
+
        gedit_debug (DEBUG_PANEL);
 
-       g_return_val_if_fail (GEDIT_IS_WINDOW (window), NULL);
+       g_return_val_if_fail (GEDIT_IS_DOCUMENTS_PANEL (panel), NULL);
+       g_return_val_if_fail (GEDIT_IS_NOTEBOOK (notebook), NULL);
 
-       return g_object_new (GEDIT_TYPE_DOCUMENTS_PANEL,
-                            "window", window,
-                            NULL);
+       row->ref = GTK_WIDGET (notebook);
+       row->panel = panel;
+
+       group_row_set_notebook_name (GTK_WIDGET (row));
+
+       g_signal_connect (row,
+                         "query-tooltip",
+                         G_CALLBACK (row_query_tooltip),
+                         &(row->ref));
+
+       return GTK_WIDGET (row);
 }
 
 /* ex:set ts=8 noet: */
diff --git a/gedit/gedit-notebook.c b/gedit/gedit-notebook.c
index 103e81d..b60f1fc 100644
--- a/gedit/gedit-notebook.c
+++ b/gedit/gedit-notebook.c
@@ -84,7 +84,10 @@ gedit_notebook_grab_focus (GtkWidget *widget)
        current_page = gtk_notebook_get_current_page (nb);
        tab = gtk_notebook_get_nth_page (nb, current_page);
 
-       gtk_widget_grab_focus (tab);
+       if (tab)
+       {
+               gtk_widget_grab_focus (tab);
+       }
 }
 
 static gint


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]