~ubuntu-branches/ubuntu/oneiric/midori/oneiric-updates

« back to all changes in this revision

Viewing changes to midori/midori-browser.c

  • Committer: Bazaar Package Importer
  • Author(s): Micah Gersten
  • Date: 2011-05-18 21:07:34 UTC
  • mfrom: (1.1.16 upstream) (3.3.9 sid)
  • Revision ID: james.westby@ubuntu.com-20110518210734-232wzq1tc88gtz2p
Tags: 0.3.6-1ubuntu1
* Merge from debian unstable. (LP: #784944) Remaining changes:
  - debian/control:
    + Change build-depends from libwebkit-dev to libwebkitgtk-dev
  - debian/rules:
    + Change package query from libwebkit-dev to libwebkitgtk-dev

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
 
 Copyright (C) 2007-2010 Christian Dywan <christian@twotoasts.de>
 
2
 Copyright (C) 2007-2011 Christian Dywan <christian@twotoasts.de>
3
3
 Copyright (C) 2008 Dale Whittaker <dayul@users.sf.net>
4
4
 Copyright (C) 2009 Jérôme Geulfucci <jeromeg@xfce.org>
5
5
 
94
94
    KatzeArray* trash;
95
95
    KatzeArray* search_engines;
96
96
    KatzeArray* history;
 
97
    GKeyFile* speeddial;
97
98
    gboolean show_tabs;
98
99
 
99
100
    gboolean show_navigationbar;
100
101
    gboolean show_statusbar;
101
 
    gboolean speed_dial_in_new_tabs;
102
102
    guint maximum_history_age;
103
103
    gchar* location_entry_search;
 
104
    guint last_web_search;
104
105
    gchar* news_aggregator;
105
106
};
106
107
 
128
129
    PROP_TRASH,
129
130
    PROP_SEARCH_ENGINES,
130
131
    PROP_HISTORY,
 
132
    PROP_SPEED_DIAL,
131
133
    PROP_SHOW_TABS,
132
134
};
133
135
 
136
138
    NEW_WINDOW,
137
139
    ADD_TAB,
138
140
    REMOVE_TAB,
 
141
    MOVE_TAB,
139
142
    ACTIVATE_ACTION,
140
143
    CONTEXT_READY,
141
144
    ADD_DOWNLOAD,
142
145
    SEND_NOTIFICATION,
143
146
    POPULATE_TOOL_MENU,
 
147
    POPULATE_TOOLBAR_MENU,
144
148
    QUIT,
 
149
    SHOW_PREFERENCES,
145
150
 
146
151
    LAST_SIGNAL
147
152
};
211
216
midori_browser_set_bookmarks (MidoriBrowser* browser,
212
217
                              KatzeArray*    bookmarks);
213
218
 
214
 
GdkPixbuf*
215
 
midori_search_action_get_icon (KatzeItem*    item,
216
 
                               GtkWidget*    widget,
217
 
                               const gchar** icon_name);
218
 
 
219
219
static void
220
220
midori_browser_add_speed_dial (MidoriBrowser* browser);
221
221
 
222
222
gboolean
223
223
midori_transferbar_confirm_delete (MidoriTransferbar* transferbar);
224
224
 
 
225
static void
 
226
_midori_browser_update_notebook (MidoriBrowser* browser);
 
227
 
225
228
#if WEBKIT_CHECK_VERSION (1, 1, 3)
226
229
void
227
230
midori_transferbar_add_download_item (MidoriTransferbar* transferbar,
242
245
_toggle_tabbar_smartly (MidoriBrowser* browser)
243
246
{
244
247
    guint n;
245
 
    gboolean always_show_tabbar;
246
248
 
247
249
    if (!browser->show_tabs)
248
250
        return;
250
252
    n = gtk_notebook_get_n_pages (GTK_NOTEBOOK (browser->notebook));
251
253
    if (n < 2)
252
254
    {
253
 
        g_object_get (browser->settings, "always-show-tabbar",
254
 
            &always_show_tabbar, NULL);
255
 
        if (always_show_tabbar)
 
255
        if (katze_object_get_boolean (browser->settings, "always-show-tabbar"))
256
256
            n++;
257
257
    }
258
258
    gtk_notebook_set_show_tabs (GTK_NOTEBOOK (browser->notebook), n > 1);
297
297
        midori_view_get_next_page (view) != NULL);
298
298
 
299
299
    gtk_action_set_visible (_action_by_name (browser, "AddSpeedDial"),
300
 
        browser->speed_dial_in_new_tabs && !midori_view_is_blank (view));
 
300
        !midori_view_is_blank (view));
301
301
    /* Currently views that don't support source, don't support
302
302
       saving either. If that changes, we need to think of something. */
303
303
    _action_set_sensitive (browser, "SaveAs", midori_view_can_view_source (view));
330
330
                      "sensitive", can_reload, NULL);
331
331
        if (!browser->show_navigationbar)
332
332
            gtk_widget_hide (browser->navigationbar);
 
333
 
 
334
        katze_item_set_meta_integer (midori_view_get_proxy_item (view), "dont-write-history", 0);
333
335
    }
334
336
    else
335
337
    {
371
373
                                    const gchar*   text)
372
374
{
373
375
    GtkWidget* widget = gtk_window_get_focus (GTK_WINDOW (browser));
374
 
    gboolean is_location = widget ?
375
 
        GTK_IS_COMBO_BOX (gtk_widget_get_parent (widget)) : FALSE;
 
376
    gboolean is_location = widget && GTK_IS_ENTRY (widget)
 
377
        && GTK_IS_ALIGNMENT (gtk_widget_get_parent (widget));
376
378
 
377
379
    katze_assign (browser->statusbar_text, sokoke_format_uri_for_display (text));
378
380
 
433
435
    /* When we are finished, we don't want to *see* progress anymore */
434
436
    if (midori_view_get_load_status (view) == MIDORI_LOAD_FINISHED)
435
437
        progress = 0.0;
 
438
    /* When loading we want to see at minimum 10% progress */
 
439
    else
 
440
        progress = CLAMP (progress, 0.1, 1.0);
436
441
    midori_location_action_set_progress (action, progress);
437
442
}
438
443
 
552
557
}
553
558
 
554
559
static void
555
 
midori_view_notify_uri_cb (GtkWidget*     view,
 
560
midori_view_notify_uri_cb (GtkWidget*     widget,
556
561
                           GParamSpec*    pspec,
557
562
                           MidoriBrowser* browser)
558
563
{
559
 
    if (view == midori_browser_get_current_tab (browser))
 
564
    if (widget == midori_browser_get_current_tab (browser))
560
565
    {
561
 
        const gchar* uri = midori_view_get_display_uri (MIDORI_VIEW (view));
 
566
        MidoriView* view = MIDORI_VIEW (widget);
 
567
        const gchar* uri = midori_view_get_display_uri (view);
562
568
        GtkAction* action = _action_by_name (browser, "Location");
563
569
        midori_location_action_set_text (MIDORI_LOCATION_ACTION (action), uri);
564
 
    }
 
570
        _action_set_sensitive (browser, "Back", midori_view_can_go_back (view));
 
571
        _action_set_sensitive (browser, "Forward", midori_view_can_go_forward (view));
 
572
    }
 
573
}
 
574
 
 
575
static void
 
576
midori_browser_set_title (MidoriBrowser* browser,
 
577
                          const gchar*   title)
 
578
{
 
579
    #if WEBKIT_CHECK_VERSION (1, 1, 2)
 
580
    if (katze_object_get_boolean (browser->settings, "enable-private-browsing"))
 
581
    {
 
582
        gchar* window_title = g_strconcat (title, " - ",
 
583
                                           g_get_application_name (), NULL);
 
584
        gtk_window_set_title (GTK_WINDOW (browser), window_title);
 
585
        g_free (window_title);
 
586
    }
 
587
    else
 
588
    #endif
 
589
        gtk_window_set_title (GTK_WINDOW (browser), title);
565
590
}
566
591
 
567
592
static void
570
595
                             MidoriBrowser* browser)
571
596
{
572
597
    MidoriView* view = MIDORI_VIEW (widget);
573
 
    const gchar* uri;
574
598
    const gchar* title;
575
 
    gchar* window_title;
576
599
 
577
 
    uri = midori_view_get_display_uri (view);
578
600
    title = midori_view_get_display_title (view);
579
601
 
580
602
    if (midori_view_get_load_status (view) == MIDORI_LOAD_COMMITTED)
589
611
                !g_str_has_prefix (proxy_uri, "about:") &&
590
612
                (katze_item_get_meta_integer (proxy, "history-step") == -1))
591
613
            {
592
 
                midori_browser_new_history_item (browser, proxy);
593
 
                katze_item_set_meta_integer (proxy, "history-step", 1);
 
614
                if (!katze_item_get_meta_boolean (proxy, "dont-write-history"))
 
615
                {
 
616
                    midori_browser_new_history_item (browser, proxy);
 
617
                    katze_item_set_meta_integer (proxy, "history-step", 1);
 
618
                }
594
619
            }
595
620
            else if (katze_item_get_name (proxy) &&
596
621
                     !g_str_has_prefix (proxy_uri, "about:") &&
603
628
    }
604
629
 
605
630
    if (widget == midori_browser_get_current_tab (browser))
 
631
        midori_browser_set_title (browser, title);
 
632
}
 
633
 
 
634
static void
 
635
midori_view_notify_minimized_cb (GtkWidget*     widget,
 
636
                                 GParamSpec*    pspec,
 
637
                                 MidoriBrowser* browser)
 
638
{
 
639
    if (katze_object_get_boolean (widget, "minimized"))
606
640
    {
607
 
        window_title = g_strconcat (title, " - ",
608
 
            g_get_application_name (), NULL);
609
 
        gtk_window_set_title (GTK_WINDOW (browser), window_title);
610
 
        g_free (window_title);
 
641
        GtkNotebook* notebook = GTK_NOTEBOOK (browser->notebook);
 
642
        GtkWidget* label = gtk_notebook_get_tab_label (notebook, widget);
 
643
        gtk_widget_set_size_request (label, -1, -1);
611
644
    }
 
645
    else
 
646
        _midori_browser_update_notebook (browser);
612
647
}
613
648
 
614
649
static void
637
672
}
638
673
 
639
674
static void
640
 
midori_browser_edit_bookmark_uri_changed_cb (GtkEntry*      entry,
641
 
                                             GtkDialog*     dialog)
642
 
{
643
 
    const gchar* uri = gtk_entry_get_text (entry);
644
 
    gtk_dialog_set_response_sensitive (dialog, GTK_RESPONSE_ACCEPT,
645
 
        uri && (g_str_has_prefix (uri, "http://")
646
 
        || g_str_has_prefix (uri, "https://")
647
 
        || g_str_has_prefix (uri, "file://")
648
 
        || g_str_has_prefix (uri, "data:")
649
 
        || g_str_has_prefix (uri, "javascript:")));
650
 
}
651
 
 
652
 
static void
653
675
midori_browser_edit_bookmark_title_changed_cb (GtkEntry*      entry,
654
676
                                               GtkDialog*     dialog)
655
677
{
769
791
        label = gtk_label_new_with_mnemonic (_("_Address:"));
770
792
        gtk_size_group_add_widget (sizegroup, label);
771
793
        gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
772
 
        entry_uri = gtk_entry_new ();
 
794
        entry_uri = katze_uri_entry_new (
 
795
        #if GTK_CHECK_VERSION (2, 20, 0)
 
796
            gtk_dialog_get_widget_for_response (GTK_DIALOG (dialog), GTK_RESPONSE_ACCEPT));
 
797
        #else
 
798
            NULL);
 
799
        #endif
773
800
        #if HAVE_HILDON
774
801
        HildonGtkInputMode mode = hildon_gtk_entry_get_input_mode (GTK_ENTRY (entry_uri));
775
802
        mode &= ~HILDON_GTK_INPUT_MODE_AUTOCAP;
777
804
        #endif
778
805
        gtk_entry_set_activates_default (GTK_ENTRY (entry_uri), TRUE);
779
806
        gtk_entry_set_text (GTK_ENTRY (entry_uri), katze_item_get_uri (bookmark));
780
 
        midori_browser_edit_bookmark_uri_changed_cb (GTK_ENTRY (entry_uri),
781
 
                                                     GTK_DIALOG (dialog));
782
 
        g_signal_connect (entry_uri, "changed",
783
 
            G_CALLBACK (midori_browser_edit_bookmark_uri_changed_cb), dialog);
784
807
        gtk_box_pack_start (GTK_BOX (hbox), entry_uri, TRUE, TRUE, 0);
785
808
        gtk_container_add (GTK_CONTAINER (content_area), hbox);
786
809
        gtk_widget_show_all (hbox);
791
814
    {
792
815
        GtkListStore* model;
793
816
        GtkCellRenderer* renderer;
794
 
        guint i, n;
 
817
        guint n;
795
818
        sqlite3_stmt* statement;
796
819
        gint result;
797
820
        const gchar* sqlcmd;
811
834
            0, _("Toplevel folder"), 1, PANGO_ELLIPSIZE_END, -1);
812
835
        gtk_combo_box_set_active (GTK_COMBO_BOX (combo_folder), 0);
813
836
 
814
 
        i = 0;
815
837
        n = 1;
816
838
        sqlcmd = "SELECT title from bookmarks where uri=''";
817
839
        result = sqlite3_prepare_v2 (db, sqlcmd, -1, &statement, NULL);
972
994
    }
973
995
 
974
996
    webkit_download_set_destination_uri (download, uri);
 
997
    g_signal_emit (browser, signals[ADD_DOWNLOAD], 0, download);
975
998
    midori_transferbar_add_download_item (MIDORI_TRANSFERBAR (browser->transferbar), download);
976
999
    return TRUE;
977
1000
}
1096
1119
}
1097
1120
 
1098
1121
static gchar*
1099
 
midori_browser_speed_dial_get_next_free_slot (void)
 
1122
midori_browser_speed_dial_get_next_free_slot (MidoriView* view)
1100
1123
{
1101
 
    GRegex* regex;
1102
 
    GMatchInfo* match_info;
1103
 
    gchar* speed_dial_body;
1104
 
    gchar* body_fname;
1105
 
    gchar* slot_id = NULL;
1106
 
 
1107
 
    body_fname = g_build_filename (sokoke_set_config_dir (NULL),
1108
 
                                   "speeddial.json", NULL);
1109
 
 
1110
 
    if (g_access (body_fname, F_OK) != 0)
 
1124
    MidoriBrowser* browser = midori_browser_get_for_widget (GTK_WIDGET (view));
 
1125
    GKeyFile* key_file;
 
1126
    guint cols, rows, slot = 1;
 
1127
 
 
1128
    g_object_get (browser, "speed-dial", &key_file, NULL);
 
1129
    rows = g_key_file_get_integer (key_file, "settings", "rows", NULL);
 
1130
    cols = g_key_file_get_integer (key_file, "settings", "columns", NULL);
 
1131
    while (slot <= cols * rows)
1111
1132
    {
1112
 
        gchar* filename = g_build_filename ("midori", "res", "speeddial.json", NULL);
1113
 
        gchar* filepath = sokoke_find_data_filename (filename);
1114
 
        g_free (filename);
1115
 
        if (g_file_get_contents (filepath, &speed_dial_body, NULL, NULL))
 
1133
        gchar* dial_id = g_strdup_printf ("Dial %d", slot);
 
1134
        if (!g_key_file_has_group (key_file, dial_id))
1116
1135
        {
1117
 
            g_file_set_contents (body_fname, speed_dial_body, -1, NULL);
1118
 
 
1119
 
            g_free (speed_dial_body);
 
1136
            g_free (dial_id);
 
1137
            return g_strdup_printf ("s%d", slot);
1120
1138
        }
1121
 
        g_free (filepath);
1122
 
        g_free (body_fname);
1123
 
        return g_strdup ("s1");
1124
 
    }
1125
 
    else
1126
 
        g_file_get_contents (body_fname, &speed_dial_body, NULL, NULL);
1127
 
 
1128
 
    regex = g_regex_new ("\"id\":\"(s[0-9]{1,2})\",\"href\":\"#\"",
1129
 
                         G_REGEX_MULTILINE, 0, NULL);
1130
 
 
1131
 
    if (g_regex_match (regex, speed_dial_body, 0, &match_info))
1132
 
    {
1133
 
        slot_id = g_match_info_fetch (match_info, 1);
1134
 
        g_match_info_free (match_info);
1135
 
    }
1136
 
 
1137
 
    if (!g_strcmp0 (slot_id, ""))
1138
 
        g_free (slot_id);
1139
 
 
1140
 
    g_free (body_fname);
1141
 
    g_free (speed_dial_body);
1142
 
    g_free (regex);
1143
 
 
1144
 
    return slot_id;
 
1139
        g_free (dial_id);
 
1140
        slot++;
 
1141
    }
 
1142
    return NULL;
1145
1143
}
1146
1144
 
1147
1145
static void
1148
1146
midori_browser_add_speed_dial (MidoriBrowser* browser)
1149
1147
{
1150
1148
    GdkPixbuf* img;
1151
 
    gchar* replace_from;
1152
 
    gchar* replace_by;
1153
 
    gsize len;
1154
 
 
1155
1149
    GtkWidget* view = midori_browser_get_current_tab (browser);
1156
 
 
1157
1150
    gchar* uri = g_strdup (midori_view_get_display_uri (MIDORI_VIEW (view)));
1158
1151
    gchar* title = g_strdup (midori_view_get_display_title (MIDORI_VIEW (view)));
1159
 
    gchar* slot_id = midori_browser_speed_dial_get_next_free_slot ();
1160
 
 
1161
 
    GRegex* reg_quotes = g_regex_new ("'", 0, 0, NULL);
1162
 
    GRegex* reg_others = g_regex_new ("[\\\"\\\\]", 0, 0, NULL);
1163
 
    gchar* temp_title = g_regex_replace_literal (reg_others, title,
1164
 
                                                 -1, 0, " ", 0, NULL);
1165
 
    g_free (title);
1166
 
    title = g_regex_replace_literal (reg_quotes, temp_title, -1, 0,
1167
 
                                     "\\\\'", 0, NULL);
1168
 
 
1169
 
    g_free (temp_title);
1170
 
    g_regex_unref (reg_quotes);
1171
 
    g_regex_unref (reg_others);
 
1152
    gchar* slot_id = midori_browser_speed_dial_get_next_free_slot (MIDORI_VIEW (view));
1172
1153
 
1173
1154
    if (slot_id == NULL)
1174
1155
    {
1177
1158
        return;
1178
1159
    }
1179
1160
 
1180
 
    if ((len = g_utf8_strlen (title, -1)) > 15)
1181
 
    {
1182
 
        /**
1183
 
          * The case when a quote was escaped with a backslash and the
1184
 
          * backslash becomes the last character of the ellipsized string.
1185
 
          * This causes JSON parsing to fail.
1186
 
          * For example: "My Foo Bar \'b\..."
1187
 
          **/
1188
 
        GRegex* reg_unsafe = g_regex_new ("([\\\\]+\\.)", 0, 0, NULL);
1189
 
 
1190
 
        gchar* temp;
1191
 
        gchar* ellipsized = g_malloc0 ( len + 1);
1192
 
 
1193
 
        g_utf8_strncpy (ellipsized, title, 15);
1194
 
        g_free (title);
1195
 
 
1196
 
        temp = g_strdup_printf ("%s...", ellipsized);
1197
 
        g_free  (ellipsized);
1198
 
 
1199
 
        title = g_regex_replace_literal (reg_unsafe, temp, -1, 0, ".", 0, NULL);
1200
 
        g_free (temp);
1201
 
 
1202
 
        g_regex_unref (reg_unsafe);
1203
 
    }
1204
 
 
1205
1161
    if ((img = midori_view_get_snapshot (MIDORI_VIEW (view), 240, 160)))
1206
1162
    {
1207
 
        GRegex* regex;
1208
 
        gchar* replace;
1209
 
        gchar* file_content;
1210
 
        gchar* encoded;
1211
 
        gchar* speed_dial_body;
1212
 
        gchar* body_fname;
1213
 
        gsize sz;
1214
 
 
1215
 
        body_fname = g_build_filename (sokoke_set_config_dir (NULL),
1216
 
                                       "speeddial.json", NULL);
1217
 
 
1218
 
        if (g_file_get_contents (body_fname, &speed_dial_body, NULL, NULL))
1219
 
        {
1220
 
            gint i;
1221
 
 
1222
 
            gdk_pixbuf_save_to_buffer (img, &file_content, &sz, "png", NULL, NULL);
1223
 
            encoded = g_base64_encode ((guchar *)file_content, sz);
1224
 
 
1225
 
            replace_from = g_strdup_printf (
1226
 
                "\\{\"id\":\"%s\",\"href\":\"#\",\"title\":\"\",\"img\":\"\"\\}",
1227
 
                slot_id);
1228
 
            replace_by = g_strdup_printf (
1229
 
                "{\"id\":\"%s\",\"href\":\"%s\",\"title\":\"%s\",\"img\":\"%s\"}",
1230
 
                slot_id, uri, title, encoded);
1231
 
 
1232
 
            regex = g_regex_new (replace_from, G_REGEX_MULTILINE, 0, NULL);
1233
 
            replace = g_regex_replace (regex, speed_dial_body, -1,
1234
 
                                       1, replace_by, 0, NULL);
1235
 
 
1236
 
            g_file_set_contents (body_fname, replace, -1, NULL);
1237
 
 
1238
 
            i = 0;
1239
 
            while ((view = gtk_notebook_get_nth_page (GTK_NOTEBOOK (
1240
 
                                                      browser->notebook), i++)))
1241
 
                if (midori_view_is_blank (MIDORI_VIEW (view)))
1242
 
                    midori_view_reload (MIDORI_VIEW (view), FALSE);
1243
 
 
1244
 
            g_object_unref (img);
1245
 
            g_regex_unref (regex);
1246
 
            g_free (encoded);
1247
 
            g_free (file_content);
1248
 
            g_free (speed_dial_body);
1249
 
            g_free (replace_from);
1250
 
            g_free (replace_by);
1251
 
            g_free (replace);
1252
 
        }
1253
 
        g_free (body_fname);
 
1163
        gint i;
 
1164
        GKeyFile* key_file;
 
1165
        gchar* dial_id = g_strdup_printf ("Dial %s", slot_id + 1);
 
1166
        gchar* config_file = g_build_filename (sokoke_set_config_dir (NULL),
 
1167
                                               "speeddial", NULL);
 
1168
        gchar* file_path = sokoke_build_thumbnail_path (uri);
 
1169
        gchar* thumb_dir = g_build_path (G_DIR_SEPARATOR_S, g_get_user_cache_dir (),
 
1170
                                         PACKAGE_NAME, "thumbnails", NULL);
 
1171
        g_object_get (browser, "speed-dial", &key_file, NULL);
 
1172
 
 
1173
        g_key_file_set_string (key_file, dial_id, "uri", uri);
 
1174
        g_key_file_set_string (key_file, dial_id, "title", title);
 
1175
 
 
1176
        if (!g_file_test (thumb_dir, G_FILE_TEST_EXISTS))
 
1177
            katze_mkdir_with_parents (thumb_dir, 0700);
 
1178
 
 
1179
        gdk_pixbuf_save (img, file_path, "png", NULL, "compression", "7", NULL);
 
1180
        sokoke_key_file_save_to_file (key_file, config_file, NULL);
 
1181
 
 
1182
        i = 0;
 
1183
        while ((view = gtk_notebook_get_nth_page (GTK_NOTEBOOK (
 
1184
                                                  browser->notebook), i++)))
 
1185
            if (midori_view_is_blank (MIDORI_VIEW (view)))
 
1186
                midori_view_reload (MIDORI_VIEW (view), FALSE);
 
1187
 
 
1188
 
 
1189
        g_object_unref (img);
 
1190
        g_free (file_path);
 
1191
        g_free (thumb_dir);
 
1192
        g_free (config_file);
 
1193
        g_free (dial_id);
1254
1194
    }
1255
1195
    g_free (uri);
 
1196
    g_free (title);
1256
1197
    g_free (slot_id);
1257
1198
}
1258
1199
 
1305
1246
}
1306
1247
 
1307
1248
static void
 
1249
midori_view_detach_inspector_cb (GtkWidget*     view,
 
1250
                                 GtkWidget*     inspector_view,
 
1251
                                 MidoriBrowser* browser)
 
1252
{
 
1253
    GtkWidget* scrolled = gtk_widget_get_parent (GTK_WIDGET (inspector_view));
 
1254
    GtkWidget* paned = gtk_widget_get_parent (scrolled);
 
1255
    browser->inspector_view = gtk_viewport_new (NULL, NULL);
 
1256
    gtk_container_remove (GTK_CONTAINER (scrolled), GTK_WIDGET (inspector_view));
 
1257
    gtk_container_add (GTK_CONTAINER (scrolled), browser->inspector_view);
 
1258
    gtk_widget_hide (paned);
 
1259
}
 
1260
 
 
1261
static void
1308
1262
midori_browser_view_copy_history (GtkWidget* view_to,
1309
1263
                                  GtkWidget* view_from,
1310
1264
                                  gboolean   omit_last)
1362
1316
midori_view_new_view_cb (GtkWidget*     view,
1363
1317
                         GtkWidget*     new_view,
1364
1318
                         MidoriNewView  where,
 
1319
                         gboolean       user_initiated,
1365
1320
                         MidoriBrowser* browser)
1366
1321
{
1367
1322
    midori_browser_view_copy_history (new_view, view, TRUE);
1378
1333
        if (where != MIDORI_NEW_VIEW_BACKGROUND)
1379
1334
            midori_browser_set_current_page (browser, n);
1380
1335
    }
 
1336
 
 
1337
    if (!user_initiated)
 
1338
    {
 
1339
        GdkWindow* window = gtk_widget_get_window (GTK_WIDGET (browser));
 
1340
        GdkWindowState state = gdk_window_get_state (window);
 
1341
        if ((state | GDK_WINDOW_STATE_MAXIMIZED)
 
1342
         || (state | GDK_WINDOW_STATE_FULLSCREEN))
 
1343
        {
 
1344
            if (where == MIDORI_NEW_VIEW_WINDOW)
 
1345
                g_signal_emit (browser, signals[SEND_NOTIFICATION], 0,
 
1346
                    _("New Window"), _("A new window has been opened"));
 
1347
            else if (!browser->show_tabs)
 
1348
                g_signal_emit (browser, signals[SEND_NOTIFICATION], 0,
 
1349
                    _("New Tab"), _("A new tab has been opened"));
 
1350
        }
 
1351
    }
1381
1352
}
1382
1353
 
1383
1354
#if WEBKIT_CHECK_VERSION (1, 1, 3)
1405
1376
                                   WebKitDownload* download,
1406
1377
                                   MidoriBrowser*  browser)
1407
1378
{
1408
 
    g_signal_emit (browser, signals[ADD_DOWNLOAD], 0, download);
1409
1379
    if (!webkit_download_get_destination_uri (download))
1410
1380
    {
1411
1381
        gchar* folder;
1507
1477
                               MidoriBrowser* browser)
1508
1478
{
1509
1479
    KatzeItem* item;
1510
 
    const gchar* uri;
1511
1480
 
1512
1481
    if (browser->proxy_array && MIDORI_IS_VIEW (widget))
1513
1482
    {
1514
1483
        item = midori_view_get_proxy_item (MIDORI_VIEW (widget));
1515
 
        uri = katze_item_get_uri (item);
1516
1484
        if (browser->trash && !midori_view_is_blank (MIDORI_VIEW (widget)))
1517
1485
            katze_array_add_item (browser->trash, item);
1518
1486
        katze_array_remove_item (browser->proxy_array, item);
1538
1506
}
1539
1507
 
1540
1508
static void
 
1509
_midori_browser_update_notebook (MidoriBrowser* browser)
 
1510
{
 
1511
    guint i;
 
1512
    gint new_size = 0;
 
1513
    gint n = gtk_notebook_get_n_pages (GTK_NOTEBOOK(browser->notebook));
 
1514
    const gint max_size = 150;
 
1515
    const gint min_size = 32;
 
1516
    GtkAllocation notebook_size;
 
1517
 
 
1518
    gtk_widget_get_allocation (browser->notebook, &notebook_size);
 
1519
    if (n > 0) new_size = notebook_size.width / n - 7;
 
1520
    if (new_size < min_size) new_size = min_size;
 
1521
    if (new_size > max_size) new_size = max_size;
 
1522
 
 
1523
    for (i = 0; i < n; i++)
 
1524
    {
 
1525
        GtkWidget* view;
 
1526
        GtkWidget* label;
 
1527
        view = gtk_notebook_get_nth_page (GTK_NOTEBOOK(browser->notebook), i);
 
1528
        label = gtk_notebook_get_tab_label (GTK_NOTEBOOK(browser->notebook), view);
 
1529
        /* Don't resize empty bin, which is used for thumbnail tabs */
 
1530
        if (GTK_IS_BIN (label) && gtk_bin_get_child (GTK_BIN (label))
 
1531
         && !katze_object_get_boolean (view, "minimized"))
 
1532
            gtk_widget_set_size_request (label, new_size, -1);
 
1533
    }
 
1534
}
 
1535
 
 
1536
static void
1541
1537
_midori_browser_add_tab (MidoriBrowser* browser,
1542
1538
                         GtkWidget*     view)
1543
1539
{
1551
1547
    item = midori_view_get_proxy_item (MIDORI_VIEW (view));
1552
1548
    g_object_ref (item);
1553
1549
    katze_array_add_item (browser->proxy_array, item);
1554
 
    katze_array_move_item (browser->proxy_array, item,
1555
 
         gtk_notebook_get_current_page (notebook) + 1);
1556
1550
 
1557
1551
    g_object_connect (view,
1558
1552
                      "signal::notify::icon",
1567
1561
                      midori_view_notify_uri_cb, browser,
1568
1562
                      "signal::notify::title",
1569
1563
                      midori_view_notify_title_cb, browser,
 
1564
                      "signal::notify::minimized",
 
1565
                      midori_view_notify_minimized_cb, browser,
1570
1566
                      "signal::notify::zoom-level",
1571
1567
                      midori_view_notify_zoom_level_cb, browser,
1572
1568
                      "signal::notify::statusbar-text",
1575
1571
                      midori_view_activate_action_cb, browser,
1576
1572
                      "signal::attach-inspector",
1577
1573
                      midori_view_attach_inspector_cb, browser,
 
1574
                      "signal::detach-inspector",
 
1575
                      midori_view_detach_inspector_cb, browser,
1578
1576
                      "signal::new-tab",
1579
1577
                      midori_view_new_tab_cb, browser,
1580
1578
                      "signal::new-window",
1617
1615
        G_CALLBACK (midori_browser_tab_destroy_cb), browser);
1618
1616
 
1619
1617
    _midori_browser_update_actions (browser);
 
1618
    _midori_browser_update_notebook (browser);
1620
1619
}
1621
1620
 
1622
1621
static void
1624
1623
                            GtkWidget*     view)
1625
1624
{
1626
1625
    gtk_widget_destroy (view);
 
1626
    _midori_browser_update_notebook (browser);
1627
1627
}
1628
1628
 
1629
1629
/**
1659
1659
                                GdkEventKey* event)
1660
1660
{
1661
1661
    GtkWindow* window = GTK_WINDOW (widget);
 
1662
    MidoriBrowser* browser = MIDORI_BROWSER (widget);
1662
1663
    GtkWidgetClass* widget_class;
1663
1664
    guint clean_state;
1664
1665
 
 
1666
    /* Interpret Ctrl(+Shift)+Tab as tab switching for compatibility */
 
1667
    if (midori_browser_get_nth_tab (browser, 1) != NULL
 
1668
     && event->keyval == GDK_Tab
 
1669
     && (event->state & GDK_CONTROL_MASK))
 
1670
    {
 
1671
        gtk_action_activate (_action_by_name (browser, "TabNext"));
 
1672
        return TRUE;
 
1673
    }
 
1674
    else if (event->keyval == GDK_ISO_Left_Tab
 
1675
     && (event->state & GDK_CONTROL_MASK)
 
1676
     && (event->state & GDK_SHIFT_MASK))
 
1677
    {
 
1678
        gtk_action_activate (_action_by_name (browser, "TabPrevious"));
 
1679
        return TRUE;
 
1680
    }
 
1681
    /* Interpret F5 as reloading for compatibility */
 
1682
    else if (event->keyval == GDK_F5)
 
1683
    {
 
1684
        gtk_action_activate (_action_by_name (browser, "Reload"));
 
1685
        return TRUE;
 
1686
    }
 
1687
 
 
1688
    if (gtk_window_get_focus (GTK_WINDOW (widget)) == NULL)
 
1689
        gtk_widget_grab_focus (midori_browser_get_current_tab (MIDORI_BROWSER (widget)));
 
1690
 
1665
1691
    if (event->state & (GDK_CONTROL_MASK | GDK_MOD1_MASK))
1666
1692
        if (sokoke_window_activate_key (window, event))
1667
1693
            return TRUE;
1677
1703
    if (event->state && gtk_window_propagate_key_event (window, event))
1678
1704
        return TRUE;
1679
1705
 
 
1706
    /* Interpret Backspace as going back for compatibility */
 
1707
    if (event->keyval == GDK_BackSpace)
 
1708
    {
 
1709
        gtk_action_activate (_action_by_name (browser, "Back"));
 
1710
        return TRUE;
 
1711
    }
 
1712
 
1680
1713
    widget_class = g_type_class_peek_static (g_type_parent (GTK_TYPE_WINDOW));
1681
1714
    return widget_class->key_press_event (widget, event);
1682
1715
}
1742
1775
        G_TYPE_NONE, 1,
1743
1776
        GTK_TYPE_WIDGET);
1744
1777
 
 
1778
    /**
 
1779
     * MidoriBrowser::move-tab:
 
1780
     * @browser: the object on which the signal is emitted
 
1781
     * @notebook: the notebook containing the tabs
 
1782
     * @cur_pos: the current position of the tab
 
1783
     * @new_pos: the new position of the tab
 
1784
     *
 
1785
     * Emitted when a tab is moved.
 
1786
     *
 
1787
     * Since: 0.3.3
 
1788
     */
 
1789
     signals[MOVE_TAB] = g_signal_new (
 
1790
        "move-tab",
 
1791
        G_TYPE_FROM_CLASS (class),
 
1792
        (GSignalFlags)(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION),
 
1793
        0,
 
1794
        0,
 
1795
        NULL,
 
1796
        midori_cclosure_marshal_VOID__OBJECT_INT_INT,
 
1797
        G_TYPE_NONE, 3,
 
1798
        GTK_TYPE_NOTEBOOK, G_TYPE_INT, G_TYPE_INT);
 
1799
 
1745
1800
    signals[ACTIVATE_ACTION] = g_signal_new (
1746
1801
        "activate-action",
1747
1802
        G_TYPE_FROM_CLASS (class),
1798
1853
     * @message: the message for the notification
1799
1854
     *
1800
1855
     * Emitted when a browser wants to display a notification message,
1801
 
     * e.g. when a download has been completed.
 
1856
     * e.g. when a download has been completed or a new tab was opened.
1802
1857
     *
1803
1858
     * Since: 0.1.7
1804
1859
     */
1834
1889
        g_cclosure_marshal_VOID__OBJECT,
1835
1890
        G_TYPE_NONE, 1,
1836
1891
        GTK_TYPE_MENU);
 
1892
    /**
 
1893
     * MidoriBrowser::populate-toolbar-menu:
 
1894
     * @browser: the object on which the signal is emitted
 
1895
     * @menu: the #GtkMenu to populate
 
1896
     *
 
1897
     * Emitted when a toolbar menu is displayed on right-click.
 
1898
     *
 
1899
     * Since: 0.3.4
 
1900
     */
 
1901
    signals[POPULATE_TOOLBAR_MENU] = g_signal_new (
 
1902
        "populate-toolbar-menu",
 
1903
        G_TYPE_FROM_CLASS (class),
 
1904
        (GSignalFlags)(G_SIGNAL_RUN_LAST),
 
1905
        0,
 
1906
        0,
 
1907
        NULL,
 
1908
        g_cclosure_marshal_VOID__OBJECT,
 
1909
        G_TYPE_NONE, 1,
 
1910
        GTK_TYPE_MENU);
1837
1911
 
1838
1912
    signals[QUIT] = g_signal_new (
1839
1913
        "quit",
1845
1919
        g_cclosure_marshal_VOID__VOID,
1846
1920
        G_TYPE_NONE, 0);
1847
1921
 
 
1922
    /**
 
1923
     * MidoriBrowser::show-preferences:
 
1924
     * @browser: the object on which the signal is emitted
 
1925
     * @preferences: the #KatzePreferences to populate
 
1926
     *
 
1927
     * Emitted when a preference dialogue displayed, to allow
 
1928
     * adding of a new page, to be used sparingly.
 
1929
     *
 
1930
     * Since: 0.3.4
 
1931
     */
 
1932
    signals[SHOW_PREFERENCES] = g_signal_new (
 
1933
        "show-preferences",
 
1934
        G_TYPE_FROM_CLASS (class),
 
1935
        (GSignalFlags)(G_SIGNAL_RUN_LAST),
 
1936
        0,
 
1937
        0,
 
1938
        NULL,
 
1939
        g_cclosure_marshal_VOID__OBJECT,
 
1940
        G_TYPE_NONE, 1,
 
1941
        KATZE_TYPE_PREFERENCES);
 
1942
 
1848
1943
    class->add_tab = _midori_browser_add_tab;
1849
1944
    class->remove_tab = _midori_browser_remove_tab;
1850
1945
    class->activate_action = _midori_browser_activate_action;
2051
2146
                                     flags));
2052
2147
 
2053
2148
    /**
 
2149
    * MidoriBrowser:speed-dial:
 
2150
    *
 
2151
    * The speed dial configuration file.
 
2152
    *
 
2153
    * Since: 0.3.4
 
2154
    */
 
2155
    g_object_class_install_property (gobject_class,
 
2156
                                     PROP_SPEED_DIAL,
 
2157
                                     g_param_spec_pointer (
 
2158
                                     "speed-dial",
 
2159
                                     "Speeddial",
 
2160
                                     "Pointer to key-value object with speed dial items",
 
2161
                                     G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
 
2162
 
 
2163
 
 
2164
    /**
2054
2165
     * MidoriBrowser:show-tabs:
2055
2166
     *
2056
2167
     * Whether or not to show tabs.
2227
2338
                                       const gchar*   uri)
2228
2339
{
2229
2340
    if (browser->news_aggregator && *browser->news_aggregator)
2230
 
        sokoke_spawn_program (browser->news_aggregator, uri);
 
2341
    {
 
2342
        /* Special-case Liferea because a helper script may be required */
 
2343
        if (g_str_equal (browser->news_aggregator, "liferea")
 
2344
         && g_find_program_in_path ("liferea-add-feed"))
 
2345
            sokoke_spawn_program ("liferea-add-feed", uri);
 
2346
        else
 
2347
            sokoke_spawn_program (browser->news_aggregator, uri);
 
2348
    }
2231
2349
    else
2232
2350
    {
2233
2351
        gchar* description = g_strdup_printf ("%s\n\n%s", uri,
2431
2549
                       MidoriBrowser* browser)
2432
2550
{
2433
2551
    GtkWidget* widget = gtk_window_get_focus (GTK_WINDOW (browser));
 
2552
    /* Work around broken clipboard handling for the sake of the user */
 
2553
    if (WEBKIT_IS_WEB_VIEW (widget))
 
2554
    {
 
2555
        GtkWidget* scrolled = gtk_widget_get_parent (widget);
 
2556
        GtkWidget* view = gtk_widget_get_parent (scrolled);
 
2557
        const gchar* selected = midori_view_get_selected_text (MIDORI_VIEW (view));
 
2558
        sokoke_widget_copy_clipboard (widget, selected);
 
2559
        return;
 
2560
    }
2434
2561
    if (G_LIKELY (widget) && g_signal_lookup ("copy-clipboard", G_OBJECT_TYPE (widget)))
2435
2562
        g_signal_emit_by_name (widget, "copy-clipboard");
2436
2563
}
2612
2739
        _action_by_name (browser, "Statusbar"));
2613
2740
    gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
2614
2741
 
 
2742
    g_signal_emit (browser, signals[POPULATE_TOOLBAR_MENU], 0, menu);
 
2743
 
2615
2744
    katze_widget_popup (widget, GTK_MENU (menu), NULL,
2616
2745
        button == -1 ? KATZE_MENU_POSITION_LEFT : KATZE_MENU_POSITION_CURSOR);
2617
2746
    return TRUE;
2633
2762
        if (item)
2634
2763
        {
2635
2764
            tooltip = g_strdup (katze_item_get_uri (item));
2636
 
            sokoke_prefetch_uri (tooltip, NULL, NULL);
 
2765
            sokoke_prefetch_uri (midori_browser_get_settings (browser),
 
2766
                                 tooltip, NULL, NULL);
2637
2767
        }
2638
2768
    }
2639
2769
    _midori_browser_set_statusbar_text (browser, tooltip);
2874
3004
    gtk_menu_shell_prepend (GTK_MENU_SHELL (menu), menuitem);
2875
3005
    gtk_widget_show (menuitem);
2876
3006
    menuitem = gtk_action_create_menu_item (
 
3007
        _action_by_name (browser, "NextView"));
 
3008
    gtk_menu_shell_prepend (GTK_MENU_SHELL (menu), menuitem);
 
3009
    gtk_widget_show (menuitem);
 
3010
    menuitem = gtk_action_create_menu_item (
2877
3011
        _action_by_name (browser, "TabNext"));
2878
3012
    gtk_menu_shell_prepend (GTK_MENU_SHELL (menu), menuitem);
2879
3013
    gtk_widget_show (menuitem);
2909
3043
    static const GtkActionEntry actions[] = {
2910
3044
      { "TabNew" },
2911
3045
      { "WindowNew" },
2912
 
      { "PrivateBrowsing" },
 
3046
      { NULL },
2913
3047
      { "Open" },
2914
3048
      { "Find" },
2915
3049
      #if !HAVE_HILDON
2916
3050
      { "Print" },
2917
 
      { NULL },
2918
 
      { "Panel" },
2919
 
      { "-" },
2920
 
      { "ClearPrivateData" },
2921
3051
      #if WEBKIT_CHECK_VERSION (1, 1, 17)
2922
3052
      { "InspectPage" },
2923
3053
      #endif
2924
 
      { "Fullscreen" },
 
3054
      #endif
 
3055
      { NULL },
 
3056
      { "PrivateBrowsing" },
 
3057
      #if !HAVE_HILDON
 
3058
      { "ClearPrivateData" },
 
3059
      { NULL },
2925
3060
      { "BookmarksImport"},
2926
3061
      { "BookmarksExport"},
 
3062
      { NULL },
 
3063
      { "Fullscreen" },
 
3064
      { "Panel" },
 
3065
      { "-" },
 
3066
      #endif
 
3067
      { NULL },
 
3068
      #if !HAVE_HILDON
 
3069
      { "HelpFAQ" },
 
3070
      { "HelpBugs"},
2927
3071
      #endif
2928
3072
      { "About" },
2929
3073
      { "Preferences" },
2930
3074
      #if HAVE_HILDON
 
3075
      { NULL },
2931
3076
      { "auto-load-images" },
2932
3077
      { "enable-scripts" },
2933
3078
      { "enable-plugins" },
2934
3079
      #endif
2935
3080
    };
 
3081
 
2936
3082
    guint i;
2937
3083
 
2938
3084
    for (i = 0; i < G_N_ELEMENTS (actions); i++)
2987
3133
                                     MidoriBrowser* browser)
2988
3134
{
2989
3135
    if (response == GTK_RESPONSE_HELP)
2990
 
        gtk_action_activate (_action_by_name (browser, "HelpContents"));
 
3136
        gtk_action_activate (_action_by_name (browser, "HelpFAQ"));
2991
3137
}
2992
3138
 
2993
3139
static void
3002
3148
    if (!dialog)
3003
3149
    {
3004
3150
        dialog = midori_preferences_new (GTK_WINDOW (browser), browser->settings);
 
3151
        g_signal_emit (browser, signals[SHOW_PREFERENCES], 0, dialog);
3005
3152
        g_signal_connect (dialog, "response",
3006
3153
            G_CALLBACK (midori_preferences_response_help_cb), browser);
3007
3154
        g_signal_connect (dialog, "destroy",
3283
3430
 
3284
3431
        source = midori_view_new (NULL);
3285
3432
        midori_view_set_settings (MIDORI_VIEW (source), browser->settings);
3286
 
        midori_view_set_uri (MIDORI_VIEW (source), "");
3287
3433
        web_view = midori_view_get_web_view (MIDORI_VIEW (source));
3288
3434
        webkit_web_view_set_view_source_mode (WEBKIT_WEB_VIEW (web_view), TRUE);
3289
3435
        webkit_web_view_load_uri (WEBKIT_WEB_VIEW (web_view), uri);
3314
3460
        gchar* filename = g_filename_from_uri (uri, NULL, NULL);
3315
3461
        sokoke_spawn_program (text_editor, filename);
3316
3462
        g_free (filename);
 
3463
        g_free (text_editor);
3317
3464
        return;
3318
3465
    }
3319
3466
    katze_net_load_uri (NULL, uri, NULL,
3321
3468
    g_free (text_editor);
3322
3469
}
3323
3470
 
 
3471
#if WEBKIT_CHECK_VERSION (1, 1, 6)
 
3472
static void
 
3473
_action_caret_browsing_activate (GtkAction*     action,
 
3474
                                 MidoriBrowser* browser)
 
3475
{
 
3476
    g_object_set (browser->settings, "enable-caret-browsing",
 
3477
        !katze_object_get_boolean (browser->settings, "enable-caret-browsing"), NULL);
 
3478
}
 
3479
#endif
 
3480
 
3324
3481
static void
3325
3482
_action_fullscreen_activate (GtkAction*     action,
3326
3483
                             MidoriBrowser* browser)
3433
3590
}
3434
3591
 
3435
3592
static void
3436
 
_action_location_active_changed (GtkAction*     action,
3437
 
                                 gint           idx,
3438
 
                                 MidoriBrowser* browser)
3439
 
{
3440
 
    const gchar* uri;
3441
 
 
3442
 
    if (idx > -1)
3443
 
    {
3444
 
        uri = midori_location_action_get_uri (MIDORI_LOCATION_ACTION (action));
3445
 
        midori_browser_set_current_uri (browser, uri);
3446
 
    }
3447
 
}
3448
 
 
3449
 
static void
3450
3593
_action_location_focus_in (GtkAction*     action,
3451
3594
                           MidoriBrowser* browser)
3452
3595
{
3501
3644
        gchar** parts;
3502
3645
        gchar* keywords = NULL;
3503
3646
        const gchar* search_uri = NULL;
3504
 
        time_t now;
3505
 
        gint64 day;
3506
 
        sqlite3* db;
3507
 
        static sqlite3_stmt* statement = NULL;
3508
3647
 
3509
3648
        /* Do we have a keyword and a string? */
3510
3649
        parts = g_strsplit (stripped_uri, " ", 2);
3511
 
        if (parts[0])
 
3650
        if (parts[0] && browser->search_engines)
3512
3651
        {
3513
3652
            KatzeItem* item;
3514
3653
            if ((item = katze_array_find_token (browser->search_engines, parts[0])))
3528
3667
        }
3529
3668
        new_uri = sokoke_search_uri (search_uri, keywords);
3530
3669
 
3531
 
        now = time (NULL);
3532
 
        day = sokoke_time_t_to_julian (&now);
3533
 
 
3534
 
        db = g_object_get_data (G_OBJECT (browser->history), "db");
3535
 
        if (!statement)
 
3670
        if (browser->history != NULL)
3536
3671
        {
3537
 
            const gchar* sqlcmd;
3538
 
            sqlcmd = "INSERT INTO search (keywords, uri, day) VALUES (?,?,?)";
3539
 
            sqlite3_prepare_v2 (db, sqlcmd, strlen (sqlcmd) + 1, &statement, NULL);
3540
 
        }
3541
 
        sqlite3_bind_text (statement, 1, keywords, -1, 0);
3542
 
        sqlite3_bind_text (statement, 2, search_uri, -1, 0);
3543
 
        sqlite3_bind_int64 (statement, 3, day);
3544
 
 
3545
 
        if (sqlite3_step (statement) != SQLITE_DONE)
3546
 
            g_printerr (_("Failed to insert new history item: %s\n"),
 
3672
            time_t now = time (NULL);
 
3673
            gint64 day = sokoke_time_t_to_julian (&now);
 
3674
            sqlite3* db = g_object_get_data (G_OBJECT (browser->history), "db");
 
3675
            static sqlite3_stmt* statement = NULL;
 
3676
 
 
3677
            if (!statement)
 
3678
            {
 
3679
                const gchar* sqlcmd;
 
3680
                sqlcmd = "INSERT INTO search (keywords, uri, day) VALUES (?,?,?)";
 
3681
                sqlite3_prepare_v2 (db, sqlcmd, strlen (sqlcmd) + 1, &statement, NULL);
 
3682
            }
 
3683
            sqlite3_bind_text (statement, 1, keywords, -1, 0);
 
3684
            sqlite3_bind_text (statement, 2, search_uri, -1, 0);
 
3685
            sqlite3_bind_int64 (statement, 3, day);
 
3686
 
 
3687
            if (sqlite3_step (statement) != SQLITE_DONE)
 
3688
                g_printerr (_("Failed to insert new history item: %s\n"),
3547
3689
                        sqlite3_errmsg (db));
3548
 
        sqlite3_reset (statement);
3549
 
        if (sqlite3_step (statement) == SQLITE_DONE)
3550
 
            sqlite3_clear_bindings (statement);
 
3690
            sqlite3_reset (statement);
 
3691
            if (sqlite3_step (statement) == SQLITE_DONE)
 
3692
                sqlite3_clear_bindings (statement);
 
3693
        }
3551
3694
 
3552
3695
        g_free (keywords);
3553
3696
    }
3661
3804
                       gboolean       new_tab,
3662
3805
                       MidoriBrowser* browser)
3663
3806
{
3664
 
    guint last_web_search;
3665
3807
    KatzeItem* item;
3666
3808
    const gchar* url;
3667
3809
    gchar* search;
3668
3810
 
3669
 
    g_object_get (browser->settings, "last-web-search", &last_web_search, NULL);
3670
 
    item = katze_array_get_nth_item (browser->search_engines, last_web_search);
 
3811
    item = katze_array_get_nth_item (browser->search_engines, browser->last_web_search);
3671
3812
    if (item)
3672
3813
        url = katze_item_get_uri (item);
3673
3814
    else /* The location entry search is our fallback */
3726
3867
        idx = 0;
3727
3868
 
3728
3869
    g_object_set (browser->settings, "last-web-search", idx, NULL);
 
3870
    browser->last_web_search = idx;
3729
3871
}
3730
3872
 
3731
3873
static void
4267
4409
    {
4268
4410
        GtkWidget* content_area;
4269
4411
        GdkScreen* screen;
4270
 
        GtkIconTheme* icon_theme;
4271
4412
        GtkSizeGroup* sizegroup;
4272
4413
        GtkWidget* hbox;
4273
4414
        GtkWidget* alignment;
4292
4433
        screen = gtk_widget_get_screen (GTK_WIDGET (browser));
4293
4434
        if (screen)
4294
4435
        {
4295
 
            icon_theme = gtk_icon_theme_get_for_screen (screen);
4296
4436
            gtk_window_set_icon_name (GTK_WINDOW (dialog), GTK_STOCK_CLEAR);
4297
4437
        }
4298
4438
        sizegroup = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
4371
4511
#endif
4372
4512
 
4373
4513
static void
 
4514
_action_tab_move_backward_activate (GtkAction*     action,
 
4515
                                    MidoriBrowser* browser)
 
4516
{
 
4517
    gint new_pos;
 
4518
    gint cur_pos = gtk_notebook_get_current_page (GTK_NOTEBOOK (browser->notebook));
 
4519
    GtkWidget* widget = gtk_notebook_get_nth_page (GTK_NOTEBOOK (browser->notebook), cur_pos);
 
4520
    if (cur_pos > 0)
 
4521
        new_pos = cur_pos - 1;
 
4522
    else
 
4523
        new_pos = gtk_notebook_get_n_pages (GTK_NOTEBOOK (browser->notebook)) - 1;
 
4524
    gtk_notebook_reorder_child (GTK_NOTEBOOK (browser->notebook), widget, new_pos);
 
4525
    g_signal_emit (browser, signals[MOVE_TAB], 0, browser->notebook, cur_pos, new_pos);
 
4526
}
 
4527
 
 
4528
static void
 
4529
_action_tab_move_forward_activate (GtkAction*     action,
 
4530
                                   MidoriBrowser* browser)
 
4531
{
 
4532
    gint new_pos;
 
4533
    gint cur_pos = gtk_notebook_get_current_page (GTK_NOTEBOOK (browser->notebook));
 
4534
    GtkWidget* widget = gtk_notebook_get_nth_page (GTK_NOTEBOOK (browser->notebook), cur_pos);
 
4535
    if (cur_pos == (gtk_notebook_get_n_pages (GTK_NOTEBOOK (browser->notebook)) - 1))
 
4536
        new_pos = 0;
 
4537
    else
 
4538
        new_pos = cur_pos + 1;
 
4539
    gtk_notebook_reorder_child (GTK_NOTEBOOK (browser->notebook), widget, new_pos);
 
4540
    g_signal_emit (browser, signals[MOVE_TAB], 0, browser->notebook, cur_pos, new_pos);
 
4541
}
 
4542
 
 
4543
static void
4374
4544
_action_tab_previous_activate (GtkAction*     action,
4375
4545
                               MidoriBrowser* browser)
4376
4546
{
4398
4568
}
4399
4569
 
4400
4570
static void
 
4571
_action_next_view_activate (GtkAction*     action,
 
4572
                              MidoriBrowser* browser)
 
4573
{
 
4574
    gtk_widget_grab_focus (midori_browser_get_current_tab (browser));
 
4575
}
 
4576
 
 
4577
static void
4401
4578
_action_tab_minimize_activate (GtkAction*     action,
4402
4579
                               MidoriBrowser* browser)
4403
4580
{
4415
4592
    GtkWidget* new_view = midori_view_new_with_title (
4416
4593
        NULL, browser->settings, FALSE);
4417
4594
    const gchar* uri = midori_view_get_display_uri (MIDORI_VIEW (view));
4418
 
    g_signal_emit_by_name (view, "new-view", new_view, where);
 
4595
    g_signal_emit_by_name (view, "new-view", new_view, where, TRUE);
4419
4596
    midori_view_set_uri (MIDORI_VIEW (new_view), uri);
4420
4597
}
4421
4598
 
4514
4691
    #endif
4515
4692
 
4516
4693
    action_name = gtk_action_get_name (action);
4517
 
    if  (!strncmp ("HelpContents", action_name, 12))
 
4694
    if  (!strncmp ("HelpFAQ", action_name, 7))
4518
4695
    {
4519
4696
        #ifdef G_OS_WIN32
4520
4697
        {
4521
4698
            #ifdef DOCDIR
4522
 
            gchar* path = sokoke_find_data_filename ("doc/midori/user/midori.html");
 
4699
            gchar* path = sokoke_find_data_filename ("doc/midori/faq.html");
4523
4700
            uri = free_uri = g_filename_to_uri (path, NULL, NULL);
4524
4701
            if (g_access (path, F_OK) != 0)
4525
4702
            {
4526
 
                if (g_access (DOCDIR "/user/midori.html", F_OK) == 0)
4527
 
                    uri = "file://" DOCDIR "/user/midori.html";
 
4703
                if (g_access (DOCDIR "/faq.html", F_OK) == 0)
 
4704
                    uri = "file://" DOCDIR "/faq.html";
4528
4705
                else
4529
4706
            #endif
4530
 
                    uri = "error:nodocs share/doc/midori/user/midori.html";
 
4707
                    uri = "error:nodocs share/doc/midori/faq.html";
4531
4708
            #ifdef DOCDIR
4532
4709
            }
4533
4710
            g_free (path);
4535
4712
        }
4536
4713
        #else
4537
4714
        #ifdef DOCDIR
4538
 
        uri = "file://" DOCDIR "/user/midori.html";
4539
 
        if (g_access (DOCDIR "/user/midori.html", F_OK) != 0)
 
4715
        uri = "file://" DOCDIR "/faq.html";
 
4716
        if (g_access (DOCDIR "/faq.html", F_OK) != 0)
4540
4717
        #endif
4541
 
            uri = "error:nodocs " DOCDIR "/user/midori.html";
 
4718
            uri = "error:nodocs " DOCDIR "/faq.html";
4542
4719
        #endif
4543
4720
    }
4544
 
    else if  (!strncmp ("HelpFAQ", action_name, 7))
4545
 
        uri = "http://wiki.xfce.org/midori/faq";
4546
4721
    else if  (!strncmp ("HelpBugs", action_name, 8))
4547
4722
        uri = PACKAGE_BUGREPORT;
4548
4723
    else
4588
4763
            (GSourceFunc)midori_browser_panel_timeout, hpaned, NULL);
4589
4764
}
4590
4765
 
 
4766
static gboolean
 
4767
midori_panel_cycle_child_focus_cb (GtkWidget*     hpaned,
 
4768
                                   gboolean       reversed,
 
4769
                                   MidoriBrowser* browser)
 
4770
{
 
4771
    /* Default cycle goes between all GtkPaned widgets.
 
4772
       If focus is in the panel, focus the location as if it's a paned.
 
4773
       If nothing is focussed, simply go to the location.
 
4774
       Be sure to suppress the default because the signal can recurse. */
 
4775
    GtkWidget* focus = gtk_window_get_focus (GTK_WINDOW (browser));
 
4776
    if (gtk_widget_get_ancestor (focus, MIDORI_TYPE_PANEL)
 
4777
     || !gtk_widget_get_ancestor (focus, GTK_TYPE_PANED))
 
4778
    {
 
4779
        g_signal_stop_emission_by_name (hpaned, "cycle-child-focus");
 
4780
        gtk_action_activate (_action_by_name (browser, "Location"));
 
4781
        return TRUE;
 
4782
    }
 
4783
    return FALSE;
 
4784
}
 
4785
 
4591
4786
static void
4592
4787
midori_panel_notify_page_cb (MidoriPanel*   panel,
4593
4788
                             GParamSpec*    pspec,
4697
4892
    MidoriView* view;
4698
4893
    const gchar* uri;
4699
4894
    GtkAction* action;
4700
 
    const gchar* title;
4701
 
    gchar* window_title;
4702
4895
 
4703
4896
    if (!(widget = midori_browser_get_current_tab (browser)))
4704
4897
        return;
4707
4900
    uri = g_object_get_data (G_OBJECT (widget), "midori-browser-typed-text");
4708
4901
    if (!uri)
4709
4902
        uri = midori_view_get_display_uri (view);
 
4903
    midori_browser_set_title (browser, midori_view_get_display_title (view));
4710
4904
    action = _action_by_name (browser, "Location");
4711
4905
    midori_location_action_set_text (MIDORI_LOCATION_ACTION (action), uri);
4712
4906
    midori_location_action_set_icon (MIDORI_LOCATION_ACTION (action),
4713
4907
                                     midori_view_get_icon (view));
4714
4908
 
4715
 
    title = midori_view_get_display_title (view);
4716
 
    window_title = g_strconcat (title, " - ", g_get_application_name (), NULL);
4717
 
    gtk_window_set_title (GTK_WINDOW (browser), window_title);
4718
 
    g_free (window_title);
4719
 
 
4720
4909
    if (browser->proxy_array)
4721
4910
        katze_item_set_meta_integer (KATZE_ITEM (browser->proxy_array), "current",
4722
4911
                                     midori_browser_get_current_page (browser));
4723
 
    g_object_freeze_notify (G_OBJECT (browser));
4724
 
    g_object_notify (G_OBJECT (browser), "uri");
4725
4912
    g_object_notify (G_OBJECT (browser), "tab");
4726
 
    g_object_thaw_notify (G_OBJECT (browser));
4727
4913
 
4728
4914
    _midori_browser_set_statusbar_text (browser, NULL);
4729
4915
    _midori_browser_update_interface (browser);
4738
4924
{
4739
4925
    KatzeItem* item = midori_view_get_proxy_item (view);
4740
4926
    katze_array_move_item (browser->proxy_array, item, page_num);
4741
 
 
4742
 
    g_object_freeze_notify (G_OBJECT (browser));
4743
 
    g_object_notify (G_OBJECT (browser), "uri");
4744
4927
    g_object_notify (G_OBJECT (browser), "tab");
4745
 
    g_object_thaw_notify (G_OBJECT (browser));
 
4928
}
 
4929
 
 
4930
static gboolean
 
4931
midori_browser_notebook_reorder_tab_cb (GtkNotebook*     notebook,
 
4932
                                        GtkDirectionType arg1,
 
4933
                                        gboolean         arg2,
 
4934
                                        gpointer         user_data)
 
4935
{
 
4936
    g_signal_stop_emission_by_name (notebook, "reorder-tab");
 
4937
    return TRUE;
 
4938
}
 
4939
 
 
4940
static void
 
4941
midori_browser_switch_tab_cb (GtkWidget*     menuitem,
 
4942
                              MidoriBrowser* browser)
 
4943
{
 
4944
    gint page = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (menuitem), "index"));
 
4945
    midori_browser_set_current_page (browser, page);
4746
4946
}
4747
4947
 
4748
4948
static gboolean
4764
4964
 
4765
4965
        return TRUE;
4766
4966
    }
 
4967
    else if (event->type == GDK_BUTTON_PRESS && event->button == 3)
 
4968
    {
 
4969
        GtkWidget* menu = gtk_menu_new ();
 
4970
        GList* tabs = gtk_container_get_children (GTK_CONTAINER (notebook));
 
4971
        GtkWidget* menuitem = sokoke_action_create_popup_menu_item (
 
4972
            gtk_action_group_get_action (browser->action_group, "TabNew"));
 
4973
        gint i = 0;
 
4974
        gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
 
4975
        menuitem = sokoke_action_create_popup_menu_item (
 
4976
            gtk_action_group_get_action (browser->action_group, "UndoTabClose"));
 
4977
        gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
 
4978
        menuitem = gtk_separator_menu_item_new ();
 
4979
        gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
 
4980
        for (; tabs != NULL; tabs = g_list_next (tabs))
 
4981
        {
 
4982
            const gchar* title = midori_view_get_display_title (tabs->data);
 
4983
            menuitem = katze_image_menu_item_new_ellipsized (title);
 
4984
            gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menuitem),
 
4985
                gtk_image_new_from_pixbuf (midori_view_get_icon (tabs->data)));
 
4986
            gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
 
4987
            g_object_set_data (G_OBJECT (menuitem), "index", GINT_TO_POINTER (i));
 
4988
            g_signal_connect (menuitem, "activate",
 
4989
                G_CALLBACK (midori_browser_switch_tab_cb), browser);
 
4990
            i++;
 
4991
        }
 
4992
        g_list_free (tabs);
 
4993
        gtk_widget_show_all (menu);
 
4994
        katze_widget_popup (GTK_WIDGET (notebook), GTK_MENU (menu), NULL,
 
4995
            KATZE_MENU_POSITION_CURSOR);
 
4996
    }
4767
4997
 
4768
4998
    return FALSE;
4769
4999
}
4845
5075
        NULL, "<Ctrl>p",
4846
5076
        N_("Print the current page"), G_CALLBACK (_action_print_activate) },
4847
5077
    { "Quit", GTK_STOCK_QUIT,
4848
 
        NULL, "<Ctrl>q",
4849
 
        N_("Quit the application"), G_CALLBACK (_action_quit_activate) },
 
5078
        N_("Close a_ll Windows"), "<Ctrl><Shift>q",
 
5079
        N_("Close all open windows"), G_CALLBACK (_action_quit_activate) },
4850
5080
 
4851
5081
    { "Edit", NULL, N_("_Edit"), NULL, NULL, G_CALLBACK (_action_edit_activate) },
4852
5082
        #if WEBKIT_CHECK_VERSION (1, 1, 14)
4892
5122
        NULL, "<Ctrl>r",
4893
5123
        N_("Reload the current page"), G_CALLBACK (_action_reload_stop_activate) },
4894
5124
    { "ReloadUncached", GTK_STOCK_REFRESH,
4895
 
        NULL, "<Ctrl><Shift>r",
 
5125
        N_("Reload page without caching"), "<Ctrl><Shift>r",
4896
5126
        N_("Reload page without caching"), G_CALLBACK (_action_reload_stop_activate) },
4897
5127
    { "Stop", GTK_STOCK_STOP,
4898
5128
        NULL, "Escape",
4913
5143
    { "SourceView", NULL,
4914
5144
        N_("View So_urce"), "<Ctrl><Alt>U",
4915
5145
        N_("View the source code of the page"), G_CALLBACK (_action_source_view_activate) },
 
5146
    #if WEBKIT_CHECK_VERSION (1, 1, 6)
 
5147
    { "CaretBrowsing", NULL,
 
5148
        N_("Ca_ret Browsing"), "F7",
 
5149
        N_("Toggle text cursor navigation"), G_CALLBACK (_action_caret_browsing_activate) },
 
5150
    #endif
4916
5151
    { "Fullscreen", GTK_STOCK_FULLSCREEN,
4917
5152
        NULL, "F11",
4918
5153
        N_("Toggle fullscreen view"), G_CALLBACK (_action_fullscreen_activate) },
4989
5224
    { "TabNext", GTK_STOCK_GO_FORWARD,
4990
5225
        N_("_Next Tab"), "<Ctrl>Page_Down",
4991
5226
        N_("Switch to the next tab"), G_CALLBACK (_action_tab_next_activate) },
 
5227
    { "TabMoveBackward", NULL, N_("Move Tab _Backward"), "<Ctrl><Shift>Page_Up",
 
5228
       N_("Move tab behind the previous tab"), G_CALLBACK (_action_tab_move_backward_activate) },
 
5229
    { "TabMoveForward", NULL, N_("_Move Tab Forward"), "<Ctrl><Shift>Page_Down",
 
5230
       N_("Move tab in front of the next tab"), G_CALLBACK (_action_tab_move_forward_activate) },
4992
5231
    { "TabCurrent", NULL,
4993
5232
        N_("Focus _Current Tab"), "<Ctrl>Home",
4994
5233
        N_("Focus the current tab"), G_CALLBACK (_action_tab_current_activate) },
 
5234
    { "NextView", NULL,
 
5235
        N_("Focus _Next view"), "F6",
 
5236
        N_("Cycle focus between views"), G_CALLBACK (_action_next_view_activate) },
4995
5237
    { "TabMinimize", NULL,
4996
5238
        N_("Only show the Icon of the _Current Tab"), "",
4997
5239
        N_("Only show the icon of the current tab"), G_CALLBACK (_action_tab_minimize_activate) },
5006
5248
        N_("Open the tabs saved in the last session"), NULL },
5007
5249
 
5008
5250
    { "Help", NULL, N_("_Help") },
5009
 
    { "HelpContents", GTK_STOCK_HELP,
5010
 
        N_("_Contents"), "F1",
5011
 
        N_("Show the documentation"), G_CALLBACK (_action_help_link_activate) },
5012
 
    { "HelpFAQ", NULL,
5013
 
        N_("_Frequent Questions"), NULL,
 
5251
    { "HelpFAQ", GTK_STOCK_HELP,
 
5252
        N_("_Frequent Questions"), "F1",
5014
5253
        N_("Show the Frequently Asked Questions"), G_CALLBACK (_action_help_link_activate) },
5015
5254
    { "HelpBugs", NULL,
5016
 
        N_("_Report a Bug"), NULL,
 
5255
        N_("_Report a Problem..."), NULL,
5017
5256
        N_("Open Midori's bug tracker"), G_CALLBACK (_action_help_link_activate) },
5018
5257
    { "About", GTK_STOCK_ABOUT,
5019
5258
        NULL, "",
5156
5395
}
5157
5396
 
5158
5397
static void
 
5398
gtk_notebook_size_allocated_cb (GtkWidget*     widget,
 
5399
                                GdkRectangle*  allocation,
 
5400
                                MidoriBrowser* browser)
 
5401
{
 
5402
    _midori_browser_update_notebook (browser);
 
5403
}
 
5404
 
 
5405
static void
5159
5406
midori_browser_destroy_cb (MidoriBrowser* browser)
5160
5407
{
5161
5408
    g_object_set_data (G_OBJECT (browser), "midori-browser-destroyed", (void*)1);
5168
5415
    /* Destroy panel first, so panels don't need special care */
5169
5416
    gtk_widget_destroy (browser->panel);
5170
5417
    /* Destroy tabs second, so child widgets don't need special care */
 
5418
    g_signal_handlers_disconnect_by_func (browser->notebook,
 
5419
                                          midori_browser_notebook_reorder_tab_cb,
 
5420
                                          NULL);
 
5421
    g_signal_handlers_disconnect_by_func (browser->notebook,
 
5422
                                          gtk_notebook_size_allocated_cb,
 
5423
                                          NULL);
5171
5424
    gtk_container_foreach (GTK_CONTAINER (browser->notebook),
5172
5425
                           (GtkCallback) gtk_widget_destroy, NULL);
5173
5426
}
5258
5511
            "<menuitem action='Tools'/>"
5259
5512
            "<menuitem action='Window'/>"
5260
5513
            "<menu action='Help'>"
5261
 
                "<menuitem action='HelpContents'/>"
5262
5514
                "<menuitem action='HelpFAQ'/>"
5263
5515
                "<menuitem action='HelpBugs'/>"
5264
5516
                "<separator/>"
5267
5519
        /* For accelerators to work all actions need to be used
5268
5520
           *somewhere* in the UI definition */
5269
5521
        "<menu action='Dummy'>"
 
5522
            "<menuitem action='TabMoveBackward'/>"
 
5523
            "<menuitem action='TabMoveForward'/>"
5270
5524
            "<menuitem action='ScrollLeft'/>"
5271
5525
            "<menuitem action='ScrollDown'/>"
5272
5526
            "<menuitem action='ScrollUp'/>"
5279
5533
            "<menuitem action='TabPrevious'/>"
5280
5534
            "<menuitem action='TabNext'/>"
5281
5535
            "<menuitem action='TabCurrent'/>"
 
5536
            "<menuitem action='NextView'/>"
5282
5537
            "<menuitem action='TabMinimize'/>"
5283
5538
            "<menuitem action='TabDuplicate'/>"
5284
5539
            "<menuitem action='TabCloseOther'/>"
5288
5543
            "<menuitem action='Preferences'/>"
5289
5544
            "<menuitem action='InspectPage'/>"
5290
5545
            "<menuitem action='ReloadUncached'/>"
 
5546
            #if WEBKIT_CHECK_VERSION (1, 1, 6)
 
5547
            "<menuitem action='CaretBrowsing'/>"
 
5548
            #endif
5291
5549
            "</menu>"
5292
5550
        "</menubar>"
5293
5551
        "<toolbar name='toolbar_navigation'>"
5373
5631
midori_browser_set_history (MidoriBrowser* browser,
5374
5632
                            KatzeArray*    history)
5375
5633
{
5376
 
    time_t now;
5377
 
    gint64 day;
5378
 
 
5379
5634
    if (browser->history == history)
5380
5635
        return;
5381
5636
 
5394
5649
    g_signal_connect (browser->history, "clear",
5395
5650
                      G_CALLBACK (midori_browser_history_clear_cb), browser);
5396
5651
 
5397
 
    now = time (NULL);
5398
 
    day = sokoke_time_t_to_julian (&now);
5399
 
 
5400
5652
    g_object_set (_action_by_name (browser, "Location"), "history",
5401
5653
                  browser->history, NULL);
5402
5654
}
5415
5667
        MidoriBrowser* browser;
5416
5668
        GtkWidget* view;
5417
5669
 
 
5670
        /* Switch to n-th tab. 9 and 0 go to the last tab. */
5418
5671
        n = keyval - GDK_0;
5419
 
        if (n == 0)
5420
 
            n = 10;
5421
5672
        browser = g_object_get_data (G_OBJECT (accel_group), "midori-browser");
5422
5673
        if ((view = gtk_notebook_get_nth_page (GTK_NOTEBOOK (browser->notebook),
5423
 
                                          n - 1)))
 
5674
                                               n < 9 ? n - 1 : -1)))
5424
5675
            midori_browser_set_current_tab (browser, view);
5425
5676
    }
5426
5677
}
5514
5765
    GtkUIManager* ui_manager;
5515
5766
    GtkAccelGroup* accel_group;
5516
5767
    guint i;
 
5768
    GClosure* accel_closure;
5517
5769
    GError* error;
5518
5770
    GtkAction* action;
5519
5771
    #if !HAVE_HILDON
5533
5785
    browser->bookmarks = NULL;
5534
5786
    browser->trash = NULL;
5535
5787
    browser->search_engines = NULL;
 
5788
    browser->speeddial = NULL;
5536
5789
 
5537
5790
    /* Setup the window metrics */
5538
5791
    g_signal_connect (browser, "realize",
5570
5823
    gtk_ui_manager_insert_action_group (ui_manager, browser->action_group, 0);
5571
5824
 
5572
5825
    g_object_set_data (G_OBJECT (accel_group), "midori-browser", browser);
 
5826
    accel_closure = g_cclosure_new (G_CALLBACK (
 
5827
        midori_browser_accel_switch_tab_activate_cb), browser, NULL);
5573
5828
    for (i = 0; i < 10; i++)
5574
5829
    {
5575
5830
        gchar* accel_path = g_strdup_printf ("<Manual>/Browser/SwitchTab%d", i);
5576
 
        GClosure* closure = g_cclosure_new (
5577
 
            G_CALLBACK (midori_browser_accel_switch_tab_activate_cb),
5578
 
            browser, NULL);
5579
5831
        gtk_accel_map_add_entry (accel_path, GDK_0 + i, GDK_MOD1_MASK);
5580
 
        gtk_accel_group_connect_by_path (accel_group, accel_path, closure);
 
5832
        gtk_accel_group_connect_by_path (accel_group, accel_path, accel_closure);
5581
5833
        g_free (accel_path);
5582
5834
    }
 
5835
    g_closure_unref (accel_closure);
5583
5836
 
5584
5837
    error = NULL;
5585
5838
    if (!gtk_ui_manager_add_ui_from_string (ui_manager, ui_markup, -1, &error))
5607
5860
    g_object_connect (action,
5608
5861
                      "signal::activate",
5609
5862
                      _action_location_activate, browser,
5610
 
                      "signal::active-changed",
5611
 
                      _action_location_active_changed, browser,
5612
5863
                      "signal::focus-in",
5613
5864
                      _action_location_focus_in, browser,
5614
5865
                      "signal::focus-out",
5846
6097
    g_signal_connect (hpaned, "notify::position",
5847
6098
                      G_CALLBACK (midori_panel_notify_position_cb),
5848
6099
                      browser);
 
6100
    g_signal_connect (hpaned, "cycle-child-focus",
 
6101
                      G_CALLBACK (midori_panel_cycle_child_focus_cb),
 
6102
                      browser);
5849
6103
    gtk_box_pack_start (GTK_BOX (vbox), hpaned, TRUE, TRUE, 0);
5850
6104
    gtk_widget_show (hpaned);
5851
6105
    browser->panel = g_object_new (MIDORI_TYPE_PANEL,
5886
6140
    g_signal_connect (browser->notebook, "page-reordered",
5887
6141
                      G_CALLBACK (midori_browser_notebook_page_reordered_cb),
5888
6142
                      browser);
 
6143
    g_signal_connect (browser->notebook, "size-allocate",
 
6144
                      G_CALLBACK (gtk_notebook_size_allocated_cb),
 
6145
                      browser);
5889
6146
    g_signal_connect_after (browser->notebook, "button-press-event",
5890
6147
        G_CALLBACK (midori_browser_notebook_button_press_event_after_cb),
5891
6148
                      browser);
 
6149
    g_signal_connect (browser->notebook, "reorder-tab",
 
6150
                      G_CALLBACK (midori_browser_notebook_reorder_tab_cb), NULL);
5892
6151
    gtk_widget_show (browser->notebook);
5893
6152
 
5894
6153
    /* Inspector container */
5977
6236
    katze_object_assign (browser->trash, NULL);
5978
6237
    katze_object_assign (browser->search_engines, NULL);
5979
6238
    katze_object_assign (browser->history, NULL);
 
6239
    browser->speeddial = NULL;
5980
6240
 
5981
6241
    katze_assign (browser->news_aggregator, NULL);
5982
6242
 
6098
6358
    gboolean show_panel;
6099
6359
    MidoriToolbarStyle toolbar_style;
6100
6360
    gchar* toolbar_items;
6101
 
    gint last_web_search;
6102
6361
    gboolean close_buttons_on_tabs;
6103
6362
    KatzeItem* item;
6104
6363
 
 
6364
    g_free (browser->location_entry_search);
6105
6365
    g_free (browser->news_aggregator);
6106
6366
 
6107
6367
    g_object_get (browser->settings,
6120
6380
                  "show-bookmarkbar", &show_bookmarkbar,
6121
6381
                  "show-panel", &show_panel,
6122
6382
                  "show-statusbar", &browser->show_statusbar,
6123
 
                  "speed-dial-in-new-tabs", &browser->speed_dial_in_new_tabs,
6124
6383
                  "toolbar-style", &toolbar_style,
6125
6384
                  "toolbar-items", &toolbar_items,
6126
 
                  "last-web-search", &last_web_search,
6127
6385
                  "location-entry-search", &browser->location_entry_search,
6128
6386
                  "close-buttons-on-tabs", &close_buttons_on_tabs,
6129
6387
                  "maximum-history-age", &browser->maximum_history_age,
6171
6429
    if (browser->search_engines)
6172
6430
    {
6173
6431
        item = katze_array_get_nth_item (browser->search_engines,
6174
 
                                         last_web_search);
 
6432
                                         browser->last_web_search);
6175
6433
        if (item)
6176
6434
            midori_search_action_set_current_item (MIDORI_SEARCH_ACTION (
6177
6435
                _action_by_name (browser, "Search")), item);
6254
6512
        browser->show_navigationbar = g_value_get_boolean (&value);
6255
6513
    else if (name == g_intern_string ("show-statusbar"))
6256
6514
        browser->show_statusbar = g_value_get_boolean (&value);
6257
 
    else if (name == g_intern_string ("speed-dial-in-new-tabs"))
6258
 
        browser->speed_dial_in_new_tabs = g_value_get_boolean (&value);
6259
6515
    else if (name == g_intern_string ("search-engines-in-completion"))
6260
6516
    {
6261
6517
        if (g_value_get_boolean (&value))
6407
6663
                                                 GParamSpec*        pspec,
6408
6664
                                                 MidoriBrowser*     browser)
6409
6665
{
6410
 
    gboolean show_bookmarkbar;
6411
 
 
6412
 
    g_object_get (browser->settings, "show-bookmarkbar",
6413
 
                  &show_bookmarkbar, NULL);
6414
 
 
6415
 
    if (!show_bookmarkbar)
 
6666
    if (!katze_object_get_boolean (browser->settings, "show-bookmarkbar"))
6416
6667
        midori_bookmarkbar_clear (browser->bookmarkbar);
6417
6668
    else
6418
6669
        midori_bookmarkbar_populate (browser);
6466
6717
                             GParamSpec*   pspec)
6467
6718
{
6468
6719
    MidoriBrowser* browser = MIDORI_BROWSER (object);
6469
 
    guint last_web_search;
6470
6720
    KatzeItem* item;
6471
6721
 
6472
6722
    switch (prop_id)
6525
6775
 
6526
6776
        if (browser->search_engines)
6527
6777
        {
6528
 
            g_object_get (browser->settings, "last-web-search", &last_web_search, NULL);
6529
 
            item = katze_array_get_nth_item (browser->search_engines, last_web_search);
 
6778
            g_object_get (browser->settings, "last-web-search", &browser->last_web_search, NULL);
 
6779
            item = katze_array_get_nth_item (browser->search_engines, browser->last_web_search);
6530
6780
            midori_search_action_set_current_item (MIDORI_SEARCH_ACTION (
6531
6781
                _action_by_name (browser, "Search")), item);
6532
6782
 
6543
6793
    case PROP_HISTORY:
6544
6794
        midori_browser_set_history (browser, g_value_get_object (value));
6545
6795
        break;
 
6796
    case PROP_SPEED_DIAL:
 
6797
        browser->speeddial = g_value_get_pointer (value);
 
6798
        break;
6546
6799
    case PROP_SHOW_TABS:
6547
6800
        browser->show_tabs = g_value_get_boolean (value);
6548
6801
        if (browser->show_tabs)
6618
6871
    case PROP_HISTORY:
6619
6872
        g_value_set_object (value, browser->history);
6620
6873
        break;
 
6874
    case PROP_SPEED_DIAL:
 
6875
        g_value_set_pointer (value, browser->speeddial);
 
6876
        break;
6621
6877
    case PROP_SHOW_TABS:
6622
6878
        g_value_set_boolean (value, browser->show_tabs);
6623
6879
        break;
6714
6970
    title = katze_item_get_name (item);
6715
6971
    view = midori_view_new_with_title (title, browser->settings,
6716
6972
        g_object_get_data (G_OBJECT (item), "midori-view-append") ? TRUE : FALSE);
 
6973
 
 
6974
    proxy_item = midori_view_get_proxy_item (MIDORI_VIEW (view));
 
6975
 
 
6976
    if (katze_item_get_meta_boolean (item, "dont-write-history"))
 
6977
        katze_item_set_meta_integer (proxy_item, "dont-write-history", 1);
 
6978
 
6717
6979
    page = midori_browser_add_tab (browser, view);
6718
6980
 
6719
6981
    /* Blank pages should not be delayed */
6720
6982
    if (katze_item_get_meta_integer (item, "delay") > 0
6721
 
     && strcmp (uri, "about:blank") != 0)
 
6983
     && strcmp (uri, "about:blank") != 0
 
6984
     && strncmp (uri, "pause:", 6) != 0)
6722
6985
    {
6723
6986
        gchar* new_uri = g_strdup_printf ("pause:%s", uri);
6724
6987
        midori_view_set_uri (MIDORI_VIEW (view), new_uri);
6791
7054
    g_return_if_fail (name != NULL);
6792
7055
 
6793
7056
    _action_set_visible (browser, name, visible);
6794
 
}
 
7057
    _action_set_sensitive (browser, name, visible);
 
7058
}
 
7059
 
 
7060
/**
 
7061
 * midori_browser_block_action:
 
7062
 * @browser: a #MidoriBrowser
 
7063
 * @name: the action to be blocked
 
7064
 *
 
7065
 * Blocks built-in behavior of the specified action without
 
7066
 * disabling it, which gives you a chance to connect your
 
7067
 * own signal handling.
 
7068
 * Call midori_browser_unblock_action() to undo the effect.
 
7069
 *
 
7070
 * Since: 0.3.4
 
7071
 **/
 
7072
void
 
7073
midori_browser_block_action (MidoriBrowser* browser,
 
7074
                             GtkAction*     action)
 
7075
{
 
7076
    const gchar* name;
 
7077
    guint i;
 
7078
 
 
7079
    g_return_if_fail (MIDORI_IS_BROWSER (browser));
 
7080
    g_return_if_fail (GTK_IS_ACTION (action));
 
7081
 
 
7082
    name = gtk_action_get_name (action);
 
7083
    for (i = 0; i < entries_n; i++)
 
7084
        if (g_str_equal (entries[i].name, name))
 
7085
        {
 
7086
            g_signal_handlers_block_by_func (action, entries[i].callback, browser);
 
7087
            return;
 
7088
        }
 
7089
    g_critical ("%s: Action \"%s\" can't be blocked.", G_STRFUNC, name);
 
7090
}
 
7091
 
 
7092
/**
 
7093
 * midori_browser_unblock_action:
 
7094
 * @browser: a #MidoriBrowser
 
7095
 * @name: the action to be unblocked
 
7096
 *
 
7097
 * Restores built-in behavior of the specified action after
 
7098
 * previously blocking it with midori_browser_block_action().
 
7099
 *
 
7100
 * Since: 0.3.4
 
7101
 **/
 
7102
void
 
7103
midori_browser_unblock_action (MidoriBrowser* browser,
 
7104
                               GtkAction*     action)
 
7105
{
 
7106
    const gchar* name;
 
7107
    guint i;
 
7108
 
 
7109
    g_return_if_fail (MIDORI_IS_BROWSER (browser));
 
7110
    g_return_if_fail (GTK_IS_ACTION (action));
 
7111
 
 
7112
    name = gtk_action_get_name (action);
 
7113
    for (i = 0; i < entries_n; i++)
 
7114
        if (g_str_equal (entries[i].name, name))
 
7115
        {
 
7116
            g_signal_handlers_unblock_by_func (action, entries[i].callback, browser);
 
7117
            return;
 
7118
        }
 
7119
    g_critical ("%s: Action \"%s\" can't be unblocked.", G_STRFUNC, name);
 
7120
}
 
7121
 
6795
7122
 
6796
7123
/**
6797
7124
 * midori_browser_get_action_group:
6955
7282
        gtk_action_activate (_action_by_name (browser, "Location"));
6956
7283
    else
6957
7284
        gtk_widget_grab_focus (view);
 
7285
 
 
7286
    g_object_freeze_notify (G_OBJECT (browser));
 
7287
    g_object_notify (G_OBJECT (browser), "uri");
 
7288
    g_object_notify (G_OBJECT (browser), "tab");
 
7289
    g_object_thaw_notify (G_OBJECT (browser));
6958
7290
}
6959
7291
 
6960
7292
/**