nautilus-places-view.c 11.8 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
/* nautilus-places-view.c
 *
 * Copyright (C) 2015 Georges Basile Stavracas Neto <georges.stavracas@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
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "nautilus-mime-actions.h"
#include "nautilus-places-view.h"
21 22 23

#include "gtk/nautilusgtkplacesviewprivate.h"

24
#include "nautilus-application.h"
25
#include "nautilus-file.h"
26
#include "nautilus-toolbar-menu-sections.h"
27 28
#include "nautilus-view.h"
#include "nautilus-window-slot.h"
29 30 31

typedef struct
{
32 33 34
    GFile *location;
    NautilusQuery *search_query;
    NautilusToolbarMenuSections *toolbar_menu_sections;
35

36
    GtkWidget *places_view;
37 38 39 40
} NautilusPlacesViewPrivate;

struct _NautilusPlacesView
{
41
    GtkFrameClass parent;
42 43
};

44
static void          nautilus_places_view_iface_init (NautilusViewInterface *iface);
45 46 47 48 49

G_DEFINE_TYPE_WITH_CODE (NautilusPlacesView, nautilus_places_view, GTK_TYPE_BOX,
                         G_ADD_PRIVATE (NautilusPlacesView)
                         G_IMPLEMENT_INTERFACE (NAUTILUS_TYPE_VIEW, nautilus_places_view_iface_init));

50 51 52 53 54
enum
{
    PROP_0,
    PROP_LOCATION,
    PROP_SEARCH_QUERY,
55 56 57
    PROP_LOADING,
    PROP_SEARCHING,
    PROP_SELECTION,
58
    LAST_PROP
59 60 61 62 63 64 65
};

static void
open_location_cb (NautilusPlacesView *view,
                  GFile              *location,
                  GtkPlacesOpenFlags  open_flags)
{
66 67
    NautilusWindowOpenFlags flags;
    GtkWidget *slot;
68

69
    slot = gtk_widget_get_ancestor (GTK_WIDGET (view), NAUTILUS_TYPE_WINDOW_SLOT);
70

71 72
    switch (open_flags)
    {
73
        case GTK_PLACES_OPEN_NEW_TAB:
74 75 76 77 78
        {
            flags = NAUTILUS_WINDOW_OPEN_FLAG_NEW_TAB |
                    NAUTILUS_WINDOW_OPEN_FLAG_DONT_MAKE_ACTIVE;
        }
        break;
79 80

        case GTK_PLACES_OPEN_NEW_WINDOW:
81 82 83 84
        {
            flags = NAUTILUS_WINDOW_OPEN_FLAG_NEW_WINDOW;
        }
        break;
85 86 87

        case GTK_PLACES_OPEN_NORMAL: /* fall-through */
        default:
88 89
        {
            flags = 0;
90
        }
91 92
        break;
    }
93

94 95 96 97
    if (slot)
    {
        NautilusFile *file;
        GtkWidget *window;
98
        char *path;
99

100
        path = "other-locations:///";
101 102 103 104 105 106
        file = nautilus_file_get (location);
        window = gtk_widget_get_toplevel (GTK_WIDGET (view));

        nautilus_mime_activate_file (GTK_WINDOW (window),
                                     NAUTILUS_WINDOW_SLOT (slot),
                                     file,
107
                                     path,
108 109 110
                                     flags);
        nautilus_file_unref (file);
    }
111 112 113 114 115
}

static void
loading_cb (NautilusView *view)
{
116
    g_object_notify (G_OBJECT (view), "loading");
117 118
}

119 120 121 122 123
static void
show_error_message_cb (NautilusGtkPlacesView *view,
                       const gchar           *primary,
                       const gchar           *secondary)
{
124 125
    GtkWidget *dialog;
    GtkWidget *window;
126

127
    window = gtk_widget_get_toplevel (GTK_WIDGET (view));
128

129 130 131 132 133 134 135
    dialog = gtk_message_dialog_new (GTK_WINDOW (window),
                                     GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_MODAL,
                                     GTK_MESSAGE_ERROR,
                                     GTK_BUTTONS_CLOSE,
                                     "%s", primary);
    gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
                                              "%s", secondary);
136

137
    gtk_dialog_run (GTK_DIALOG (dialog));
138

139
    gtk_widget_destroy (dialog);
140 141
}

142 143 144
static void
nautilus_places_view_finalize (GObject *object)
{
145 146
    NautilusPlacesView *self = (NautilusPlacesView *) object;
    NautilusPlacesViewPrivate *priv = nautilus_places_view_get_instance_private (self);
147

148 149
    g_clear_object (&priv->location);
    g_clear_object (&priv->search_query);
150

151
    g_free (priv->toolbar_menu_sections);
152

153
    G_OBJECT_CLASS (nautilus_places_view_parent_class)->finalize (object);
154 155 156 157 158 159 160 161
}

static void
nautilus_places_view_get_property (GObject    *object,
                                   guint       prop_id,
                                   GValue     *value,
                                   GParamSpec *pspec)
{
162
    NautilusView *view = NAUTILUS_VIEW (object);
163

164 165
    switch (prop_id)
    {
166
        case PROP_LOCATION:
167 168 169 170
        {
            g_value_set_object (value, nautilus_view_get_location (view));
        }
        break;
171 172

        case PROP_SEARCH_QUERY:
173 174 175 176
        {
            g_value_set_object (value, nautilus_view_get_search_query (view));
        }
        break;
177 178

        default:
179 180
            G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
    }
181 182 183 184 185 186 187 188
}

static void
nautilus_places_view_set_property (GObject      *object,
                                   guint         prop_id,
                                   const GValue *value,
                                   GParamSpec   *pspec)
{
189
    NautilusView *view = NAUTILUS_VIEW (object);
190

191 192
    switch (prop_id)
    {
193
        case PROP_LOCATION:
194 195 196 197
        {
            nautilus_view_set_location (view, g_value_get_object (value));
        }
        break;
198 199

        case PROP_SEARCH_QUERY:
200 201 202 203
        {
            nautilus_view_set_search_query (view, g_value_get_object (value));
        }
        break;
204 205

        default:
206 207
            G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
    }
208 209
}

210
static GFile *
211 212
nautilus_places_view_get_location (NautilusView *view)
{
213
    NautilusPlacesViewPrivate *priv;
214

215
    priv = nautilus_places_view_get_instance_private (NAUTILUS_PLACES_VIEW (view));
216

217
    return priv->location;
218 219 220 221 222 223
}

static void
nautilus_places_view_set_location (NautilusView *view,
                                   GFile        *location)
{
224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244
    if (location)
    {
        NautilusPlacesViewPrivate *priv;
        gchar *uri;

        priv = nautilus_places_view_get_instance_private (NAUTILUS_PLACES_VIEW (view));
        uri = g_file_get_uri (location);

        /*
         * If it's not trying to open the places view itself, simply
         * delegates the location to application, which takes care of
         * selecting the appropriate view.
         */
        if (g_strcmp0 (uri, "other-locations:///") != 0)
        {
            nautilus_application_open_location_full (NAUTILUS_APPLICATION (g_application_get_default ()),
                                                     location, 0, NULL, NULL, NULL);
        }
        else
        {
            g_set_object (&priv->location, location);
245
        }
246 247 248

        g_free (uri);
    }
249 250
}

251
static GList *
252 253
nautilus_places_view_get_selection (NautilusView *view)
{
254 255
    /* STUB */
    return NULL;
256 257 258 259 260 261
}

static void
nautilus_places_view_set_selection (NautilusView *view,
                                    GList        *selection)
{
262
    /* STUB */
263 264
}

265
static NautilusQuery *
266 267
nautilus_places_view_get_search_query (NautilusView *view)
{
268
    NautilusPlacesViewPrivate *priv;
269

270
    priv = nautilus_places_view_get_instance_private (NAUTILUS_PLACES_VIEW (view));
271

272
    return priv->search_query;
273 274 275 276 277 278
}

static void
nautilus_places_view_set_search_query (NautilusView  *view,
                                       NautilusQuery *query)
{
279 280
    NautilusPlacesViewPrivate *priv;
    gchar *text;
281

282
    priv = nautilus_places_view_get_instance_private (NAUTILUS_PLACES_VIEW (view));
283

284
    g_set_object (&priv->search_query, query);
285

286
    text = query ? nautilus_query_get_text (query) : NULL;
287

288
    nautilus_gtk_places_view_set_search_query (NAUTILUS_GTK_PLACES_VIEW (priv->places_view), text);
289

290
    g_free (text);
291 292
}

293 294
static NautilusToolbarMenuSections *
nautilus_places_view_get_toolbar_menu_sections (NautilusView *view)
295
{
296
    NautilusPlacesViewPrivate *priv;
297

298
    priv = nautilus_places_view_get_instance_private (NAUTILUS_PLACES_VIEW (view));
299

300
    return priv->toolbar_menu_sections;
301 302 303 304 305
}

static gboolean
nautilus_places_view_is_loading (NautilusView *view)
{
306
    NautilusPlacesViewPrivate *priv;
307

308
    priv = nautilus_places_view_get_instance_private (NAUTILUS_PLACES_VIEW (view));
309

310
    return nautilus_gtk_places_view_get_loading (NAUTILUS_GTK_PLACES_VIEW (priv->places_view));
311 312 313 314 315
}

static gboolean
nautilus_places_view_is_searching (NautilusView *view)
{
316
    NautilusPlacesViewPrivate *priv;
317

318
    priv = nautilus_places_view_get_instance_private (NAUTILUS_PLACES_VIEW (view));
319

320
    return priv->search_query != NULL;
321 322
}

323 324 325 326 327 328
static guint
nautilus_places_view_get_view_id (NautilusView *view)
{
    return NAUTILUS_VIEW_OTHER_LOCATIONS_ID;
}

329 330 331
static void
nautilus_places_view_iface_init (NautilusViewInterface *iface)
{
332 333 334 335 336 337 338 339 340
    iface->get_location = nautilus_places_view_get_location;
    iface->set_location = nautilus_places_view_set_location;
    iface->get_selection = nautilus_places_view_get_selection;
    iface->set_selection = nautilus_places_view_set_selection;
    iface->get_search_query = nautilus_places_view_get_search_query;
    iface->set_search_query = nautilus_places_view_set_search_query;
    iface->get_toolbar_menu_sections = nautilus_places_view_get_toolbar_menu_sections;
    iface->is_loading = nautilus_places_view_is_loading;
    iface->is_searching = nautilus_places_view_is_searching;
341
    iface->get_view_id = nautilus_places_view_get_view_id;
342 343 344 345 346
}

static void
nautilus_places_view_class_init (NautilusPlacesViewClass *klass)
{
347
    GObjectClass *object_class = G_OBJECT_CLASS (klass);
348

349 350 351
    object_class->finalize = nautilus_places_view_finalize;
    object_class->get_property = nautilus_places_view_get_property;
    object_class->set_property = nautilus_places_view_set_property;
352

353 354
    g_object_class_override_property (object_class, PROP_LOADING, "loading");
    g_object_class_override_property (object_class, PROP_SEARCHING, "searching");
355 356
    g_object_class_override_property (object_class, PROP_LOCATION, "location");
    g_object_class_override_property (object_class, PROP_SEARCH_QUERY, "search-query");
357 358 359 360 361
}

static void
nautilus_places_view_init (NautilusPlacesView *self)
{
362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395
    NautilusPlacesViewPrivate *priv;

    priv = nautilus_places_view_get_instance_private (self);

    /* Location */
    priv->location = g_file_new_for_uri ("other-locations:///");

    /* Places view */
    priv->places_view = nautilus_gtk_places_view_new ();
    nautilus_gtk_places_view_set_open_flags (NAUTILUS_GTK_PLACES_VIEW (priv->places_view),
                                             GTK_PLACES_OPEN_NEW_TAB | GTK_PLACES_OPEN_NEW_WINDOW | GTK_PLACES_OPEN_NORMAL);
    gtk_widget_set_hexpand (priv->places_view, TRUE);
    gtk_widget_set_vexpand (priv->places_view, TRUE);
    gtk_widget_show (priv->places_view);
    gtk_container_add (GTK_CONTAINER (self), priv->places_view);

    g_signal_connect_swapped (priv->places_view,
                              "notify::loading",
                              G_CALLBACK (loading_cb),
                              self);

    g_signal_connect_swapped (priv->places_view,
                              "open-location",
                              G_CALLBACK (open_location_cb),
                              self);

    g_signal_connect_swapped (priv->places_view,
                              "show-error-message",
                              G_CALLBACK (show_error_message_cb),
                              self);

    /* Toolbar menu */
    priv->toolbar_menu_sections = g_new0 (NautilusToolbarMenuSections, 1);
    priv->toolbar_menu_sections->supports_undo_redo = FALSE;
396 397 398 399 400
}

NautilusPlacesView *
nautilus_places_view_new (void)
{
401
    NautilusPlacesView *view;
402

403 404 405 406 407
    view = g_object_new (NAUTILUS_TYPE_PLACES_VIEW, NULL);
    if (g_object_is_floating (view))
    {
        g_object_ref_sink (view);
    }
408

409
    return view;
410
}