Imported Upstream version 0.2.2
This commit is contained in:
parent
79bb58a7fe
commit
67e400912e
76 changed files with 21903 additions and 12382 deletions
12
.gitignore
vendored
Normal file
12
.gitignore
vendored
Normal file
|
@ -0,0 +1,12 @@
|
|||
Makefile
|
||||
|
||||
.waf-*
|
||||
.lock-wscript
|
||||
_build_
|
||||
|
||||
po/.intltool-merge-cache
|
||||
po/POTFILES
|
||||
po/stamp-it
|
||||
po/*.gmo
|
||||
|
||||
midori.desktop
|
1
AUTHORS
1
AUTHORS
|
@ -52,6 +52,7 @@ Translations:
|
|||
it: Luca Perri <kurama_luka@yahoo.it>
|
||||
ja: Masato Hashimoto <cabezon.hashimoto@gmail.com>
|
||||
nl: Vincent Tunru <projects@vinnl.nl>
|
||||
no: Olav Andreas Lindekleiv <olalinde@gmail.com>
|
||||
pl: Przemysław Sitek <el.pescado@gazeta.pl>
|
||||
pl: Lukasz Romanowicz <romanowicz88@gmail.com>
|
||||
pt_PT: Sérgio Marques <smarquespt@gmail.com>
|
||||
|
|
44
ChangeLog
44
ChangeLog
|
@ -1,5 +1,49 @@
|
|||
This file is licensed under the terms of the expat license, see the file EXPAT.
|
||||
|
||||
v0.2.2
|
||||
+ Turn libnotify into a proper build-time dependency
|
||||
+ Use Ctrl + Return to open tabs from the location entry
|
||||
+ Support right-click on bookmark menu items
|
||||
+ Support -e in midori -a and with multiple commands
|
||||
+ Make Middle click open selection search if needed
|
||||
+ Make Ctrl+C work as expected again
|
||||
+ Fix order of History, Trash and Recently opened pages
|
||||
+ Revise Shortcuts dialogue to fix oddities
|
||||
+ Perform Form history completion case insensitive
|
||||
+ Add 'Web Cache' to Delete Private data dialogue
|
||||
+ Load accels from /etc/xdg if present
|
||||
+ Improve XBEL format compatibility and performance
|
||||
+ Fix inline find by correcting key handling
|
||||
+ Add option to open panels in separate windows
|
||||
+ Support Portrait orientation in Fremantle
|
||||
+ Support Hildon MIME and URI handling
|
||||
+ Check status before caching in Web Cache
|
||||
+ Show popup menu on news feed icon if needed
|
||||
+ Support Colourful Tabs with Tab Panel
|
||||
+ Tweak sqlite and dbus handling for Win32
|
||||
+ 'Run as web app' and 'Show in toolbar' for bookmarks
|
||||
+ Add 'Small icons' toolbar style
|
||||
+ Fix build with Glib < 2.20 and GTK+ < 2.12
|
||||
+ Add Import bookmarks for XBEL, Opera and RDF
|
||||
+ Add Open Link in Foreground/ Background Tab menu
|
||||
+ Allow closing all tabs
|
||||
+ Hildon file chooser support
|
||||
|
||||
v0.2.1
|
||||
+ Fix Mouse Gestures to work after activation
|
||||
+ Explicitly link to X11 to support gold
|
||||
+ Implement various Hildon specific features
|
||||
+ Hide the navigationbar in fullscreen
|
||||
+ Implement permanent storage of form history
|
||||
+ Support keyboard shortcuts like Ctrl+Tab or "a"
|
||||
+ Handle SIGHUP, SIGINT, SIGTERM and SIGQUIT
|
||||
+ Make creation of new windows fast
|
||||
+ Introduce the Tab History List extension
|
||||
+ Load icons laziy at startup to speed up startup
|
||||
+ Introduce a Web Cache extension
|
||||
+ Refactor and tweak the Preferences dialogue
|
||||
+ Implement combos to choose external applications
|
||||
|
||||
v0.2.0
|
||||
+ (Kinetic) drag scrolling on touchscreen devices
|
||||
+ Workaround a speed dial crasher
|
||||
|
|
10
INSTALL
10
INSTALL
|
@ -16,8 +16,8 @@ You can now run Midori from the build folder like so
|
|||
|
||||
'./waf build --run'
|
||||
|
||||
This is a convenience that will load extensions as well as
|
||||
localizations from the build folder.
|
||||
Using --run as shown above will make sure extensions as well as
|
||||
localizations are used from the build folder.
|
||||
|
||||
You can install it with './waf install'
|
||||
|
||||
|
@ -51,6 +51,12 @@ If you are interested in HTTP communication, try this:
|
|||
|
||||
Where '2' can be a level between 0 and 3.
|
||||
|
||||
If you are interested in (non-) touchscreen behaviour, try this:
|
||||
|
||||
'MIDORI_TOUCHSCREEN=1 _build_/default/midori/midori', or
|
||||
|
||||
'MIDORI_TOUCHSCREEN=0 _build_/default/midori/midori'
|
||||
|
||||
For further information a tutorial for gdb and
|
||||
reading up on how you can install debugging
|
||||
symbols for libraries used by Midori are recommended.
|
||||
|
|
4
TODO
4
TODO
|
@ -3,10 +3,8 @@ This file is licensed under the terms of the expat license, see the file EXPAT.
|
|||
TODO:
|
||||
. Use an update timeout in KatzePropertyProxy instead of only focus-out
|
||||
. Show a loading mouse pointer
|
||||
. Scroll tabs w/o switching tabs
|
||||
. Import and export of the bookmarks file, or using one from a specific path
|
||||
. Custom context menu actions, like in Thunar or Epiphany
|
||||
. Custom tab names
|
||||
. Analogus to blocked popups, blocked scripts moving layers on load (extension)
|
||||
. Per-site blocking of individual elements on a page
|
||||
. Statusbar icon 'cookies blocked', icon 'popups blocked'
|
||||
|
@ -17,7 +15,6 @@ TODO:
|
|||
. Mark (dogear) a selection so that it isn't cleared implicitly, multiply on one page
|
||||
. Have an internal uri scheme, eg. 'res:', to reference eg. themed icons
|
||||
. 'about:' uris: about, blank, cache, config, plugins
|
||||
. Panel of open tabs (with tree-structure), optional thumbnail-view
|
||||
. Check specific bookmarks for updates automatically (extension)
|
||||
. Mark "new" as well as "actually modified" tabs specially (even over sessions)
|
||||
. SearchEngine: "Show in context menu"
|
||||
|
@ -32,7 +29,6 @@ TODO:
|
|||
. Style: none, compatible (b/w), default, [styles], "media", ["media" styles], ...
|
||||
. Mouse pointer coordinates in the status bar (extension)
|
||||
. Draw rectangle with the mouse, x/y/x2/y2 in the statusbar (extension)
|
||||
. Formfill (like Opera's magic wand)
|
||||
. Private browsing mode (no browsing, download or search history)
|
||||
. Shared bookmarks and config
|
||||
. Custom-mode, e.g. hide menubar and use help icon to have a help viewer
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
/**
|
||||
* An autosuggest textbox control.
|
||||
* from Nicholas C. Zakas (Author) example: http://www.nczonline.net/
|
||||
* @class
|
||||
* @scope public
|
||||
* Adopted for Midori by Alexander V. Butenko <a.butenka@gmail.com>
|
||||
*/
|
||||
|
||||
function AutoSuggestControl(oTextbox /*:HTMLInputElement*/,
|
||||
oProvider /*:SuggestionProvider*/) {
|
||||
/**
|
||||
|
@ -28,7 +28,6 @@ function AutoSuggestControl(oTextbox /*:HTMLInputElement*/,
|
|||
this.textbox /*:HTMLInputElement*/ = oTextbox;
|
||||
//initialize the control
|
||||
this.init();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -38,13 +37,9 @@ function AutoSuggestControl(oTextbox /*:HTMLInputElement*/,
|
|||
* @param aSuggestions An array of suggestion strings.
|
||||
* @param bTypeAhead If the control should provide a type ahead suggestion.
|
||||
*/
|
||||
AutoSuggestControl.prototype.autosuggest = function (aSuggestions /*:Array*/,
|
||||
bTypeAhead /*:boolean*/) {
|
||||
AutoSuggestControl.prototype.autosuggest = function (aSuggestions /*:Array*/) {
|
||||
//make sure theres at least one suggestion
|
||||
if (aSuggestions.length > 0) {
|
||||
if (bTypeAhead) {
|
||||
this.typeAhead(aSuggestions[0]);
|
||||
}
|
||||
this.showSuggestions(aSuggestions);
|
||||
} else {
|
||||
this.hideSuggestions();
|
||||
|
@ -56,17 +51,14 @@ AutoSuggestControl.prototype.autosuggest = function (aSuggestions /*:Array*/,
|
|||
* @scope private
|
||||
*/
|
||||
AutoSuggestControl.prototype.createDropDown = function () {
|
||||
|
||||
var oThis = this;
|
||||
|
||||
//create the layer and assign styles
|
||||
this.layer = document.createElement("div");
|
||||
this.layer.className = "suggestions";
|
||||
this.layer.style.visibility = "hidden";
|
||||
this.layer.style.width = this.textbox.offsetWidth + 10;
|
||||
this.layer.style.width = this.textbox.offsetWidth;
|
||||
|
||||
//when the user clicks on the a suggestion, get the text (innerHTML)
|
||||
//and place it into a textbox
|
||||
this.layer.onmousedown =
|
||||
this.layer.onmouseup =
|
||||
this.layer.onmouseover = function (oEvent) {
|
||||
|
@ -82,8 +74,6 @@ AutoSuggestControl.prototype.createDropDown = function () {
|
|||
oThis.textbox.focus();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
document.body.appendChild(this.layer);
|
||||
};
|
||||
|
||||
|
@ -93,7 +83,6 @@ AutoSuggestControl.prototype.createDropDown = function () {
|
|||
* @return The left coordinate of the textbox in pixels.
|
||||
*/
|
||||
AutoSuggestControl.prototype.getLeft = function () /*:int*/ {
|
||||
|
||||
var oNode = this.textbox;
|
||||
var iLeft = 0;
|
||||
|
||||
|
@ -148,8 +137,7 @@ AutoSuggestControl.prototype.handleKeyUp = function (oEvent /*:Event*/) {
|
|||
var iKeyCode = oEvent.keyCode;
|
||||
//for backspace (8) and delete (46), shows suggestions without typeahead
|
||||
if (iKeyCode == 8 || iKeyCode == 46) {
|
||||
this.provider.requestSuggestions(this, false);
|
||||
|
||||
this.provider.requestSuggestions(this);
|
||||
//make sure not to interfere with non-character keys
|
||||
} else if (iKeyCode < 32 || (iKeyCode >= 33 && iKeyCode < 46) || (iKeyCode >= 112 && iKeyCode <= 123) ) {
|
||||
//ignore
|
||||
|
@ -158,11 +146,8 @@ AutoSuggestControl.prototype.handleKeyUp = function (oEvent /*:Event*/) {
|
|||
this.hideSuggestions();
|
||||
} else {
|
||||
//request suggestions from the suggestion provider with typeahead
|
||||
this.provider.requestSuggestions(this, true);
|
||||
this.provider.requestSuggestions(this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -195,44 +180,35 @@ AutoSuggestControl.prototype.highlightSuggestion = function (oSuggestionNode) {
|
|||
* @scope private
|
||||
*/
|
||||
AutoSuggestControl.prototype.init = function () {
|
||||
|
||||
//save a reference to this object
|
||||
var oThis = this;
|
||||
|
||||
//assign the onkeyup event handler
|
||||
this.textbox.onkeyup = function (oEvent) {
|
||||
|
||||
//check for the proper location of the event object
|
||||
if (!oEvent) {
|
||||
oEvent = window.event;
|
||||
}
|
||||
|
||||
//call the handleKeyUp() method with the event object
|
||||
oThis.handleKeyUp(oEvent);
|
||||
};
|
||||
|
||||
//assign onkeydown event handler
|
||||
this.textbox.onkeydown = function (oEvent) {
|
||||
|
||||
//check for the proper location of the event object
|
||||
if (!oEvent) {
|
||||
oEvent = window.event;
|
||||
}
|
||||
|
||||
//call the handleKeyDown() method with the event object
|
||||
oThis.handleKeyDown(oEvent);
|
||||
};
|
||||
|
||||
//assign onblur event handler (hides suggestions)
|
||||
this.textbox.onblur = function () {
|
||||
oThis.hideSuggestions();
|
||||
};
|
||||
|
||||
this.textbox.onblur =
|
||||
this.textbox.onclick = function () {
|
||||
oThis.hideSuggestions();
|
||||
};
|
||||
|
||||
|
||||
//create the suggestions dropdown
|
||||
this.createDropDown();
|
||||
};
|
||||
|
@ -274,20 +250,9 @@ AutoSuggestControl.prototype.previousSuggestion = function () {
|
|||
* @param iLength The number of characters to select.
|
||||
*/
|
||||
AutoSuggestControl.prototype.selectRange = function (iStart /*:int*/, iLength /*:int*/) {
|
||||
|
||||
//use text ranges for Internet Explorer
|
||||
if (this.textbox.createTextRange) {
|
||||
var oRange = this.textbox.createTextRange();
|
||||
oRange.moveStart("character", iStart);
|
||||
oRange.moveEnd("character", iLength - this.textbox.value.length);
|
||||
oRange.select();
|
||||
|
||||
//use setSelectionRange() for Mozilla
|
||||
} else if (this.textbox.setSelectionRange) {
|
||||
if (this.textbox.setSelectionRange) {
|
||||
this.textbox.setSelectionRange(iStart, iLength);
|
||||
}
|
||||
|
||||
//set focus back to the textbox
|
||||
this.textbox.focus();
|
||||
};
|
||||
|
||||
|
@ -298,7 +263,6 @@ AutoSuggestControl.prototype.selectRange = function (iStart /*:int*/, iLength /*
|
|||
* @param aSuggestions An array of suggestions for the control.
|
||||
*/
|
||||
AutoSuggestControl.prototype.showSuggestions = function (aSuggestions /*:Array*/) {
|
||||
|
||||
var oDiv = null;
|
||||
this.layer.innerHTML = ""; //clear contents of the layer
|
||||
|
||||
|
@ -311,53 +275,35 @@ AutoSuggestControl.prototype.showSuggestions = function (aSuggestions /*:Array*/
|
|||
this.layer.style.left = this.getLeft() + "px";
|
||||
this.layer.style.top = (this.getTop()+this.textbox.offsetHeight) + "px";
|
||||
this.layer.style.visibility = "visible";
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Inserts a suggestion into the textbox, highlighting the
|
||||
* suggested part of the text.
|
||||
* @scope private
|
||||
* @param sSuggestion The suggestion for the textbox.
|
||||
*/
|
||||
AutoSuggestControl.prototype.typeAhead = function (sSuggestion /*:String*/) {
|
||||
|
||||
//check for support of typeahead functionality
|
||||
if (this.textbox.createTextRange || this.textbox.setSelectionRange){
|
||||
var iLen = this.textbox.value.length;
|
||||
this.textbox.value = sSuggestion;
|
||||
this.selectRange(iLen, sSuggestion.length);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Request suggestions for the given autosuggest control.
|
||||
* @scope protected
|
||||
* @param oAutoSuggestControl The autosuggest control to provide suggestions for.
|
||||
*/
|
||||
FormSuggestions.prototype.requestSuggestions = function (oAutoSuggestControl /*:AutoSuggestControl*/,
|
||||
bTypeAhead /*:boolean*/) {
|
||||
FormSuggestions.prototype.requestSuggestions = function (oAutoSuggestControl /*:AutoSuggestControl*/) {
|
||||
var aSuggestions = [];
|
||||
var sTextboxValue = oAutoSuggestControl.textbox.value;
|
||||
var sTextboxValue = oAutoSuggestControl.textbox.value.toLowerCase();
|
||||
|
||||
if (!this.suggestions)
|
||||
return;
|
||||
if (!sTextboxValue.length)
|
||||
return;
|
||||
|
||||
if (sTextboxValue.length > 0){
|
||||
//search for matching suggestions
|
||||
for (var i=0; i < this.suggestions.length; i++) {
|
||||
if (this.suggestions[i].indexOf(sTextboxValue) == 0) {
|
||||
if (this.suggestions[i].toLowerCase().indexOf(sTextboxValue) == 0) {
|
||||
aSuggestions.push(this.suggestions[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
//provide suggestions to the control
|
||||
oAutoSuggestControl.autosuggest(aSuggestions, bTypeAhead);
|
||||
oAutoSuggestControl.autosuggest(aSuggestions);
|
||||
};
|
||||
|
||||
function initSuggestions () {
|
||||
var inputs = document.getElementsByTagName("input");
|
||||
|
||||
for (i=0;i<inputs.length;i++)
|
||||
{
|
||||
var ename = inputs[i].getAttribute("name");
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
.. |(version)| replace:: 0.1.6
|
||||
.. |(version)| replace:: 0.2.2
|
||||
|
||||
'''''''
|
||||
Midori
|
||||
|
@ -9,7 +9,7 @@
|
|||
-----------------------------------------
|
||||
|
||||
:Authors: Christian Dywan
|
||||
:Date: $Date: 2009-04-14 18:00:35 +0100 (Tue, 14 Apr 2009) $
|
||||
:Date: $Date: 2009-11-18 18:20:11 +0100 (Wed, 18 Nov 2009) $
|
||||
:Version: |(version)|
|
||||
|
||||
Copyright © 2008-2009
|
||||
|
@ -132,6 +132,8 @@ The following arguments are supported if you call Midori from a command line.
|
|||
+-------+--------------------+------------------------------------------------+
|
||||
| -r | --run | Run the specified filename as javascript |
|
||||
+-------+--------------------+------------------------------------------------+
|
||||
| -s | --snapshot + Take a snapshot of the specified URI |
|
||||
+-------+--------------------+------------------------------------------------+
|
||||
| -V | --version | Show version information and exit. |
|
||||
+-------+--------------------+------------------------------------------------+
|
||||
|
||||
|
@ -159,8 +161,12 @@ The files stored in the primary configuration folder are the following:
|
|||
+----------------+------------------------------------------------------------+
|
||||
| history.db | History, sqlite3 |
|
||||
+----------------+------------------------------------------------------------+
|
||||
| logins | Usernames and passwords, plain text |
|
||||
+----------------+------------------------------------------------------------+
|
||||
| running | A file created to track whether Midori quit cleanly |
|
||||
+----------------+------------------------------------------------------------+
|
||||
| search | Search engines, text key file |
|
||||
+----------------+------------------------------------------------------------+
|
||||
| session.xbel | The current or last session, ie. open tabs, |
|
||||
+----------------+------------------------------------------------------------+
|
||||
| tabtrash.xbel | The 10 last closed tabs |
|
||||
|
@ -173,10 +179,6 @@ replace the 'bookmarks.xbel' as long as it is valid XBEL/ XML.
|
|||
Currently while Midori is running it will happily overwrite files as needed and
|
||||
never read back any changes.
|
||||
|
||||
Incidentally Midori will recognize readonly files and not write modifications
|
||||
to readonly files back to disk. This can be useful for kiosk systems where
|
||||
particular changes shouldn't be saved.
|
||||
|
||||
|
||||
Keyboard shortcuts
|
||||
------------------
|
||||
|
@ -190,9 +192,8 @@ The navigationbar
|
|||
|
||||
|
||||
The navigationbar is the primary toolbar containing notably back and forward
|
||||
buttons, the location entry and a search entry. Except for the location entry
|
||||
any item can be removed and others can be added by right-clicking the toolbar
|
||||
and using the Add and Remove menu items.
|
||||
buttons, the location entry and a search entry. The "Toolbar Editor" extension
|
||||
can be used to add or remove items.
|
||||
|
||||
|
||||
The sidepanel
|
||||
|
|
|
@ -26,13 +26,47 @@
|
|||
(__filter && (g_str_has_prefix (__filter, "http") \
|
||||
|| g_str_has_prefix (__filter, "file")))
|
||||
|
||||
typedef struct
|
||||
{
|
||||
const gchar* page_uri;
|
||||
const gchar* uri;
|
||||
const gchar* query;
|
||||
} Matcher;
|
||||
|
||||
static GHashTable* pattern;
|
||||
static gchar* blockcss = NULL;
|
||||
static gchar* blockcssprivate = NULL;
|
||||
static gchar* blockscript = NULL;
|
||||
|
||||
static void
|
||||
adblock_parse_file (gchar* path);
|
||||
|
||||
static gchar*
|
||||
adblock_build_js (const gchar* style,
|
||||
const gchar* private)
|
||||
{
|
||||
return g_strdup_printf (
|
||||
"window.addEventListener ('DOMContentLoaded',"
|
||||
"function () {"
|
||||
" var URL = location.href;"
|
||||
" var sites = new Array(); %s;"
|
||||
" var public = '%s';"
|
||||
" for (var i in sites) {"
|
||||
" if (URL.indexOf(i) != -1) {"
|
||||
" public += sites[i];"
|
||||
" break;"
|
||||
" }}"
|
||||
" public += ' {display: none !important;}';"
|
||||
" var mystyle = document.createElement('style');"
|
||||
" mystyle.setAttribute('type', 'text/css');"
|
||||
" mystyle.appendChild(document.createTextNode(public));"
|
||||
" var head = document.getElementsByTagName('head')[0];"
|
||||
" if (head) head.appendChild(mystyle);"
|
||||
"}, true);",
|
||||
private,
|
||||
style);
|
||||
}
|
||||
|
||||
static gchar *
|
||||
adblock_fixup_regexp (gchar* src)
|
||||
{
|
||||
|
@ -45,10 +79,6 @@ adblock_fixup_regexp (gchar* src)
|
|||
/* FIXME: Avoid always allocating twice the string */
|
||||
s = dst = g_malloc (strlen (src) * 2);
|
||||
|
||||
/* |http:// means ^http:// */
|
||||
if (src[0] == '|')
|
||||
src[0] = '^';
|
||||
|
||||
while (*src)
|
||||
{
|
||||
switch (*src)
|
||||
|
@ -65,6 +95,12 @@ adblock_fixup_regexp (gchar* src)
|
|||
case '|':
|
||||
*s++ = '\\';
|
||||
break;
|
||||
/* FIXME: We actually need to match :[0-9]+ or '/'. Sign means
|
||||
"here could be port number or nothing". So bla.com^ will match
|
||||
bla.com/ or bla.com:8080/ but not bla.com.au/ */
|
||||
case '^':
|
||||
*src = '?';
|
||||
break;
|
||||
}
|
||||
*s++ = *src;
|
||||
src++;
|
||||
|
@ -102,7 +138,8 @@ adblock_reload_rules (MidoriExtension* extension)
|
|||
pattern = g_hash_table_new_full (g_str_hash, g_str_equal,
|
||||
(GDestroyNotify)g_free,
|
||||
(GDestroyNotify)g_regex_unref);
|
||||
katze_assign (blockcss, NULL);
|
||||
katze_assign (blockcss, g_strdup ("z-non-exist"));
|
||||
katze_assign (blockcssprivate, g_strdup (""));
|
||||
|
||||
while (filters[i++] != NULL)
|
||||
{
|
||||
|
@ -130,6 +167,7 @@ adblock_reload_rules (MidoriExtension* extension)
|
|||
}
|
||||
g_free (filename);
|
||||
}
|
||||
katze_assign (blockscript, adblock_build_js (blockcss, blockcssprivate));
|
||||
g_strfreev (filters);
|
||||
g_free (folder);
|
||||
}
|
||||
|
@ -265,6 +303,26 @@ adblock_preferences_add_clicked_cb (GtkWidget* button,
|
|||
gtk_entry_set_text (entry, "");
|
||||
}
|
||||
|
||||
static void
|
||||
adblock_preferences_edit_clicked_cb (GtkWidget* button,
|
||||
GtkTreeViewColumn* column)
|
||||
{
|
||||
GdkEvent* event = gtk_get_current_event ();
|
||||
GtkTreeView* treeview = g_object_get_data (G_OBJECT (button), "treeview");
|
||||
GtkTreeModel* model;
|
||||
GtkTreeIter iter;
|
||||
if (katze_tree_view_get_selected_iter (treeview, &model, &iter))
|
||||
{
|
||||
gchar* path = gtk_tree_model_get_string_from_iter (model, &iter);
|
||||
GtkTreePath* tree_path = gtk_tree_path_new_from_string (path);
|
||||
/* gtk_cell_renderer_start_editing */
|
||||
gtk_tree_view_set_cursor (treeview, tree_path, column, TRUE);
|
||||
gtk_tree_path_free (tree_path);
|
||||
g_free (path);
|
||||
}
|
||||
gdk_event_free (event);
|
||||
}
|
||||
|
||||
static void
|
||||
adblock_preferences_remove_clicked_cb (GtkWidget* button,
|
||||
GtkTreeView* treeview)
|
||||
|
@ -280,7 +338,11 @@ static gboolean
|
|||
adblock_activate_link_cb (GtkWidget* label,
|
||||
const gchar* uri)
|
||||
{
|
||||
return sokoke_show_uri (gtk_widget_get_screen (label), uri, GDK_CURRENT_TIME, NULL);
|
||||
MidoriBrowser* browser = midori_browser_get_for_widget (label);
|
||||
gint n = midori_browser_add_uri (browser, uri);
|
||||
if (n > -1)
|
||||
midori_browser_set_current_page (browser, n);
|
||||
return n > -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -316,7 +378,9 @@ adblock_get_preferences_dialog (MidoriExtension* extension)
|
|||
dialog = gtk_dialog_new_with_buttons (dialog_title, GTK_WINDOW (browser),
|
||||
GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_NO_SEPARATOR,
|
||||
#if !HAVE_OSX
|
||||
#if !HAVE_HILDON
|
||||
GTK_STOCK_HELP, GTK_RESPONSE_HELP,
|
||||
#endif
|
||||
GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE,
|
||||
#endif
|
||||
NULL);
|
||||
|
@ -417,8 +481,10 @@ adblock_get_preferences_dialog (MidoriExtension* extension)
|
|||
G_CALLBACK (adblock_preferences_add_clicked_cb), liststore);
|
||||
gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
|
||||
button = gtk_button_new_from_stock (GTK_STOCK_EDIT);
|
||||
g_object_set_data (G_OBJECT (button), "treeview", treeview);
|
||||
g_signal_connect (button, "clicked",
|
||||
G_CALLBACK (adblock_preferences_edit_clicked_cb), column);
|
||||
gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
|
||||
gtk_widget_set_sensitive (button, FALSE);
|
||||
button = gtk_button_new_from_stock (GTK_STOCK_REMOVE);
|
||||
g_signal_connect (button, "clicked",
|
||||
G_CALLBACK (adblock_preferences_remove_clicked_cb), treeview);
|
||||
|
@ -488,11 +554,39 @@ adblock_browser_populate_tool_menu_cb (MidoriBrowser* browser,
|
|||
}
|
||||
|
||||
static gboolean
|
||||
adblock_is_matched (const gchar* patt,
|
||||
adblock_is_matched (const gchar* opts,
|
||||
const GRegex* regex,
|
||||
const gchar* uri)
|
||||
Matcher* data)
|
||||
{
|
||||
return g_regex_match_full (regex, uri, -1, 0, 0, NULL, NULL);
|
||||
gchar* patt;
|
||||
|
||||
patt = g_strdup (data->uri);
|
||||
/* TODO: To figure out
|
||||
if (g_regex_match_simple ("type=fulluri,", opts, G_REGEX_UNGREEDY, G_REGEX_MATCH_NOTEMPTY))
|
||||
patt = g_strdup (data->uri);
|
||||
else
|
||||
patt = g_strdup (data->query);
|
||||
*/
|
||||
if (g_regex_match_full (regex, patt, -1, 0, 0, NULL, NULL))
|
||||
{
|
||||
if (g_regex_match_simple (",third-party", opts,
|
||||
G_REGEX_CASELESS, G_REGEX_MATCH_NOTEMPTY))
|
||||
{
|
||||
if (data->page_uri && g_regex_match_full (regex, data->page_uri, -1, 0, 0, NULL, NULL))
|
||||
{
|
||||
g_free (patt);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
/* TODO: Domain opt check */
|
||||
g_free (patt);
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
g_free (patt);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
#if HAVE_WEBKIT_RESOURCE_REQUEST
|
||||
|
@ -502,15 +596,53 @@ adblock_resource_request_starting_cb (WebKitWebView* web_view,
|
|||
WebKitWebResource* web_resource,
|
||||
WebKitNetworkRequest* request,
|
||||
WebKitNetworkResponse* response,
|
||||
MidoriView* view)
|
||||
GtkWidget* image)
|
||||
{
|
||||
const gchar* uri = webkit_network_request_get_uri (request);
|
||||
if (!strncmp (uri, "data", 4))
|
||||
Matcher data;
|
||||
const char *page_uri;
|
||||
const gchar* uri;
|
||||
SoupMessage* msg;
|
||||
SoupURI* soup_uri;
|
||||
|
||||
uri = webkit_network_request_get_uri (request);
|
||||
if (!strncmp (uri, "data", 4) || !strncmp (uri, "file", 4))
|
||||
return;
|
||||
if (g_hash_table_find (pattern, (GHRFunc) adblock_is_matched, (char*)uri))
|
||||
|
||||
msg = webkit_network_request_get_message (request);
|
||||
if (!msg)
|
||||
return;
|
||||
|
||||
if (msg->method && !strncmp (msg->method, "POST", 4))
|
||||
return;
|
||||
|
||||
soup_uri = soup_uri_new (uri);
|
||||
if (soup_uri->query)
|
||||
data.query = g_strdup_printf ("%s?%s", soup_uri->path, soup_uri->query);
|
||||
else
|
||||
data.query = g_strdup (soup_uri->path);
|
||||
soup_uri_free (soup_uri);
|
||||
|
||||
data.uri = uri;
|
||||
page_uri = webkit_web_view_get_uri (web_view);
|
||||
|
||||
if (!page_uri || !strcmp (page_uri, "about:blank"))
|
||||
page_uri = uri;
|
||||
data.page_uri = page_uri;
|
||||
|
||||
if (g_hash_table_find (pattern, (GHRFunc) adblock_is_matched, &data))
|
||||
{
|
||||
#if 0
|
||||
gchar* text;
|
||||
|
||||
if (gtk_widget_get_has_tooltip (image))
|
||||
text = g_strdup_printf ("%s\n%s", gtk_widget_get_tooltip_text (image), uri);
|
||||
else
|
||||
text = g_strdup_printf ("Blocked content: \n%s", uri);
|
||||
gtk_widget_set_tooltip_text (image, text);
|
||||
g_free (text);
|
||||
#endif
|
||||
|
||||
webkit_network_request_set_uri (request, "about:blank");
|
||||
/* TODO: Need to figure out how to indicate what was blocked */
|
||||
}
|
||||
}
|
||||
#else
|
||||
|
@ -518,10 +650,34 @@ static void
|
|||
adblock_session_request_queued_cb (SoupSession* session,
|
||||
SoupMessage* msg)
|
||||
{
|
||||
SoupURI* soup_uri = soup_message_get_uri (msg);
|
||||
gchar* uri = soup_uri ? soup_uri_to_string (soup_uri, FALSE) : g_strdup ("");
|
||||
if (g_hash_table_find (pattern, (GHRFunc) adblock_is_matched, uri))
|
||||
Matcher data;
|
||||
SoupURI* soup_uri;
|
||||
gchar* uri;
|
||||
gchar* page_uri;
|
||||
|
||||
if (msg->method && !strncmp (msg->method, "POST", 4))
|
||||
return;
|
||||
|
||||
/* FIXME: There is a crasher somewhere introduced with the refactoring */
|
||||
|
||||
soup_uri = soup_message_get_uri (msg);
|
||||
uri = soup_uri_to_string (soup_uri, FALSE);
|
||||
if (soup_uri->query)
|
||||
data.query = g_strdup_printf ("%s?%s", soup_uri->path, soup_uri->query);
|
||||
else
|
||||
data.query = g_strdup (soup_uri->path);
|
||||
|
||||
data.uri = uri;
|
||||
page_uri = NULL; /* FIXME */
|
||||
|
||||
if (!page_uri || !strcmp (page_uri, "about:blank"))
|
||||
page_uri = uri;
|
||||
data.page_uri = page_uri;
|
||||
|
||||
if (g_hash_table_find (pattern, (GHRFunc) adblock_is_matched, &data))
|
||||
{
|
||||
/* FIXME: Update image tooltip */
|
||||
|
||||
soup_uri = soup_uri_new ("http://.invalid");
|
||||
soup_message_set_uri (msg, soup_uri);
|
||||
soup_uri_free (soup_uri);
|
||||
|
@ -530,22 +686,6 @@ adblock_session_request_queued_cb (SoupSession* session,
|
|||
}
|
||||
#endif
|
||||
|
||||
static gchar*
|
||||
adblock_build_js (gchar* style)
|
||||
{
|
||||
return g_strdup_printf (
|
||||
"window.addEventListener ('DOMContentLoaded',"
|
||||
"function () {"
|
||||
"var mystyle = document.createElement(\"style\");"
|
||||
"mystyle.setAttribute(\"type\", \"text/css\");"
|
||||
"mystyle.appendChild(document.createTextNode('%s'));"
|
||||
"var head = document.getElementsByTagName(\"head\")[0];"
|
||||
"if (head) head.appendChild(mystyle);"
|
||||
"else document.documentElement.insertBefore(mystyle, document.documentElement.firstChild);"
|
||||
"}, true);",
|
||||
style);
|
||||
}
|
||||
|
||||
static void
|
||||
adblock_window_object_cleared_cb (GtkWidget* web_view,
|
||||
WebKitWebFrame* web_frame,
|
||||
|
@ -557,26 +697,28 @@ adblock_window_object_cleared_cb (GtkWidget* web_view,
|
|||
|
||||
static void
|
||||
adblock_add_tab_cb (MidoriBrowser* browser,
|
||||
MidoriView* view)
|
||||
MidoriView* view,
|
||||
GtkWidget* image)
|
||||
{
|
||||
GtkWidget* web_view = gtk_bin_get_child (GTK_BIN (view));
|
||||
g_signal_connect (web_view, "window-object-cleared",
|
||||
G_CALLBACK (adblock_window_object_cleared_cb), 0);
|
||||
#if HAVE_WEBKIT_RESOURCE_REQUEST
|
||||
g_signal_connect (web_view, "resource-request-starting",
|
||||
G_CALLBACK (adblock_resource_request_starting_cb), view);
|
||||
G_CALLBACK (adblock_resource_request_starting_cb), image);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
adblock_deactivate_cb (MidoriExtension* extension,
|
||||
MidoriBrowser* browser);
|
||||
GtkWidget* image);
|
||||
|
||||
static void
|
||||
adblock_add_tab_foreach_cb (MidoriView* view,
|
||||
MidoriBrowser* browser)
|
||||
MidoriBrowser* browser,
|
||||
GtkWidget* image)
|
||||
{
|
||||
adblock_add_tab_cb (browser, view);
|
||||
adblock_add_tab_cb (browser, view, image);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -584,13 +726,88 @@ adblock_app_add_browser_cb (MidoriApp* app,
|
|||
MidoriBrowser* browser,
|
||||
MidoriExtension* extension)
|
||||
{
|
||||
GtkWidget* statusbar;
|
||||
GtkWidget* image;
|
||||
|
||||
statusbar = katze_object_get_object (browser, "statusbar");
|
||||
#if 0
|
||||
image = gtk_image_new_from_stock (STOCK_IMAGE, GTK_ICON_SIZE_MENU);
|
||||
gtk_widget_show (image);
|
||||
gtk_box_pack_start (GTK_BOX (statusbar), image, FALSE, FALSE, 3);
|
||||
#else
|
||||
image = GTK_WIDGET (browser);
|
||||
#endif
|
||||
|
||||
midori_browser_foreach (browser,
|
||||
(GtkCallback)adblock_add_tab_foreach_cb, browser);
|
||||
g_signal_connect (browser, "add-tab", G_CALLBACK (adblock_add_tab_cb), 0);
|
||||
(GtkCallback)adblock_add_tab_foreach_cb, image);
|
||||
g_signal_connect (browser, "add-tab",
|
||||
G_CALLBACK (adblock_add_tab_cb), image);
|
||||
g_signal_connect (browser, "populate-tool-menu",
|
||||
G_CALLBACK (adblock_browser_populate_tool_menu_cb), extension);
|
||||
g_signal_connect (extension, "deactivate",
|
||||
G_CALLBACK (adblock_deactivate_cb), browser);
|
||||
G_CALLBACK (adblock_deactivate_cb), image);
|
||||
g_object_unref (statusbar);
|
||||
}
|
||||
|
||||
static void
|
||||
adblock_compile_regexp (GHashTable* tbl,
|
||||
gchar* patt,
|
||||
gchar* opts)
|
||||
{
|
||||
GRegex* regex;
|
||||
GError* error = NULL;
|
||||
|
||||
/* TODO: Play with optimization flags */
|
||||
regex = g_regex_new (patt, G_REGEX_OPTIMIZE,
|
||||
G_REGEX_MATCH_NOTEMPTY, &error);
|
||||
|
||||
if (!error)
|
||||
g_hash_table_insert (tbl, opts, regex);
|
||||
else
|
||||
{
|
||||
g_warning ("%s: %s", G_STRFUNC, error->message);
|
||||
g_error_free (error);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
adblock_add_url_pattern (gchar* format,
|
||||
gchar* type,
|
||||
gchar* line)
|
||||
{
|
||||
gchar** data;
|
||||
gchar* patt;
|
||||
gchar* fixed_patt;
|
||||
gchar* format_patt;
|
||||
gchar* opts;
|
||||
|
||||
data = g_strsplit (line, "$", -1);
|
||||
if (data && data[0] && data[1] && data[2])
|
||||
{
|
||||
patt = g_strdup_printf ("%s%s", data[0], data[1]);
|
||||
opts = g_strdup_printf ("type=%s,regexp=%s,%s", type, patt, data[2]);
|
||||
}
|
||||
else if (data && data[0] && data[1])
|
||||
{
|
||||
patt = g_strdup (data[0]);
|
||||
opts = g_strdup_printf ("type=%s,regexp=%s,%s", type, patt, data[1]);
|
||||
}
|
||||
else
|
||||
{
|
||||
patt = g_strdup (data[0]);
|
||||
opts = g_strdup_printf ("type=%s,regexp=%s", type, patt);
|
||||
}
|
||||
|
||||
fixed_patt = adblock_fixup_regexp (patt);
|
||||
format_patt = g_strdup_printf (format, fixed_patt);
|
||||
|
||||
/* g_debug ("got: %s opts %s", format_patt, opts); */
|
||||
adblock_compile_regexp (pattern, format_patt, opts);
|
||||
|
||||
g_strfreev (data);
|
||||
g_free (patt);
|
||||
g_free (fixed_patt);
|
||||
g_free (format_patt);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -600,11 +817,41 @@ adblock_frame_add (gchar* line)
|
|||
|
||||
(void)*line++;
|
||||
(void)*line++;
|
||||
new_blockcss = g_strdup_printf ("%s %s { display: none !important; }",
|
||||
blockcss, line);
|
||||
new_blockcss = g_strdup_printf ("%s, %s", blockcss, line);
|
||||
katze_assign (blockcss, new_blockcss);
|
||||
}
|
||||
|
||||
static void
|
||||
adblock_frame_add_private (const gchar* line,
|
||||
const gchar* sep)
|
||||
{
|
||||
gchar* new_blockcss;
|
||||
gchar** data;
|
||||
data = g_strsplit (line, sep, 2);
|
||||
|
||||
if (strstr (data[0],","))
|
||||
{
|
||||
gchar** domains;
|
||||
gint max, i;
|
||||
|
||||
domains = g_strsplit (data[0], ",", -1);
|
||||
for (max = i = 0; domains[i]; i++)
|
||||
{
|
||||
new_blockcss = g_strdup_printf ("%s;\nsites['%s']+=',%s'",
|
||||
blockcssprivate, g_strstrip (domains[i]), data[1]);
|
||||
katze_assign (blockcssprivate, new_blockcss);
|
||||
}
|
||||
g_strfreev (domains);
|
||||
}
|
||||
else
|
||||
{
|
||||
new_blockcss = g_strdup_printf ("%s;\nsites['%s']+=',%s'",
|
||||
blockcssprivate, data[0], data[1]);
|
||||
katze_assign (blockcssprivate, new_blockcss);
|
||||
}
|
||||
g_strfreev (data);
|
||||
}
|
||||
|
||||
static gchar*
|
||||
adblock_parse_line (gchar* line)
|
||||
{
|
||||
|
@ -617,97 +864,108 @@ adblock_parse_line (gchar* line)
|
|||
/* FIXME: No support for whitelisting */
|
||||
if (line[0] == '@' && line[1] == '@')
|
||||
return NULL;
|
||||
/* FIXME: What is this? */
|
||||
if (line[0] == '|' && line[1] == '|')
|
||||
/* FIXME: No support for [include] and [exclude] tags */
|
||||
if (line[0] == '[')
|
||||
return NULL;
|
||||
/* ditto */
|
||||
if (strstr (line,"$"))
|
||||
return NULL;
|
||||
/* Got block hider */
|
||||
if (line[0] == '#' && line[1] == '#' && (line[2] == '.'||line[2] == '#'||line[2] == 'a'))
|
||||
|
||||
/* Got CSS block hider */
|
||||
if (line[0] == '#' && line[1] == '#' )
|
||||
{
|
||||
adblock_frame_add (line);
|
||||
return NULL;
|
||||
}
|
||||
/* FIXME: Do we have smth else starting with ##? */
|
||||
if (line[0] == '#' && line[1] == '#')
|
||||
/* Got CSS block hider. Workaround */
|
||||
if (line[0] == '#')
|
||||
return NULL;
|
||||
/* FIXME: No support for per domain element hiding */
|
||||
|
||||
/* Got per domain CSS hider rule */
|
||||
if (strstr (line,"##"))
|
||||
{
|
||||
adblock_frame_add_private (line,"##");
|
||||
return NULL;
|
||||
/* FIXME: No support for [include] and [exclude] tags */
|
||||
if (line[0] == '[')
|
||||
}
|
||||
|
||||
/* Got per domain CSS hider rule. Workaround */
|
||||
if (strstr (line,"#"))
|
||||
{
|
||||
adblock_frame_add_private (line,"#");
|
||||
return NULL;
|
||||
return adblock_fixup_regexp (line);
|
||||
}
|
||||
/* Got URL blocker rule */
|
||||
if (line[0] == '|' && line[1] == '|' )
|
||||
{
|
||||
(void)*line++;
|
||||
(void)*line++;
|
||||
adblock_add_url_pattern ("^https?://([a-z0-9\\.]+)?%s", "fulluri", line);
|
||||
return NULL;
|
||||
}
|
||||
if (line[0] == '|')
|
||||
{
|
||||
(void)*line++;
|
||||
adblock_add_url_pattern ("^%s", "fulluri", line);
|
||||
return NULL;
|
||||
}
|
||||
adblock_add_url_pattern ("%s", "uri", line);
|
||||
return line;
|
||||
}
|
||||
|
||||
static void
|
||||
adblock_parse_file (gchar* path)
|
||||
{
|
||||
FILE* file;
|
||||
gchar line[500];
|
||||
|
||||
if ((file = g_fopen (path, "r")))
|
||||
{
|
||||
gchar line[500];
|
||||
GRegex* regex;
|
||||
|
||||
while (fgets (line, 500, file))
|
||||
{
|
||||
GError* error = NULL;
|
||||
gchar* parsed;
|
||||
|
||||
parsed = adblock_parse_line (line);
|
||||
if (!parsed)
|
||||
continue;
|
||||
|
||||
regex = g_regex_new (parsed, G_REGEX_OPTIMIZE,
|
||||
G_REGEX_MATCH_NOTEMPTY, &error);
|
||||
if (error)
|
||||
{
|
||||
g_warning ("%s: %s", G_STRFUNC, error->message);
|
||||
g_error_free (error);
|
||||
g_free (parsed);
|
||||
}
|
||||
else
|
||||
g_hash_table_insert (pattern, parsed, regex);
|
||||
}
|
||||
katze_assign (blockscript, adblock_build_js (blockcss));
|
||||
adblock_parse_line (line);
|
||||
fclose (file);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
adblock_deactivate_tabs (MidoriView* view,
|
||||
MidoriBrowser* browser)
|
||||
GtkWidget* image)
|
||||
{
|
||||
GtkWidget* web_view = gtk_bin_get_child (GTK_BIN (view));
|
||||
MidoriBrowser* browser = midori_browser_get_for_widget (image);
|
||||
|
||||
g_signal_handlers_disconnect_by_func (
|
||||
browser, adblock_add_tab_cb, 0);
|
||||
g_signal_handlers_disconnect_by_func (
|
||||
web_view, adblock_window_object_cleared_cb, 0);
|
||||
#if HAVE_WEBKIT_RESOURCE_REQUEST
|
||||
g_signal_handlers_disconnect_by_func (
|
||||
web_view, adblock_resource_request_starting_cb, view);
|
||||
#else
|
||||
g_signal_handlers_disconnect_by_func (
|
||||
webkit_get_default_session (), adblock_session_request_queued_cb, NULL);
|
||||
web_view, adblock_resource_request_starting_cb, image);
|
||||
#endif
|
||||
#if 0
|
||||
gtk_widget_destroy (image);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
adblock_deactivate_cb (MidoriExtension* extension,
|
||||
MidoriBrowser* browser)
|
||||
GtkWidget* image)
|
||||
{
|
||||
MidoriBrowser* browser = midori_browser_get_for_widget (image);
|
||||
MidoriApp* app = midori_extension_get_app (extension);
|
||||
|
||||
#if !HAVE_WEBKIT_RESOURCE_REQUEST
|
||||
g_signal_handlers_disconnect_matched (webkit_get_default_session (),
|
||||
G_SIGNAL_MATCH_FUNC,
|
||||
g_signal_lookup ("request-queued", SOUP_TYPE_SESSION), 0,
|
||||
NULL, adblock_session_request_queued_cb, NULL);
|
||||
#endif
|
||||
g_signal_handlers_disconnect_by_func (
|
||||
browser, adblock_browser_populate_tool_menu_cb, extension);
|
||||
g_signal_handlers_disconnect_by_func (
|
||||
extension, adblock_deactivate_cb, browser);
|
||||
g_signal_handlers_disconnect_by_func (
|
||||
app, adblock_app_add_browser_cb, extension);
|
||||
midori_browser_foreach (browser, (GtkCallback)adblock_deactivate_tabs, browser);
|
||||
midori_browser_foreach (browser, (GtkCallback)adblock_deactivate_tabs, image);
|
||||
|
||||
katze_assign (blockcss, NULL);
|
||||
katze_assign (blockcssprivate, NULL);
|
||||
g_hash_table_destroy (pattern);
|
||||
}
|
||||
|
||||
|
@ -768,6 +1026,7 @@ test_adblock_pattern (void)
|
|||
|
||||
temp = g_file_open_tmp ("midori_adblock_match_test_XXXXXX", &filename, NULL);
|
||||
|
||||
/* TODO: Update some tests and add new ones. */
|
||||
g_file_set_contents (filename,
|
||||
"*ads.foo.bar*\n"
|
||||
"*ads.bogus.name*\n"
|
||||
|
|
|
@ -23,12 +23,6 @@ colorful_tabs_view_notify_uri_cb (MidoriView* view,
|
|||
GdkColor color;
|
||||
|
||||
label = midori_view_get_proxy_tab_label (view);
|
||||
if (!midori_extension_get_boolean (extension, "tint"))
|
||||
{
|
||||
gtk_widget_modify_bg (label, GTK_STATE_NORMAL, NULL);
|
||||
gtk_widget_modify_bg (label, GTK_STATE_ACTIVE, NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Find a color that is unique to an address. We merely compute
|
||||
a hash value, pick the first 6 + 1 characters and turn the
|
||||
|
@ -60,45 +54,35 @@ colorful_tabs_view_notify_uri_cb (MidoriView* view,
|
|||
gtk_widget_modify_bg (label, GTK_STATE_ACTIVE, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
colorful_tabs_browser_foreach_cb (GtkWidget* view,
|
||||
colorful_tabs_browser_add_tab_cb (MidoriBrowser* browser,
|
||||
GtkWidget* view,
|
||||
MidoriExtension* extension)
|
||||
{
|
||||
colorful_tabs_view_notify_uri_cb (MIDORI_VIEW (view), NULL, extension);
|
||||
}
|
||||
|
||||
static void
|
||||
colorful_tabs_button_toggled_cb (GtkWidget* button,
|
||||
MidoriExtension* extension)
|
||||
{
|
||||
MidoriBrowser* browser = midori_browser_get_for_widget (button);
|
||||
|
||||
midori_extension_set_boolean (extension, "tint",
|
||||
!midori_extension_get_boolean (extension, "tint"));
|
||||
midori_browser_foreach (browser,
|
||||
(GtkCallback)colorful_tabs_browser_foreach_cb, extension);
|
||||
}
|
||||
|
||||
static void
|
||||
colorful_tabs_browser_add_tab_cb (MidoriBrowser* browser,
|
||||
MidoriView* view,
|
||||
MidoriExtension* extension)
|
||||
{
|
||||
g_signal_connect (view, "notify::uri",
|
||||
G_CALLBACK (colorful_tabs_view_notify_uri_cb), extension);
|
||||
}
|
||||
|
||||
static void
|
||||
colorful_tabs_deactivate_cb (MidoriExtension* extension,
|
||||
GtkWidget* bbox)
|
||||
MidoriBrowser* browser)
|
||||
{
|
||||
guint i;
|
||||
GtkWidget* view;
|
||||
|
||||
g_signal_handlers_disconnect_by_func (
|
||||
extension, colorful_tabs_deactivate_cb, bbox);
|
||||
/* FIXME: Disconnect signals */
|
||||
midori_browser_foreach (midori_browser_get_for_widget (bbox),
|
||||
(GtkCallback)colorful_tabs_browser_foreach_cb, extension);
|
||||
gtk_widget_destroy (bbox);
|
||||
extension, colorful_tabs_deactivate_cb, browser);
|
||||
i = 0;
|
||||
while ((view = midori_browser_get_nth_tab (browser, i++)))
|
||||
{
|
||||
GtkWidget* label = midori_view_get_proxy_tab_label (MIDORI_VIEW (view));
|
||||
gtk_event_box_set_visible_window (GTK_EVENT_BOX (label), FALSE);
|
||||
gtk_widget_modify_bg (label, GTK_STATE_NORMAL, NULL);
|
||||
gtk_widget_modify_bg (label, GTK_STATE_ACTIVE, NULL);
|
||||
g_signal_handlers_disconnect_by_func (
|
||||
view, colorful_tabs_view_notify_uri_cb, extension);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -106,26 +90,16 @@ colorful_tabs_app_add_browser_cb (MidoriApp* app,
|
|||
MidoriBrowser* browser,
|
||||
MidoriExtension* extension)
|
||||
{
|
||||
GtkWidget* statusbar;
|
||||
GtkWidget* bbox;
|
||||
GtkWidget* button;
|
||||
guint i;
|
||||
GtkWidget* view;
|
||||
|
||||
statusbar = katze_object_get_object (browser, "statusbar");
|
||||
bbox = gtk_hbox_new (FALSE, 0);
|
||||
button = gtk_check_button_new_with_label (_("Tint tabs distinctly"));
|
||||
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button),
|
||||
midori_extension_get_boolean (extension, "tint"));
|
||||
gtk_box_pack_start (GTK_BOX (bbox), button, FALSE, FALSE, 2);
|
||||
gtk_widget_show (button);
|
||||
gtk_widget_show (bbox);
|
||||
gtk_box_pack_start (GTK_BOX (statusbar), bbox, FALSE, FALSE, 3);
|
||||
|
||||
g_signal_connect (button, "toggled",
|
||||
G_CALLBACK (colorful_tabs_button_toggled_cb), extension);
|
||||
i = 0;
|
||||
while ((view = midori_browser_get_nth_tab (browser, i++)))
|
||||
colorful_tabs_browser_add_tab_cb (browser, view, extension);
|
||||
g_signal_connect (browser, "add-tab",
|
||||
G_CALLBACK (colorful_tabs_browser_add_tab_cb), extension);
|
||||
g_signal_connect (extension, "deactivate",
|
||||
G_CALLBACK (colorful_tabs_deactivate_cb), bbox);
|
||||
G_CALLBACK (colorful_tabs_deactivate_cb), browser);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -142,6 +116,8 @@ colorful_tabs_activate_cb (MidoriExtension* extension,
|
|||
colorful_tabs_app_add_browser_cb (app, browser, extension);
|
||||
g_signal_connect (app, "add-browser",
|
||||
G_CALLBACK (colorful_tabs_app_add_browser_cb), extension);
|
||||
|
||||
g_object_unref (browsers);
|
||||
}
|
||||
|
||||
MidoriExtension*
|
||||
|
@ -153,7 +129,6 @@ extension_init (void)
|
|||
"version", "0.1",
|
||||
"authors", "Christian Dywan <christian@twotoasts.de>",
|
||||
NULL);
|
||||
midori_extension_install_boolean (extension, "tint", FALSE);
|
||||
|
||||
g_signal_connect (extension, "activate",
|
||||
G_CALLBACK (colorful_tabs_activate_cb), NULL);
|
||||
|
|
|
@ -91,7 +91,7 @@ feed_panel_treeview_render_icon_cb (GtkTreeViewColumn* column,
|
|||
uri = katze_item_get_uri (pitem);
|
||||
if (uri)
|
||||
{
|
||||
pixbuf = katze_net_load_icon (panel->net, uri, NULL, NULL, NULL);
|
||||
pixbuf = katze_load_cached_icon (uri, NULL);
|
||||
if (!pixbuf)
|
||||
pixbuf = panel->pixbuf;
|
||||
}
|
||||
|
@ -509,8 +509,11 @@ feed_panel_open_in_window_activate_cb (GtkWidget* menuitem,
|
|||
if (uri && *uri)
|
||||
{
|
||||
MidoriBrowser* browser;
|
||||
MidoriBrowser* new_browser;
|
||||
|
||||
browser = midori_browser_get_for_widget (GTK_WIDGET (panel));
|
||||
g_signal_emit_by_name (browser, "new-window", uri);
|
||||
g_signal_emit_by_name (browser, "new-window", NULL, &new_browser);
|
||||
midori_browser_add_uri (new_browser, uri);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -550,8 +553,8 @@ feed_panel_popup (GtkWidget* widget,
|
|||
item, feed_panel_delete_activate_cb, panel);
|
||||
}
|
||||
|
||||
sokoke_widget_popup (widget, GTK_MENU (menu),
|
||||
event, SOKOKE_MENU_POSITION_CURSOR);
|
||||
katze_widget_popup (widget, GTK_MENU (menu),
|
||||
event, KATZE_MENU_POSITION_CURSOR);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
/*
|
||||
Copyright (C) 2009 Alexander Butenko <a.butenka@gmail.com>
|
||||
Copyright (C) 2009 Christian Dywan <christian@twotoasts.de>
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
|
@ -7,18 +8,23 @@
|
|||
version 2.1 of the License, or (at your option) any later version.
|
||||
*/
|
||||
|
||||
#define MAXCHARS 20
|
||||
#define MAXCHARS 60
|
||||
#define MINCHARS 2
|
||||
|
||||
#include <midori/midori.h>
|
||||
|
||||
#include "config.h"
|
||||
#include "midori/sokoke.h"
|
||||
|
||||
#include <glib/gstdio.h>
|
||||
#if HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#if HAVE_SQLITE
|
||||
#include <sqlite3.h>
|
||||
#endif
|
||||
|
||||
static GHashTable* global_keys;
|
||||
static gchar* jsforms;
|
||||
|
||||
|
@ -30,7 +36,7 @@ formhistory_prepare_js ()
|
|||
guint i;
|
||||
gchar* file;
|
||||
|
||||
gchar* data_path = g_build_filename (MDATADIR, PACKAGE_NAME, NULL);
|
||||
gchar* data_path = g_build_filename (MDATADIR, PACKAGE_NAME, "res", NULL);
|
||||
file = g_build_filename (data_path,"/autosuggestcontrol.js",NULL);
|
||||
if (!g_file_test (file, G_FILE_TEST_EXISTS))
|
||||
return FALSE;
|
||||
|
@ -72,6 +78,22 @@ formhistory_prepare_js ()
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
static gchar*
|
||||
formhistory_fixup_value (char* value)
|
||||
{
|
||||
guint i = 0;
|
||||
g_strchomp (value);
|
||||
while (value[i])
|
||||
{
|
||||
if (value[i] == '\n')
|
||||
value[i] = ' ';
|
||||
else if (value[i] == '"')
|
||||
value[i] = '\'';
|
||||
i++;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
static gchar*
|
||||
formhistory_build_js ()
|
||||
{
|
||||
|
@ -99,7 +121,129 @@ formhistory_build_js ()
|
|||
}
|
||||
|
||||
static void
|
||||
formhistory_update_main_hash (GHashTable* keys)
|
||||
formhistory_update_database (gpointer db,
|
||||
const gchar* key,
|
||||
const gchar* value)
|
||||
{
|
||||
#if HAVE_SQLITE
|
||||
gchar* sqlcmd;
|
||||
gchar* errmsg;
|
||||
gint success;
|
||||
|
||||
sqlcmd = sqlite3_mprintf ("INSERT INTO forms VALUES"
|
||||
"('%q', '%q', '%q')",
|
||||
NULL, key, value);
|
||||
success = sqlite3_exec (db, sqlcmd, NULL, NULL, &errmsg);
|
||||
sqlite3_free (sqlcmd);
|
||||
if (success != SQLITE_OK)
|
||||
{
|
||||
g_printerr (_("Failed to add form value: %s\n"), errmsg);
|
||||
g_free (errmsg);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static gboolean
|
||||
formhistory_update_main_hash (gchar* key,
|
||||
gchar* value)
|
||||
{
|
||||
guint length;
|
||||
gchar* tmp;
|
||||
|
||||
if (!(value && *value))
|
||||
return FALSE;
|
||||
length = strlen (value);
|
||||
if (length > MAXCHARS || length < MINCHARS)
|
||||
return FALSE;
|
||||
|
||||
formhistory_fixup_value (value);
|
||||
if ((tmp = g_hash_table_lookup (global_keys, (gpointer)key)))
|
||||
{
|
||||
gchar* rvalue = g_strdup_printf ("\"%s\"",value);
|
||||
if (!g_regex_match_simple (rvalue, tmp,
|
||||
G_REGEX_CASELESS, G_REGEX_MATCH_NOTEMPTY))
|
||||
{
|
||||
gchar* new_value = g_strdup_printf ("%s%s,", tmp, rvalue);
|
||||
g_hash_table_insert (global_keys, g_strdup (key), new_value);
|
||||
g_free (rvalue);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_free (rvalue);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
gchar* new_value = g_strdup_printf ("\"%s\",",value);
|
||||
g_hash_table_replace (global_keys, g_strdup (key), new_value);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#if WEBKIT_CHECK_VERSION (1, 1, 4)
|
||||
static gboolean
|
||||
formhistory_navigation_decision_cb (WebKitWebView* web_view,
|
||||
WebKitWebFrame* web_frame,
|
||||
WebKitNetworkRequest* request,
|
||||
WebKitWebNavigationAction* action,
|
||||
WebKitWebPolicyDecision* decision,
|
||||
MidoriExtension* extension)
|
||||
{
|
||||
JSContextRef js_context = webkit_web_frame_get_global_context (web_frame);
|
||||
/* The script returns form data in the form "field_name|,|value|,|field_type".
|
||||
We are handling only input fields with 'text' or 'password' type.
|
||||
The field separator is "|||" */
|
||||
const gchar* script = "function dumpForm (inputs) {"
|
||||
" var out = '';"
|
||||
" for (i=0;i<inputs.length;i++) {"
|
||||
" if (inputs[i].value && (inputs[i].type == 'text' || inputs[i].type == 'password')) {"
|
||||
" var ename = inputs[i].getAttribute('name');"
|
||||
" var eid = inputs[i].getAttribute('id');"
|
||||
" if (!ename && eid)"
|
||||
" ename=eid;"
|
||||
" out += ename+'|,|'+inputs[i].value +'|,|'+inputs[i].type +'|||';"
|
||||
" }"
|
||||
" }"
|
||||
" return out;"
|
||||
"}"
|
||||
"dumpForm (document.getElementsByTagName('input'))";
|
||||
|
||||
if (webkit_web_navigation_action_get_reason (action) == WEBKIT_WEB_NAVIGATION_REASON_FORM_SUBMITTED
|
||||
|| webkit_web_navigation_action_get_reason (action) == WEBKIT_WEB_NAVIGATION_REASON_FORM_RESUBMITTED)
|
||||
{
|
||||
gchar* value = sokoke_js_script_eval (js_context, script, NULL);
|
||||
if (value)
|
||||
{
|
||||
gpointer db = g_object_get_data (G_OBJECT (extension), "formhistory-db");
|
||||
gchar** inputs = g_strsplit (value, "|||", 0);
|
||||
guint i = 0;
|
||||
while (inputs[i] != NULL)
|
||||
{
|
||||
gchar** parts = g_strsplit (inputs[i], "|,|", 3);
|
||||
if (parts && parts[0] && parts[1] && parts[2])
|
||||
{
|
||||
/* FIXME: We need to handle passwords */
|
||||
if (strcmp (parts[2], "password"))
|
||||
{
|
||||
if (formhistory_update_main_hash (parts[0], parts[1]))
|
||||
formhistory_update_database (db, parts[0], parts[1]);
|
||||
}
|
||||
}
|
||||
g_strfreev (parts);
|
||||
i++;
|
||||
}
|
||||
g_strfreev (inputs);
|
||||
g_free (value);
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
#else
|
||||
static void
|
||||
formhistory_feed_keys (GHashTable* keys,
|
||||
gpointer db)
|
||||
{
|
||||
GHashTableIter iter;
|
||||
gchar* key;
|
||||
|
@ -108,58 +252,38 @@ formhistory_update_main_hash (GHashTable* keys)
|
|||
g_hash_table_iter_init (&iter, keys);
|
||||
while (g_hash_table_iter_next (&iter, (gpointer)&key, (gpointer)&value))
|
||||
{
|
||||
guint length;
|
||||
gchar* tmp;
|
||||
|
||||
if (!(value && *value))
|
||||
continue;
|
||||
length = strlen (value);
|
||||
if (length > MAXCHARS || length < MINCHARS)
|
||||
continue;
|
||||
|
||||
tmp = g_hash_table_lookup (global_keys, (gpointer)key);
|
||||
if (tmp)
|
||||
{
|
||||
gchar* rvalue = g_strdup_printf ("\"%s\"",value);
|
||||
if (!g_regex_match_simple (rvalue, tmp,
|
||||
G_REGEX_CASELESS, G_REGEX_MATCH_NOTEMPTY))
|
||||
{
|
||||
gchar* new_value = g_strdup_printf ("%s%s,", tmp, rvalue);
|
||||
g_hash_table_replace (global_keys, key, new_value);
|
||||
}
|
||||
g_free (rvalue);
|
||||
}
|
||||
else
|
||||
{
|
||||
gchar* new_value = g_strdup_printf ("\"%s\",",value);
|
||||
g_hash_table_insert (global_keys, key, new_value);
|
||||
}
|
||||
if (formhistory_update_main_hash (key, value))
|
||||
formhistory_update_database (db, key, value);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
formhistory_session_request_queued_cb (SoupSession* session,
|
||||
SoupMessage* msg)
|
||||
SoupMessage* msg,
|
||||
MidoriExtension* extension)
|
||||
{
|
||||
gchar* method = katze_object_get_string (msg, "method");
|
||||
if (method && !strncmp (method, "POST", 4))
|
||||
{
|
||||
/* SoupMessageHeaders* hdrs = msg->request_headers;
|
||||
const gchar* referer; */
|
||||
SoupMessageBody* body = msg->request_body;
|
||||
if (soup_message_body_get_accumulate (body))
|
||||
{
|
||||
SoupBuffer* buffer = soup_message_body_flatten (body);
|
||||
GHashTable* keys = soup_form_decode (body->data);
|
||||
formhistory_update_main_hash (keys);
|
||||
SoupBuffer* buffer;
|
||||
GHashTable* keys;
|
||||
gpointer db;
|
||||
|
||||
buffer = soup_message_body_flatten (body);
|
||||
keys = soup_form_decode (body->data);
|
||||
|
||||
db = g_object_get_data (G_OBJECT (extension), "formhistory-db");
|
||||
formhistory_feed_keys (keys, db);
|
||||
soup_buffer_free (buffer);
|
||||
g_hash_table_destroy (keys);
|
||||
}
|
||||
/* FIXME: Need a permanent storage implementation */
|
||||
/* referer = soup_message_headers_get_one (hdrs, "Referer"); */
|
||||
}
|
||||
g_free (method);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static void
|
||||
formhistory_window_object_cleared_cb (GtkWidget* web_view,
|
||||
|
@ -173,14 +297,19 @@ formhistory_window_object_cleared_cb (GtkWidget* web_view,
|
|||
|
||||
static void
|
||||
formhistory_add_tab_cb (MidoriBrowser* browser,
|
||||
MidoriView* view)
|
||||
MidoriView* view,
|
||||
MidoriExtension* extension)
|
||||
{
|
||||
GtkWidget* web_view = gtk_bin_get_child (GTK_BIN (view));
|
||||
SoupSession *session = webkit_get_default_session ();
|
||||
g_signal_connect (web_view, "window-object-cleared",
|
||||
G_CALLBACK (formhistory_window_object_cleared_cb), 0);
|
||||
g_signal_connect (session, "request-queued",
|
||||
G_CALLBACK (formhistory_session_request_queued_cb), 0);
|
||||
G_CALLBACK (formhistory_window_object_cleared_cb), NULL);
|
||||
#if WEBKIT_CHECK_VERSION (1, 1, 4)
|
||||
g_signal_connect (web_view, "navigation-policy-decision-requested",
|
||||
G_CALLBACK (formhistory_navigation_decision_cb), extension);
|
||||
#else
|
||||
g_signal_connect (webkit_get_default_session (), "request-queued",
|
||||
G_CALLBACK (formhistory_session_request_queued_cb), extension);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -189,9 +318,10 @@ formhistory_deactivate_cb (MidoriExtension* extension,
|
|||
|
||||
static void
|
||||
formhistory_add_tab_foreach_cb (MidoriView* view,
|
||||
MidoriBrowser* browser)
|
||||
MidoriBrowser* browser,
|
||||
MidoriExtension* extension)
|
||||
{
|
||||
formhistory_add_tab_cb (browser, view);
|
||||
formhistory_add_tab_cb (browser, view, extension);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -200,24 +330,30 @@ formhistory_app_add_browser_cb (MidoriApp* app,
|
|||
MidoriExtension* extension)
|
||||
{
|
||||
midori_browser_foreach (browser,
|
||||
(GtkCallback)formhistory_add_tab_foreach_cb, browser);
|
||||
g_signal_connect (browser, "add-tab", G_CALLBACK (formhistory_add_tab_cb), 0);
|
||||
(GtkCallback)formhistory_add_tab_foreach_cb, extension);
|
||||
g_signal_connect (browser, "add-tab",
|
||||
G_CALLBACK (formhistory_add_tab_cb), extension);
|
||||
g_signal_connect (extension, "deactivate",
|
||||
G_CALLBACK (formhistory_deactivate_cb), browser);
|
||||
}
|
||||
|
||||
static void
|
||||
formhistory_deactivate_tabs (MidoriView* view,
|
||||
MidoriBrowser* browser)
|
||||
MidoriBrowser* browser,
|
||||
MidoriExtension* extension)
|
||||
{
|
||||
GtkWidget* web_view = gtk_bin_get_child (GTK_BIN (view));
|
||||
SoupSession *session = webkit_get_default_session ();
|
||||
g_signal_handlers_disconnect_by_func (
|
||||
browser, formhistory_add_tab_cb, 0);
|
||||
browser, formhistory_add_tab_cb, extension);
|
||||
g_signal_handlers_disconnect_by_func (
|
||||
web_view, formhistory_window_object_cleared_cb, 0);
|
||||
web_view, formhistory_window_object_cleared_cb, NULL);
|
||||
#if WEBKIT_CHECK_VERSION (1, 1, 4)
|
||||
g_signal_handlers_disconnect_by_func (
|
||||
session, formhistory_session_request_queued_cb, 0);
|
||||
web_view, formhistory_navigation_decision_cb, extension);
|
||||
#else
|
||||
g_signal_handlers_disconnect_by_func (
|
||||
webkit_get_default_session (), formhistory_session_request_queued_cb, extension);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -225,22 +361,67 @@ formhistory_deactivate_cb (MidoriExtension* extension,
|
|||
MidoriBrowser* browser)
|
||||
{
|
||||
MidoriApp* app = midori_extension_get_app (extension);
|
||||
#if HAVE_SQLITE
|
||||
sqlite3* db;
|
||||
#endif
|
||||
|
||||
g_signal_handlers_disconnect_by_func (
|
||||
extension, formhistory_deactivate_cb, browser);
|
||||
g_signal_handlers_disconnect_by_func (
|
||||
app, formhistory_app_add_browser_cb, extension);
|
||||
midori_browser_foreach (browser, (GtkCallback)formhistory_deactivate_tabs, browser);
|
||||
midori_browser_foreach (browser,
|
||||
(GtkCallback)formhistory_deactivate_tabs, extension);
|
||||
|
||||
jsforms = "";
|
||||
if (global_keys)
|
||||
g_hash_table_destroy (global_keys);
|
||||
|
||||
#if HAVE_SQLITE
|
||||
if ((db = g_object_get_data (G_OBJECT (extension), "formhistory-db")))
|
||||
sqlite3_close (db);
|
||||
#endif
|
||||
}
|
||||
|
||||
#if HAVE_SQLITE
|
||||
static int
|
||||
formhistory_add_field (gpointer data,
|
||||
int argc,
|
||||
char** argv,
|
||||
char** colname)
|
||||
{
|
||||
gint i;
|
||||
gint ncols = 3;
|
||||
|
||||
/* Test whether have the right number of columns */
|
||||
g_return_val_if_fail (argc % ncols == 0, 1);
|
||||
|
||||
for (i = 0; i < (argc - ncols) + 1; i++)
|
||||
{
|
||||
if (argv[i])
|
||||
{
|
||||
if (colname[i] && !g_ascii_strcasecmp (colname[i], "domain")
|
||||
&& colname[i + 1] && !g_ascii_strcasecmp (colname[i + 1], "field")
|
||||
&& colname[i + 2] && !g_ascii_strcasecmp (colname[i + 2], "value"))
|
||||
{
|
||||
gchar* key = argv[i + 1];
|
||||
formhistory_update_main_hash (g_strdup (key), g_strdup (argv[i + 2]));
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
formhistory_activate_cb (MidoriExtension* extension,
|
||||
MidoriApp* app)
|
||||
{
|
||||
#if HAVE_SQLITE
|
||||
const gchar* config_dir;
|
||||
gchar* filename;
|
||||
sqlite3* db;
|
||||
char* errmsg = NULL, *errmsg2 = NULL;
|
||||
#endif
|
||||
KatzeArray* browsers;
|
||||
MidoriBrowser* browser;
|
||||
guint i;
|
||||
|
@ -248,6 +429,39 @@ formhistory_activate_cb (MidoriExtension* extension,
|
|||
global_keys = g_hash_table_new_full (g_str_hash, g_str_equal,
|
||||
(GDestroyNotify)g_free,
|
||||
(GDestroyNotify)g_free);
|
||||
#if HAVE_SQLITE
|
||||
config_dir = midori_extension_get_config_dir (extension);
|
||||
katze_mkdir_with_parents (config_dir, 0700);
|
||||
filename = g_build_filename (config_dir, "forms.db", NULL);
|
||||
if (sqlite3_open (filename, &db))
|
||||
{
|
||||
g_warning (_("Failed to open database: %s\n"), sqlite3_errmsg (db));
|
||||
sqlite3_close (db);
|
||||
}
|
||||
g_free (filename);
|
||||
if ((sqlite3_exec (db, "CREATE TABLE IF NOT EXISTS "
|
||||
"forms (domain text, field text, value text)",
|
||||
NULL, NULL, &errmsg) == SQLITE_OK)
|
||||
&& (sqlite3_exec (db, "SELECT domain, field, value FROM forms ",
|
||||
formhistory_add_field,
|
||||
NULL, &errmsg2) == SQLITE_OK))
|
||||
g_object_set_data (G_OBJECT (extension), "formhistory-db", db);
|
||||
else
|
||||
{
|
||||
if (errmsg)
|
||||
{
|
||||
g_critical (_("Failed to execute database statement: %s\n"), errmsg);
|
||||
sqlite3_free (errmsg);
|
||||
if (errmsg2)
|
||||
{
|
||||
g_critical (_("Failed to execute database statement: %s\n"), errmsg2);
|
||||
sqlite3_free (errmsg2);
|
||||
}
|
||||
}
|
||||
sqlite3_close (db);
|
||||
}
|
||||
#endif
|
||||
|
||||
browsers = katze_object_get_object (app, "browsers");
|
||||
i = 0;
|
||||
while ((browser = katze_array_get_nth_item (browsers, i++)))
|
||||
|
@ -278,8 +492,10 @@ MidoriExtension*
|
|||
extension_init (void)
|
||||
{
|
||||
gboolean should_init = TRUE;
|
||||
gchar* ver;
|
||||
const gchar* ver;
|
||||
gchar* desc;
|
||||
MidoriExtension* extension;
|
||||
|
||||
if (formhistory_prepare_js ())
|
||||
{
|
||||
ver = "0.1";
|
||||
|
@ -292,7 +508,8 @@ extension_init (void)
|
|||
ver = NULL;
|
||||
should_init = FALSE;
|
||||
}
|
||||
MidoriExtension* extension = g_object_new (MIDORI_TYPE_EXTENSION,
|
||||
|
||||
extension = g_object_new (MIDORI_TYPE_EXTENSION,
|
||||
"name", _("Form history filler"),
|
||||
"description", desc,
|
||||
"version", ver,
|
||||
|
|
298
extensions/mouse-gestures.c
Normal file
298
extensions/mouse-gestures.c
Normal file
|
@ -0,0 +1,298 @@
|
|||
/*
|
||||
Copyright (C) 2009 Matthias Kruk <mkruk@matthiaskruk.de>
|
||||
Copyright (C) 2009 Christian Dywan <christian@twotoasts.de>
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
See the file COPYING for the full license text.
|
||||
*/
|
||||
|
||||
#include <midori/midori.h>
|
||||
|
||||
typedef struct _MouseGesture MouseGesture;
|
||||
typedef enum _MouseButton MouseButton;
|
||||
|
||||
enum _MouseButton {
|
||||
MOUSE_BUTTON_LEFT = 1,
|
||||
MOUSE_BUTTON_RIGHT = 3,
|
||||
MOUSE_BUTTON_MIDDLE = 2,
|
||||
MOUSE_BUTTON_UNSET = 0
|
||||
};
|
||||
|
||||
struct MouseGestureNode {
|
||||
double x;
|
||||
double y;
|
||||
} MouseGestureNode_t;
|
||||
|
||||
struct _MouseGesture {
|
||||
struct MouseGestureNode start;
|
||||
struct MouseGestureNode middle;
|
||||
struct MouseGestureNode end;
|
||||
MouseButton last;
|
||||
};
|
||||
|
||||
#define DEVIANCE 20
|
||||
#define MINLENGTH 50
|
||||
|
||||
#define MOUSE_GESTURES_BUTTON MOUSE_BUTTON_MIDDLE
|
||||
|
||||
MouseGesture *gesture;
|
||||
|
||||
void mouse_gesture_clear (MouseGesture *g)
|
||||
{
|
||||
g->start.x = 0;
|
||||
g->start.y = 0;
|
||||
g->middle.x = 0;
|
||||
g->middle.y = 0;
|
||||
g->end.x = 0;
|
||||
g->end.y = 0;
|
||||
g->last = MOUSE_BUTTON_UNSET;
|
||||
}
|
||||
|
||||
MouseGesture* mouse_gesture_new (void)
|
||||
{
|
||||
MouseGesture* g = g_new (MouseGesture, 1);
|
||||
mouse_gesture_clear (g);
|
||||
|
||||
return g;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
mouse_gestures_button_press_event_cb (GtkWidget* web_view,
|
||||
GdkEvent* event,
|
||||
MidoriBrowser* browser)
|
||||
{
|
||||
if (event->button.button == MOUSE_GESTURES_BUTTON)
|
||||
{
|
||||
/* If the gesture was previously cleaned,
|
||||
start a new gesture and coordinates. */
|
||||
if (gesture->last == MOUSE_BUTTON_UNSET)
|
||||
{
|
||||
gesture->start.x = event->button.x;
|
||||
gesture->start.y = event->button.y;
|
||||
gesture->last = event->button.button;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
mouse_gestures_motion_notify_event_cb (GtkWidget* web_view,
|
||||
GdkEvent* event,
|
||||
MidoriBrowser* browser)
|
||||
{
|
||||
if (gesture->last != MOUSE_BUTTON_UNSET)
|
||||
{
|
||||
guint x, y;
|
||||
|
||||
x = event->motion.x;
|
||||
y = event->motion.y;
|
||||
|
||||
if ((gesture->start.x - x < DEVIANCE && gesture->start.x - x > -DEVIANCE) ||
|
||||
(gesture->start.y - y < DEVIANCE && gesture->start.y - y > -DEVIANCE))
|
||||
{
|
||||
gesture->middle.x = x;
|
||||
gesture->middle.y = y;
|
||||
}
|
||||
else if ((gesture->middle.x - x < DEVIANCE && gesture->middle.x - x > -DEVIANCE) ||
|
||||
(gesture->middle.y - y < DEVIANCE && gesture->middle.y - y > -DEVIANCE))
|
||||
{
|
||||
gesture->end.x = x;
|
||||
gesture->end.y = y;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
mouse_gestures_button_release_event_cb (GtkWidget* web_view,
|
||||
GdkEvent* event,
|
||||
MidoriBrowser* browser)
|
||||
{
|
||||
/* All mouse gestures will use this mouse button */
|
||||
if (gesture->last == MOUSE_GESTURES_BUTTON)
|
||||
{
|
||||
/* The initial horizontal move is between the bounds */
|
||||
if ((gesture->middle.x - gesture->start.x < DEVIANCE) &&
|
||||
(gesture->middle.x - gesture->start.x > -DEVIANCE))
|
||||
{
|
||||
/* We initially moved down more than MINLENGTH pixels */
|
||||
if (gesture->middle.y > gesture->start.y + MINLENGTH)
|
||||
{
|
||||
/* Then we the final vertical move is between the bounds and
|
||||
we moved right more than MINLENGTH pixels */
|
||||
if ((gesture->middle.y - gesture->end.y < DEVIANCE) &&
|
||||
(gesture->middle.y - gesture->end.y > -DEVIANCE) &&
|
||||
(gesture->end.x > gesture->middle.x + MINLENGTH))
|
||||
/* We moved down then right: close the tab */
|
||||
midori_browser_activate_action (browser, "TabClose");
|
||||
/* Then we the final vertical move is between the bounds and
|
||||
we moved left more than MINLENGTH pixels */
|
||||
else if ((gesture->middle.y - gesture->end.y < DEVIANCE) &&
|
||||
(gesture->middle.y - gesture->end.y > -DEVIANCE) &&
|
||||
(gesture->end.x + MINLENGTH < gesture->middle.x))
|
||||
/* We moved down then left: reload */
|
||||
midori_browser_activate_action (browser, "Reload");
|
||||
/* The end node was never updated, we only did a vertical move */
|
||||
else if(gesture->end.y == 0 && gesture->end.x == 0)
|
||||
/* We moved down then: create a new tab */
|
||||
midori_browser_activate_action (browser, "TabNew");
|
||||
}
|
||||
/* We initially moved up more than MINLENGTH pixels */
|
||||
else if (gesture->middle.y + MINLENGTH < gesture->start.y)
|
||||
{
|
||||
/* The end node was never updated, we only did a vertical move */
|
||||
if (gesture->end.y == 0 && gesture->end.x == 0)
|
||||
/* We moved up: stop */
|
||||
midori_browser_activate_action (browser, "Stop");
|
||||
}
|
||||
}
|
||||
/* The initial horizontal move is between the bounds */
|
||||
else if ((gesture->middle.y - gesture->start.y < DEVIANCE) &&
|
||||
(gesture->middle.y - gesture->start.y > -DEVIANCE))
|
||||
{
|
||||
/* We initially moved right more than MINLENGTH pixels */
|
||||
if (gesture->middle.x > gesture->start.x + MINLENGTH)
|
||||
{
|
||||
/* The end node was never updated, we only did an horizontal move */
|
||||
if (gesture->end.x == 0 && gesture->end.y == 0)
|
||||
/* We moved right: forward */
|
||||
midori_browser_activate_action (browser, "Forward");
|
||||
}
|
||||
/* We initially moved left more than MINLENGTH pixels */
|
||||
else if (gesture->middle.x + MINLENGTH < gesture->start.x)
|
||||
{
|
||||
/* The end node was never updated, we only did an horizontal move */
|
||||
if (gesture->end.x == 0 && gesture->end.y == 0)
|
||||
/* We moved left: back */
|
||||
midori_browser_activate_action (browser, "Back");
|
||||
}
|
||||
}
|
||||
|
||||
mouse_gesture_clear (gesture);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
mouse_gestures_add_tab_cb (MidoriBrowser* browser,
|
||||
MidoriView* view,
|
||||
MidoriExtension* extension)
|
||||
{
|
||||
GtkWidget* web_view = gtk_bin_get_child (GTK_BIN (view));
|
||||
|
||||
g_object_connect (web_view,
|
||||
"signal::button-press-event",
|
||||
mouse_gestures_button_press_event_cb, browser,
|
||||
"signal::motion-notify-event",
|
||||
mouse_gestures_motion_notify_event_cb, browser,
|
||||
"signal::button-release-event",
|
||||
mouse_gestures_button_release_event_cb, browser,
|
||||
NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
mouse_gestures_deactivate_cb (MidoriExtension* extension,
|
||||
MidoriBrowser* browser);
|
||||
|
||||
static void
|
||||
mouse_gestures_add_tab_foreach_cb (MidoriView* view,
|
||||
MidoriBrowser* browser,
|
||||
MidoriExtension* extension)
|
||||
{
|
||||
mouse_gestures_add_tab_cb (browser, view, extension);
|
||||
}
|
||||
|
||||
static void
|
||||
mouse_gestures_app_add_browser_cb (MidoriApp* app,
|
||||
MidoriBrowser* browser,
|
||||
MidoriExtension* extension)
|
||||
{
|
||||
midori_browser_foreach (browser,
|
||||
(GtkCallback)mouse_gestures_add_tab_foreach_cb, extension);
|
||||
g_signal_connect (browser, "add-tab",
|
||||
G_CALLBACK (mouse_gestures_add_tab_cb), extension);
|
||||
g_signal_connect (extension, "deactivate",
|
||||
G_CALLBACK (mouse_gestures_deactivate_cb), browser);
|
||||
}
|
||||
|
||||
static void
|
||||
mouse_gestures_deactivate_tabs (MidoriView* view,
|
||||
MidoriBrowser* browser)
|
||||
{
|
||||
GtkWidget* web_view = gtk_bin_get_child (GTK_BIN (view));
|
||||
|
||||
g_object_disconnect (web_view,
|
||||
"any_signal::button-press-event",
|
||||
mouse_gestures_button_press_event_cb, browser,
|
||||
"any_signal::motion-notify-event",
|
||||
mouse_gestures_motion_notify_event_cb, browser,
|
||||
"any_signal::button-release-event",
|
||||
mouse_gestures_button_release_event_cb, browser,
|
||||
NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
mouse_gestures_deactivate_cb (MidoriExtension* extension,
|
||||
MidoriBrowser* browser)
|
||||
{
|
||||
MidoriApp* app = midori_extension_get_app (extension);
|
||||
|
||||
g_signal_handlers_disconnect_by_func (
|
||||
extension, mouse_gestures_deactivate_cb, browser);
|
||||
g_signal_handlers_disconnect_by_func (
|
||||
app, mouse_gestures_app_add_browser_cb, extension);
|
||||
g_signal_handlers_disconnect_by_func (
|
||||
browser, mouse_gestures_add_tab_cb, extension);
|
||||
midori_browser_foreach (browser,
|
||||
(GtkCallback)mouse_gestures_deactivate_tabs, browser);
|
||||
|
||||
g_free (gesture);
|
||||
}
|
||||
|
||||
static void
|
||||
mouse_gestures_activate_cb (MidoriExtension* extension,
|
||||
MidoriApp* app)
|
||||
{
|
||||
KatzeArray* browsers;
|
||||
MidoriBrowser* browser;
|
||||
guint i;
|
||||
|
||||
gesture = mouse_gesture_new ();
|
||||
|
||||
browsers = katze_object_get_object (app, "browsers");
|
||||
i = 0;
|
||||
while ((browser = katze_array_get_nth_item (browsers, i++)))
|
||||
mouse_gestures_app_add_browser_cb (app, browser, extension);
|
||||
g_signal_connect (app, "add-browser",
|
||||
G_CALLBACK (mouse_gestures_app_add_browser_cb), extension);
|
||||
|
||||
g_object_unref (browsers);
|
||||
}
|
||||
|
||||
MidoriExtension*
|
||||
extension_init (void)
|
||||
{
|
||||
MidoriExtension* extension = g_object_new (MIDORI_TYPE_EXTENSION,
|
||||
"name", _("Mouse Gestures"),
|
||||
"description", _("Control Midori by moving the mouse"),
|
||||
"version", "0.1",
|
||||
"authors", "Matthias Kruk <mkruk@matthiaskruk.de>", NULL);
|
||||
midori_extension_install_integer (extension, "button", MOUSE_GESTURES_BUTTON);
|
||||
|
||||
g_signal_connect (extension, "activate",
|
||||
G_CALLBACK (mouse_gestures_activate_cb), NULL);
|
||||
|
||||
return extension;
|
||||
}
|
|
@ -1,255 +0,0 @@
|
|||
/*
|
||||
Copyright (C) 2009 Matthias Kruk <mkruk@matthiaskruk.de>
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
See the file COPYING for the full license text.
|
||||
*/
|
||||
|
||||
#include <midori/midori.h>
|
||||
#include "mouse-gestures.h"
|
||||
|
||||
#define MOUSE_GESTURES_VERSION "0.1"
|
||||
#define DEVIANCE 20
|
||||
#define MINLENGTH 50
|
||||
|
||||
/* #define __MOUSE_GESTURES_DEBUG__ */
|
||||
|
||||
MouseGesture *gesture;
|
||||
|
||||
void mouse_gesture_clear (MouseGesture *g)
|
||||
{
|
||||
g->start.x = 0;
|
||||
g->start.y = 0;
|
||||
g->middle.x = 0;
|
||||
g->middle.y = 0;
|
||||
g->end.x = 0;
|
||||
g->end.y = 0;
|
||||
g->last = MOUSE_BUTTON_UNSET;
|
||||
}
|
||||
|
||||
MouseGesture* mouse_gesture_new (void)
|
||||
{
|
||||
MouseGesture *g = g_new (MouseGesture, 1);
|
||||
mouse_gesture_clear (g);
|
||||
|
||||
return g;
|
||||
}
|
||||
|
||||
static gboolean mouse_gestures_handle_events (GtkWidget *widget,
|
||||
GdkEvent *event,
|
||||
MidoriBrowser *browser)
|
||||
{
|
||||
/* A button was pressed */
|
||||
if (event->type == GDK_BUTTON_PRESS && event->button.button == 2)
|
||||
{
|
||||
/* If the gesture was previously cleaned, start a new gesture and coordinates */
|
||||
if (gesture->last == MOUSE_BUTTON_UNSET)
|
||||
{
|
||||
gesture->start.x = event->button.x;
|
||||
gesture->start.y = event->button.y;
|
||||
gesture->last = event->button.button;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
else if (event->type == GDK_MOTION_NOTIFY)
|
||||
{
|
||||
if (gesture->last != MOUSE_BUTTON_UNSET)
|
||||
{
|
||||
guint x, y;
|
||||
|
||||
x = event->motion.x;
|
||||
y = event->motion.y;
|
||||
|
||||
if ((gesture->start.x - x < DEVIANCE && gesture->start.x - x > -DEVIANCE) ||
|
||||
(gesture->start.y - y < DEVIANCE && gesture->start.y - y > -DEVIANCE))
|
||||
{
|
||||
gesture->middle.x = x;
|
||||
gesture->middle.y = y;
|
||||
}
|
||||
else if ((gesture->middle.x - x < DEVIANCE && gesture->middle.x - x > -DEVIANCE) ||
|
||||
(gesture->middle.y - y < DEVIANCE && gesture->middle.y - y > -DEVIANCE))
|
||||
{
|
||||
gesture->end.x = x;
|
||||
gesture->end.y = y;
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
else if (event->type == GDK_BUTTON_RELEASE)
|
||||
{
|
||||
/* All mouse gestures will use the middle mouse button */
|
||||
if (gesture->last == MOUSE_BUTTON_MIDDLE)
|
||||
{
|
||||
/* The initial horizontal move is between the bounds */
|
||||
if ((gesture->middle.x - gesture->start.x < DEVIANCE) &&
|
||||
(gesture->middle.x - gesture->start.x > -DEVIANCE))
|
||||
{
|
||||
/* We initially moved down more than MINLENGTH pixels */
|
||||
if (gesture->middle.y > gesture->start.y + MINLENGTH)
|
||||
{
|
||||
/* Then we the final vertical move is between the bounds and
|
||||
we moved right more than MINLENGTH pixels */
|
||||
if ((gesture->middle.y - gesture->end.y < DEVIANCE) &&
|
||||
(gesture->middle.y - gesture->end.y > -DEVIANCE) &&
|
||||
(gesture->end.x > gesture->middle.x + MINLENGTH))
|
||||
{
|
||||
/* We moved down then right: close the tab */
|
||||
midori_browser_activate_action (browser, "TabClose");
|
||||
}
|
||||
/* Then we the final vertical move is between the bounds and
|
||||
we moved left more than MINLENGTH pixels */
|
||||
else if ((gesture->middle.y - gesture->end.y < DEVIANCE) &&
|
||||
(gesture->middle.y - gesture->end.y > -DEVIANCE) &&
|
||||
(gesture->end.x + MINLENGTH < gesture->middle.x))
|
||||
{
|
||||
/* We moved down then left: reload */
|
||||
midori_browser_activate_action (browser, "Reload");
|
||||
}
|
||||
/* The end node was never updated, we only did a vertical move */
|
||||
else if(gesture->end.y == 0 && gesture->end.x == 0)
|
||||
{
|
||||
/* We moved down then: create a new tab */
|
||||
midori_browser_activate_action (browser, "TabNew");
|
||||
}
|
||||
}
|
||||
/* We initially moved up more than MINLENGTH pixels */
|
||||
else if (gesture->middle.y + MINLENGTH < gesture->start.y)
|
||||
{
|
||||
/* The end node was never updated, we only did a vertical move */
|
||||
if (gesture->end.y == 0 && gesture->end.x == 0)
|
||||
{
|
||||
/* We moved up: stop */
|
||||
midori_browser_activate_action (browser, "Stop");
|
||||
}
|
||||
}
|
||||
}
|
||||
/* The initial horizontal move is between the bounds */
|
||||
else if ((gesture->middle.y - gesture->start.y < DEVIANCE) &&
|
||||
(gesture->middle.y - gesture->start.y > -DEVIANCE))
|
||||
{
|
||||
/* We initially moved right more than MINLENGTH pixels */
|
||||
if (gesture->middle.x > gesture->start.x + MINLENGTH)
|
||||
{
|
||||
/* The end node was never updated, we only did an horizontal move */
|
||||
if (gesture->end.x == 0 && gesture->end.y == 0)
|
||||
{
|
||||
/* We moved right: forward */
|
||||
midori_browser_activate_action (browser, "Forward");
|
||||
}
|
||||
}
|
||||
/* We initially moved left more than MINLENGTH pixels */
|
||||
else if (gesture->middle.x + MINLENGTH < gesture->start.x)
|
||||
{
|
||||
/* The end node was never updated, we only did an horizontal move */
|
||||
if (gesture->end.x == 0 && gesture->end.y == 0)
|
||||
{
|
||||
/* We moved left: back */
|
||||
midori_browser_activate_action (browser, "Back");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mouse_gesture_clear (gesture);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void mouse_gestures_tab_cb (MidoriBrowser* browser, GtkWidget *view)
|
||||
{
|
||||
g_signal_connect (view, "event", G_CALLBACK (mouse_gestures_handle_events), browser);
|
||||
}
|
||||
|
||||
static void mouse_gestures_browser_cb (MidoriApp *app, MidoriBrowser *browser)
|
||||
{
|
||||
g_signal_connect (browser, "add-tab", G_CALLBACK (mouse_gestures_tab_cb), NULL);
|
||||
}
|
||||
|
||||
static void mouse_gestures_deactivate (MidoriExtension *extension, MidoriApp *app)
|
||||
{
|
||||
gulong signal_id;
|
||||
KatzeArray* browsers;
|
||||
MidoriBrowser* browser;
|
||||
guint i;
|
||||
|
||||
signal_id = g_signal_handler_find (app, G_SIGNAL_MATCH_FUNC, 0, 0, NULL,
|
||||
mouse_gestures_browser_cb, NULL);
|
||||
|
||||
if (signal_id != 0)
|
||||
g_signal_handler_disconnect (app, signal_id);
|
||||
|
||||
browsers = katze_object_get_object (app, "browsers");
|
||||
i = 0;
|
||||
while ((browser = katze_array_get_nth_item (browsers, i++)))
|
||||
{
|
||||
gint j;
|
||||
GtkWidget* notebook;
|
||||
|
||||
signal_id = g_signal_handler_find (browser, G_SIGNAL_MATCH_FUNC,
|
||||
0, 0, NULL, mouse_gestures_tab_cb, NULL);
|
||||
if (signal_id != 0)
|
||||
g_signal_handler_disconnect (browser, signal_id);
|
||||
|
||||
notebook = katze_object_get_object (browser, "notebook");
|
||||
|
||||
for (j = 0; j < gtk_notebook_get_n_pages (GTK_NOTEBOOK (notebook)); j++)
|
||||
{
|
||||
GtkWidget *page = gtk_notebook_get_nth_page (GTK_NOTEBOOK (notebook), j);
|
||||
|
||||
signal_id = g_signal_handler_find (page, G_SIGNAL_MATCH_FUNC,
|
||||
0, 0, NULL, mouse_gestures_handle_events, NULL);
|
||||
|
||||
if (signal_id != 0)
|
||||
g_signal_handler_disconnect (page, signal_id);
|
||||
}
|
||||
}
|
||||
g_object_unref (browsers);
|
||||
|
||||
g_signal_handlers_disconnect_by_func (extension, mouse_gestures_deactivate, app);
|
||||
g_free (gesture);
|
||||
}
|
||||
|
||||
static void mouse_gestures_activate (MidoriExtension *extension, MidoriApp *app)
|
||||
{
|
||||
KatzeArray* browsers;
|
||||
MidoriBrowser* browser;
|
||||
guint i;
|
||||
|
||||
gesture = mouse_gesture_new ();
|
||||
|
||||
browsers = katze_object_get_object (app, "browsers");
|
||||
i = 0;
|
||||
while ((browser = katze_array_get_nth_item (browsers, i++)))
|
||||
mouse_gestures_browser_cb (app, browser);
|
||||
g_object_unref (browsers);
|
||||
|
||||
g_signal_connect (app, "add-browser",
|
||||
G_CALLBACK (mouse_gestures_browser_cb), NULL);
|
||||
g_signal_connect (extension, "deactivate",
|
||||
G_CALLBACK (mouse_gestures_deactivate), app);
|
||||
}
|
||||
|
||||
MidoriExtension* extension_init (void)
|
||||
{
|
||||
MidoriExtension* extension;
|
||||
|
||||
extension = g_object_new (MIDORI_TYPE_EXTENSION,
|
||||
"name", _("Mouse Gestures"),
|
||||
"description", _("Control Midori by moving the mouse"),
|
||||
"version", MOUSE_GESTURES_VERSION,
|
||||
"authors", "Matthias Kruk <mkruk@matthiaskruk.de>", NULL);
|
||||
|
||||
g_signal_connect (extension, "activate",
|
||||
G_CALLBACK (mouse_gestures_activate), NULL);
|
||||
|
||||
return extension;
|
||||
}
|
|
@ -1,37 +0,0 @@
|
|||
/*
|
||||
Copyright (C) 2009 Matthias Kruk <mkruk@matthiaskruk.de>
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
See the file COPYING for the full license text.
|
||||
*/
|
||||
|
||||
#ifndef __MOUSE_GESTURES_H__
|
||||
#define __MOUSE_GESTURES_H__
|
||||
|
||||
typedef struct _MouseGesture MouseGesture;
|
||||
typedef enum _MouseButton MouseButton;
|
||||
|
||||
enum _MouseButton {
|
||||
MOUSE_BUTTON_LEFT = 1,
|
||||
MOUSE_BUTTON_RIGHT = 3,
|
||||
MOUSE_BUTTON_MIDDLE = 2,
|
||||
MOUSE_BUTTON_UNSET = 0
|
||||
};
|
||||
|
||||
struct MouseGestureNode {
|
||||
double x;
|
||||
double y;
|
||||
} MouseGestureNode_t;
|
||||
|
||||
struct _MouseGesture {
|
||||
struct MouseGestureNode start;
|
||||
struct MouseGestureNode middle;
|
||||
struct MouseGestureNode end;
|
||||
MouseButton last;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -175,7 +175,7 @@ extension_init (void)
|
|||
|
||||
MidoriExtension* extension = g_object_new (MIDORI_TYPE_EXTENSION,
|
||||
"name", _("Pageholder"),
|
||||
"description", "",
|
||||
"description", _("Keep one or multiple pages open in parallel to your tabs"),
|
||||
"version", "0.1",
|
||||
"authors", "Christian Dywan <christian@twotoasts.de>",
|
||||
NULL);
|
||||
|
|
|
@ -38,67 +38,6 @@ shortcuts_deactivate_cb (MidoriExtension* extension,
|
|||
app, shortcuts_app_add_browser_cb, extension);
|
||||
}
|
||||
|
||||
static void
|
||||
shortcuts_preferences_render_text (GtkTreeViewColumn* column,
|
||||
GtkCellRenderer* renderer,
|
||||
GtkTreeModel* model,
|
||||
GtkTreeIter* iter,
|
||||
MidoriExtension* extension)
|
||||
{
|
||||
GtkAction* action;
|
||||
gchar* label;
|
||||
gchar* stripped;
|
||||
|
||||
gtk_tree_model_get (model, iter, 0, &action, -1);
|
||||
if ((label = katze_object_get_string (action, "label")))
|
||||
stripped = katze_strip_mnemonics (label);
|
||||
else
|
||||
{
|
||||
GtkStockItem item;
|
||||
g_object_get (action, "stock-id", &label, NULL);
|
||||
if (gtk_stock_lookup (label, &item))
|
||||
stripped = katze_strip_mnemonics (item.label);
|
||||
else
|
||||
stripped = g_strdup ("");
|
||||
}
|
||||
g_free (label);
|
||||
g_object_set (renderer, "text", stripped, NULL);
|
||||
g_free (stripped);
|
||||
g_object_unref (action);
|
||||
}
|
||||
|
||||
static void
|
||||
shortcuts_preferences_render_accel (GtkTreeViewColumn* column,
|
||||
GtkCellRenderer* renderer,
|
||||
GtkTreeModel* model,
|
||||
GtkTreeIter* iter,
|
||||
MidoriExtension* extension)
|
||||
{
|
||||
GtkAction* action;
|
||||
const gchar* accel_path;
|
||||
GtkAccelKey key;
|
||||
|
||||
gtk_tree_model_get (model, iter, 0, &action, -1);
|
||||
accel_path = gtk_action_get_accel_path (action);
|
||||
if (accel_path)
|
||||
{
|
||||
if (gtk_accel_map_lookup_entry (accel_path, &key))
|
||||
{
|
||||
if (key.accel_key)
|
||||
g_object_set (renderer,
|
||||
"accel-key", key.accel_key,
|
||||
"accel-mods", key.accel_mods,
|
||||
NULL);
|
||||
else
|
||||
g_object_set (renderer, "text", _("None"), NULL);
|
||||
}
|
||||
g_object_set (renderer, "sensitive", TRUE, "editable", TRUE, NULL);
|
||||
}
|
||||
else
|
||||
g_object_set (renderer, "text", "", "sensitive", FALSE, NULL);
|
||||
g_object_unref (action);
|
||||
}
|
||||
|
||||
static void
|
||||
shortcuts_accel_edited_cb (GtkCellRenderer* renderer,
|
||||
const gchar* tree_path,
|
||||
|
@ -113,11 +52,19 @@ shortcuts_accel_edited_cb (GtkCellRenderer* renderer,
|
|||
{
|
||||
GtkAction* action;
|
||||
const gchar* accel_path;
|
||||
GtkTreeIter child_iter;
|
||||
GtkTreeModel* liststore;
|
||||
|
||||
gtk_tree_model_get (model, &iter, 0, &action, -1);
|
||||
gtk_tree_model_get (model, &iter, 6, &action, -1);
|
||||
accel_path = gtk_action_get_accel_path (action);
|
||||
gtk_accel_map_change_entry (accel_path, accel_key, accel_mods, TRUE);
|
||||
|
||||
gtk_tree_model_sort_convert_iter_to_child_iter (GTK_TREE_MODEL_SORT (model),
|
||||
&child_iter, &iter);
|
||||
liststore = gtk_tree_model_sort_get_model (GTK_TREE_MODEL_SORT (model));
|
||||
gtk_list_store_set (GTK_LIST_STORE (liststore),
|
||||
&child_iter, 1, accel_key, 2, accel_mods, -1);
|
||||
|
||||
g_object_unref (action);
|
||||
}
|
||||
}
|
||||
|
@ -133,15 +80,58 @@ shortcuts_accel_cleared_cb (GtkCellRenderer* renderer,
|
|||
{
|
||||
GtkAction* action;
|
||||
const gchar* accel_path;
|
||||
GtkTreeIter child_iter;
|
||||
GtkTreeModel* liststore;
|
||||
|
||||
gtk_tree_model_get (model, &iter, 0, &action, -1);
|
||||
gtk_tree_model_get (model, &iter, 6, &action, -1);
|
||||
accel_path = gtk_action_get_accel_path (action);
|
||||
gtk_accel_map_change_entry (accel_path, 0, 0, FALSE);
|
||||
|
||||
gtk_tree_model_sort_convert_iter_to_child_iter (GTK_TREE_MODEL_SORT (model),
|
||||
&child_iter, &iter);
|
||||
liststore = gtk_tree_model_sort_get_model (GTK_TREE_MODEL_SORT (model));
|
||||
gtk_list_store_set (GTK_LIST_STORE (liststore),
|
||||
&child_iter, 1, 0, 2, 0, -1);
|
||||
|
||||
g_object_unref (action);
|
||||
}
|
||||
}
|
||||
|
||||
static gchar*
|
||||
shortcuts_label_for_action (GtkAction* action)
|
||||
{
|
||||
gchar* label;
|
||||
gchar* stripped;
|
||||
|
||||
if ((label = katze_object_get_string (action, "label")))
|
||||
stripped = katze_strip_mnemonics (label);
|
||||
else
|
||||
{
|
||||
GtkStockItem item;
|
||||
|
||||
g_object_get (action, "stock-id", &label, NULL);
|
||||
if (gtk_stock_lookup (label, &item))
|
||||
stripped = katze_strip_mnemonics (item.label);
|
||||
else
|
||||
stripped = g_strdup ("");
|
||||
}
|
||||
|
||||
g_free (label);
|
||||
return stripped;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
shortcuts_hotkey_for_action (GtkAction* action,
|
||||
GtkAccelKey* key)
|
||||
{
|
||||
const gchar* accel_path = gtk_action_get_accel_path (action);
|
||||
if (accel_path)
|
||||
if (gtk_accel_map_lookup_entry (accel_path, key))
|
||||
return TRUE;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static GtkWidget*
|
||||
shortcuts_get_preferences_dialog (MidoriExtension* extension)
|
||||
{
|
||||
|
@ -153,10 +143,10 @@ shortcuts_get_preferences_dialog (MidoriExtension* extension)
|
|||
GtkWidget* xfce_heading;
|
||||
GtkWidget* hbox;
|
||||
GtkListStore* liststore;
|
||||
GtkTreeModel* model;
|
||||
GtkWidget* treeview;
|
||||
GtkTreeViewColumn* column;
|
||||
GtkCellRenderer* renderer_text;
|
||||
GtkCellRenderer* renderer_accel;
|
||||
GtkCellRenderer* renderer;
|
||||
GtkWidget* scrolled;
|
||||
GtkActionGroup* action_group;
|
||||
GList* actions;
|
||||
|
@ -190,26 +180,29 @@ shortcuts_get_preferences_dialog (MidoriExtension* extension)
|
|||
hbox = gtk_hbox_new (FALSE, 0);
|
||||
gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), hbox,
|
||||
TRUE, TRUE, 12);
|
||||
liststore = gtk_list_store_new (1, GTK_TYPE_ACTION);
|
||||
treeview = gtk_tree_view_new_with_model (GTK_TREE_MODEL (liststore));
|
||||
liststore = gtk_list_store_new (7,
|
||||
G_TYPE_STRING, G_TYPE_INT, G_TYPE_INT, G_TYPE_INT, G_TYPE_BOOLEAN,
|
||||
G_TYPE_STRING, GTK_TYPE_ACTION);
|
||||
model = gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL (liststore));
|
||||
treeview = gtk_tree_view_new_with_model (model);
|
||||
gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (treeview), FALSE);
|
||||
column = gtk_tree_view_column_new ();
|
||||
renderer_text = gtk_cell_renderer_text_new ();
|
||||
gtk_tree_view_column_pack_start (column, renderer_text, FALSE);
|
||||
gtk_tree_view_column_set_cell_data_func (column, renderer_text,
|
||||
(GtkTreeCellDataFunc)shortcuts_preferences_render_text,
|
||||
extension, NULL);
|
||||
renderer = gtk_cell_renderer_text_new ();
|
||||
gtk_tree_view_column_pack_start (column, renderer, FALSE);
|
||||
gtk_cell_layout_add_attribute (GTK_CELL_LAYOUT (column), renderer, "text", 0);
|
||||
gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column);
|
||||
column = gtk_tree_view_column_new ();
|
||||
renderer_accel = gtk_cell_renderer_accel_new ();
|
||||
gtk_tree_view_column_pack_start (column, renderer_accel, TRUE);
|
||||
gtk_tree_view_column_set_cell_data_func (column, renderer_accel,
|
||||
(GtkTreeCellDataFunc)shortcuts_preferences_render_accel,
|
||||
extension, NULL);
|
||||
g_signal_connect (renderer_accel, "accel-edited",
|
||||
G_CALLBACK (shortcuts_accel_edited_cb), liststore);
|
||||
g_signal_connect (renderer_accel, "accel-cleared",
|
||||
G_CALLBACK (shortcuts_accel_cleared_cb), liststore);
|
||||
renderer = gtk_cell_renderer_accel_new ();
|
||||
gtk_tree_view_column_pack_start (column, renderer, TRUE);
|
||||
gtk_cell_layout_add_attribute (GTK_CELL_LAYOUT (column), renderer, "accel-key", 1);
|
||||
gtk_cell_layout_add_attribute (GTK_CELL_LAYOUT (column), renderer, "accel-mods", 2);
|
||||
gtk_cell_layout_add_attribute (GTK_CELL_LAYOUT (column), renderer, "accel-mode", 3);
|
||||
gtk_cell_layout_add_attribute (GTK_CELL_LAYOUT (column), renderer, "sensitive", 4);
|
||||
gtk_cell_layout_add_attribute (GTK_CELL_LAYOUT (column), renderer, "editable", 4);
|
||||
g_signal_connect (renderer, "accel-edited",
|
||||
G_CALLBACK (shortcuts_accel_edited_cb), model);
|
||||
g_signal_connect (renderer, "accel-cleared",
|
||||
G_CALLBACK (shortcuts_accel_cleared_cb), model);
|
||||
gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column);
|
||||
scrolled = gtk_scrolled_window_new (NULL, NULL);
|
||||
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled),
|
||||
|
@ -224,11 +217,22 @@ shortcuts_get_preferences_dialog (MidoriExtension* extension)
|
|||
i = 0;
|
||||
/* FIXME: Catch added and removed actions */
|
||||
while ((action = g_list_nth_data (actions, i++)))
|
||||
{
|
||||
gchar* label = shortcuts_label_for_action (action);
|
||||
GtkAccelKey key;
|
||||
gboolean has_hotkey = shortcuts_hotkey_for_action (action, &key);
|
||||
gtk_list_store_insert_with_values (GTK_LIST_STORE (liststore),
|
||||
NULL, G_MAXINT, 0, action, -1);
|
||||
NULL, G_MAXINT, 0, label, 1, key.accel_key, 2, key.accel_mods,
|
||||
3, GTK_CELL_RENDERER_ACCEL_MODE_OTHER,
|
||||
4, has_hotkey, 6, action, -1);
|
||||
g_free (label);
|
||||
}
|
||||
g_list_free (actions);
|
||||
|
||||
g_object_unref (liststore);
|
||||
gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (model),
|
||||
0, GTK_SORT_ASCENDING);
|
||||
g_object_unref (model);
|
||||
|
||||
gtk_widget_show_all (GTK_DIALOG (dialog)->vbox);
|
||||
|
||||
|
|
|
@ -196,8 +196,7 @@ tab_panel_popup (GtkWidget* widget,
|
|||
{
|
||||
GtkWidget* menu = midori_view_get_tab_menu (MIDORI_VIEW (view));
|
||||
|
||||
sokoke_widget_popup (widget, GTK_MENU (menu),
|
||||
event, SOKOKE_MENU_POSITION_CURSOR);
|
||||
katze_widget_popup (widget, GTK_MENU (menu), event, KATZE_MENU_POSITION_CURSOR);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
|
@ -355,9 +354,12 @@ tab_panel_view_notify_title_cb (GtkWidget* view,
|
|||
GtkTreeIter iter;
|
||||
if (tab_panel_get_iter_for_view (model, &iter, view))
|
||||
{
|
||||
GtkWidget* label = midori_view_get_proxy_tab_label (MIDORI_VIEW (view));
|
||||
GtkStyle* style = gtk_widget_get_style (label);
|
||||
gtk_tree_store_set (GTK_TREE_STORE (model), &iter,
|
||||
4, title,
|
||||
5, midori_view_get_label_ellipsize (MIDORI_VIEW (view)), -1);
|
||||
5, midori_view_get_label_ellipsize (MIDORI_VIEW (view)),
|
||||
6, &style->bg[GTK_STATE_NORMAL], -1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -421,7 +423,7 @@ tab_panel_browser_add_tab_cb (MidoriBrowser* browser,
|
|||
|
||||
gtk_tree_store_insert_with_values (GTK_TREE_STORE (model),
|
||||
&iter, NULL, page, 0, view, 1, GTK_STOCK_CLOSE, 2, buttons,
|
||||
3, icon, 4, title, 5, ellipsize , -1);
|
||||
3, icon, 4, title, 5, ellipsize, 6, NULL, -1);
|
||||
}
|
||||
|
||||
if (!g_signal_handler_find (view, G_SIGNAL_MATCH_FUNC,
|
||||
|
@ -499,8 +501,8 @@ tab_panel_app_add_browser_cb (MidoriApp* app,
|
|||
|
||||
panel = katze_object_get_object (browser, "panel");
|
||||
|
||||
model = gtk_tree_store_new (6, MIDORI_TYPE_VIEW,
|
||||
G_TYPE_STRING, G_TYPE_BOOLEAN, GDK_TYPE_PIXBUF, G_TYPE_STRING, G_TYPE_INT);
|
||||
model = gtk_tree_store_new (7, MIDORI_TYPE_VIEW,
|
||||
G_TYPE_STRING, G_TYPE_BOOLEAN, GDK_TYPE_PIXBUF, G_TYPE_STRING, G_TYPE_INT, GDK_TYPE_COLOR);
|
||||
g_object_set_data (G_OBJECT (browser), "tab-panel-ext-model", model);
|
||||
treeview = gtk_tree_view_new_with_model (GTK_TREE_MODEL (model));
|
||||
gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (treeview), FALSE);
|
||||
|
@ -514,18 +516,19 @@ tab_panel_app_add_browser_cb (MidoriApp* app,
|
|||
renderer_pixbuf = gtk_cell_renderer_pixbuf_new ();
|
||||
gtk_tree_view_column_pack_start (column, renderer_pixbuf, FALSE);
|
||||
gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (column), renderer_pixbuf,
|
||||
"pixbuf", 3, NULL);
|
||||
"pixbuf", 3, "cell-background-gdk", 6, NULL);
|
||||
renderer_text = gtk_cell_renderer_text_new ();
|
||||
gtk_tree_view_column_pack_start (column, renderer_text, TRUE);
|
||||
gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (column), renderer_text,
|
||||
"text", 4, "ellipsize", 5, NULL);
|
||||
"text", 4, "ellipsize", 5, "cell-background-gdk", 6, NULL);
|
||||
gtk_tree_view_column_set_expand (column, TRUE);
|
||||
gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column);
|
||||
column = gtk_tree_view_column_new ();
|
||||
renderer_pixbuf = gtk_cell_renderer_pixbuf_new ();
|
||||
gtk_tree_view_column_pack_start (column, renderer_pixbuf, FALSE);
|
||||
gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (column), renderer_pixbuf,
|
||||
"stock-id", 1, "follow-state", 2, "visible", 2, NULL);
|
||||
"stock-id", 1, "follow-state", 2,
|
||||
"visible", 2, "cell-background-gdk", 6, NULL);
|
||||
gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column);
|
||||
g_object_connect (treeview,
|
||||
"signal::row-activated",
|
||||
|
|
415
extensions/tab-switcher.c
Normal file
415
extensions/tab-switcher.c
Normal file
|
@ -0,0 +1,415 @@
|
|||
/*
|
||||
Copyright (C) 2009 André Stösel <Midori-Plugin@PyIT.de>
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
See the file COPYING for the full license text.
|
||||
*/
|
||||
|
||||
#include <midori/midori.h>
|
||||
|
||||
enum { TAB_ICON, TAB_NAME, TAB_POINTER, TAB_CELL_COUNT };
|
||||
|
||||
static MidoriExtension *thisExtension;
|
||||
static gboolean switchEvent;
|
||||
|
||||
static GdkPixbuf* tab_selector_get_snapshot(MidoriView* view,
|
||||
gint maxwidth,
|
||||
gint maxheight)
|
||||
{
|
||||
GtkWidget* web_view;
|
||||
guint width, height;
|
||||
gfloat factor;
|
||||
|
||||
g_return_val_if_fail (MIDORI_IS_VIEW (view), NULL);
|
||||
web_view = gtk_bin_get_child (GTK_BIN (view));
|
||||
|
||||
if(maxwidth < 0) {
|
||||
maxwidth *= -1;
|
||||
}
|
||||
if(maxheight < 0) {
|
||||
maxheight *= -1;
|
||||
}
|
||||
|
||||
factor = MIN((gfloat) maxwidth / web_view->allocation.width, (gfloat) maxheight / web_view->allocation.height);
|
||||
width = (int)(factor * web_view->allocation.width);
|
||||
height = (int)(factor * web_view->allocation.height);
|
||||
|
||||
return midori_view_get_snapshot(view, width, height);
|
||||
}
|
||||
|
||||
static void tab_selector_list_foreach (GtkWidget *view,
|
||||
GtkListStore *store)
|
||||
{
|
||||
GtkTreeIter it;
|
||||
GdkPixbuf* icon = midori_view_get_icon (MIDORI_VIEW (view));
|
||||
const gchar *title = midori_view_get_display_title (MIDORI_VIEW (view));
|
||||
gtk_list_store_append (store, &it);
|
||||
gtk_list_store_set (store, &it, TAB_ICON, icon, -1);
|
||||
gtk_list_store_set (store, &it, TAB_NAME, title, -1);
|
||||
gtk_list_store_set (store, &it, TAB_POINTER, view, -1);
|
||||
}
|
||||
|
||||
static GtkWidget* tab_selector_init_window (MidoriBrowser *browser)
|
||||
{
|
||||
GList *list;
|
||||
gint col_offset;
|
||||
GtkCellRenderer *renderer;
|
||||
GtkTreeViewColumn *column;
|
||||
GtkWidget *window, *treeview, *sw, *hbox;
|
||||
GtkListStore *store;
|
||||
GtkWidget *page;
|
||||
GtkWidget *image;
|
||||
GdkPixbuf *snapshot;
|
||||
|
||||
window = gtk_window_new(GTK_WINDOW_POPUP);
|
||||
gtk_window_set_default_size(GTK_WINDOW(window), 320, 20);
|
||||
gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
|
||||
|
||||
|
||||
hbox = gtk_hbox_new(FALSE, 1);
|
||||
gtk_container_add(GTK_CONTAINER(window), hbox);
|
||||
gtk_container_set_border_width(GTK_CONTAINER(hbox), 1);
|
||||
|
||||
sw = gtk_scrolled_window_new (NULL, NULL);
|
||||
gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (sw),
|
||||
GTK_SHADOW_ETCHED_IN);
|
||||
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
|
||||
GTK_POLICY_NEVER,
|
||||
GTK_POLICY_AUTOMATIC);
|
||||
|
||||
gtk_box_pack_start (GTK_BOX (hbox), sw, TRUE, TRUE, 0);
|
||||
|
||||
store = gtk_list_store_new(TAB_CELL_COUNT, GDK_TYPE_PIXBUF, G_TYPE_STRING, G_TYPE_POINTER);
|
||||
treeview = gtk_tree_view_new_with_model(GTK_TREE_MODEL(store));
|
||||
g_object_set_data(G_OBJECT(window), "tab_selector_treeview", treeview);
|
||||
|
||||
list = g_object_get_data(G_OBJECT(browser), "tab_selector_list");
|
||||
g_list_foreach(list, (GFunc) tab_selector_list_foreach, store);
|
||||
|
||||
g_object_unref(store);
|
||||
g_object_set(treeview, "headers-visible", FALSE, NULL);
|
||||
|
||||
renderer = gtk_cell_renderer_pixbuf_new();
|
||||
|
||||
gtk_tree_view_insert_column_with_attributes(
|
||||
GTK_TREE_VIEW(treeview), -1, "Icon", renderer, "pixbuf", TAB_ICON, NULL);
|
||||
|
||||
renderer = gtk_cell_renderer_text_new();
|
||||
|
||||
col_offset = gtk_tree_view_insert_column_with_attributes(
|
||||
GTK_TREE_VIEW(treeview), -1, "Title", renderer, "text", TAB_NAME, NULL);
|
||||
column = gtk_tree_view_get_column (GTK_TREE_VIEW (treeview), col_offset - 1);
|
||||
gtk_tree_view_column_set_sizing (GTK_TREE_VIEW_COLUMN (column),
|
||||
GTK_TREE_VIEW_COLUMN_FIXED);
|
||||
gtk_tree_view_column_set_fixed_width (GTK_TREE_VIEW_COLUMN (column),
|
||||
midori_extension_get_integer(thisExtension, "TitleColumnWidth"));
|
||||
|
||||
gtk_container_add (GTK_CONTAINER (sw), treeview);
|
||||
|
||||
page = katze_object_get_object(browser, "tab");
|
||||
snapshot = tab_selector_get_snapshot(MIDORI_VIEW(page),
|
||||
midori_extension_get_integer(thisExtension, "TabPreviewWidth"),
|
||||
midori_extension_get_integer(thisExtension, "TabPreviewHeight"));
|
||||
image = gtk_image_new_from_pixbuf (snapshot);
|
||||
gtk_box_pack_start (GTK_BOX (hbox), image, TRUE, TRUE, 0);
|
||||
g_object_set_data(G_OBJECT(window), "tab_selector_image", image);
|
||||
|
||||
gtk_widget_show_all(window);
|
||||
|
||||
return window;
|
||||
}
|
||||
|
||||
static void tab_selector_window_walk ( GtkWidget *window,
|
||||
GdkEventKey *event,
|
||||
MidoriBrowser *browser)
|
||||
{
|
||||
gint *pindex, iindex, items;
|
||||
GtkWidget *view;
|
||||
GtkTreeIter iter;
|
||||
GtkTreePath *path;
|
||||
GtkTreeView *treeview;
|
||||
GtkTreeModel *model;
|
||||
GtkTreeViewColumn *column;
|
||||
|
||||
treeview = g_object_get_data (G_OBJECT (window), "tab_selector_treeview");
|
||||
model = gtk_tree_view_get_model (treeview);
|
||||
items = gtk_tree_model_iter_n_children (model, NULL) -1;
|
||||
gtk_tree_view_get_cursor (treeview, &path, &column);
|
||||
pindex = gtk_tree_path_get_indices (path);
|
||||
if(!pindex)
|
||||
return;
|
||||
iindex = *pindex;
|
||||
gtk_tree_path_free(path);
|
||||
|
||||
if (event->state & GDK_SHIFT_MASK)
|
||||
iindex = iindex == 0 ? items : iindex-1;
|
||||
else
|
||||
iindex = iindex == items ? 0 : iindex+1;
|
||||
|
||||
path = gtk_tree_path_new_from_indices(iindex, -1);
|
||||
column = gtk_tree_view_get_column (GTK_TREE_VIEW (treeview), 1);
|
||||
gtk_tree_view_set_cursor (GTK_TREE_VIEW (treeview), path, column, FALSE);
|
||||
|
||||
gtk_tree_model_get_iter (model, &iter, path);
|
||||
gtk_tree_model_get (model, &iter, TAB_POINTER, &view, -1);
|
||||
|
||||
if (midori_extension_get_boolean (thisExtension, "ShowTabInBackground")) {
|
||||
midori_browser_set_current_tab (browser, view);
|
||||
} else {
|
||||
GtkImage *image;
|
||||
GdkPixbuf *snapshot = tab_selector_get_snapshot(MIDORI_VIEW(view),
|
||||
midori_extension_get_integer(thisExtension, "TabPreviewWidth"),
|
||||
midori_extension_get_integer(thisExtension, "TabPreviewHeight"));
|
||||
image = g_object_get_data(G_OBJECT(window), "tab_selector_image");
|
||||
gtk_image_set_from_pixbuf(image, snapshot);
|
||||
}
|
||||
gtk_tree_path_free(path);
|
||||
}
|
||||
|
||||
static gboolean tab_selector_handle_events (GtkWidget *widget,
|
||||
GdkEventKey *event,
|
||||
MidoriBrowser *browser)
|
||||
{
|
||||
/* tab -> 23
|
||||
ctrl -> 37 */
|
||||
gint treeitems;
|
||||
static GtkWidget *window;
|
||||
if(event->type == GDK_KEY_PRESS && event->hardware_keycode == 23 && event->state & GDK_CONTROL_MASK) {
|
||||
treeitems = gtk_notebook_get_n_pages (GTK_NOTEBOOK (
|
||||
katze_object_get_object(browser, "notebook")));
|
||||
if(treeitems > 1) {
|
||||
if(!GTK_IS_WINDOW(window)) {
|
||||
switchEvent = FALSE;
|
||||
window = tab_selector_init_window(browser);
|
||||
}
|
||||
tab_selector_window_walk(window, event, browser);
|
||||
}
|
||||
return TRUE;
|
||||
} else if(event->type == GDK_KEY_RELEASE && event->hardware_keycode == 37 && GTK_IS_WINDOW(window)) {
|
||||
switchEvent = TRUE;
|
||||
if(midori_extension_get_boolean(thisExtension, "ShowTabInBackground")) {
|
||||
GtkWidget *page;
|
||||
page = katze_object_get_object(browser, "tab");
|
||||
|
||||
GList *list = g_object_get_data(G_OBJECT(browser), "tab_selector_list");
|
||||
list = g_list_remove(list, page);
|
||||
list = g_list_prepend(list, page);
|
||||
g_object_set_data(G_OBJECT(browser), "tab_selector_list", list);
|
||||
} else {
|
||||
GtkTreePath *path;
|
||||
GtkTreeViewColumn *column;
|
||||
GtkTreeIter iter;
|
||||
GtkWidget *view, *treeview;
|
||||
GtkTreeModel *model;
|
||||
|
||||
treeview = g_object_get_data(G_OBJECT(window), "tab_selector_treeview");
|
||||
model = gtk_tree_view_get_model(GTK_TREE_VIEW(treeview));
|
||||
|
||||
gtk_tree_view_get_cursor (
|
||||
GTK_TREE_VIEW(treeview), &path, &column);
|
||||
gtk_tree_model_get_iter (
|
||||
model, &iter, path);
|
||||
gtk_tree_model_get (
|
||||
model, &iter, TAB_POINTER, &view, -1);
|
||||
midori_browser_set_current_tab (browser, view);
|
||||
gtk_tree_path_free (path);
|
||||
}
|
||||
gtk_widget_destroy(window);
|
||||
window = NULL;
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void tab_selector_switch_page (GtkNotebook *notebook,
|
||||
GtkNotebookPage *page_,
|
||||
guint page_num,
|
||||
MidoriBrowser *browser)
|
||||
{
|
||||
if(switchEvent) {
|
||||
/* Don't know why *page_ points to the wrong address */
|
||||
GtkWidget *page;
|
||||
page = katze_object_get_object(browser, "tab");
|
||||
|
||||
GList *list = g_object_get_data(G_OBJECT(browser), "tab_selector_list");
|
||||
list = g_list_remove(list, page);
|
||||
list = g_list_prepend(list, page);
|
||||
g_object_set_data(G_OBJECT(browser), "tab_selector_list", list);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
tab_selector_browser_add_tab_cb (MidoriBrowser *browser,
|
||||
GtkWidget *view,
|
||||
MidoriExtension *extension)
|
||||
{
|
||||
g_signal_connect (view, "key_press_event",
|
||||
G_CALLBACK (tab_selector_handle_events), browser);
|
||||
g_signal_connect (view, "key_release_event",
|
||||
G_CALLBACK (tab_selector_handle_events), browser);
|
||||
|
||||
GList *list = g_object_get_data(G_OBJECT(browser), "tab_selector_list");
|
||||
list = g_list_append(list, view);
|
||||
g_object_set_data(G_OBJECT(browser), "tab_selector_list", list);
|
||||
}
|
||||
|
||||
static void
|
||||
tab_selector_browser_remove_tab_cb (MidoriBrowser *browser,
|
||||
GtkWidget *view,
|
||||
MidoriExtension *extension)
|
||||
{
|
||||
GList *list = g_object_get_data(G_OBJECT(browser), "tab_selector_list");
|
||||
list = g_list_remove(list, view);
|
||||
g_object_set_data(G_OBJECT(browser), "tab_selector_list", list);
|
||||
}
|
||||
|
||||
static void
|
||||
tab_selector_disconnect_tab_cb (GtkWidget *view,
|
||||
MidoriBrowser *browser)
|
||||
{
|
||||
g_signal_handlers_disconnect_by_func (
|
||||
view, tab_selector_handle_events, browser);
|
||||
}
|
||||
|
||||
static void
|
||||
tab_selector_app_add_browser_cb (MidoriApp *app,
|
||||
MidoriBrowser *browser,
|
||||
MidoriExtension *extension)
|
||||
{
|
||||
GtkWidget *navigationbar, *notebook;
|
||||
|
||||
g_object_set_data(G_OBJECT(browser), "tab_selector_list", NULL);
|
||||
|
||||
g_signal_connect (browser, "add-tab",
|
||||
G_CALLBACK (tab_selector_browser_add_tab_cb), extension);
|
||||
g_signal_connect (browser, "remove-tab",
|
||||
G_CALLBACK (tab_selector_browser_remove_tab_cb), extension);
|
||||
|
||||
navigationbar = katze_object_get_object(browser, "navigationbar");
|
||||
g_signal_connect (navigationbar, "key_press_event",
|
||||
G_CALLBACK (tab_selector_handle_events), browser);
|
||||
g_signal_connect (navigationbar, "key_release_event",
|
||||
G_CALLBACK (tab_selector_handle_events), browser);
|
||||
g_object_unref(navigationbar);
|
||||
|
||||
notebook = katze_object_get_object(browser, "notebook");
|
||||
g_signal_connect_after (notebook, "switch-page",
|
||||
G_CALLBACK (tab_selector_switch_page), browser);
|
||||
g_object_unref(notebook);
|
||||
}
|
||||
|
||||
static void
|
||||
tab_selector_app_remove_browser_cb (MidoriApp *app,
|
||||
MidoriBrowser *browser,
|
||||
MidoriExtension *extension)
|
||||
{
|
||||
GList *list = g_object_get_data (G_OBJECT (browser), "tab_selector_list");
|
||||
g_list_free (list);
|
||||
}
|
||||
|
||||
static void
|
||||
tab_selector_disconnect_browser_cb (MidoriApp *app,
|
||||
MidoriBrowser *browser,
|
||||
MidoriExtension *extension)
|
||||
{
|
||||
GtkWidget *navigationbar, *notebook;
|
||||
|
||||
midori_browser_foreach (browser,
|
||||
(GtkCallback)tab_selector_disconnect_tab_cb, browser);
|
||||
|
||||
g_signal_handlers_disconnect_by_func (
|
||||
browser, tab_selector_browser_add_tab_cb, extension);
|
||||
g_signal_handlers_disconnect_by_func (
|
||||
browser, tab_selector_browser_remove_tab_cb, extension);
|
||||
g_signal_handlers_disconnect_by_func (
|
||||
katze_object_get_object (browser, "navigationbar"),
|
||||
tab_selector_handle_events, browser);
|
||||
|
||||
navigationbar = katze_object_get_object (browser, "navigationbar");
|
||||
g_signal_handlers_disconnect_by_func (navigationbar,
|
||||
tab_selector_handle_events, browser);
|
||||
g_signal_handlers_disconnect_by_func (navigationbar,
|
||||
tab_selector_handle_events, browser);
|
||||
g_object_unref (navigationbar);
|
||||
|
||||
notebook = katze_object_get_object (browser, "notebook");
|
||||
g_signal_handlers_disconnect_by_func (notebook,
|
||||
tab_selector_switch_page, browser);
|
||||
g_object_unref (notebook);
|
||||
}
|
||||
|
||||
static void
|
||||
tab_selector_activate_cb (MidoriExtension *extension,
|
||||
MidoriApp *app)
|
||||
{
|
||||
GtkWidget *view;
|
||||
KatzeArray *browsers;
|
||||
MidoriBrowser *browser;
|
||||
guint i, j;
|
||||
|
||||
browsers = katze_object_get_object (app, "browsers");
|
||||
i = 0;
|
||||
while ((browser = katze_array_get_nth_item (browsers, i++))) {
|
||||
j = 0;
|
||||
tab_selector_app_add_browser_cb (app, browser, extension);
|
||||
while((view = midori_browser_get_nth_tab(browser, j++)))
|
||||
tab_selector_browser_add_tab_cb(browser, view, extension);
|
||||
}
|
||||
g_object_unref (browsers);
|
||||
g_signal_connect (app, "add-browser",
|
||||
G_CALLBACK (tab_selector_app_add_browser_cb), extension);
|
||||
g_signal_connect (app, "remove-browser",
|
||||
G_CALLBACK (tab_selector_app_remove_browser_cb), extension);
|
||||
}
|
||||
|
||||
static void
|
||||
tab_selector_deactivate_cb (MidoriExtension *extension,
|
||||
GtkWidget *foo)
|
||||
{
|
||||
MidoriApp* app = midori_extension_get_app (extension);
|
||||
KatzeArray *browsers;
|
||||
MidoriBrowser *browser;
|
||||
guint i;
|
||||
|
||||
g_signal_handlers_disconnect_by_func (
|
||||
app, tab_selector_app_add_browser_cb, extension);
|
||||
g_signal_handlers_disconnect_by_func (
|
||||
app, tab_selector_app_remove_browser_cb, extension);
|
||||
|
||||
browsers = katze_object_get_object (app, "browsers");
|
||||
i = 0;
|
||||
while ((browser = katze_array_get_nth_item (browsers, i++)))
|
||||
tab_selector_disconnect_browser_cb (app, browser, extension);
|
||||
g_object_unref (browsers);
|
||||
}
|
||||
|
||||
MidoriExtension*
|
||||
extension_init (void)
|
||||
{
|
||||
MidoriExtension *extension = g_object_new (MIDORI_TYPE_EXTENSION,
|
||||
"name", _("Tab History List"),
|
||||
"description", _("Allows to switch tabs by choosing from a "
|
||||
"list sorted by last usage"),
|
||||
"version", "0.1",
|
||||
"authors", "André Stösel <Midori-Plugin@PyIT.de>",
|
||||
NULL);
|
||||
|
||||
g_signal_connect (extension, "activate",
|
||||
G_CALLBACK (tab_selector_activate_cb), NULL);
|
||||
g_signal_connect (extension, "deactivate",
|
||||
G_CALLBACK (tab_selector_deactivate_cb), NULL);
|
||||
|
||||
midori_extension_install_boolean (extension, "ShowTabInBackground", FALSE);
|
||||
midori_extension_install_integer (extension, "TitleColumnWidth", 300);
|
||||
midori_extension_install_integer (extension, "TabPreviewWidth", 200);
|
||||
midori_extension_install_integer (extension, "TabPreviewHeight", 200);
|
||||
thisExtension = extension;
|
||||
switchEvent = TRUE;
|
||||
|
||||
return extension;
|
||||
}
|
||||
|
605
extensions/web-cache.c
Normal file
605
extensions/web-cache.c
Normal file
|
@ -0,0 +1,605 @@
|
|||
/*
|
||||
Copyright (C) 2009 Christian Dywan <christian@twotoasts.de>
|
||||
Copyright (C) 2009 Alexander Butenko <a.butenka@gmail.com>
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
See the file COPYING for the full license text.
|
||||
*/
|
||||
|
||||
#include <midori/midori.h>
|
||||
|
||||
#include <midori/sokoke.h>
|
||||
#include "config.h"
|
||||
|
||||
#include <glib/gstdio.h>
|
||||
#include <stdlib.h>
|
||||
#if HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
static gboolean offline_mode = FALSE;
|
||||
#define HAVE_WEBKIT_RESOURCE_REQUEST WEBKIT_CHECK_VERSION (1, 1, 14)
|
||||
#define MAXLENGTH 1024 * 1024
|
||||
|
||||
static gchar*
|
||||
web_cache_get_cached_path (MidoriExtension* extension,
|
||||
const gchar* uri)
|
||||
{
|
||||
static const gchar* cache_path = NULL;
|
||||
gchar* checksum;
|
||||
gchar* folder;
|
||||
gchar* sub_path;
|
||||
gchar* encoded;
|
||||
gchar* ext;
|
||||
gchar* cached_filename;
|
||||
gchar* cached_path;
|
||||
|
||||
if (!cache_path)
|
||||
cache_path = midori_extension_get_string (extension, "path");
|
||||
checksum = g_compute_checksum_for_string (G_CHECKSUM_MD5, uri, -1);
|
||||
folder = g_strdup_printf ("%c%c", checksum[0], checksum[1]);
|
||||
sub_path = g_build_path (G_DIR_SEPARATOR_S, cache_path, folder, NULL);
|
||||
g_mkdir (sub_path, 0700);
|
||||
g_free (folder);
|
||||
|
||||
encoded = soup_uri_encode (uri, "/");
|
||||
ext = g_strdup (g_strrstr (encoded, "."));
|
||||
/* Make sure ext isn't becoming too long */
|
||||
if (ext && ext[0] && ext[1] && ext[2] && ext[3] && ext[4])
|
||||
ext[4] = '\0';
|
||||
cached_filename = g_strdup_printf ("%s%s", checksum, ext ? ext : "");
|
||||
g_free (ext);
|
||||
g_free (encoded);
|
||||
g_free (checksum);
|
||||
cached_path = g_build_filename (sub_path, cached_filename, NULL);
|
||||
g_free (cached_filename);
|
||||
return cached_path;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
web_cache_replace_frame_uri (MidoriExtension* extension,
|
||||
const gchar* uri,
|
||||
WebKitWebFrame* web_frame)
|
||||
{
|
||||
gchar* filename;
|
||||
gboolean handled = FALSE;
|
||||
|
||||
filename = web_cache_get_cached_path (extension, uri);
|
||||
|
||||
/* g_debug ("cache lookup: %s => %s", uri, filename); */
|
||||
|
||||
if (g_file_test (filename, G_FILE_TEST_EXISTS))
|
||||
{
|
||||
gchar* data;
|
||||
g_file_get_contents (filename, &data, NULL, NULL);
|
||||
webkit_web_frame_load_alternate_string (web_frame, data, NULL, uri);
|
||||
g_free (data);
|
||||
handled = TRUE;
|
||||
}
|
||||
|
||||
g_free (filename);
|
||||
return handled;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
web_cache_navigation_decision_cb (WebKitWebView* web_view,
|
||||
WebKitWebFrame* web_frame,
|
||||
WebKitNetworkRequest* request,
|
||||
WebKitWebNavigationAction* action,
|
||||
WebKitWebPolicyDecision* decision,
|
||||
MidoriExtension* extension)
|
||||
{
|
||||
const gchar* uri = webkit_network_request_get_uri (request);
|
||||
if (!(uri && g_str_has_prefix (uri, "http://")))
|
||||
return FALSE;
|
||||
if (offline_mode == FALSE)
|
||||
return FALSE;
|
||||
|
||||
return web_cache_replace_frame_uri (extension, uri, web_frame);
|
||||
}
|
||||
|
||||
#if WEBKIT_CHECK_VERSION (1, 1, 6)
|
||||
static gboolean
|
||||
web_cache_load_error_cb (WebKitWebView* web_view,
|
||||
WebKitWebFrame* web_frame,
|
||||
const gchar* uri,
|
||||
GError* error,
|
||||
MidoriExtension* extension)
|
||||
{
|
||||
if (offline_mode == FALSE)
|
||||
return FALSE;
|
||||
if (!(uri && g_str_has_prefix (uri, "http://")))
|
||||
return FALSE;
|
||||
|
||||
return web_cache_replace_frame_uri (extension, uri, web_frame);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
web_cache_save_headers (SoupMessage* msg,
|
||||
gchar* filename)
|
||||
{
|
||||
gchar* dsc_filename = g_strdup_printf ("%s.dsc.tmp", filename);
|
||||
SoupMessageHeaders* hdrs = msg->response_headers;
|
||||
SoupMessageHeadersIter iter;
|
||||
const gchar* name, *value;
|
||||
FILE* dscfd;
|
||||
|
||||
soup_message_headers_iter_init (&iter, hdrs);
|
||||
dscfd = g_fopen (dsc_filename, "w");
|
||||
while (soup_message_headers_iter_next (&iter, &name, &value))
|
||||
g_fprintf (dscfd, "%s: %s\n", name, value);
|
||||
fclose (dscfd);
|
||||
|
||||
g_free (dsc_filename);
|
||||
}
|
||||
|
||||
GHashTable*
|
||||
web_cache_get_headers (gchar* filename)
|
||||
{
|
||||
GHashTable* headers;
|
||||
FILE* file;
|
||||
gchar* dsc_filename;
|
||||
|
||||
headers = g_hash_table_new_full (g_str_hash, g_str_equal,
|
||||
(GDestroyNotify)g_free,
|
||||
(GDestroyNotify)g_free);
|
||||
|
||||
if (!filename)
|
||||
return headers;
|
||||
if (!g_file_test (filename, G_FILE_TEST_EXISTS))
|
||||
return headers;
|
||||
|
||||
dsc_filename = g_strdup_printf ("%s.dsc", filename);
|
||||
if (!g_file_test (dsc_filename, G_FILE_TEST_EXISTS))
|
||||
{
|
||||
g_free (dsc_filename);
|
||||
return headers;
|
||||
}
|
||||
if ((file = g_fopen (dsc_filename, "r")))
|
||||
{
|
||||
gchar line[128];
|
||||
while (fgets (line, 128, file))
|
||||
{
|
||||
if (line==NULL)
|
||||
continue;
|
||||
g_strchomp (line);
|
||||
gchar** data;
|
||||
data = g_strsplit (line, ":", 2);
|
||||
if (data[0] && data[1])
|
||||
g_hash_table_insert (headers, g_strdup (data[0]),
|
||||
g_strdup (g_strchug (data[1])));
|
||||
g_strfreev (data);
|
||||
}
|
||||
}
|
||||
fclose (file);
|
||||
/* g_hash_table_destroy (headers); */
|
||||
g_free (dsc_filename);
|
||||
return headers;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
web_cache_tmp_prepare (gchar* filename)
|
||||
{
|
||||
gchar* tmp_filename = g_strdup_printf ("%s.tmp", filename);
|
||||
|
||||
/* FIXME: If load was interruped we are ending up with a partical
|
||||
cache files forever */
|
||||
if (g_file_test (tmp_filename, G_FILE_TEST_EXISTS))
|
||||
{
|
||||
g_free (tmp_filename);
|
||||
return FALSE;
|
||||
}
|
||||
g_file_set_contents (tmp_filename, "", -1, NULL);
|
||||
g_free (tmp_filename);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
web_cache_set_content_type (SoupMessage* msg,
|
||||
SoupBuffer* buffer)
|
||||
{
|
||||
#if WEBKIT_CHECK_VERSION (1, 1, 15)
|
||||
const char *ct;
|
||||
SoupContentSniffer* sniffer = soup_content_sniffer_new ();
|
||||
ct = soup_content_sniffer_sniff (sniffer, msg, buffer, NULL);
|
||||
if (!ct)
|
||||
ct = soup_message_headers_get_one (msg->response_headers, "Content-Type");
|
||||
if (ct)
|
||||
g_signal_emit_by_name (msg, "content-sniffed", ct, NULL);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
web_cache_message_finished_cb (SoupMessage* msg,
|
||||
gchar* filename)
|
||||
{
|
||||
gchar* headers;
|
||||
gchar* tmp_headers;
|
||||
gchar* tmp_data;
|
||||
|
||||
headers = g_strdup_printf ("%s.dsc", filename);
|
||||
tmp_headers = g_strdup_printf ("%s.dsc.tmp", filename);
|
||||
tmp_data = g_strdup_printf ("%s.tmp", filename);
|
||||
|
||||
if (msg->status_code == SOUP_STATUS_OK)
|
||||
{
|
||||
g_rename (tmp_data, filename);
|
||||
g_rename (tmp_headers, headers);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_unlink (tmp_data);
|
||||
g_unlink (tmp_headers);
|
||||
}
|
||||
|
||||
g_free (headers);
|
||||
g_free (tmp_headers);
|
||||
g_free (tmp_data);
|
||||
}
|
||||
|
||||
static void
|
||||
web_cache_message_got_chunk_cb (SoupMessage* msg,
|
||||
SoupBuffer* chunk,
|
||||
gchar* filename)
|
||||
{
|
||||
GFile *file;
|
||||
GOutputStream *stream;
|
||||
gchar *tmp_filename;
|
||||
|
||||
if (!chunk->data || !chunk->length)
|
||||
return;
|
||||
|
||||
tmp_filename = g_strdup_printf ("%s.tmp", filename);
|
||||
file = g_file_new_for_path (tmp_filename);
|
||||
if ((stream = (GOutputStream*)g_file_append_to (file, 0, NULL, NULL)))
|
||||
{
|
||||
g_output_stream_write (stream, chunk->data, chunk->length, NULL, NULL);
|
||||
g_object_unref (stream);
|
||||
}
|
||||
g_object_unref (file);
|
||||
g_free (tmp_filename);
|
||||
}
|
||||
|
||||
static void
|
||||
web_cache_message_rewrite (SoupMessage* msg,
|
||||
gchar* filename)
|
||||
{
|
||||
GHashTable* cache_headers = web_cache_get_headers (filename);
|
||||
GHashTableIter iter;
|
||||
SoupBuffer *buffer;
|
||||
gpointer key, value;
|
||||
char *data;
|
||||
gsize length;
|
||||
|
||||
soup_message_set_status (msg, SOUP_STATUS_OK);
|
||||
g_hash_table_iter_init (&iter, cache_headers);
|
||||
while (g_hash_table_iter_next (&iter, &key, &value))
|
||||
soup_message_headers_replace (msg->response_headers, key, value);
|
||||
g_signal_emit_by_name (msg, "got-headers", NULL);
|
||||
|
||||
msg->response_body = soup_message_body_new ();
|
||||
g_file_get_contents (filename, &data, &length, NULL);
|
||||
if (data && length)
|
||||
{
|
||||
buffer = soup_buffer_new (SOUP_MEMORY_TEMPORARY, data, length);
|
||||
web_cache_set_content_type (msg, buffer);
|
||||
soup_message_body_append_buffer (msg->response_body, buffer);
|
||||
g_signal_emit_by_name (msg, "got-chunk", buffer, NULL);
|
||||
soup_buffer_free (buffer);
|
||||
}
|
||||
soup_message_got_body (msg);
|
||||
g_free (data);
|
||||
|
||||
#if 0
|
||||
if (offline_mode == TRUE)
|
||||
{
|
||||
/* Workaroung for offline mode
|
||||
FIXME: libsoup-CRITICAL **: queue_message: assertion `item != NULL' failed */
|
||||
SoupSession *session = webkit_get_default_session ();
|
||||
soup_session_requeue_message (session, msg);
|
||||
}
|
||||
soup_message_finished (msg);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
web_cache_mesage_got_headers_cb (SoupMessage* msg,
|
||||
MidoriExtension* extension)
|
||||
{
|
||||
SoupURI* soup_uri = soup_message_get_uri (msg);
|
||||
gchar* uri;
|
||||
gchar* filename;
|
||||
const gchar* nocache;
|
||||
SoupMessageHeaders *hdrs = msg->response_headers;
|
||||
|
||||
/* Skip files downloaded by the user */
|
||||
if (g_object_get_data (G_OBJECT (msg), "midori-web-cache-download"))
|
||||
return;
|
||||
|
||||
/* Skip big files */
|
||||
const char* cl = soup_message_headers_get_one (hdrs, "Content-Length");
|
||||
if (cl && atoi (cl) > MAXLENGTH)
|
||||
return;
|
||||
|
||||
nocache = soup_message_headers_get_one (hdrs, "Pragma");
|
||||
if (!nocache)
|
||||
nocache = soup_message_headers_get_one (hdrs, "Cache-Control");
|
||||
if (nocache && g_regex_match_simple ("no-cache|no-store", nocache,
|
||||
G_REGEX_CASELESS, G_REGEX_MATCH_NOTEMPTY))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
uri = soup_uri ? soup_uri_to_string (soup_uri, FALSE) : g_strdup ("");
|
||||
filename = web_cache_get_cached_path (extension, uri);
|
||||
if (msg->status_code == SOUP_STATUS_NOT_MODIFIED)
|
||||
{
|
||||
/* g_debug ("loading from cache: %s -> %s", uri, filename); */
|
||||
g_signal_handlers_disconnect_by_func (msg,
|
||||
web_cache_mesage_got_headers_cb, extension);
|
||||
web_cache_message_rewrite (msg, filename);
|
||||
g_free (filename);
|
||||
}
|
||||
else if (msg->status_code == SOUP_STATUS_OK)
|
||||
{
|
||||
/* g_debug ("updating cache: %s -> %s", uri, filename); */
|
||||
if (!web_cache_tmp_prepare (filename))
|
||||
return;
|
||||
web_cache_save_headers (msg, filename);
|
||||
g_signal_connect_data (msg, "got-chunk",
|
||||
G_CALLBACK (web_cache_message_got_chunk_cb),
|
||||
filename, (GClosureNotify)g_free, 0);
|
||||
g_signal_connect (msg, "finished",
|
||||
G_CALLBACK (web_cache_message_finished_cb), filename);
|
||||
}
|
||||
g_free (uri);
|
||||
}
|
||||
|
||||
#if HAVE_WEBKIT_RESOURCE_REQUEST
|
||||
static void
|
||||
web_cache_resource_request_starting_cb (WebKitWebView* web_view,
|
||||
WebKitWebFrame* web_frame,
|
||||
WebKitWebResource* web_resource,
|
||||
WebKitNetworkRequest* request,
|
||||
WebKitNetworkResponse* response,
|
||||
MidoriExtension* extension)
|
||||
{
|
||||
const gchar* uri;
|
||||
gchar* filename;
|
||||
/* TODO: Good place to check are we offline */
|
||||
uri = webkit_network_request_get_uri (request);
|
||||
if (!(uri && g_str_has_prefix (uri, "http://")))
|
||||
return;
|
||||
|
||||
if (offline_mode == FALSE)
|
||||
return;
|
||||
|
||||
filename = web_cache_get_cached_path (extension, uri);
|
||||
/* g_debug ("loading %s -> %s",uri, filename); */
|
||||
if (!g_file_test (filename, G_FILE_TEST_EXISTS))
|
||||
{
|
||||
g_free (filename);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(g_strcmp0 (uri, webkit_web_frame_get_uri (web_frame))
|
||||
&& g_strcmp0 (webkit_web_data_source_get_unreachable_uri (
|
||||
webkit_web_frame_get_data_source (web_frame)), uri)))
|
||||
{
|
||||
web_cache_replace_frame_uri (extension, uri, web_frame);
|
||||
g_free (filename);
|
||||
return;
|
||||
}
|
||||
|
||||
gchar* file_uri = g_filename_to_uri (filename, NULL, NULL);
|
||||
webkit_network_request_set_uri (request, file_uri);
|
||||
|
||||
g_free (file_uri);
|
||||
g_free (filename);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
web_cache_session_request_queued_cb (SoupSession* session,
|
||||
SoupMessage* msg,
|
||||
MidoriExtension* extension)
|
||||
{
|
||||
/*FIXME: Should we need to free soupuri? */
|
||||
SoupURI* soup_uri = soup_message_get_uri (msg);
|
||||
gchar* uri = soup_uri ? soup_uri_to_string (soup_uri, FALSE) : g_strdup ("");
|
||||
|
||||
/* For now we are handling only online mode here */
|
||||
if (offline_mode == TRUE)
|
||||
return;
|
||||
|
||||
if (g_str_has_prefix (uri, "http") && !g_strcmp0 (msg->method, "GET"))
|
||||
{
|
||||
gchar* filename = web_cache_get_cached_path (extension, uri);
|
||||
if (offline_mode == FALSE)
|
||||
{
|
||||
GHashTable* cache_headers;
|
||||
gchar* etag;
|
||||
gchar* last_modified;
|
||||
|
||||
cache_headers = web_cache_get_headers (filename);
|
||||
etag = g_hash_table_lookup (cache_headers, "ETag");
|
||||
last_modified = g_hash_table_lookup (cache_headers, "Last-Modified");
|
||||
if (etag)
|
||||
soup_message_headers_replace (msg->request_headers,
|
||||
"If-None-Match", etag);
|
||||
if (last_modified)
|
||||
soup_message_headers_replace (msg->request_headers,
|
||||
"If-Modified-Since", last_modified);
|
||||
g_signal_connect (msg, "got-headers",
|
||||
G_CALLBACK (web_cache_mesage_got_headers_cb), extension);
|
||||
|
||||
g_free (etag);
|
||||
g_free (last_modified);
|
||||
g_free (filename);
|
||||
/* FIXME: uncoment this is leading to a crash
|
||||
g_hash_table_destroy (cache_headers); */
|
||||
return;
|
||||
}
|
||||
/*
|
||||
else
|
||||
{
|
||||
g_debug("queued in offline mode: %s -> %s", uri, filename);
|
||||
if (g_file_test (filename, G_FILE_TEST_EXISTS))
|
||||
{
|
||||
soup_message_set_status (msg, SOUP_STATUS_NOT_MODIFIED);
|
||||
web_cache_message_rewrite (msg, filename);
|
||||
}
|
||||
}
|
||||
*/
|
||||
g_free (filename);
|
||||
}
|
||||
g_free (uri);
|
||||
}
|
||||
|
||||
static void
|
||||
web_cache_add_tab_cb (MidoriBrowser* browser,
|
||||
MidoriView* view,
|
||||
MidoriExtension* extension)
|
||||
{
|
||||
GtkWidget* web_view = gtk_bin_get_child (GTK_BIN (view));
|
||||
g_signal_connect (web_view, "navigation-policy-decision-requested",
|
||||
G_CALLBACK (web_cache_navigation_decision_cb), extension);
|
||||
|
||||
#if WEBKIT_CHECK_VERSION (1, 1, 6)
|
||||
g_signal_connect (web_view, "load-error",
|
||||
G_CALLBACK (web_cache_load_error_cb), extension);
|
||||
#endif
|
||||
|
||||
#if HAVE_WEBKIT_RESOURCE_REQUEST
|
||||
g_signal_connect (web_view, "resource-request-starting",
|
||||
G_CALLBACK (web_cache_resource_request_starting_cb), extension);
|
||||
#endif
|
||||
}
|
||||
|
||||
#if WEBKIT_CHECK_VERSION (1, 1, 3)
|
||||
static void
|
||||
web_cache_add_download_cb (MidoriBrowser* browser,
|
||||
WebKitDownload* download,
|
||||
MidoriExtension* extension)
|
||||
{
|
||||
WebKitNetworkRequest* request = webkit_download_get_network_request (download);
|
||||
SoupMessage* msg = webkit_network_request_get_message (request);
|
||||
if (msg)
|
||||
g_object_set_data (G_OBJECT (msg), "midori-web-cache-download",
|
||||
(gpointer)0xdeadbeef);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
web_cache_deactivate_cb (MidoriExtension* extension,
|
||||
MidoriBrowser* browser);
|
||||
|
||||
static void
|
||||
web_cache_add_tab_foreach_cb (MidoriView* view,
|
||||
MidoriBrowser* browser,
|
||||
MidoriExtension* extension)
|
||||
{
|
||||
web_cache_add_tab_cb (browser, view, extension);
|
||||
}
|
||||
|
||||
static void
|
||||
web_cache_app_add_browser_cb (MidoriApp* app,
|
||||
MidoriBrowser* browser,
|
||||
MidoriExtension* extension)
|
||||
{
|
||||
midori_browser_foreach (browser,
|
||||
(GtkCallback)web_cache_add_tab_foreach_cb, extension);
|
||||
g_signal_connect (browser, "add-tab",
|
||||
G_CALLBACK (web_cache_add_tab_cb), extension);
|
||||
#if WEBKIT_CHECK_VERSION (1, 1, 3)
|
||||
g_signal_connect (browser, "add-download",
|
||||
G_CALLBACK (web_cache_add_download_cb), extension);
|
||||
#endif
|
||||
g_signal_connect (extension, "deactivate",
|
||||
G_CALLBACK (web_cache_deactivate_cb), browser);
|
||||
}
|
||||
|
||||
static void
|
||||
web_cache_deactivate_tabs (MidoriView* view,
|
||||
MidoriExtension* extension)
|
||||
{
|
||||
#if HAVE_WEBKIT_RESOURCE_REQUEST
|
||||
GtkWidget* web_view = gtk_bin_get_child (GTK_BIN (view));
|
||||
|
||||
g_signal_handlers_disconnect_by_func (
|
||||
web_view, web_cache_resource_request_starting_cb, extension);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
web_cache_deactivate_cb (MidoriExtension* extension,
|
||||
MidoriBrowser* browser)
|
||||
{
|
||||
MidoriApp* app = midori_extension_get_app (extension);
|
||||
SoupSession* session = webkit_get_default_session ();
|
||||
|
||||
g_signal_handlers_disconnect_by_func (
|
||||
session, web_cache_session_request_queued_cb, extension);
|
||||
g_signal_handlers_disconnect_by_func (
|
||||
extension, web_cache_deactivate_cb, browser);
|
||||
g_signal_handlers_disconnect_by_func (
|
||||
app, web_cache_app_add_browser_cb, extension);
|
||||
g_signal_handlers_disconnect_by_func (
|
||||
browser, web_cache_add_tab_cb, extension);
|
||||
#if WEBKIT_CHECK_VERSION (1, 1, 3)
|
||||
g_signal_handlers_disconnect_by_func (
|
||||
browser, web_cache_add_download_cb, extension);
|
||||
#endif
|
||||
midori_browser_foreach (browser, (GtkCallback)web_cache_deactivate_tabs, extension);
|
||||
}
|
||||
|
||||
static void
|
||||
web_cache_activate_cb (MidoriExtension* extension,
|
||||
MidoriApp* app)
|
||||
{
|
||||
const gchar* cache_path = midori_extension_get_string (extension, "path");
|
||||
KatzeArray* browsers;
|
||||
MidoriBrowser* browser;
|
||||
guint i;
|
||||
SoupSession* session = webkit_get_default_session ();
|
||||
|
||||
katze_mkdir_with_parents (cache_path, 0700);
|
||||
g_signal_connect (session, "request-queued",
|
||||
G_CALLBACK (web_cache_session_request_queued_cb), extension);
|
||||
|
||||
browsers = katze_object_get_object (app, "browsers");
|
||||
i = 0;
|
||||
while ((browser = katze_array_get_nth_item (browsers, i++)))
|
||||
web_cache_app_add_browser_cb (app, browser, extension);
|
||||
g_signal_connect (app, "add-browser",
|
||||
G_CALLBACK (web_cache_app_add_browser_cb), extension);
|
||||
|
||||
g_object_unref (browsers);
|
||||
}
|
||||
|
||||
MidoriExtension*
|
||||
extension_init (void)
|
||||
{
|
||||
gchar* cache_path = g_build_filename (g_get_user_cache_dir (),
|
||||
PACKAGE_NAME, "web", NULL);
|
||||
MidoriExtension* extension = g_object_new (MIDORI_TYPE_EXTENSION,
|
||||
"name", _("Web Cache"),
|
||||
"description", _("Cache HTTP communication on disk"),
|
||||
"version", "0.1",
|
||||
"authors", "Christian Dywan <christian@twotoasts.de>",
|
||||
NULL);
|
||||
midori_extension_install_string (extension, "path", cache_path);
|
||||
midori_extension_install_integer (extension, "size", 50);
|
||||
|
||||
g_free (cache_path);
|
||||
|
||||
g_signal_connect (extension, "activate",
|
||||
G_CALLBACK (web_cache_activate_cb), NULL);
|
||||
|
||||
return extension;
|
||||
}
|
|
@ -15,7 +15,9 @@ def add_image (bld, category, name):
|
|||
if rsvg_convert:
|
||||
Utils.check_dir (blddir + '/icons')
|
||||
|
||||
for size in [16, 22, 24, 32, 48]:
|
||||
icon_sizes = [16, 22, 24, 32, 48]
|
||||
|
||||
for size in icon_sizes:
|
||||
format = str (size) + 'x' + str (size)
|
||||
if os.access (srcdir + '/icons/' + format + '/' + name + '.png', os.F_OK):
|
||||
bld.install_files ('${MDATADIR}/icons/hicolor/' + format + '/' + category,
|
||||
|
|
|
@ -20,12 +20,17 @@
|
|||
#include <glib/gi18n.h>
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#if HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
struct _KatzeArrayAction
|
||||
{
|
||||
GtkAction parent_instance;
|
||||
|
||||
KatzeArray* array;
|
||||
KatzeNet* net;
|
||||
gboolean reversed;
|
||||
};
|
||||
|
||||
struct _KatzeArrayActionClass
|
||||
|
@ -39,7 +44,8 @@ enum
|
|||
{
|
||||
PROP_0,
|
||||
|
||||
PROP_ARRAY
|
||||
PROP_ARRAY,
|
||||
PROP_REVERSED
|
||||
};
|
||||
|
||||
enum
|
||||
|
@ -154,6 +160,22 @@ katze_array_action_class_init (KatzeArrayActionClass* class)
|
|||
"The array the action represents",
|
||||
KATZE_TYPE_ARRAY,
|
||||
G_PARAM_READWRITE));
|
||||
|
||||
/**
|
||||
* KatzeArrayAction:reversed:
|
||||
*
|
||||
* Whether the array should be walked backwards when building menus.
|
||||
*
|
||||
* Since: 0.2.2
|
||||
**/
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_REVERSED,
|
||||
g_param_spec_boolean (
|
||||
"reversed",
|
||||
"Reversed",
|
||||
"Whether the array should be walked backwards when building menus",
|
||||
FALSE,
|
||||
G_PARAM_READWRITE));
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -161,6 +183,7 @@ katze_array_action_init (KatzeArrayAction* array_action)
|
|||
{
|
||||
array_action->array = NULL;
|
||||
array_action->net = katze_net_new ();
|
||||
array_action->reversed = FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -187,6 +210,9 @@ katze_array_action_set_property (GObject* object,
|
|||
case PROP_ARRAY:
|
||||
katze_array_action_set_array (array_action, g_value_get_object (value));
|
||||
break;
|
||||
case PROP_REVERSED:
|
||||
array_action->reversed = g_value_get_boolean (value);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
|
@ -206,6 +232,9 @@ katze_array_action_get_property (GObject* object,
|
|||
case PROP_ARRAY:
|
||||
g_value_set_object (value, array_action->array);
|
||||
break;
|
||||
case PROP_REVERSED:
|
||||
g_value_set_boolean (value, array_action->reversed);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
|
@ -272,7 +301,8 @@ katze_array_action_generate_menu (KatzeArrayAction* array_action,
|
|||
GtkWidget* menu,
|
||||
GtkWidget* proxy)
|
||||
{
|
||||
guint i;
|
||||
gint i;
|
||||
gint summand;
|
||||
KatzeItem* item;
|
||||
GtkWidget* menuitem;
|
||||
const gchar* icon_name;
|
||||
|
@ -280,8 +310,17 @@ katze_array_action_generate_menu (KatzeArrayAction* array_action,
|
|||
GtkWidget* image;
|
||||
GtkWidget* submenu;
|
||||
|
||||
i = 0;
|
||||
while ((item = katze_array_get_nth_item (array, i++)))
|
||||
if (array_action->reversed)
|
||||
{
|
||||
i = katze_array_get_length (array);
|
||||
summand = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
i = -1;
|
||||
summand = +1;
|
||||
}
|
||||
while ((item = katze_array_get_nth_item (array, i += summand)))
|
||||
{
|
||||
/* FIXME: The menu item should reflect changes to the item */
|
||||
if (!KATZE_IS_ARRAY (item) && !katze_item_get_uri (item))
|
||||
|
@ -301,8 +340,7 @@ katze_array_action_generate_menu (KatzeArrayAction* array_action,
|
|||
icon = gtk_widget_render_icon (menuitem,
|
||||
GTK_STOCK_DIRECTORY, GTK_ICON_SIZE_MENU, NULL);
|
||||
else
|
||||
icon = katze_net_load_icon (array_action->net,
|
||||
katze_item_get_uri (item), NULL, proxy, NULL);
|
||||
icon = katze_load_cached_icon (katze_item_get_uri (item), proxy);
|
||||
image = gtk_image_new_from_pixbuf (icon);
|
||||
g_object_unref (icon);
|
||||
}
|
||||
|
@ -322,19 +360,12 @@ katze_array_action_generate_menu (KatzeArrayAction* array_action,
|
|||
}
|
||||
else
|
||||
{
|
||||
g_signal_connect (menuitem, "button-press-event",
|
||||
G_CALLBACK (katze_array_action_menu_button_press_cb), array_action);
|
||||
/* we need the 'activate' signal as well for keyboard events */
|
||||
g_signal_connect (menuitem, "activate",
|
||||
G_CALLBACK (katze_array_action_menu_activate_cb), array_action);
|
||||
}
|
||||
gtk_widget_show (menuitem);
|
||||
}
|
||||
if (!i)
|
||||
{
|
||||
menuitem = gtk_image_menu_item_new_with_label (_("Empty"));
|
||||
gtk_widget_set_sensitive (menuitem, FALSE);
|
||||
gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
|
||||
g_signal_connect (menuitem, "button-press-event",
|
||||
G_CALLBACK (katze_array_action_menu_button_press_cb), array_action);
|
||||
gtk_widget_show (menuitem);
|
||||
}
|
||||
}
|
||||
|
@ -370,9 +401,15 @@ katze_array_action_proxy_clicked_cb (GtkWidget* proxy,
|
|||
return;
|
||||
}
|
||||
|
||||
array = (KatzeArray*)g_object_get_data (G_OBJECT (proxy), "KatzeArray");
|
||||
if (KATZE_IS_ITEM (array) && katze_item_get_uri ((KatzeItem*)array))
|
||||
{
|
||||
g_signal_emit (array_action, signals[ACTIVATE_ITEM], 0, array);
|
||||
return;
|
||||
}
|
||||
|
||||
menu = gtk_menu_new ();
|
||||
|
||||
array = (KatzeArray*)g_object_get_data (G_OBJECT (proxy), "KatzeArray");
|
||||
if (!array)
|
||||
array = array_action->array;
|
||||
katze_array_action_generate_menu (array_action, array, menu, proxy);
|
||||
|
@ -381,8 +418,14 @@ katze_array_action_proxy_clicked_cb (GtkWidget* proxy,
|
|||
if (array == array_action->array)
|
||||
g_signal_emit (array_action, signals[POPULATE_POPUP], 0, menu);
|
||||
|
||||
#if HAVE_HILDON
|
||||
/* Avoid a bug in GTK+ messing up the initial scrolling position */
|
||||
katze_widget_popup (NULL, GTK_MENU (menu),
|
||||
NULL, KATZE_MENU_POSITION_LEFT);
|
||||
#else
|
||||
katze_widget_popup (GTK_WIDGET (proxy), GTK_MENU (menu),
|
||||
NULL, KATZE_MENU_POSITION_LEFT);
|
||||
#endif
|
||||
}
|
||||
|
||||
static GtkWidget*
|
||||
|
@ -399,7 +442,7 @@ katze_array_action_create_tool_item (GtkAction* action)
|
|||
{
|
||||
GtkWidget* toolitem;
|
||||
|
||||
toolitem = GTK_WIDGET (gtk_tool_button_new (NULL, NULL));
|
||||
toolitem = GTK_WIDGET (gtk_tool_button_new (NULL, ""));
|
||||
return toolitem;
|
||||
}
|
||||
|
||||
|
@ -460,8 +503,7 @@ katze_array_action_item_notify_cb (KatzeItem* item,
|
|||
}
|
||||
else if (!KATZE_IS_ARRAY (item) && !strcmp (property, "uri"))
|
||||
{
|
||||
icon = katze_net_load_icon (array_action->net, katze_item_get_uri (item),
|
||||
NULL, GTK_WIDGET (toolitem), NULL);
|
||||
icon = katze_load_cached_icon (katze_item_get_uri (item), GTK_WIDGET (toolitem));
|
||||
image = gtk_image_new_from_pixbuf (icon);
|
||||
g_object_unref (icon);
|
||||
gtk_widget_show (image);
|
||||
|
@ -497,8 +539,7 @@ katze_array_action_proxy_create_menu_proxy_cb (GtkWidget* proxy,
|
|||
icon = gtk_widget_render_icon (menuitem,
|
||||
GTK_STOCK_DIRECTORY, GTK_ICON_SIZE_MENU, NULL);
|
||||
else
|
||||
icon = katze_net_load_icon (array_action->net,
|
||||
katze_item_get_uri (item), NULL, proxy, NULL);
|
||||
icon = katze_load_cached_icon (katze_item_get_uri (item), proxy);
|
||||
image = gtk_image_new_from_pixbuf (icon);
|
||||
g_object_unref (icon);
|
||||
}
|
||||
|
@ -508,16 +549,34 @@ katze_array_action_proxy_create_menu_proxy_cb (GtkWidget* proxy,
|
|||
GTK_IMAGE_MENU_ITEM (menuitem), TRUE);
|
||||
#endif
|
||||
g_object_set_data (G_OBJECT (menuitem), "KatzeItem", item);
|
||||
if (KATZE_IS_ARRAY (item))
|
||||
{
|
||||
GtkWidget* submenu = gtk_menu_new ();
|
||||
gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), submenu);
|
||||
g_signal_connect (menuitem, "select",
|
||||
G_CALLBACK (katze_array_action_menu_item_select_cb), array_action);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_signal_connect (menuitem, "button-press-event",
|
||||
G_CALLBACK (katze_array_action_menu_button_press_cb), array_action);
|
||||
/* we need the 'activate' signal as well for keyboard events */
|
||||
g_signal_connect (menuitem, "activate",
|
||||
G_CALLBACK (katze_array_action_menu_activate_cb), array_action);
|
||||
}
|
||||
gtk_tool_item_set_proxy_menu_item (GTK_TOOL_ITEM (proxy),
|
||||
"katze-tool-item-menu", menuitem);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
katze_array_action_toolitem_destroy_cb (GtkToolItem* toolitem,
|
||||
KatzeItem* item)
|
||||
{
|
||||
g_signal_handlers_disconnect_by_func (item,
|
||||
G_CALLBACK (katze_array_action_item_notify_cb), toolitem);
|
||||
}
|
||||
|
||||
/**
|
||||
* katze_array_action_create_tool_item_for:
|
||||
* @array_action: a #KatzeArrayAction
|
||||
|
@ -552,15 +611,14 @@ katze_array_action_create_tool_item_for (KatzeArrayAction* array_action,
|
|||
if (!KATZE_IS_ARRAY (item) && !uri)
|
||||
return gtk_separator_tool_item_new ();
|
||||
|
||||
toolitem = gtk_tool_button_new (NULL, NULL);
|
||||
toolitem = gtk_tool_button_new (NULL, "");
|
||||
g_signal_connect (toolitem, "create-menu-proxy",
|
||||
G_CALLBACK (katze_array_action_proxy_create_menu_proxy_cb), item);
|
||||
if (KATZE_IS_ARRAY (item))
|
||||
icon = gtk_widget_render_icon (GTK_WIDGET (toolitem),
|
||||
GTK_STOCK_DIRECTORY, GTK_ICON_SIZE_MENU, NULL);
|
||||
else
|
||||
icon = katze_net_load_icon (array_action->net, uri,
|
||||
NULL, GTK_WIDGET (toolitem), NULL);
|
||||
icon = katze_load_cached_icon (uri, GTK_WIDGET (toolitem));
|
||||
image = gtk_image_new_from_pixbuf (icon);
|
||||
g_object_unref (icon);
|
||||
gtk_widget_show (image);
|
||||
|
@ -585,16 +643,16 @@ katze_array_action_create_tool_item_for (KatzeArrayAction* array_action,
|
|||
gtk_tool_item_set_tooltip_text (toolitem, desc);
|
||||
else
|
||||
gtk_tool_item_set_tooltip_text (toolitem, uri);
|
||||
if (KATZE_IS_ARRAY (item))
|
||||
{
|
||||
|
||||
g_object_set_data (G_OBJECT (toolitem), "KatzeArray", item);
|
||||
g_signal_connect (toolitem, "clicked",
|
||||
G_CALLBACK (katze_array_action_proxy_clicked_cb), array_action);
|
||||
}
|
||||
|
||||
g_object_set_data (G_OBJECT (toolitem), "KatzeArrayAction", array_action);
|
||||
g_signal_connect (item, "notify",
|
||||
G_CALLBACK (katze_array_action_item_notify_cb), toolitem);
|
||||
g_signal_connect (toolitem, "destroy",
|
||||
G_CALLBACK (katze_array_action_toolitem_destroy_cb), item);
|
||||
return toolitem;
|
||||
}
|
||||
|
||||
|
|
|
@ -75,12 +75,14 @@ katze_item_class_init (KatzeItemClass* class)
|
|||
*
|
||||
* Emitted when a meta data value was changed.
|
||||
*
|
||||
* Since 0.2.2 details according to keys are supported.
|
||||
*
|
||||
* Since: 0.1.9
|
||||
*/
|
||||
signals[META_DATA_CHANGED] = g_signal_new (
|
||||
"meta-data-changed",
|
||||
G_TYPE_FROM_CLASS (class),
|
||||
(GSignalFlags)(G_SIGNAL_RUN_LAST),
|
||||
(GSignalFlags)(G_SIGNAL_RUN_LAST |G_SIGNAL_DETAILED),
|
||||
0,
|
||||
0,
|
||||
NULL,
|
||||
|
@ -510,7 +512,7 @@ katze_item_set_meta_data_value (KatzeItem* item,
|
|||
g_hash_table_insert (item->metadata, g_strdup (&key[7]), value);
|
||||
else
|
||||
g_hash_table_insert (item->metadata, g_strdup (key), value);
|
||||
g_signal_emit (item, signals[META_DATA_CHANGED], 0, key);
|
||||
g_signal_emit (item, signals[META_DATA_CHANGED], g_quark_from_string (key), key);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -590,7 +592,7 @@ katze_item_get_meta_integer (KatzeItem* item,
|
|||
if (g_str_has_prefix (key, "midori:"))
|
||||
key = &key[7];
|
||||
if (g_hash_table_lookup_extended (item->metadata, key, NULL, &value))
|
||||
return g_ascii_strtoll (value, NULL, 0);
|
||||
return value ? g_ascii_strtoll (value, NULL, 0) : -1;
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
|
|
@ -157,7 +157,7 @@ katze_net_get_cached_path (KatzeNet* net,
|
|||
cache_path = g_build_filename (net->cache_path, subfolder, NULL);
|
||||
else
|
||||
cache_path = net->cache_path;
|
||||
g_mkdir_with_parents (cache_path, 0700);
|
||||
katze_mkdir_with_parents (cache_path, 0700);
|
||||
checksum = g_compute_checksum_for_string (G_CHECKSUM_MD5, uri, -1);
|
||||
|
||||
extension = g_strrstr (uri, ".");
|
||||
|
|
421
katze/katze-preferences.c
Normal file
421
katze/katze-preferences.c
Normal file
|
@ -0,0 +1,421 @@
|
|||
/*
|
||||
Copyright (C) 2007-2009 Christian Dywan <christian@twotoasts.de>
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
See the file COPYING for the full license text.
|
||||
*/
|
||||
|
||||
#include "katze-preferences.h"
|
||||
|
||||
#if HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#if HAVE_HILDON
|
||||
#include "katze-scrolled.h"
|
||||
#include <hildon/hildon.h>
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
#include <glib/gi18n.h>
|
||||
|
||||
struct _KatzePreferencesPrivate
|
||||
{
|
||||
#if HAVE_HILDON
|
||||
GtkWidget* scrolled;
|
||||
GtkSizeGroup* sizegroup;
|
||||
GtkSizeGroup* sizegroup2;
|
||||
GtkWidget* box;
|
||||
GtkWidget* hbox;
|
||||
#else
|
||||
GtkWidget* notebook;
|
||||
GtkWidget* toolbar;
|
||||
GtkWidget* toolbutton;
|
||||
GtkSizeGroup* sizegroup;
|
||||
GtkSizeGroup* sizegroup2;
|
||||
GtkWidget* page;
|
||||
GtkWidget* frame;
|
||||
GtkWidget* box;
|
||||
GtkWidget* hbox;
|
||||
#endif
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (KatzePreferences, katze_preferences, GTK_TYPE_DIALOG);
|
||||
|
||||
static void
|
||||
katze_preferences_finalize (GObject* object);
|
||||
|
||||
static void
|
||||
katze_preferences_class_init (KatzePreferencesClass* class)
|
||||
{
|
||||
GObjectClass* gobject_class = G_OBJECT_CLASS (class);
|
||||
gobject_class->finalize = katze_preferences_finalize;
|
||||
|
||||
g_type_class_add_private (class, sizeof (KatzePreferencesPrivate));
|
||||
}
|
||||
|
||||
static void
|
||||
katze_preferences_response_cb (KatzePreferences* preferences,
|
||||
gint response)
|
||||
{
|
||||
if (response == GTK_RESPONSE_CLOSE || response == GTK_RESPONSE_APPLY)
|
||||
gtk_widget_destroy (GTK_WIDGET (preferences));
|
||||
}
|
||||
|
||||
#ifdef HAVE_HILDON_2_2
|
||||
static void
|
||||
katze_preferences_size_request_cb (KatzePreferences* preferences,
|
||||
GtkRequisition* requisition)
|
||||
{
|
||||
GdkScreen* screen = gtk_widget_get_screen (GTK_WIDGET (preferences));
|
||||
if (gdk_screen_get_height (screen) > gdk_screen_get_width (screen))
|
||||
gtk_widget_hide (gtk_dialog_get_action_area (GTK_DIALOG (preferences)));
|
||||
else
|
||||
gtk_widget_show (gtk_dialog_get_action_area (GTK_DIALOG (preferences)));
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
katze_preferences_init (KatzePreferences* preferences)
|
||||
{
|
||||
KatzePreferencesPrivate* priv;
|
||||
gchar* dialog_title;
|
||||
|
||||
preferences->priv = priv = G_TYPE_INSTANCE_GET_PRIVATE ((preferences),
|
||||
KATZE_TYPE_PREFERENCES, KatzePreferencesPrivate);
|
||||
|
||||
dialog_title = g_strdup_printf (_("Preferences for %s"),
|
||||
g_get_application_name ());
|
||||
g_object_set (preferences,
|
||||
"icon-name", GTK_STOCK_PREFERENCES,
|
||||
"title", dialog_title,
|
||||
"has-separator", FALSE,
|
||||
NULL);
|
||||
g_free (dialog_title);
|
||||
|
||||
#if !HAVE_OSX
|
||||
gtk_dialog_add_buttons (GTK_DIALOG (preferences),
|
||||
GTK_STOCK_HELP, GTK_RESPONSE_HELP,
|
||||
#if HAVE_HILDON
|
||||
GTK_STOCK_SAVE, GTK_RESPONSE_APPLY,
|
||||
#else
|
||||
GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE,
|
||||
#endif
|
||||
NULL);
|
||||
#endif
|
||||
|
||||
g_object_connect (preferences,
|
||||
"signal::response", katze_preferences_response_cb, NULL,
|
||||
NULL);
|
||||
|
||||
#ifdef HAVE_HILDON_2_2
|
||||
katze_preferences_size_request_cb (preferences, NULL);
|
||||
g_object_connect (preferences,
|
||||
"signal::size-request", katze_preferences_size_request_cb, NULL,
|
||||
NULL);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
katze_preferences_finalize (GObject* object)
|
||||
{
|
||||
G_OBJECT_CLASS (katze_preferences_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
/**
|
||||
* katze_preferences_new:
|
||||
* @parent: the parent window, or %NULL
|
||||
*
|
||||
* Creates a new preferences dialog.
|
||||
*
|
||||
* Return value: a new #KatzePreferences
|
||||
*
|
||||
* Since: 0.2.1
|
||||
**/
|
||||
GtkWidget*
|
||||
katze_preferences_new (GtkWindow* parent)
|
||||
{
|
||||
KatzePreferences* preferences;
|
||||
|
||||
g_return_val_if_fail (!parent || GTK_IS_WINDOW (parent), NULL);
|
||||
|
||||
preferences = g_object_new (KATZE_TYPE_PREFERENCES,
|
||||
"transient-for", parent,
|
||||
NULL);
|
||||
|
||||
return GTK_WIDGET (preferences);
|
||||
}
|
||||
|
||||
#if HAVE_OSX
|
||||
static void
|
||||
katze_preferences_help_clicked_cb (GtkWidget* button,
|
||||
GtkDialog* dialog)
|
||||
{
|
||||
gtk_dialog_response (dialog, GTK_RESPONSE_HELP);
|
||||
}
|
||||
|
||||
static void
|
||||
katze_preferences_toolbutton_clicked_cb (GtkWidget* toolbutton,
|
||||
GtkWidget* page)
|
||||
{
|
||||
gpointer notebook = g_object_get_data (G_OBJECT (toolbutton), "notebook");
|
||||
guint n = gtk_notebook_page_num (notebook, page);
|
||||
gtk_notebook_set_current_page (notebook, n);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
katze_preferences_prepare (KatzePreferences* preferences)
|
||||
{
|
||||
KatzePreferencesPrivate* priv = preferences->priv;
|
||||
|
||||
#if HAVE_HILDON
|
||||
GtkWidget* viewport;
|
||||
|
||||
priv->scrolled = katze_scrolled_new (NULL, NULL);
|
||||
gtk_box_pack_end (GTK_BOX (GTK_DIALOG (preferences)->vbox),
|
||||
priv->scrolled, TRUE, TRUE, 4);
|
||||
viewport = gtk_viewport_new (NULL, NULL);
|
||||
gtk_viewport_set_shadow_type (GTK_VIEWPORT (viewport), GTK_SHADOW_NONE);
|
||||
gtk_container_add (GTK_CONTAINER (priv->scrolled), viewport);
|
||||
priv->box = gtk_vbox_new (FALSE, 0);
|
||||
gtk_container_add (GTK_CONTAINER (viewport), priv->box);
|
||||
|
||||
priv->hbox = NULL;
|
||||
priv->sizegroup = NULL;
|
||||
priv->sizegroup2 = NULL;
|
||||
|
||||
g_signal_connect (priv->scrolled, "destroy",
|
||||
G_CALLBACK (gtk_widget_destroyed), &priv->scrolled);
|
||||
#else
|
||||
priv->notebook = gtk_notebook_new ();
|
||||
gtk_container_set_border_width (GTK_CONTAINER (priv->notebook), 6);
|
||||
|
||||
#if HAVE_OSX
|
||||
gtk_notebook_set_show_tabs (GTK_NOTEBOOK (priv->notebook), FALSE);
|
||||
gtk_notebook_set_show_border (GTK_NOTEBOOK (priv->notebook), FALSE);
|
||||
priv->toolbar = gtk_toolbar_new ();
|
||||
gtk_toolbar_set_style (GTK_TOOLBAR (priv->toolbar), GTK_TOOLBAR_BOTH);
|
||||
gtk_toolbar_set_show_arrow (GTK_TOOLBAR (priv->toolbar), FALSE);
|
||||
gtk_box_pack_start (GTK_BOX (GTK_DIALOG (preferences)->vbox),
|
||||
priv->toolbar, FALSE, FALSE, 0);
|
||||
#else
|
||||
priv->toolbar = NULL;
|
||||
#endif
|
||||
priv->toolbutton = NULL;
|
||||
gtk_box_pack_end (GTK_BOX (GTK_DIALOG (preferences)->vbox),
|
||||
priv->notebook, FALSE, FALSE, 4);
|
||||
|
||||
priv->sizegroup = NULL;
|
||||
priv->sizegroup2 = NULL;
|
||||
priv->page = NULL;
|
||||
priv->frame = NULL;
|
||||
priv->box = NULL;
|
||||
priv->hbox = NULL;
|
||||
|
||||
g_signal_connect (priv->notebook, "destroy",
|
||||
G_CALLBACK (gtk_widget_destroyed), &priv->notebook);
|
||||
#endif
|
||||
|
||||
#if HAVE_OSX
|
||||
GtkWidget* icon;
|
||||
GtkWidget* hbox = gtk_hbox_new (FALSE, 0);
|
||||
GtkWidget* button = gtk_button_new ();
|
||||
icon = gtk_image_new_from_stock (GTK_STOCK_HELP, GTK_ICON_SIZE_BUTTON);
|
||||
gtk_button_set_image (GTK_BUTTON (button), icon);
|
||||
g_signal_connect (button, "clicked",
|
||||
G_CALLBACK (katze_preferences_help_clicked_cb), preferences);
|
||||
gtk_box_pack_end (GTK_BOX (hbox), button, FALSE, FALSE, 4);
|
||||
gtk_box_pack_end (GTK_BOX (GTK_DIALOG (preferences)->action_area),
|
||||
hbox, FALSE, FALSE, 0);
|
||||
#endif
|
||||
gtk_widget_show_all (GTK_DIALOG (preferences)->vbox);
|
||||
}
|
||||
|
||||
/**
|
||||
* katze_preferences_add_category:
|
||||
* @preferences: a #KatzePreferences instance
|
||||
* @label: a category label
|
||||
* @icon: an icon name
|
||||
*
|
||||
* Adds a new category with the specified label to the dialog.
|
||||
*
|
||||
* Since: 0.2.1
|
||||
**/
|
||||
void
|
||||
katze_preferences_add_category (KatzePreferences* preferences,
|
||||
const gchar* label,
|
||||
const gchar* icon)
|
||||
{
|
||||
KatzePreferencesPrivate* priv = preferences->priv;
|
||||
|
||||
#if HAVE_HILDON
|
||||
GtkWidget* widget;
|
||||
gchar* markup;
|
||||
|
||||
if (!priv->scrolled)
|
||||
katze_preferences_prepare (preferences);
|
||||
|
||||
widget = gtk_label_new (NULL);
|
||||
gtk_widget_show (widget);
|
||||
markup = g_markup_printf_escaped ("<b>%s</b>", label);
|
||||
gtk_label_set_markup (GTK_LABEL (widget), markup);
|
||||
g_free (markup);
|
||||
gtk_box_pack_start (GTK_BOX (priv->box), widget, TRUE, TRUE, 0);
|
||||
|
||||
priv->sizegroup = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
|
||||
priv->sizegroup2 = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
|
||||
priv->hbox = NULL;
|
||||
#else
|
||||
if (!priv->notebook)
|
||||
katze_preferences_prepare (preferences);
|
||||
|
||||
priv->page = gtk_vbox_new (FALSE, 0);
|
||||
priv->sizegroup = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
|
||||
gtk_widget_show (priv->page);
|
||||
gtk_container_set_border_width (GTK_CONTAINER (priv->page), 4);
|
||||
gtk_notebook_append_page (GTK_NOTEBOOK (priv->notebook),
|
||||
priv->page, gtk_label_new (label));
|
||||
#if HAVE_OSX
|
||||
priv->toolbutton = GTK_WIDGET (priv->toolbutton ?
|
||||
gtk_radio_tool_button_new_from_widget (
|
||||
GTK_RADIO_TOOL_BUTTON (priv->toolbutton))
|
||||
: gtk_radio_tool_button_new (NULL));
|
||||
gtk_widget_show (priv->toolbutton);
|
||||
gtk_tool_button_set_label (GTK_TOOL_BUTTON (priv->toolbutton), label);
|
||||
gtk_tool_button_set_stock_id (GTK_TOOL_BUTTON (priv->toolbutton), icon);
|
||||
gtk_toolbar_insert (GTK_TOOLBAR (priv->toolbar),
|
||||
GTK_TOOL_ITEM (priv->toolbutton), -1);
|
||||
g_signal_connect (priv->toolbutton, "clicked",
|
||||
G_CALLBACK (katze_preferences_toolbutton_clicked_cb), priv->page);
|
||||
if (priv->toolbutton)
|
||||
g_object_set_data (G_OBJECT (priv->toolbutton), "notebook", priv->notebook);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
#if !HAVE_HILDON
|
||||
static GtkWidget*
|
||||
katze_hig_frame_new (const gchar* title)
|
||||
{
|
||||
/* Create a frame with no actual frame but a bold label and indentation */
|
||||
GtkWidget* frame = gtk_frame_new (NULL);
|
||||
#ifdef G_OS_WIN32
|
||||
gtk_frame_set_label (GTK_FRAME (frame), title);
|
||||
#else
|
||||
gchar* title_bold = g_strdup_printf ("<b>%s</b>", title);
|
||||
GtkWidget* label = gtk_label_new (NULL);
|
||||
gtk_label_set_markup (GTK_LABEL (label), title_bold);
|
||||
g_free (title_bold);
|
||||
gtk_frame_set_label_widget (GTK_FRAME (frame), label);
|
||||
gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_NONE);
|
||||
#endif
|
||||
return frame;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* katze_preferences_add_group:
|
||||
* @preferences: a #KatzePreferences instance
|
||||
* @label: a group label
|
||||
*
|
||||
* Adds a new group with the specified label to the dialog.
|
||||
*
|
||||
* Since: 0.2.1
|
||||
**/
|
||||
void
|
||||
katze_preferences_add_group (KatzePreferences* preferences,
|
||||
const gchar* label)
|
||||
{
|
||||
#if !HAVE_HILDON
|
||||
KatzePreferencesPrivate* priv = preferences->priv;
|
||||
|
||||
priv->sizegroup2 = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
|
||||
priv->frame = katze_hig_frame_new (label);
|
||||
gtk_container_set_border_width (GTK_CONTAINER (priv->frame), 4);
|
||||
gtk_box_pack_start (GTK_BOX (priv->page), priv->frame, FALSE, FALSE, 0);
|
||||
priv->box = gtk_vbox_new (FALSE, 4);
|
||||
gtk_container_set_border_width (GTK_CONTAINER (priv->box), 4);
|
||||
gtk_container_add (GTK_CONTAINER (priv->frame), priv->box);
|
||||
gtk_widget_show_all (priv->frame);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* katze_preferences_add_widget:
|
||||
* @preferences: a #KatzePreferences instance
|
||||
* @widget: a widget representing an option
|
||||
* @type: "filled", "indented", or "spanned"
|
||||
*
|
||||
* Adds a widget to the dialog.
|
||||
*
|
||||
* Since: 0.2.1
|
||||
**/
|
||||
void
|
||||
katze_preferences_add_widget (KatzePreferences* preferences,
|
||||
GtkWidget* widget,
|
||||
const gchar* type)
|
||||
{
|
||||
KatzePreferencesPrivate* priv;
|
||||
const gchar* _type;
|
||||
|
||||
g_return_if_fail (KATZE_IS_PREFERENCES (preferences));
|
||||
g_return_if_fail (GTK_IS_WIDGET (widget));
|
||||
g_return_if_fail (type != NULL);
|
||||
|
||||
priv = preferences->priv;
|
||||
_type = g_intern_string (type);
|
||||
|
||||
/* Showing implicitly widget and children is not the best idea,
|
||||
but lots of repeated function calls aren't either. */
|
||||
gtk_widget_show_all (widget);
|
||||
|
||||
if (!priv->hbox)
|
||||
_type = g_intern_string ("indented");
|
||||
#ifdef HAVE_HILDON_2_2
|
||||
else if (HILDON_IS_CHECK_BUTTON (widget) || HILDON_IS_PICKER_BUTTON (widget))
|
||||
_type = g_intern_string ("indented");
|
||||
#endif
|
||||
|
||||
if (_type != g_intern_static_string ("spanned"))
|
||||
{
|
||||
priv->hbox = gtk_hbox_new (FALSE, 4);
|
||||
gtk_widget_show (priv->hbox);
|
||||
gtk_box_pack_start (GTK_BOX (priv->hbox), widget, TRUE, FALSE, 0);
|
||||
}
|
||||
|
||||
if (_type == g_intern_static_string ("filled"))
|
||||
gtk_box_pack_start (GTK_BOX (priv->box), priv->hbox, TRUE, FALSE, 0);
|
||||
else if (_type == g_intern_static_string ("indented"))
|
||||
{
|
||||
GtkWidget* align = gtk_alignment_new (0, 0.5, 0, 0);
|
||||
gtk_widget_show (align);
|
||||
gtk_container_add (GTK_CONTAINER (align), priv->hbox);
|
||||
#if HAVE_HILDON
|
||||
if (!GTK_IS_SPIN_BUTTON (widget) && !GTK_IS_LABEL (widget))
|
||||
#else
|
||||
if (!GTK_IS_SPIN_BUTTON (widget))
|
||||
#endif
|
||||
gtk_size_group_add_widget (priv->sizegroup, widget);
|
||||
gtk_box_pack_start (GTK_BOX (priv->box), align, TRUE, FALSE, 0);
|
||||
}
|
||||
else if (_type == g_intern_static_string ("spanned"))
|
||||
{
|
||||
GtkWidget* align = gtk_alignment_new (0, 0.5, 0, 0);
|
||||
gtk_widget_show (align);
|
||||
gtk_container_add (GTK_CONTAINER (align), widget);
|
||||
if (!GTK_IS_LABEL (widget) && !GTK_IS_SPIN_BUTTON (widget)
|
||||
&& !(GTK_IS_BUTTON (widget) && !GTK_IS_TOGGLE_BUTTON (widget)))
|
||||
gtk_size_group_add_widget (priv->sizegroup2, widget);
|
||||
gtk_box_pack_start (GTK_BOX (priv->hbox), align, TRUE, FALSE, 0);
|
||||
}
|
||||
|
||||
#if HAVE_HILDON
|
||||
if (GTK_IS_BUTTON (widget) && !GTK_WIDGET_IS_SENSITIVE (widget))
|
||||
gtk_widget_hide (widget);
|
||||
#endif
|
||||
}
|
70
katze/katze-preferences.h
Normal file
70
katze/katze-preferences.h
Normal file
|
@ -0,0 +1,70 @@
|
|||
/*
|
||||
Copyright (C) 2008-2009 Christian Dywan <christian@twotoasts.de>
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
See the file COPYING for the full license text.
|
||||
*/
|
||||
|
||||
#ifndef __KATZE_PREFERENCES_H__
|
||||
#define __KATZE_PREFERENCES_H__
|
||||
|
||||
#include "katze-utils.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define KATZE_TYPE_PREFERENCES \
|
||||
(katze_preferences_get_type ())
|
||||
#define KATZE_PREFERENCES(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_CAST ((obj), KATZE_TYPE_PREFERENCES, KatzePreferences))
|
||||
#define KATZE_PREFERENCES_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_CAST ((klass), KATZE_TYPE_PREFERENCES, KatzePreferencesClass))
|
||||
#define KATZE_IS_PREFERENCES(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_TYPE ((obj), KATZE_TYPE_PREFERENCES))
|
||||
#define KATZE_IS_PREFERENCES_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_TYPE ((klass), KATZE_TYPE_PREFERENCES))
|
||||
#define KATZE_PREFERENCES_GET_CLASS(obj) \
|
||||
(G_TYPE_INSTANCE_GET_CLASS ((obj), KATZE_TYPE_PREFERENCES, KatzePreferencesClass))
|
||||
|
||||
typedef struct _KatzePreferences KatzePreferences;
|
||||
typedef struct _KatzePreferencesClass KatzePreferencesClass;
|
||||
typedef struct _KatzePreferencesPrivate KatzePreferencesPrivate;
|
||||
|
||||
struct _KatzePreferences
|
||||
{
|
||||
GtkDialog parent_instance;
|
||||
|
||||
KatzePreferencesPrivate* priv;
|
||||
};
|
||||
|
||||
struct _KatzePreferencesClass
|
||||
{
|
||||
GtkDialogClass parent_class;
|
||||
};
|
||||
|
||||
GType
|
||||
katze_preferences_get_type (void);
|
||||
|
||||
GtkWidget*
|
||||
katze_preferences_new (GtkWindow* parent);
|
||||
|
||||
void
|
||||
katze_preferences_add_category (KatzePreferences* preferences,
|
||||
const gchar* label,
|
||||
const gchar* icon);
|
||||
|
||||
void
|
||||
katze_preferences_add_group (KatzePreferences* preferences,
|
||||
const gchar* label);
|
||||
|
||||
void
|
||||
katze_preferences_add_widget (KatzePreferences* preferences,
|
||||
GtkWidget* widget,
|
||||
const gchar* type);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __KATZE_PREFERENCES_H__ */
|
|
@ -16,6 +16,7 @@
|
|||
#endif
|
||||
|
||||
#include "katze-scrolled.h"
|
||||
#include "katze-utils.h"
|
||||
|
||||
#define DEFAULT_INTERVAL 50
|
||||
#define DEFAULT_DECELERATION 0.7
|
||||
|
@ -819,14 +820,13 @@ katze_scrolled_realize (GtkWidget* widget)
|
|||
KatzeScrolled* scrolled = KATZE_SCROLLED (widget);
|
||||
KatzeScrolledPrivate* priv = scrolled->priv;
|
||||
gboolean drag_scrolling;
|
||||
GtkSettings* settings = gtk_widget_get_settings (widget);
|
||||
GtkPolicyType policy;
|
||||
GdkWindowAttr attr;
|
||||
GdkColor color;
|
||||
|
||||
(*GTK_WIDGET_CLASS (katze_scrolled_parent_class)->realize) (widget);
|
||||
|
||||
g_object_get (settings, "gtk-touchscreen-mode", &drag_scrolling, NULL);
|
||||
drag_scrolling = katze_widget_has_touchscreen_mode (widget);
|
||||
policy = drag_scrolling ? GTK_POLICY_NEVER : GTK_POLICY_AUTOMATIC;
|
||||
g_object_set (scrolled, "drag-scrolling", drag_scrolling,
|
||||
"hscrollbar-policy", policy, "vscrollbar-policy", policy, NULL);
|
||||
|
@ -888,7 +888,6 @@ katze_scrolled_class_init (KatzeScrolledClass* class)
|
|||
GtkWidgetClass* widget_class;
|
||||
GtkContainerClass* container_class;
|
||||
GParamFlags flags = G_PARAM_READWRITE | G_PARAM_CONSTRUCT;
|
||||
GtkSettings* gtk_settings;
|
||||
|
||||
gobject_class = G_OBJECT_CLASS (class);
|
||||
widget_class = GTK_WIDGET_CLASS (class);
|
||||
|
@ -944,13 +943,8 @@ katze_scrolled_class_init (KatzeScrolledClass* class)
|
|||
|
||||
/* Usually touchscreen mode is either always set or it isn't, so it
|
||||
should be a safe optimization to not setup events if not needed. */
|
||||
if ((gtk_settings = gtk_settings_get_default ()))
|
||||
{
|
||||
gboolean touchscreen;
|
||||
g_object_get (gtk_settings, "gtk-touchscreen-mode", &touchscreen, NULL);
|
||||
if (touchscreen)
|
||||
if (katze_widget_has_touchscreen_mode (NULL))
|
||||
katze_scrolled_event_handler_append (katze_scrolled_event_handler, NULL);
|
||||
}
|
||||
|
||||
g_type_class_add_private (class, sizeof (KatzeScrolledPrivate));
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright (C) 2007-2008 Christian Dywan <christian@twotoasts.de>
|
||||
Copyright (C) 2007-2009 Christian Dywan <christian@twotoasts.de>
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
|
@ -11,15 +11,31 @@
|
|||
|
||||
#include "katze-utils.h"
|
||||
|
||||
#include <glib/gstdio.h>
|
||||
#include <glib/gi18n.h>
|
||||
#include <gio/gio.h>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#if HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_HILDON_2_2
|
||||
#include <hildon/hildon.h>
|
||||
#endif
|
||||
|
||||
static void
|
||||
proxy_toggle_button_toggled_cb (GtkToggleButton* button,
|
||||
GObject* object)
|
||||
{
|
||||
gboolean toggled = gtk_toggle_button_get_active (button);
|
||||
gboolean toggled;
|
||||
#ifdef HAVE_HILDON_2_2
|
||||
if (HILDON_IS_CHECK_BUTTON (button))
|
||||
toggled = hildon_check_button_get_active (HILDON_CHECK_BUTTON (button));
|
||||
#else
|
||||
toggled = gtk_toggle_button_get_active (button);
|
||||
#endif
|
||||
const gchar* property = g_object_get_data (G_OBJECT (button), "property");
|
||||
g_object_set (object, property, toggled, NULL);
|
||||
}
|
||||
|
@ -60,6 +76,79 @@ proxy_combo_box_text_changed_cb (GtkComboBox* button,
|
|||
g_object_set (object, property, text, NULL);
|
||||
}
|
||||
|
||||
static const gchar*
|
||||
katze_app_info_get_commandline (GAppInfo* info)
|
||||
{
|
||||
const gchar* exe;
|
||||
|
||||
#if GLIB_CHECK_VERSION (2, 20, 0)
|
||||
exe = g_app_info_get_commandline (info);
|
||||
#else
|
||||
exe = g_object_get_data (G_OBJECT (info), "katze-cmdline");
|
||||
#endif
|
||||
if (!exe)
|
||||
exe = g_app_info_get_executable (info);
|
||||
return exe;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
proxy_entry_focus_out_event_cb (GtkEntry* entry,
|
||||
GdkEventFocus* event,
|
||||
GObject* object);
|
||||
|
||||
static void
|
||||
proxy_combo_box_apps_changed_cb (GtkComboBox* button,
|
||||
GObject* object)
|
||||
{
|
||||
guint active = gtk_combo_box_get_active (button);
|
||||
GtkTreeModel* model = gtk_combo_box_get_model (button);
|
||||
GtkTreeIter iter;
|
||||
|
||||
if (gtk_tree_model_iter_nth_child (model, &iter, NULL, active))
|
||||
{
|
||||
GAppInfo* info;
|
||||
gboolean use_entry;
|
||||
GtkWidget* child;
|
||||
const gchar* exe;
|
||||
const gchar* property = g_object_get_data (G_OBJECT (button), "property");
|
||||
|
||||
gtk_tree_model_get (model, &iter, 0, &info, -1);
|
||||
|
||||
use_entry = info && !g_app_info_get_icon (info);
|
||||
child = gtk_bin_get_child (GTK_BIN (button));
|
||||
if (use_entry && GTK_IS_CELL_VIEW (child))
|
||||
{
|
||||
GtkWidget* entry = gtk_entry_new ();
|
||||
exe = g_app_info_get_executable (info);
|
||||
if (exe && *exe && strcmp (exe, "%f"))
|
||||
gtk_entry_set_text (GTK_ENTRY (entry), exe);
|
||||
gtk_widget_show (entry);
|
||||
gtk_container_add (GTK_CONTAINER (button), entry);
|
||||
gtk_widget_grab_focus (entry);
|
||||
g_signal_connect (entry, "focus-out-event",
|
||||
G_CALLBACK (proxy_entry_focus_out_event_cb), object);
|
||||
g_object_set_data_full (G_OBJECT (entry), "property",
|
||||
g_strdup (property), g_free);
|
||||
}
|
||||
else if (!use_entry && GTK_IS_ENTRY (child))
|
||||
{
|
||||
/* Force the combo to change the item again */
|
||||
gtk_widget_destroy (child);
|
||||
gtk_combo_box_set_active (button, 0);
|
||||
gtk_combo_box_set_active_iter (button, &iter);
|
||||
}
|
||||
|
||||
if (info)
|
||||
{
|
||||
exe = katze_app_info_get_commandline (info);
|
||||
g_object_set (object, property, exe, NULL);
|
||||
g_object_unref (info);
|
||||
}
|
||||
else
|
||||
g_object_set (object, property, "", NULL);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
proxy_entry_activate_cb (GtkEntry* entry,
|
||||
GObject* object)
|
||||
|
@ -99,14 +188,73 @@ proxy_spin_button_changed_cb (GtkSpinButton* button,
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef HAVE_HILDON_2_2
|
||||
static void
|
||||
proxy_picker_button_changed_cb (HildonPickerButton* button,
|
||||
GObject* object)
|
||||
{
|
||||
gint value = hildon_picker_button_get_active (button);
|
||||
const gchar* property = g_object_get_data (G_OBJECT (button), "property");
|
||||
g_object_set (object, property, value, NULL);
|
||||
/* FIXME: Implement custom-PROPERTY */
|
||||
}
|
||||
#else
|
||||
static void
|
||||
proxy_combo_box_changed_cb (GtkComboBox* button,
|
||||
GObject* object)
|
||||
{
|
||||
gint value = gtk_combo_box_get_active (button);
|
||||
const gchar* property = g_object_get_data (G_OBJECT (button), "property");
|
||||
gint custom_value = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (button),
|
||||
"katze-custom-value"));
|
||||
const gchar* custom_property = g_object_get_data (G_OBJECT (button),
|
||||
"katze-custom-property");
|
||||
|
||||
if (custom_value)
|
||||
{
|
||||
GtkWidget* child = gtk_bin_get_child (GTK_BIN (button));
|
||||
|
||||
if (value == custom_value && GTK_IS_CELL_VIEW (child))
|
||||
{
|
||||
GtkWidget* entry = gtk_entry_new ();
|
||||
gchar* custom_text = katze_object_get_string (object, custom_property);
|
||||
if (custom_text && *custom_text)
|
||||
gtk_entry_set_text (GTK_ENTRY (entry), custom_text);
|
||||
g_free (custom_text);
|
||||
gtk_widget_show (entry);
|
||||
gtk_container_add (GTK_CONTAINER (button), entry);
|
||||
gtk_widget_grab_focus (entry);
|
||||
g_signal_connect (entry, "focus-out-event",
|
||||
G_CALLBACK (proxy_entry_focus_out_event_cb), object);
|
||||
g_object_set_data_full (G_OBJECT (entry), "property",
|
||||
g_strdup (custom_property), g_free);
|
||||
}
|
||||
else if (value != custom_value && GTK_IS_ENTRY (child))
|
||||
{
|
||||
/* Force the combo to change the item again */
|
||||
gtk_widget_destroy (child);
|
||||
gtk_combo_box_set_active (button, value + 1);
|
||||
gtk_combo_box_set_active (button, value);
|
||||
}
|
||||
}
|
||||
|
||||
g_object_set (object, property, value, NULL);
|
||||
|
||||
if (custom_value)
|
||||
{
|
||||
#if GTK_CHECK_VERSION (2, 12, 0)
|
||||
if (value == custom_value)
|
||||
gtk_widget_set_tooltip_text (GTK_WIDGET (button), NULL);
|
||||
else
|
||||
{
|
||||
gchar* custom_text = katze_object_get_string (object, custom_property);
|
||||
gtk_widget_set_tooltip_text (GTK_WIDGET (button), custom_text);
|
||||
g_free (custom_text);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
proxy_object_notify_boolean_cb (GObject* object,
|
||||
|
@ -145,6 +293,127 @@ proxy_widget_string_destroy_cb (GtkWidget* proxy,
|
|||
proxy_object_notify_string_cb, proxy);
|
||||
}
|
||||
|
||||
static GList*
|
||||
katze_app_info_get_all_for_category (const gchar* category)
|
||||
{
|
||||
GList* all_apps = g_app_info_get_all ();
|
||||
GList* apps = NULL;
|
||||
guint i = 0;
|
||||
GAppInfo* info;
|
||||
while ((info = g_list_nth_data (all_apps, i++)))
|
||||
{
|
||||
#ifdef GDK_WINDOWING_X11
|
||||
gchar* filename = g_strconcat ("applications/", g_app_info_get_id (info), NULL);
|
||||
GKeyFile* file = g_key_file_new ();
|
||||
|
||||
if (g_key_file_load_from_data_dirs (file, filename, NULL, G_KEY_FILE_NONE, NULL))
|
||||
{
|
||||
gchar* cat = g_key_file_get_string (file, "Desktop Entry",
|
||||
"Categories", NULL);
|
||||
if (cat && g_strrstr (cat, category))
|
||||
apps = g_list_append (apps, info);
|
||||
|
||||
g_free (cat);
|
||||
}
|
||||
g_key_file_free (file);
|
||||
g_free (filename);
|
||||
#else
|
||||
apps = g_list_append (apps, info);
|
||||
#endif
|
||||
}
|
||||
g_list_free (all_apps);
|
||||
return apps;
|
||||
}
|
||||
|
||||
#if !GLIB_CHECK_VERSION (2, 20, 0)
|
||||
/* Icon tokenization, for Glib < 2.20 */
|
||||
static gboolean
|
||||
g_icon_to_string_tokenized (GIcon *icon,
|
||||
GString *s)
|
||||
{
|
||||
GPtrArray *tokens;
|
||||
guint i;
|
||||
|
||||
if (G_IS_THEMED_ICON (icon))
|
||||
{
|
||||
guint n;
|
||||
const char * const *names;
|
||||
tokens = g_ptr_array_new ();
|
||||
g_object_get (icon, "names", &names, NULL);
|
||||
for (n = 0; names[n] != NULL; n++)
|
||||
g_ptr_array_add (tokens, g_strdup (names[n]));
|
||||
}
|
||||
else if (G_IS_FILE_ICON (icon))
|
||||
{
|
||||
tokens = g_ptr_array_new ();
|
||||
g_ptr_array_add (tokens,
|
||||
g_file_get_uri (g_file_icon_get_file (G_FILE_ICON (icon))));
|
||||
}
|
||||
else
|
||||
return FALSE;
|
||||
|
||||
g_string_append (s, g_type_name_from_instance ((GTypeInstance *)icon));
|
||||
|
||||
for (i = 0; i < tokens->len; i++)
|
||||
{
|
||||
char *token = g_ptr_array_index (tokens, i);
|
||||
|
||||
g_string_append_c (s, ' ');
|
||||
g_string_append_uri_escaped (s, token, "!$&'()*+,;=:@/", TRUE);
|
||||
|
||||
g_free (token);
|
||||
}
|
||||
|
||||
g_ptr_array_free (tokens, TRUE);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* GIcon serialization, for Glib < 2.20 */
|
||||
static gchar *
|
||||
g_icon_to_string (GIcon *icon)
|
||||
{
|
||||
gchar *ret = NULL;
|
||||
|
||||
g_return_val_if_fail (G_IS_ICON (icon), NULL);
|
||||
|
||||
if (G_IS_FILE_ICON (icon))
|
||||
{
|
||||
GFile *file = g_file_icon_get_file (G_FILE_ICON (icon));
|
||||
if (g_file_is_native (file))
|
||||
{
|
||||
ret = g_file_get_path (file);
|
||||
if (!g_utf8_validate (ret, -1, NULL))
|
||||
{
|
||||
g_free (ret);
|
||||
ret = NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
ret = g_file_get_uri (file);
|
||||
}
|
||||
else if (G_IS_THEMED_ICON (icon))
|
||||
{
|
||||
const char * const *names;
|
||||
g_object_get (icon, "names", &names, NULL);
|
||||
if (names && names[0] && names[0][0] != '.' &&
|
||||
g_utf8_validate (names[0], -1, NULL) && names[1] == NULL)
|
||||
ret = g_strdup (names[0]);
|
||||
}
|
||||
|
||||
if (ret == NULL)
|
||||
{
|
||||
GString *s = g_string_new (". ");
|
||||
if (g_icon_to_string_tokenized (icon, s))
|
||||
ret = g_string_free (s, FALSE);
|
||||
else
|
||||
g_string_free (s, TRUE);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* katze_property_proxy:
|
||||
* @object: a #GObject
|
||||
|
@ -173,12 +442,23 @@ proxy_widget_string_destroy_cb (GtkWidget* proxy,
|
|||
* Since 0.2.0 the following hints are also supported:
|
||||
* "font-monospace": the widget created will be particularly suitable for
|
||||
* choosing a fixed-width font from installed fonts.
|
||||
* Since 0.2.1 the following hints are also supported:
|
||||
* "application-TYPE": the widget created will be particularly suitable
|
||||
* for choosing an application to open TYPE files, ie. "text/plain".
|
||||
* "application-CATEGORY": the widget created will be particularly suitable
|
||||
* for choosing an application to open CATEGORY files, ie. "Network".
|
||||
* "custom-PROPERTY": the last value of an enumeration will be the "custom"
|
||||
* value, where the user may enter text freely, which then updates
|
||||
* the property PROPERTY instead. This applies only to enumerations.
|
||||
*
|
||||
* Any other values for @hint are silently ignored.
|
||||
*
|
||||
* Since 0.1.2 strings without hints and booleans are truly synchronous
|
||||
* including property changes causing the proxy to be updated.
|
||||
*
|
||||
* Since 0.2.1 the proxy may contain a label if the platform
|
||||
* has according widgets.
|
||||
*
|
||||
* Return value: a new widget
|
||||
**/
|
||||
GtkWidget*
|
||||
|
@ -216,12 +496,23 @@ katze_property_proxy (gpointer object,
|
|||
gchar* notify_property;
|
||||
gboolean toggled = katze_object_get_boolean (object, property);
|
||||
|
||||
#ifdef HAVE_HILDON_2_2
|
||||
if (_hint != g_intern_string ("toggle"))
|
||||
{
|
||||
widget = hildon_check_button_new (HILDON_SIZE_FINGER_HEIGHT | HILDON_SIZE_AUTO_WIDTH);
|
||||
gtk_button_set_label (GTK_BUTTON (widget), gettext (nick));
|
||||
hildon_check_button_set_active (HILDON_CHECK_BUTTON (widget), toggled);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
widget = gtk_check_button_new ();
|
||||
if (_hint == g_intern_string ("toggle"))
|
||||
gtk_toggle_button_set_mode (GTK_TOGGLE_BUTTON (widget), FALSE);
|
||||
else
|
||||
gtk_button_set_label (GTK_BUTTON (widget), gettext (nick));
|
||||
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), toggled);
|
||||
}
|
||||
g_signal_connect (widget, "toggled",
|
||||
G_CALLBACK (proxy_toggle_button_toggled_cb), object);
|
||||
notify_property = g_strdup_printf ("notify::%s", property);
|
||||
|
@ -295,6 +586,9 @@ katze_property_proxy (gpointer object,
|
|||
pango_context_list_families (context, &families, &n_families);
|
||||
if (!string)
|
||||
string = g_strdup (G_PARAM_SPEC_STRING (pspec)->default_value);
|
||||
/* 'sans' and 'sans-serif' are presumably the same */
|
||||
if (!g_strcmp0 (string, "sans-serif"))
|
||||
katze_assign (string, g_strdup ("sans"));
|
||||
if (string)
|
||||
{
|
||||
gint j = 0;
|
||||
|
@ -315,6 +609,101 @@ katze_property_proxy (gpointer object,
|
|||
G_CALLBACK (proxy_combo_box_text_changed_cb), object);
|
||||
g_free (families);
|
||||
}
|
||||
else if (type == G_TYPE_PARAM_STRING && hint && g_str_has_prefix (hint, "application-"))
|
||||
{
|
||||
GtkListStore* model;
|
||||
GtkCellRenderer* renderer;
|
||||
GtkComboBox* combo;
|
||||
GList* apps;
|
||||
const gchar* app_type = &hint[12];
|
||||
gint icon_width = 16;
|
||||
gtk_icon_size_lookup (GTK_ICON_SIZE_MENU, &icon_width, NULL);
|
||||
|
||||
model = gtk_list_store_new (4, G_TYPE_APP_INFO, G_TYPE_STRING,
|
||||
G_TYPE_STRING, G_TYPE_INT);
|
||||
widget = gtk_combo_box_new_with_model (GTK_TREE_MODEL (model));
|
||||
renderer = gtk_cell_renderer_pixbuf_new ();
|
||||
gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (widget), renderer, FALSE);
|
||||
gtk_cell_layout_add_attribute (GTK_CELL_LAYOUT (widget), renderer, "icon-name", 1);
|
||||
gtk_cell_layout_add_attribute (GTK_CELL_LAYOUT (widget), renderer, "width", 3);
|
||||
renderer = gtk_cell_renderer_text_new ();
|
||||
gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (widget), renderer, TRUE);
|
||||
gtk_cell_layout_add_attribute (GTK_CELL_LAYOUT (widget), renderer, "text", 2);
|
||||
combo = GTK_COMBO_BOX (widget);
|
||||
apps = g_app_info_get_all_for_type (app_type);
|
||||
if (!apps)
|
||||
apps = katze_app_info_get_all_for_category (app_type);
|
||||
|
||||
string = katze_object_get_string (object, property);
|
||||
if (!g_strcmp0 (string, ""))
|
||||
katze_assign (string, NULL);
|
||||
|
||||
if (apps)
|
||||
{
|
||||
GtkTreeIter iter_none;
|
||||
gint i = 0;
|
||||
GAppInfo* info;
|
||||
|
||||
gtk_list_store_insert_with_values (model, &iter_none, 0,
|
||||
0, NULL, 1, NULL, 2, _("None"), 3, icon_width, -1);
|
||||
|
||||
while ((info = g_list_nth_data (apps, i++)))
|
||||
{
|
||||
const gchar* name = g_app_info_get_name (info);
|
||||
GIcon* icon = g_app_info_get_icon (info);
|
||||
gchar* icon_name;
|
||||
GtkTreeIter iter;
|
||||
|
||||
if (!g_app_info_should_show (info))
|
||||
continue;
|
||||
|
||||
icon_name = icon ? g_icon_to_string (icon) : NULL;
|
||||
gtk_list_store_insert_with_values (model, &iter, G_MAXINT,
|
||||
0, info, 1, icon_name, 2, name, 3, icon_width, -1);
|
||||
if (string && !strcmp (katze_app_info_get_commandline (info), string))
|
||||
gtk_combo_box_set_active_iter (combo, &iter);
|
||||
|
||||
g_free (icon_name);
|
||||
}
|
||||
|
||||
info = g_app_info_create_from_commandline ("",
|
||||
"", G_APP_INFO_CREATE_NONE, NULL);
|
||||
gtk_list_store_insert_with_values (model, NULL, G_MAXINT,
|
||||
0, info, 1, NULL, 2, _("Custom..."), 3, icon_width, -1);
|
||||
g_object_unref (info);
|
||||
|
||||
if (gtk_combo_box_get_active (combo) == -1)
|
||||
{
|
||||
if (string)
|
||||
{
|
||||
GtkWidget* entry;
|
||||
const gchar* exe;
|
||||
|
||||
info = g_app_info_create_from_commandline (string,
|
||||
NULL, G_APP_INFO_CREATE_NONE, NULL);
|
||||
#if !GLIB_CHECK_VERSION (2, 20, 0)
|
||||
g_object_set_data (G_OBJECT (info), "katze-cmdline", string);
|
||||
#endif
|
||||
entry = gtk_entry_new ();
|
||||
exe = g_app_info_get_executable (info);
|
||||
if (exe && *exe && strcmp (exe, "%f"))
|
||||
gtk_entry_set_text (GTK_ENTRY (entry), string);
|
||||
gtk_widget_show (entry);
|
||||
gtk_container_add (GTK_CONTAINER (combo), entry);
|
||||
g_object_unref (info);
|
||||
g_signal_connect (entry, "focus-out-event",
|
||||
G_CALLBACK (proxy_entry_focus_out_event_cb), object);
|
||||
g_object_set_data_full (G_OBJECT (entry), "property",
|
||||
g_strdup (property), g_free);
|
||||
}
|
||||
else
|
||||
gtk_combo_box_set_active_iter (combo, &iter_none);
|
||||
}
|
||||
}
|
||||
g_list_free (apps);
|
||||
g_signal_connect (widget, "changed",
|
||||
G_CALLBACK (proxy_combo_box_apps_changed_cb), object);
|
||||
}
|
||||
else if (type == G_TYPE_PARAM_STRING)
|
||||
{
|
||||
gchar* notify_property;
|
||||
|
@ -356,6 +745,10 @@ katze_property_proxy (gpointer object,
|
|||
widget = gtk_spin_button_new_with_range (
|
||||
G_PARAM_SPEC_INT (pspec)->minimum,
|
||||
G_PARAM_SPEC_INT (pspec)->maximum, 1);
|
||||
#if HAVE_HILDON
|
||||
hildon_gtk_entry_set_input_mode (GTK_ENTRY (widget),
|
||||
HILDON_GTK_INPUT_MODE_NUMERIC);
|
||||
#endif
|
||||
/* Keep it narrow, 5 digits are usually fine */
|
||||
gtk_entry_set_width_chars (GTK_ENTRY (widget), 5);
|
||||
gtk_spin_button_set_value (GTK_SPIN_BUTTON (widget), value);
|
||||
|
@ -368,23 +761,81 @@ katze_property_proxy (gpointer object,
|
|||
GEnumClass* enum_class = G_ENUM_CLASS (
|
||||
g_type_class_ref (pspec->value_type));
|
||||
gint value = katze_object_get_enum (object, property);
|
||||
const gchar* custom = NULL;
|
||||
|
||||
if (hint && g_str_has_prefix (hint, "custom-"))
|
||||
custom = &hint[7];
|
||||
|
||||
#ifdef HAVE_HILDON_2_2
|
||||
GtkWidget* selector;
|
||||
|
||||
widget = hildon_picker_button_new (
|
||||
HILDON_SIZE_FINGER_HEIGHT | HILDON_SIZE_AUTO_WIDTH,
|
||||
HILDON_BUTTON_ARRANGEMENT_HORIZONTAL);
|
||||
selector = hildon_touch_selector_new_text ();
|
||||
hildon_button_set_title (HILDON_BUTTON (widget), gettext (nick));
|
||||
hildon_picker_button_set_selector (HILDON_PICKER_BUTTON (widget),
|
||||
HILDON_TOUCH_SELECTOR (selector));
|
||||
#else
|
||||
widget = gtk_combo_box_new_text ();
|
||||
#endif
|
||||
for (i = 0; i < enum_class->n_values; i++)
|
||||
{
|
||||
const gchar* label = gettext (enum_class->values[i].value_nick);
|
||||
#ifdef HAVE_HILDON_2_2
|
||||
hildon_touch_selector_append_text (HILDON_TOUCH_SELECTOR (selector), label);
|
||||
#else
|
||||
gtk_combo_box_append_text (GTK_COMBO_BOX (widget), label);
|
||||
#endif
|
||||
}
|
||||
#ifdef HAVE_HILDON_2_2
|
||||
hildon_touch_selector_set_active (HILDON_TOUCH_SELECTOR (selector), 0, value);
|
||||
g_signal_connect (widget, "value-changed",
|
||||
G_CALLBACK (proxy_picker_button_changed_cb), object);
|
||||
#else
|
||||
gtk_combo_box_set_active (GTK_COMBO_BOX (widget), value);
|
||||
g_signal_connect (widget, "changed",
|
||||
G_CALLBACK (proxy_combo_box_changed_cb), object);
|
||||
#endif
|
||||
if (custom)
|
||||
{
|
||||
gchar* custom_text = katze_object_get_string (object, custom);
|
||||
|
||||
if (value == (gint)(enum_class->n_values - 1))
|
||||
{
|
||||
GtkWidget* entry = gtk_entry_new ();
|
||||
gchar* text = katze_object_get_string (object, custom);
|
||||
if (text && *text)
|
||||
gtk_entry_set_text (GTK_ENTRY (entry), text);
|
||||
gtk_widget_show (entry);
|
||||
gtk_container_add (GTK_CONTAINER (widget), entry);
|
||||
g_signal_connect (entry, "focus-out-event",
|
||||
G_CALLBACK (proxy_entry_focus_out_event_cb), object);
|
||||
g_object_set_data_full (G_OBJECT (entry), "property",
|
||||
g_strdup (custom), g_free);
|
||||
}
|
||||
#if GTK_CHECK_VERSION (2, 12, 0)
|
||||
else
|
||||
gtk_widget_set_tooltip_text (widget, custom_text);
|
||||
#endif
|
||||
|
||||
g_free (custom_text);
|
||||
|
||||
g_object_set_data (G_OBJECT (widget), "katze-custom-value",
|
||||
GINT_TO_POINTER (enum_class->n_values - 1));
|
||||
g_object_set_data (G_OBJECT (widget), "katze-custom-property",
|
||||
(gpointer)custom);
|
||||
}
|
||||
g_type_class_unref (enum_class);
|
||||
}
|
||||
else
|
||||
widget = gtk_label_new (gettext (nick));
|
||||
g_free (string);
|
||||
|
||||
#if GTK_CHECK_VERSION (2, 12, 0)
|
||||
if (!gtk_widget_get_tooltip_text (widget))
|
||||
gtk_widget_set_tooltip_text (widget, g_param_spec_get_blurb (pspec));
|
||||
#endif
|
||||
gtk_widget_set_sensitive (widget, pspec->flags & G_PARAM_WRITABLE);
|
||||
|
||||
g_object_set_data_full (G_OBJECT (widget), "property",
|
||||
|
@ -401,6 +852,9 @@ katze_property_proxy (gpointer object,
|
|||
* Create a label widget displaying the name of the specified object's property.
|
||||
*
|
||||
* Return value: a new label widget
|
||||
*
|
||||
* Since 0.2.1 the label will be empty if the property proxy for the
|
||||
* same property would contain a label already.
|
||||
**/
|
||||
GtkWidget*
|
||||
katze_property_label (gpointer object,
|
||||
|
@ -421,8 +875,18 @@ katze_property_label (gpointer object,
|
|||
property, G_OBJECT_CLASS_NAME (class));
|
||||
return gtk_label_new (property);
|
||||
}
|
||||
|
||||
#ifdef HAVE_HILDON_2_2
|
||||
if (G_PARAM_SPEC_TYPE (pspec) == G_TYPE_PARAM_ENUM)
|
||||
return gtk_label_new (NULL);
|
||||
#endif
|
||||
|
||||
nick = g_param_spec_get_nick (pspec);
|
||||
widget = gtk_label_new (nick);
|
||||
#if GTK_CHECK_VERSION (2, 12, 0)
|
||||
gtk_widget_set_tooltip_text (widget, g_param_spec_get_blurb (pspec));
|
||||
#endif
|
||||
gtk_misc_set_alignment (GTK_MISC (widget), 0.0, 0.5);
|
||||
|
||||
return widget;
|
||||
}
|
||||
|
@ -849,3 +1313,167 @@ katze_object_get_object (gpointer object,
|
|||
g_object_get (object, property, &value, NULL);
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* katze_mkdir_with_parents:
|
||||
* @pathname: a pathname in the GLib file name encoding
|
||||
* @mode: permissions to use for newly created directories
|
||||
*
|
||||
* Create a directory if it doesn't already exist. Create intermediate
|
||||
* parent directories as needed, too.
|
||||
*
|
||||
* Similar to g_mkdir_with_parents() but returning early if the
|
||||
* @pathname refers to an existing directory.
|
||||
*
|
||||
* Returns: 0 if the directory already exists, or was successfully
|
||||
* created. Returns -1 if an error occurred, with errno set.
|
||||
*
|
||||
* Since: 0.2.1
|
||||
*/
|
||||
/* Creating directories recursively
|
||||
Copyright 2000 Red Hat, Inc.
|
||||
Originally copied from Glib 2.20, coding style adjusted
|
||||
Modified to determine file existence early and pathname must be != NULL */
|
||||
int
|
||||
katze_mkdir_with_parents (const gchar* pathname,
|
||||
int mode)
|
||||
{
|
||||
gchar* fn, *p;
|
||||
|
||||
if (g_file_test (pathname, G_FILE_TEST_EXISTS))
|
||||
return 0;
|
||||
|
||||
fn = g_strdup (pathname);
|
||||
|
||||
if (g_path_is_absolute (fn))
|
||||
p = (gchar *) g_path_skip_root (fn);
|
||||
else
|
||||
p = fn;
|
||||
|
||||
do
|
||||
{
|
||||
while (*p && !G_IS_DIR_SEPARATOR (*p))
|
||||
p++;
|
||||
|
||||
if (!*p)
|
||||
p = NULL;
|
||||
else
|
||||
*p = '\0';
|
||||
|
||||
if (!g_file_test (fn, G_FILE_TEST_EXISTS))
|
||||
{
|
||||
if (g_mkdir (fn, mode) == -1)
|
||||
{
|
||||
g_free (fn);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else if (!g_file_test (fn, G_FILE_TEST_IS_DIR))
|
||||
{
|
||||
g_free (fn);
|
||||
return -1;
|
||||
}
|
||||
if (p)
|
||||
{
|
||||
*p++ = G_DIR_SEPARATOR;
|
||||
while (*p && G_IS_DIR_SEPARATOR (*p))
|
||||
p++;
|
||||
}
|
||||
}
|
||||
while (p);
|
||||
|
||||
g_free (fn);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* katze_widget_has_touchscreen_mode:
|
||||
* @widget: a #GtkWidget, or %NULL
|
||||
*
|
||||
* Determines whether @widget should operate in touchscreen
|
||||
* mode, as determined by GtkSettings or the environment
|
||||
* variable MIDORI_TOUCHSCREEN.
|
||||
*
|
||||
* If @widget is %NULL, the default screen will be used.
|
||||
*
|
||||
* Returns: %TRUE if touchscreen mode should be used
|
||||
*
|
||||
* Since: 0.2.1
|
||||
*/
|
||||
gboolean
|
||||
katze_widget_has_touchscreen_mode (GtkWidget* widget)
|
||||
{
|
||||
const gchar* touchscreen = g_getenv ("MIDORI_TOUCHSCREEN");
|
||||
if (touchscreen && touchscreen[0] == '1')
|
||||
return TRUE;
|
||||
else if (touchscreen && touchscreen[0] == '0')
|
||||
return FALSE;
|
||||
else
|
||||
{
|
||||
GdkScreen* screen = widget && gtk_widget_has_screen (widget)
|
||||
? gtk_widget_get_screen (widget) : gdk_screen_get_default ();
|
||||
GtkSettings* gtk_settings = gtk_settings_get_for_screen (screen);
|
||||
gboolean enabled;
|
||||
g_object_get (gtk_settings, "gtk-touchscreen-mode", &enabled, NULL);
|
||||
return enabled;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* katze_load_cached_icon:
|
||||
* @uri: an URI string
|
||||
* @widget: a #GtkWidget, or %NULL
|
||||
*
|
||||
* Loads a cached icon for the specified @uri. If there is no
|
||||
* icon and @widget is specified, a default will be returned.
|
||||
*
|
||||
* Returns: a #GdkPixbuf, or %NULL
|
||||
*
|
||||
* Since: 0.2.2
|
||||
*/
|
||||
GdkPixbuf*
|
||||
katze_load_cached_icon (const gchar* uri,
|
||||
GtkWidget* widget)
|
||||
{
|
||||
GdkPixbuf* icon = NULL;
|
||||
|
||||
if (g_str_has_prefix (uri, "http://"))
|
||||
{
|
||||
guint i;
|
||||
gchar* icon_uri;
|
||||
gchar* checksum;
|
||||
gchar* ext;
|
||||
gchar* filename;
|
||||
gchar* path;
|
||||
|
||||
i = 8;
|
||||
while (uri[i] != '\0' && uri[i] != '/')
|
||||
i++;
|
||||
if (uri[i] == '/')
|
||||
{
|
||||
icon_uri = g_strdup (uri);
|
||||
icon_uri[i] = '\0';
|
||||
icon_uri = g_strdup_printf ("%s/favicon.ico", icon_uri);
|
||||
}
|
||||
else
|
||||
icon_uri = g_strdup_printf ("%s/favicon.ico", uri);
|
||||
|
||||
checksum = g_compute_checksum_for_string (G_CHECKSUM_MD5, icon_uri, -1);
|
||||
ext = g_strrstr (icon_uri, ".");
|
||||
g_free (icon_uri);
|
||||
filename = g_strdup_printf ("%s%s", checksum, ext ? ext : "");
|
||||
g_free (checksum);
|
||||
path = g_build_filename (g_get_user_cache_dir (), PACKAGE_NAME,
|
||||
"icons", filename, NULL);
|
||||
if ((icon = gdk_pixbuf_new_from_file_at_size (path, 16, 16, NULL)))
|
||||
{
|
||||
g_free (path);
|
||||
return icon;
|
||||
}
|
||||
g_free (path);
|
||||
}
|
||||
|
||||
return icon || !widget ? icon : gtk_widget_render_icon (widget,
|
||||
GTK_STOCK_FILE, GTK_ICON_SIZE_MENU, NULL);
|
||||
}
|
||||
|
|
|
@ -34,11 +34,12 @@ G_BEGIN_DECLS
|
|||
* Frees @lvalue if needed and assigns it the value of @rvalue.
|
||||
**/
|
||||
#define katze_assign(lvalue, rvalue) \
|
||||
if (1) \
|
||||
do \
|
||||
{ \
|
||||
g_free (lvalue); \
|
||||
lvalue = rvalue; \
|
||||
}
|
||||
} \
|
||||
while (0)
|
||||
|
||||
/**
|
||||
* katze_object_assign:
|
||||
|
@ -48,12 +49,13 @@ G_BEGIN_DECLS
|
|||
* Unrefs @lvalue if needed and assigns it the value of @rvalue.
|
||||
**/
|
||||
#define katze_object_assign(lvalue, rvalue) \
|
||||
if (1) \
|
||||
do \
|
||||
{ \
|
||||
if (lvalue) \
|
||||
g_object_unref (lvalue); \
|
||||
lvalue = rvalue; \
|
||||
}
|
||||
} \
|
||||
while (0)
|
||||
|
||||
/**
|
||||
* katze_strv_assign:
|
||||
|
@ -65,11 +67,12 @@ G_BEGIN_DECLS
|
|||
* Since: 0.1.7
|
||||
**/
|
||||
#define katze_strv_assign(lvalue, rvalue) \
|
||||
if (1) \
|
||||
do \
|
||||
{ \
|
||||
g_strfreev (lvalue); \
|
||||
lvalue = rvalue; \
|
||||
}
|
||||
} \
|
||||
while (0)
|
||||
|
||||
GtkWidget*
|
||||
katze_property_proxy (gpointer object,
|
||||
|
@ -137,6 +140,17 @@ gpointer
|
|||
katze_object_get_object (gpointer object,
|
||||
const gchar* property);
|
||||
|
||||
int
|
||||
katze_mkdir_with_parents (const gchar* pathname,
|
||||
int mode);
|
||||
|
||||
gboolean
|
||||
katze_widget_has_touchscreen_mode (GtkWidget* widget);
|
||||
|
||||
GdkPixbuf*
|
||||
katze_load_cached_icon (const gchar* uri,
|
||||
GtkWidget* widget);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __KATZE_UTILS_H__ */
|
||||
|
|
|
@ -22,5 +22,6 @@
|
|||
#include "katze-separatoraction.h"
|
||||
#include "katze-net.h"
|
||||
#include "katze-scrolled.h"
|
||||
#include "katze-preferences.h"
|
||||
|
||||
#endif /* __KATZE_H__ */
|
||||
|
|
|
@ -10,5 +10,5 @@ obj.target = 'katze'
|
|||
obj.includes = '. ../.'
|
||||
obj.find_sources_in_dirs ('.')
|
||||
obj.add_marshal_file ('marshal.list', 'katze_cclosure_marshal')
|
||||
obj.uselib = 'M GMODULE LIBSOUP GTK LIBXML WEBKIT'
|
||||
obj.uselib = 'M GMODULE LIBSOUP GTK HILDON LIBXML WEBKIT'
|
||||
obj.install_path = None
|
||||
|
|
|
@ -39,6 +39,7 @@ G_BEGIN_DECLS
|
|||
#define GTK_TYPE_ICON_ENTRY GTK_TYPE_ENTRY
|
||||
#define gtk_icon_entry_new gtk_entry_new
|
||||
#define gtk_icon_entry_set_icon_from_stock gtk_entry_set_icon_from_stock
|
||||
#define gtk_icon_entry_set_icon_from_icon_name gtk_entry_set_icon_from_icon_name
|
||||
|
||||
void
|
||||
gtk_icon_entry_set_icon_from_pixbuf (GtkEntry* entry,
|
||||
|
|
224
midori/main.c
224
midori/main.c
|
@ -29,12 +29,8 @@
|
|||
|
||||
#if HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#define is_writable(_cfg_filename) \
|
||||
!g_access (_cfg_filename, W_OK) || \
|
||||
!g_file_test (_cfg_filename, G_FILE_TEST_EXISTS)
|
||||
#else
|
||||
#define is_writable(_cfg_filename) 1
|
||||
#endif
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
@ -50,8 +46,14 @@
|
|||
#include <locale.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SIGNAL_H
|
||||
#include <signal.h>
|
||||
#endif
|
||||
|
||||
#if HAVE_HILDON
|
||||
#include <libosso.h>
|
||||
#define BOOKMARK_FILE "/home/user/.bookmarks/MyBookmarks.xml"
|
||||
#else
|
||||
#define BOOKMARK_FILE "bookmarks.xbel"
|
||||
#endif
|
||||
|
||||
#define MIDORI_HISTORY_ERROR g_quark_from_string("MIDORI_HISTORY_ERROR")
|
||||
|
@ -66,8 +68,11 @@ typedef enum
|
|||
static gchar*
|
||||
build_config_filename (const gchar* filename)
|
||||
{
|
||||
const gchar* path = sokoke_set_config_dir (NULL);
|
||||
g_mkdir_with_parents (path, 0700);
|
||||
const gchar* path;
|
||||
|
||||
if (g_path_is_absolute (filename))
|
||||
return g_strdup (filename);
|
||||
path = sokoke_set_config_dir (NULL);
|
||||
return g_build_filename (path, filename, NULL);
|
||||
}
|
||||
|
||||
|
@ -199,36 +204,39 @@ settings_save_to_file (MidoriWebSettings* settings,
|
|||
type = G_PARAM_SPEC_TYPE (pspec);
|
||||
property = g_param_spec_get_name (pspec);
|
||||
if (!(pspec->flags & G_PARAM_WRITABLE))
|
||||
{
|
||||
gchar* prop_comment = g_strdup_printf ("# %s", property);
|
||||
g_key_file_set_string (key_file, "settings", prop_comment, "");
|
||||
g_free (prop_comment);
|
||||
continue;
|
||||
}
|
||||
if (type == G_TYPE_PARAM_STRING)
|
||||
{
|
||||
gchar* string;
|
||||
const gchar* def_string = G_PARAM_SPEC_STRING (pspec)->default_value;
|
||||
g_object_get (settings, property, &string, NULL);
|
||||
g_key_file_set_string (key_file, "settings", property,
|
||||
string ? string : "");
|
||||
if (!string)
|
||||
string = g_strdup ("");
|
||||
if (!def_string)
|
||||
def_string = "";
|
||||
if (strcmp (string, def_string))
|
||||
g_key_file_set_string (key_file, "settings", property, string);
|
||||
g_free (string);
|
||||
}
|
||||
else if (type == G_TYPE_PARAM_INT)
|
||||
{
|
||||
gint integer;
|
||||
g_object_get (settings, property, &integer, NULL);
|
||||
if (integer != G_PARAM_SPEC_INT (pspec)->default_value)
|
||||
g_key_file_set_integer (key_file, "settings", property, integer);
|
||||
}
|
||||
else if (type == G_TYPE_PARAM_FLOAT)
|
||||
{
|
||||
gfloat number;
|
||||
g_object_get (settings, property, &number, NULL);
|
||||
if (number != G_PARAM_SPEC_FLOAT (pspec)->default_value)
|
||||
g_key_file_set_double (key_file, "settings", property, number);
|
||||
}
|
||||
else if (type == G_TYPE_PARAM_BOOLEAN)
|
||||
{
|
||||
gboolean truth;
|
||||
g_object_get (settings, property, &truth, NULL);
|
||||
if (truth != G_PARAM_SPEC_BOOLEAN (pspec)->default_value)
|
||||
g_key_file_set_boolean (key_file, "settings", property, truth);
|
||||
}
|
||||
else if (type == G_TYPE_PARAM_ENUM)
|
||||
|
@ -236,8 +244,10 @@ settings_save_to_file (MidoriWebSettings* settings,
|
|||
GEnumClass* enum_class = G_ENUM_CLASS (
|
||||
g_type_class_ref (pspec->value_type));
|
||||
gint integer;
|
||||
GEnumValue* enum_value;
|
||||
g_object_get (settings, property, &integer, NULL);
|
||||
GEnumValue* enum_value = g_enum_get_value (enum_class, integer);
|
||||
enum_value = g_enum_get_value (enum_class, integer);
|
||||
if (integer != G_PARAM_SPEC_ENUM (pspec)->default_value)
|
||||
g_key_file_set_string (key_file, "settings", property,
|
||||
enum_value->value_name);
|
||||
}
|
||||
|
@ -445,7 +455,7 @@ midori_history_remove_item_cb (KatzeArray* history,
|
|||
|
||||
sqlcmd = sqlite3_mprintf (
|
||||
"DELETE FROM history WHERE uri = '%q' AND"
|
||||
" title = '%q' AND date = %" G_GINT64_FORMAT,
|
||||
" title = '%q' AND date = %llu",
|
||||
katze_item_get_uri (item),
|
||||
katze_item_get_name (item),
|
||||
katze_item_get_added (item));
|
||||
|
@ -491,7 +501,7 @@ midori_history_notify_item_cb (KatzeItem* item,
|
|||
GError* error = NULL;
|
||||
|
||||
sqlcmd = sqlite3_mprintf ("UPDATE history SET title='%q' WHERE "
|
||||
"uri='%q' AND date=%" G_GUINT64_FORMAT,
|
||||
"uri='%q' AND date=%llu",
|
||||
katze_item_get_name (item),
|
||||
katze_item_get_uri (item),
|
||||
katze_item_get_added (item));
|
||||
|
@ -539,8 +549,8 @@ midori_history_add_item_cb (KatzeArray* array,
|
|||
}
|
||||
}
|
||||
sqlcmd = sqlite3_mprintf ("INSERT INTO history VALUES"
|
||||
"('%q', '%q', %" G_GUINT64_FORMAT ","
|
||||
" %" G_GUINT64_FORMAT ")",
|
||||
"('%q', '%q', %llu,"
|
||||
" %llu)",
|
||||
katze_item_get_uri (item),
|
||||
katze_item_get_name (item),
|
||||
katze_item_get_added (item),
|
||||
|
@ -810,7 +820,7 @@ midori_bookmarks_notify_item_cb (KatzeArray* folder,
|
|||
gchar* config_file;
|
||||
GError* error;
|
||||
|
||||
config_file = build_config_filename ("bookmarks.xbel");
|
||||
config_file = build_config_filename (BOOKMARK_FILE);
|
||||
error = NULL;
|
||||
if (!midori_array_to_file (bookmarks, config_file, "xbel", &error))
|
||||
{
|
||||
|
@ -822,7 +832,7 @@ midori_bookmarks_notify_item_cb (KatzeArray* folder,
|
|||
|
||||
static void
|
||||
midori_bookmarks_add_item_cb (KatzeArray* folder,
|
||||
GObject* item,
|
||||
KatzeItem* item,
|
||||
KatzeArray* bookmarks);
|
||||
|
||||
static void
|
||||
|
@ -831,24 +841,17 @@ midori_bookmarks_remove_item_cb (KatzeArray* folder,
|
|||
KatzeArray* bookmarks);
|
||||
|
||||
static void
|
||||
midori_bookmarks_add_item_cb (KatzeArray* folder,
|
||||
GObject* item,
|
||||
midori_bookmarks_connect_item (KatzeArray* folder,
|
||||
KatzeItem* item,
|
||||
KatzeArray* bookmarks)
|
||||
{
|
||||
gchar* config_file;
|
||||
GError* error;
|
||||
|
||||
config_file = build_config_filename ("bookmarks.xbel");
|
||||
error = NULL;
|
||||
if (!midori_array_to_file (bookmarks, config_file, "xbel", &error))
|
||||
if (KATZE_IS_ARRAY (item))
|
||||
{
|
||||
g_warning (_("The bookmarks couldn't be saved. %s"), error->message);
|
||||
g_error_free (error);
|
||||
}
|
||||
g_free (config_file);
|
||||
KatzeItem* child;
|
||||
guint i = 0;
|
||||
while ((child = katze_array_get_nth_item ((KatzeArray*)item, i++)))
|
||||
midori_bookmarks_connect_item ((KatzeArray*)item, child, bookmarks);
|
||||
|
||||
if (folder == bookmarks && KATZE_IS_ARRAY (item))
|
||||
{
|
||||
g_signal_connect_after (item, "add-item",
|
||||
G_CALLBACK (midori_bookmarks_add_item_cb), bookmarks);
|
||||
g_signal_connect_after (item, "remove-item",
|
||||
|
@ -859,6 +862,26 @@ midori_bookmarks_add_item_cb (KatzeArray* folder,
|
|||
G_CALLBACK (midori_bookmarks_notify_item_cb), bookmarks);
|
||||
}
|
||||
|
||||
static void
|
||||
midori_bookmarks_add_item_cb (KatzeArray* folder,
|
||||
KatzeItem* item,
|
||||
KatzeArray* bookmarks)
|
||||
{
|
||||
gchar* config_file;
|
||||
GError* error;
|
||||
|
||||
config_file = build_config_filename (BOOKMARK_FILE);
|
||||
error = NULL;
|
||||
if (!midori_array_to_file (bookmarks, config_file, "xbel", &error))
|
||||
{
|
||||
g_warning (_("The bookmarks couldn't be saved. %s"), error->message);
|
||||
g_error_free (error);
|
||||
}
|
||||
g_free (config_file);
|
||||
|
||||
midori_bookmarks_connect_item (folder, item, bookmarks);
|
||||
}
|
||||
|
||||
static void
|
||||
midori_bookmarks_remove_item_cb (KatzeArray* folder,
|
||||
GObject* item,
|
||||
|
@ -867,7 +890,7 @@ midori_bookmarks_remove_item_cb (KatzeArray* folder,
|
|||
gchar* config_file;
|
||||
GError* error;
|
||||
|
||||
config_file = build_config_filename ("bookmarks.xbel");
|
||||
config_file = build_config_filename (BOOKMARK_FILE);
|
||||
error = NULL;
|
||||
if (!midori_array_to_file (bookmarks, config_file, "xbel", &error))
|
||||
{
|
||||
|
@ -877,8 +900,15 @@ midori_bookmarks_remove_item_cb (KatzeArray* folder,
|
|||
g_free (config_file);
|
||||
|
||||
if (KATZE_IS_ARRAY (item))
|
||||
{
|
||||
g_signal_handlers_disconnect_by_func (item,
|
||||
midori_bookmarks_add_item_cb, bookmarks);
|
||||
g_signal_handlers_disconnect_by_func (item,
|
||||
midori_bookmarks_remove_item_cb, bookmarks);
|
||||
}
|
||||
|
||||
g_signal_handlers_disconnect_by_func (item,
|
||||
midori_bookmarks_notify_item_cb, bookmarks);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -966,8 +996,9 @@ midori_app_add_browser_cb (MidoriApp* app,
|
|||
midori_panel_append_page (MIDORI_PANEL (panel), MIDORI_VIEWABLE (addon));
|
||||
|
||||
/* Extensions */
|
||||
addon = g_object_new (MIDORI_TYPE_EXTENSIONS, "app", app, NULL);
|
||||
addon = g_object_new (MIDORI_TYPE_EXTENSIONS, NULL);
|
||||
gtk_widget_show (addon);
|
||||
g_object_set (addon, "app", app, NULL);
|
||||
midori_panel_append_page (MIDORI_PANEL (panel), MIDORI_VIEWABLE (addon));
|
||||
|
||||
g_object_unref (panel);
|
||||
|
@ -1308,7 +1339,6 @@ midori_load_extensions (gpointer data)
|
|||
{
|
||||
const gchar* filename;
|
||||
gchar* config_file = build_config_filename ("config");
|
||||
gboolean is_writable = is_writable (config_file);
|
||||
|
||||
while ((filename = g_dir_read_name (extension_dir)))
|
||||
{
|
||||
|
@ -1352,13 +1382,10 @@ midori_load_extensions (gpointer data)
|
|||
if (!g_strcmp0 (filename, name))
|
||||
g_signal_emit_by_name (extension, "activate", app);
|
||||
}
|
||||
if (is_writable)
|
||||
{
|
||||
g_signal_connect_after (extension, "activate",
|
||||
G_CALLBACK (extension_activate_cb), app);
|
||||
g_signal_connect_after (extension, "deactivate",
|
||||
G_CALLBACK (extension_activate_cb), app);
|
||||
}
|
||||
g_object_unref (extension);
|
||||
}
|
||||
g_dir_close (extension_dir);
|
||||
|
@ -1419,13 +1446,12 @@ midori_load_session (gpointer data)
|
|||
GtkAction* action = gtk_action_group_get_action (action_group, "LastSession");
|
||||
g_signal_connect (action, "activate",
|
||||
G_CALLBACK (midori_browser_action_last_session_activate_cb), browser);
|
||||
gtk_action_set_sensitive (action, TRUE);
|
||||
gtk_action_set_visible (action, TRUE);
|
||||
}
|
||||
midori_app_add_browser (app, browser);
|
||||
gtk_widget_show (GTK_WIDGET (browser));
|
||||
|
||||
katze_assign (config_file, build_config_filename ("accels"));
|
||||
if (is_writable (config_file))
|
||||
g_signal_connect_after (gtk_accel_map_get (), "changed",
|
||||
G_CALLBACK (accel_map_changed_cb), NULL);
|
||||
|
||||
|
@ -1465,8 +1491,6 @@ midori_load_session (gpointer data)
|
|||
g_object_unref (_session);
|
||||
|
||||
katze_assign (config_file, build_config_filename ("session.xbel"));
|
||||
if (is_writable (config_file))
|
||||
{
|
||||
g_signal_connect_after (browser, "notify::uri",
|
||||
G_CALLBACK (midori_browser_session_cb), session);
|
||||
g_signal_connect_after (browser, "add-tab",
|
||||
|
@ -1475,7 +1499,6 @@ midori_load_session (gpointer data)
|
|||
G_CALLBACK (midori_browser_session_cb), session);
|
||||
g_object_weak_ref (G_OBJECT (session),
|
||||
(GWeakNotify)(midori_browser_weak_notify_cb), browser);
|
||||
}
|
||||
|
||||
if (command)
|
||||
midori_app_send_command (app, command);
|
||||
|
@ -1569,12 +1592,22 @@ midori_remove_config_file (gint clear_prefs,
|
|||
if ((clear_prefs & flag) == flag)
|
||||
{
|
||||
gchar* config_file = build_config_filename (filename);
|
||||
if (is_writable (config_file))
|
||||
g_unlink (config_file);
|
||||
g_free (config_file);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef HAVE_SIGNAL_H
|
||||
static void
|
||||
signal_handler (int signal_id)
|
||||
{
|
||||
signal (signal_id, 0);
|
||||
midori_app_quit_cb (NULL);
|
||||
if (kill (getpid (), signal_id))
|
||||
exit (1);
|
||||
}
|
||||
#endif
|
||||
|
||||
int
|
||||
main (int argc,
|
||||
char** argv)
|
||||
|
@ -1593,8 +1626,10 @@ main (int argc,
|
|||
{
|
||||
{ "app", 'a', 0, G_OPTION_ARG_STRING, &webapp,
|
||||
N_("Run ADDRESS as a web application"), N_("ADDRESS") },
|
||||
#if !HAVE_HILDON
|
||||
{ "config", 'c', 0, G_OPTION_ARG_FILENAME, &config,
|
||||
N_("Use FOLDER as configuration folder"), N_("FOLDER") },
|
||||
#endif
|
||||
{ "run", 'r', 0, G_OPTION_ARG_NONE, &run,
|
||||
N_("Run the specified filename as javascript"), NULL },
|
||||
#if WEBKIT_CHECK_VERSION (1, 1, 6)
|
||||
|
@ -1627,9 +1662,6 @@ main (int argc,
|
|||
sqlite3* db;
|
||||
gint max_history_age;
|
||||
#endif
|
||||
#if HAVE_HILDON
|
||||
osso_context_t* osso_context;
|
||||
#endif
|
||||
gint clear_prefs = MIDORI_CLEAR_NONE;
|
||||
|
||||
#if ENABLE_NLS
|
||||
|
@ -1650,6 +1682,21 @@ main (int argc,
|
|||
textdomain (GETTEXT_PACKAGE);
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SIGNAL_H
|
||||
#ifdef SIGHUP
|
||||
signal (SIGHUP, &signal_handler);
|
||||
#endif
|
||||
#ifdef SIGINT
|
||||
signal (SIGINT, &signal_handler);
|
||||
#endif
|
||||
#ifdef SIGTERM
|
||||
signal (SIGTERM, &signal_handler);
|
||||
#endif
|
||||
#ifdef SIGQUIT
|
||||
signal (SIGQUIT, &signal_handler);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Parse cli options */
|
||||
webapp = NULL;
|
||||
config = NULL;
|
||||
|
@ -1736,14 +1783,26 @@ main (int argc,
|
|||
NULL);
|
||||
g_object_unref (settings);
|
||||
g_object_set (browser, "settings", settings, NULL);
|
||||
sokoke_set_config_dir ("/");
|
||||
g_signal_connect (browser, "notify::load-status",
|
||||
G_CALLBACK (midori_web_app_browser_notify_load_status_cb), NULL);
|
||||
midori_browser_add_uri (browser, webapp);
|
||||
g_object_set_data (G_OBJECT (browser), "locked", (void*)1);
|
||||
g_signal_connect (browser, "quit",
|
||||
G_CALLBACK (gtk_main_quit), NULL);
|
||||
g_signal_connect (browser, "destroy",
|
||||
G_CALLBACK (gtk_main_quit), NULL);
|
||||
gtk_widget_show (GTK_WIDGET (browser));
|
||||
midori_browser_activate_action (browser, "Location");
|
||||
if (execute)
|
||||
{
|
||||
i = 0;
|
||||
while (uris[i] != NULL)
|
||||
{
|
||||
midori_browser_activate_action (browser, uris[i]);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
gtk_main ();
|
||||
return 0;
|
||||
}
|
||||
|
@ -1752,16 +1811,6 @@ main (int argc,
|
|||
if (run)
|
||||
return midori_run_script (uris ? *uris : NULL);
|
||||
|
||||
#if HAVE_HILDON
|
||||
osso_context = osso_initialize (PACKAGE_NAME, PACKAGE_VERSION, FALSE, NULL);
|
||||
|
||||
if (!osso_context)
|
||||
{
|
||||
g_critical ("Error initializing OSSO D-Bus context - Midori");
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (config && !g_path_is_absolute (config))
|
||||
{
|
||||
g_critical (_("The specified configuration folder is invalid."));
|
||||
|
@ -1819,12 +1868,16 @@ main (int argc,
|
|||
return 1;
|
||||
}
|
||||
|
||||
katze_mkdir_with_parents (sokoke_set_config_dir (NULL), 0700);
|
||||
|
||||
/* Load configuration files */
|
||||
error_messages = g_string_new (NULL);
|
||||
config_file = build_config_filename ("config");
|
||||
error = NULL;
|
||||
settings = settings_new_from_file (config_file, &extensions);
|
||||
katze_assign (config_file, build_config_filename ("accels"));
|
||||
if (!g_file_test (config_file, G_FILE_TEST_EXISTS))
|
||||
katze_assign (config_file, sokoke_find_config_filename (NULL, "accels"));
|
||||
gtk_accel_map_load (config_file);
|
||||
katze_assign (config_file, build_config_filename ("search"));
|
||||
error = NULL;
|
||||
|
@ -1862,7 +1915,7 @@ main (int argc,
|
|||
}
|
||||
bookmarks = katze_array_new (KATZE_TYPE_ARRAY);
|
||||
#if HAVE_LIBXML
|
||||
katze_assign (config_file, build_config_filename ("bookmarks.xbel"));
|
||||
katze_assign (config_file, build_config_filename (BOOKMARK_FILE));
|
||||
error = NULL;
|
||||
if (!midori_array_from_file (bookmarks, config_file, "xbel", &error))
|
||||
{
|
||||
|
@ -1974,7 +2027,9 @@ main (int argc,
|
|||
{
|
||||
item = katze_item_new ();
|
||||
/* Construct an absolute path if the file is relative */
|
||||
if (g_file_test (uri, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR))
|
||||
if (g_path_is_absolute (uri))
|
||||
uri_ready = g_strconcat ("file://", uri, NULL);
|
||||
else if (g_file_test (uri, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR))
|
||||
{
|
||||
gchar* current_dir = g_get_current_dir ();
|
||||
uri_ready = g_strconcat ("file://", current_dir,
|
||||
|
@ -1994,12 +2049,11 @@ main (int argc,
|
|||
}
|
||||
|
||||
katze_assign (config_file, build_config_filename ("config"));
|
||||
if (is_writable (config_file))
|
||||
g_signal_connect_after (settings, "notify",
|
||||
G_CALLBACK (settings_notify_cb), app);
|
||||
|
||||
katze_assign (config_file, build_config_filename ("search"));
|
||||
if (is_writable (config_file))
|
||||
if (1)
|
||||
{
|
||||
g_signal_connect_after (search_engines, "add-item",
|
||||
G_CALLBACK (midori_search_engines_modify_cb), search_engines);
|
||||
|
@ -2013,47 +2067,27 @@ main (int argc,
|
|||
G_CALLBACK (midori_search_engines_modify_cb), search_engines);
|
||||
}
|
||||
}
|
||||
katze_assign (config_file, build_config_filename ("bookmarks.xbel"));
|
||||
if (is_writable (config_file))
|
||||
katze_assign (config_file, build_config_filename (BOOKMARK_FILE));
|
||||
/* Don't save bookmarks if they are not our own */
|
||||
if (!g_path_is_absolute (BOOKMARK_FILE))
|
||||
{
|
||||
midori_bookmarks_connect_item (NULL, (KatzeItem*)bookmarks, bookmarks);
|
||||
g_signal_connect_after (bookmarks, "add-item",
|
||||
G_CALLBACK (midori_bookmarks_add_item_cb), bookmarks);
|
||||
g_signal_connect_after (bookmarks, "remove-item",
|
||||
G_CALLBACK (midori_bookmarks_remove_item_cb), bookmarks);
|
||||
if (!katze_array_is_empty (bookmarks))
|
||||
{
|
||||
i = 0;
|
||||
while ((item = katze_array_get_nth_item (bookmarks, i++)))
|
||||
{
|
||||
if (KATZE_IS_ARRAY (item))
|
||||
{
|
||||
g_signal_connect_after (item, "add-item",
|
||||
G_CALLBACK (midori_bookmarks_add_item_cb), bookmarks);
|
||||
g_signal_connect_after (item, "remove-item",
|
||||
G_CALLBACK (midori_bookmarks_remove_item_cb), bookmarks);
|
||||
}
|
||||
g_signal_connect_after (item, "notify",
|
||||
G_CALLBACK (midori_bookmarks_notify_item_cb), bookmarks);
|
||||
}
|
||||
}
|
||||
}
|
||||
katze_assign (config_file, build_config_filename ("tabtrash.xbel"));
|
||||
if (is_writable (config_file))
|
||||
{
|
||||
g_signal_connect_after (trash, "add-item",
|
||||
G_CALLBACK (midori_trash_add_item_cb), NULL);
|
||||
g_signal_connect_after (trash, "remove-item",
|
||||
G_CALLBACK (midori_trash_remove_item_cb), NULL);
|
||||
}
|
||||
#if HAVE_SQLITE
|
||||
katze_assign (config_file, build_config_filename ("history.db"));
|
||||
if (is_writable (config_file))
|
||||
{
|
||||
g_signal_connect_after (history, "add-item",
|
||||
G_CALLBACK (midori_history_add_item_cb), db);
|
||||
g_signal_connect_after (history, "clear",
|
||||
G_CALLBACK (midori_history_clear_cb), db);
|
||||
}
|
||||
#endif
|
||||
|
||||
katze_item_set_parent (KATZE_ITEM (_session), app);
|
||||
|
@ -2095,10 +2129,6 @@ main (int argc,
|
|||
|
||||
gtk_main ();
|
||||
|
||||
#if HAVE_HILDON
|
||||
osso_deinitialize (osso_context);
|
||||
#endif
|
||||
|
||||
settings = katze_object_get_object (app, "settings");
|
||||
#if HAVE_SQLITE
|
||||
g_object_get (settings, "maximum-history-age", &max_history_age, NULL);
|
||||
|
@ -2128,13 +2158,19 @@ main (int argc,
|
|||
g_free (cache);
|
||||
}
|
||||
midori_remove_config_file (clear_prefs, MIDORI_CLEAR_TRASH, "tabtrash.xbel");
|
||||
if ((clear_prefs & MIDORI_CLEAR_WEB_CACHE) == MIDORI_CLEAR_WEB_CACHE)
|
||||
{
|
||||
gchar* cache = g_build_filename (g_get_user_cache_dir (),
|
||||
PACKAGE_NAME, "web", NULL);
|
||||
sokoke_remove_path (cache, TRUE);
|
||||
g_free (cache);
|
||||
}
|
||||
}
|
||||
|
||||
if (katze_object_get_boolean (settings, "load-on-startup")
|
||||
!= MIDORI_STARTUP_LAST_OPEN_PAGES)
|
||||
{
|
||||
katze_assign (config_file, build_config_filename ("session.xbel"));
|
||||
if (is_writable (config_file))
|
||||
g_unlink (config_file);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
BOOLEAN:OBJECT
|
||||
BOOLEAN:VOID
|
||||
OBJECT:OBJECT
|
||||
VOID:BOOLEAN,STRING
|
||||
VOID:OBJECT,ENUM
|
||||
VOID:STRING,BOOLEAN
|
||||
|
|
|
@ -20,7 +20,16 @@
|
|||
#include <gtk/gtk.h>
|
||||
#include <glib/gi18n.h>
|
||||
|
||||
#if HAVE_UNIQUE
|
||||
#if HAVE_HILDON
|
||||
#include <libosso.h>
|
||||
#ifdef HAVE_HILDON_2_2
|
||||
#include <dbus/dbus.h>
|
||||
#include <mce/mode-names.h>
|
||||
#include <mce/dbus-names.h>
|
||||
#endif
|
||||
typedef osso_context_t* MidoriAppInstance;
|
||||
#define MidoriAppInstanceNull NULL
|
||||
#elif HAVE_UNIQUE
|
||||
typedef gpointer MidoriAppInstance;
|
||||
#define MidoriAppInstanceNull NULL
|
||||
#include <unique/unique.h>
|
||||
|
@ -31,19 +40,9 @@
|
|||
#include "socket.h"
|
||||
#endif
|
||||
|
||||
typedef struct _NotifyNotification NotifyNotification;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
gboolean (*init) (const gchar* app_name);
|
||||
void (*uninit) (void);
|
||||
NotifyNotification* (*notification_new) (const gchar* summary,
|
||||
const gchar* body,
|
||||
const gchar* icon,
|
||||
GtkWidget* attach);
|
||||
gboolean (*notification_show) (NotifyNotification* notification,
|
||||
GError** error);
|
||||
} LibNotifyFuncs;
|
||||
#if HAVE_LIBNOTIFY
|
||||
#include <libnotify/notify.h>
|
||||
#endif
|
||||
|
||||
struct _MidoriApp
|
||||
{
|
||||
|
@ -63,10 +62,9 @@ struct _MidoriApp
|
|||
|
||||
MidoriAppInstance instance;
|
||||
|
||||
/* libnotify handling */
|
||||
#if !HAVE_HILDON
|
||||
gchar* program_notify_send;
|
||||
GModule* libnotify_module;
|
||||
LibNotifyFuncs libnotify_funcs;
|
||||
#endif
|
||||
};
|
||||
|
||||
struct _MidoriAppClass
|
||||
|
@ -115,9 +113,6 @@ static guint signals[LAST_SIGNAL];
|
|||
static void
|
||||
midori_app_finalize (GObject* object);
|
||||
|
||||
static void
|
||||
midori_app_init_libnotify (MidoriApp* app);
|
||||
|
||||
static void
|
||||
midori_app_set_property (GObject* object,
|
||||
guint prop_id,
|
||||
|
@ -140,11 +135,12 @@ midori_browser_focus_in_event_cb (MidoriBrowser* browser,
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
static MidoriBrowser*
|
||||
midori_browser_new_window_cb (MidoriBrowser* browser,
|
||||
MidoriBrowser* new_browser,
|
||||
MidoriApp* app)
|
||||
{
|
||||
if (new_browser)
|
||||
g_object_set (new_browser,
|
||||
"settings", app->settings,
|
||||
"bookmarks", app->bookmarks,
|
||||
|
@ -152,9 +148,13 @@ midori_browser_new_window_cb (MidoriBrowser* browser,
|
|||
"search-engines", app->search_engines,
|
||||
"history", app->history,
|
||||
NULL);
|
||||
else
|
||||
new_browser = midori_app_create_browser (app);
|
||||
|
||||
midori_app_add_browser (app, new_browser);
|
||||
gtk_widget_show (GTK_WIDGET (new_browser));
|
||||
|
||||
return new_browser;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
|
@ -407,6 +407,9 @@ midori_app_command_received (MidoriApp* app,
|
|||
|
||||
if (g_str_equal (command, "activate"))
|
||||
{
|
||||
if (!app->browser)
|
||||
return FALSE;
|
||||
|
||||
gtk_window_set_screen (GTK_WINDOW (app->browser), screen);
|
||||
gtk_window_present (GTK_WINDOW (app->browser));
|
||||
return TRUE;
|
||||
|
@ -424,6 +427,9 @@ midori_app_command_received (MidoriApp* app,
|
|||
}
|
||||
else if (g_str_equal (command, "open"))
|
||||
{
|
||||
if (!app->browser)
|
||||
return FALSE;
|
||||
|
||||
gtk_window_set_screen (GTK_WINDOW (app->browser), screen);
|
||||
gtk_window_present (GTK_WINDOW (app->browser));
|
||||
if (!uris)
|
||||
|
@ -465,16 +471,51 @@ midori_app_command_received (MidoriApp* app,
|
|||
}
|
||||
else if (g_str_equal (command, "command"))
|
||||
{
|
||||
guint i = 0;
|
||||
|
||||
if (!uris || !app->browser)
|
||||
return FALSE;
|
||||
midori_browser_activate_action (app->browser, *uris);
|
||||
while (uris[i] != NULL)
|
||||
{
|
||||
midori_browser_activate_action (app->browser, uris[i]);
|
||||
i++;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
#if HAVE_UNIQUE
|
||||
#if HAVE_HILDON
|
||||
static osso_return_t
|
||||
midori_app_osso_rpc_handler_cb (const gchar* interface,
|
||||
const gchar* method,
|
||||
GArray* arguments,
|
||||
gpointer data,
|
||||
osso_rpc_t * retval)
|
||||
{
|
||||
MidoriApp* app = MIDORI_APP (data);
|
||||
GdkScreen* screen = NULL;
|
||||
gboolean success;
|
||||
|
||||
if (!g_strcmp0 (method, "top_application"))
|
||||
success = midori_app_command_received (app, "activate", NULL, screen);
|
||||
else if (!g_strcmp0 (method, "new"))
|
||||
success = midori_app_command_received (app, "new", NULL, screen);
|
||||
else if (!g_strcmp0 (method, "open"))
|
||||
{
|
||||
/* FIXME: Handle arguments */
|
||||
success = midori_app_command_received (app, "open", NULL, screen);
|
||||
}
|
||||
else if (!g_strcmp0 (method, "command"))
|
||||
{
|
||||
/* FIXME: Handle arguments */
|
||||
success = midori_app_command_received (app, "command", NULL, screen);
|
||||
}
|
||||
|
||||
return success ? OSSO_OK : OSSO_INVALID;
|
||||
}
|
||||
#elif HAVE_UNIQUE
|
||||
static UniqueResponse
|
||||
midori_browser_message_received_cb (UniqueApp* instance,
|
||||
UniqueCommand command,
|
||||
|
@ -577,6 +618,30 @@ midori_app_create_instance (MidoriApp* app,
|
|||
const gchar* name)
|
||||
{
|
||||
MidoriAppInstance instance;
|
||||
|
||||
#if HAVE_HILDON
|
||||
instance = osso_initialize (PACKAGE_NAME, PACKAGE_VERSION, FALSE, NULL);
|
||||
|
||||
if (!instance)
|
||||
{
|
||||
g_critical ("Error initializing OSSO D-Bus context - Midori");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (osso_rpc_set_default_cb_f (instance, midori_app_osso_rpc_handler_cb,
|
||||
app) != OSSO_OK)
|
||||
{
|
||||
g_critical ("Error initializing remote procedure call handler - Midori");
|
||||
osso_deinitialize (instance);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#ifdef HAVE_HILDON_2_2
|
||||
if (OSSO_OK == osso_rpc_run_system (instance, MCE_SERVICE, MCE_REQUEST_PATH,
|
||||
MCE_REQUEST_IF, MCE_ACCELEROMETER_ENABLE_REQ, NULL, DBUS_TYPE_INVALID))
|
||||
/* Accelerometer enabled */;
|
||||
#endif
|
||||
#else
|
||||
GdkDisplay* display;
|
||||
gchar* display_name;
|
||||
gchar* instance_name;
|
||||
|
@ -595,7 +660,8 @@ midori_app_create_instance (MidoriApp* app,
|
|||
display_name = g_strdup (gdk_display_get_name (display));
|
||||
n = strlen (display_name);
|
||||
for (i = 0; i < n; i++)
|
||||
if (display_name[i] == ':' || display_name[i] == '.')
|
||||
if (display_name[i] == ':' || display_name[i] == '.'
|
||||
|| display_name[i] == '\\')
|
||||
display_name[i] = '_';
|
||||
instance_name = g_strdup_printf ("de.twotoasts.%s_%s", name, display_name);
|
||||
|
||||
|
@ -608,14 +674,18 @@ midori_app_create_instance (MidoriApp* app,
|
|||
instance = socket_init (instance_name, sokoke_set_config_dir (NULL), &exists);
|
||||
g_object_set_data (G_OBJECT (app), "sock-exists",
|
||||
exists ? (gpointer)0xdeadbeef : NULL);
|
||||
if (instance != MidoriAppInstanceNull)
|
||||
{
|
||||
channel = g_io_channel_unix_new (instance);
|
||||
g_io_add_watch (channel, G_IO_IN | G_IO_PRI | G_IO_ERR,
|
||||
(GIOFunc)midori_app_io_channel_watch_cb, app);
|
||||
}
|
||||
#endif
|
||||
|
||||
g_free (instance_name);
|
||||
g_free (display_name);
|
||||
|
||||
#endif
|
||||
return instance;
|
||||
}
|
||||
|
||||
|
@ -634,7 +704,11 @@ midori_app_init (MidoriApp* app)
|
|||
|
||||
app->instance = MidoriAppInstanceNull;
|
||||
|
||||
midori_app_init_libnotify (app);
|
||||
#if HAVE_LIBNOTIFY
|
||||
notify_init ("midori");
|
||||
#endif
|
||||
|
||||
app->program_notify_send = g_find_program_in_path ("notify-send");
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -653,17 +727,19 @@ midori_app_finalize (GObject* object)
|
|||
katze_object_assign (app->extensions, NULL);
|
||||
katze_object_assign (app->browsers, NULL);
|
||||
|
||||
#if HAVE_UNIQUE
|
||||
#if HAVE_HILDON
|
||||
osso_deinitialize (app->instance);
|
||||
app->instance = NULL;
|
||||
#elif HAVE_UNIQUE
|
||||
katze_object_assign (app->instance, NULL);
|
||||
#else
|
||||
sock_cleanup ();
|
||||
#endif
|
||||
|
||||
if (app->libnotify_module)
|
||||
{
|
||||
app->libnotify_funcs.uninit ();
|
||||
g_module_close (app->libnotify_module);
|
||||
}
|
||||
#if HAVE_LIBNOTIFY
|
||||
if (notify_is_initted ())
|
||||
notify_uninit ();
|
||||
#endif
|
||||
katze_assign (app->program_notify_send, NULL);
|
||||
|
||||
G_OBJECT_CLASS (midori_app_parent_class)->finalize (object);
|
||||
|
@ -794,7 +870,12 @@ midori_app_instance_is_running (MidoriApp* app)
|
|||
|
||||
if (app->instance == MidoriAppInstanceNull)
|
||||
app->instance = midori_app_create_instance (app, app->name);
|
||||
#if HAVE_UNIQUE
|
||||
|
||||
#if HAVE_HILDON
|
||||
/* FIXME: Determine if application is running already */
|
||||
if (app->instance)
|
||||
return FALSE;
|
||||
#elif HAVE_UNIQUE
|
||||
if (app->instance)
|
||||
return unique_app_is_running (app->instance);
|
||||
#else
|
||||
|
@ -824,7 +905,9 @@ midori_app_instance_send_activate (MidoriApp* app)
|
|||
/* g_return_val_if_fail (MIDORI_IS_APP (app), FALSE); */
|
||||
g_return_val_if_fail (midori_app_instance_is_running (app), FALSE);
|
||||
|
||||
#if HAVE_UNIQUE
|
||||
#if HAVE_HILDON
|
||||
osso_application_top (app->instance, PACKAGE_NAME, NULL);
|
||||
#elif HAVE_UNIQUE
|
||||
if (app->instance)
|
||||
{
|
||||
response = unique_app_send_message (app->instance, UNIQUE_ACTIVATE, NULL);
|
||||
|
@ -860,7 +943,9 @@ midori_app_instance_send_new_browser (MidoriApp* app)
|
|||
/* g_return_val_if_fail (MIDORI_IS_APP (app), FALSE); */
|
||||
g_return_val_if_fail (midori_app_instance_is_running (app), FALSE);
|
||||
|
||||
#if HAVE_UNIQUE
|
||||
#if HAVE_HILDON
|
||||
osso_application_top (app->instance, PACKAGE_NAME, "new");
|
||||
#elif HAVE_UNIQUE
|
||||
if (app->instance)
|
||||
{
|
||||
response = unique_app_send_message (app->instance, UNIQUE_NEW, NULL);
|
||||
|
@ -902,7 +987,9 @@ midori_app_instance_send_uris (MidoriApp* app,
|
|||
g_return_val_if_fail (midori_app_instance_is_running (app), FALSE);
|
||||
g_return_val_if_fail (uris != NULL, FALSE);
|
||||
|
||||
#if HAVE_UNIQUE
|
||||
#if HAVE_HILDON
|
||||
/* FIXME: Implement */
|
||||
#elif HAVE_UNIQUE
|
||||
if (app->instance)
|
||||
{
|
||||
message = unique_message_data_new ();
|
||||
|
@ -952,7 +1039,9 @@ midori_app_send_command (MidoriApp* app,
|
|||
if (!midori_app_instance_is_running (app))
|
||||
return midori_app_command_received (app, "command", command, NULL);
|
||||
|
||||
#if HAVE_UNIQUE
|
||||
#if HAVE_HILDON
|
||||
/* FIXME: Implement */
|
||||
#elif HAVE_UNIQUE
|
||||
if (app->instance)
|
||||
{
|
||||
message = unique_message_data_new ();
|
||||
|
@ -1003,6 +1092,9 @@ midori_app_add_browser (MidoriApp* app,
|
|||
* Creates a #MidoriBrowser which inherits its settings,
|
||||
* bookmarks, trash, search engines and history from @app.
|
||||
*
|
||||
* Note that creating a browser this way can be a lot
|
||||
* faster than setting it up manually.
|
||||
*
|
||||
* Return value: a new #MidoriBrowser
|
||||
*
|
||||
* Since: 0.1.2
|
||||
|
@ -1037,52 +1129,16 @@ midori_app_quit (MidoriApp* app)
|
|||
g_signal_emit (app, signals[QUIT], 0);
|
||||
}
|
||||
|
||||
static void
|
||||
midori_app_init_libnotify (MidoriApp* app)
|
||||
{
|
||||
gint i;
|
||||
const gchar* sonames[] = { "libnotify.so", "libnotify.so.1", NULL };
|
||||
|
||||
for (i = 0; sonames[i] != NULL && app->libnotify_module == NULL; i++ )
|
||||
{
|
||||
app->libnotify_module = g_module_open (sonames[i], G_MODULE_BIND_LOCAL);
|
||||
}
|
||||
|
||||
if (app->libnotify_module != NULL)
|
||||
{
|
||||
g_module_symbol (app->libnotify_module, "notify_init",
|
||||
(void*) &(app->libnotify_funcs.init));
|
||||
g_module_symbol (app->libnotify_module, "notify_uninit",
|
||||
(void*) &(app->libnotify_funcs.uninit));
|
||||
g_module_symbol (app->libnotify_module, "notify_notification_new",
|
||||
(void*) &(app->libnotify_funcs.notification_new));
|
||||
g_module_symbol (app->libnotify_module, "notify_notification_show",
|
||||
(void*) &(app->libnotify_funcs.notification_show));
|
||||
|
||||
/* init libnotify */
|
||||
if (!app->libnotify_funcs.init || !app->libnotify_funcs.init ("midori"))
|
||||
{
|
||||
g_module_close (app->libnotify_module);
|
||||
app->libnotify_module = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
app->program_notify_send = g_find_program_in_path ("notify-send");
|
||||
}
|
||||
|
||||
/**
|
||||
* midori_app_send_notification:
|
||||
* @app: a #MidoriApp
|
||||
* @title: title of the notification
|
||||
* @message: text of the notification, or NULL
|
||||
*
|
||||
* Send #message to the notification daemon to display it.
|
||||
* This is done by using libnotify if available or by using the program
|
||||
* "notify-send" as a fallback.
|
||||
* Send #message to a notification service to display it.
|
||||
*
|
||||
* There is no guarantee that the message have been sent and displayed, as
|
||||
* neither libnotify nor "notify-send" might be available or the
|
||||
* notification daemon might not be running.
|
||||
* There is no guarantee that the message has been sent and displayed, as
|
||||
* there might not be any notification service available.
|
||||
*
|
||||
* Since 0.1.7
|
||||
**/
|
||||
|
@ -1091,19 +1147,26 @@ midori_app_send_notification (MidoriApp* app,
|
|||
const gchar* title,
|
||||
const gchar* message)
|
||||
{
|
||||
gboolean sent = FALSE;
|
||||
|
||||
g_return_if_fail (MIDORI_IS_APP (app));
|
||||
g_return_if_fail (title);
|
||||
|
||||
if (app->libnotify_module)
|
||||
{
|
||||
NotifyNotification* n;
|
||||
#if HAVE_HILDON
|
||||
hildon_banner_show_information_with_markup (GTK_WIDGET (app->browser),
|
||||
"midori", message);
|
||||
#else
|
||||
gboolean sent = FALSE;
|
||||
|
||||
n = app->libnotify_funcs.notification_new (title, message, "midori", NULL);
|
||||
sent = app->libnotify_funcs.notification_show (n, NULL);
|
||||
g_object_unref (n);
|
||||
#if HAVE_LIBNOTIFY
|
||||
if (notify_is_initted ())
|
||||
{
|
||||
NotifyNotification* note;
|
||||
|
||||
note = notify_notification_new (title, message, "midori", NULL);
|
||||
sent = notify_notification_show (note, NULL);
|
||||
g_object_unref (note);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Fall back to the command line program "notify-send" */
|
||||
if (!sent && app->program_notify_send)
|
||||
{
|
||||
|
@ -1118,4 +1181,5 @@ midori_app_send_notification (MidoriApp* app,
|
|||
g_free (msgq);
|
||||
g_free (command);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <glib/gstdio.h>
|
||||
#include <glib/gi18n.h>
|
||||
|
||||
#if HAVE_LIBXML
|
||||
|
@ -22,6 +23,8 @@
|
|||
#include <libxml/tree.h>
|
||||
#endif
|
||||
|
||||
#define katze_str_equal(str1, str2) !strcmp (str1, str2)
|
||||
|
||||
static void
|
||||
katze_xbel_parse_info (KatzeItem* item,
|
||||
xmlNodePtr cur);
|
||||
|
@ -34,29 +37,18 @@ static KatzeItem*
|
|||
katze_item_from_xmlNodePtr (xmlNodePtr cur)
|
||||
{
|
||||
KatzeItem* item;
|
||||
xmlChar* key;
|
||||
|
||||
item = katze_item_new ();
|
||||
key = xmlGetProp (cur, (xmlChar*)"href");
|
||||
katze_item_set_uri (item, (gchar*)key);
|
||||
g_free (key);
|
||||
item->uri = (gchar*)xmlGetProp (cur, (xmlChar*)"href");
|
||||
|
||||
cur = cur->xmlChildrenNode;
|
||||
while (cur)
|
||||
{
|
||||
if (!xmlStrcmp (cur->name, (const xmlChar*)"title"))
|
||||
{
|
||||
key = xmlNodeGetContent (cur);
|
||||
katze_item_set_name (item, g_strstrip ((gchar*)key));
|
||||
g_free (key);
|
||||
}
|
||||
else if (!xmlStrcmp (cur->name, (const xmlChar*)"desc"))
|
||||
{
|
||||
key = xmlNodeGetContent (cur);
|
||||
katze_item_set_text (item, g_strstrip ((gchar*)key));
|
||||
g_free (key);
|
||||
}
|
||||
else if (!xmlStrcmp (cur->name, (const xmlChar*)"info"))
|
||||
if (katze_str_equal ((gchar*)cur->name, "title"))
|
||||
item->name = g_strstrip ((gchar*)xmlNodeGetContent (cur));
|
||||
else if (katze_str_equal ((gchar*)cur->name, "desc"))
|
||||
item->text = g_strstrip ((gchar*)xmlNodeGetContent (cur));
|
||||
else if (katze_str_equal ((gchar*)cur->name, "info"))
|
||||
katze_xbel_parse_info (item, cur);
|
||||
cur = cur->next;
|
||||
}
|
||||
|
@ -88,27 +80,23 @@ katze_array_from_xmlNodePtr (xmlNodePtr cur)
|
|||
cur = cur->xmlChildrenNode;
|
||||
while (cur)
|
||||
{
|
||||
if (!xmlStrcmp (cur->name, (const xmlChar*)"title"))
|
||||
{
|
||||
key = xmlNodeGetContent (cur);
|
||||
katze_item_set_name (KATZE_ITEM (array), g_strstrip ((gchar*)key));
|
||||
}
|
||||
else if (!xmlStrcmp (cur->name, (const xmlChar*)"desc"))
|
||||
{
|
||||
key = xmlNodeGetContent (cur);
|
||||
katze_item_set_text (KATZE_ITEM (array), g_strstrip ((gchar*)key));
|
||||
}
|
||||
else if (!xmlStrcmp (cur->name, (const xmlChar*)"folder"))
|
||||
if (katze_str_equal ((gchar*)cur->name, "title"))
|
||||
((KatzeItem*)array)->name = g_strstrip ((gchar*)xmlNodeGetContent (cur));
|
||||
else if (katze_str_equal ((gchar*)cur->name, "desc"))
|
||||
((KatzeItem*)array)->text = g_strstrip ((gchar*)xmlNodeGetContent (cur));
|
||||
else if (katze_str_equal ((gchar*)cur->name, "info"))
|
||||
katze_xbel_parse_info ((KatzeItem*)array, cur);
|
||||
else if (katze_str_equal ((gchar*)cur->name, "folder"))
|
||||
{
|
||||
item = (KatzeItem*)katze_array_from_xmlNodePtr (cur);
|
||||
katze_array_add_item (array, item);
|
||||
}
|
||||
else if (!xmlStrcmp (cur->name, (const xmlChar*)"bookmark"))
|
||||
else if (katze_str_equal ((gchar*)cur->name, "bookmark"))
|
||||
{
|
||||
item = katze_item_from_xmlNodePtr (cur);
|
||||
katze_array_add_item (array, item);
|
||||
}
|
||||
else if (!xmlStrcmp (cur->name, (const xmlChar*)"separator"))
|
||||
else if (katze_str_equal ((gchar*)cur->name, "separator"))
|
||||
{
|
||||
item = katze_item_new ();
|
||||
katze_array_add_item (array, item);
|
||||
|
@ -125,22 +113,29 @@ katze_xbel_parse_info (KatzeItem* item,
|
|||
cur = cur->xmlChildrenNode;
|
||||
while (cur)
|
||||
{
|
||||
if (!xmlStrcmp (cur->name, (const xmlChar*)"metadata"))
|
||||
if (katze_str_equal ((gchar*)cur->name, "metadata"))
|
||||
{
|
||||
xmlChar* owner = xmlGetProp (cur, (xmlChar*)"owner");
|
||||
if (owner)
|
||||
g_strstrip ((gchar*)owner);
|
||||
else
|
||||
/* Albeit required, "owner" is not set by MicroB */
|
||||
owner = (xmlChar*)NULL;
|
||||
/* FIXME: Save metadata from unknown owners */
|
||||
if (!g_strcmp0 ((gchar*)owner, "http://www.twotoasts.de"))
|
||||
if (!owner || katze_str_equal ((gchar*)owner, "http://www.twotoasts.de"))
|
||||
{
|
||||
xmlAttrPtr properties = cur->properties;
|
||||
xmlNodePtr children = cur->children;
|
||||
while (properties)
|
||||
{
|
||||
if (!xmlStrcmp (properties->name, (xmlChar*)"owner"))
|
||||
xmlChar* value;
|
||||
|
||||
if (katze_str_equal ((gchar*)properties->name, "owner"))
|
||||
{
|
||||
properties = properties->next;
|
||||
continue;
|
||||
}
|
||||
xmlChar* value = xmlGetProp (cur, properties->name);
|
||||
value = xmlGetProp (cur, properties->name);
|
||||
if (properties->ns && properties->ns->prefix)
|
||||
{
|
||||
gchar* ns_value = g_strdup_printf ("%s:%s",
|
||||
|
@ -155,10 +150,30 @@ katze_xbel_parse_info (KatzeItem* item,
|
|||
xmlFree (value);
|
||||
properties = properties->next;
|
||||
}
|
||||
while (children)
|
||||
{
|
||||
xmlNodePtr grand_children = children->children;
|
||||
while (grand_children)
|
||||
{
|
||||
xmlChar* value = grand_children->content;
|
||||
gchar* ns_value;
|
||||
if (!owner)
|
||||
ns_value = g_strdup_printf (":%s", children->name);
|
||||
else if (katze_str_equal ((gchar*)owner, "http://www.twotoasts.de"))
|
||||
ns_value = g_strdup_printf ("midori:%s", children->name);
|
||||
else /* FIXME: Save metadata from unknown owners */
|
||||
ns_value = g_strdup_printf (":%s", children->name);
|
||||
katze_item_set_meta_string (item, ns_value, (gchar*)value);
|
||||
g_free (ns_value);
|
||||
grand_children = grand_children->next;
|
||||
}
|
||||
|
||||
children = children->next;
|
||||
}
|
||||
}
|
||||
xmlFree (owner);
|
||||
}
|
||||
else if (g_strcmp0 ((gchar*)cur->name, "text"))
|
||||
else if (!katze_str_equal ((gchar*)cur->name, "text"))
|
||||
g_critical ("Unexpected element <%s> in <metadata>.", cur->name);
|
||||
cur = cur->next;
|
||||
}
|
||||
|
@ -170,15 +185,24 @@ katze_array_from_xmlDocPtr (KatzeArray* array,
|
|||
xmlDocPtr doc)
|
||||
{
|
||||
xmlNodePtr cur;
|
||||
xmlChar* version;
|
||||
gchar* value;
|
||||
KatzeItem* item;
|
||||
|
||||
cur = xmlDocGetRootElement (doc);
|
||||
version = xmlGetProp (cur, (xmlChar*)"version");
|
||||
if (xmlStrcmp (version, (xmlChar*)"1.0"))
|
||||
|
||||
if ((cur = xmlDocGetRootElement (doc)) == NULL)
|
||||
{
|
||||
/* Empty document */
|
||||
return FALSE;
|
||||
}
|
||||
if (katze_str_equal ((gchar*)cur->name, "xbel"))
|
||||
{
|
||||
/* XBEL 1.0 */
|
||||
gchar* value;
|
||||
|
||||
value = (gchar*)xmlGetProp (cur, (xmlChar*)"version");
|
||||
if (!katze_str_equal (value, "1.0"))
|
||||
g_warning ("XBEL version is not 1.0.");
|
||||
xmlFree (version);
|
||||
g_free (value);
|
||||
|
||||
value = (gchar*)xmlGetProp (cur, (xmlChar*)"title");
|
||||
katze_item_set_name (KATZE_ITEM (array), value);
|
||||
|
@ -187,45 +211,197 @@ katze_array_from_xmlDocPtr (KatzeArray* array,
|
|||
value = (gchar*)xmlGetProp (cur, (xmlChar*)"desc");
|
||||
katze_item_set_text (KATZE_ITEM (array), value);
|
||||
g_free (value);
|
||||
|
||||
if ((cur = xmlDocGetRootElement (doc)) == NULL)
|
||||
{
|
||||
/* Empty document */
|
||||
return FALSE;
|
||||
}
|
||||
if (xmlStrcmp (cur->name, (const xmlChar*)"xbel"))
|
||||
else if (katze_str_equal ((gchar*)cur->name, "RDF"))
|
||||
{
|
||||
/* Wrong document kind */
|
||||
return FALSE;
|
||||
}
|
||||
/* Minimal RSS 1.0 support, enough to read bookmarks */
|
||||
cur = cur->xmlChildrenNode;
|
||||
while (cur)
|
||||
{
|
||||
item = NULL;
|
||||
if (!xmlStrcmp (cur->name, (const xmlChar*)"folder"))
|
||||
item = (KatzeItem*)katze_array_from_xmlNodePtr (cur);
|
||||
else if (!xmlStrcmp (cur->name, (const xmlChar*)"bookmark"))
|
||||
item = katze_item_from_xmlNodePtr (cur);
|
||||
else if (!xmlStrcmp (cur->name, (const xmlChar*)"separator"))
|
||||
if (katze_str_equal ((gchar*)cur->name, "item"))
|
||||
{
|
||||
xmlNodePtr cur_item;
|
||||
|
||||
item = katze_item_new ();
|
||||
else if (!xmlStrcmp (cur->name, (const xmlChar*)"info"))
|
||||
katze_xbel_parse_info (KATZE_ITEM (array), cur);
|
||||
|
||||
cur_item = cur->xmlChildrenNode;
|
||||
while (cur_item)
|
||||
{
|
||||
if (katze_str_equal ((gchar*)cur_item->name, "title"))
|
||||
item->name = g_strstrip ((gchar*)xmlNodeGetContent (cur_item));
|
||||
else if (katze_str_equal ((gchar*)cur_item->name, "link"))
|
||||
item->uri = g_strstrip ((gchar*)xmlNodeGetContent (cur_item));
|
||||
else if (katze_str_equal ((gchar*)cur_item->name, "subject"))
|
||||
{
|
||||
gchar* value = g_strstrip ((gchar*)xmlNodeGetContent (cur_item));
|
||||
/* FIXME: Create a folder according to the tag */
|
||||
g_free (value);
|
||||
}
|
||||
cur_item = cur_item->next;
|
||||
}
|
||||
}
|
||||
else if (katze_str_equal ((gchar*)cur->name, "channel"))
|
||||
/* Ignored */;
|
||||
else if (!katze_str_equal ((gchar*)cur->name, "text"))
|
||||
g_warning ("Unexpected attribute: %s", (gchar*)cur->name);
|
||||
if (item)
|
||||
katze_array_add_item (array, item);
|
||||
cur = cur->next;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Wrong document kind */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
cur = cur->xmlChildrenNode;
|
||||
while (cur)
|
||||
{
|
||||
item = NULL;
|
||||
if (katze_str_equal ((gchar*)cur->name, "folder"))
|
||||
item = (KatzeItem*)katze_array_from_xmlNodePtr (cur);
|
||||
else if (katze_str_equal ((gchar*)cur->name, "bookmark"))
|
||||
item = katze_item_from_xmlNodePtr (cur);
|
||||
else if (katze_str_equal ((gchar*)cur->name, "separator"))
|
||||
item = katze_item_new ();
|
||||
else if (katze_str_equal ((gchar*)cur->name, "info"))
|
||||
katze_xbel_parse_info (KATZE_ITEM (array), cur);
|
||||
else if (katze_str_equal ((gchar*)cur->name, "title"))
|
||||
{
|
||||
xmlNodePtr node = cur->xmlChildrenNode;
|
||||
katze_item_set_name (KATZE_ITEM (array), (gchar*)node->content);
|
||||
}
|
||||
else if (katze_str_equal ((gchar*)cur->name, "desc"))
|
||||
{
|
||||
xmlNodePtr node = cur->xmlChildrenNode;
|
||||
katze_item_set_text (KATZE_ITEM (array), (gchar*)node->content);
|
||||
}
|
||||
else if (!katze_str_equal ((gchar*)cur->name, "text"))
|
||||
g_warning ("Unexpected attribute: %s", (gchar*)cur->name);
|
||||
if (item)
|
||||
katze_array_add_item (array, item);
|
||||
cur = cur->next;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
katze_array_from_opera_file (KatzeArray* array,
|
||||
FILE* file)
|
||||
{
|
||||
gchar line[200];
|
||||
gchar* partial_line = NULL;
|
||||
KatzeArray* folder = array;
|
||||
KatzeItem* item = NULL;
|
||||
|
||||
while (fgets (line, 200, file))
|
||||
{
|
||||
gboolean incomplete_line = (strlen (line) == 199);
|
||||
g_strstrip (line);
|
||||
if (line[0] == '\0')
|
||||
{
|
||||
item = NULL;
|
||||
continue;
|
||||
}
|
||||
else if (line[0] == '-')
|
||||
{
|
||||
item = NULL;
|
||||
if (folder != array)
|
||||
folder = katze_item_get_parent ((KatzeItem*)folder);
|
||||
else
|
||||
g_warning ("A level-up although we are at the top level");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (line[0] == '#')
|
||||
{
|
||||
const gchar* element = &line[1];
|
||||
if (!g_ascii_strncasecmp (element, "FOLDER", 6))
|
||||
{
|
||||
item = (KatzeItem*)katze_array_new (KATZE_TYPE_ARRAY);
|
||||
katze_array_add_item (folder, item);
|
||||
folder = (KatzeArray*)item;
|
||||
}
|
||||
else if (!g_ascii_strncasecmp (element, "URL", 3))
|
||||
{
|
||||
item = katze_item_new ();
|
||||
katze_array_add_item (folder, item);
|
||||
}
|
||||
else
|
||||
g_warning ("Unexpected element: %s", element);
|
||||
}
|
||||
else if (item)
|
||||
{
|
||||
gchar** parts;
|
||||
|
||||
/* Handle lines longer than 200 characters */
|
||||
if (incomplete_line)
|
||||
{
|
||||
if (partial_line)
|
||||
{
|
||||
gchar* chunk = g_strconcat (partial_line, line, NULL);
|
||||
katze_assign (partial_line, chunk);
|
||||
}
|
||||
else
|
||||
partial_line = g_strdup (line);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (partial_line)
|
||||
{
|
||||
gchar* full_line = g_strconcat (partial_line, line, NULL);
|
||||
katze_assign (partial_line, NULL);
|
||||
parts = g_strsplit (full_line, "=", 2);
|
||||
g_free (full_line);
|
||||
}
|
||||
else
|
||||
parts = g_strsplit (line, "=", 2);
|
||||
|
||||
if (parts && parts[0] && parts[1])
|
||||
{
|
||||
if (katze_str_equal (parts[0], "NAME"))
|
||||
item->name = g_strdup (parts[1]);
|
||||
else if (katze_str_equal (parts[0], "URL"))
|
||||
item->uri = g_strdup (parts[1]);
|
||||
else if (katze_str_equal (parts[0], "DESCRIPTION"))
|
||||
item->text = g_strdup (parts[1]);
|
||||
else if (katze_str_equal (parts[0], "CREATED"))
|
||||
item->added = g_ascii_strtoull (parts[1], NULL, 10);
|
||||
/* FIXME: Implement visited time
|
||||
else if (katze_str_equal (parts[0], "VISITED"))
|
||||
item->visited = g_ascii_strtoull (parts[1], NULL, 10); */
|
||||
else if (katze_str_equal (parts[0], "ON PERSONALBAR"))
|
||||
katze_item_set_meta_integer (item, "toolbar",
|
||||
katze_str_equal (parts[1], "YES") ? 1 : -1);
|
||||
/* FIXME: Implement websites as panels
|
||||
else if (katze_str_equal (parts[0], "IN PANEL"))
|
||||
; */
|
||||
}
|
||||
else
|
||||
g_warning ("Broken property: %s", line);
|
||||
g_strfreev (parts);
|
||||
}
|
||||
else
|
||||
g_warning ("Unexpected property outside of element: %s", line);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* midori_array_from_file:
|
||||
* @array: a #KatzeArray
|
||||
* @filename: a filename to load from
|
||||
* @format: the desired format
|
||||
* @format: "xbel", "opera", or %NULL
|
||||
* @error: a #GError or %NULL
|
||||
*
|
||||
* Loads the contents of a file in the specified format.
|
||||
*
|
||||
* Since 0.2.2 @format can be %NULL to indicate that the
|
||||
* file should be loaded if it's any supported format.
|
||||
*
|
||||
* Return value: %TRUE on success, %FALSE otherwise
|
||||
*
|
||||
* Since: 0.1.6
|
||||
|
@ -236,11 +412,8 @@ midori_array_from_file (KatzeArray* array,
|
|||
const gchar* format,
|
||||
GError** error)
|
||||
{
|
||||
xmlDocPtr doc;
|
||||
|
||||
g_return_val_if_fail (katze_array_is_a (array, KATZE_TYPE_ITEM), FALSE);
|
||||
g_return_val_if_fail (filename != NULL, FALSE);
|
||||
g_return_val_if_fail (!g_strcmp0 (format, "xbel"), FALSE);
|
||||
g_return_val_if_fail (!error || !*error, FALSE);
|
||||
|
||||
if (!g_file_test (filename, G_FILE_TEST_EXISTS))
|
||||
|
@ -252,6 +425,54 @@ midori_array_from_file (KatzeArray* array,
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
if (!format)
|
||||
format = "";
|
||||
|
||||
/* Opera6 */
|
||||
if (katze_str_equal (format, "opera")
|
||||
|| (!*format && g_str_has_suffix (filename, ".adr")))
|
||||
{
|
||||
FILE* file;
|
||||
if ((file = g_fopen (filename, "r")))
|
||||
{
|
||||
guint verify;
|
||||
gchar line[50];
|
||||
|
||||
verify = 0;
|
||||
while (fgets (line, 50, file))
|
||||
{
|
||||
g_strstrip (line);
|
||||
if (verify == 0 && katze_str_equal (line, "Opera Hotlist version 2.0"))
|
||||
verify++;
|
||||
else if (verify == 1
|
||||
&& katze_str_equal (line, "Options: encoding = utf8, version=3"))
|
||||
verify++;
|
||||
else if (verify == 2)
|
||||
{
|
||||
if (!katze_array_from_opera_file (array, file))
|
||||
{
|
||||
/* Parsing failed */
|
||||
fclose (file);
|
||||
if (error)
|
||||
*error = g_error_new_literal (G_FILE_ERROR,
|
||||
G_FILE_ERROR_FAILED, _("Malformed document."));
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
fclose (file);
|
||||
}
|
||||
}
|
||||
|
||||
/* XBEL */
|
||||
if (katze_str_equal (format, "xbel")
|
||||
|| !*format)
|
||||
{
|
||||
xmlDocPtr doc;
|
||||
|
||||
if ((doc = xmlParseFile (filename)) == NULL)
|
||||
{
|
||||
/* No valid xml or broken encoding */
|
||||
|
@ -272,77 +493,123 @@ midori_array_from_file (KatzeArray* array,
|
|||
}
|
||||
xmlFreeDoc (doc);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (error)
|
||||
*error = g_error_new_literal (G_FILE_ERROR, G_FILE_ERROR_FAILED,
|
||||
_("Unrecognized bookmark format."));
|
||||
return FALSE;
|
||||
}
|
||||
#endif
|
||||
|
||||
static gchar*
|
||||
_simple_xml_element (const gchar* name,
|
||||
const gchar* value)
|
||||
/* Inspired by append_escaped_text() from gmarkup.c in Glib.
|
||||
The main difference is that we filter out control characters. */
|
||||
static void
|
||||
string_append_escaped (GString *str,
|
||||
const gchar *text)
|
||||
{
|
||||
gchar* value_escaped;
|
||||
gchar* markup;
|
||||
gssize length;
|
||||
const gchar* p;
|
||||
const gchar* end;
|
||||
gunichar c;
|
||||
|
||||
if (!value)
|
||||
return g_strdup ("");
|
||||
value_escaped = g_markup_escape_text (value, -1);
|
||||
markup = g_strdup_printf ("<%s>%s</%s>\n", name, value_escaped, name);
|
||||
g_free (value_escaped);
|
||||
return markup;
|
||||
length = strlen (text);
|
||||
p = text;
|
||||
end = text + length;
|
||||
|
||||
while (p != end)
|
||||
{
|
||||
const gchar *next;
|
||||
next = g_utf8_next_char (p);
|
||||
|
||||
switch (*p)
|
||||
{
|
||||
case '&':
|
||||
g_string_append (str, "&");
|
||||
break;
|
||||
case '<':
|
||||
g_string_append (str, "<");
|
||||
break;
|
||||
case '>':
|
||||
g_string_append (str, ">");
|
||||
break;
|
||||
case '\'':
|
||||
g_string_append (str, "'");
|
||||
break;
|
||||
case '"':
|
||||
g_string_append (str, """);
|
||||
break;
|
||||
default:
|
||||
c = g_utf8_get_char (p);
|
||||
if (g_unichar_iscntrl (c))
|
||||
g_string_append_c (str, ' ');
|
||||
else if ((0x1 <= c && c <= 0x8)
|
||||
|| (0xb <= c && c <= 0xc)
|
||||
|| (0xe <= c && c <= 0x1f)
|
||||
|| (0x7f <= c && c <= 0x84)
|
||||
|| (0x86 <= c && c <= 0x9f))
|
||||
g_string_append_printf (str, "&#x%x;", c);
|
||||
else
|
||||
g_string_append_len (str, p, next - p);
|
||||
break;
|
||||
}
|
||||
|
||||
p = next;
|
||||
}
|
||||
}
|
||||
|
||||
static gchar*
|
||||
katze_item_to_data (KatzeItem* item)
|
||||
static void
|
||||
string_append_xml_element (GString* string,
|
||||
const gchar* name,
|
||||
const gchar* value)
|
||||
{
|
||||
if (value)
|
||||
{
|
||||
g_string_append_printf (string, "<%s>", name);
|
||||
string_append_escaped (string, value);
|
||||
g_string_append_printf (string, "</%s>\n", name);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
string_append_item (GString* string,
|
||||
KatzeItem* item)
|
||||
{
|
||||
gchar* markup;
|
||||
gchar* metadata;
|
||||
|
||||
g_return_val_if_fail (KATZE_IS_ITEM (item), NULL);
|
||||
g_return_if_fail (KATZE_IS_ITEM (item));
|
||||
|
||||
markup = NULL;
|
||||
metadata = katze_item_metadata_to_xbel (item);
|
||||
if (KATZE_IS_ARRAY (item))
|
||||
{
|
||||
GString* _markup = g_string_new (NULL);
|
||||
guint i = 0;
|
||||
KatzeItem* _item;
|
||||
while ((_item = katze_array_get_nth_item (KATZE_ARRAY (item), i++)))
|
||||
{
|
||||
gchar* item_markup = katze_item_to_data (_item);
|
||||
g_string_append (_markup, item_markup);
|
||||
g_free (item_markup);
|
||||
}
|
||||
/* gchar* folded = item->folded ? NULL : g_strdup_printf (" folded=\"no\""); */
|
||||
gchar* title = _simple_xml_element ("title", katze_item_get_name (item));
|
||||
gchar* desc = _simple_xml_element ("desc", katze_item_get_text (item));
|
||||
markup = g_strdup_printf ("<folder%s>\n%s%s%s%s</folder>\n",
|
||||
"" /* folded ? folded : "" */,
|
||||
title, desc,
|
||||
_markup->str,
|
||||
metadata);
|
||||
g_string_free (_markup, TRUE);
|
||||
/* g_free (folded); */
|
||||
g_free (title);
|
||||
g_free (desc);
|
||||
KatzeArray* array = KATZE_ARRAY (item);
|
||||
|
||||
g_string_append (string, "<folder>\n");
|
||||
/* FIXME: " folded=\"no\" */
|
||||
string_append_xml_element (string, "title", katze_item_get_name (item));
|
||||
string_append_xml_element (string, "desc", katze_item_get_text (item));
|
||||
while ((_item = katze_array_get_nth_item (array, i++)))
|
||||
string_append_item (string, _item);
|
||||
g_string_append (string, metadata);
|
||||
g_string_append (string, "</folder>\n");
|
||||
}
|
||||
else if (katze_item_get_uri (item))
|
||||
{
|
||||
gchar* href_escaped = g_markup_escape_text (katze_item_get_uri (item), -1);
|
||||
gchar* href = g_strdup_printf (" href=\"%s\"", href_escaped);
|
||||
g_free (href_escaped);
|
||||
gchar* title = _simple_xml_element ("title", katze_item_get_name (item));
|
||||
gchar* desc = _simple_xml_element ("desc", katze_item_get_text (item));
|
||||
markup = g_strdup_printf ("<bookmark%s>\n%s%s%s</bookmark>\n",
|
||||
href,
|
||||
title, desc,
|
||||
metadata);
|
||||
g_free (href);
|
||||
g_free (title);
|
||||
g_free (desc);
|
||||
g_string_append (string, "<bookmark href=\"");
|
||||
string_append_escaped (string, katze_item_get_uri (item));
|
||||
g_string_append (string, "\">\n");
|
||||
string_append_xml_element (string, "title", katze_item_get_name (item));
|
||||
string_append_xml_element (string, "desc", katze_item_get_text (item));
|
||||
g_string_append (string, metadata);
|
||||
g_string_append (string, "</bookmark>\n");
|
||||
}
|
||||
else
|
||||
markup = g_strdup ("<separator/>\n");
|
||||
g_string_append (string, "<separator/>\n");
|
||||
g_free (metadata);
|
||||
return markup;
|
||||
}
|
||||
|
||||
static gchar*
|
||||
|
@ -350,28 +617,55 @@ katze_item_metadata_to_xbel (KatzeItem* item)
|
|||
{
|
||||
GList* keys = katze_item_get_meta_keys (item);
|
||||
GString* markup;
|
||||
/* FIXME: Allow specifying an alternative namespace/ URI */
|
||||
const gchar* namespace_uri = "http://www.twotoasts.de";
|
||||
const gchar* namespace = "midori";
|
||||
GString* markdown;
|
||||
/* FIXME: Allow specifying an alternative default namespace */
|
||||
/* FIXME: Support foreign namespaces with their own URI */
|
||||
gchar* namespace = NULL;
|
||||
const gchar* namespace_uri;
|
||||
gsize i;
|
||||
const gchar* key;
|
||||
const gchar* value;
|
||||
|
||||
if (!keys)
|
||||
return g_strdup ("");
|
||||
|
||||
markup = g_string_new ("<info>\n<metadata owner=\"");
|
||||
g_string_append_printf (markup, "%s\"", namespace_uri);
|
||||
markup = g_string_new ("<info>\n<metadata");
|
||||
markdown = g_string_new (NULL);
|
||||
i = 0;
|
||||
while ((key = g_list_nth_data (keys, i++)))
|
||||
if (katze_item_get_meta_string (item, key))
|
||||
if ((value = katze_item_get_meta_string (item, key)))
|
||||
{
|
||||
gchar* escaped =
|
||||
g_markup_escape_text (katze_item_get_meta_string (item, key), -1);
|
||||
g_string_append_printf (markup, " %s:%s=\"%s\"", namespace, key,
|
||||
escaped);
|
||||
g_free (escaped);
|
||||
namespace = strchr (key, ':');
|
||||
if (key[0] == ':') /* MicroB uses un-namespaced children */
|
||||
{
|
||||
key = &key[1];
|
||||
g_string_append_printf (markdown, "<%s>", key);
|
||||
string_append_escaped (markdown, value);
|
||||
g_string_append_printf (markdown, "</%s>\n", key);
|
||||
}
|
||||
else if (namespace)
|
||||
{
|
||||
g_string_append_printf (markup, " %s=\"", key);
|
||||
string_append_escaped (markup, value);
|
||||
g_string_append_c (markup, '\"');
|
||||
}
|
||||
else
|
||||
{
|
||||
g_string_append_printf (markup, " midori:%s=\"", key);
|
||||
string_append_escaped (markup, value);
|
||||
g_string_append_c (markup, '\"');
|
||||
}
|
||||
}
|
||||
if (!namespace)
|
||||
{
|
||||
namespace_uri = "http://www.twotoasts.de";
|
||||
g_string_append_printf (markup, " owner=\"%s\"", namespace_uri);
|
||||
}
|
||||
if (markdown->len)
|
||||
g_string_append_printf (markup, ">\n%s</metadata>\n</info>\n", markdown->str);
|
||||
else
|
||||
g_string_append_printf (markup, "/>\n</info>\n");
|
||||
g_string_free (markdown, TRUE);
|
||||
return g_string_free (markup, FALSE);
|
||||
}
|
||||
|
||||
|
@ -379,46 +673,29 @@ static gchar*
|
|||
katze_array_to_xbel (KatzeArray* array,
|
||||
GError** error)
|
||||
{
|
||||
GString* inner_markup;
|
||||
gchar* metadata = katze_item_metadata_to_xbel (KATZE_ITEM (array));
|
||||
guint i;
|
||||
KatzeItem* item;
|
||||
gchar* item_xml;
|
||||
const gchar* namespacing;
|
||||
gchar* title;
|
||||
gchar* desc;
|
||||
gchar* metadata;
|
||||
gchar* outer_markup;
|
||||
|
||||
inner_markup = g_string_new (NULL);
|
||||
i = 0;
|
||||
while ((item = katze_array_get_nth_item (array, i++)))
|
||||
{
|
||||
item_xml = katze_item_to_data (item);
|
||||
g_string_append (inner_markup, item_xml);
|
||||
g_free (item_xml);
|
||||
}
|
||||
|
||||
namespacing = " xmlns:midori=\"http://www.twotoasts.de\"";
|
||||
title = _simple_xml_element ("title", katze_item_get_name (KATZE_ITEM (array)));
|
||||
desc = _simple_xml_element ("desc", katze_item_get_text (KATZE_ITEM (array)));
|
||||
metadata = katze_item_metadata_to_xbel (KATZE_ITEM (array));
|
||||
outer_markup = g_strdup_printf (
|
||||
"%s%s<xbel version=\"1.0\"%s>\n%s%s%s%s</xbel>\n",
|
||||
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n",
|
||||
GString* markup = g_string_new (
|
||||
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
|
||||
"<!DOCTYPE xbel PUBLIC \"+//IDN python.org//DTD "
|
||||
"XML Bookmark Exchange Language 1.0//EN//XML\" "
|
||||
"\"http://www.python.org/topics/xml/dtds/xbel-1.0.dtd\">\n",
|
||||
namespacing,
|
||||
title,
|
||||
desc,
|
||||
metadata,
|
||||
inner_markup->str);
|
||||
g_string_free (inner_markup, TRUE);
|
||||
g_free (title);
|
||||
g_free (desc);
|
||||
"\"http://www.python.org/topics/xml/dtds/xbel-1.0.dtd\">\n"
|
||||
"<xbel version=\"1.0\""
|
||||
" xmlns:midori=\"http://www.twotoasts.de\""
|
||||
">\n");
|
||||
string_append_xml_element (markup, "title", katze_item_get_name (KATZE_ITEM (array)));
|
||||
string_append_xml_element (markup, "desc", katze_item_get_text (KATZE_ITEM (array)));
|
||||
g_string_append (markup, metadata);
|
||||
i = 0;
|
||||
while ((item = katze_array_get_nth_item (array, i++)))
|
||||
string_append_item (markup, item);
|
||||
g_string_append (markup, "</xbel>\n");
|
||||
|
||||
g_free (metadata);
|
||||
|
||||
return outer_markup;
|
||||
return g_string_free (markup, FALSE);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -658,7 +658,7 @@ midori_extension_set_boolean (MidoriExtension* extension,
|
|||
/* FIXME: Handle readonly folder/ file */
|
||||
gchar* config_file = g_build_filename (extension->priv->config_dir,
|
||||
"config", NULL);
|
||||
g_mkdir_with_parents (extension->priv->config_dir, 0700);
|
||||
katze_mkdir_with_parents (extension->priv->config_dir, 0700);
|
||||
g_key_file_set_boolean (extension->priv->key_file,
|
||||
"settings", name, value);
|
||||
sokoke_key_file_save_to_file (extension->priv->key_file, config_file, &error);
|
||||
|
@ -755,7 +755,7 @@ midori_extension_set_integer (MidoriExtension* extension,
|
|||
/* FIXME: Handle readonly folder/ file */
|
||||
gchar* config_file = g_build_filename (extension->priv->config_dir,
|
||||
"config", NULL);
|
||||
g_mkdir_with_parents (extension->priv->config_dir, 0700);
|
||||
katze_mkdir_with_parents (extension->priv->config_dir, 0700);
|
||||
g_key_file_set_integer (extension->priv->key_file,
|
||||
"settings", name, value);
|
||||
sokoke_key_file_save_to_file (extension->priv->key_file, config_file, &error);
|
||||
|
@ -852,7 +852,7 @@ midori_extension_set_string (MidoriExtension* extension,
|
|||
/* FIXME: Handle readonly folder/ file */
|
||||
gchar* config_file = g_build_filename (extension->priv->config_dir,
|
||||
"config", NULL);
|
||||
g_mkdir_with_parents (extension->priv->config_dir, 0700);
|
||||
katze_mkdir_with_parents (extension->priv->config_dir, 0700);
|
||||
g_key_file_set_string (extension->priv->key_file,
|
||||
"settings", name, value);
|
||||
sokoke_key_file_save_to_file (extension->priv->key_file, config_file, &error);
|
||||
|
@ -964,7 +964,7 @@ midori_extension_set_string_list (MidoriExtension* extension,
|
|||
/* FIXME: Handle readonly folder/ file */
|
||||
gchar* config_file = g_build_filename (extension->priv->config_dir,
|
||||
"config", NULL);
|
||||
g_mkdir_with_parents (extension->priv->config_dir, 0700);
|
||||
katze_mkdir_with_parents (extension->priv->config_dir, 0700);
|
||||
g_key_file_set_string_list (extension->priv->key_file,
|
||||
"settings", name, (const gchar**)value, length);
|
||||
sokoke_key_file_save_to_file (extension->priv->key_file, config_file, &error);
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include "gtkiconentry.h"
|
||||
#include "marshal.h"
|
||||
#include "sokoke.h"
|
||||
#include "midori-browser.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <glib/gi18n.h>
|
||||
|
@ -421,13 +422,8 @@ midori_location_action_insert_history_item (MidoriLocationAction* action,
|
|||
else
|
||||
{
|
||||
uri = katze_item_get_uri (item);
|
||||
pixbuf = katze_net_load_icon (action->net, katze_item_get_uri (item),
|
||||
NULL, NULL, NULL);
|
||||
if (!pixbuf)
|
||||
pixbuf = action->default_icon;
|
||||
midori_location_action_add_item (action, uri,
|
||||
pixbuf, katze_item_get_name (item));
|
||||
g_object_unref (pixbuf);
|
||||
g_signal_connect (katze_item_get_parent (item), "remove-item",
|
||||
G_CALLBACK (midori_location_action_history_remove_item_cb), action);
|
||||
}
|
||||
|
@ -576,7 +572,7 @@ midori_location_action_key_press_event_cb (GtkEntry* entry,
|
|||
if ((uri = gtk_entry_get_text (entry)) && *uri)
|
||||
{
|
||||
g_signal_emit (action, signals[SUBMIT_URI], 0, uri,
|
||||
(event->state & GDK_MOD1_MASK) ? TRUE : FALSE);
|
||||
(event->state & GDK_CONTROL_MASK) ? TRUE : FALSE);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
@ -630,6 +626,7 @@ midori_location_entry_render_text_cb (GtkCellLayout* layout,
|
|||
{
|
||||
gchar* uri;
|
||||
gchar* title;
|
||||
GdkPixbuf* icon;
|
||||
gchar* desc;
|
||||
gchar* desc_uri;
|
||||
gchar* desc_title;
|
||||
|
@ -641,19 +638,39 @@ midori_location_entry_render_text_cb (GtkCellLayout* layout,
|
|||
gchar** parts;
|
||||
size_t len;
|
||||
|
||||
gtk_tree_model_get (model, iter, URI_COL, &uri, TITLE_COL, &title, -1);
|
||||
entry = data;
|
||||
|
||||
gtk_tree_model_get (model, iter, URI_COL, &uri, TITLE_COL, &title,
|
||||
FAVICON_COL, &icon, -1);
|
||||
|
||||
if (G_UNLIKELY (!icon) && uri)
|
||||
{
|
||||
#if !HAVE_HILDON
|
||||
MidoriLocationAction* action
|
||||
= g_object_get_data (G_OBJECT (renderer), "location-action");
|
||||
if ((icon = katze_load_cached_icon (uri, NULL)))
|
||||
{
|
||||
midori_location_action_set_icon_for_uri (action, icon, uri);
|
||||
g_object_unref (icon);
|
||||
}
|
||||
else
|
||||
midori_location_action_set_icon_for_uri (action, action->default_icon, uri);
|
||||
#endif
|
||||
}
|
||||
else if (icon)
|
||||
g_object_unref (icon);
|
||||
|
||||
desc = desc_uri = desc_title = key = NULL;
|
||||
if (G_LIKELY (data))
|
||||
{
|
||||
entry = gtk_entry_completion_get_entry (GTK_ENTRY_COMPLETION (data));
|
||||
key = title ? g_utf8_strdown (gtk_entry_get_text (GTK_ENTRY (entry)), -1)
|
||||
: g_ascii_strdown (gtk_entry_get_text (GTK_ENTRY (entry)), -1);
|
||||
len = 0;
|
||||
}
|
||||
if (G_LIKELY (data && uri))
|
||||
|
||||
/* g_uri_unescape_segment () sometimes produces garbage */
|
||||
if (G_UNLIKELY (uri && !g_utf8_validate (uri, -1, (const gchar **)&temp)))
|
||||
temp[0]='\0';
|
||||
else if (G_LIKELY (uri))
|
||||
{
|
||||
temp = g_ascii_strdown (uri, -1);
|
||||
temp = g_utf8_strdown (uri, -1);
|
||||
if (key && *key && (start = strstr (temp, key)))
|
||||
{
|
||||
len = strlen (key);
|
||||
|
@ -662,19 +679,21 @@ midori_location_entry_render_text_cb (GtkCellLayout* layout,
|
|||
if (skey && *skey && (parts = g_strsplit (uri, skey, 2)))
|
||||
{
|
||||
if (parts[0] && parts[1])
|
||||
{
|
||||
desc_uri = g_markup_printf_escaped ("%s<b>%s</b>%s",
|
||||
parts[0], skey, parts[1]);
|
||||
g_strfreev (parts);
|
||||
}
|
||||
}
|
||||
g_free (skey);
|
||||
}
|
||||
g_free (temp);
|
||||
}
|
||||
if (uri && !desc_uri)
|
||||
desc_uri = g_markup_escape_text (uri, -1);
|
||||
if (G_LIKELY (data && title))
|
||||
|
||||
/* g_uri_unescape_segment () sometimes produces garbage */
|
||||
if (G_UNLIKELY (title && !g_utf8_validate (title, -1, (const gchar **)&temp)))
|
||||
temp[0]='\0';
|
||||
else if (G_LIKELY (title))
|
||||
{
|
||||
temp = g_utf8_strdown (title, -1);
|
||||
if (key && *key && (start = strstr (temp, key)))
|
||||
|
@ -724,7 +743,6 @@ midori_location_entry_completion_match_cb (GtkEntryCompletion* completion,
|
|||
gchar* uri;
|
||||
gchar* title;
|
||||
gboolean match;
|
||||
gchar* temp;
|
||||
|
||||
model = gtk_entry_completion_get_model (completion);
|
||||
gtk_tree_model_get (model, iter, URI_COL, &uri, TITLE_COL, &title, -1);
|
||||
|
@ -732,17 +750,20 @@ midori_location_entry_completion_match_cb (GtkEntryCompletion* completion,
|
|||
match = FALSE;
|
||||
if (G_LIKELY (uri))
|
||||
{
|
||||
temp = g_utf8_casefold (uri, -1);
|
||||
match = (strstr (temp, key) != NULL);
|
||||
g_free (temp);
|
||||
gchar* fkey = g_utf8_casefold (key, -1);
|
||||
gchar* furi = g_utf8_casefold (uri, -1);
|
||||
g_free (uri);
|
||||
match = strstr (furi, fkey) != NULL;
|
||||
g_free (furi);
|
||||
|
||||
if (!match && G_LIKELY (title))
|
||||
{
|
||||
temp = g_utf8_casefold (title, -1);
|
||||
match = (strstr (temp, key) != NULL);
|
||||
g_free (temp);
|
||||
gchar* ftitle = g_utf8_casefold (title, -1);
|
||||
match = strstr (ftitle, fkey) != NULL;
|
||||
g_free (ftitle);
|
||||
}
|
||||
|
||||
g_free (fkey);
|
||||
}
|
||||
|
||||
g_free (title);
|
||||
|
@ -880,7 +901,7 @@ midori_location_action_set_item (MidoriLocationAction* location_action,
|
|||
g_object_unref (original_icon);
|
||||
}
|
||||
else
|
||||
new_icon = location_action->default_icon;
|
||||
new_icon = NULL;
|
||||
if (new_icon)
|
||||
gtk_list_store_set (GTK_LIST_STORE (model), &iter,
|
||||
FAVICON_COL, new_icon, -1);
|
||||
|
@ -998,13 +1019,14 @@ midori_location_action_completion_init (MidoriLocationAction* location_action,
|
|||
gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (completion), renderer,
|
||||
"pixbuf", FAVICON_COL, "yalign", YALIGN_COL, NULL);
|
||||
renderer = gtk_cell_renderer_text_new ();
|
||||
g_object_set_data (G_OBJECT (renderer), "location-action", location_action);
|
||||
gtk_cell_renderer_set_fixed_size (renderer, 1, -1);
|
||||
gtk_cell_renderer_text_set_fixed_height_from_font (
|
||||
GTK_CELL_RENDERER_TEXT (renderer), 2);
|
||||
gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (completion), renderer, TRUE);
|
||||
gtk_cell_layout_set_cell_data_func (GTK_CELL_LAYOUT (completion), renderer,
|
||||
midori_location_entry_render_text_cb,
|
||||
completion, NULL);
|
||||
entry, NULL);
|
||||
gtk_entry_completion_set_match_func (completion,
|
||||
midori_location_entry_completion_match_cb, NULL, NULL);
|
||||
|
||||
|
@ -1052,11 +1074,27 @@ midori_location_action_entry_changed_cb (GtkComboBox* combo_box,
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
midori_location_action_populate_popup_cb (GtkWidget* entry,
|
||||
GtkMenuShell* menu,
|
||||
MidoriLocationAction* location_action)
|
||||
{
|
||||
MidoriBrowser* browser = midori_browser_get_for_widget (entry);
|
||||
GtkActionGroup* actions = midori_browser_get_action_group (browser);
|
||||
GtkWidget* menuitem;
|
||||
|
||||
menuitem = gtk_separator_menu_item_new ();
|
||||
gtk_widget_show (menuitem);
|
||||
gtk_menu_shell_append (menu, menuitem);
|
||||
menuitem = sokoke_action_create_popup_menu_item (
|
||||
gtk_action_group_get_action (actions, "ManageSearchEngines"));
|
||||
gtk_menu_shell_append (menu, menuitem);
|
||||
}
|
||||
|
||||
static void
|
||||
midori_location_action_connect_proxy (GtkAction* action,
|
||||
GtkWidget* proxy)
|
||||
{
|
||||
GtkWidget* entry;
|
||||
MidoriLocationAction* location_action;
|
||||
GtkCellRenderer* renderer;
|
||||
|
||||
|
@ -1070,7 +1108,8 @@ midori_location_action_connect_proxy (GtkAction* action,
|
|||
|
||||
if (GTK_IS_TOOL_ITEM (proxy))
|
||||
{
|
||||
entry = midori_location_action_entry_for_proxy (proxy);
|
||||
GtkWidget* entry = midori_location_action_entry_for_proxy (proxy);
|
||||
GtkWidget* child = gtk_bin_get_child (GTK_BIN (entry));
|
||||
|
||||
midori_location_entry_set_progress (MIDORI_LOCATION_ENTRY (entry),
|
||||
MIDORI_LOCATION_ACTION (action)->progress);
|
||||
|
@ -1086,17 +1125,17 @@ midori_location_action_connect_proxy (GtkAction* action,
|
|||
gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (entry), renderer,
|
||||
"pixbuf", FAVICON_COL, "yalign", YALIGN_COL, NULL);
|
||||
renderer = gtk_cell_renderer_text_new ();
|
||||
g_object_set_data (G_OBJECT (renderer), "location-action", action);
|
||||
gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (entry), renderer, TRUE);
|
||||
gtk_cell_layout_set_cell_data_func (GTK_CELL_LAYOUT (entry),
|
||||
renderer, midori_location_entry_render_text_cb, NULL, NULL);
|
||||
renderer, midori_location_entry_render_text_cb, child, NULL);
|
||||
|
||||
gtk_combo_box_set_active (GTK_COMBO_BOX (entry), -1);
|
||||
midori_location_action_completion_init (location_action,
|
||||
GTK_ENTRY (gtk_bin_get_child (GTK_BIN (entry))));
|
||||
midori_location_action_completion_init (location_action, GTK_ENTRY (child));
|
||||
g_signal_connect (entry, "changed",
|
||||
G_CALLBACK (midori_location_action_entry_changed_cb), action);
|
||||
|
||||
g_object_connect (gtk_bin_get_child (GTK_BIN (entry)),
|
||||
g_object_connect (child,
|
||||
"signal::changed",
|
||||
midori_location_action_changed_cb, action,
|
||||
"signal::key-press-event",
|
||||
|
@ -1107,6 +1146,8 @@ midori_location_action_connect_proxy (GtkAction* action,
|
|||
midori_location_action_focus_out_event_cb, action,
|
||||
"signal::icon-release",
|
||||
midori_location_action_icon_released_cb, action,
|
||||
"signal::populate-popup",
|
||||
midori_location_action_populate_popup_cb, action,
|
||||
NULL);
|
||||
}
|
||||
}
|
||||
|
@ -1246,11 +1287,11 @@ void
|
|||
midori_location_action_set_icon (MidoriLocationAction* location_action,
|
||||
GdkPixbuf* icon)
|
||||
{
|
||||
#if !HAVE_HILDON
|
||||
GSList* proxies;
|
||||
GtkWidget* location_entry;
|
||||
GtkWidget* entry;
|
||||
|
||||
#if !HAVE_HILDON
|
||||
g_return_if_fail (MIDORI_IS_LOCATION_ACTION (location_action));
|
||||
g_return_if_fail (!icon || GDK_IS_PIXBUF (icon));
|
||||
|
||||
|
@ -1293,9 +1334,11 @@ midori_location_action_add_item (MidoriLocationAction* location_action,
|
|||
GdkPixbuf* icon,
|
||||
const gchar* title)
|
||||
{
|
||||
#if !HAVE_HILDON
|
||||
GSList* proxies;
|
||||
GtkWidget* location_entry;
|
||||
GtkWidget* entry;
|
||||
#endif
|
||||
|
||||
g_return_if_fail (MIDORI_IS_LOCATION_ACTION (location_action));
|
||||
g_return_if_fail (uri != NULL);
|
||||
|
@ -1328,9 +1371,11 @@ midori_location_action_set_icon_for_uri (MidoriLocationAction* location_action,
|
|||
GdkPixbuf* icon,
|
||||
const gchar* uri)
|
||||
{
|
||||
#if !HAVE_HILDON
|
||||
GSList* proxies;
|
||||
GtkWidget* location_entry;
|
||||
GtkWidget* entry;
|
||||
#endif
|
||||
|
||||
g_return_if_fail (MIDORI_IS_LOCATION_ACTION (location_action));
|
||||
g_return_if_fail (!icon || GDK_IS_PIXBUF (icon));
|
||||
|
@ -1407,6 +1452,7 @@ midori_location_action_set_search_engines (MidoriLocationAction* location_action
|
|||
if (location_action->search_engines)
|
||||
while ((item = katze_array_get_nth_item (location_action->search_engines, i++)))
|
||||
gtk_entry_completion_delete_action (completion, 0);
|
||||
|
||||
midori_location_action_add_actions (completion, search_engines);
|
||||
}
|
||||
|
||||
|
@ -1449,9 +1495,11 @@ void
|
|||
midori_location_action_set_secondary_icon (MidoriLocationAction* location_action,
|
||||
const gchar* stock_id)
|
||||
{
|
||||
#if !HAVE_HILDON
|
||||
GSList* proxies;
|
||||
GtkWidget* entry;
|
||||
GtkWidget* child;
|
||||
#endif
|
||||
GtkStockItem stock_item;
|
||||
|
||||
g_return_if_fail (MIDORI_IS_LOCATION_ACTION (location_action));
|
||||
|
|
|
@ -369,6 +369,9 @@ static void
|
|||
midori_location_entry_init (MidoriLocationEntry* location_entry)
|
||||
{
|
||||
GtkWidget* entry;
|
||||
#if HAVE_HILDON
|
||||
HildonGtkInputMode mode;
|
||||
#endif
|
||||
|
||||
/* We want the widget to have appears-as-list applied */
|
||||
gtk_rc_parse_string ("style \"midori-location-entry-style\" {\n"
|
||||
|
@ -378,8 +381,13 @@ midori_location_entry_init (MidoriLocationEntry* location_entry)
|
|||
|
||||
location_entry->progress = 0.0;
|
||||
|
||||
#if HAVE_HILDON
|
||||
entry = gtk_entry_new ();
|
||||
mode = hildon_gtk_entry_get_input_mode (GTK_ENTRY (entry));
|
||||
mode &= ~HILDON_GTK_INPUT_MODE_AUTOCAP;
|
||||
hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry), mode);
|
||||
#else
|
||||
entry = gtk_icon_entry_new ();
|
||||
#if !HAVE_HILDON
|
||||
gtk_icon_entry_set_icon_from_stock (GTK_ICON_ENTRY (entry),
|
||||
GTK_ICON_ENTRY_PRIMARY, GTK_STOCK_FILE);
|
||||
gtk_icon_entry_set_icon_highlight (GTK_ICON_ENTRY (entry),
|
||||
|
|
|
@ -19,6 +19,12 @@
|
|||
|
||||
#include <glib/gi18n.h>
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#ifdef HAVE_HILDON_2_2
|
||||
#include <hildon/hildon.h>
|
||||
#endif
|
||||
|
||||
struct _MidoriPanel
|
||||
{
|
||||
GtkHBox parent_instance;
|
||||
|
@ -31,11 +37,13 @@ struct _MidoriPanel
|
|||
GtkWidget* frame;
|
||||
GtkWidget* toolbook;
|
||||
GtkWidget* notebook;
|
||||
GtkActionGroup* action_group;
|
||||
GtkMenu* menu;
|
||||
|
||||
gboolean show_titles;
|
||||
gboolean show_controls;
|
||||
gboolean right_aligned;
|
||||
gboolean open_panels_in_windows;
|
||||
};
|
||||
|
||||
struct _MidoriPanelClass
|
||||
|
@ -54,11 +62,13 @@ enum
|
|||
PROP_0,
|
||||
|
||||
PROP_SHADOW_TYPE,
|
||||
PROP_ACTION_GROUP,
|
||||
PROP_MENU,
|
||||
PROP_PAGE,
|
||||
PROP_SHOW_TITLES,
|
||||
PROP_SHOW_CONTROLS,
|
||||
PROP_RIGHT_ALIGNED,
|
||||
PROP_OPEN_PANELS_IN_WINDOWS,
|
||||
};
|
||||
|
||||
enum {
|
||||
|
@ -138,6 +148,23 @@ midori_panel_class_init (MidoriPanelClass* class)
|
|||
GTK_SHADOW_NONE,
|
||||
flags));
|
||||
|
||||
/**
|
||||
* MidoriWebSettings:action-group:
|
||||
*
|
||||
* This is the action group the panel will add actions
|
||||
* corresponding to pages to.
|
||||
*
|
||||
* Since: 0.2.1
|
||||
*/
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_ACTION_GROUP,
|
||||
g_param_spec_object (
|
||||
"action-group",
|
||||
"Action Group",
|
||||
"The action group the panel will add actions to",
|
||||
GTK_TYPE_ACTION_GROUP,
|
||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||
|
||||
/**
|
||||
* MidoriWebSettings:menu:
|
||||
*
|
||||
|
@ -212,6 +239,22 @@ midori_panel_class_init (MidoriPanelClass* class)
|
|||
"Whether the panel is aligned to the right",
|
||||
FALSE,
|
||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||
|
||||
/**
|
||||
* MidoriWebSettings:open-panels-in-windows:
|
||||
*
|
||||
* Whether to open panels in separate windows.
|
||||
*
|
||||
* Since: 0.2.2
|
||||
*/
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_OPEN_PANELS_IN_WINDOWS,
|
||||
g_param_spec_boolean (
|
||||
"open-panels-in-windows",
|
||||
"Open panels in windows",
|
||||
"Whether to open panels in standalone windows by default",
|
||||
FALSE,
|
||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -241,6 +284,7 @@ midori_panel_detached_window_delete_event_cb (GtkWidget* window,
|
|||
GtkWidget* scrolled = g_object_get_data (G_OBJECT (window), "scrolled");
|
||||
GtkWidget* toolbar = g_object_get_data (G_OBJECT (scrolled), "panel-toolbar");
|
||||
GtkWidget* menuitem = g_object_get_data (G_OBJECT (scrolled), "panel-menuitem");
|
||||
GtkWidget* viewable = _midori_panel_child_for_scrolled (panel, scrolled);
|
||||
GtkToolItem* toolitem;
|
||||
gint n;
|
||||
|
||||
|
@ -252,15 +296,10 @@ midori_panel_detached_window_delete_event_cb (GtkWidget* window,
|
|||
gtk_container_remove (GTK_CONTAINER (vbox), scrolled);
|
||||
n = gtk_notebook_append_page (GTK_NOTEBOOK (panel->notebook), scrolled, NULL);
|
||||
g_object_unref (scrolled);
|
||||
toolitem = midori_panel_construct_tool_item (panel,
|
||||
MIDORI_VIEWABLE (_midori_panel_child_for_scrolled (panel, scrolled)));
|
||||
toolitem = midori_panel_construct_tool_item (panel, MIDORI_VIEWABLE (viewable));
|
||||
if (menuitem)
|
||||
{
|
||||
gtk_widget_show (menuitem);
|
||||
g_object_set_data (G_OBJECT (menuitem), "toolitem", toolitem);
|
||||
}
|
||||
midori_panel_set_current_page (panel, n);
|
||||
gtk_toggle_tool_button_set_active (GTK_TOGGLE_TOOL_BUTTON (toolitem), TRUE);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
@ -274,13 +313,9 @@ midori_panel_widget_destroy_cb (GtkWidget* viewable,
|
|||
}
|
||||
|
||||
static void
|
||||
midori_panel_button_detach_clicked_cb (GtkWidget* toolbutton,
|
||||
MidoriPanel* panel)
|
||||
midori_panel_detach_page (MidoriPanel* panel,
|
||||
gint n)
|
||||
{
|
||||
/* FIXME: What happens when the browser is destroyed? */
|
||||
/* FIXME: What about multiple browsers? */
|
||||
/* FIXME: Should we remember if the child was detached? */
|
||||
gint n = midori_panel_get_current_page (panel);
|
||||
GtkToolItem* toolitem = gtk_toolbar_get_nth_item (
|
||||
GTK_TOOLBAR (panel->toolbar), n);
|
||||
const gchar* title = gtk_tool_button_get_label (GTK_TOOL_BUTTON (toolitem));
|
||||
|
@ -288,26 +323,32 @@ midori_panel_button_detach_clicked_cb (GtkWidget* toolbutton,
|
|||
GTK_NOTEBOOK (panel->toolbook), n);
|
||||
GtkWidget* scrolled = gtk_notebook_get_nth_page (
|
||||
GTK_NOTEBOOK (panel->notebook), n);
|
||||
GtkWidget* menuitem = g_object_get_data (G_OBJECT (scrolled), "panel-menuitem");
|
||||
GtkWidget* window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
|
||||
GtkWidget* vbox = gtk_vbox_new (FALSE, 0);
|
||||
g_object_set_data (G_OBJECT (window), "scrolled", scrolled);
|
||||
gtk_window_set_title (GTK_WINDOW (window), title);
|
||||
#if HAVE_HILDON
|
||||
GtkWidget* window = hildon_window_new ();
|
||||
hildon_program_add_window (hildon_program_get_instance (), HILDON_WINDOW (window));
|
||||
#else
|
||||
GtkWidget* window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
|
||||
gtk_window_set_skip_taskbar_hint (GTK_WINDOW (window), TRUE);
|
||||
gtk_window_set_default_size (GTK_WINDOW (window), 250, 400);
|
||||
gtk_window_set_transient_for (GTK_WINDOW (window),
|
||||
GTK_WINDOW (gtk_widget_get_toplevel (panel->notebook)));
|
||||
#endif
|
||||
gtk_widget_show (vbox);
|
||||
gtk_container_add (GTK_CONTAINER (window), vbox);
|
||||
if (menuitem)
|
||||
gtk_widget_hide (menuitem);
|
||||
g_object_set_data (G_OBJECT (window), "scrolled", scrolled);
|
||||
gtk_window_set_title (GTK_WINDOW (window), title);
|
||||
g_signal_handlers_disconnect_by_func (
|
||||
_midori_panel_child_for_scrolled (panel, scrolled),
|
||||
midori_panel_widget_destroy_cb, toolitem);
|
||||
gtk_container_remove (GTK_CONTAINER (panel->toolbar), GTK_WIDGET (toolitem));
|
||||
g_object_ref (toolbar);
|
||||
gtk_container_remove (GTK_CONTAINER (panel->toolbook), toolbar);
|
||||
#if HAVE_HILDON
|
||||
hildon_window_add_toolbar (HILDON_WINDOW (window), GTK_TOOLBAR (toolbar));
|
||||
#else
|
||||
gtk_box_pack_start (GTK_BOX (vbox), toolbar, FALSE, FALSE, 0);
|
||||
#endif
|
||||
g_object_unref (toolbar);
|
||||
g_object_set_data (G_OBJECT (scrolled), "panel-toolbar", toolbar);
|
||||
g_object_ref (scrolled);
|
||||
|
@ -317,14 +358,24 @@ midori_panel_button_detach_clicked_cb (GtkWidget* toolbutton,
|
|||
midori_panel_set_current_page (panel, n > 0 ? n - 1 : 0);
|
||||
toolitem = gtk_toolbar_get_nth_item (GTK_TOOLBAR (panel->toolbar),
|
||||
n > 0 ? n - 1 : 0);
|
||||
gtk_toggle_tool_button_set_active (GTK_TOGGLE_TOOL_BUTTON (toolitem), TRUE);
|
||||
if (!gtk_notebook_get_n_pages (GTK_NOTEBOOK (panel->notebook)))
|
||||
gtk_widget_set_sensitive (toolbutton, FALSE);
|
||||
gtk_widget_set_sensitive (GTK_WIDGET (panel->button_detach), FALSE);
|
||||
g_signal_connect (window, "delete-event",
|
||||
G_CALLBACK (midori_panel_detached_window_delete_event_cb), panel);
|
||||
gtk_widget_show (window);
|
||||
}
|
||||
|
||||
static void
|
||||
midori_panel_button_detach_clicked_cb (GtkWidget* toolbutton,
|
||||
MidoriPanel* panel)
|
||||
{
|
||||
/* FIXME: What happens when the browser is destroyed? */
|
||||
/* FIXME: What about multiple browsers? */
|
||||
/* FIXME: Should we remember if the child was detached? */
|
||||
gint n = midori_panel_get_current_page (panel);
|
||||
midori_panel_detach_page (panel, n);
|
||||
}
|
||||
|
||||
static void
|
||||
midori_panel_button_align_clicked_cb (GtkWidget* toolitem,
|
||||
MidoriPanel* panel)
|
||||
|
@ -347,6 +398,7 @@ midori_panel_init (MidoriPanel* panel)
|
|||
GtkWidget* labelbar;
|
||||
GtkToolItem* toolitem;
|
||||
|
||||
panel->action_group = NULL;
|
||||
panel->show_titles = TRUE;
|
||||
panel->show_controls = TRUE;
|
||||
panel->right_aligned = FALSE;
|
||||
|
@ -370,6 +422,7 @@ midori_panel_init (MidoriPanel* panel)
|
|||
toolitem = gtk_tool_item_new ();
|
||||
gtk_tool_item_set_expand (toolitem, TRUE);
|
||||
panel->toolbar_label = gtk_label_new (NULL);
|
||||
gtk_label_set_ellipsize (GTK_LABEL (panel->toolbar_label), PANGO_ELLIPSIZE_END);
|
||||
gtk_misc_set_alignment (GTK_MISC (panel->toolbar_label), 0, 0.5);
|
||||
gtk_container_add (GTK_CONTAINER (toolitem), panel->toolbar_label);
|
||||
gtk_container_set_border_width (GTK_CONTAINER (toolitem), 6);
|
||||
|
@ -454,6 +507,9 @@ midori_panel_set_property (GObject* object,
|
|||
gtk_frame_set_shadow_type (GTK_FRAME (panel->frame),
|
||||
g_value_get_enum (value));
|
||||
break;
|
||||
case PROP_ACTION_GROUP:
|
||||
katze_object_assign (panel->action_group, g_value_dup_object (value));
|
||||
break;
|
||||
case PROP_MENU:
|
||||
katze_object_assign (panel->menu, g_value_dup_object (value));
|
||||
break;
|
||||
|
@ -462,9 +518,6 @@ midori_panel_set_property (GObject* object,
|
|||
break;
|
||||
case PROP_SHOW_TITLES:
|
||||
panel->show_titles = g_value_get_boolean (value);
|
||||
#if HAVE_HILDON
|
||||
panel->show_titles = TRUE;
|
||||
#endif
|
||||
gtk_toolbar_set_style (GTK_TOOLBAR (panel->toolbar),
|
||||
panel->show_titles ? GTK_TOOLBAR_BOTH : GTK_TOOLBAR_ICONS);
|
||||
break;
|
||||
|
@ -476,6 +529,9 @@ midori_panel_set_property (GObject* object,
|
|||
case PROP_RIGHT_ALIGNED:
|
||||
midori_panel_set_right_aligned (panel, g_value_get_boolean (value));
|
||||
break;
|
||||
case PROP_OPEN_PANELS_IN_WINDOWS:
|
||||
panel->open_panels_in_windows = g_value_get_boolean (value);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
|
@ -496,6 +552,9 @@ midori_panel_get_property (GObject* object,
|
|||
g_value_set_enum (value,
|
||||
gtk_frame_get_shadow_type (GTK_FRAME (panel->frame)));
|
||||
break;
|
||||
case PROP_ACTION_GROUP:
|
||||
g_value_set_object (value, panel->action_group);
|
||||
break;
|
||||
case PROP_MENU:
|
||||
g_value_set_object (value, panel->menu);
|
||||
break;
|
||||
|
@ -511,6 +570,9 @@ midori_panel_get_property (GObject* object,
|
|||
case PROP_RIGHT_ALIGNED:
|
||||
g_value_set_boolean (value, panel->right_aligned);
|
||||
break;
|
||||
case PROP_OPEN_PANELS_IN_WINDOWS:
|
||||
g_value_set_boolean (value, panel->open_panels_in_windows);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
|
@ -581,50 +643,20 @@ midori_panel_set_right_aligned (MidoriPanel* panel,
|
|||
g_object_notify (G_OBJECT (panel), "right-aligned");
|
||||
}
|
||||
|
||||
static void
|
||||
midori_panel_menu_item_activate_cb (GtkWidget* widget,
|
||||
MidoriPanel* panel)
|
||||
{
|
||||
GtkWidget* child;
|
||||
GtkToolItem* toolitem;
|
||||
guint n;
|
||||
|
||||
child = g_object_get_data (G_OBJECT (widget), "page");
|
||||
n = midori_panel_page_num (panel, child);
|
||||
toolitem = gtk_toolbar_get_nth_item (GTK_TOOLBAR (panel->toolbar), n);
|
||||
|
||||
if (toolitem)
|
||||
{
|
||||
/* Unsetting the button before setting it ensures that
|
||||
it will emit signals even if it was active before */
|
||||
GtkToggleToolButton* button = GTK_TOGGLE_TOOL_BUTTON (toolitem);
|
||||
g_signal_handlers_block_by_func (widget,
|
||||
midori_panel_menu_item_activate_cb, panel);
|
||||
gtk_toggle_tool_button_set_active (button, FALSE);
|
||||
gtk_toggle_tool_button_set_active (button, TRUE);
|
||||
g_signal_handlers_unblock_by_func (widget,
|
||||
midori_panel_menu_item_activate_cb, panel);
|
||||
}
|
||||
|
||||
midori_panel_set_current_page (panel, n);
|
||||
g_signal_emit (panel, signals[SWITCH_PAGE], 0, n);
|
||||
gtk_widget_show (GTK_WIDGET (panel));
|
||||
}
|
||||
|
||||
/* Private function, used by MidoriBrowser */
|
||||
/* static */ GtkWidget*
|
||||
midori_panel_construct_menu_item (MidoriPanel* panel,
|
||||
MidoriViewable* viewable)
|
||||
{
|
||||
const gchar* stock_id;
|
||||
GtkAction* action;
|
||||
GtkWidget* menuitem;
|
||||
|
||||
stock_id = midori_viewable_get_stock_id (viewable);
|
||||
menuitem = gtk_image_menu_item_new_from_stock (stock_id, NULL);
|
||||
gtk_widget_show (menuitem);
|
||||
action = g_object_get_data (G_OBJECT (viewable), "midori-panel-action");
|
||||
menuitem = gtk_action_create_menu_item (action);
|
||||
g_object_set_data (G_OBJECT (menuitem), "page", viewable);
|
||||
g_signal_connect (menuitem, "activate",
|
||||
G_CALLBACK (midori_panel_menu_item_activate_cb), panel);
|
||||
|
||||
if (GTK_WIDGET_VISIBLE (viewable))
|
||||
gtk_widget_show (menuitem);
|
||||
return menuitem;
|
||||
}
|
||||
|
||||
|
@ -644,35 +676,23 @@ static GtkToolItem*
|
|||
midori_panel_construct_tool_item (MidoriPanel* panel,
|
||||
MidoriViewable* viewable)
|
||||
{
|
||||
const gchar* label = midori_viewable_get_label (viewable);
|
||||
const gchar* stock_id = midori_viewable_get_stock_id (viewable);
|
||||
GtkToolItem* toolitem;
|
||||
GtkWidget* image;
|
||||
GtkAction* action;
|
||||
GtkWidget* toolitem;
|
||||
|
||||
toolitem = gtk_radio_tool_button_new_from_stock (NULL, stock_id);
|
||||
g_object_set (toolitem, "group",
|
||||
gtk_toolbar_get_nth_item (GTK_TOOLBAR (panel->toolbar), 0), NULL);
|
||||
image = gtk_image_new_from_stock (stock_id, GTK_ICON_SIZE_BUTTON);
|
||||
gtk_tool_button_set_icon_widget (GTK_TOOL_BUTTON (toolitem), image);
|
||||
if (label)
|
||||
{
|
||||
gtk_tool_button_set_label (GTK_TOOL_BUTTON (toolitem), label);
|
||||
gtk_widget_set_tooltip_text (GTK_WIDGET (toolitem), label);
|
||||
}
|
||||
action = g_object_get_data (G_OBJECT (viewable), "midori-panel-action");
|
||||
toolitem = gtk_action_create_tool_item (action);
|
||||
g_object_set_data (G_OBJECT (toolitem), "page", viewable);
|
||||
g_signal_connect (toolitem, "clicked",
|
||||
G_CALLBACK (midori_panel_menu_item_activate_cb), panel);
|
||||
gtk_widget_show_all (GTK_WIDGET (toolitem));
|
||||
gtk_toolbar_insert (GTK_TOOLBAR (panel->toolbar), toolitem, -1);
|
||||
gtk_toolbar_insert (GTK_TOOLBAR (panel->toolbar), GTK_TOOL_ITEM (toolitem), -1);
|
||||
g_signal_connect (viewable, "destroy",
|
||||
G_CALLBACK (midori_panel_widget_destroy_cb), toolitem);
|
||||
|
||||
if (gtk_notebook_get_n_pages (GTK_NOTEBOOK (panel->notebook)))
|
||||
gtk_widget_set_sensitive (GTK_WIDGET (panel->button_detach), TRUE);
|
||||
|
||||
return toolitem;
|
||||
return GTK_TOOL_ITEM (toolitem);
|
||||
}
|
||||
|
||||
#if !HAVE_HILDON
|
||||
static void
|
||||
midori_panel_show_titles_toggled_cb (GtkWidget* menuitem,
|
||||
MidoriPanel* panel)
|
||||
|
@ -699,7 +719,6 @@ midori_panel_options_clicked_cb (GtkToolItem* toolitem,
|
|||
n = midori_panel_get_current_page (panel);
|
||||
viewable = midori_panel_get_nth_page (panel, n);
|
||||
menu = gtk_menu_new ();
|
||||
#if !HAVE_HILDON
|
||||
menuitem = gtk_check_menu_item_new_with_mnemonic (_("Show panel _titles"));
|
||||
gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (menuitem),
|
||||
panel->show_titles);
|
||||
|
@ -707,7 +726,6 @@ midori_panel_options_clicked_cb (GtkToolItem* toolitem,
|
|||
G_CALLBACK (midori_panel_show_titles_toggled_cb), panel);
|
||||
gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
|
||||
gtk_widget_show (menuitem);
|
||||
#endif
|
||||
menuitem = gtk_check_menu_item_new_with_mnemonic (_("Show operating _controls"));
|
||||
gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (menuitem),
|
||||
panel->show_controls);
|
||||
|
@ -718,7 +736,35 @@ midori_panel_options_clicked_cb (GtkToolItem* toolitem,
|
|||
g_signal_emit_by_name (viewable, "populate-option-menu", menu);
|
||||
|
||||
katze_widget_popup (GTK_WIDGET (toolitem), GTK_MENU (menu),
|
||||
NULL, SOKOKE_MENU_POSITION_LEFT);
|
||||
NULL, KATZE_MENU_POSITION_LEFT);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
midori_panel_action_activate_cb (GtkRadioAction* action,
|
||||
MidoriPanel* panel)
|
||||
{
|
||||
GtkWidget* viewable = g_object_get_data (G_OBJECT (action), "viewable");
|
||||
gint n = midori_panel_page_num (panel, viewable);
|
||||
|
||||
/* If the panel is detached, focus the window */
|
||||
if (n == -1)
|
||||
{
|
||||
GtkWidget* toplevel = gtk_widget_get_toplevel (viewable);
|
||||
gtk_window_present (GTK_WINDOW (toplevel));
|
||||
return;
|
||||
}
|
||||
|
||||
if (panel->open_panels_in_windows
|
||||
&& gtk_radio_action_get_current_value (action)
|
||||
== katze_object_get_int (action, "value"))
|
||||
midori_panel_detach_page (panel, n);
|
||||
else
|
||||
{
|
||||
midori_panel_set_current_page (panel, n);
|
||||
g_signal_emit (panel, signals[SWITCH_PAGE], 0, n);
|
||||
gtk_widget_show (GTK_WIDGET (panel));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -735,6 +781,10 @@ midori_panel_options_clicked_cb (GtkToolItem* toolitem,
|
|||
* Since 0.1.3 destroying the @viewable implicitly removes
|
||||
* the page including the menu and eventual toolbar.
|
||||
*
|
||||
* Since 0.2.1 a hidden @viewable will not be shown in the panel.
|
||||
*
|
||||
* Since 0.2.1 an action with an accelerator is created implicitly.
|
||||
*
|
||||
* In the case of an error, -1 is returned.
|
||||
*
|
||||
* Return value: the index of the new page, or -1
|
||||
|
@ -748,8 +798,9 @@ midori_panel_append_page (MidoriPanel* panel,
|
|||
GtkWidget* widget;
|
||||
GtkWidget* toolbar;
|
||||
GtkToolItem* toolitem;
|
||||
const gchar* label;
|
||||
guint n;
|
||||
gchar* action_name;
|
||||
GtkAction* action;
|
||||
|
||||
g_return_val_if_fail (MIDORI_IS_PANEL (panel), -1);
|
||||
g_return_val_if_fail (MIDORI_IS_VIEWABLE (viewable), -1);
|
||||
|
@ -778,25 +829,57 @@ midori_panel_append_page (MidoriPanel* panel,
|
|||
gtk_container_add (GTK_CONTAINER (panel->notebook), scrolled);
|
||||
|
||||
toolbar = midori_viewable_get_toolbar (viewable);
|
||||
#if !HAVE_HILDON
|
||||
toolitem = gtk_tool_button_new_from_stock (GTK_STOCK_PROPERTIES);
|
||||
gtk_tool_item_set_tooltip_text (toolitem, _("Options"));
|
||||
g_signal_connect (toolitem, "clicked",
|
||||
G_CALLBACK (midori_panel_options_clicked_cb), panel);
|
||||
gtk_toolbar_insert (GTK_TOOLBAR (toolbar), toolitem, 0);
|
||||
gtk_widget_show (GTK_WIDGET (toolitem));
|
||||
#endif
|
||||
gtk_widget_show (toolbar);
|
||||
gtk_container_add (GTK_CONTAINER (panel->toolbook), toolbar);
|
||||
g_signal_connect (viewable, "destroy",
|
||||
G_CALLBACK (midori_panel_widget_destroy_cb), toolbar);
|
||||
|
||||
n = midori_panel_page_num (panel, scrolled);
|
||||
label = midori_viewable_get_label (viewable);
|
||||
n = midori_panel_get_n_pages (panel) - 1;
|
||||
/* FIXME: Use something better than the stock ID */
|
||||
action_name = g_strconcat ("PanelPage",
|
||||
midori_viewable_get_stock_id (viewable), NULL);
|
||||
action = (GtkAction*)gtk_radio_action_new (action_name,
|
||||
midori_viewable_get_label (viewable),
|
||||
NULL, midori_viewable_get_stock_id (viewable), n);
|
||||
g_object_set_data (G_OBJECT (action), "viewable", viewable);
|
||||
g_signal_connect (action, "activate",
|
||||
G_CALLBACK (midori_panel_action_activate_cb), panel);
|
||||
if (panel->action_group)
|
||||
{
|
||||
/* FIXME: For some reason the accelerator only works if a menuitem
|
||||
is created, but not before that. */
|
||||
GtkWidget* toplevel = gtk_widget_get_toplevel (GTK_WIDGET (panel));
|
||||
GSList* groups = gtk_accel_groups_from_object (G_OBJECT (toplevel));
|
||||
gtk_action_set_accel_group (action, g_slist_nth_data (groups, 0));
|
||||
gtk_action_group_add_action_with_accel (panel->action_group,
|
||||
action, NULL);
|
||||
}
|
||||
if (n > 0)
|
||||
g_object_set (action, "group", g_object_get_data (
|
||||
G_OBJECT (midori_panel_get_nth_page (panel, 0)),
|
||||
"midori-panel-action"), NULL);
|
||||
g_object_set_data (G_OBJECT (viewable), "midori-panel-action", action);
|
||||
g_free (action_name);
|
||||
|
||||
g_object_set_data (G_OBJECT (viewable), "parent", scrolled);
|
||||
midori_panel_construct_tool_item (panel, viewable);
|
||||
toolitem = midori_panel_construct_tool_item (panel, viewable);
|
||||
g_signal_connect (viewable, "destroy",
|
||||
G_CALLBACK (midori_panel_viewable_destroy_cb), panel);
|
||||
|
||||
if (!GTK_WIDGET_VISIBLE (viewable))
|
||||
{
|
||||
gtk_widget_hide (scrolled);
|
||||
gtk_widget_hide (GTK_WIDGET (toolitem));
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
|
@ -925,6 +1008,8 @@ midori_panel_page_num (MidoriPanel* panel,
|
|||
* silently ignore the attempt to switch the page.
|
||||
*
|
||||
* Since 0.1.8 the "page" property is notifying changes.
|
||||
*
|
||||
* Since 0.2.1 switching to hidden pages fails silently.
|
||||
**/
|
||||
void
|
||||
midori_panel_set_current_page (MidoriPanel* panel,
|
||||
|
@ -938,6 +1023,8 @@ midori_panel_set_current_page (MidoriPanel* panel,
|
|||
{
|
||||
const gchar* label;
|
||||
|
||||
if (!GTK_WIDGET_VISIBLE (viewable))
|
||||
return;
|
||||
gtk_notebook_set_current_page (GTK_NOTEBOOK (panel->toolbook), n);
|
||||
gtk_notebook_set_current_page (GTK_NOTEBOOK (panel->notebook), n);
|
||||
label = midori_viewable_get_label (MIDORI_VIEWABLE (viewable));
|
||||
|
|
|
@ -22,15 +22,18 @@
|
|||
#include <glib/gi18n.h>
|
||||
#include <libsoup/soup.h>
|
||||
|
||||
#if HAVE_LIBNOTIFY
|
||||
#include <libnotify/notify.h>
|
||||
#endif
|
||||
|
||||
struct _MidoriPreferences
|
||||
{
|
||||
GtkDialog parent_instance;
|
||||
KatzePreferences parent_instance;
|
||||
|
||||
MidoriWebSettings* settings;
|
||||
GtkWidget* notebook;
|
||||
gpointer settings;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (MidoriPreferences, midori_preferences, GTK_TYPE_DIALOG)
|
||||
G_DEFINE_TYPE (MidoriPreferences, midori_preferences, KATZE_TYPE_PREFERENCES);
|
||||
|
||||
enum
|
||||
{
|
||||
|
@ -62,6 +65,11 @@ midori_preferences_class_init (MidoriPreferencesClass* class)
|
|||
gobject_class->set_property = midori_preferences_set_property;
|
||||
gobject_class->get_property = midori_preferences_get_property;
|
||||
|
||||
/**
|
||||
* MidoriPreferences:settings:
|
||||
*
|
||||
* The settings to proxy properties from.
|
||||
*/
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_SETTINGS,
|
||||
g_param_spec_object (
|
||||
|
@ -72,38 +80,10 @@ midori_preferences_class_init (MidoriPreferencesClass* class)
|
|||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||
}
|
||||
|
||||
static void
|
||||
midori_preferences_response_cb (MidoriPreferences* preferences,
|
||||
gint response)
|
||||
{
|
||||
if (response == GTK_RESPONSE_CLOSE)
|
||||
gtk_widget_destroy (GTK_WIDGET (preferences));
|
||||
}
|
||||
|
||||
static void
|
||||
midori_preferences_init (MidoriPreferences* preferences)
|
||||
{
|
||||
gchar* dialog_title;
|
||||
|
||||
preferences->settings = NULL;
|
||||
preferences->notebook = NULL;
|
||||
|
||||
dialog_title = g_strdup_printf (_("Preferences for %s"),
|
||||
g_get_application_name ());
|
||||
g_object_set (preferences,
|
||||
"icon-name", GTK_STOCK_PREFERENCES,
|
||||
"title", dialog_title,
|
||||
"has-separator", FALSE,
|
||||
NULL);
|
||||
g_free (dialog_title);
|
||||
#if !HAVE_OSX
|
||||
gtk_dialog_add_buttons (GTK_DIALOG (preferences),
|
||||
GTK_STOCK_HELP, GTK_RESPONSE_HELP,
|
||||
GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE,
|
||||
NULL);
|
||||
#endif
|
||||
g_signal_connect (preferences, "response",
|
||||
G_CALLBACK (midori_preferences_response_cb), NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -179,9 +159,17 @@ midori_preferences_new (GtkWindow* parent,
|
|||
return GTK_WIDGET (preferences);
|
||||
}
|
||||
|
||||
#if GTK_CHECK_VERSION (2, 16, 0)
|
||||
static void
|
||||
midori_preferences_homepage_icon_press_cb (GtkWidget* button,
|
||||
GtkEntryIconPosition position,
|
||||
GdkEvent* event,
|
||||
MidoriWebSettings* settings)
|
||||
#else
|
||||
static void
|
||||
midori_preferences_homepage_current_clicked_cb (GtkWidget* button,
|
||||
MidoriWebSettings* settings)
|
||||
#endif
|
||||
{
|
||||
GtkWidget* preferences = gtk_widget_get_toplevel (button);
|
||||
GtkWidget* browser = katze_object_get_object (preferences, "transient-for");
|
||||
|
@ -194,53 +182,7 @@ midori_preferences_homepage_current_clicked_cb (GtkWidget* button,
|
|||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
proxy_download_manager_icon_cb (GtkWidget* entry,
|
||||
GdkEventFocus* event,
|
||||
GtkImage* icon)
|
||||
{
|
||||
const gchar* command;
|
||||
gchar* first_space;
|
||||
gchar* first_part;
|
||||
gchar* path;
|
||||
|
||||
command = gtk_entry_get_text (GTK_ENTRY (entry));
|
||||
if ((first_space = strstr (command, " ")))
|
||||
first_part = g_strndup (command, first_space - command);
|
||||
else
|
||||
first_part = g_strdup (command);
|
||||
path = g_find_program_in_path (first_part);
|
||||
|
||||
if (path)
|
||||
{
|
||||
if (gtk_icon_theme_has_icon (gtk_icon_theme_get_for_screen (
|
||||
gtk_widget_get_screen (entry)), first_part))
|
||||
gtk_image_set_from_icon_name (icon, first_part, GTK_ICON_SIZE_MENU);
|
||||
else
|
||||
gtk_image_set_from_stock (icon, GTK_STOCK_EXECUTE, GTK_ICON_SIZE_MENU);
|
||||
g_free (path);
|
||||
}
|
||||
else if (first_part && *first_part)
|
||||
gtk_image_set_from_stock (icon, GTK_STOCK_STOP, GTK_ICON_SIZE_MENU);
|
||||
else
|
||||
gtk_image_clear (icon);
|
||||
|
||||
g_free (first_part);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
midori_preferences_notify_preferred_encoding_cb (MidoriWebSettings* settings,
|
||||
GParamSpec* pspec,
|
||||
GtkWidget* entry)
|
||||
{
|
||||
MidoriPreferredEncoding preferred_encoding;
|
||||
|
||||
preferred_encoding = katze_object_get_enum (settings, "preferred-encoding");
|
||||
gtk_widget_set_sensitive (entry, preferred_encoding == MIDORI_ENCODING_CUSTOM);
|
||||
}
|
||||
|
||||
#if !HAVE_HILDON
|
||||
static void
|
||||
midori_preferences_notify_auto_detect_proxy_cb (MidoriWebSettings* settings,
|
||||
GParamSpec* pspec,
|
||||
|
@ -251,25 +193,9 @@ midori_preferences_notify_auto_detect_proxy_cb (MidoriWebSettings* settings,
|
|||
|
||||
gtk_widget_set_sensitive (entry, !auto_detect_proxy);
|
||||
}
|
||||
|
||||
static void
|
||||
midori_preferences_notify_identify_as_cb (MidoriWebSettings* settings,
|
||||
GParamSpec* pspec,
|
||||
GtkWidget* entry)
|
||||
{
|
||||
MidoriIdentity identify_as = katze_object_get_enum (settings, "identify-as");
|
||||
|
||||
gtk_widget_set_sensitive (entry, identify_as == MIDORI_IDENT_CUSTOM);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if HAVE_OSX
|
||||
static void
|
||||
midori_preferences_help_clicked_cb (GtkWidget* button,
|
||||
GtkDialog* dialog)
|
||||
{
|
||||
gtk_dialog_response (dialog, GTK_RESPONSE_HELP);
|
||||
}
|
||||
|
||||
static void
|
||||
midori_preferences_toolbutton_clicked_cb (GtkWidget* toolbutton,
|
||||
GtkWidget* page)
|
||||
|
@ -298,6 +224,28 @@ midori_preferences_add_toolbutton (GtkWidget* toolbar,
|
|||
#endif
|
||||
}
|
||||
|
||||
#if 0
|
||||
static void
|
||||
midori_preferences_list_dicts_cb (const gchar* lang_tag,
|
||||
const gchar* provider_name,
|
||||
const gchar* provider_desc,
|
||||
const gchar* provider_file,
|
||||
GList** dicts)
|
||||
{
|
||||
*dicts = g_list_prepend (*dicts, (gchar*)lang_tag);
|
||||
}
|
||||
|
||||
static GList*
|
||||
midori_preferences_get_spell_languages (void)
|
||||
{
|
||||
GList* dicts = NULL;
|
||||
gpointer broker = enchant_broker_init ();
|
||||
enchant_broker_list_dicts (broker, (GCallback)midori_preferences_list_dicts_cb, &dicts);
|
||||
enchant_broker_free (broker);
|
||||
return dicts;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* midori_preferences_set_settings:
|
||||
* @settings: the settings
|
||||
|
@ -315,393 +263,262 @@ midori_preferences_set_settings (MidoriPreferences* preferences,
|
|||
GtkWidget* header;
|
||||
GtkWindow* parent;
|
||||
const gchar* icon_name;
|
||||
#if WEBKIT_CHECK_VERSION (1, 1, 15)
|
||||
GtkSettings* gtk_settings;
|
||||
#endif
|
||||
GtkSizeGroup* sizegroup;
|
||||
GtkWidget* toolbar;
|
||||
GtkWidget* toolbutton;
|
||||
GtkWidget* page;
|
||||
GtkWidget* frame;
|
||||
GtkWidget* table;
|
||||
GtkWidget* align;
|
||||
KatzePreferences* _preferences;
|
||||
GtkWidget* label;
|
||||
GtkWidget* button;
|
||||
GtkWidget* entry;
|
||||
GtkWidget* hbox;
|
||||
gint icon_width, icon_height;
|
||||
|
||||
g_return_if_fail (MIDORI_IS_PREFERENCES (preferences));
|
||||
g_return_if_fail (MIDORI_IS_WEB_SETTINGS (settings));
|
||||
|
||||
g_return_if_fail (!preferences->notebook);
|
||||
g_return_if_fail (!preferences->settings);
|
||||
|
||||
katze_assign (preferences->settings, g_object_ref (settings));
|
||||
preferences->settings = settings;
|
||||
|
||||
g_object_get (preferences, "transient-for", &parent, NULL);
|
||||
icon_name = parent ? gtk_window_get_icon_name (parent) : NULL;
|
||||
if ((header = sokoke_xfce_header_new (icon_name,
|
||||
gtk_window_get_title (GTK_WINDOW (preferences)))))
|
||||
{
|
||||
gtk_box_pack_start (GTK_BOX (GTK_DIALOG (preferences)->vbox),
|
||||
header, FALSE, FALSE, 0);
|
||||
#if WEBKIT_CHECK_VERSION (1, 1, 15)
|
||||
gtk_settings = parent ? gtk_widget_get_settings (GTK_WIDGET (parent)) : NULL;
|
||||
#endif
|
||||
gtk_widget_show_all (header);
|
||||
}
|
||||
_preferences = KATZE_PREFERENCES (preferences);
|
||||
|
||||
preferences->notebook = gtk_notebook_new ();
|
||||
gtk_container_set_border_width (GTK_CONTAINER (preferences->notebook), 6);
|
||||
|
||||
#if HAVE_OSX
|
||||
gtk_notebook_set_show_tabs (GTK_NOTEBOOK (preferences->notebook), FALSE);
|
||||
gtk_notebook_set_show_border (GTK_NOTEBOOK (preferences->notebook), FALSE);
|
||||
toolbar = gtk_toolbar_new ();
|
||||
gtk_toolbar_set_style (GTK_TOOLBAR (toolbar), GTK_TOOLBAR_BOTH);
|
||||
gtk_toolbar_set_show_arrow (GTK_TOOLBAR (toolbar), FALSE);
|
||||
gtk_box_pack_start (GTK_BOX (GTK_DIALOG (preferences)->vbox),
|
||||
toolbar, FALSE, FALSE, 0);
|
||||
#else
|
||||
toolbar = NULL;
|
||||
#endif
|
||||
toolbutton = NULL;
|
||||
|
||||
sizegroup = NULL;
|
||||
#define PAGE_NEW(__icon, __label) \
|
||||
page = gtk_vbox_new (FALSE, 0); \
|
||||
midori_preferences_add_toolbutton (toolbar, &toolbutton, \
|
||||
__icon, __label, page); \
|
||||
if (toolbutton) g_object_set_data (G_OBJECT (toolbutton), \
|
||||
"notebook", preferences->notebook); \
|
||||
if (sizegroup) g_object_unref (sizegroup); \
|
||||
sizegroup = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL); \
|
||||
gtk_container_set_border_width (GTK_CONTAINER (page), 4); \
|
||||
gtk_notebook_append_page (GTK_NOTEBOOK (preferences->notebook), page, \
|
||||
gtk_label_new (__label))
|
||||
#define FRAME_NEW(__label) frame = sokoke_hig_frame_new (__label); \
|
||||
gtk_container_set_border_width (GTK_CONTAINER (frame), 4); \
|
||||
gtk_box_pack_start (GTK_BOX (page), frame, FALSE, FALSE, 0);
|
||||
#define TABLE_NEW(__rows, __cols) table = gtk_table_new ( \
|
||||
__rows, __cols, FALSE); \
|
||||
gtk_container_set_border_width (GTK_CONTAINER (table), 4); \
|
||||
gtk_container_add (GTK_CONTAINER (frame), table);
|
||||
#define WIDGET_ADD(__widget, __left, __right, __top, __bottom) \
|
||||
gtk_table_attach (GTK_TABLE (table), __widget \
|
||||
, __left, __right, __top, __bottom \
|
||||
, GTK_FILL, GTK_FILL, 8, 2)
|
||||
#define FILLED_ADD(__widget, __left, __right, __top, __bottom) \
|
||||
gtk_table_attach (GTK_TABLE (table), __widget \
|
||||
, __left, __right, __top, __bottom\
|
||||
, GTK_EXPAND | GTK_FILL, GTK_FILL, 8, 2)
|
||||
#define INDENTED_ADD(__widget, __left, __right, __top, __bottom) \
|
||||
align = gtk_alignment_new (0, 0.5, 0, 0); \
|
||||
gtk_container_add (GTK_CONTAINER (align), __widget); \
|
||||
gtk_size_group_add_widget (sizegroup, align); \
|
||||
WIDGET_ADD (align, __left, __right, __top, __bottom)
|
||||
#define SPANNED_ADD(__widget, __left, __right, __top, __bottom) \
|
||||
align = gtk_alignment_new (0, 0.5, 0, 0); \
|
||||
gtk_container_add (GTK_CONTAINER (align), __widget); \
|
||||
FILLED_ADD (align, __left, __right, __top, __bottom)
|
||||
katze_preferences_add_category (_preferences, __label, __icon)
|
||||
#define FRAME_NEW(__label) \
|
||||
katze_preferences_add_group (_preferences, __label)
|
||||
#define FILLED_ADD(__widget) \
|
||||
katze_preferences_add_widget (_preferences, __widget, "filled")
|
||||
#define INDENTED_ADD(__widget) \
|
||||
katze_preferences_add_widget (_preferences, __widget, "indented")
|
||||
#define SPANNED_ADD(__widget) \
|
||||
katze_preferences_add_widget (_preferences, __widget, "spanned")
|
||||
/* Page "General" */
|
||||
PAGE_NEW (GTK_STOCK_HOME, _("General"));
|
||||
FRAME_NEW (_("Startup"));
|
||||
TABLE_NEW (3, 2);
|
||||
label = katze_property_label (settings, "load-on-startup");
|
||||
INDENTED_ADD (label, 0, 1, 0, 1);
|
||||
INDENTED_ADD (label);
|
||||
button = katze_property_proxy (settings, "load-on-startup", NULL);
|
||||
FILLED_ADD (button, 1, 2, 0, 1);
|
||||
SPANNED_ADD (button);
|
||||
label = katze_property_label (settings, "homepage");
|
||||
INDENTED_ADD (label, 0, 1, 1, 2);
|
||||
hbox = gtk_hbox_new (FALSE, 4);
|
||||
INDENTED_ADD (label);
|
||||
entry = katze_property_proxy (settings, "homepage", NULL);
|
||||
gtk_box_pack_start (GTK_BOX (hbox), entry, TRUE, TRUE, 0);
|
||||
SPANNED_ADD (entry);
|
||||
if (parent && katze_object_has_property (parent, "uri"))
|
||||
{
|
||||
#if GTK_CHECK_VERSION (2, 16, 0)
|
||||
gtk_entry_set_icon_from_stock (GTK_ENTRY (entry),
|
||||
GTK_ENTRY_ICON_SECONDARY, GTK_STOCK_JUMP_TO);
|
||||
gtk_entry_set_icon_tooltip_text (GTK_ENTRY (entry),
|
||||
GTK_ENTRY_ICON_SECONDARY, _("Use current page as homepage"));
|
||||
g_signal_connect (entry, "icon-press",
|
||||
G_CALLBACK (midori_preferences_homepage_icon_press_cb), settings);
|
||||
#else
|
||||
button = gtk_button_new ();
|
||||
label = gtk_image_new_from_stock (GTK_STOCK_JUMP_TO, GTK_ICON_SIZE_BUTTON);
|
||||
gtk_button_set_image (GTK_BUTTON (button), label);
|
||||
gtk_widget_set_tooltip_text (button, _("Use current page as homepage"));
|
||||
g_signal_connect (button, "clicked",
|
||||
G_CALLBACK (midori_preferences_homepage_current_clicked_cb), settings);
|
||||
gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0);
|
||||
SPANNED_ADD (button);
|
||||
#endif
|
||||
}
|
||||
FILLED_ADD (hbox, 1, 2, 1, 2);
|
||||
button = katze_property_proxy (settings, "show-crash-dialog", NULL);
|
||||
INDENTED_ADD (button, 0, 1, 2, 3);
|
||||
INDENTED_ADD (button);
|
||||
button = katze_property_proxy (settings, "speed-dial-in-new-tabs", NULL);
|
||||
FILLED_ADD (button, 1, 2, 2, 3);
|
||||
SPANNED_ADD (button);
|
||||
FRAME_NEW (_("Transfers"));
|
||||
TABLE_NEW (2, 2);
|
||||
#if !HAVE_HILDON
|
||||
label = katze_property_label (settings, "download-folder");
|
||||
INDENTED_ADD (label, 0, 1, 0, 1);
|
||||
INDENTED_ADD (label);
|
||||
button = katze_property_proxy (settings, "download-folder", "folder");
|
||||
FILLED_ADD (button, 1, 2, 0, 1);
|
||||
SPANNED_ADD (button);
|
||||
label = katze_property_proxy (settings, "ask-for-destination-folder", NULL);
|
||||
INDENTED_ADD (label, 0, 1, 1, 2);
|
||||
INDENTED_ADD (label);
|
||||
#if HAVE_LIBNOTIFY
|
||||
if (notify_is_initted () || g_find_program_in_path ("notify-send"))
|
||||
{
|
||||
button = katze_property_proxy (settings, "notify-transfer-completed", NULL);
|
||||
/* FIXME: Disable the option if notifications presumably cannot be sent
|
||||
gtk_widget_set_sensitive (button, FALSE); */
|
||||
SPANNED_ADD (button, 1, 2, 1, 2);
|
||||
SPANNED_ADD (button);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Page "Appearance" */
|
||||
PAGE_NEW (GTK_STOCK_SELECT_FONT, _("Appearance"));
|
||||
FRAME_NEW (_("Font settings"));
|
||||
TABLE_NEW (7, 2);
|
||||
#if !HAVE_HILDON
|
||||
label = gtk_label_new (_("Default Font Family"));
|
||||
INDENTED_ADD (label, 0, 1, 0, 1);
|
||||
hbox = gtk_hbox_new (FALSE, 4);
|
||||
INDENTED_ADD (label);
|
||||
button = katze_property_proxy (settings, "default-font-family", "font");
|
||||
gtk_widget_set_tooltip_text (button, _("The default font family used to display text"));
|
||||
gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
|
||||
SPANNED_ADD (button);
|
||||
entry = katze_property_proxy (settings, "default-font-size", NULL);
|
||||
gtk_widget_set_tooltip_text (entry, _("The default font size used to display text"));
|
||||
gtk_box_pack_end (GTK_BOX (hbox), entry, FALSE, FALSE, 4);
|
||||
FILLED_ADD (hbox, 1, 2, 0, 1);
|
||||
SPANNED_ADD (entry);
|
||||
label = gtk_label_new (_("Fixed-width Font Family"));
|
||||
INDENTED_ADD (label, 0, 1, 1, 2);
|
||||
hbox = gtk_hbox_new (FALSE, 4);
|
||||
INDENTED_ADD (label);
|
||||
button = katze_property_proxy (settings, "monospace-font-family", "font-monospace");
|
||||
gtk_widget_set_tooltip_text (button, _("The font family used to display fixed-width text"));
|
||||
gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
|
||||
SPANNED_ADD (button);
|
||||
entry = katze_property_proxy (settings, "default-monospace-font-size", NULL);
|
||||
gtk_widget_set_tooltip_text (entry, _("The font size used to display fixed-width text"));
|
||||
gtk_box_pack_end (GTK_BOX (hbox), entry, FALSE, FALSE, 4);
|
||||
INDENTED_ADD (hbox, 1, 2, 1, 2);
|
||||
SPANNED_ADD (entry);
|
||||
label = gtk_label_new (_("Minimum Font Size"));
|
||||
INDENTED_ADD (label, 0, 1, 2, 3);
|
||||
INDENTED_ADD (label);
|
||||
entry = katze_property_proxy (settings, "minimum-font-size", NULL);
|
||||
gtk_widget_set_tooltip_text (entry, _("The minimum font size used to display text"));
|
||||
INDENTED_ADD (entry, 1, 2, 2, 3);
|
||||
SPANNED_ADD (entry);
|
||||
#endif
|
||||
label = katze_property_label (settings, "preferred-encoding");
|
||||
INDENTED_ADD (label, 0, 1, 3, 4);
|
||||
button = katze_property_proxy (settings, "preferred-encoding", NULL);
|
||||
FILLED_ADD (button, 1, 2, 3, 4);
|
||||
label = katze_property_label (settings, "default-encoding");
|
||||
gtk_label_set_label (GTK_LABEL (label), _("Encoding"));
|
||||
INDENTED_ADD (label, 0, 1, 4, 5);
|
||||
entry = katze_property_proxy (settings, "default-encoding", NULL);
|
||||
gtk_widget_set_tooltip_text (entry, _("The character encoding to use by default"));
|
||||
g_signal_connect (settings, "notify::preferred-encoding",
|
||||
G_CALLBACK (midori_preferences_notify_preferred_encoding_cb), entry);
|
||||
midori_preferences_notify_preferred_encoding_cb (settings, NULL, entry);
|
||||
FILLED_ADD (entry, 1, 2, 4, 5);
|
||||
INDENTED_ADD (label);
|
||||
button = katze_property_proxy (settings, "preferred-encoding", "custom-default-encoding");
|
||||
SPANNED_ADD (button);
|
||||
|
||||
/* Page "Behavior" */
|
||||
PAGE_NEW (GTK_STOCK_SELECT_COLOR, _("Behavior"));
|
||||
FRAME_NEW (_("Features"));
|
||||
TABLE_NEW (6, 2);
|
||||
#if !HAVE_HILDON
|
||||
button = katze_property_proxy (settings, "auto-load-images", NULL);
|
||||
gtk_button_set_label (GTK_BUTTON (button), _("Load images automatically"));
|
||||
gtk_widget_set_tooltip_text (button, _("Load and display images automatically"));
|
||||
INDENTED_ADD (button, 0, 1, 0, 1);
|
||||
#if WEBKIT_CHECK_VERSION (1, 1, 15)
|
||||
if (katze_object_get_boolean (gtk_settings, "gtk-touchscreen-mode"))
|
||||
INDENTED_ADD (button);
|
||||
#endif
|
||||
#if WEBKIT_CHECK_VERSION (1, 1, 15) || HAVE_HILDON
|
||||
if (katze_widget_has_touchscreen_mode (parent ?
|
||||
GTK_WIDGET (parent) : GTK_WIDGET (preferences)))
|
||||
button = katze_property_proxy (settings, "kinetic-scrolling", NULL);
|
||||
else
|
||||
{
|
||||
button = katze_property_proxy (settings, "auto-shrink-images", NULL);
|
||||
gtk_button_set_label (GTK_BUTTON (button), _("Shrink images automatically"));
|
||||
gtk_widget_set_tooltip_text (button, _("Automatically shrink standalone images to fit"));
|
||||
}
|
||||
button = katze_property_proxy (settings, "open-panels-in-windows", NULL);
|
||||
#else
|
||||
button = katze_property_proxy (settings, "middle-click-opens-selection", NULL);
|
||||
#endif
|
||||
SPANNED_ADD (button, 1, 2, 0, 1);
|
||||
SPANNED_ADD (button);
|
||||
#if !HAVE_HILDON
|
||||
button = katze_property_proxy (settings, "enable-scripts", NULL);
|
||||
gtk_button_set_label (GTK_BUTTON (button), _("Enable scripts"));
|
||||
gtk_widget_set_tooltip_text (button, _("Enable embedded scripting languages"));
|
||||
INDENTED_ADD (button, 0, 1, 2, 3);
|
||||
INDENTED_ADD (button);
|
||||
button = katze_property_proxy (settings, "enable-plugins", NULL);
|
||||
gtk_button_set_label (GTK_BUTTON (button), _("Enable Netscape plugins"));
|
||||
gtk_widget_set_tooltip_text (button, _("Enable embedded Netscape plugin objects"));
|
||||
SPANNED_ADD (button, 1, 2, 2, 3);
|
||||
SPANNED_ADD (button);
|
||||
button = katze_property_proxy (settings, "enforce-96-dpi", NULL);
|
||||
gtk_button_set_label (GTK_BUTTON (button), _("Enforce 96 dots per inch"));
|
||||
gtk_widget_set_tooltip_text (button, _("Enforce a video dot density of 96 DPI"));
|
||||
SPANNED_ADD (button, 0, 1, 3, 4);
|
||||
INDENTED_ADD (button);
|
||||
button = katze_property_proxy (settings, "enable-developer-extras", NULL);
|
||||
gtk_button_set_label (GTK_BUTTON (button), _("Enable developer tools"));
|
||||
gtk_widget_set_tooltip_text (button, _("Enable special extensions for developers"));
|
||||
SPANNED_ADD (button, 1, 2, 3, 4);
|
||||
SPANNED_ADD (button);
|
||||
#endif
|
||||
button = katze_property_proxy (settings, "zoom-text-and-images", NULL);
|
||||
SPANNED_ADD (button, 0, 1, 4, 5);
|
||||
INDENTED_ADD (button);
|
||||
button = katze_property_proxy (settings, "find-while-typing", NULL);
|
||||
SPANNED_ADD (button, 1, 2, 4, 5);
|
||||
SPANNED_ADD (button);
|
||||
#if WEBKIT_CHECK_VERSION (1, 1, 6)
|
||||
FRAME_NEW (_("Spell Checking"));
|
||||
TABLE_NEW (1, 2);
|
||||
/* FIXME: Provide a nice dictionary selection */
|
||||
button = katze_property_proxy (settings, "enable-spell-checking", NULL);
|
||||
gtk_button_set_label (GTK_BUTTON (button), _("Enable Spell Checking"));
|
||||
gtk_widget_set_tooltip_text (button, _("Enable spell checking while typing"));
|
||||
INDENTED_ADD (button, 0, 1, 0, 1);
|
||||
INDENTED_ADD (button);
|
||||
entry = katze_property_proxy (settings, "spell-checking-languages", NULL);
|
||||
/* i18n: The example should be adjusted to contain a good local default */
|
||||
gtk_widget_set_tooltip_text (entry, _("A comma separated list of languages to be used for spell checking, for example \"en_GB,de_DE\""));
|
||||
FILLED_ADD (entry, 1, 2, 0, 1);
|
||||
gtk_widget_set_tooltip_text (entry, _("A comma separated list of "
|
||||
"languages to be used for spell checking, for example \"en_GB,de_DE\""));
|
||||
SPANNED_ADD (entry);
|
||||
#endif
|
||||
|
||||
/* Page "Interface" */
|
||||
PAGE_NEW (GTK_STOCK_CONVERT, _("Interface"));
|
||||
FRAME_NEW (_("Navigationbar"));
|
||||
TABLE_NEW (2, 2);
|
||||
#if !HAVE_HILDON
|
||||
INDENTED_ADD (katze_property_label (settings, "toolbar-style"), 0, 1, 0, 1);
|
||||
INDENTED_ADD (katze_property_label (settings, "toolbar-style"));
|
||||
button = katze_property_proxy (settings, "toolbar-style", NULL);
|
||||
FILLED_ADD (button, 1, 2, 0, 1);
|
||||
#endif
|
||||
SPANNED_ADD (button);
|
||||
button = katze_property_proxy (settings, "progress-in-location", NULL);
|
||||
FILLED_ADD (button, 0, 1, 1, 2);
|
||||
INDENTED_ADD (button);
|
||||
button = katze_property_proxy (settings, "search-engines-in-completion", NULL);
|
||||
FILLED_ADD (button, 1, 2, 1, 2);
|
||||
SPANNED_ADD (button);
|
||||
#endif
|
||||
FRAME_NEW (_("Browsing"));
|
||||
TABLE_NEW (5, 2);
|
||||
hbox = gtk_hbox_new (FALSE, 4);
|
||||
label = katze_property_label (settings, "open-new-pages-in");
|
||||
gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 4);
|
||||
INDENTED_ADD (label);
|
||||
button = katze_property_proxy (settings, "open-new-pages-in", NULL);
|
||||
gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 4);
|
||||
INDENTED_ADD (hbox, 0, 1, 0, 1);
|
||||
hbox = gtk_hbox_new (FALSE, 4);
|
||||
SPANNED_ADD (button);
|
||||
label = katze_property_label (settings, "open-external-pages-in");
|
||||
gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 4);
|
||||
INDENTED_ADD (label);
|
||||
button = katze_property_proxy (settings, "open-external-pages-in", NULL);
|
||||
gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 4);
|
||||
FILLED_ADD (hbox, 1, 2, 0, 1);
|
||||
SPANNED_ADD (button);
|
||||
#if !HAVE_HILDON
|
||||
button = katze_property_proxy (settings, "always-show-tabbar", NULL);
|
||||
INDENTED_ADD (button, 0, 1, 2, 3);
|
||||
button = katze_property_proxy (settings, "open-tabs-in-the-background", NULL);
|
||||
INDENTED_ADD (button, 1, 2, 2, 3);
|
||||
button = katze_property_proxy (settings, "open-tabs-next-to-current", NULL);
|
||||
WIDGET_ADD (button, 0, 1, 5, 6);
|
||||
INDENTED_ADD (button);
|
||||
button = katze_property_proxy (settings, "close-buttons-on-tabs", NULL);
|
||||
WIDGET_ADD (button, 1, 2, 5, 6);
|
||||
SPANNED_ADD (button);
|
||||
#endif
|
||||
button = katze_property_proxy (settings, "open-tabs-next-to-current", NULL);
|
||||
INDENTED_ADD (button);
|
||||
button = katze_property_proxy (settings, "open-tabs-in-the-background", NULL);
|
||||
SPANNED_ADD (button);
|
||||
|
||||
#if !HAVE_HILDON
|
||||
/* Page "Applications" */
|
||||
PAGE_NEW (GTK_STOCK_CONVERT, _("Applications"));
|
||||
FRAME_NEW (_("External applications"));
|
||||
TABLE_NEW (3, 2);
|
||||
label = katze_property_label (settings, "text-editor");
|
||||
INDENTED_ADD (label, 0, 1, 0, 1);
|
||||
hbox = gtk_hbox_new (FALSE, 4);
|
||||
button = gtk_image_new ();
|
||||
gtk_icon_size_lookup_for_settings (gtk_widget_get_settings (button),
|
||||
GTK_ICON_SIZE_MENU, &icon_width, &icon_height);
|
||||
gtk_widget_set_size_request (button, icon_width, icon_height);
|
||||
gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 4);
|
||||
entry = katze_property_proxy (settings, "text-editor", NULL);
|
||||
gtk_box_pack_start (GTK_BOX (hbox), entry, TRUE, TRUE, 0);
|
||||
proxy_download_manager_icon_cb (entry, NULL, GTK_IMAGE (button));
|
||||
g_signal_connect (entry, "focus-out-event",
|
||||
G_CALLBACK (proxy_download_manager_icon_cb), button);
|
||||
FILLED_ADD (hbox, 1, 2, 0, 1);
|
||||
INDENTED_ADD (label);
|
||||
entry = katze_property_proxy (settings, "text-editor", "application-text/plain");
|
||||
SPANNED_ADD (entry);
|
||||
label = katze_property_label (settings, "download-manager");
|
||||
INDENTED_ADD (label, 0, 1, 1, 2);
|
||||
hbox = gtk_hbox_new (FALSE, 4);
|
||||
button = gtk_image_new ();
|
||||
gtk_icon_size_lookup_for_settings (gtk_widget_get_settings (button),
|
||||
GTK_ICON_SIZE_MENU, &icon_width, &icon_height);
|
||||
gtk_widget_set_size_request (button, icon_width, icon_height);
|
||||
gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 4);
|
||||
entry = katze_property_proxy (settings, "download-manager", NULL);
|
||||
gtk_box_pack_start (GTK_BOX (hbox), entry, TRUE, TRUE, 0);
|
||||
proxy_download_manager_icon_cb (entry, NULL, GTK_IMAGE (button));
|
||||
g_signal_connect (entry, "focus-out-event",
|
||||
G_CALLBACK (proxy_download_manager_icon_cb), button);
|
||||
FILLED_ADD (hbox, 1, 2, 1, 2);
|
||||
INDENTED_ADD (label);
|
||||
entry = katze_property_proxy (settings, "download-manager", "application-Network");
|
||||
SPANNED_ADD (entry);
|
||||
label = katze_property_label (settings, "news-aggregator");
|
||||
INDENTED_ADD (label, 0, 1, 2, 3);
|
||||
hbox = gtk_hbox_new (FALSE, 4);
|
||||
button = gtk_image_new ();
|
||||
gtk_icon_size_lookup_for_settings (gtk_widget_get_settings (button),
|
||||
GTK_ICON_SIZE_MENU, &icon_width, &icon_height);
|
||||
gtk_widget_set_size_request (button, icon_width, icon_height);
|
||||
gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 4);
|
||||
entry = katze_property_proxy (settings, "news-aggregator", NULL);
|
||||
gtk_box_pack_start (GTK_BOX (hbox), entry, TRUE, TRUE, 0);
|
||||
proxy_download_manager_icon_cb (entry, NULL, GTK_IMAGE (button));
|
||||
g_signal_connect (entry, "focus-out-event",
|
||||
G_CALLBACK (proxy_download_manager_icon_cb), button);
|
||||
FILLED_ADD (hbox, 1, 2, 2, 3);
|
||||
INDENTED_ADD (label);
|
||||
entry = katze_property_proxy (settings, "news-aggregator", "application-News");
|
||||
SPANNED_ADD (entry);
|
||||
#endif
|
||||
|
||||
/* Page "Network" */
|
||||
PAGE_NEW (GTK_STOCK_NETWORK, _("Network"));
|
||||
FRAME_NEW (_("Network"));
|
||||
TABLE_NEW (5, 2);
|
||||
#if !HAVE_HILDON
|
||||
label = katze_property_label (settings, "http-proxy");
|
||||
INDENTED_ADD (label, 0, 1, 0, 1);
|
||||
INDENTED_ADD (label);
|
||||
entry = katze_property_proxy (settings, "http-proxy", NULL);
|
||||
FILLED_ADD (entry, 1, 2, 0, 1);
|
||||
SPANNED_ADD (entry);
|
||||
INDENTED_ADD (gtk_event_box_new ());
|
||||
button = katze_property_proxy (settings, "auto-detect-proxy", NULL);
|
||||
FILLED_ADD (button, 1, 2, 1, 2);
|
||||
SPANNED_ADD (button);
|
||||
g_signal_connect (settings, "notify::auto-detect-proxy",
|
||||
G_CALLBACK (midori_preferences_notify_auto_detect_proxy_cb), entry);
|
||||
midori_preferences_notify_auto_detect_proxy_cb (settings, NULL, entry);
|
||||
#endif
|
||||
label = katze_property_label (settings, "identify-as");
|
||||
INDENTED_ADD (label, 0, 1, 2, 3);
|
||||
button = katze_property_proxy (settings, "identify-as", NULL);
|
||||
FILLED_ADD (button, 1, 2, 2, 3);
|
||||
label = katze_property_label (settings, "ident-string");
|
||||
INDENTED_ADD (label, 0, 1, 3, 4);
|
||||
entry = katze_property_proxy (settings, "ident-string", NULL);
|
||||
g_signal_connect (settings, "notify::identify-as",
|
||||
G_CALLBACK (midori_preferences_notify_identify_as_cb), entry);
|
||||
midori_preferences_notify_identify_as_cb (settings, NULL, entry);
|
||||
FILLED_ADD (entry, 1, 2, 3, 4);
|
||||
label = katze_property_label (settings, "cache-size");
|
||||
INDENTED_ADD (label, 0, 1, 4, 5);
|
||||
hbox = gtk_hbox_new (FALSE, 4);
|
||||
entry = katze_property_proxy (settings, "cache-size", NULL);
|
||||
gtk_box_pack_start (GTK_BOX (hbox), entry, FALSE, FALSE, 0);
|
||||
gtk_box_pack_start (GTK_BOX (hbox), gtk_label_new (_("MB")),
|
||||
FALSE, FALSE, 0);
|
||||
FILLED_ADD (hbox, 1, 2, 4, 5);
|
||||
INDENTED_ADD (label);
|
||||
button = katze_property_proxy (settings, "identify-as", "custom-ident-string");
|
||||
SPANNED_ADD (button);
|
||||
|
||||
/* Page "Privacy" */
|
||||
PAGE_NEW (GTK_STOCK_INDEX, _("Privacy"));
|
||||
FRAME_NEW (_("Web Cookies"));
|
||||
TABLE_NEW (3, 2);
|
||||
label = katze_property_label (settings, "accept-cookies");
|
||||
INDENTED_ADD (label, 0, 1, 0, 1);
|
||||
INDENTED_ADD (label);
|
||||
button = katze_property_proxy (settings, "accept-cookies", NULL);
|
||||
FILLED_ADD (button, 1, 2, 0, 1);
|
||||
SPANNED_ADD (button);
|
||||
button = katze_property_proxy (settings, "original-cookies-only", NULL);
|
||||
SPANNED_ADD (button, 0, 1, 1, 2);
|
||||
hbox = gtk_hbox_new (FALSE, 4);
|
||||
INDENTED_ADD (button);
|
||||
label = katze_property_label (settings, "maximum-cookie-age");
|
||||
gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
|
||||
INDENTED_ADD (label);
|
||||
entry = katze_property_proxy (settings, "maximum-cookie-age", NULL);
|
||||
gtk_box_pack_start (GTK_BOX (hbox), entry, FALSE, FALSE, 0);
|
||||
gtk_box_pack_start (GTK_BOX (hbox), gtk_label_new (_("days")),
|
||||
FALSE, FALSE, 0);
|
||||
FILLED_ADD (hbox, 1, 2, 1, 2);
|
||||
SPANNED_ADD (entry);
|
||||
label = gtk_label_new (_("days"));
|
||||
SPANNED_ADD (label);
|
||||
FRAME_NEW (_("History"));
|
||||
TABLE_NEW (3, 2);
|
||||
button = katze_property_proxy (settings, "remember-last-visited-pages", NULL);
|
||||
SPANNED_ADD (button, 0, 1, 0, 1);
|
||||
hbox = gtk_hbox_new (FALSE, 4);
|
||||
button = katze_property_label (settings, "maximum-history-age");
|
||||
INDENTED_ADD (button);
|
||||
button = katze_property_proxy (settings, "maximum-history-age", NULL);
|
||||
gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0);
|
||||
gtk_box_pack_start (GTK_BOX (hbox), gtk_label_new (_("days")),
|
||||
FALSE, FALSE, 0);
|
||||
SPANNED_ADD (hbox, 1, 2, 0, 1);
|
||||
button = katze_property_proxy (settings, "remember-last-form-inputs", NULL);
|
||||
SPANNED_ADD (button, 0, 2, 1, 2);
|
||||
SPANNED_ADD (button);
|
||||
label = gtk_label_new (_("days"));
|
||||
SPANNED_ADD (label);
|
||||
button = katze_property_proxy (settings, "remember-last-downloaded-files", NULL);
|
||||
SPANNED_ADD (button, 0, 2, 2, 3);
|
||||
|
||||
g_object_unref (sizegroup);
|
||||
gtk_box_pack_start (GTK_BOX (GTK_DIALOG (preferences)->vbox),
|
||||
preferences->notebook, FALSE, FALSE, 4);
|
||||
#if HAVE_OSX
|
||||
GtkWidget* icon;
|
||||
hbox = gtk_hbox_new (FALSE, 0);
|
||||
button = gtk_button_new ();
|
||||
icon = gtk_image_new_from_stock (GTK_STOCK_HELP, GTK_ICON_SIZE_BUTTON);
|
||||
gtk_button_set_image (GTK_BUTTON (button), icon);
|
||||
g_signal_connect (button, "clicked",
|
||||
G_CALLBACK (midori_preferences_help_clicked_cb), preferences);
|
||||
gtk_box_pack_end (GTK_BOX (hbox),
|
||||
button, FALSE, FALSE, 4);
|
||||
gtk_box_pack_end (GTK_BOX (GTK_DIALOG (preferences)->vbox),
|
||||
hbox, FALSE, FALSE, 0);
|
||||
#endif
|
||||
gtk_widget_show_all (GTK_DIALOG (preferences)->vbox);
|
||||
INDENTED_ADD (button);
|
||||
}
|
||||
|
|
|
@ -14,8 +14,6 @@
|
|||
|
||||
#include "midori-websettings.h"
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#include <katze/katze.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
@ -38,7 +36,7 @@ typedef struct _MidoriPreferencesClass MidoriPreferencesClass;
|
|||
|
||||
struct _MidoriPreferencesClass
|
||||
{
|
||||
GtkDialogClass parent_class;
|
||||
KatzePreferencesClass parent_class;
|
||||
};
|
||||
|
||||
GType
|
||||
|
|
|
@ -407,9 +407,9 @@ midori_search_action_manage_activate_cb (GtkWidget* menuitem,
|
|||
|
||||
/* Private function, used by MidoriView */
|
||||
/* static */ GdkPixbuf*
|
||||
midori_search_action_get_icon (KatzeNet* net,
|
||||
KatzeItem* item,
|
||||
GtkWidget* widget)
|
||||
midori_search_action_get_icon (KatzeItem* item,
|
||||
GtkWidget* widget,
|
||||
const gchar** icon_name)
|
||||
{
|
||||
const gchar* icon;
|
||||
|
||||
|
@ -417,25 +417,21 @@ midori_search_action_get_icon (KatzeNet* net,
|
|||
{
|
||||
GdkScreen* screen;
|
||||
GtkIconTheme* icon_theme;
|
||||
gint width, height;
|
||||
GdkPixbuf* pixbuf;
|
||||
|
||||
if (G_UNLIKELY (!(screen = gtk_widget_get_screen (widget))))
|
||||
return gtk_widget_render_icon (widget, GTK_STOCK_FILE,
|
||||
GTK_ICON_SIZE_MENU, NULL);
|
||||
screen = gtk_widget_get_screen (widget);
|
||||
icon_theme = gtk_icon_theme_get_for_screen (screen);
|
||||
gtk_icon_size_lookup_for_settings (gtk_widget_get_settings (widget),
|
||||
GTK_ICON_SIZE_MENU, &width, &height);
|
||||
if ((pixbuf = gtk_icon_theme_load_icon (icon_theme, icon, MAX (width, height),
|
||||
GTK_ICON_LOOKUP_USE_BUILTIN, NULL)))
|
||||
return pixbuf;
|
||||
if (gtk_icon_theme_has_icon (icon_theme, icon))
|
||||
*icon_name = icon;
|
||||
else
|
||||
*icon_name = GTK_STOCK_FILE;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ((icon = katze_item_get_uri (item)) && (g_strstr_len (icon, 8, "://")))
|
||||
return katze_net_load_icon (net, icon, NULL, widget, NULL);
|
||||
return katze_load_cached_icon (icon, widget);
|
||||
|
||||
return gtk_widget_render_icon (widget, GTK_STOCK_FILE,
|
||||
GTK_ICON_SIZE_MENU, NULL);
|
||||
*icon_name = GTK_STOCK_FILE;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -463,13 +459,20 @@ midori_search_action_icon_released_cb (GtkWidget* entry,
|
|||
{
|
||||
do
|
||||
{
|
||||
const gchar* icon_name;
|
||||
|
||||
menuitem = gtk_image_menu_item_new_with_label (
|
||||
katze_item_get_name (item));
|
||||
image = gtk_image_new ();
|
||||
icon = midori_search_action_get_icon (
|
||||
MIDORI_SEARCH_ACTION (action)->net, item, entry);
|
||||
icon = midori_search_action_get_icon (item, entry, &icon_name);
|
||||
if (icon)
|
||||
{
|
||||
gtk_image_set_from_pixbuf (GTK_IMAGE (image), icon);
|
||||
g_object_unref (icon);
|
||||
}
|
||||
else
|
||||
gtk_image_set_from_icon_name (GTK_IMAGE (image), icon_name,
|
||||
GTK_ICON_SIZE_MENU);
|
||||
gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menuitem), image);
|
||||
#if GTK_CHECK_VERSION (2, 16, 0)
|
||||
gtk_image_menu_item_set_always_show_image (
|
||||
|
@ -501,8 +504,7 @@ midori_search_action_icon_released_cb (GtkWidget* entry,
|
|||
g_signal_connect (menuitem, "activate",
|
||||
G_CALLBACK (midori_search_action_manage_activate_cb), action);
|
||||
gtk_widget_show (menuitem);
|
||||
sokoke_widget_popup (entry, GTK_MENU (menu),
|
||||
NULL, SOKOKE_MENU_POSITION_LEFT);
|
||||
katze_widget_popup (entry, GTK_MENU (menu), NULL, KATZE_MENU_POSITION_LEFT);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
|
@ -525,11 +527,19 @@ midori_search_action_set_entry_icon (MidoriSearchAction* search_action,
|
|||
|
||||
if (search_action->current_item)
|
||||
{
|
||||
icon = midori_search_action_get_icon (search_action->net,
|
||||
search_action->current_item, entry);
|
||||
const gchar* icon_name;
|
||||
|
||||
icon = midori_search_action_get_icon (search_action->current_item,
|
||||
entry, &icon_name);
|
||||
if (icon)
|
||||
{
|
||||
gtk_icon_entry_set_icon_from_pixbuf (GTK_ICON_ENTRY (entry),
|
||||
GTK_ICON_ENTRY_PRIMARY, icon);
|
||||
g_object_unref (icon);
|
||||
}
|
||||
else
|
||||
gtk_icon_entry_set_icon_from_icon_name (GTK_ICON_ENTRY (entry),
|
||||
GTK_ICON_ENTRY_PRIMARY, icon_name);
|
||||
sokoke_entry_set_default_text (GTK_ENTRY (entry),
|
||||
katze_item_get_name (search_action->current_item));
|
||||
}
|
||||
|
@ -819,13 +829,18 @@ midori_search_action_dialog_render_icon_cb (GtkTreeViewColumn* column,
|
|||
KatzeItem* item;
|
||||
MidoriSearchAction* search_action;
|
||||
GdkPixbuf* icon;
|
||||
const gchar* icon_name;
|
||||
|
||||
gtk_tree_model_get (model, iter, 0, &item, -1);
|
||||
|
||||
search_action = g_object_get_data (G_OBJECT (treeview), "search-action");
|
||||
icon = midori_search_action_get_icon (search_action->net, item, treeview);
|
||||
if ((icon = midori_search_action_get_icon (item, treeview, &icon_name)))
|
||||
{
|
||||
g_object_set (renderer, "pixbuf", icon, "yalign", 0.25, NULL);
|
||||
g_object_unref (icon);
|
||||
}
|
||||
else
|
||||
g_object_set (renderer, "icon-name", icon_name, "yalign", 0.25, NULL);
|
||||
g_object_unref (item);
|
||||
}
|
||||
|
||||
|
@ -1016,6 +1031,10 @@ midori_search_action_get_editor (MidoriSearchAction* search_action,
|
|||
|
||||
if (new_engine)
|
||||
katze_array_add_item (search_action->search_engines, item);
|
||||
/* If it isn't a new search engine but the old default one,
|
||||
we need to update the default search engine after editing it. */
|
||||
else if (item == midori_search_action_get_default_item (search_action))
|
||||
midori_search_action_set_default_item (search_action, item);
|
||||
}
|
||||
gtk_widget_destroy (dialog);
|
||||
}
|
||||
|
@ -1217,7 +1236,9 @@ midori_search_action_get_dialog (MidoriSearchAction* search_action)
|
|||
toplevel ? GTK_WINDOW (toplevel) : NULL,
|
||||
GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_NO_SEPARATOR,
|
||||
#if !HAVE_OSX
|
||||
#if !HAVE_HILDON
|
||||
GTK_STOCK_HELP, GTK_RESPONSE_HELP,
|
||||
#endif
|
||||
GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE,
|
||||
#endif
|
||||
NULL);
|
||||
|
|
|
@ -30,7 +30,7 @@
|
|||
#define STOCK_STYLE "gnome-settings-theme"
|
||||
#define STOCK_TRANSFER "package"
|
||||
#define STOCK_TRANSFERS "package"
|
||||
#define STOCK_PLUGINS GTK_STOCK_CONVERT
|
||||
#define STOCK_PLUGINS "gnome-mime-application-x-shockwave-flash"
|
||||
|
||||
#define STOCK_BOOKMARK_ADD "stock_add-bookmark"
|
||||
#define STOCK_HOMEPAGE GTK_STOCK_HOME
|
||||
|
@ -43,4 +43,13 @@
|
|||
#define STOCK_USER_TRASH "gnome-stock-trash"
|
||||
#define STOCK_WINDOW_NEW "stock_new-window"
|
||||
|
||||
#if defined (HAVE_HILDON) && HAVE_HILDON
|
||||
#undef STOCK_BOOKMARKS
|
||||
#define STOCK_BOOKMARKS "general_mybookmarks_folder"
|
||||
#undef STOCK_NEWS_FEED
|
||||
#define STOCK_NEWS_FEED "general_rss"
|
||||
#undef STOCK_WEB_BROWSER
|
||||
#define STOCK_WEB_BROWSER "general_web"
|
||||
#endif
|
||||
|
||||
#endif /* !__MIDORI_STOCK_H__ */
|
||||
|
|
|
@ -40,18 +40,13 @@ webkit_web_frame_print (WebKitWebFrame* web_frame);
|
|||
#endif
|
||||
|
||||
GdkPixbuf*
|
||||
midori_search_action_get_icon (KatzeNet* net,
|
||||
KatzeItem* item,
|
||||
GtkWidget* widget);
|
||||
midori_search_action_get_icon (KatzeItem* item,
|
||||
GtkWidget* widget,
|
||||
const gchar** icon_name);
|
||||
|
||||
static void
|
||||
midori_view_construct_web_view (MidoriView* view);
|
||||
|
||||
GdkPixbuf*
|
||||
midori_view_get_snapshot (MidoriView* view,
|
||||
gint width,
|
||||
gint height);
|
||||
|
||||
static void
|
||||
midori_view_item_meta_data_changed (KatzeItem* item,
|
||||
const gchar* key,
|
||||
|
@ -625,8 +620,8 @@ midori_view_update_icon (MidoriView* view,
|
|||
if (!icon)
|
||||
{
|
||||
GdkScreen* screen;
|
||||
GtkIconTheme* icon_theme;
|
||||
gchar** parts;
|
||||
GtkIconTheme* icon_theme = NULL;
|
||||
gchar** parts = NULL;
|
||||
gchar* icon_name;
|
||||
|
||||
if ((screen = gtk_widget_get_screen (GTK_WIDGET (view))))
|
||||
|
@ -638,8 +633,6 @@ midori_view_update_icon (MidoriView* view,
|
|||
katze_assign (parts, NULL);
|
||||
}
|
||||
}
|
||||
else
|
||||
parts = NULL;
|
||||
|
||||
if (parts)
|
||||
icon = midori_view_mime_icon (icon_theme, "%s-%s",
|
||||
|
@ -713,13 +706,15 @@ midori_view_web_view_navigation_decision_cb (WebKitWebView* web_view
|
|||
MidoriView* view)
|
||||
{
|
||||
const gchar* uri = webkit_network_request_get_uri (request);
|
||||
if (g_str_has_prefix (uri, "mailto:"))
|
||||
if (g_str_has_prefix (uri, "mailto:") || g_str_has_prefix (uri, "tel:"))
|
||||
{
|
||||
if (sokoke_show_uri (gtk_widget_get_screen (GTK_WIDGET (web_view)),
|
||||
uri, GDK_CURRENT_TIME, NULL))
|
||||
{
|
||||
webkit_web_policy_decision_ignore (decision);
|
||||
sokoke_show_uri (gtk_widget_get_screen (GTK_WIDGET (web_view)),
|
||||
uri, GDK_CURRENT_TIME, NULL);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
/* TODO: Handle more external protocols */
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -818,6 +813,71 @@ webkit_web_view_progress_changed_cb (WebKitWebView* web_view,
|
|||
}
|
||||
|
||||
#if WEBKIT_CHECK_VERSION (1, 1, 6)
|
||||
#if WEBKIT_CHECK_VERSION (1, 1, 14)
|
||||
static void
|
||||
midori_view_web_view_resource_request_cb (WebKitWebView* web_view,
|
||||
WebKitWebFrame* web_frame,
|
||||
WebKitWebResource* web_resource,
|
||||
WebKitNetworkRequest* request,
|
||||
WebKitNetworkResponse* response,
|
||||
MidoriView* view)
|
||||
{
|
||||
const gchar* uri = webkit_network_request_get_uri (request);
|
||||
|
||||
/* Only apply custom URIs to special pages for security purposes */
|
||||
if (!webkit_web_data_source_get_unreachable_uri (
|
||||
webkit_web_frame_get_data_source (web_frame)))
|
||||
return;
|
||||
|
||||
if (g_str_has_prefix (uri, "res://"))
|
||||
{
|
||||
gchar* filename = g_build_filename ("midori/res", &uri[5], NULL);
|
||||
gchar* filepath = sokoke_find_data_filename (filename);
|
||||
gchar* file_uri;
|
||||
|
||||
g_free (filename);
|
||||
file_uri = g_filename_to_uri (filepath, NULL, NULL);
|
||||
g_free (filepath);
|
||||
webkit_network_request_set_uri (request, file_uri);
|
||||
g_free (file_uri);
|
||||
}
|
||||
else if (g_str_has_prefix (uri, "stock://"))
|
||||
{
|
||||
GtkIconTheme* icon_theme = gtk_icon_theme_get_default ();
|
||||
const gchar* icon_name = &uri[8] ? &uri[8] : "";
|
||||
gint icon_size = 22;
|
||||
GtkIconInfo* info;
|
||||
|
||||
if (g_ascii_isalpha (icon_name[0]))
|
||||
icon_size = strstr (icon_name, "dialog") ? 48 : 22;
|
||||
else if (g_ascii_isdigit (icon_name[0]))
|
||||
{
|
||||
guint i = 0;
|
||||
while (icon_name[i])
|
||||
if (icon_name[i++] == '/')
|
||||
{
|
||||
gchar* size = g_strndup (icon_name, i - 1);
|
||||
icon_size = atoi (size);
|
||||
g_free (size);
|
||||
icon_name = &icon_name[i];
|
||||
}
|
||||
}
|
||||
|
||||
if ((info = gtk_icon_theme_lookup_icon (icon_theme, icon_name, icon_size, 0)))
|
||||
{
|
||||
const gchar* filename = gtk_icon_info_get_filename (info);
|
||||
if (filename)
|
||||
{
|
||||
gchar* file_uri = g_filename_to_uri (filename, NULL, NULL);
|
||||
webkit_network_request_set_uri (request, file_uri);
|
||||
g_free (file_uri);
|
||||
}
|
||||
gtk_icon_info_free (info);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static gboolean
|
||||
webkit_web_view_load_error_cb (WebKitWebView* web_view,
|
||||
WebKitWebFrame* web_frame,
|
||||
|
@ -832,18 +892,25 @@ webkit_web_view_load_error_cb (WebKitWebView* web_view,
|
|||
g_free (template_file);
|
||||
if (g_file_get_contents (path, &template, NULL, NULL))
|
||||
{
|
||||
#if !WEBKIT_CHECK_VERSION (1, 1, 14)
|
||||
SoupServer* res_server;
|
||||
guint port;
|
||||
#endif
|
||||
gchar* res_root;
|
||||
gchar* stock_root;
|
||||
gchar* title;
|
||||
gchar* message;
|
||||
gchar* result;
|
||||
|
||||
#if WEBKIT_CHECK_VERSION (1, 1, 14)
|
||||
res_root = g_strdup ("res:/");
|
||||
stock_root = g_strdup ("stock:/");
|
||||
#else
|
||||
res_server = sokoke_get_res_server ();
|
||||
port = soup_server_get_port (res_server);
|
||||
res_root = g_strdup_printf ("http://localhost:%d/res", port);
|
||||
stock_root = g_strdup_printf ("http://localhost:%d/stock", port);
|
||||
#endif
|
||||
|
||||
title = g_strdup_printf (_("Error - %s"), uri);
|
||||
message = g_strdup_printf (_("The page '%s' couldn't be loaded."), uri);
|
||||
|
@ -952,13 +1019,13 @@ webkit_web_view_load_finished_cb (WebKitWebView* web_view,
|
|||
URI1|title1,URI2|title2
|
||||
FIXME: Ensure separators contained in the string can't break it */
|
||||
gchar* value = sokoke_js_script_eval (js_context,
|
||||
"function links (l) { var f = new Array (); for (i in l) "
|
||||
"(function (l) { var f = new Array (); for (i in l) "
|
||||
"{ var t = l[i].type; var r = l[i].rel; "
|
||||
"if (t && (t.indexOf ('rss') != -1 || t.indexOf ('atom') != -1)) "
|
||||
"f.push (l[i].href + '|' + l[i].title);"
|
||||
"else if (r && r.indexOf ('icon') != -1) f.push (l[i].href); } "
|
||||
"return f; }"
|
||||
"links (document.getElementsByTagName ('link'))", NULL);
|
||||
"return f; })("
|
||||
"document.getElementsByTagName ('link'));", NULL);
|
||||
gchar** items = g_strsplit (value, ",", 0);
|
||||
guint i = 0;
|
||||
gchar* default_uri = NULL;
|
||||
|
@ -1193,14 +1260,22 @@ gtk_widget_button_press_event_cb (WebKitWebView* web_view,
|
|||
clipboard = gtk_clipboard_get_for_display (
|
||||
gtk_widget_get_display (GTK_WIDGET (view)),
|
||||
GDK_SELECTION_PRIMARY);
|
||||
uri = gtk_clipboard_wait_for_text (clipboard);
|
||||
if (uri && strchr (uri, '.'))
|
||||
if ((uri = gtk_clipboard_wait_for_text (clipboard)))
|
||||
{
|
||||
KatzeArray* empty_array = katze_array_new (KATZE_TYPE_ITEM);
|
||||
guint i = 0;
|
||||
while (uri[i++] != '\0')
|
||||
if (uri[i] == '\n' || uri[i] == '\r')
|
||||
uri[i] = ' ';
|
||||
new_uri = sokoke_magic_uri (g_strstrip (uri), NULL);
|
||||
new_uri = sokoke_magic_uri (g_strstrip (uri), empty_array);
|
||||
g_object_unref (empty_array);
|
||||
if (!new_uri)
|
||||
{
|
||||
gchar* search;
|
||||
g_object_get (view->settings, "location-entry-search",
|
||||
&search, NULL);
|
||||
new_uri = sokoke_search_uri (search, uri);
|
||||
}
|
||||
if (event->state & GDK_CONTROL_MASK)
|
||||
{
|
||||
background = view->open_tabs_in_the_background;
|
||||
|
@ -1294,6 +1369,19 @@ gtk_widget_scroll_event_cb (WebKitWebView* web_view,
|
|||
}
|
||||
|
||||
#if WEBKIT_CHECK_VERSION (1, 1, 15)
|
||||
static void
|
||||
midori_web_view_set_clipboard (GtkWidget* widget,
|
||||
const gchar* text)
|
||||
{
|
||||
GdkDisplay* display = gtk_widget_get_display (widget);
|
||||
GtkClipboard* clipboard;
|
||||
|
||||
clipboard = gtk_clipboard_get_for_display (display, GDK_SELECTION_CLIPBOARD);
|
||||
gtk_clipboard_set_text (clipboard, text, -1);
|
||||
clipboard = gtk_clipboard_get_for_display (display, GDK_SELECTION_PRIMARY);
|
||||
gtk_clipboard_set_text (clipboard, text, -1);
|
||||
}
|
||||
|
||||
static void
|
||||
midori_web_view_menu_open_activate_cb (GtkWidget* widget,
|
||||
MidoriView* view)
|
||||
|
@ -1312,10 +1400,7 @@ static void
|
|||
midori_web_view_menu_link_copy_activate_cb (GtkWidget* widget,
|
||||
MidoriView* view)
|
||||
{
|
||||
GdkDisplay* display = gtk_widget_get_display (widget);
|
||||
GtkClipboard* clipboard = gtk_clipboard_get_for_display (display,
|
||||
GDK_SELECTION_CLIPBOARD);
|
||||
gtk_clipboard_set_text (clipboard, view->link_uri, -1);
|
||||
midori_web_view_set_clipboard (widget, view->link_uri);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -1356,11 +1441,8 @@ static void
|
|||
midori_web_view_menu_image_copy_activate_cb (GtkWidget* widget,
|
||||
MidoriView* view)
|
||||
{
|
||||
GdkDisplay* display = gtk_widget_get_display (widget);
|
||||
GtkClipboard* clipboard = gtk_clipboard_get_for_display (display,
|
||||
GDK_SELECTION_CLIPBOARD);
|
||||
gchar* uri = katze_object_get_string (view->hit_test, "image-uri");
|
||||
gtk_clipboard_set_text (clipboard, uri, -1);
|
||||
midori_web_view_set_clipboard (widget, uri);
|
||||
g_free (uri);
|
||||
}
|
||||
|
||||
|
@ -1385,11 +1467,8 @@ static void
|
|||
midori_web_view_menu_video_copy_activate_cb (GtkWidget* widget,
|
||||
MidoriView* view)
|
||||
{
|
||||
GdkDisplay* display = gtk_widget_get_display (widget);
|
||||
GtkClipboard* clipboard = gtk_clipboard_get_for_display (display,
|
||||
GDK_SELECTION_CLIPBOARD);
|
||||
gchar* uri = katze_object_get_string (view->hit_test, "media-uri");
|
||||
gtk_clipboard_set_text (clipboard, uri, -1);
|
||||
midori_web_view_set_clipboard (widget, uri);
|
||||
g_free (uri);
|
||||
}
|
||||
|
||||
|
@ -1415,7 +1494,7 @@ midori_web_view_menu_video_download_activate_cb (GtkWidget* widget,
|
|||
MidoriView* view)
|
||||
{
|
||||
gchar* uri = katze_object_get_string (view->hit_test, "media-uri");
|
||||
sokoke_spawn_program (view->download_manager, uri, TRUE);
|
||||
sokoke_spawn_program (view->download_manager, uri, FALSE);
|
||||
g_free (uri);
|
||||
}
|
||||
#endif
|
||||
|
@ -1447,6 +1526,16 @@ midori_web_view_menu_new_tab_activate_cb (GtkWidget* widget,
|
|||
}
|
||||
}
|
||||
|
||||
#if WEBKIT_CHECK_VERSION (1, 1, 15)
|
||||
static void
|
||||
midori_web_view_menu_background_tab_activate_cb (GtkWidget* widget,
|
||||
MidoriView* view)
|
||||
{
|
||||
g_signal_emit (view, signals[NEW_TAB], 0, view->link_uri,
|
||||
!view->open_tabs_in_the_background);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
midori_web_view_menu_search_web_activate_cb (GtkWidget* widget,
|
||||
MidoriView* view)
|
||||
|
@ -1473,10 +1562,7 @@ static void
|
|||
midori_web_view_menu_copy_activate_cb (GtkWidget* widget,
|
||||
MidoriView* view)
|
||||
{
|
||||
GdkDisplay* display = gtk_widget_get_display (widget);
|
||||
GtkClipboard* clipboard = gtk_clipboard_get_for_display (display,
|
||||
GDK_SELECTION_CLIPBOARD);
|
||||
gtk_clipboard_set_text (clipboard, view->selected_text, -1);
|
||||
midori_web_view_set_clipboard (widget, view->selected_text);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -1493,7 +1579,7 @@ static void
|
|||
midori_web_view_menu_download_activate_cb (GtkWidget* widget,
|
||||
MidoriView* view)
|
||||
{
|
||||
sokoke_spawn_program (view->download_manager, view->link_uri, TRUE);
|
||||
sokoke_spawn_program (view->download_manager, view->link_uri, FALSE);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -1655,6 +1741,11 @@ webkit_web_view_populate_popup_cb (WebKitWebView* web_view,
|
|||
midori_view_insert_menu_item (menu_shell, -1,
|
||||
_("Open Link in New _Tab"), STOCK_TAB_NEW,
|
||||
G_CALLBACK (midori_web_view_menu_new_tab_activate_cb), widget);
|
||||
midori_view_insert_menu_item (menu_shell, -1,
|
||||
view->open_tabs_in_the_background
|
||||
? _("Open Link in _Foreground Tab")
|
||||
: _("Open Link in _Background Tab"), STOCK_TAB_NEW,
|
||||
G_CALLBACK (midori_web_view_menu_background_tab_activate_cb), widget);
|
||||
midori_view_insert_menu_item (menu_shell, -1,
|
||||
_("Open Link in New _Window"), STOCK_WINDOW_NEW,
|
||||
G_CALLBACK (midori_web_view_menu_new_window_activate_cb), widget);
|
||||
|
@ -1767,11 +1858,18 @@ webkit_web_view_populate_popup_cb (WebKitWebView* web_view,
|
|||
while ((item = katze_array_get_nth_item (search_engines, i++)))
|
||||
{
|
||||
GdkPixbuf* pixbuf;
|
||||
const gchar* icon_name;
|
||||
|
||||
menuitem = gtk_image_menu_item_new_with_mnemonic (katze_item_get_name (item));
|
||||
pixbuf = midori_search_action_get_icon (view->net, item,
|
||||
GTK_WIDGET (web_view));
|
||||
pixbuf = midori_search_action_get_icon (item,
|
||||
GTK_WIDGET (web_view), &icon_name);
|
||||
if (pixbuf)
|
||||
{
|
||||
icon = gtk_image_new_from_pixbuf (pixbuf);
|
||||
g_object_unref (pixbuf);
|
||||
}
|
||||
else
|
||||
icon = gtk_image_new_from_icon_name (icon_name, GTK_ICON_SIZE_MENU);
|
||||
gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menuitem), icon);
|
||||
#if GTK_CHECK_VERSION (2, 16, 0)
|
||||
gtk_image_menu_item_set_always_show_image (
|
||||
|
@ -1807,7 +1905,7 @@ webkit_web_view_populate_popup_cb (WebKitWebView* web_view,
|
|||
|
||||
g_strstrip (view->selected_text);
|
||||
if (view->selected_text && !strchr (view->selected_text, ' ')
|
||||
&& strchr (view->selected_text, '.'))
|
||||
&& (strchr (view->selected_text, '.') || g_strstr_len (view->selected_text, 9, "://")))
|
||||
{
|
||||
if (strchr (view->selected_text, '@'))
|
||||
{
|
||||
|
@ -1894,12 +1992,14 @@ webkit_web_view_populate_popup_cb (WebKitWebView* web_view,
|
|||
gtk_menu_shell_append (menu_shell, menuitem);
|
||||
}
|
||||
|
||||
#if !HAVE_HILDON
|
||||
menuitem = sokoke_action_create_popup_menu_item (
|
||||
gtk_action_group_get_action (actions, "ZoomIn"));
|
||||
gtk_menu_shell_append (menu_shell, menuitem);
|
||||
menuitem = sokoke_action_create_popup_menu_item (
|
||||
gtk_action_group_get_action (actions, "ZoomOut"));
|
||||
gtk_menu_shell_append (menu_shell, menuitem);
|
||||
#endif
|
||||
|
||||
menuitem = sokoke_action_create_popup_menu_item (
|
||||
gtk_action_group_get_action (actions, "Encoding"));
|
||||
|
@ -1911,6 +2011,7 @@ webkit_web_view_populate_popup_cb (WebKitWebView* web_view,
|
|||
{ "EncodingAutomatic" },
|
||||
{ "EncodingChinese" },
|
||||
{ "EncodingJapanese" },
|
||||
{ "EncodingKorean" },
|
||||
{ "EncodingRussian" },
|
||||
{ "EncodingUnicode" },
|
||||
{ "EncodingWestern" },
|
||||
|
@ -1928,7 +2029,18 @@ webkit_web_view_populate_popup_cb (WebKitWebView* web_view,
|
|||
}
|
||||
}
|
||||
|
||||
#if !HAVE_HILDON
|
||||
#if HAVE_HILDON
|
||||
gtk_menu_shell_append (menu_shell, gtk_separator_menu_item_new ());
|
||||
menuitem = sokoke_action_create_popup_menu_item (
|
||||
gtk_action_group_get_action (actions, "CompactAdd"));
|
||||
gtk_menu_shell_append (menu_shell, menuitem);
|
||||
menuitem = sokoke_action_create_popup_menu_item (
|
||||
gtk_action_group_get_action (actions, "Fullscreen"));
|
||||
gtk_menu_shell_append (menu_shell, menuitem);
|
||||
menuitem = sokoke_action_create_popup_menu_item (
|
||||
gtk_action_group_get_action (actions, "PrivateBrowsing"));
|
||||
gtk_menu_shell_append (menu_shell, menuitem);
|
||||
#else
|
||||
gtk_menu_shell_append (menu_shell, gtk_separator_menu_item_new ());
|
||||
menuitem = sokoke_action_create_popup_menu_item (
|
||||
gtk_action_group_get_action (actions, "BookmarkAdd"));
|
||||
|
@ -1943,6 +2055,7 @@ webkit_web_view_populate_popup_cb (WebKitWebView* web_view,
|
|||
menuitem = sokoke_action_create_popup_menu_item (
|
||||
gtk_action_group_get_action (actions, "AddDesktopShortcut"));
|
||||
gtk_menu_shell_append (menu_shell, menuitem);
|
||||
gtk_widget_set_no_show_all (menuitem, TRUE);
|
||||
#endif
|
||||
|
||||
menuitem = sokoke_action_create_popup_menu_item (
|
||||
|
@ -1994,6 +2107,12 @@ webkit_web_view_web_view_ready_cb (GtkWidget* web_view,
|
|||
{
|
||||
GtkWidget* new_view = gtk_widget_get_parent (web_view);
|
||||
MidoriNewView where = MIDORI_NEW_VIEW_TAB;
|
||||
|
||||
/* FIXME: Open windows opened by scripts in tabs if they otherwise
|
||||
would be replacing the page the user opened. */
|
||||
if (view->open_new_pages_in == MIDORI_NEW_PAGE_CURRENT)
|
||||
return TRUE;
|
||||
|
||||
if (view->open_new_pages_in == MIDORI_NEW_PAGE_TAB)
|
||||
{
|
||||
if (view->open_tabs_in_the_background)
|
||||
|
@ -2003,12 +2122,6 @@ webkit_web_view_web_view_ready_cb (GtkWidget* web_view,
|
|||
where = MIDORI_NEW_VIEW_WINDOW;
|
||||
|
||||
gtk_widget_show (new_view);
|
||||
if (view->open_new_pages_in == MIDORI_NEW_PAGE_CURRENT)
|
||||
{
|
||||
g_debug ("Opening all pages in current tab not implemented");
|
||||
g_signal_emit (view, signals[NEW_VIEW], 0, new_view, where);
|
||||
}
|
||||
else
|
||||
g_signal_emit (view, signals[NEW_VIEW], 0, new_view, where);
|
||||
|
||||
return TRUE;
|
||||
|
@ -2019,14 +2132,21 @@ webkit_web_view_create_web_view_cb (GtkWidget* web_view,
|
|||
WebKitWebFrame* web_frame,
|
||||
MidoriView* view)
|
||||
{
|
||||
GtkWidget* new_view = g_object_new (MIDORI_TYPE_VIEW,
|
||||
MidoriView* new_view;
|
||||
|
||||
if (view->open_new_pages_in == MIDORI_NEW_PAGE_CURRENT)
|
||||
new_view = view;
|
||||
else
|
||||
{
|
||||
new_view = g_object_new (MIDORI_TYPE_VIEW,
|
||||
"net", view->net,
|
||||
"settings", view->settings,
|
||||
NULL);
|
||||
midori_view_construct_web_view (MIDORI_VIEW (new_view));
|
||||
g_signal_connect (MIDORI_VIEW (new_view)->web_view, "web-view-ready",
|
||||
midori_view_construct_web_view (new_view);
|
||||
g_signal_connect (new_view->web_view, "web-view-ready",
|
||||
G_CALLBACK (webkit_web_view_web_view_ready_cb), view);
|
||||
return MIDORI_VIEW (new_view)->web_view;
|
||||
}
|
||||
return new_view->web_view;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
|
@ -2073,6 +2193,12 @@ webkit_web_view_mime_type_decision_cb (GtkWidget* web_view,
|
|||
#else
|
||||
content_type = g_strdup (mime_type);
|
||||
#endif
|
||||
if (!content_type)
|
||||
#ifdef G_OS_WIN32
|
||||
content_type = g_content_type_get_mime_type ("*");
|
||||
#else
|
||||
content_type = g_strdup ("application/octet-stream");
|
||||
#endif
|
||||
description = g_content_type_get_description (content_type);
|
||||
#if GTK_CHECK_VERSION (2, 14, 0)
|
||||
icon = g_content_type_get_icon (content_type);
|
||||
|
@ -2673,6 +2799,10 @@ midori_view_construct_web_view (MidoriView* view)
|
|||
g_object_connect (view->web_view,
|
||||
"signal::navigation-policy-decision-requested",
|
||||
midori_view_web_view_navigation_decision_cb, view,
|
||||
#if WEBKIT_CHECK_VERSION (1, 1, 14)
|
||||
"signal::resource-request-starting",
|
||||
midori_view_web_view_resource_request_cb, view,
|
||||
#endif
|
||||
"signal::load-started",
|
||||
webkit_web_view_load_started_cb, view,
|
||||
"signal::load-committed",
|
||||
|
@ -2725,7 +2855,7 @@ midori_view_construct_web_view (MidoriView* view)
|
|||
midori_view_web_view_print_requested_cb, view,
|
||||
#endif
|
||||
#if WEBKIT_CHECK_VERSION (1, 1, 6)
|
||||
"signal::load-error",
|
||||
"signal-after::load-error",
|
||||
webkit_web_view_load_error_cb, view,
|
||||
#endif
|
||||
NULL);
|
||||
|
@ -2777,8 +2907,10 @@ midori_view_set_uri (MidoriView* view,
|
|||
|
||||
if (view->speed_dial_in_new_tabs && !g_strcmp0 (uri, ""))
|
||||
{
|
||||
#if !WEBKIT_CHECK_VERSION (1, 1, 14)
|
||||
SoupServer* res_server;
|
||||
guint port;
|
||||
#endif
|
||||
gchar* res_root;
|
||||
gchar* speed_dial_head;
|
||||
gchar* speed_dial_body;
|
||||
|
@ -2792,10 +2924,15 @@ midori_view_set_uri (MidoriView* view,
|
|||
if (G_UNLIKELY (!speed_dial_head))
|
||||
speed_dial_head = g_strdup ("");
|
||||
|
||||
#if WEBKIT_CHECK_VERSION (1, 1, 14)
|
||||
res_root = g_strdup ("res:/");
|
||||
stock_root = g_strdup ("stock:/");
|
||||
#else
|
||||
res_server = sokoke_get_res_server ();
|
||||
port = soup_server_get_port (res_server);
|
||||
res_root = g_strdup_printf ("http://localhost:%d/res", port);
|
||||
stock_root = g_strdup_printf ("http://localhost:%d/stock", port);
|
||||
#endif
|
||||
body_fname = g_build_filename (sokoke_set_config_dir (NULL),
|
||||
"speeddial.json", NULL);
|
||||
|
||||
|
@ -2894,7 +3031,9 @@ midori_view_set_uri (MidoriView* view,
|
|||
{
|
||||
midori_view_execute_script (view, &uri[11], NULL);
|
||||
}
|
||||
else if (g_str_has_prefix (uri, "mailto:"))
|
||||
else if (g_str_has_prefix (uri, "mailto:")
|
||||
|| g_str_has_prefix (uri, "tel:")
|
||||
|| g_str_has_prefix (uri, "callto:"))
|
||||
{
|
||||
sokoke_show_uri (NULL, uri, GDK_CURRENT_TIME, NULL);
|
||||
}
|
||||
|
@ -3138,7 +3277,7 @@ midori_view_get_proxy_menu_item (MidoriView* view)
|
|||
if (!view->menu_item)
|
||||
{
|
||||
title = midori_view_get_display_title (view);
|
||||
view->menu_item = sokoke_image_menu_item_new_ellipsized (title);
|
||||
view->menu_item = katze_image_menu_item_new_ellipsized (title);
|
||||
gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (view->menu_item),
|
||||
gtk_image_new_from_pixbuf (view->icon));
|
||||
|
||||
|
@ -3149,13 +3288,6 @@ midori_view_get_proxy_menu_item (MidoriView* view)
|
|||
return view->menu_item;
|
||||
}
|
||||
|
||||
static void
|
||||
midori_view_tab_label_menu_new_tab_cb (GtkWidget* menuitem,
|
||||
MidoriView* view)
|
||||
{
|
||||
g_signal_emit (view, signals[NEW_TAB], 0, "", FALSE);
|
||||
}
|
||||
|
||||
static void
|
||||
midori_view_tab_label_menu_open_cb (GtkWidget* menuitem,
|
||||
GtkWidget* view)
|
||||
|
@ -3213,16 +3345,23 @@ midori_view_tab_label_menu_close_cb (GtkWidget* menuitem,
|
|||
GtkWidget*
|
||||
midori_view_get_tab_menu (MidoriView* view)
|
||||
{
|
||||
MidoriBrowser* browser;
|
||||
GtkActionGroup* actions;
|
||||
GtkWidget* menu;
|
||||
GtkWidget* menuitem;
|
||||
|
||||
g_return_val_if_fail (MIDORI_IS_VIEW (view), NULL);
|
||||
|
||||
browser = midori_browser_get_for_widget (GTK_WIDGET (view));
|
||||
actions = midori_browser_get_action_group (browser);
|
||||
|
||||
menu = gtk_menu_new ();
|
||||
menuitem = gtk_menu_item_new_with_mnemonic (_("New _Tab"));
|
||||
menuitem = sokoke_action_create_popup_menu_item (
|
||||
gtk_action_group_get_action (actions, "TabNew"));
|
||||
gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
|
||||
menuitem = sokoke_action_create_popup_menu_item (
|
||||
gtk_action_group_get_action (actions, "UndoTabClose"));
|
||||
gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
|
||||
g_signal_connect (menuitem, "activate",
|
||||
G_CALLBACK (midori_view_tab_label_menu_new_tab_cb), view);
|
||||
menuitem = gtk_separator_menu_item_new ();
|
||||
gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
|
||||
menuitem = gtk_image_menu_item_new_from_stock (GTK_STOCK_OPEN, NULL);
|
||||
|
@ -3270,7 +3409,7 @@ midori_view_tab_label_button_release_event (GtkWidget* tab_label,
|
|||
GtkWidget* menu = midori_view_get_tab_menu (MIDORI_VIEW (widget));
|
||||
|
||||
katze_widget_popup (widget, GTK_MENU (menu),
|
||||
event, SOKOKE_MENU_POSITION_CURSOR);
|
||||
event, KATZE_MENU_POSITION_CURSOR);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -3677,8 +3816,6 @@ can_do (find)
|
|||
* @from_cache: whether to allow caching
|
||||
*
|
||||
* Reloads the view.
|
||||
*
|
||||
* Note: The @from_cache value is currently ignored.
|
||||
**/
|
||||
void
|
||||
midori_view_reload (MidoriView* view,
|
||||
|
@ -3981,7 +4118,22 @@ midori_view_execute_script (MidoriView* view,
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
/* For now this is private API */
|
||||
/**
|
||||
* midori_view_get_snapshot
|
||||
* @view: a #MidoriView
|
||||
* @width: the desired width
|
||||
* @height: the desired height
|
||||
*
|
||||
* Take a snapshot of the view at the given dimensions. The
|
||||
* view has to be mapped on the screen.
|
||||
*
|
||||
* If width and height are negative, the resulting
|
||||
* image is going to be optimized for speed.
|
||||
*
|
||||
* Returns: a newly allocated #GdkPixbuf
|
||||
*
|
||||
* Since: 0.2.1
|
||||
**/
|
||||
GdkPixbuf*
|
||||
midori_view_get_snapshot (MidoriView* view,
|
||||
gint width,
|
||||
|
|
|
@ -195,6 +195,11 @@ midori_view_execute_script (MidoriView* view,
|
|||
const gchar* script,
|
||||
gchar** exception);
|
||||
|
||||
GdkPixbuf*
|
||||
midori_view_get_snapshot (MidoriView* view,
|
||||
gint width,
|
||||
gint height);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __MIDORI_VIEW_H__ */
|
||||
|
|
|
@ -50,6 +50,7 @@ struct _MidoriWebSettings
|
|||
gboolean compact_sidepanel;
|
||||
gboolean show_panel_controls;
|
||||
gboolean right_align_sidepanel;
|
||||
gboolean open_panels_in_windows;
|
||||
|
||||
MidoriStartup load_on_startup;
|
||||
gchar* homepage;
|
||||
|
@ -82,14 +83,12 @@ struct _MidoriWebSettings
|
|||
|
||||
gboolean remember_last_visited_pages;
|
||||
gint maximum_history_age;
|
||||
gboolean remember_last_form_inputs;
|
||||
gboolean remember_last_downloaded_files;
|
||||
|
||||
gchar* http_proxy;
|
||||
gboolean auto_detect_proxy;
|
||||
MidoriIdentity identify_as;
|
||||
gchar* ident_string;
|
||||
gint cache_size;
|
||||
|
||||
gint clear_private_data;
|
||||
};
|
||||
|
@ -127,6 +126,7 @@ enum
|
|||
PROP_COMPACT_SIDEPANEL,
|
||||
PROP_SHOW_PANEL_CONTROLS,
|
||||
PROP_RIGHT_ALIGN_SIDEPANEL,
|
||||
PROP_OPEN_PANELS_IN_WINDOWS,
|
||||
|
||||
PROP_LOAD_ON_STARTUP,
|
||||
PROP_HOMEPAGE,
|
||||
|
@ -150,6 +150,9 @@ enum
|
|||
PROP_OPEN_TABS_NEXT_TO_CURRENT,
|
||||
PROP_OPEN_POPUPS_IN_TABS,
|
||||
|
||||
PROP_AUTO_LOAD_IMAGES,
|
||||
PROP_ENABLE_SCRIPTS,
|
||||
PROP_ENABLE_PLUGINS,
|
||||
PROP_ZOOM_TEXT_AND_IMAGES,
|
||||
PROP_FIND_WHILE_TYPING,
|
||||
PROP_KINETIC_SCROLLING,
|
||||
|
@ -159,14 +162,12 @@ enum
|
|||
|
||||
PROP_REMEMBER_LAST_VISITED_PAGES,
|
||||
PROP_MAXIMUM_HISTORY_AGE,
|
||||
PROP_REMEMBER_LAST_FORM_INPUTS,
|
||||
PROP_REMEMBER_LAST_DOWNLOADED_FILES,
|
||||
|
||||
PROP_HTTP_PROXY,
|
||||
PROP_AUTO_DETECT_PROXY,
|
||||
PROP_IDENTIFY_AS,
|
||||
PROP_IDENT_STRING,
|
||||
PROP_CACHE_SIZE,
|
||||
|
||||
PROP_CLEAR_PRIVATE_DATA
|
||||
};
|
||||
|
@ -215,6 +216,7 @@ midori_preferred_encoding_get_type (void)
|
|||
static const GEnumValue values[] = {
|
||||
{ MIDORI_ENCODING_CHINESE, "MIDORI_ENCODING_CHINESE", N_("Chinese (BIG5)") },
|
||||
{ MIDORI_ENCODING_JAPANESE, "MIDORI_ENCODING_JAPANESE", N_("Japanese (SHIFT_JIS)") },
|
||||
{ MIDORI_ENCODING_KOREAN, "MIDORI_ENCODING_KOREAN", N_("Korean (EUC-KR)") },
|
||||
{ MIDORI_ENCODING_RUSSIAN, "MIDORI_ENCODING_RUSSIAN", N_("Russian (KOI8-R)") },
|
||||
{ MIDORI_ENCODING_UNICODE, "MIDORI_ENCODING_UNICODE", N_("Unicode (UTF-8)") },
|
||||
{ MIDORI_ENCODING_WESTERN, "MIDORI_ENCODING_WESTERN", N_("Western (ISO-8859-1)") },
|
||||
|
@ -252,6 +254,7 @@ midori_toolbar_style_get_type (void)
|
|||
static const GEnumValue values[] = {
|
||||
{ MIDORI_TOOLBAR_DEFAULT, "MIDORI_TOOLBAR_DEFAULT", N_("Default") },
|
||||
{ MIDORI_TOOLBAR_ICONS, "MIDORI_TOOLBAR_ICONS", N_("Icons") },
|
||||
{ MIDORI_TOOLBAR_SMALL_ICONS, "MIDORI_TOOLBAR_SMALL_ICONS", N_("Small icons") },
|
||||
{ MIDORI_TOOLBAR_TEXT, "MIDORI_TOOLBAR_TEXT", N_("Text") },
|
||||
{ MIDORI_TOOLBAR_BOTH, "MIDORI_TOOLBAR_BOTH", N_("Icons and text") },
|
||||
{ MIDORI_TOOLBAR_BOTH_HORIZ, "MIDORI_TOOLBAR_BOTH_HORIZ", N_("Text beside icons") },
|
||||
|
@ -320,7 +323,7 @@ midori_get_download_dir (void)
|
|||
const gchar* dir = g_get_user_special_dir (G_USER_DIRECTORY_DOWNLOAD);
|
||||
if (dir)
|
||||
{
|
||||
g_mkdir_with_parents (dir, 0700);
|
||||
katze_mkdir_with_parents (dir, 0700);
|
||||
return dir;
|
||||
}
|
||||
return g_get_home_dir ();
|
||||
|
@ -566,6 +569,22 @@ midori_web_settings_class_init (MidoriWebSettingsClass* class)
|
|||
FALSE,
|
||||
flags));
|
||||
|
||||
/**
|
||||
* MidoriWebSettings:open-panels-in-window:
|
||||
*
|
||||
* Whether to open panels in separate windows.
|
||||
*
|
||||
* Since: 0.2.2
|
||||
*/
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_OPEN_PANELS_IN_WINDOWS,
|
||||
g_param_spec_boolean (
|
||||
"open-panels-in-windows",
|
||||
_("Open panels in separate windows"),
|
||||
_("Whether to always open panels in separate windows"),
|
||||
FALSE,
|
||||
flags));
|
||||
|
||||
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_LOAD_ON_STARTUP,
|
||||
|
@ -803,6 +822,32 @@ midori_web_settings_class_init (MidoriWebSettingsClass* class)
|
|||
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
|
||||
|
||||
|
||||
/* Override properties to localize them for preference proxies */
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_AUTO_LOAD_IMAGES,
|
||||
g_param_spec_boolean (
|
||||
"auto-load-images",
|
||||
_("Load images automatically"),
|
||||
_("Load and display images automatically"),
|
||||
TRUE,
|
||||
flags));
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_ENABLE_SCRIPTS,
|
||||
g_param_spec_boolean (
|
||||
"enable-scripts",
|
||||
_("Enable scripts"),
|
||||
_("Enable embedded scripting languages"),
|
||||
TRUE,
|
||||
flags));
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_ENABLE_PLUGINS,
|
||||
g_param_spec_boolean (
|
||||
"enable-plugins",
|
||||
_("Enable Netscape plugins"),
|
||||
_("Enable embedded Netscape plugin objects"),
|
||||
TRUE,
|
||||
flags));
|
||||
|
||||
/**
|
||||
* MidoriWebSettings:zoom-text-and-images:
|
||||
*
|
||||
|
@ -881,6 +926,13 @@ midori_web_settings_class_init (MidoriWebSettingsClass* class)
|
|||
|
||||
|
||||
|
||||
/**
|
||||
* MidoriWebSettings:remember-last-visited-pages:
|
||||
*
|
||||
* Whether the last visited pages are saved.
|
||||
*
|
||||
* Deprecated: 0.2.2
|
||||
*/
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_REMEMBER_LAST_VISITED_PAGES,
|
||||
g_param_spec_boolean (
|
||||
|
@ -899,15 +951,6 @@ midori_web_settings_class_init (MidoriWebSettingsClass* class)
|
|||
0, G_MAXINT, 30,
|
||||
flags));
|
||||
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_REMEMBER_LAST_FORM_INPUTS,
|
||||
g_param_spec_boolean (
|
||||
"remember-last-form-inputs",
|
||||
_("Remember last form inputs"),
|
||||
_("Whether the last form inputs are saved"),
|
||||
TRUE,
|
||||
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
|
||||
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_REMEMBER_LAST_DOWNLOADED_FILES,
|
||||
g_param_spec_boolean (
|
||||
|
@ -978,15 +1021,6 @@ midori_web_settings_class_init (MidoriWebSettingsClass* class)
|
|||
NULL,
|
||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_CACHE_SIZE,
|
||||
g_param_spec_int (
|
||||
"cache-size",
|
||||
_("Cache size"),
|
||||
_("The allowed size of the cache"),
|
||||
0, G_MAXINT, 100,
|
||||
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
|
||||
|
||||
/**
|
||||
* MidoriWebSettings:clear-private-data:
|
||||
*
|
||||
|
@ -1021,6 +1055,8 @@ notify_default_encoding_cb (GObject* object,
|
|||
web_settings->preferred_encoding = MIDORI_ENCODING_CHINESE;
|
||||
else if (!strcmp (encoding, "SHIFT_JIS"))
|
||||
web_settings->preferred_encoding = MIDORI_ENCODING_JAPANESE;
|
||||
else if (!strcmp (encoding, "EUC-KR"))
|
||||
web_settings->preferred_encoding = MIDORI_ENCODING_KOREAN;
|
||||
else if (!strcmp (encoding, "KOI8-R"))
|
||||
web_settings->preferred_encoding = MIDORI_ENCODING_RUSSIAN;
|
||||
else if (!strcmp (encoding, "UTF-8"))
|
||||
|
@ -1041,7 +1077,6 @@ midori_web_settings_init (MidoriWebSettings* web_settings)
|
|||
web_settings->http_proxy = NULL;
|
||||
web_settings->show_panel_controls = TRUE;
|
||||
web_settings->open_popups_in_tabs = TRUE;
|
||||
web_settings->remember_last_form_inputs = TRUE;
|
||||
web_settings->remember_last_downloaded_files = TRUE;
|
||||
web_settings->kinetic_scrolling = TRUE;
|
||||
web_settings->auto_detect_proxy = TRUE;
|
||||
|
@ -1070,7 +1105,7 @@ midori_web_settings_finalize (GObject* object)
|
|||
G_OBJECT_CLASS (midori_web_settings_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
#if defined (G_OS_UNIX)
|
||||
#if defined (G_OS_UNIX) && !HAVE_OSX
|
||||
static gchar*
|
||||
get_sys_name (void)
|
||||
{
|
||||
|
@ -1233,6 +1268,9 @@ midori_web_settings_set_property (GObject* object,
|
|||
case PROP_RIGHT_ALIGN_SIDEPANEL:
|
||||
web_settings->right_align_sidepanel = g_value_get_boolean (value);
|
||||
break;
|
||||
case PROP_OPEN_PANELS_IN_WINDOWS:
|
||||
web_settings->open_panels_in_windows = g_value_get_boolean (value);
|
||||
break;
|
||||
|
||||
case PROP_LOAD_ON_STARTUP:
|
||||
web_settings->load_on_startup = g_value_get_enum (value);
|
||||
|
@ -1277,6 +1315,9 @@ midori_web_settings_set_property (GObject* object,
|
|||
case MIDORI_ENCODING_JAPANESE:
|
||||
g_object_set (object, "default-encoding", "SHIFT_JIS", NULL);
|
||||
break;
|
||||
case MIDORI_ENCODING_KOREAN:
|
||||
g_object_set (object, "default-encoding", "EUC-KR", NULL);
|
||||
break;
|
||||
case MIDORI_ENCODING_RUSSIAN:
|
||||
g_object_set (object, "default-encoding", "KOI8-R", NULL);
|
||||
break;
|
||||
|
@ -1316,6 +1357,18 @@ midori_web_settings_set_property (GObject* object,
|
|||
web_settings->open_popups_in_tabs = g_value_get_boolean (value);
|
||||
break;
|
||||
|
||||
case PROP_AUTO_LOAD_IMAGES:
|
||||
g_object_set (web_settings, "WebKitWebSettings::auto-load-images",
|
||||
g_value_get_boolean (value), NULL);
|
||||
break;
|
||||
case PROP_ENABLE_SCRIPTS:
|
||||
g_object_set (web_settings, "WebKitWebSettings::enable-scripts",
|
||||
g_value_get_boolean (value), NULL);
|
||||
break;
|
||||
case PROP_ENABLE_PLUGINS:
|
||||
g_object_set (web_settings, "WebKitWebSettings::enable-plugins",
|
||||
g_value_get_boolean (value), NULL);
|
||||
break;
|
||||
case PROP_ZOOM_TEXT_AND_IMAGES:
|
||||
web_settings->zoom_text_and_images = g_value_get_boolean (value);
|
||||
break;
|
||||
|
@ -1341,9 +1394,6 @@ midori_web_settings_set_property (GObject* object,
|
|||
case PROP_MAXIMUM_HISTORY_AGE:
|
||||
web_settings->maximum_history_age = g_value_get_int (value);
|
||||
break;
|
||||
case PROP_REMEMBER_LAST_FORM_INPUTS:
|
||||
web_settings->remember_last_form_inputs = g_value_get_boolean (value);
|
||||
break;
|
||||
case PROP_REMEMBER_LAST_DOWNLOADED_FILES:
|
||||
web_settings->remember_last_downloaded_files = g_value_get_boolean (value);
|
||||
break;
|
||||
|
@ -1375,9 +1425,6 @@ midori_web_settings_set_property (GObject* object,
|
|||
#endif
|
||||
}
|
||||
break;
|
||||
case PROP_CACHE_SIZE:
|
||||
web_settings->cache_size = g_value_get_int (value);
|
||||
break;
|
||||
case PROP_CLEAR_PRIVATE_DATA:
|
||||
web_settings->clear_private_data = g_value_get_int (value);
|
||||
break;
|
||||
|
@ -1459,6 +1506,9 @@ midori_web_settings_get_property (GObject* object,
|
|||
case PROP_RIGHT_ALIGN_SIDEPANEL:
|
||||
g_value_set_boolean (value, web_settings->right_align_sidepanel);
|
||||
break;
|
||||
case PROP_OPEN_PANELS_IN_WINDOWS:
|
||||
g_value_set_boolean (value, web_settings->open_panels_in_windows);
|
||||
break;
|
||||
|
||||
case PROP_LOAD_ON_STARTUP:
|
||||
g_value_set_enum (value, web_settings->load_on_startup);
|
||||
|
@ -1522,6 +1572,18 @@ midori_web_settings_get_property (GObject* object,
|
|||
g_value_set_boolean (value, web_settings->open_popups_in_tabs);
|
||||
break;
|
||||
|
||||
case PROP_AUTO_LOAD_IMAGES:
|
||||
g_value_set_boolean (value, katze_object_get_boolean (web_settings,
|
||||
"WebKitWebSettings::auto-load-images"));
|
||||
break;
|
||||
case PROP_ENABLE_SCRIPTS:
|
||||
g_value_set_boolean (value, katze_object_get_boolean (web_settings,
|
||||
"WebKitWebSettings::enable-scripts"));
|
||||
break;
|
||||
case PROP_ENABLE_PLUGINS:
|
||||
g_value_set_boolean (value, katze_object_get_boolean (web_settings,
|
||||
"WebKitWebSettings::enable-plugins"));
|
||||
break;
|
||||
case PROP_ZOOM_TEXT_AND_IMAGES:
|
||||
g_value_set_boolean (value, web_settings->zoom_text_and_images);
|
||||
break;
|
||||
|
@ -1547,9 +1609,6 @@ midori_web_settings_get_property (GObject* object,
|
|||
case PROP_MAXIMUM_HISTORY_AGE:
|
||||
g_value_set_int (value, web_settings->maximum_history_age);
|
||||
break;
|
||||
case PROP_REMEMBER_LAST_FORM_INPUTS:
|
||||
g_value_set_boolean (value, web_settings->remember_last_form_inputs);
|
||||
break;
|
||||
case PROP_REMEMBER_LAST_DOWNLOADED_FILES:
|
||||
g_value_set_boolean (value, web_settings->remember_last_downloaded_files);
|
||||
break;
|
||||
|
@ -1571,9 +1630,6 @@ midori_web_settings_get_property (GObject* object,
|
|||
}
|
||||
g_value_set_string (value, web_settings->ident_string);
|
||||
break;
|
||||
case PROP_CACHE_SIZE:
|
||||
g_value_set_int (value, web_settings->cache_size);
|
||||
break;
|
||||
case PROP_CLEAR_PRIVATE_DATA:
|
||||
g_value_set_int (value, web_settings->clear_private_data);
|
||||
break;
|
||||
|
|
|
@ -43,6 +43,7 @@ enum
|
|||
MIDORI_CLEAR_WEBSITE_ICONS = 8,
|
||||
MIDORI_CLEAR_TRASH = 16,
|
||||
MIDORI_CLEAR_ON_QUIT = 32,
|
||||
MIDORI_CLEAR_WEB_CACHE = 64,
|
||||
};
|
||||
|
||||
typedef enum
|
||||
|
@ -76,6 +77,7 @@ typedef enum
|
|||
{
|
||||
MIDORI_ENCODING_CHINESE,
|
||||
MIDORI_ENCODING_JAPANESE,
|
||||
MIDORI_ENCODING_KOREAN,
|
||||
MIDORI_ENCODING_RUSSIAN,
|
||||
MIDORI_ENCODING_UNICODE,
|
||||
MIDORI_ENCODING_WESTERN,
|
||||
|
@ -105,6 +107,7 @@ typedef enum
|
|||
{
|
||||
MIDORI_TOOLBAR_DEFAULT,
|
||||
MIDORI_TOOLBAR_ICONS,
|
||||
MIDORI_TOOLBAR_SMALL_ICONS,
|
||||
MIDORI_TOOLBAR_TEXT,
|
||||
MIDORI_TOOLBAR_BOTH,
|
||||
MIDORI_TOOLBAR_BOTH_HORIZ
|
||||
|
|
417
midori/sokoke.c
417
midori/sokoke.c
|
@ -11,14 +11,14 @@
|
|||
*/
|
||||
|
||||
#include "sokoke.h"
|
||||
#include "midori-stock.h"
|
||||
|
||||
#include "compat.h"
|
||||
|
||||
#if HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include "compat.h"
|
||||
#include "midori-stock.h"
|
||||
|
||||
#if HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
@ -40,6 +40,17 @@
|
|||
#include <idna.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_HILDON_FM
|
||||
#include <hildon/hildon-file-chooser-dialog.h>
|
||||
#endif
|
||||
|
||||
#if HAVE_HILDON
|
||||
#include <libosso.h>
|
||||
#include <hildon/hildon.h>
|
||||
#include <hildon-mime.h>
|
||||
#include <hildon-uri.h>
|
||||
#endif
|
||||
|
||||
static gchar*
|
||||
sokoke_js_string_utf8 (JSStringRef js_string)
|
||||
{
|
||||
|
@ -73,6 +84,7 @@ sokoke_js_script_eval (JSContextRef js_context,
|
|||
{
|
||||
JSStringRef js_message = JSValueToStringCopy (js_context,
|
||||
js_exception, NULL);
|
||||
if (exception)
|
||||
*exception = sokoke_js_string_utf8 (js_message);
|
||||
JSStringRelease (js_message);
|
||||
js_value = JSValueMakeNull (js_context);
|
||||
|
@ -85,17 +97,106 @@ sokoke_js_script_eval (JSContextRef js_context,
|
|||
return value;
|
||||
}
|
||||
|
||||
static void
|
||||
error_dialog (const gchar* short_message,
|
||||
void
|
||||
sokoke_message_dialog (GtkMessageType message_type,
|
||||
const gchar* short_message,
|
||||
const gchar* detailed_message)
|
||||
{
|
||||
GtkWidget* dialog = gtk_message_dialog_new (
|
||||
NULL, 0, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, "%s", short_message);
|
||||
NULL, 0, message_type,
|
||||
#if HAVE_HILDON
|
||||
GTK_BUTTONS_NONE,
|
||||
#else
|
||||
GTK_BUTTONS_OK,
|
||||
#endif
|
||||
"%s", short_message);
|
||||
gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
|
||||
"%s", detailed_message);
|
||||
gtk_widget_show (dialog);
|
||||
g_signal_connect_swapped (dialog, "response",
|
||||
G_CALLBACK (gtk_widget_destroy), dialog);
|
||||
gtk_widget_show (dialog);
|
||||
}
|
||||
|
||||
/**
|
||||
* sokoke_show_uri_with_mime_type:
|
||||
* @screen: a #GdkScreen, or %NULL
|
||||
* @uri: the URI to show
|
||||
* @mime_type: a MIME type
|
||||
* @timestamp: the timestamp of the event
|
||||
* @error: the location of a #GError, or %NULL
|
||||
*
|
||||
* Shows the specified URI with an appropriate application,
|
||||
* as though it had the specified MIME type.
|
||||
*
|
||||
* On Maemo, hildon_mime_open_file_with_mime_type() is used.
|
||||
*
|
||||
* See also: sokoke_show_uri().
|
||||
*
|
||||
* Return value: %TRUE on success, %FALSE if an error occurred
|
||||
**/
|
||||
gboolean
|
||||
sokoke_show_uri_with_mime_type (GdkScreen* screen,
|
||||
const gchar* uri,
|
||||
const gchar* mime_type,
|
||||
guint32 timestamp,
|
||||
GError** error)
|
||||
{
|
||||
gboolean success;
|
||||
#if HAVE_HILDON
|
||||
osso_context_t* osso;
|
||||
DBusConnection* dbus;
|
||||
|
||||
osso = osso_initialize (PACKAGE_NAME, PACKAGE_VERSION, FALSE, NULL);
|
||||
if (!osso)
|
||||
{
|
||||
g_print ("Failed to initialize libosso\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
dbus = (DBusConnection *) osso_get_dbus_connection (osso);
|
||||
if (!dbus)
|
||||
{
|
||||
osso_deinitialize (osso);
|
||||
g_print ("Failed to get dbus connection from osso context\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
success = (hildon_mime_open_file_with_mime_type (dbus,
|
||||
uri, mime_type) == 1);
|
||||
osso_deinitialize (osso);
|
||||
#else
|
||||
GFile* file = g_file_new_for_uri (uri);
|
||||
gchar* content_type;
|
||||
GAppInfo* app_info;
|
||||
GList* files;
|
||||
gpointer context;
|
||||
|
||||
#if GLIB_CHECK_VERSION (2, 18, 0)
|
||||
content_type = g_content_type_from_mime_type (mime_type);
|
||||
#else
|
||||
content_type = g_strdup (mime_type);
|
||||
#endif
|
||||
|
||||
app_info = g_app_info_get_default_for_type (content_type,
|
||||
!g_str_has_prefix (uri, "file://"));
|
||||
g_free (content_type);
|
||||
files = g_list_prepend (NULL, file);
|
||||
#if GTK_CHECK_VERSION (2, 14, 0)
|
||||
context = gdk_app_launch_context_new ();
|
||||
gdk_app_launch_context_set_screen (context, screen);
|
||||
gdk_app_launch_context_set_timestamp (context, timestamp);
|
||||
#else
|
||||
context = g_app_launch_context_new ();
|
||||
#endif
|
||||
|
||||
success = g_app_info_launch (app_info, files, context, error);
|
||||
|
||||
g_object_unref (app_info);
|
||||
g_list_free (files);
|
||||
g_object_unref (file);
|
||||
#endif
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -109,6 +210,8 @@ error_dialog (const gchar* short_message,
|
|||
* supports xdg-open, exo-open and gnome-open as fallbacks if
|
||||
* GIO doesn't do the trick.
|
||||
*
|
||||
* On Maemo, hildon_uri_open() is used.
|
||||
*
|
||||
* Return value: %TRUE on success, %FALSE if an error occurred
|
||||
**/
|
||||
gboolean
|
||||
|
@ -117,6 +220,11 @@ sokoke_show_uri (GdkScreen* screen,
|
|||
guint32 timestamp,
|
||||
GError** error)
|
||||
{
|
||||
#if HAVE_HILDON
|
||||
HildonURIAction* action = hildon_uri_get_default_action_by_uri (uri, NULL);
|
||||
return hildon_uri_open (uri, action, error);
|
||||
#else
|
||||
|
||||
const gchar* fallbacks [] = { "xdg-open", "exo-open", "gnome-open" };
|
||||
gsize i;
|
||||
|
||||
|
@ -139,49 +247,113 @@ sokoke_show_uri (GdkScreen* screen,
|
|||
}
|
||||
|
||||
return FALSE;
|
||||
#endif
|
||||
}
|
||||
|
||||
gboolean
|
||||
sokoke_spawn_program (const gchar* command,
|
||||
const gchar* argument,
|
||||
gboolean quote)
|
||||
gboolean filename)
|
||||
{
|
||||
gchar* argument_escaped;
|
||||
gchar* command_ready;
|
||||
gchar** argv;
|
||||
GError* error;
|
||||
|
||||
g_return_val_if_fail (command != NULL, FALSE);
|
||||
g_return_val_if_fail (argument != NULL, FALSE);
|
||||
|
||||
argument_escaped = quote ? g_shell_quote (argument) : g_strdup (argument);
|
||||
if (strstr (command, "%s"))
|
||||
command_ready = g_strdup_printf (command, argument_escaped);
|
||||
if (filename)
|
||||
{
|
||||
gboolean success;
|
||||
|
||||
#if HAVE_HILDON
|
||||
osso_context_t* osso;
|
||||
DBusConnection* dbus;
|
||||
|
||||
osso = osso_initialize (PACKAGE_NAME, PACKAGE_VERSION, FALSE, NULL);
|
||||
if (!osso)
|
||||
{
|
||||
sokoke_message_dialog (GTK_MESSAGE_ERROR,
|
||||
_("Could not run external program."),
|
||||
"Failed to initialize libosso");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
dbus = (DBusConnection *) osso_get_dbus_connection (osso);
|
||||
if (!dbus)
|
||||
{
|
||||
osso_deinitialize (osso);
|
||||
sokoke_message_dialog (GTK_MESSAGE_ERROR,
|
||||
_("Could not run external program."),
|
||||
"Failed to get dbus connection from osso context");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
error = NULL;
|
||||
/* FIXME: This is not correct, find a proper way to do this */
|
||||
success = (osso_application_top (osso, command, argument) == OSSO_OK);
|
||||
osso_deinitialize (osso);
|
||||
#else
|
||||
GAppInfo* info;
|
||||
GFile* file;
|
||||
GList* files;
|
||||
|
||||
info = g_app_info_create_from_commandline (command,
|
||||
NULL, G_APP_INFO_CREATE_NONE, NULL);
|
||||
file = g_file_new_for_commandline_arg (argument);
|
||||
files = g_list_append (NULL, file);
|
||||
|
||||
error = NULL;
|
||||
success = g_app_info_launch (info, files, NULL, &error);
|
||||
g_object_unref (file);
|
||||
g_list_free (files);
|
||||
#endif
|
||||
|
||||
if (!success)
|
||||
{
|
||||
sokoke_message_dialog (GTK_MESSAGE_ERROR,
|
||||
_("Could not run external program."),
|
||||
error ? error->message : "");
|
||||
if (error)
|
||||
g_error_free (error);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
command_ready = g_strconcat (command, " ", argument_escaped, NULL);
|
||||
{
|
||||
/* FIXME: Implement Hildon specific version */
|
||||
gchar* command_ready;
|
||||
gchar** argv;
|
||||
|
||||
if (strstr (command, "%s"))
|
||||
command_ready = g_strdup_printf (command, argument);
|
||||
else
|
||||
command_ready = g_strconcat (command, " ", argument, NULL);
|
||||
|
||||
error = NULL;
|
||||
if (!g_shell_parse_argv (command_ready, NULL, &argv, &error))
|
||||
{
|
||||
error_dialog (_("Could not run external program."), error->message);
|
||||
sokoke_message_dialog (GTK_MESSAGE_ERROR,
|
||||
_("Could not run external program."),
|
||||
error->message);
|
||||
g_error_free (error);
|
||||
g_free (command_ready);
|
||||
g_free (argument_escaped);
|
||||
return FALSE;
|
||||
}
|
||||
g_free (command_ready);
|
||||
|
||||
error = NULL;
|
||||
if (!g_spawn_async (NULL, argv, NULL,
|
||||
(GSpawnFlags)G_SPAWN_SEARCH_PATH | G_SPAWN_DO_NOT_REAP_CHILD,
|
||||
NULL, NULL, NULL, &error))
|
||||
{
|
||||
error_dialog (_("Could not run external program."), error->message);
|
||||
sokoke_message_dialog (GTK_MESSAGE_ERROR,
|
||||
_("Could not run external program."),
|
||||
error->message);
|
||||
g_error_free (error);
|
||||
}
|
||||
|
||||
g_strfreev (argv);
|
||||
g_free (command_ready);
|
||||
g_free (argument_escaped);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -365,6 +537,8 @@ sokoke_magic_uri (const gchar* uri,
|
|||
/* Just return if it's a javascript: or mailto: uri */
|
||||
if (g_str_has_prefix (uri, "javascript:")
|
||||
|| g_str_has_prefix (uri, "mailto:")
|
||||
|| g_str_has_prefix (uri, "tel:")
|
||||
|| g_str_has_prefix (uri, "callto:")
|
||||
|| g_str_has_prefix (uri, "data:"))
|
||||
return g_strdup (uri);
|
||||
/* Add file:// if we have a local path */
|
||||
|
@ -428,11 +602,22 @@ sokoke_format_uri_for_display (const gchar* uri)
|
|||
{
|
||||
if (uri && g_str_has_prefix (uri, "http://"))
|
||||
{
|
||||
gchar* unescaped = g_uri_unescape_string (uri, NULL);
|
||||
gchar* unescaped = g_uri_unescape_string (uri, " +");
|
||||
#ifdef HAVE_LIBSOUP_2_27_90
|
||||
gchar* path;
|
||||
gchar* hostname = sokoke_hostname_from_uri (unescaped, &path);
|
||||
gchar* decoded = g_hostname_to_unicode (hostname);
|
||||
gchar* hostname;
|
||||
gchar* decoded;
|
||||
|
||||
if (!unescaped)
|
||||
return g_strdup (uri);
|
||||
else if (!g_utf8_validate (unescaped, -1, NULL))
|
||||
{
|
||||
g_free (unescaped);
|
||||
return g_strdup (uri);
|
||||
}
|
||||
|
||||
hostname = sokoke_hostname_from_uri (unescaped, &path);
|
||||
decoded = g_hostname_to_unicode (hostname);
|
||||
|
||||
if (decoded)
|
||||
{
|
||||
|
@ -446,6 +631,15 @@ sokoke_format_uri_for_display (const gchar* uri)
|
|||
return unescaped;
|
||||
#elif HAVE_LIBIDN
|
||||
gchar* decoded;
|
||||
|
||||
if (!unescaped)
|
||||
return g_strdup (uri);
|
||||
else if (!g_utf8_validate (unescaped, -1, NULL))
|
||||
{
|
||||
g_free (unescaped);
|
||||
return g_strdup (uri);
|
||||
}
|
||||
|
||||
if (!idna_to_unicode_8z8z (unescaped, &decoded, 0) == IDNA_SUCCESS)
|
||||
return unescaped;
|
||||
g_free (unescaped);
|
||||
|
@ -490,15 +684,6 @@ sokoke_container_show_children (GtkContainer* container)
|
|||
gtk_container_foreach (container, (GtkCallback)(gtk_widget_show_all), NULL);
|
||||
}
|
||||
|
||||
void
|
||||
sokoke_widget_popup (GtkWidget* widget,
|
||||
GtkMenu* menu,
|
||||
GdkEventButton* event,
|
||||
SokokeMenuPos pos)
|
||||
{
|
||||
katze_widget_popup (widget, menu, event, (KatzeMenuPos)pos);
|
||||
}
|
||||
|
||||
typedef enum
|
||||
{
|
||||
SOKOKE_DESKTOP_UNTESTED,
|
||||
|
@ -608,24 +793,6 @@ sokoke_xfce_header_new (const gchar* icon,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
GtkWidget*
|
||||
sokoke_hig_frame_new (const gchar* title)
|
||||
{
|
||||
/* Create a frame with no actual frame but a bold label and indentation */
|
||||
GtkWidget* frame = gtk_frame_new (NULL);
|
||||
#ifdef G_OS_WIN32
|
||||
gtk_frame_set_label (GTK_FRAME (frame), title);
|
||||
#else
|
||||
gchar* title_bold = g_strdup_printf ("<b>%s</b>", title);
|
||||
GtkWidget* label = gtk_label_new (NULL);
|
||||
gtk_label_set_markup (GTK_LABEL (label), title_bold);
|
||||
g_free (title_bold);
|
||||
gtk_frame_set_label_widget (GTK_FRAME (frame), label);
|
||||
gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_NONE);
|
||||
#endif
|
||||
return frame;
|
||||
}
|
||||
|
||||
void
|
||||
sokoke_widget_set_pango_font_style (GtkWidget* widget,
|
||||
PangoStyle style)
|
||||
|
@ -888,20 +1055,6 @@ sokoke_action_create_popup_menu_item (GtkAction* action)
|
|||
return menuitem;
|
||||
}
|
||||
|
||||
/**
|
||||
* sokoke_image_menu_item_new_ellipsized:
|
||||
* @label: the text of the menu item
|
||||
*
|
||||
* Creates a new #GtkImageMenuItem containing an ellipsized label.
|
||||
*
|
||||
* Return value: a new #GtkImageMenuItem
|
||||
**/
|
||||
GtkWidget*
|
||||
sokoke_image_menu_item_new_ellipsized (const gchar* label)
|
||||
{
|
||||
return katze_image_menu_item_new_ellipsized (label);
|
||||
}
|
||||
|
||||
/**
|
||||
* sokoke_time_t_to_julian:
|
||||
* @timestamp: a time_t timestamp value
|
||||
|
@ -934,6 +1087,11 @@ sokoke_time_t_to_julian (const time_t* timestamp)
|
|||
void
|
||||
sokoke_register_stock_items (void)
|
||||
{
|
||||
GtkIconSource* icon_source;
|
||||
GtkIconSet* icon_set;
|
||||
GtkIconFactory* factory;
|
||||
gsize i;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
const gchar* stock_id;
|
||||
|
@ -942,11 +1100,6 @@ sokoke_register_stock_items (void)
|
|||
guint keyval;
|
||||
const gchar* fallback;
|
||||
} FatStockItem;
|
||||
GtkIconSource* icon_source;
|
||||
GtkIconSet* icon_set;
|
||||
GtkIconFactory* factory = gtk_icon_factory_new ();
|
||||
gsize i;
|
||||
|
||||
static FatStockItem items[] =
|
||||
{
|
||||
{ STOCK_EXTENSION, NULL, 0, 0, GTK_STOCK_CONVERT },
|
||||
|
@ -958,7 +1111,7 @@ sokoke_register_stock_items (void)
|
|||
{ STOCK_TRANSFER, NULL, 0, 0, GTK_STOCK_SAVE },
|
||||
|
||||
{ STOCK_BOOKMARK, N_("_Bookmark"), 0, 0, GTK_STOCK_FILE },
|
||||
{ STOCK_BOOKMARKS, N_("_Bookmarks"), 0, 0, GTK_STOCK_DIRECTORY },
|
||||
{ STOCK_BOOKMARKS, N_("_Bookmarks"), GDK_CONTROL_MASK, GDK_B, GTK_STOCK_DIRECTORY },
|
||||
{ STOCK_BOOKMARK_ADD, N_("Add Boo_kmark"), 0, 0, GTK_STOCK_ADD },
|
||||
{ STOCK_CONSOLE, N_("_Console"), 0, 0, GTK_STOCK_DIALOG_WARNING },
|
||||
{ STOCK_EXTENSIONS, N_("_Extensions"), 0, 0, GTK_STOCK_CONVERT },
|
||||
|
@ -972,6 +1125,7 @@ sokoke_register_stock_items (void)
|
|||
{ STOCK_WINDOW_NEW, N_("New _Window"), 0, 0, GTK_STOCK_ADD },
|
||||
};
|
||||
|
||||
factory = gtk_icon_factory_new ();
|
||||
for (i = 0; i < G_N_ELEMENTS (items); i++)
|
||||
{
|
||||
icon_set = gtk_icon_set_new ();
|
||||
|
@ -991,6 +1145,55 @@ sokoke_register_stock_items (void)
|
|||
gtk_stock_add ((GtkStockItem*)items, G_N_ELEMENTS (items));
|
||||
gtk_icon_factory_add_default (factory);
|
||||
g_object_unref (factory);
|
||||
|
||||
#if HAVE_HILDON
|
||||
/* Maemo doesn't theme stock icons. So we map platform icons
|
||||
to stock icons. These are all monochrome toolbar icons. */
|
||||
typedef struct
|
||||
{
|
||||
const gchar* stock_id;
|
||||
const gchar* icon_name;
|
||||
} CompatItem;
|
||||
static CompatItem compat_items[] =
|
||||
{
|
||||
{ GTK_STOCK_ADD, "general_add" },
|
||||
{ GTK_STOCK_BOLD, "general_bold" },
|
||||
{ GTK_STOCK_CLOSE, "general_close_b" },
|
||||
{ GTK_STOCK_DELETE, "general_delete" },
|
||||
{ GTK_STOCK_DIRECTORY, "general_toolbar_folder" },
|
||||
{ GTK_STOCK_FIND, "general_search" },
|
||||
{ GTK_STOCK_FULLSCREEN, "general_fullsize_b" },
|
||||
{ GTK_STOCK_GO_BACK, "general_back" },
|
||||
{ GTK_STOCK_GO_FORWARD, "general_forward" },
|
||||
{ GTK_STOCK_GO_UP, "filemanager_folder_up" },
|
||||
{ GTK_STOCK_GOTO_FIRST, "pdf_viewer_first_page" },
|
||||
{ GTK_STOCK_GOTO_LAST, "pdf_viewer_last_page" },
|
||||
{ GTK_STOCK_INFO, "general_information" },
|
||||
{ GTK_STOCK_ITALIC, "general_italic" },
|
||||
{ GTK_STOCK_JUMP_TO, "general_move_to_folder" },
|
||||
{ GTK_STOCK_PREFERENCES,"general_settings" },
|
||||
{ GTK_STOCK_REFRESH, "general_refresh" },
|
||||
{ GTK_STOCK_SAVE, "notes_save" },
|
||||
{ GTK_STOCK_STOP, "general_stop" },
|
||||
{ GTK_STOCK_UNDERLINE, "notes_underline" },
|
||||
{ GTK_STOCK_ZOOM_IN, "pdf_zoomin" },
|
||||
{ GTK_STOCK_ZOOM_OUT, "pdf_zoomout" },
|
||||
};
|
||||
|
||||
factory = gtk_icon_factory_new ();
|
||||
for (i = 0; i < G_N_ELEMENTS (compat_items); i++)
|
||||
{
|
||||
icon_set = gtk_icon_set_new ();
|
||||
icon_source = gtk_icon_source_new ();
|
||||
gtk_icon_source_set_icon_name (icon_source, compat_items[i].icon_name);
|
||||
gtk_icon_set_add_source (icon_set, icon_source);
|
||||
gtk_icon_source_free (icon_source);
|
||||
gtk_icon_factory_add (factory, compat_items[i].stock_id, icon_set);
|
||||
gtk_icon_set_unref (icon_set);
|
||||
}
|
||||
gtk_icon_factory_add_default (factory);
|
||||
g_object_unref (factory);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1117,6 +1320,7 @@ sokoke_find_data_filename (const gchar* filename)
|
|||
return g_build_filename (MDATADIR, filename, NULL);
|
||||
}
|
||||
|
||||
#if !WEBKIT_CHECK_VERSION (1, 1, 14)
|
||||
static void
|
||||
res_server_handler_cb (SoupServer* res_server,
|
||||
SoupMessage* msg,
|
||||
|
@ -1209,6 +1413,7 @@ sokoke_get_res_server (void)
|
|||
|
||||
return res_server;
|
||||
}
|
||||
#endif
|
||||
|
||||
gchar*
|
||||
sokoke_replace_variables (const gchar* template,
|
||||
|
@ -1234,3 +1439,75 @@ sokoke_replace_variables (const gchar* template,
|
|||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* sokoke_window_activate_key:
|
||||
* @window: a #GtkWindow
|
||||
* @event: a #GdkEventKey
|
||||
*
|
||||
* Attempts to activate they key from the event, much
|
||||
* like gtk_window_activate_key(), including keys
|
||||
* that gtk_accelerator_valid() considers invalid.
|
||||
*
|
||||
* Return value: %TRUE on success
|
||||
**/
|
||||
gboolean
|
||||
sokoke_window_activate_key (GtkWindow* window,
|
||||
GdkEventKey* event)
|
||||
{
|
||||
gchar *accel_name;
|
||||
GQuark accel_quark;
|
||||
GObject* object;
|
||||
GSList *slist;
|
||||
|
||||
if (gtk_window_activate_key (window, event))
|
||||
return TRUE;
|
||||
|
||||
/* We don't use gtk_accel_groups_activate because it refuses to
|
||||
activate anything that gtk_accelerator_valid doesn't like. */
|
||||
accel_name = gtk_accelerator_name (event->keyval, (event->state & gtk_accelerator_get_default_mod_mask ()));
|
||||
accel_quark = g_quark_from_string (accel_name);
|
||||
g_free (accel_name);
|
||||
object = G_OBJECT (window);
|
||||
|
||||
for (slist = gtk_accel_groups_from_object (object); slist; slist = slist->next)
|
||||
if (gtk_accel_group_activate (slist->data, accel_quark,
|
||||
object, event->keyval, event->state))
|
||||
return TRUE;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* sokoke_file_chooser_dialog_new:
|
||||
* @title: a window title, or %NULL
|
||||
* @window: a parent #GtkWindow, or %NULL
|
||||
* @action: a #GtkFileChooserAction
|
||||
*
|
||||
* Creates a new file chooser dialog, as appropriate for
|
||||
* the platform, with buttons according to the @action.
|
||||
*
|
||||
* The positive response is %GTK_RESPONSE_OK.
|
||||
*
|
||||
* Return value: a new #GtkFileChooser
|
||||
**/
|
||||
GtkWidget*
|
||||
sokoke_file_chooser_dialog_new (const gchar* title,
|
||||
GtkWindow* window,
|
||||
GtkFileChooserAction action)
|
||||
{
|
||||
const gchar* stock_id = GTK_STOCK_OPEN;
|
||||
GtkWidget* dialog;
|
||||
|
||||
if (action == GTK_FILE_CHOOSER_ACTION_SAVE)
|
||||
stock_id = GTK_STOCK_SAVE;
|
||||
#ifdef HAVE_HILDON_FM
|
||||
dialog = hildon_file_chooser_dialog_new (window, action);
|
||||
#else
|
||||
dialog = gtk_file_chooser_dialog_new (title, window, action,
|
||||
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
|
||||
stock_id, GTK_RESPONSE_OK, NULL);
|
||||
gtk_window_set_icon_name (GTK_WINDOW (dialog), stock_id);
|
||||
#endif
|
||||
return dialog;
|
||||
}
|
||||
|
|
|
@ -15,8 +15,7 @@
|
|||
|
||||
#include <katze/katze.h>
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
#include <libsoup/soup.h>
|
||||
#include <webkit/webkit.h>
|
||||
#include <JavaScriptCore/JavaScript.h>
|
||||
|
||||
gchar*
|
||||
|
@ -27,6 +26,18 @@ sokoke_js_script_eval (JSContextRef js_context,
|
|||
/* Many themes need this hack for small toolbars to work */
|
||||
#define GTK_ICON_SIZE_SMALL_TOOLBAR GTK_ICON_SIZE_BUTTON
|
||||
|
||||
void
|
||||
sokoke_message_dialog (GtkMessageType message_type,
|
||||
const gchar* short_message,
|
||||
const gchar* detailed_message);
|
||||
|
||||
gboolean
|
||||
sokoke_show_uri_with_mime_type (GdkScreen* screen,
|
||||
const gchar* uri,
|
||||
const gchar* mime_type,
|
||||
guint32 timestamp,
|
||||
GError** error);
|
||||
|
||||
gboolean
|
||||
sokoke_show_uri (GdkScreen* screen,
|
||||
const gchar* uri,
|
||||
|
@ -55,12 +66,6 @@ sokoke_magic_uri (const gchar* uri,
|
|||
gchar*
|
||||
sokoke_format_uri_for_display (const gchar* uri);
|
||||
|
||||
typedef enum {
|
||||
SOKOKE_MENU_POSITION_CURSOR = 0,
|
||||
SOKOKE_MENU_POSITION_LEFT,
|
||||
SOKOKE_MENU_POSITION_RIGHT
|
||||
} SokokeMenuPos;
|
||||
|
||||
void
|
||||
sokoke_combo_box_add_strings (GtkComboBox* combobox,
|
||||
const gchar* label_first,
|
||||
|
@ -73,19 +78,10 @@ sokoke_widget_set_visible (GtkWidget* widget,
|
|||
void
|
||||
sokoke_container_show_children (GtkContainer* container);
|
||||
|
||||
void
|
||||
sokoke_widget_popup (GtkWidget* widget,
|
||||
GtkMenu* menu,
|
||||
GdkEventButton* event,
|
||||
SokokeMenuPos pos);
|
||||
|
||||
GtkWidget*
|
||||
sokoke_xfce_header_new (const gchar* icon,
|
||||
const gchar* title);
|
||||
|
||||
GtkWidget*
|
||||
sokoke_hig_frame_new (const gchar* title);
|
||||
|
||||
void
|
||||
sokoke_widget_set_pango_font_style (GtkWidget* widget,
|
||||
PangoStyle style);
|
||||
|
@ -145,9 +141,6 @@ sokoke_widget_get_text_size (GtkWidget* widget,
|
|||
GtkWidget*
|
||||
sokoke_action_create_popup_menu_item (GtkAction* action);
|
||||
|
||||
GtkWidget*
|
||||
sokoke_image_menu_item_new_ellipsized (const gchar* label);
|
||||
|
||||
gint64
|
||||
sokoke_time_t_to_julian (const time_t* timestamp);
|
||||
|
||||
|
@ -168,11 +161,22 @@ sokoke_find_config_filename (const gchar* folder,
|
|||
gchar*
|
||||
sokoke_find_data_filename (const gchar* filename);
|
||||
|
||||
#if !WEBKIT_CHECK_VERSION (1, 1, 14)
|
||||
SoupServer*
|
||||
sokoke_get_res_server (void);
|
||||
#endif
|
||||
|
||||
gchar*
|
||||
sokoke_replace_variables (const gchar* template,
|
||||
const gchar* variable_first, ...);
|
||||
|
||||
gboolean
|
||||
sokoke_window_activate_key (GtkWindow* window,
|
||||
GdkEventKey* event);
|
||||
|
||||
GtkWidget*
|
||||
sokoke_file_chooser_dialog_new (const gchar* title,
|
||||
GtkWindow* window,
|
||||
GtkFileChooserAction action);
|
||||
|
||||
#endif /* !__SOKOKE_H__ */
|
||||
|
|
|
@ -10,7 +10,9 @@ obj.target = 'midori'
|
|||
obj.includes = '. ..'
|
||||
obj.find_sources_in_dirs ('.', excludes=['main.c'])
|
||||
obj.add_marshal_file ('marshal.list', 'midori_cclosure_marshal')
|
||||
obj.uselib = 'UNIQUE LIBSOUP LIBIDN GIO GTK SQLITE WEBKIT LIBXML WS2_32 OPENSSL HILDON'
|
||||
obj.uselib = 'UNIQUE LIBSOUP LIBIDN GIO GTK SQLITE LIBNOTIFY WEBKIT LIBXML ' \
|
||||
'WS2_32 OPENSSL ' \
|
||||
'HILDON HILDON_FM'
|
||||
obj.uselib_local = 'katze'
|
||||
obj.install_path = None
|
||||
|
||||
|
@ -19,7 +21,7 @@ obj.name = 'panels'
|
|||
obj.target = 'panels'
|
||||
obj.includes = '. ..'
|
||||
obj.find_sources_in_dirs ('../panels')
|
||||
obj.uselib = 'UNIQUE LIBSOUP GMODULE GTHREAD GIO GTK SQLITE WEBKIT LIBXML'
|
||||
obj.uselib = 'UNIQUE LIBSOUP GMODULE GTHREAD GIO GTK SQLITE WEBKIT LIBXML X11'
|
||||
obj.uselib_local = 'midori-core'
|
||||
obj.install_path = None
|
||||
|
||||
|
|
|
@ -280,14 +280,21 @@ static void
|
|||
midori_addons_button_add_clicked_cb (GtkToolItem* toolitem,
|
||||
MidoriAddons* addons)
|
||||
{
|
||||
GtkWidget* dialog = gtk_message_dialog_new (
|
||||
gchar* path_scripts, *path_styles;
|
||||
GtkWidget* dialog;
|
||||
|
||||
path_scripts = g_build_path (G_DIR_SEPARATOR_S, g_get_user_data_dir (),
|
||||
PACKAGE_NAME, "scripts", NULL);
|
||||
path_styles = g_build_path (G_DIR_SEPARATOR_S, g_get_user_data_dir (),
|
||||
PACKAGE_NAME, "styles", NULL);
|
||||
dialog = gtk_message_dialog_new (
|
||||
GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (addons))),
|
||||
GTK_DIALOG_DESTROY_WITH_PARENT,
|
||||
GTK_MESSAGE_INFO, GTK_BUTTONS_CLOSE,
|
||||
_("Copy userscripts to the folder %s and "
|
||||
"copy userstyles to the folder %s."),
|
||||
"~/.local/share/midori/scripts",
|
||||
"~/.local/share/midori/styles");
|
||||
"copy userstyles to the folder %s."), path_scripts, path_styles);
|
||||
g_free (path_scripts);
|
||||
g_free (path_styles);
|
||||
gtk_dialog_run (GTK_DIALOG (dialog));
|
||||
gtk_widget_destroy (dialog);
|
||||
}
|
||||
|
|
|
@ -32,6 +32,10 @@ midori_browser_edit_bookmark_dialog_new (MidoriBrowser* browser,
|
|||
gboolean new_bookmark,
|
||||
gboolean is_folder);
|
||||
|
||||
void
|
||||
midori_browser_open_bookmark (MidoriBrowser* browser,
|
||||
KatzeItem* item);
|
||||
|
||||
struct _MidoriBookmarks
|
||||
{
|
||||
GtkVBox parent_instance;
|
||||
|
@ -182,6 +186,14 @@ midori_bookmarks_folder_clicked_cb (GtkWidget* toolitem)
|
|||
NULL, TRUE, TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
midori_bookmarks_import_clicked_cb (GtkWidget* toolitem)
|
||||
{
|
||||
MidoriBrowser* browser = midori_browser_get_for_widget (GTK_WIDGET (toolitem));
|
||||
/* FIXME: Take selected folder into account */
|
||||
midori_browser_activate_action (browser, "BookmarksImport");
|
||||
}
|
||||
|
||||
static void
|
||||
midori_bookmarks_cursor_or_row_changed_cb (GtkTreeView* treeview,
|
||||
MidoriBookmarks* bookmarks)
|
||||
|
@ -255,6 +267,13 @@ midori_bookmarks_get_toolbar (MidoriViewable* viewable)
|
|||
gtk_tool_item_set_expand (toolitem, TRUE);
|
||||
gtk_toolbar_insert (GTK_TOOLBAR (toolbar), toolitem, -1);
|
||||
gtk_widget_show (GTK_WIDGET (toolitem));
|
||||
toolitem = gtk_tool_button_new_from_stock (GTK_STOCK_CONVERT);
|
||||
gtk_widget_set_tooltip_text (GTK_WIDGET (toolitem),
|
||||
_("Import bookmarks..."));
|
||||
g_signal_connect (toolitem, "clicked",
|
||||
G_CALLBACK (midori_bookmarks_import_clicked_cb), bookmarks);
|
||||
gtk_toolbar_insert (GTK_TOOLBAR (toolbar), toolitem, -1);
|
||||
gtk_widget_show (GTK_WIDGET (toolitem));
|
||||
toolitem = gtk_tool_button_new_from_stock (GTK_STOCK_DIRECTORY);
|
||||
gtk_widget_set_tooltip_text (GTK_WIDGET (toolitem),
|
||||
_("Add a new folder"));
|
||||
|
@ -563,9 +582,7 @@ midori_bookmarks_treeview_render_icon_cb (GtkTreeViewColumn* column,
|
|||
pixbuf = gtk_widget_render_icon (treeview, GTK_STOCK_DIRECTORY,
|
||||
GTK_ICON_SIZE_MENU, NULL);
|
||||
else if (katze_item_get_uri (item))
|
||||
pixbuf = katze_net_load_icon (
|
||||
MIDORI_BOOKMARKS (gtk_widget_get_parent (treeview))->net,
|
||||
katze_item_get_uri (item), NULL, treeview, NULL);
|
||||
pixbuf = katze_load_cached_icon (katze_item_get_uri (item), treeview);
|
||||
g_object_set (renderer, "pixbuf", pixbuf, NULL);
|
||||
|
||||
if (pixbuf)
|
||||
|
@ -603,19 +620,17 @@ midori_bookmarks_row_activated_cb (GtkTreeView* treeview,
|
|||
GtkTreeModel* model;
|
||||
GtkTreeIter iter;
|
||||
KatzeItem* item;
|
||||
const gchar* uri;
|
||||
|
||||
model = gtk_tree_view_get_model (treeview);
|
||||
|
||||
if (gtk_tree_model_get_iter (model, &iter, path))
|
||||
{
|
||||
MidoriBrowser* browser;
|
||||
|
||||
gtk_tree_model_get (model, &iter, 0, &item, -1);
|
||||
uri = katze_item_get_uri (item);
|
||||
if (uri && *uri)
|
||||
{
|
||||
MidoriBrowser* browser = midori_browser_get_for_widget (GTK_WIDGET (bookmarks));
|
||||
midori_browser_set_current_uri (browser, uri);
|
||||
}
|
||||
|
||||
browser = midori_browser_get_for_widget (GTK_WIDGET (bookmarks));
|
||||
midori_browser_open_bookmark (browser, item);
|
||||
|
||||
g_object_unref (item);
|
||||
}
|
||||
|
@ -797,8 +812,7 @@ midori_bookmarks_popup (GtkWidget* widget,
|
|||
midori_bookmarks_popup_item (menu, GTK_STOCK_DELETE, NULL,
|
||||
item, midori_bookmarks_delete_activate_cb, bookmarks);
|
||||
|
||||
sokoke_widget_popup (widget, GTK_MENU (menu),
|
||||
event, SOKOKE_MENU_POSITION_CURSOR);
|
||||
katze_widget_popup (widget, GTK_MENU (menu), event, KATZE_MENU_POSITION_CURSOR);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
|
|
|
@ -73,7 +73,7 @@ midori_extensions_class_init (MidoriExtensionsClass* class)
|
|||
gobject_class->get_property = midori_extensions_get_property;
|
||||
gobject_class->finalize = midori_extensions_finalize;
|
||||
|
||||
flags = G_PARAM_READWRITE | G_PARAM_CONSTRUCT;
|
||||
flags = G_PARAM_READWRITE;
|
||||
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_APP,
|
||||
|
@ -183,6 +183,10 @@ midori_extensions_set_property (GObject* object,
|
|||
i = 0;
|
||||
while ((extension = katze_array_get_nth_item (array, i++)))
|
||||
midori_extensions_add_item_cb (array, extension, extensions);
|
||||
|
||||
/* Hide if there are no extensions at all */
|
||||
if (!katze_array_get_nth_item (array, 0))
|
||||
gtk_widget_hide (GTK_WIDGET (object));
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
@ -378,8 +382,7 @@ midori_extensions_popup (GtkWidget* widget,
|
|||
midori_extensions_about_activate_cb, FALSE,
|
||||
extensions);
|
||||
|
||||
sokoke_widget_popup (widget, GTK_MENU (menu),
|
||||
event, SOKOKE_MENU_POSITION_CURSOR);
|
||||
katze_widget_popup (widget, GTK_MENU (menu), event, KATZE_MENU_POSITION_CURSOR);
|
||||
|
||||
g_free (website);
|
||||
}
|
||||
|
|
|
@ -328,7 +328,7 @@ midori_history_add_item_cb (KatzeArray* array,
|
|||
if (array == history->array)
|
||||
{
|
||||
gtk_tree_store_insert_with_values (GTK_TREE_STORE (model),
|
||||
&iter, NULL, G_MAXINT, 0, added_item, -1);
|
||||
&iter, NULL, 0, 0, added_item, -1);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -344,7 +344,7 @@ midori_history_add_item_cb (KatzeArray* array,
|
|||
GtkTreeIter child_iter;
|
||||
|
||||
gtk_tree_store_insert_with_values (GTK_TREE_STORE (model),
|
||||
&child_iter, &iter, G_MAXINT, 0, added_item, -1);
|
||||
&child_iter, &iter, 0, 0, added_item, -1);
|
||||
break;
|
||||
}
|
||||
g_object_unref (item);
|
||||
|
@ -560,9 +560,7 @@ midori_history_treeview_render_icon_cb (GtkTreeViewColumn* column,
|
|||
pixbuf = gtk_widget_render_icon (treeview, GTK_STOCK_DIRECTORY,
|
||||
GTK_ICON_SIZE_MENU, NULL);
|
||||
else
|
||||
pixbuf = katze_net_load_icon (
|
||||
MIDORI_HISTORY (gtk_widget_get_parent (treeview))->net,
|
||||
katze_item_get_uri (item), NULL, treeview, NULL);
|
||||
pixbuf = katze_load_cached_icon (katze_item_get_uri (item), treeview);
|
||||
|
||||
g_object_set (renderer, "pixbuf", pixbuf, NULL);
|
||||
|
||||
|
@ -577,7 +575,7 @@ midori_history_treeview_render_text_cb (GtkTreeViewColumn* column,
|
|||
GtkCellRenderer* renderer,
|
||||
GtkTreeModel* model,
|
||||
GtkTreeIter* iter,
|
||||
GtkWidget* treeview)
|
||||
MidoriHistory* history)
|
||||
{
|
||||
KatzeItem* item;
|
||||
gint64 age;
|
||||
|
@ -590,9 +588,21 @@ midori_history_treeview_render_text_cb (GtkTreeViewColumn* column,
|
|||
{
|
||||
gchar* sdate;
|
||||
|
||||
g_assert (age >= 0);
|
||||
/* A negative age is a date in the future, the clock is probably off */
|
||||
if (age < -1)
|
||||
{
|
||||
static gboolean clock_warning = FALSE;
|
||||
if (!clock_warning)
|
||||
{
|
||||
midori_app_send_notification (history->app,
|
||||
_("Erroneous clock time"),
|
||||
_("The clock time lies in the past. "
|
||||
"Please check the current date and time."));
|
||||
clock_warning = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if (age > 7)
|
||||
if (age > 7 || age < 0)
|
||||
{
|
||||
g_object_set (renderer, "text", katze_item_get_name (item), NULL);
|
||||
}
|
||||
|
@ -828,8 +838,7 @@ midori_history_popup (GtkWidget* widget,
|
|||
midori_history_popup_item (menu, GTK_STOCK_DELETE, NULL,
|
||||
item, midori_history_delete_activate_cb, history);
|
||||
|
||||
sokoke_widget_popup (widget, GTK_MENU (menu),
|
||||
event, SOKOKE_MENU_POSITION_CURSOR);
|
||||
katze_widget_popup (widget, GTK_MENU (menu), event, KATZE_MENU_POSITION_CURSOR);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
|
@ -941,7 +950,7 @@ midori_history_init (MidoriHistory* history)
|
|||
gtk_tree_view_column_pack_start (column, renderer_text, FALSE);
|
||||
gtk_tree_view_column_set_cell_data_func (column, renderer_text,
|
||||
(GtkTreeCellDataFunc)midori_history_treeview_render_text_cb,
|
||||
treeview, NULL);
|
||||
history, NULL);
|
||||
gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column);
|
||||
g_object_unref (model);
|
||||
g_object_connect (treeview,
|
||||
|
|
|
@ -255,8 +255,7 @@ midori_plugins_init (MidoriPlugins* plugins)
|
|||
FIXME: Ensure separators contained in the string can't break it */
|
||||
gchar* value = sokoke_js_script_eval (js_context,
|
||||
"function plugins (l) { var f = new Array (); for (i in l) "
|
||||
"{ var t = l[i].name; "
|
||||
"f.push (l[i].name + '|' + l[i].filename); } return f; }"
|
||||
"{ f.push (l[i].name + '|' + l[i].filename); } return f; }"
|
||||
"plugins (navigator.plugins)", NULL);
|
||||
gchar** items = g_strsplit (value, ",", 0);
|
||||
guint i = 0;
|
||||
|
|
|
@ -483,8 +483,7 @@ midori_transfers_popup (GtkWidget* widget,
|
|||
_("Copy Link Loc_ation"), download,
|
||||
midori_transfers_copy_address_activate_cb, FALSE, transfers);
|
||||
|
||||
sokoke_widget_popup (widget, GTK_MENU (menu),
|
||||
event, SOKOKE_MENU_POSITION_CURSOR);
|
||||
katze_widget_popup (widget, GTK_MENU (menu), event, KATZE_MENU_POSITION_CURSOR);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
# set of available languages (in alphabetic order)
|
||||
ast ca cs da de el en_GB es et fi fr gl he hu id it ja ko nl pl pt pt_BR ro ru sk sr sr@latin sv tr uk zh_CN zh_TW
|
||||
ast ca cs da de el en_GB es et fi fr gl he hu id it ja ko nl no pl pt pt_BR ro ru sk sr sr@latin sv tr uk zh_CN zh_TW
|
||||
|
|
|
@ -26,6 +26,7 @@ katze/katze-utils.c
|
|||
katze/katze-item.c
|
||||
katze/katze-array.c
|
||||
katze/katze-arrayaction.c
|
||||
katze/katze-preferences.c
|
||||
extensions/adblock.c
|
||||
extensions/colorful-tabs.c
|
||||
extensions/cookie-manager/cookie-manager.c
|
||||
|
@ -38,9 +39,11 @@ extensions/feed-panel/feed-parse.c
|
|||
extensions/feed-panel/feed-rss.c
|
||||
extensions/feed-panel/main.c
|
||||
extensions/formhistory.c
|
||||
extensions/mouse-gestures/main.c
|
||||
extensions/mouse-gestures.c
|
||||
extensions/page-holder.c
|
||||
extensions/shortcuts.c
|
||||
extensions/statusbar-features.c
|
||||
extensions/tab-panel.c
|
||||
extensions/tab-switcher.c
|
||||
extensions/toolbar-editor.c
|
||||
extensions/web-cache.c
|
||||
|
|
1252
po/midori.pot
1252
po/midori.pot
File diff suppressed because it is too large
Load diff
12
po/sk.po
12
po/sk.po
|
@ -7,7 +7,7 @@ msgstr ""
|
|||
"Project-Id-Version: Midori 0.1.9-3345559\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2009-07-29 23:58+0200\n"
|
||||
"PO-Revision-Date: 2009-10-12 16:32+0200\n"
|
||||
"PO-Revision-Date: 2009-11-21 15:33+0100\n"
|
||||
"Last-Translator: Robert Hartl <hartl.robert@gmail.com>\n"
|
||||
"Language-Team: Slovak <sk-i18n@lists.linux.sk>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
|
@ -2028,11 +2028,11 @@ msgstr "Zoznam, detaily a mazanie cookies"
|
|||
|
||||
#: ../extensions/feed-panel/feed-atom.c:242
|
||||
msgid "Failed to find required Atom \"entry\" elements in XML data."
|
||||
msgstr ""
|
||||
msgstr "Nepodarilo sa nájsť požadované prvky Atom \"entry\" v dátach XML."
|
||||
|
||||
#: ../extensions/feed-panel/feed-atom.c:348
|
||||
msgid "Failed to find required Atom \"feed\" elements in XML data."
|
||||
msgstr ""
|
||||
msgstr "Nepodarilo sa nájsť požadované prvky Atom \"feed\" v dátach XML."
|
||||
|
||||
#. i18n: The local date a feed was last updated
|
||||
#: ../extensions/feed-panel/feed-panel.c:399
|
||||
|
@ -2074,7 +2074,7 @@ msgstr "Zlyhalo načítanie XML kanála: %s"
|
|||
|
||||
#: ../extensions/feed-panel/feed-rss.c:46
|
||||
msgid "Failed to find \"channel\" element in RSS XML data."
|
||||
msgstr "Nepodarilo sa nájsť element \"channel\" v RSS XML dátach"
|
||||
msgstr "Nepodarilo sa nájsť prvok \"channel\" v RSS dátach XML."
|
||||
|
||||
#: ../extensions/feed-panel/feed-rss.c:51
|
||||
msgid "Unsupported RSS version found."
|
||||
|
@ -2082,11 +2082,11 @@ msgstr "Našla sa nepodporovaná verzia RSS"
|
|||
|
||||
#: ../extensions/feed-panel/feed-rss.c:148
|
||||
msgid "Failed to find required RSS \"item\" elements in XML data."
|
||||
msgstr ""
|
||||
msgstr "Nepodarilo sa nájsť požadované prvky RSS \"item\" v dátach XML."
|
||||
|
||||
#: ../extensions/feed-panel/feed-rss.c:248
|
||||
msgid "Failed to find required RSS \"channel\" elements in XML data."
|
||||
msgstr ""
|
||||
msgstr "Nepodarilo sa nájsť požadované prvky RSS \"channel\" v dátach XML."
|
||||
|
||||
#: ../extensions/feed-panel/main.c:114
|
||||
#, c-format
|
||||
|
|
1236
po/zh_CN.po
1236
po/zh_CN.po
File diff suppressed because it is too large
Load diff
|
@ -78,6 +78,9 @@ properties_object_get_set (GObject* object)
|
|||
g_param_spec_get_name (pspec),
|
||||
g_param_spec_get_name (pspecs[j]));
|
||||
|
||||
if (!(pspec->flags & G_PARAM_READABLE))
|
||||
continue;
|
||||
|
||||
g_object_get (object, property, &value, NULL);
|
||||
if (type == G_TYPE_PARAM_BOOLEAN)
|
||||
{
|
||||
|
|
36
wscript
36
wscript
|
@ -25,7 +25,7 @@ import misc
|
|||
|
||||
major = 0
|
||||
minor = 2
|
||||
micro = 0
|
||||
micro = 2
|
||||
|
||||
APPNAME = 'midori'
|
||||
VERSION = str (major) + '.' + str (minor) + '.' + str (micro)
|
||||
|
@ -56,12 +56,12 @@ def is_mingw (env):
|
|||
return False
|
||||
|
||||
# Compile Win32 res files to (resource) object files
|
||||
@extension ('.rc')
|
||||
def rc_file(self, node):
|
||||
rctask = self.create_task ('winrc')
|
||||
rctask.set_inputs (node)
|
||||
rctask.set_outputs (node.change_ext ('.rc.o'))
|
||||
self.compiled_tasks.append (rctask)
|
||||
rc_file = extension ('.rc')(rc_file)
|
||||
Task.simple_task_type ('winrc', '${WINRC} -o${TGT} ${SRC}', color='BLUE',
|
||||
before='cc cxx', shell=False)
|
||||
|
||||
|
@ -190,6 +190,15 @@ def configure (conf):
|
|||
sqlite = 'no '
|
||||
conf.define ('HAVE_SQLITE', [0,1][sqlite == 'yes'])
|
||||
|
||||
if option_enabled ('libnotify'):
|
||||
check_pkg ('libnotify', mandatory=False)
|
||||
libnotify = ['N/A','yes'][conf.env['HAVE_LIBNOTIFY'] == 1]
|
||||
if libnotify != 'yes':
|
||||
option_checkfatal ('libnotify', 'notifications')
|
||||
else:
|
||||
libnotify = 'no '
|
||||
conf.define ('HAVE_LIBNOTIFY', [0,1][libnotify == 'yes'])
|
||||
|
||||
conf.check (lib='m', mandatory=True)
|
||||
check_pkg ('gmodule-2.0', '2.8.0', False)
|
||||
check_pkg ('gthread-2.0', '2.8.0', False)
|
||||
|
@ -197,6 +206,8 @@ def configure (conf):
|
|||
args = ''
|
||||
if Options.platform == 'win32':
|
||||
args = '--define-variable=target=win32'
|
||||
elif sys.platform != 'darwin':
|
||||
check_pkg ('x11')
|
||||
check_pkg ('gtk+-2.0', '2.10.0', var='GTK', args=args)
|
||||
check_pkg ('webkit-1.0', '1.1.1', args=args)
|
||||
check_pkg ('libsoup-2.4', '2.25.2')
|
||||
|
@ -220,6 +231,8 @@ def configure (conf):
|
|||
if option_enabled ('hildon'):
|
||||
if check_pkg ('hildon-1', mandatory=False, var='HILDON'):
|
||||
check_pkg ('libosso', var='HILDON')
|
||||
check_pkg ('hildon-1', '2.2', var='HILDON_2_2')
|
||||
check_pkg ('hildon-fm-2', var='HILDON_FM')
|
||||
hildon = ['N/A','yes'][conf.env['HAVE_HILDON'] == 1]
|
||||
if hildon != 'yes':
|
||||
option_checkfatal ('hildon', 'Maemo integration')
|
||||
|
@ -246,6 +259,8 @@ def configure (conf):
|
|||
conf.define ('HAVE_OSX', int(sys.platform == 'darwin'))
|
||||
if Options.platform == 'win32':
|
||||
conf.env.append_value ('LINKFLAGS', '-mwindows')
|
||||
else:
|
||||
conf.check (header_name='signal.h')
|
||||
|
||||
conf.define ('PACKAGE_VERSION', VERSION)
|
||||
conf.define ('PACKAGE_NAME', APPNAME)
|
||||
|
@ -290,6 +305,7 @@ def configure (conf):
|
|||
Localization: %(nls)s (intltool)
|
||||
Icon optimizations: %(icons)s (rsvg-convert)
|
||||
Persistent history: %(sqlite)s (sqlite3)
|
||||
Notifications: %(libnotify)s (libnotify)
|
||||
|
||||
IDN support: %(idn)s (libidn or libsoup 2.27.90)
|
||||
User documentation: %(user_docs)s (docutils)
|
||||
|
@ -300,7 +316,7 @@ def configure (conf):
|
|||
Utils.pprint ('RED', 'Please use an older or newer version.')
|
||||
|
||||
def set_options (opt):
|
||||
def is_maemo (): return os.path.exists ('/etc/osso-af-init/osso-gtk.defs')
|
||||
def is_maemo (): return os.path.exists ('/etc/osso-af-init/')
|
||||
|
||||
def add_enable_option (option, desc, group=None, disable=False):
|
||||
if group == None:
|
||||
|
@ -338,9 +354,14 @@ def set_options (opt):
|
|||
add_enable_option ('unique', 'single instance support', group)
|
||||
add_enable_option ('libidn', 'international domain name support', group)
|
||||
add_enable_option ('sqlite', 'history database support', group)
|
||||
add_enable_option ('libnotify', 'notification support', group)
|
||||
add_enable_option ('addons', 'building of extensions', group)
|
||||
add_enable_option ('hildon', 'Maemo integration', group, disable=not is_maemo ())
|
||||
|
||||
# Provided for compatibility
|
||||
opt.add_option ('--build', help='Ignored')
|
||||
opt.add_option ('--disable-maintainer-mode', help='Ignored')
|
||||
|
||||
def build (bld):
|
||||
def image_to_win32ico (task):
|
||||
'Converts an image to a Win32 ico'
|
||||
|
@ -378,7 +399,7 @@ def build (bld):
|
|||
|
||||
if bld.env['docs']:
|
||||
bld.install_files ('${DOCDIR}/' + APPNAME + '/', \
|
||||
'AUTHORS ChangeLog COPYING EXPAT README TRANSLATE')
|
||||
'AUTHORS COPYING ChangeLog EXPAT README')
|
||||
|
||||
# Install default configuration
|
||||
bld.install_files ('${SYSCONFDIR}/xdg/' + APPNAME + '/', 'data/search')
|
||||
|
@ -449,12 +470,15 @@ def build (bld):
|
|||
bld.install_files ('${MDATADIR}/' + APPNAME + '/res', blddir + '/data/logo-shade.png')
|
||||
else:
|
||||
Utils.pprint ('BLUE', "logo-shade could not be rasterized.")
|
||||
|
||||
bld.install_files ('${MDATADIR}/' + APPNAME + '/res', 'data/error.html')
|
||||
bld.install_files ('${MDATADIR}/' + APPNAME + '/res', 'data/speeddial-head.html')
|
||||
bld.install_files ('${MDATADIR}/' + APPNAME + '/res', 'data/speeddial.json')
|
||||
bld.install_files ('${MDATADIR}/' + APPNAME + '/res', 'data/mootools.js')
|
||||
bld.install_files ('${MDATADIR}/' + APPNAME, 'data/autosuggestcontrol.js')
|
||||
bld.install_files ('${MDATADIR}/' + APPNAME, 'data/autosuggestcontrol.css')
|
||||
|
||||
if bld.env['addons']:
|
||||
bld.install_files ('${MDATADIR}/' + APPNAME + '/res', 'data/autosuggestcontrol.js')
|
||||
bld.install_files ('${MDATADIR}/' + APPNAME + '/res', 'data/autosuggestcontrol.css')
|
||||
|
||||
# FIXME: Determine the library naming for other platforms
|
||||
if Options.platform == 'linux':
|
||||
|
|
Loading…
Reference in a new issue