]> www.fi.muni.cz Git - evince.git/blobdiff - shell/ev-sidebar-links.c
[dualscreen] fix crash on ctrl+w and fix control window closing
[evince.git] / shell / ev-sidebar-links.c
index 623753c9272549da6f43db3a9d8f4919bf8866d3..28a4fddc66d2db03e7e5cbb19b000bde20dabbdc 100644 (file)
@@ -17,7 +17,7 @@
  *
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  */
 
 #ifdef HAVE_CONFIG_H
@@ -46,7 +46,7 @@ struct _EvSidebarLinksPrivate {
        EvJob *job;
        GtkTreeModel *model;
        EvDocument *document;
-       EvPageCache *page_cache;
+       EvDocumentModel *doc_model;
 };
 
 enum {
@@ -60,18 +60,20 @@ enum {
        N_SIGNALS
 };
 
-static void update_page_callback                       (EvPageCache       *page_cache,
-                                                        gint               current_page,
-                                                        EvSidebarLinks    *sidebar_links);
+static void update_page_callback                       (EvSidebarLinks    *sidebar_links,
+                                                        gint               old_page,
+                                                        gint               current_page);
 static void row_activated_callback                     (GtkTreeView *treeview,
                                                         GtkTreePath *arg1,
                                                         GtkTreeViewColumn *arg2,
                                                         gpointer user_data);
+static void ev_sidebar_links_set_links_model            (EvSidebarLinks *links,
+                                                        GtkTreeModel   *model);
 static void job_finished_callback                      (EvJobLinks     *job,
                                                         EvSidebarLinks *sidebar_links);
-static void ev_sidebar_links_page_iface_init           (EvSidebarPageIface *iface);
-static void ev_sidebar_links_set_document                      (EvSidebarPage  *sidebar_page,
-                                                        EvDocument     *document);
+static void ev_sidebar_links_set_current_page           (EvSidebarLinks *sidebar_links,
+                                                        gint            current_page);
+static void ev_sidebar_links_page_iface_init           (EvSidebarPageInterface *iface);
 static gboolean ev_sidebar_links_support_document      (EvSidebarPage  *sidebar_page,
                                                         EvDocument     *document);
 static const gchar* ev_sidebar_links_get_label                 (EvSidebarPage *sidebar_page);
@@ -95,18 +97,12 @@ ev_sidebar_links_set_property (GObject      *object,
                               const GValue *value,
                               GParamSpec   *pspec)
 {
-       EvSidebarLinks *ev_sidebar_links;
-       GtkTreeModel *model;
-  
-       ev_sidebar_links = EV_SIDEBAR_LINKS (object);
+       EvSidebarLinks *ev_sidebar_links = EV_SIDEBAR_LINKS (object);
 
        switch (prop_id)
        {
        case PROP_MODEL:
-               model = ev_sidebar_links->priv->model;
-               ev_sidebar_links->priv->model = GTK_TREE_MODEL (g_value_dup_object (value));
-               if (model)
-                       g_object_unref (model);
+               ev_sidebar_links_set_links_model (ev_sidebar_links, g_value_get_object (value));
                break;
        default:
                G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@@ -159,7 +155,7 @@ ev_sidebar_links_dispose (GObject *object)
        if (sidebar->priv->document) {
                g_object_unref (sidebar->priv->document);
                sidebar->priv->document = NULL;
-               sidebar->priv->page_cache = NULL;
+               sidebar->priv->doc_model = NULL;
        }
 
        G_OBJECT_CLASS (ev_sidebar_links_parent_class)->dispose (object);
@@ -175,9 +171,8 @@ ev_sidebar_links_map (GtkWidget *widget)
        GTK_WIDGET_CLASS (ev_sidebar_links_parent_class)->map (widget);
 
        if (links->priv->model) {
-               update_page_callback (links->priv->page_cache,
-                                     ev_page_cache_get_current_page (links->priv->page_cache),
-                                     links);
+               ev_sidebar_links_set_current_page (links,
+                                                  ev_document_model_get_page (links->priv->doc_model));
        }
 }
 
@@ -239,10 +234,10 @@ selection_changed_callback (GtkTreeSelection   *selection,
                if (link == NULL)
                        return;
 
-               g_signal_handler_block (ev_sidebar_links->priv->page_cache,
+               g_signal_handler_block (ev_sidebar_links->priv->doc_model,
                                        ev_sidebar_links->priv->page_changed_id);
                g_signal_emit (ev_sidebar_links, signals[LINK_ACTIVATED], 0, link);
-               g_signal_handler_unblock (ev_sidebar_links->priv->page_cache,
+               g_signal_handler_unblock (ev_sidebar_links->priv->doc_model,
                                          ev_sidebar_links->priv->page_changed_id);
 
                g_object_unref (link);
@@ -264,7 +259,7 @@ create_loading_model (void)
                                                     G_TYPE_STRING);
 
        gtk_list_store_append (GTK_LIST_STORE (retval), &iter);
-       markup = g_strdup_printf ("<span size=\"larger\" style=\"italic\">%s</span>", _("Loading..."));
+       markup = g_strdup_printf ("<span size=\"larger\" style=\"italic\">%s</span>", _("Loading…"));
        gtk_list_store_set (GTK_LIST_STORE (retval), &iter,
                            EV_DOCUMENT_LINKS_COLUMN_MARKUP, markup,
                            EV_DOCUMENT_LINKS_COLUMN_EXPAND, FALSE,
@@ -289,6 +284,7 @@ print_section_cb (GtkWidget *menuitem, EvSidebarLinks *sidebar)
        if (gtk_tree_selection_get_selected (selection, &model, &iter)) {
                EvLink *link;
                int first_page, last_page = -1;
+               EvDocumentLinks *document_links;
 
                gtk_tree_model_get (model, &iter,
                                    EV_DOCUMENT_LINKS_COLUMN_LINK, &link,
@@ -297,7 +293,9 @@ print_section_cb (GtkWidget *menuitem, EvSidebarLinks *sidebar)
                if (!link)
                        return;
 
-               first_page = ev_link_get_page (link);
+               document_links = EV_DOCUMENT_LINKS (sidebar->priv->document);
+
+               first_page = ev_document_links_get_link_page (document_links, link);
                if (first_page == -1) {
                        g_object_unref (link);
                        return;
@@ -312,15 +310,15 @@ print_section_cb (GtkWidget *menuitem, EvSidebarLinks *sidebar)
                                            -1);
 
                        if (link) {
-                               last_page = ev_link_get_page (link);
+                               last_page = ev_document_links_get_link_page (document_links, link);;
                                g_object_unref (link);
                        }
                } else {
-                       last_page = ev_page_cache_get_n_pages (sidebar->priv->page_cache);
+                       last_page = ev_document_get_n_pages (sidebar->priv->document);
                }
 
                if (last_page == -1)
-                       last_page = ev_page_cache_get_n_pages (sidebar->priv->page_cache);
+                       last_page = ev_document_get_n_pages (sidebar->priv->document);
        
                window = gtk_widget_get_toplevel (GTK_WIDGET (sidebar));
                if (EV_IS_WINDOW (window)) {
@@ -337,7 +335,7 @@ build_popup_menu (EvSidebarLinks *sidebar)
 
        menu = gtk_menu_new ();
        item = gtk_image_menu_item_new_from_stock (GTK_STOCK_PRINT, NULL);
-       gtk_label_set_label (GTK_LABEL (GTK_BIN (item)->child), _("Print..."));
+       gtk_label_set_label (GTK_LABEL (gtk_bin_get_child (GTK_BIN (item))), _("Print…"));
        gtk_widget_show (item);
        gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
        g_signal_connect (item, "activate",
@@ -437,13 +435,16 @@ ev_sidebar_links_construct (EvSidebarLinks *ev_sidebar_links)
        gtk_tree_view_column_set_attributes (GTK_TREE_VIEW_COLUMN (column), renderer,
                                             "text", EV_DOCUMENT_LINKS_COLUMN_PAGE_LABEL,
                                             NULL);
-       g_object_set (G_OBJECT (renderer), "style", PANGO_STYLE_ITALIC, NULL);
+       g_object_set (G_OBJECT (renderer),
+                      "style", PANGO_STYLE_ITALIC,
+                      "xalign", 1.0,
+                      NULL);
 
-       g_signal_connect (GTK_TREE_VIEW (priv->tree_view),
+       g_signal_connect (priv->tree_view,
                          "button_press_event",
                          G_CALLBACK (button_press_cb),
                          ev_sidebar_links);
-       g_signal_connect (GTK_TREE_VIEW (priv->tree_view),
+       g_signal_connect (priv->tree_view,
                          "popup_menu",
                          G_CALLBACK (popup_menu_cb),
                          ev_sidebar_links);
@@ -457,40 +458,6 @@ ev_sidebar_links_init (EvSidebarLinks *ev_sidebar_links)
        ev_sidebar_links_construct (ev_sidebar_links);
 }
 
-static gboolean
-fill_page_labels (GtkTreeModel *tree_model,
-                  GtkTreePath *path,
-                  GtkTreeIter *iter,
-                 EvSidebarLinks    *sidebar_links)
-{
-       EvLink *link;
-       gint page;
-       gchar *page_label;
-
-       gtk_tree_model_get (tree_model, iter,
-                           EV_DOCUMENT_LINKS_COLUMN_LINK, &link,
-                           -1);
-
-       if (!link)
-               return FALSE;
-
-       page = ev_link_get_page (link);
-
-       if (page < 0) 
-               return FALSE;
-       
-       page_label = ev_page_cache_get_page_label (sidebar_links->priv->page_cache,
-                                                  page);
-       gtk_tree_store_set (GTK_TREE_STORE (tree_model), iter,
-                           EV_DOCUMENT_LINKS_COLUMN_PAGE_LABEL, page_label, 
-                           -1);
-
-       g_free (page_label);
-
-       g_object_unref (link);
-       return FALSE;
-}
-
 /* Public Functions */
 
 GtkWidget *
@@ -519,11 +486,12 @@ update_page_callback_foreach (GtkTreeModel *model,
        if (link) {
                int current_page;
                int dest_page;
+               EvDocumentLinks *document_links = EV_DOCUMENT_LINKS (sidebar_links->priv->document);
 
-               dest_page = ev_link_get_page (link);
+               dest_page = ev_document_links_get_link_page (document_links, link);
                g_object_unref (link);
                
-               current_page = ev_page_cache_get_current_page (sidebar_links->priv->page_cache);
+               current_page = ev_document_model_get_page (sidebar_links->priv->doc_model);
                         
                if (dest_page == current_page) {
                        gtk_tree_view_expand_to_path (GTK_TREE_VIEW (sidebar_links->priv->tree_view),
@@ -539,16 +507,15 @@ update_page_callback_foreach (GtkTreeModel *model,
 }
 
 static void
-update_page_callback (EvPageCache    *page_cache,
-                     gint            current_page,
-                     EvSidebarLinks *sidebar_links)
+ev_sidebar_links_set_current_page (EvSidebarLinks *sidebar_links,
+                                  gint            current_page)
 {
        GtkTreeSelection *selection;
        GtkTreeModel *model;
        GtkTreeIter iter;
 
        /* Widget is not currently visible */
-       if (!GTK_WIDGET_MAPPED (sidebar_links))
+       if (!gtk_widget_get_mapped (GTK_WIDGET (sidebar_links)))
                return;
        
        selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (sidebar_links->priv->tree_view));
@@ -561,8 +528,9 @@ update_page_callback (EvPageCache    *page_cache,
                                    -1);
                if (link) {
                        gint dest_page;
+                       EvDocumentLinks *document_links = EV_DOCUMENT_LINKS (sidebar_links->priv->document);
 
-                       dest_page = ev_link_get_page (link);
+                       dest_page = ev_document_links_get_link_page (document_links, link);
                        g_object_unref (link);
                        
                        if (dest_page == current_page)
@@ -586,6 +554,14 @@ update_page_callback (EvPageCache    *page_cache,
        g_signal_handler_unblock (sidebar_links->priv->tree_view, sidebar_links->priv->row_activated_id);
 }
 
+static void
+update_page_callback (EvSidebarLinks *sidebar_links,
+                     gint            old_page,
+                     gint            new_page)
+{
+       ev_sidebar_links_set_current_page (sidebar_links, new_page);
+}
+
 static void 
 row_activated_callback (GtkTreeView       *treeview,
                        GtkTreePath       *arg1,
@@ -622,20 +598,31 @@ expand_open_links (GtkTreeView *tree_view, GtkTreeModel *model, GtkTreeIter *par
                } while (gtk_tree_model_iter_next (model, &iter));
        }
 }
-       
+
+static void
+ev_sidebar_links_set_links_model (EvSidebarLinks *sidebar_links,
+                                 GtkTreeModel   *model)
+{
+       EvSidebarLinksPrivate *priv = sidebar_links->priv;
+
+       if (priv->model == model)
+               return;
+
+       if (priv->model)
+               g_object_unref (priv->model);
+       priv->model = g_object_ref (model);
+
+       g_object_notify (G_OBJECT (sidebar_links), "model");
+}
+
 static void
 job_finished_callback (EvJobLinks     *job,
                       EvSidebarLinks *sidebar_links)
 {
-       EvSidebarLinksPrivate *priv;
+       EvSidebarLinksPrivate *priv = sidebar_links->priv;
        GtkTreeSelection *selection;
 
-       priv = sidebar_links->priv;
-       
-       priv->model = job->model;
-       g_object_notify (G_OBJECT (sidebar_links), "model");
-       
-       gtk_tree_model_foreach (priv->model, (GtkTreeModelForeachFunc)fill_page_labels, sidebar_links);
+       ev_sidebar_links_set_links_model (sidebar_links, job->model);
 
        gtk_tree_view_set_model (GTK_TREE_VIEW (priv->tree_view), job->model);
        
@@ -653,34 +640,34 @@ job_finished_callback (EvJobLinks     *job,
                                          G_CALLBACK (selection_changed_callback),
                                          sidebar_links);
        }
-       priv->page_changed_id = g_signal_connect (priv->page_cache, "page-changed",
-                                                 G_CALLBACK (update_page_callback),
-                                                 sidebar_links);
+       priv->page_changed_id =
+               g_signal_connect_swapped (priv->doc_model, "page-changed",
+                                         G_CALLBACK (update_page_callback),
+                                         sidebar_links);
        if (priv->row_activated_id <= 0) {
                priv->row_activated_id =
-                       g_signal_connect (G_OBJECT (priv->tree_view), "row-activated",
+                       g_signal_connect (priv->tree_view, "row-activated",
                                          G_CALLBACK (row_activated_callback),
                                          sidebar_links);
        }
-       
-       update_page_callback (priv->page_cache,
-                             ev_page_cache_get_current_page (priv->page_cache),
-                             sidebar_links);
+
+       ev_sidebar_links_set_current_page (sidebar_links,
+                                          ev_document_model_get_page (priv->doc_model));
 }
 
 static void
-ev_sidebar_links_set_document (EvSidebarPage  *sidebar_page,
-                              EvDocument     *document)
+ev_sidebar_links_document_changed_cb (EvDocumentModel *model,
+                                     GParamSpec      *pspec,
+                                     EvSidebarLinks  *sidebar_links)
 {
-       EvSidebarLinks *sidebar_links;
-       EvSidebarLinksPrivate *priv;
+       EvDocument *document = ev_document_model_get_document (model);
+       EvSidebarLinksPrivate *priv = sidebar_links->priv;
 
-       g_return_if_fail (EV_IS_SIDEBAR_PAGE (sidebar_page));
-       g_return_if_fail (EV_IS_DOCUMENT (document));
-       
-       sidebar_links = EV_SIDEBAR_LINKS (sidebar_page);
+       if (!EV_IS_DOCUMENT_LINKS (document))
+               return;
 
-       priv = sidebar_links->priv;
+       if (!ev_document_links_has_document_links (EV_DOCUMENT_LINKS (document)))
+               return;
 
        if (priv->document) {
                gtk_tree_view_set_model (GTK_TREE_VIEW (priv->tree_view), NULL);
@@ -688,7 +675,6 @@ ev_sidebar_links_set_document (EvSidebarPage  *sidebar_page,
        }
 
        priv->document = g_object_ref (document);
-       priv->page_cache = ev_page_cache_get (document);
 
        if (priv->job) {
                g_signal_handlers_disconnect_by_func (priv->job,
@@ -706,6 +692,22 @@ ev_sidebar_links_set_document (EvSidebarPage  *sidebar_page,
        ev_job_scheduler_push_job (priv->job, EV_JOB_PRIORITY_NONE);
 }
 
+static void
+ev_sidebar_links_set_model (EvSidebarPage   *sidebar_page,
+                           EvDocumentModel *model)
+{
+       EvSidebarLinks *sidebar_links = EV_SIDEBAR_LINKS (sidebar_page);
+       EvSidebarLinksPrivate *priv = sidebar_links->priv;
+
+       if (priv->doc_model == model)
+               return;
+
+       priv->doc_model = model;
+       g_signal_connect (model, "notify::document",
+                         G_CALLBACK (ev_sidebar_links_document_changed_cb),
+                         sidebar_page);
+}
+
 static gboolean
 ev_sidebar_links_support_document (EvSidebarPage  *sidebar_page,
                                   EvDocument *document)
@@ -721,10 +723,10 @@ ev_sidebar_links_get_label (EvSidebarPage *sidebar_page)
 }
 
 static void
-ev_sidebar_links_page_iface_init (EvSidebarPageIface *iface)
+ev_sidebar_links_page_iface_init (EvSidebarPageInterface *iface)
 {
        iface->support_document = ev_sidebar_links_support_document;
-       iface->set_document = ev_sidebar_links_set_document;
+       iface->set_model = ev_sidebar_links_set_model;
        iface->get_label = ev_sidebar_links_get_label;
 }