~ubuntu-branches/ubuntu/trusty/epiphany-browser/trusty

« back to all changes in this revision

Viewing changes to src/window-commands.c

  • Committer: Package Import Robot
  • Author(s): Sebastien Bacher
  • Date: 2011-11-21 17:15:18 UTC
  • mfrom: (1.6.3) (98.2.3 sid)
  • Revision ID: package-import@ubuntu.com-20111121171518-0f07y0i5rvb2wrix
Tags: 3.2.1-2ubuntu1
* Resynchronize on Debian, remaining diffs:
* debian/branding.conf.in: set the branding to Ubuntu.
* debian/epiphany-browser-data.gsettings-override:
  - set startpage and search to Ubuntu
* debian/patches/80_ubuntu_search_url.patch: use Ubuntu search
* debian/patches/81_ubuntu_force_update_bookmarks_menu.patch:
  - update the bookmarks menu every time the internal structure
    is changed (needed for the indicator application menu to work correctly).

Show diffs side-by-side

added added

removed removed

Lines of Context:
2
2
/*
3
3
 *  Copyright © 2000-2004 Marco Pesenti Gritti
4
4
 *  Copyright © 2009 Collabora Ltd.
 
5
 *  Copyright © 2011 Igalia S.L.
5
6
 *
6
7
 *  This program is free software; you can redistribute it and/or modify
7
8
 *  it under the terms of the GNU General Public License as published by
50
51
#include "ephy-stock-icons.h"
51
52
#include "ephy-string.h"
52
53
#include "pdm-dialog.h"
 
54
#include "ephy-web-app-utils.h"
53
55
 
54
56
#include <string.h>
55
57
#include <glib.h>
57
59
#include <gtk/gtk.h>
58
60
#include <glib/gi18n.h>
59
61
#include <webkit/webkit.h>
 
62
#include <libnotify/notify.h>
60
63
 
61
64
static void
62
65
page_setup_done_cb (GtkPageSetup *setup,
321
324
        gtk_widget_show (GTK_WIDGET (dialog));
322
325
}
323
326
 
324
 
void
325
 
window_cmd_file_save_as (GtkAction *action,
326
 
                         EphyWindow *window)
 
327
static char *
 
328
get_suggested_filename (EphyWebView *view)
327
329
{
328
 
        EphyEmbed *embed;
329
 
        EphyFileChooser *dialog;
330
 
 
331
 
        /* These all are needed in order to get the suggested filename */
332
330
        char *suggested_filename;
333
331
        const char *mimetype;
334
 
        EphyWebView *view;
335
332
        WebKitWebFrame *frame;
336
333
        WebKitWebDataSource *data_source;
337
334
        WebKitWebResource *web_resource;
338
335
 
339
 
        embed = ephy_embed_container_get_active_child (EPHY_EMBED_CONTAINER (window));
340
 
        g_return_if_fail (embed != NULL);
341
 
 
342
 
        dialog = ephy_file_chooser_new (_("Save"),
343
 
                                        GTK_WIDGET (window),
344
 
                                        GTK_FILE_CHOOSER_ACTION_SAVE,
345
 
                                        EPHY_PREFS_STATE_SAVE_DIR,
346
 
                                        EPHY_FILE_FILTER_ALL);
347
 
 
348
 
        gtk_file_chooser_set_do_overwrite_confirmation (GTK_FILE_CHOOSER (dialog), TRUE);
349
 
 
350
 
        view = ephy_embed_get_web_view (embed);
351
336
        frame = webkit_web_view_get_main_frame (WEBKIT_WEB_VIEW (view));
352
337
        data_source = webkit_web_frame_get_data_source (frame);
353
338
        web_resource = webkit_web_data_source_get_main_resource (data_source);
356
341
        if ((g_ascii_strncasecmp (mimetype, "text/html", 9)) == 0)
357
342
        {
358
343
                /* Web Title will be used as suggested filename*/
359
 
                suggested_filename = g_strconcat(ephy_web_view_get_title (view), ".html",NULL);
 
344
                suggested_filename = g_strconcat (ephy_web_view_get_title (view), ".html", NULL);
360
345
        }
361
346
        else
362
347
        {
365
350
                soup_uri_free (soup_uri);
366
351
        }
367
352
 
 
353
        return suggested_filename;
 
354
}
 
355
 
 
356
void
 
357
window_cmd_file_save_as (GtkAction *action,
 
358
                         EphyWindow *window)
 
359
{
 
360
        EphyEmbed *embed;
 
361
        EphyFileChooser *dialog;
 
362
        char *suggested_filename;
 
363
        EphyWebView *view;
 
364
 
 
365
        embed = ephy_embed_container_get_active_child (EPHY_EMBED_CONTAINER (window));
 
366
        g_return_if_fail (embed != NULL);
 
367
 
 
368
        dialog = ephy_file_chooser_new (_("Save"),
 
369
                                        GTK_WIDGET (window),
 
370
                                        GTK_FILE_CHOOSER_ACTION_SAVE,
 
371
                                        EPHY_PREFS_STATE_SAVE_DIR,
 
372
                                        EPHY_FILE_FILTER_NONE);
 
373
 
 
374
        gtk_file_chooser_set_do_overwrite_confirmation (GTK_FILE_CHOOSER (dialog), TRUE);
 
375
 
 
376
        view = ephy_embed_get_web_view (embed);
 
377
        suggested_filename = get_suggested_filename (view);
 
378
 
368
379
        gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (dialog), suggested_filename);
369
380
        g_free (suggested_filename);
370
381
 
374
385
        gtk_widget_show (GTK_WIDGET (dialog));
375
386
}
376
387
 
 
388
typedef struct {
 
389
        EphyWebView *view;
 
390
        GtkWidget *image;
 
391
        GtkWidget *entry;
 
392
        GtkWidget *spinner;
 
393
        GtkWidget *box;
 
394
        char *icon_href;
 
395
} EphyApplicationDialogData;
 
396
 
 
397
static void
 
398
ephy_application_dialog_data_free (EphyApplicationDialogData *data)
 
399
{
 
400
        g_free (data->icon_href);
 
401
        g_slice_free (EphyApplicationDialogData, data);
 
402
}
 
403
 
 
404
static void
 
405
take_page_snapshot_and_set_image (EphyApplicationDialogData *data)
 
406
{
 
407
        GdkPixbuf *snapshot;
 
408
        int x, y, w, h;
 
409
 
 
410
        x = y = 0;
 
411
        w = h = 128; /* GNOME hi-res icon size. */
 
412
 
 
413
        snapshot = ephy_web_view_get_snapshot (data->view, x, y, w, h);
 
414
 
 
415
        gtk_image_set_from_pixbuf (GTK_IMAGE (data->image), snapshot);
 
416
        g_object_unref (snapshot);
 
417
}
 
418
 
 
419
static void
 
420
download_status_changed_cb (WebKitDownload *download,
 
421
                            GParamSpec *spec,
 
422
                            EphyApplicationDialogData *data)
 
423
{
 
424
        WebKitDownloadStatus status = webkit_download_get_status (download);
 
425
        const char *destination;
 
426
 
 
427
        switch (status)
 
428
        {
 
429
        case WEBKIT_DOWNLOAD_STATUS_FINISHED:
 
430
                destination = g_filename_from_uri (webkit_download_get_destination_uri (download),
 
431
                                                   NULL, NULL);
 
432
                gtk_image_set_from_file (GTK_IMAGE (data->image), destination);
 
433
                break;
 
434
        case WEBKIT_DOWNLOAD_STATUS_ERROR:
 
435
        case WEBKIT_DOWNLOAD_STATUS_CANCELLED:
 
436
                /* Something happened, default to a page snapshot. */
 
437
                take_page_snapshot_and_set_image (data);
 
438
                break;
 
439
        default:
 
440
                break;
 
441
        }
 
442
}
 
443
 
 
444
static void
 
445
download_icon_and_set_image (EphyApplicationDialogData *data)
 
446
{
 
447
        WebKitNetworkRequest *request;
 
448
        WebKitDownload *download;
 
449
        char *destination, *destination_uri, *tmp_filename;
 
450
 
 
451
        request = webkit_network_request_new (data->icon_href);
 
452
        download = webkit_download_new (request);
 
453
        g_object_unref (request);
 
454
 
 
455
        tmp_filename = ephy_file_tmp_filename ("ephy-download-XXXXXX", NULL);
 
456
        destination = g_build_filename (ephy_file_tmp_dir (), tmp_filename, NULL);
 
457
        destination_uri = g_filename_to_uri (destination, NULL, NULL);
 
458
        webkit_download_set_destination_uri (download, destination_uri);
 
459
        g_free (destination);
 
460
        g_free (destination_uri);
 
461
        g_free (tmp_filename);
 
462
 
 
463
        g_signal_connect (download, "notify::status",
 
464
                          G_CALLBACK (download_status_changed_cb), data);
 
465
 
 
466
        webkit_download_start (download);       
 
467
}
 
468
 
 
469
static void
 
470
fill_default_application_image (EphyApplicationDialogData *data)
 
471
{
 
472
        WebKitDOMDocument *document;
 
473
        WebKitDOMNodeList *links;
 
474
        gulong length, i;
 
475
 
 
476
        document = webkit_web_view_get_dom_document (WEBKIT_WEB_VIEW (data->view));
 
477
        links = webkit_dom_document_get_elements_by_tag_name (document, "link");
 
478
        length = webkit_dom_node_list_get_length (links);
 
479
 
 
480
        for (i = 0; i < length; i++)
 
481
        {
 
482
                char *rel;
 
483
                WebKitDOMNode *node = webkit_dom_node_list_item (links, i);
 
484
                rel = webkit_dom_html_link_element_get_rel (WEBKIT_DOM_HTML_LINK_ELEMENT (node));
 
485
                /* TODO: support more than one possible icon. */
 
486
                if (g_strcmp0 (rel, "apple-touch-icon") == 0 ||
 
487
                    g_strcmp0 (rel, "apple-touch-icon-precomposed") == 0)
 
488
                {
 
489
                        data->icon_href = webkit_dom_html_link_element_get_href (WEBKIT_DOM_HTML_LINK_ELEMENT (node));
 
490
                        download_icon_and_set_image (data);
 
491
                        g_free (rel);
 
492
                        return;
 
493
                }
 
494
        }
 
495
 
 
496
        /* If we make it here, no "apple-touch-icon" link was
 
497
         * found. Take a snapshot of the page. */
 
498
        take_page_snapshot_and_set_image (data);
 
499
}
 
500
 
 
501
static void
 
502
fill_default_application_title (EphyApplicationDialogData *data)
 
503
{
 
504
        const char *title = ephy_web_view_get_title (data->view);
 
505
        gtk_entry_set_text (GTK_ENTRY (data->entry), title);
 
506
}
 
507
 
 
508
static void
 
509
notify_launch_cb (NotifyNotification *notification,
 
510
                  char *action,
 
511
                  gpointer user_data)
 
512
{
 
513
        char * desktop_file = user_data;
 
514
        /* A gross hack to be able to launch epiphany from within
 
515
         * Epiphany. Might be a good idea to figure out a better
 
516
         * solution... */
 
517
        g_unsetenv (EPHY_UUID_ENVVAR);
 
518
        ephy_file_launch_desktop_file (desktop_file, NULL, 0, NULL);
 
519
        g_free (desktop_file);
 
520
}
 
521
 
 
522
static gboolean
 
523
confirm_web_application_overwrite (GtkWindow *parent, const char *title)
 
524
{
 
525
  GtkResponseType response;
 
526
  GtkWidget *dialog;
 
527
 
 
528
  dialog = gtk_message_dialog_new (parent, 0,
 
529
                                   GTK_MESSAGE_QUESTION,
 
530
                                   GTK_BUTTONS_NONE,
 
531
                                   _("A web application named '%s' already exists. Do you want to replace it?"),
 
532
                                   title);
 
533
  gtk_dialog_add_buttons (GTK_DIALOG (dialog),
 
534
                          _("Cancel"),
 
535
                          GTK_RESPONSE_CANCEL,
 
536
                          _("Replace"),
 
537
                          GTK_RESPONSE_OK,
 
538
                          NULL);
 
539
  gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
 
540
                                            _("An application with the same name already exists. Replacing it will "
 
541
                                              "overwrite it."));
 
542
  gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_CANCEL);
 
543
  response = gtk_dialog_run (GTK_DIALOG (dialog));
 
544
 
 
545
  gtk_widget_destroy (dialog);
 
546
 
 
547
  return response == GTK_RESPONSE_OK;
 
548
}
 
549
 
 
550
static void
 
551
dialog_save_as_application_response_cb (GtkDialog *dialog,
 
552
                                        gint response,
 
553
                                        EphyApplicationDialogData *data)
 
554
{
 
555
        char *profile_dir;
 
556
        char *desktop_file;
 
557
        char *message;
 
558
        NotifyNotification *notification;
 
559
        gboolean profile_exists;
 
560
 
 
561
        if (response == GTK_RESPONSE_OK) {
 
562
                profile_dir = ephy_web_application_get_profile_directory (gtk_entry_get_text (GTK_ENTRY (data->entry)));
 
563
                profile_exists = g_file_test (profile_dir, G_FILE_TEST_IS_DIR);
 
564
                g_free (profile_dir);
 
565
 
 
566
                if (profile_exists)
 
567
                {
 
568
                        if (confirm_web_application_overwrite (GTK_WINDOW (dialog),
 
569
                                                               gtk_entry_get_text (GTK_ENTRY (data->entry))))
 
570
                                ephy_web_application_delete (gtk_entry_get_text (GTK_ENTRY (data->entry)));
 
571
                        else
 
572
                                return;
 
573
                }
 
574
 
 
575
                /* Create Web Application, including a new profile and .desktop file. */
 
576
                desktop_file = ephy_web_application_create (data->view,
 
577
                                                            gtk_entry_get_text (GTK_ENTRY (data->entry)),
 
578
                                                            gtk_image_get_pixbuf (GTK_IMAGE (data->image)));
 
579
                if (desktop_file)
 
580
                        message = g_strdup_printf (_("The application '%s' is ready to be used"),
 
581
                                                   gtk_entry_get_text (GTK_ENTRY (data->entry)));
 
582
                else
 
583
                        message = g_strdup_printf (_("The application '%s' could not be created"),
 
584
                                                   gtk_entry_get_text (GTK_ENTRY (data->entry)));
 
585
 
 
586
                notification = notify_notification_new (message,
 
587
                                                        NULL, NULL);
 
588
                g_free (message);
 
589
 
 
590
                if (desktop_file) {
 
591
                        notify_notification_add_action (notification, "launch", _("Launch"),
 
592
                                                        (NotifyActionCallback)notify_launch_cb,
 
593
                                                        g_path_get_basename (desktop_file),
 
594
                                                        NULL);
 
595
                        notify_notification_set_icon_from_pixbuf (notification, gtk_image_get_pixbuf (GTK_IMAGE (data->image)));
 
596
                        g_free (desktop_file);
 
597
                }
 
598
 
 
599
                notify_notification_set_timeout (notification, NOTIFY_EXPIRES_DEFAULT);
 
600
                notify_notification_set_urgency (notification, NOTIFY_URGENCY_LOW);
 
601
                notify_notification_set_hint (notification, "transient", g_variant_new_boolean (TRUE));
 
602
                notify_notification_show (notification, NULL);
 
603
        }
 
604
 
 
605
        ephy_application_dialog_data_free (data);
 
606
        gtk_widget_destroy (GTK_WIDGET (dialog));
 
607
}
 
608
 
 
609
void
 
610
window_cmd_file_save_as_application (GtkAction *action,
 
611
                                     EphyWindow *window)
 
612
{
 
613
        EphyEmbed *embed;
 
614
        GtkWidget *dialog, *box, *image, *entry, *content_area;
 
615
        EphyWebView *view;
 
616
        EphyApplicationDialogData *data;
 
617
 
 
618
        embed = ephy_embed_container_get_active_child (EPHY_EMBED_CONTAINER (window));
 
619
        g_return_if_fail (embed != NULL);
 
620
 
 
621
        view = EPHY_WEB_VIEW (EPHY_GET_WEBKIT_WEB_VIEW_FROM_EMBED (embed));
 
622
 
 
623
        /* Show dialog with icon, title. */
 
624
        dialog = gtk_dialog_new_with_buttons (_("Create Web Application"),
 
625
                                              GTK_WINDOW (window),
 
626
                                              0,
 
627
                                              GTK_STOCK_CANCEL,
 
628
                                              GTK_RESPONSE_CANCEL,
 
629
                                              _("Create"),
 
630
                                              GTK_RESPONSE_OK,
 
631
                                              NULL);
 
632
 
 
633
        content_area = gtk_dialog_get_content_area (GTK_DIALOG (dialog));
 
634
        gtk_container_set_border_width (GTK_CONTAINER (dialog), 5);
 
635
        gtk_box_set_spacing (GTK_BOX (content_area), 14); /* 14 + 2 * 5 = 24 */
 
636
 
 
637
        box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 5);
 
638
        gtk_container_add (GTK_CONTAINER (content_area), box);
 
639
 
 
640
        image = gtk_image_new ();
 
641
        gtk_widget_set_size_request (image, 128, 128);
 
642
        gtk_container_add (GTK_CONTAINER (box), image);
 
643
 
 
644
        entry = gtk_entry_new ();
 
645
        gtk_entry_set_activates_default (GTK_ENTRY (entry), TRUE);
 
646
        gtk_box_pack_end (GTK_BOX (box), entry, FALSE, FALSE, 0);
 
647
 
 
648
        data = g_slice_new0 (EphyApplicationDialogData);
 
649
        data->view = view;
 
650
        data->image = image;
 
651
        data->entry = entry;
 
652
 
 
653
        fill_default_application_image (data);
 
654
        fill_default_application_title (data);
 
655
 
 
656
        gtk_widget_show_all (dialog);
 
657
 
 
658
        gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
 
659
        g_signal_connect (dialog, "response",
 
660
                          G_CALLBACK (dialog_save_as_application_response_cb),
 
661
                          data);
 
662
        gtk_widget_show_all (dialog);
 
663
}
 
664
 
377
665
void
378
666
window_cmd_file_work_offline (GtkAction *action,
379
667
                              EphyWindow *window)
647
935
}
648
936
 
649
937
static void
 
938
view_source_embedded (const char *uri, EphyEmbed *embed)
 
939
{
 
940
        EphyEmbed *new_embed;
 
941
 
 
942
        new_embed = ephy_shell_new_tab
 
943
                        (ephy_shell_get_default (),
 
944
                         EPHY_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (embed))),
 
945
                         embed,
 
946
                         NULL,
 
947
                         EPHY_NEW_TAB_JUMP | EPHY_NEW_TAB_IN_EXISTING_WINDOW | EPHY_NEW_TAB_APPEND_AFTER);
 
948
 
 
949
        webkit_web_view_set_view_source_mode
 
950
                (EPHY_GET_WEBKIT_WEB_VIEW_FROM_EMBED (new_embed), TRUE);
 
951
        webkit_web_view_load_uri
 
952
                (EPHY_GET_WEBKIT_WEB_VIEW_FROM_EMBED (new_embed), uri);
 
953
}
 
954
 
 
955
 
 
956
static void
650
957
save_temp_source_close_cb (GOutputStream *ostream, GAsyncResult *result, gpointer data)
651
958
{
652
959
        char *uri;
664
971
        uri = (char*)g_object_get_data (G_OBJECT (ostream), "ephy-save-temp-source-uri");
665
972
 
666
973
        file = g_file_new_for_uri (uri);
 
974
 
667
975
        if (!ephy_file_launch_handler ("text/plain", file, gtk_get_current_event_time ()))
668
976
        {
669
977
                /* Fallback to view the source inside the browser */
670
978
                const char *uri;
671
 
                EphyEmbed *embed, *new_embed;
 
979
                EphyEmbed *embed;
672
980
 
673
981
                uri = (const char*) g_object_get_data (G_OBJECT (ostream),
674
982
                                                       "ephy-original-source-uri");
675
983
                embed = (EphyEmbed*)g_object_get_data (G_OBJECT (ostream),
676
984
                                                       "ephy-save-temp-source-embed");
677
 
 
678
 
                new_embed = ephy_shell_new_tab (ephy_shell_get_default (),
679
 
                                                EPHY_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (embed))),
680
 
                                                embed,
681
 
                                                NULL,
682
 
                                                EPHY_NEW_TAB_JUMP | EPHY_NEW_TAB_IN_EXISTING_WINDOW);
683
 
 
684
 
                webkit_web_view_set_view_source_mode (EPHY_GET_WEBKIT_WEB_VIEW_FROM_EMBED (new_embed),
685
 
                                                      TRUE);
686
 
                webkit_web_view_load_uri (EPHY_GET_WEBKIT_WEB_VIEW_FROM_EMBED (new_embed),
687
 
                                          uri);
 
985
                view_source_embedded (uri, embed);
688
986
        }
689
 
 
690
987
        g_object_unref (ostream);
 
988
 
691
989
        g_object_unref (file);
692
990
}
693
991
 
832
1130
        g_return_if_fail (embed != NULL);
833
1131
 
834
1132
        address = ephy_web_view_get_address (ephy_embed_get_web_view (embed));
 
1133
 
 
1134
        if (g_settings_get_boolean (EPHY_SETTINGS_MAIN,
 
1135
                                    EPHY_PREFS_INTERNAL_VIEW_SOURCE))
 
1136
        {
 
1137
                view_source_embedded (address, embed);
 
1138
                return;
 
1139
        }
 
1140
 
835
1141
        user_time = gtk_get_current_event_time ();
836
1142
 
837
1143
        if (g_str_has_prefix (address, "file://"))