Imported Upstream version 0.2.4
This commit is contained in:
parent
67e400912e
commit
9eaa210044
109 changed files with 29999 additions and 24286 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -5,7 +5,9 @@ Makefile
|
|||
_build_
|
||||
|
||||
po/.intltool-merge-cache
|
||||
po/LINGUAS
|
||||
po/POTFILES
|
||||
po/midori.pot
|
||||
po/stamp-it
|
||||
po/*.gmo
|
||||
|
||||
|
|
38
ChangeLog
38
ChangeLog
|
@ -1,5 +1,43 @@
|
|||
This file is licensed under the terms of the expat license, see the file EXPAT.
|
||||
|
||||
v0.2.4
|
||||
+ Prevent completion from overlapping
|
||||
+ Fix tab order when restoring session
|
||||
+ Ignore accidentally middle click search
|
||||
+ Implement bookmark export to XBEL
|
||||
+ Provide scroll hotkeys, default to Vim
|
||||
+ Store and complete search in location
|
||||
+ Fix opening externally with multiple windows
|
||||
+ Only use icons in panel buttons
|
||||
+ Fix build with different GTK+ versions
|
||||
+ Omit micro version and arch from ident string
|
||||
|
||||
v0.2.3
|
||||
+ Improve relocatability for Win32
|
||||
+ Implement 'Close other tabs' menu item
|
||||
+ Use new GTK+ accessors where available
|
||||
+ Allow searching freely in History panel
|
||||
+ Re-implement completion based on sqlite
|
||||
+ Re-implement completion suggestion popup
|
||||
+ Simplify sqlite use towards efficient calls
|
||||
+ Move panel icons to the bottom
|
||||
+ Merge Netscape Plugins and Extensions panels
|
||||
+ Implement 'about:version' special page
|
||||
+ Implement 'Preferred languages' preference
|
||||
+ Improve window raising behaviour
|
||||
+ Allow Ctrl+Right-click to suppress javascript menu
|
||||
+ Add 'Open link as web app' in context menu
|
||||
+ Add 'Block image' menu item to Adblock
|
||||
+ Location progress and compat code refactored
|
||||
+ Implement 'Paste and proceed' in location
|
||||
+ Move DNS prefetching into the core
|
||||
+ Allow selecting and deleting multiple cookies
|
||||
+ Support attaching/ detaching web inspector
|
||||
+ Always enable web inspector
|
||||
+ --diagnostic-dialog command line switch
|
||||
+ Faster file existence checks
|
||||
+ Simplified, faster adblock implementation
|
||||
|
||||
v0.2.2
|
||||
+ Turn libnotify into a proper build-time dependency
|
||||
+ Use Ctrl + Return to open tabs from the location entry
|
||||
|
|
64
HACKING
64
HACKING
|
@ -1,10 +1,68 @@
|
|||
This file is licensed under the terms of the expat license, see the file EXPAT.
|
||||
|
||||
It is 4 spaces, no tabs, preferrably at 80 columns per line.
|
||||
+++ Hacking guide for Midori +++
|
||||
|
||||
The preferred coding style is explained by example.
|
||||
Indentation is 4 spaces, no tabs, preferrably at 80 to 120 columns per line to
|
||||
avoid automated line-breaks. Trailing whitespace is not desirable.
|
||||
|
||||
Source file example:
|
||||
Declarations go to the beginning of a block, not inline. Variables of one plain
|
||||
type may be grouped in one declaration, pointer types may not be grouped. The
|
||||
asterisk goes next to the type.
|
||||
Variables should be ordered in the order they are used.
|
||||
|
||||
Comments explain functionality, they should not state facts. The appropriate
|
||||
style is always C style /* */, not C++ style.
|
||||
|
||||
Variable and function names should be animal, animal_shelter or animalsc in
|
||||
case it would otherwise be very long. Loop counters may be single letters.
|
||||
Type names should be Animal, AnimalShelter or AnimalSC. No prefixes from third
|
||||
party projects should be used, such as GTK or WebKit, while underlines may be
|
||||
used but do not have a particular meaning.
|
||||
|
||||
There is a space between functions or keywords and round brackets, and curly
|
||||
brackets always go on separate lines, at the indentation level of the
|
||||
function, conditional or loop expression. Curly brackets are left out for single
|
||||
statement conditionals and loops unless they notably help readability.
|
||||
The type of a function goes on a separate line before the function.
|
||||
Preprocessor instructions are indented with the code they relate to.
|
||||
|
||||
Code history is precious, so one should avoid renaming a lot of functions at
|
||||
once or moving whole paragraphs only to add or remove a level of indentation.
|
||||
Moving blocks of code around is also undesriable because it makes patches less
|
||||
readable since the result looks like new code.
|
||||
|
||||
|
||||
+++ Source files in the project +++
|
||||
|
||||
Core:
|
||||
Files prefixed with "midori-" in the folder "midori" make up the core. They
|
||||
are essential to running the browser and mostly tailored to the browser.
|
||||
All header files prefixed with "midori-" are considered supported API and
|
||||
can be used to implement extensions.
|
||||
"sokoke" is a collection of very specialized helper functions which change
|
||||
from time to time as needed. In the past some of the code was moved to
|
||||
"katze" when it was considered generally useful.
|
||||
"socket" is a socket implementation with no dependency on other parts of
|
||||
the core, which is used if Midori is built without an external single
|
||||
instance support library.
|
||||
Panels:
|
||||
Files in the "panels" folder are classes that implement MidoriViewable and
|
||||
which are loaded into the MidoriPanel at startup. These panels are in
|
||||
principle optional.
|
||||
Katze:
|
||||
Re-usable classes and utility functions that don't depend on the core and
|
||||
some of that code indeed found its way into other projects.
|
||||
Extensions:
|
||||
These are extensions, written in C, which are loaded optionally if the user
|
||||
so chooses. Extensions can use API from "midori-" and "katze-" headers. Each
|
||||
module consists of either a single .c file or a folder with .c files.
|
||||
Tests:
|
||||
Unit tests are run regularly to verify possible regressions or measure
|
||||
performance of implementations. Except for select cases code changes should
|
||||
not cause failure of unit tests.
|
||||
|
||||
|
||||
+++ Examplary source code +++
|
||||
|
||||
/*
|
||||
Copyright
|
||||
|
|
4
INSTALL
4
INSTALL
|
@ -21,6 +21,10 @@ localizations are used from the build folder.
|
|||
|
||||
You can install it with './waf install'
|
||||
|
||||
If you need to do a clean rebuild, you can do either './waf clean'
|
||||
in order to remove binaries or './waf distclean' which deletes generated
|
||||
configuration files as well.
|
||||
|
||||
For further options run './waf --help'
|
||||
|
||||
+++ Debugging Midori +++
|
||||
|
|
74
TODO
74
TODO
|
@ -1,9 +1,72 @@
|
|||
This file is licensed under the terms of the expat license, see the file EXPAT.
|
||||
|
||||
TODO:
|
||||
. Detect opensearch engines on sites: http://searchplugins.net/pluginlist.aspx
|
||||
. Request network if not connected and re-open the url on success
|
||||
. Make cookie manager horizontal if the window is wide
|
||||
. Handle SSL like SSH: confirm any cert on first connection, warn about any change in subsequent connections
|
||||
. Open on startup: Ask (Last open pages, Blank, Homepage, [x] Don't ask anymore)
|
||||
. Support @run-at document-start: http://dev.chromium.org/developers/design-documents/user-scripts
|
||||
. Add an 'install' button to addons
|
||||
. Dragging a link onto the web view to open it
|
||||
. Extension: Ask Google if an address cannot be found, ie. typo
|
||||
. View source is not always equal to Save As
|
||||
. Show New Window icon in statusbar for new-window links
|
||||
. Validate search engine tokens
|
||||
. Easily register stock items in extensions (mouse gestures, input-mouse)
|
||||
. Show graphical error when a bookmarklet fails to run
|
||||
. Unit test katze array action
|
||||
. There is no way to reset the toolbar
|
||||
. Estimate download speed
|
||||
. Implement no_proxy, https_proxy
|
||||
. Make it possible to use extra C or C++ libraries in extensions
|
||||
. Add icon cache size preference
|
||||
. Fix icons with white background to be transparent?
|
||||
. Visually indicate that a tab is being opened even if outside the visible tabs
|
||||
. gget/ eatmonkey/ Transmission dbus in Transfers
|
||||
. Add Midori to autostart, and remove it if it's quit, optionally disabled
|
||||
. Use @include and @exclude with userstyles
|
||||
. Support -moz-document domain: http://userstyles.org/styles/22837
|
||||
. Need a throbber with invisible menubar: make compact-menu throbb?
|
||||
. Implement live bookmarks, see http://johnbokma.com/firefox/rss-and-live-bookmarks.html
|
||||
. Add a dialog (right-cick) to Addons, to edit @include and @exclude
|
||||
. Show URI in css overlay tooltips if statusbar is hidden
|
||||
. "Menu" tool buttons aren't depressed while a menu is open
|
||||
. Statusbar doesn't show right-click menu
|
||||
. Consider pango_layout_set_auto_dir
|
||||
. Make it possible to change ident string for particular domains
|
||||
. Support max-age for Flash cookies
|
||||
. Update speed dial thumbnail when loading the according page from speed dial
|
||||
. Implement "Open image" which opens an image with an external application
|
||||
. Add custom actions extension; example Set Wallpaper
|
||||
. Offer restoring session after crash, if session isn't opened at startup AND crash dialogue is enabled
|
||||
. Vi extension, modelled after vimprobable
|
||||
. Show loading tabs in the tab panel extension
|
||||
. Let extensions add preferences
|
||||
. Show syntax errors in userscripts/ styles
|
||||
. Add HTTP_PRAGMA: no-cache when Ctrl+Shift+R
|
||||
. Honor HTTP_PRAGMA: no-cache in web cache
|
||||
. Switching browser window: Ctrl+Shift+PageUp/PageDown
|
||||
. Switching panel: Ctrl+Alt+PageUp/PageDown
|
||||
. Bookmark folder context menu, "Sort by Name"
|
||||
. Adblock Block image: dialog to edit regex before adding
|
||||
. KatzeArrayAction should support "activate" signal
|
||||
. Remove extra inner panel border
|
||||
. Move statusbar_contents below panel if statusbar is hidden
|
||||
. Teplace "disable plugins" with showing a "load plugins automatically", where unchecking that keeps a placeholder that can be clicked to play
|
||||
. Show "Type an address or keywords to search" in empty location even when focussed
|
||||
. Show "Search hostname" in (can't resolve) error page, www.heyarnold.twotoastsde == typo?
|
||||
. Enable extensions in private (app) mode
|
||||
. Allow -e Set setting or so
|
||||
. Remember if inspector was attached or not
|
||||
. Icon in empty entry to paste from clipboard
|
||||
. Show suggestions in error page, ie. missing www. or www. not existing for a domain: http://www.svcl.org/
|
||||
. Warn when closing tab with unsubmitted form
|
||||
. Always allow popups, keep hidden, show icon to ask whether to show popups
|
||||
. Make Shift + Click download the link
|
||||
. Use an update timeout in KatzePropertyProxy instead of only focus-out
|
||||
. Show a loading mouse pointer
|
||||
. Import and export of the bookmarks file, or using one from a specific path
|
||||
. Export of the bookmarks file, or using one from a specific path
|
||||
. Custom context menu actions, like in Thunar or Epiphany
|
||||
. Analogus to blocked popups, blocked scripts moving layers on load (extension)
|
||||
. Per-site blocking of individual elements on a page
|
||||
|
@ -13,11 +76,8 @@ TODO:
|
|||
. Automatic update checks (browser, extensions)?
|
||||
. Auto-group tabs by opener, with colors?
|
||||
. 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
|
||||
. Check specific bookmarks for updates automatically (extension)
|
||||
. Mark "new" as well as "actually modified" tabs specially (even over sessions)
|
||||
. SearchEngine: "Show in context menu"
|
||||
. Save screenshot of a document?
|
||||
. Right-click a textbox in a search form and choose 'add to websearch'
|
||||
. Honor design principle "no warnings but undo of backups"?
|
||||
|
@ -25,11 +85,9 @@ TODO:
|
|||
. Protected tabs prompt when attempting to close them
|
||||
. Provide a 'sleep mode' after a crash where open documents are loaded manually
|
||||
. Option to run plugins or scripts only on demand, like NoScript, per-site
|
||||
. Optional http redirection manually or on timeout
|
||||
. Style: none, compatible (b/w), default, [styles], "media", ["media" styles], ...
|
||||
. Optional http redirection manually or on timeout via SoupMessage::restarted
|
||||
. 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)
|
||||
. 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
|
||||
. Prevent dead tabs: download, aborted page
|
||||
|
|
14
TRANSLATE
14
TRANSLATE
|
@ -2,21 +2,25 @@ This file is licensed under the terms of the expat license, see the file EXPAT.
|
|||
|
||||
+++ Translating Midori +++
|
||||
|
||||
If you want to translate Midori, here are a few helpful tips.
|
||||
The recommended tool for translating Midori is Transifex, which is what all
|
||||
Xfce projects use. It makes the life of translators and developers easier.
|
||||
That said, it is also possible to manually create or update a .po file and
|
||||
send a .po or .diff file via email or Flyspray.
|
||||
Either way the following instructions should get you started.
|
||||
|
||||
To update the localization template:
|
||||
There is no template in the repository. To create a localization template:
|
||||
|
||||
./waf build --update-po
|
||||
|
||||
You can use the same command in the future to update the template. It is
|
||||
recommended to do that always before you update localizations.
|
||||
|
||||
If you want to add a new language 'aa', create it like this:
|
||||
|
||||
cd po
|
||||
msginit -l aa_CC -o aa.po -i midori.pot
|
||||
sed -i 's/PACKAGE/midori/g' aa.po
|
||||
|
||||
Make sure you add your language to the file po/LINGUAS.
|
||||
Just open the file with a text editor and add your code.
|
||||
|
||||
To check your language 'aa' for errors, do this:
|
||||
|
||||
msgfmt -c --check-accelerators=_ aa.po
|
||||
|
|
|
@ -1,10 +1,8 @@
|
|||
div.suggestions {
|
||||
-moz-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
border: 1px solid #cccccc;
|
||||
-webkit-appearance: listbox;
|
||||
text-align: left;
|
||||
background-color: #ffffff;
|
||||
position: absolute;
|
||||
z-index: 999;
|
||||
}
|
||||
div.suggestions div {
|
||||
cursor: default;
|
||||
|
|
|
@ -38,7 +38,6 @@ function AutoSuggestControl(oTextbox /*:HTMLInputElement*/,
|
|||
* @param bTypeAhead If the control should provide a type ahead suggestion.
|
||||
*/
|
||||
AutoSuggestControl.prototype.autosuggest = function (aSuggestions /*:Array*/) {
|
||||
//make sure theres at least one suggestion
|
||||
if (aSuggestions.length > 0) {
|
||||
this.showSuggestions(aSuggestions);
|
||||
} else {
|
||||
|
@ -51,29 +50,16 @@ AutoSuggestControl.prototype.autosuggest = function (aSuggestions /*:Array*/) {
|
|||
* @scope private
|
||||
*/
|
||||
AutoSuggestControl.prototype.createDropDown = function () {
|
||||
var oThis = this;
|
||||
|
||||
//create the layer and assign styles
|
||||
var sDiv = document.getElementById("suggestions_box");
|
||||
if (sDiv) {
|
||||
this.layer = sDiv;
|
||||
return;
|
||||
}
|
||||
this.layer = document.createElement("div");
|
||||
this.layer.className = "suggestions";
|
||||
this.layer.id = "suggestions_box";
|
||||
this.layer.style.visibility = "hidden";
|
||||
this.layer.style.width = this.textbox.offsetWidth;
|
||||
|
||||
this.layer.onmousedown =
|
||||
this.layer.onmouseup =
|
||||
this.layer.onmouseover = function (oEvent) {
|
||||
oEvent = oEvent || window.event;
|
||||
oTarget = oEvent.target || oEvent.srcElement;
|
||||
|
||||
if (oEvent.type == "mousedown") {
|
||||
oThis.textbox.value = oTarget.firstChild.nodeValue;
|
||||
oThis.hideSuggestions();
|
||||
} else if (oEvent.type == "mouseover") {
|
||||
oThis.highlightSuggestion(oTarget);
|
||||
} else {
|
||||
oThis.textbox.focus();
|
||||
}
|
||||
};
|
||||
document.body.appendChild(this.layer);
|
||||
};
|
||||
|
||||
|
@ -85,12 +71,10 @@ AutoSuggestControl.prototype.createDropDown = function () {
|
|||
AutoSuggestControl.prototype.getLeft = function () /*:int*/ {
|
||||
var oNode = this.textbox;
|
||||
var iLeft = 0;
|
||||
|
||||
while(oNode.tagName != "BODY") {
|
||||
while (oNode.tagName != "BODY") {
|
||||
iLeft += oNode.offsetLeft;
|
||||
oNode = oNode.offsetParent;
|
||||
}
|
||||
|
||||
return iLeft;
|
||||
};
|
||||
|
||||
|
@ -135,17 +119,15 @@ AutoSuggestControl.prototype.handleKeyDown = function (oEvent /*:Event*/) {
|
|||
*/
|
||||
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);
|
||||
//make sure not to interfere with non-character keys
|
||||
} else if (iKeyCode < 32 || (iKeyCode >= 33 && iKeyCode < 46) || (iKeyCode >= 112 && iKeyCode <= 123) ) {
|
||||
//ignore
|
||||
} else if (oEvent.ctrlKey) {
|
||||
iKeyCode = 0;
|
||||
this.hideSuggestions();
|
||||
} else {
|
||||
//request suggestions from the suggestion provider with typeahead
|
||||
//request suggestions from the suggestion provider
|
||||
this.provider.requestSuggestions(this);
|
||||
}
|
||||
};
|
||||
|
@ -221,11 +203,15 @@ AutoSuggestControl.prototype.init = function () {
|
|||
AutoSuggestControl.prototype.nextSuggestion = function () {
|
||||
var cSuggestionNodes = this.layer.childNodes;
|
||||
|
||||
if (cSuggestionNodes.length > 0 && this.cur < cSuggestionNodes.length-1) {
|
||||
var oNode = cSuggestionNodes[++this.cur];
|
||||
this.highlightSuggestion(oNode);
|
||||
this.textbox.value = oNode.firstChild.nodeValue;
|
||||
}
|
||||
if (!cSuggestionNodes.length)
|
||||
return;
|
||||
|
||||
if (this.cur == cSuggestionNodes.length-1)
|
||||
this.cur = -1;
|
||||
|
||||
var oNode = cSuggestionNodes[++this.cur];
|
||||
this.highlightSuggestion(oNode);
|
||||
this.textbox.value = oNode.firstChild.nodeValue;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -236,24 +222,15 @@ AutoSuggestControl.prototype.nextSuggestion = function () {
|
|||
AutoSuggestControl.prototype.previousSuggestion = function () {
|
||||
var cSuggestionNodes = this.layer.childNodes;
|
||||
|
||||
if (cSuggestionNodes.length > 0 && this.cur > 0) {
|
||||
var oNode = cSuggestionNodes[--this.cur];
|
||||
this.highlightSuggestion(oNode);
|
||||
this.textbox.value = oNode.firstChild.nodeValue;
|
||||
}
|
||||
};
|
||||
if (!cSuggestionNodes.length)
|
||||
return;
|
||||
|
||||
/**
|
||||
* Selects a range of text in the textbox.
|
||||
* @scope public
|
||||
* @param iStart The start index (base 0) of the selection.
|
||||
* @param iLength The number of characters to select.
|
||||
*/
|
||||
AutoSuggestControl.prototype.selectRange = function (iStart /*:int*/, iLength /*:int*/) {
|
||||
if (this.textbox.setSelectionRange) {
|
||||
this.textbox.setSelectionRange(iStart, iLength);
|
||||
}
|
||||
this.textbox.focus();
|
||||
if (this.cur == -1 || this.cur == 0)
|
||||
this.cur = cSuggestionNodes.length;
|
||||
|
||||
var oNode = cSuggestionNodes[--this.cur];
|
||||
this.highlightSuggestion(oNode);
|
||||
this.textbox.value = oNode.firstChild.nodeValue;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -263,6 +240,7 @@ AutoSuggestControl.prototype.selectRange = function (iStart /*:int*/, iLength /*
|
|||
* @param aSuggestions An array of suggestions for the control.
|
||||
*/
|
||||
AutoSuggestControl.prototype.showSuggestions = function (aSuggestions /*:Array*/) {
|
||||
var oThis = this;
|
||||
var oDiv = null;
|
||||
this.layer.innerHTML = ""; //clear contents of the layer
|
||||
|
||||
|
@ -275,6 +253,22 @@ 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";
|
||||
this.layer.style.position = "absolute";
|
||||
this.layer.onmousedown =
|
||||
this.layer.onmouseup =
|
||||
this.layer.onmouseover = function (oEvent) {
|
||||
var oEvent = oEvent || window.event;
|
||||
var oTarget = oEvent.target || oEvent.srcElement;
|
||||
|
||||
if (oEvent.type == "mousedown") {
|
||||
oThis.textbox.value = oTarget.firstChild.nodeValue;
|
||||
oThis.hideSuggestions();
|
||||
} else if (oEvent.type == "mouseover") {
|
||||
oThis.highlightSuggestion(oTarget);
|
||||
} else {
|
||||
oThis.textbox.focus();
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -288,14 +282,13 @@ FormSuggestions.prototype.requestSuggestions = function (oAutoSuggestControl /*:
|
|||
|
||||
if (!this.suggestions)
|
||||
return;
|
||||
if (!sTextboxValue.length)
|
||||
return;
|
||||
|
||||
//search for matching suggestions
|
||||
for (var i=0; i < this.suggestions.length; i++) {
|
||||
if (this.suggestions[i].toLowerCase().indexOf(sTextboxValue) == 0) {
|
||||
aSuggestions.push(this.suggestions[i]);
|
||||
}
|
||||
if (sTextboxValue.length)
|
||||
for (var i=0; i < this.suggestions.length; i++) {
|
||||
if (this.suggestions[i].toLowerCase().indexOf(sTextboxValue) == 0) {
|
||||
aSuggestions.push(this.suggestions[i]);
|
||||
}
|
||||
}
|
||||
//provide suggestions to the control
|
||||
oAutoSuggestControl.autosuggest(aSuggestions);
|
||||
|
@ -308,9 +301,11 @@ function initSuggestions () {
|
|||
{
|
||||
var ename = inputs[i].getAttribute("name");
|
||||
var eid = inputs[i].getAttribute("id");
|
||||
var autocomplete = inputs[i].getAttribute ("autocomplete");
|
||||
|
||||
if (!ename && eid)
|
||||
ename=eid;
|
||||
if (inputs[i].type == "text")
|
||||
var smth = new AutoSuggestControl(inputs[i], new FormSuggestions(ename));
|
||||
if (inputs[i].type == "text" && autocomplete != "off")
|
||||
var smth = new AutoSuggestControl (inputs[i], new FormSuggestions (ename));
|
||||
}
|
||||
};
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -64,13 +64,23 @@ colorful_tabs_browser_add_tab_cb (MidoriBrowser* browser,
|
|||
G_CALLBACK (colorful_tabs_view_notify_uri_cb), extension);
|
||||
}
|
||||
|
||||
static void
|
||||
colorful_tabs_app_add_browser_cb (MidoriApp* app,
|
||||
MidoriBrowser* browser,
|
||||
MidoriExtension* extension);
|
||||
|
||||
static void
|
||||
colorful_tabs_deactivate_cb (MidoriExtension* extension,
|
||||
MidoriBrowser* browser)
|
||||
{
|
||||
guint i;
|
||||
GtkWidget* view;
|
||||
MidoriApp* app = midori_extension_get_app (extension);
|
||||
|
||||
g_signal_handlers_disconnect_by_func (
|
||||
app, colorful_tabs_app_add_browser_cb, extension);
|
||||
g_signal_handlers_disconnect_by_func (
|
||||
browser, colorful_tabs_browser_add_tab_cb, extension);
|
||||
g_signal_handlers_disconnect_by_func (
|
||||
extension, colorful_tabs_deactivate_cb, browser);
|
||||
i = 0;
|
||||
|
@ -102,6 +112,7 @@ colorful_tabs_app_add_browser_cb (MidoriApp* app,
|
|||
G_CALLBACK (colorful_tabs_deactivate_cb), browser);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
colorful_tabs_activate_cb (MidoriExtension* extension,
|
||||
MidoriApp* app)
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
*/
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
#include <gdk/gdkkeysyms.h>
|
||||
|
||||
#include <midori/midori.h>
|
||||
#include <midori/gtkiconentry.h>
|
||||
|
@ -67,6 +68,8 @@ static void cm_tree_popup_collapse_activate_cb(GtkMenuItem *item, CookieManagerP
|
|||
static void cm_tree_popup_expand_activate_cb(GtkMenuItem *item, CookieManagerPage *cmp);
|
||||
static void cm_filter_tree(CookieManagerPage *cmp, const gchar *filter_text);
|
||||
|
||||
typedef void (*CMPathWalkFunc) (GtkTreePath *path);
|
||||
|
||||
|
||||
G_DEFINE_TYPE_WITH_CODE(CookieManagerPage, cookie_manager_page, GTK_TYPE_VBOX,
|
||||
G_IMPLEMENT_INTERFACE(MIDORI_TYPE_VIEWABLE,
|
||||
|
@ -225,7 +228,6 @@ static void cookie_manager_page_set_property(GObject *object, guint prop_id, con
|
|||
COOKIE_MANAGER_COL_VISIBLE);
|
||||
gtk_tree_view_set_model(GTK_TREE_VIEW(priv->treeview), GTK_TREE_MODEL(priv->filter));
|
||||
g_object_unref(priv->filter);
|
||||
|
||||
break;
|
||||
}
|
||||
case PROP_PARENT:
|
||||
|
@ -304,6 +306,28 @@ static void cm_set_button_sensitiveness(CookieManagerPage *cmp, gboolean set)
|
|||
}
|
||||
|
||||
|
||||
static void cm_free_selection_list(GList *rows, GFunc func)
|
||||
{
|
||||
g_list_foreach(rows, func, NULL);
|
||||
g_list_free(rows);
|
||||
}
|
||||
|
||||
|
||||
/* Fast version of g_list_length(). It only checks for the first few elements of
|
||||
* the list and returns the length 0, 1 or 2 where 2 means 2 elements or more. */
|
||||
static gint cm_list_length(GList *list)
|
||||
{
|
||||
if (list == NULL)
|
||||
return 0;
|
||||
else if (list->next == NULL)
|
||||
return 1;
|
||||
else if (list->next != NULL)
|
||||
return 2;
|
||||
|
||||
return 0; /* safe default */
|
||||
}
|
||||
|
||||
|
||||
static void cm_tree_popup_collapse_activate_cb(GtkMenuItem *item, CookieManagerPage *cmp)
|
||||
{
|
||||
CookieManagerPagePrivate *priv = COOKIE_MANAGER_PAGE_GET_PRIVATE(cmp);
|
||||
|
@ -342,72 +366,165 @@ static void cm_delete_cookie(CookieManagerPage *cmp, GtkTreeModel *model, GtkTre
|
|||
}
|
||||
|
||||
|
||||
static void cm_button_delete_clicked_cb(GtkToolButton *button, CookieManagerPage *cmp)
|
||||
static gboolean cm_try_to_select(CMPathWalkFunc path_func, GtkTreeSelection *selection,
|
||||
GtkTreeModel *model, GtkTreePath *path)
|
||||
{
|
||||
GtkTreeIter iter;
|
||||
|
||||
if (gtk_tree_path_get_depth(path) <= 0) /* sanity check */
|
||||
return FALSE;
|
||||
|
||||
/* modify the path using the passed function */
|
||||
if (path_func != NULL)
|
||||
path_func(path);
|
||||
|
||||
if (gtk_tree_path_get_depth(path) <= 0) /* sanity check */
|
||||
return FALSE;
|
||||
|
||||
/* check whether the path points to something valid and if so, select it */
|
||||
if (gtk_tree_model_get_iter(model, &iter, path))
|
||||
{
|
||||
GtkTreeView *treeview = gtk_tree_selection_get_tree_view(selection);
|
||||
gboolean was_expanded = gtk_tree_view_row_expanded(treeview, path);
|
||||
/* to get gtk_tree_selection_select_path() working, we need to expand the row first
|
||||
* if it isn't expanded yet, at least when the row is a parent item */
|
||||
if (! was_expanded)
|
||||
gtk_tree_view_expand_to_path(treeview, path);
|
||||
|
||||
gtk_tree_selection_select_path(selection, path);
|
||||
|
||||
if (! was_expanded) /* restore the previous state */
|
||||
gtk_tree_view_collapse_row(treeview, path);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
/* select an item after deletion */
|
||||
static void cm_select_path(CookieManagerPage *cmp, GtkTreeModel *model, GtkTreePath *path)
|
||||
{
|
||||
CookieManagerPagePrivate *priv = COOKIE_MANAGER_PAGE_GET_PRIVATE(cmp);
|
||||
GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(priv->treeview));
|
||||
CMPathWalkFunc path_funcs[] = {
|
||||
(CMPathWalkFunc) gtk_tree_path_prev, (CMPathWalkFunc) gtk_tree_path_up,
|
||||
(CMPathWalkFunc) gtk_tree_path_next, NULL };
|
||||
CMPathWalkFunc *path_func;
|
||||
|
||||
/* first try selecting the item directly to which path points */
|
||||
if (! cm_try_to_select(NULL, selection, model, path))
|
||||
{ /* if this failed, modify the path until we found something valid */
|
||||
path_func = path_funcs;
|
||||
while (*path_func != NULL)
|
||||
{
|
||||
if (cm_try_to_select(*path_func, selection, model, path))
|
||||
break;
|
||||
path_func++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void cm_delete_item(CookieManagerPage *cmp)
|
||||
{
|
||||
GtkTreeIter iter, iter_store, child;
|
||||
GtkTreeModel *model;
|
||||
GtkTreePath *path, *last_path;
|
||||
GtkTreeSelection *selection;
|
||||
GList *rows, *row;
|
||||
GList *refs = NULL;
|
||||
CookieManagerPagePrivate *priv = COOKIE_MANAGER_PAGE_GET_PRIVATE(cmp);
|
||||
|
||||
selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(priv->treeview));
|
||||
if (! gtk_tree_selection_get_selected(selection, &model, &iter))
|
||||
rows = gtk_tree_selection_get_selected_rows(selection, &model);
|
||||
if (cm_list_length(rows) == 0)
|
||||
return;
|
||||
|
||||
if (gtk_tree_model_iter_has_child(model, &iter))
|
||||
{
|
||||
GtkTreePath *path = gtk_tree_model_get_path(model, &iter);
|
||||
last_path = gtk_tree_path_copy(g_list_nth_data(rows, 0));
|
||||
|
||||
while (gtk_tree_model_iter_children(model, &child, &iter))
|
||||
/* as paths will change during delete, first create GtkTreeRowReferences for
|
||||
* all selected rows */
|
||||
row = rows;
|
||||
do
|
||||
{
|
||||
refs = g_list_append(refs, gtk_tree_row_reference_new(model, (GtkTreePath*) (row->data)));
|
||||
} while ((row = row->next) != NULL);
|
||||
|
||||
row = refs;
|
||||
do
|
||||
{
|
||||
/* get iter */
|
||||
path = gtk_tree_row_reference_get_path((GtkTreeRowReference*) row->data);
|
||||
if (path == NULL)
|
||||
continue;
|
||||
gtk_tree_model_get_iter(model, &iter, path);
|
||||
|
||||
if (gtk_tree_model_iter_has_child(model, &iter))
|
||||
{
|
||||
cm_delete_cookie(cmp, model, &child);
|
||||
cm_store_remove(cmp, &child);
|
||||
/* we retrieve again the iter at path because it got invalid by the delete operation */
|
||||
gtk_tree_model_get_iter(model, &iter, path);
|
||||
while (gtk_tree_model_iter_children(model, &child, &iter))
|
||||
{
|
||||
cm_delete_cookie(cmp, model, &child);
|
||||
cm_store_remove(cmp, &child);
|
||||
/* we retrieve again the iter at path because it got invalid by the delete operation */
|
||||
gtk_tree_model_get_iter(model, &iter, path);
|
||||
}
|
||||
/* remove/hide the parent */
|
||||
gtk_tree_model_filter_convert_iter_to_child_iter(GTK_TREE_MODEL_FILTER(priv->filter),
|
||||
&iter_store, &iter);
|
||||
if (gtk_tree_model_iter_has_child(GTK_TREE_MODEL(priv->store), &iter_store))
|
||||
gtk_tree_store_set(priv->store, &iter_store, COOKIE_MANAGER_COL_VISIBLE, FALSE, -1);
|
||||
else
|
||||
cm_store_remove(cmp, &iter);
|
||||
}
|
||||
else
|
||||
{
|
||||
GtkTreePath *path_store, *path_model;
|
||||
|
||||
gtk_tree_model_filter_convert_iter_to_child_iter(GTK_TREE_MODEL_FILTER(priv->filter),
|
||||
&iter_store, &iter);
|
||||
path_store = gtk_tree_model_get_path(GTK_TREE_MODEL(priv->store), &iter_store);
|
||||
path_model = gtk_tree_model_get_path(model, &iter);
|
||||
|
||||
cm_delete_cookie(cmp, model, &iter);
|
||||
gtk_tree_store_remove(priv->store, &iter_store);
|
||||
|
||||
/* check whether the parent still has children, otherwise delete it */
|
||||
if (gtk_tree_path_up(path_store))
|
||||
{
|
||||
gtk_tree_model_get_iter(GTK_TREE_MODEL(priv->store), &iter_store, path_store);
|
||||
if (! gtk_tree_model_iter_has_child(GTK_TREE_MODEL(priv->store), &iter_store))
|
||||
/* remove the empty parent */
|
||||
gtk_tree_store_remove(priv->store, &iter_store);
|
||||
}
|
||||
/* now for the filter model */
|
||||
if (gtk_tree_path_up(path_model))
|
||||
{
|
||||
gtk_tree_model_get_iter(model, &iter, path_model);
|
||||
if (! gtk_tree_model_iter_has_child(model, &iter))
|
||||
{
|
||||
gtk_tree_model_filter_convert_iter_to_child_iter(
|
||||
GTK_TREE_MODEL_FILTER(priv->filter), &iter_store, &iter);
|
||||
/* hide the empty parent */
|
||||
gtk_tree_store_set(priv->store, &iter_store, COOKIE_MANAGER_COL_VISIBLE, FALSE, -1);
|
||||
}
|
||||
}
|
||||
gtk_tree_path_free(path_store);
|
||||
gtk_tree_path_free(path_model);
|
||||
}
|
||||
gtk_tree_path_free(path);
|
||||
/* remove/hide the parent */
|
||||
gtk_tree_model_filter_convert_iter_to_child_iter(GTK_TREE_MODEL_FILTER(priv->filter),
|
||||
&iter_store, &iter);
|
||||
if (gtk_tree_model_iter_has_child(GTK_TREE_MODEL(priv->store), &iter_store))
|
||||
gtk_tree_store_set(priv->store, &iter_store, COOKIE_MANAGER_COL_VISIBLE, FALSE, -1);
|
||||
else
|
||||
cm_store_remove(cmp, &iter);
|
||||
}
|
||||
else
|
||||
{
|
||||
GtkTreePath *path_store, *path_model;
|
||||
} while ((row = row->next) != NULL);
|
||||
cm_free_selection_list(rows, (GFunc) gtk_tree_path_free);
|
||||
cm_free_selection_list(refs, (GFunc) gtk_tree_row_reference_free);
|
||||
|
||||
gtk_tree_model_filter_convert_iter_to_child_iter(GTK_TREE_MODEL_FILTER(priv->filter),
|
||||
&iter_store, &iter);
|
||||
path_store = gtk_tree_model_get_path(GTK_TREE_MODEL(priv->store), &iter_store);
|
||||
path_model = gtk_tree_model_get_path(model, &iter);
|
||||
cm_select_path(cmp, model, last_path);
|
||||
gtk_tree_path_free(last_path);
|
||||
}
|
||||
|
||||
cm_delete_cookie(cmp, model, &iter);
|
||||
gtk_tree_store_remove(priv->store, &iter_store);
|
||||
|
||||
/* check whether the parent still has children, otherwise delete it */
|
||||
if (gtk_tree_path_up(path_store))
|
||||
{
|
||||
gtk_tree_model_get_iter(GTK_TREE_MODEL(priv->store), &iter_store, path_store);
|
||||
if (! gtk_tree_model_iter_has_child(GTK_TREE_MODEL(priv->store), &iter_store))
|
||||
/* remove the empty parent */
|
||||
gtk_tree_store_remove(priv->store, &iter_store);
|
||||
}
|
||||
/* now for the filter model */
|
||||
if (gtk_tree_path_up(path_model))
|
||||
{
|
||||
gtk_tree_model_get_iter(model, &iter, path_model);
|
||||
if (! gtk_tree_model_iter_has_child(model, &iter))
|
||||
{
|
||||
gtk_tree_model_filter_convert_iter_to_child_iter(
|
||||
GTK_TREE_MODEL_FILTER(priv->filter), &iter_store, &iter);
|
||||
/* hide the empty parent */
|
||||
gtk_tree_store_set(priv->store, &iter_store, COOKIE_MANAGER_COL_VISIBLE, FALSE, -1);
|
||||
}
|
||||
}
|
||||
gtk_tree_path_free(path_store);
|
||||
gtk_tree_path_free(path_model);
|
||||
}
|
||||
static void cm_button_delete_clicked_cb(GtkToolButton *button, CookieManagerPage *cmp)
|
||||
{
|
||||
cm_delete_item(cmp);
|
||||
}
|
||||
|
||||
|
||||
|
@ -438,11 +555,12 @@ static void cm_delete_all_cookies_real(CookieManagerPage *cmp)
|
|||
else
|
||||
cm_store_remove(cmp, &iter);
|
||||
}
|
||||
gtk_tree_path_free(path_first);
|
||||
|
||||
/* now that we deleted all matching cookies, we reset the filter */
|
||||
gtk_entry_set_text(GTK_ENTRY(priv->filter_entry), "");
|
||||
cm_set_button_sensitiveness(cmp, FALSE);
|
||||
|
||||
cm_select_path(cmp, model, path_first);
|
||||
gtk_tree_path_free(path_first);
|
||||
}
|
||||
|
||||
|
||||
|
@ -478,6 +596,12 @@ static void cm_button_delete_all_clicked_cb(GtkToolButton *button, CookieManager
|
|||
}
|
||||
|
||||
|
||||
static const gchar *cm_skip_leading_dot(const gchar *text)
|
||||
{
|
||||
return (*text == '.') ? text + 1 : text;
|
||||
}
|
||||
|
||||
|
||||
static void cm_tree_drag_data_get_cb(GtkWidget *widget, GdkDragContext *drag_context,
|
||||
GtkSelectionData *data, guint info, guint ltime,
|
||||
CookieManagerPage *cmp)
|
||||
|
@ -485,11 +609,18 @@ static void cm_tree_drag_data_get_cb(GtkWidget *widget, GdkDragContext *drag_con
|
|||
GtkTreeIter iter, iter_store;
|
||||
GtkTreeSelection *selection;
|
||||
GtkTreeModel *model;
|
||||
GList *rows;
|
||||
CookieManagerPagePrivate *priv = COOKIE_MANAGER_PAGE_GET_PRIVATE(cmp);
|
||||
|
||||
selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(priv->treeview));
|
||||
if (! gtk_tree_selection_get_selected(selection, &model, &iter))
|
||||
rows = gtk_tree_selection_get_selected_rows(selection, &model);
|
||||
if (cm_list_length(rows) != 1)
|
||||
{
|
||||
cm_free_selection_list(rows, (GFunc) gtk_tree_path_free);
|
||||
return;
|
||||
}
|
||||
/* get iter */
|
||||
gtk_tree_model_get_iter(model, &iter, (GtkTreePath*) (g_list_nth_data(rows, 0)));
|
||||
|
||||
gtk_tree_model_filter_convert_iter_to_child_iter(
|
||||
GTK_TREE_MODEL_FILTER(model), &iter_store, &iter);
|
||||
|
@ -497,18 +628,25 @@ static void cm_tree_drag_data_get_cb(GtkWidget *widget, GdkDragContext *drag_con
|
|||
if (gtk_tree_store_iter_is_valid(priv->store, &iter_store))
|
||||
{
|
||||
SoupCookie *cookie;
|
||||
gchar *name, *text;
|
||||
gchar *name;
|
||||
const gchar *text;
|
||||
|
||||
gtk_tree_model_get(model, &iter,
|
||||
COOKIE_MANAGER_COL_NAME, &name,
|
||||
COOKIE_MANAGER_COL_COOKIE, &cookie,
|
||||
-1);
|
||||
|
||||
if (cookie == NULL && name != NULL)
|
||||
if (name != NULL)
|
||||
{
|
||||
/* skip a leading dot */
|
||||
text = (*name == '.') ? name + 1 : name;
|
||||
GtkTreeIter parent;
|
||||
/* get the name of the parent item which should be a domain item */
|
||||
if (cookie != NULL && gtk_tree_model_iter_parent(model, &parent, &iter))
|
||||
{
|
||||
g_free(name);
|
||||
gtk_tree_model_get(model, &parent, COOKIE_MANAGER_COL_NAME, &name, -1);
|
||||
}
|
||||
|
||||
text = cm_skip_leading_dot(name);
|
||||
gtk_selection_data_set_text(data, text, -1);
|
||||
}
|
||||
g_free(name);
|
||||
|
@ -552,6 +690,24 @@ static gchar *cm_get_cookie_description_text(SoupCookie *cookie)
|
|||
}
|
||||
|
||||
|
||||
static gchar *cm_get_domain_description_text(const gchar *domain, gint cookie_count)
|
||||
{
|
||||
gchar *str, *text;
|
||||
|
||||
domain = cm_skip_leading_dot(domain);
|
||||
|
||||
text = g_markup_printf_escaped(
|
||||
_("<b>Domain</b>: %s\n<b>Cookies</b>: %d"),
|
||||
domain, cookie_count);
|
||||
|
||||
str = g_strconcat(text, "\n\n\n\n", NULL);
|
||||
|
||||
g_free(text);
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
|
||||
#if GTK_CHECK_VERSION(2, 12, 0)
|
||||
static gboolean cm_tree_query_tooltip(GtkWidget *widget, gint x, gint y, gboolean keyboard_mode,
|
||||
GtkTooltip *tooltip, CookieManagerPage *cmp)
|
||||
|
@ -683,24 +839,36 @@ static void cm_filter_entry_clear_icon_released_cb(GtkIconEntry *e, gint pos, gi
|
|||
|
||||
static void cm_tree_selection_changed_cb(GtkTreeSelection *selection, CookieManagerPage *cmp)
|
||||
{
|
||||
GList *rows;
|
||||
GtkTreeIter iter, iter_store;
|
||||
GtkTreeModel *model;
|
||||
gchar *text;
|
||||
gchar *text, *name;
|
||||
gboolean valid = TRUE;
|
||||
gboolean delete_possible = FALSE;
|
||||
gboolean delete_possible = TRUE;
|
||||
guint rows_len;
|
||||
SoupCookie *cookie;
|
||||
CookieManagerPagePrivate *priv = COOKIE_MANAGER_PAGE_GET_PRIVATE(cmp);
|
||||
|
||||
if (! gtk_tree_selection_get_selected(selection, &model, &iter))
|
||||
rows = gtk_tree_selection_get_selected_rows(selection, &model);
|
||||
rows_len = cm_list_length(rows);
|
||||
if (rows_len == 0)
|
||||
{
|
||||
valid = FALSE;
|
||||
else
|
||||
delete_possible = FALSE;
|
||||
}
|
||||
else if (rows_len == 1)
|
||||
{
|
||||
/* get iter */
|
||||
gtk_tree_model_get_iter(model, &iter, (GtkTreePath*) (g_list_nth_data(rows, 0)));
|
||||
|
||||
gtk_tree_model_filter_convert_iter_to_child_iter(GTK_TREE_MODEL_FILTER(model),
|
||||
&iter_store, &iter);
|
||||
}
|
||||
else
|
||||
valid = FALSE;
|
||||
|
||||
if (valid && gtk_tree_store_iter_is_valid(priv->store, &iter_store))
|
||||
{
|
||||
delete_possible = TRUE;
|
||||
|
||||
gtk_tree_model_get(model, &iter, COOKIE_MANAGER_COL_COOKIE, &cookie, -1);
|
||||
if (cookie != NULL)
|
||||
{
|
||||
|
@ -711,13 +879,27 @@ static void cm_tree_selection_changed_cb(GtkTreeSelection *selection, CookieMana
|
|||
g_free(text);
|
||||
}
|
||||
else
|
||||
valid = FALSE;
|
||||
{
|
||||
gtk_tree_model_get(model, &iter, COOKIE_MANAGER_COL_NAME, &name, -1);
|
||||
if (name != NULL)
|
||||
{
|
||||
gint cookie_count = gtk_tree_model_iter_n_children(model, &iter);
|
||||
|
||||
text = cm_get_domain_description_text(name, cookie_count);
|
||||
gtk_label_set_markup(GTK_LABEL(priv->desc_label), text);
|
||||
|
||||
g_free(text);
|
||||
g_free(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
/* This is a bit hack'ish but we add some empty lines to get a minimum height of the
|
||||
* label at the bottom without any font size calculation. */
|
||||
if (! valid)
|
||||
gtk_label_set_text(GTK_LABEL(priv->desc_label), CM_EMPTY_LABEL_TEXT);
|
||||
cm_set_button_sensitiveness(cmp, delete_possible);
|
||||
|
||||
cm_free_selection_list(rows, (GFunc) gtk_tree_path_free);
|
||||
}
|
||||
|
||||
|
||||
|
@ -760,19 +942,36 @@ static gboolean cm_tree_button_release_event_cb(GtkWidget *widget, GdkEventButto
|
|||
}
|
||||
|
||||
|
||||
static gboolean cm_tree_key_press_cb(GtkWidget *widget, GdkEventKey *event, CookieManagerPage *cmp)
|
||||
{
|
||||
if (event->keyval == GDK_Delete && !
|
||||
(event->state & (GDK_SHIFT_MASK | GDK_CONTROL_MASK | GDK_MOD1_MASK)))
|
||||
{
|
||||
cm_delete_item(cmp);
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
static gboolean cm_tree_button_press_event_cb(GtkWidget *widget, GdkEventButton *ev,
|
||||
CookieManagerPage *cmp)
|
||||
{
|
||||
gboolean ret = FALSE;
|
||||
|
||||
if (ev->type == GDK_2BUTTON_PRESS)
|
||||
{
|
||||
GtkTreeSelection *selection;
|
||||
GtkTreeModel *model;
|
||||
GtkTreeIter iter;
|
||||
GList *rows;
|
||||
|
||||
selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(widget));
|
||||
|
||||
if (gtk_tree_selection_get_selected(selection, &model, &iter))
|
||||
rows = gtk_tree_selection_get_selected_rows(selection, &model);
|
||||
if (cm_list_length(rows) == 1)
|
||||
{
|
||||
/* get iter */
|
||||
gtk_tree_model_get_iter(model, &iter, (GtkTreePath*) (g_list_nth_data(rows, 0)));
|
||||
/* double click on parent node expands/collapses it */
|
||||
if (gtk_tree_model_iter_has_child(model, &iter))
|
||||
{
|
||||
|
@ -785,12 +984,32 @@ static gboolean cm_tree_button_press_event_cb(GtkWidget *widget, GdkEventButton
|
|||
|
||||
gtk_tree_path_free(path);
|
||||
|
||||
return TRUE;
|
||||
ret = TRUE;
|
||||
}
|
||||
}
|
||||
cm_free_selection_list(rows, (GFunc) gtk_tree_path_free);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
|
||||
static void cm_tree_render_text_cb(GtkTreeViewColumn *column, GtkCellRenderer *renderer, GtkTreeModel *model,
|
||||
GtkTreeIter *iter, gpointer data)
|
||||
{
|
||||
gchar *name;
|
||||
|
||||
gtk_tree_model_get(model, iter, COOKIE_MANAGER_COL_NAME, &name, -1);
|
||||
|
||||
if (name != NULL && *name != '.')
|
||||
{
|
||||
gchar *display_name = g_strconcat(" ", name, NULL);
|
||||
g_object_set(renderer, "text", display_name, NULL);
|
||||
g_free(display_name);
|
||||
}
|
||||
else
|
||||
g_object_set(renderer, "text", name, NULL);
|
||||
|
||||
g_free(name);
|
||||
}
|
||||
|
||||
|
||||
|
@ -812,6 +1031,8 @@ static GtkWidget *cm_tree_prepare(CookieManagerPage *cmp)
|
|||
gtk_tree_view_column_set_sort_indicator(column, TRUE);
|
||||
gtk_tree_view_column_set_sort_column_id(column, COOKIE_MANAGER_COL_NAME);
|
||||
gtk_tree_view_column_set_resizable(column, TRUE);
|
||||
gtk_tree_view_column_set_cell_data_func(column, renderer,
|
||||
(GtkTreeCellDataFunc) cm_tree_render_text_cb, NULL, NULL);
|
||||
gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), column);
|
||||
|
||||
gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(treeview), TRUE);
|
||||
|
@ -820,10 +1041,11 @@ static GtkWidget *cm_tree_prepare(CookieManagerPage *cmp)
|
|||
|
||||
/* selection handling */
|
||||
sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview));
|
||||
gtk_tree_selection_set_mode(sel, GTK_SELECTION_SINGLE);
|
||||
gtk_tree_selection_set_mode(sel, GTK_SELECTION_MULTIPLE);
|
||||
|
||||
/* signals */
|
||||
g_signal_connect(sel, "changed", G_CALLBACK(cm_tree_selection_changed_cb), cmp);
|
||||
g_signal_connect(treeview, "key-press-event", G_CALLBACK(cm_tree_key_press_cb), cmp);
|
||||
g_signal_connect(treeview, "button-press-event", G_CALLBACK(cm_tree_button_press_event_cb), cmp);
|
||||
g_signal_connect(treeview, "button-release-event", G_CALLBACK(cm_tree_button_release_event_cb), cmp);
|
||||
g_signal_connect(treeview, "popup-menu", G_CALLBACK(cm_tree_popup_menu_cb), cmp);
|
||||
|
@ -843,7 +1065,6 @@ static GtkWidget *cm_tree_prepare(CookieManagerPage *cmp)
|
|||
GDK_ACTION_COPY
|
||||
);
|
||||
gtk_drag_source_add_text_targets(treeview);
|
||||
/*gtk_drag_source_add_uri_targets(treeview);*/
|
||||
g_signal_connect(treeview, "drag-data-get", G_CALLBACK(cm_tree_drag_data_get_cb), cmp);
|
||||
|
||||
/* popup menu */
|
||||
|
|
|
@ -1,203 +0,0 @@
|
|||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
#include <midori/midori.h>
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <glib/gstdio.h>
|
||||
#if HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#define MAXHOSTS 50
|
||||
static gchar* hosts = NULL;
|
||||
static int host_count;
|
||||
|
||||
static bool
|
||||
dnsprefetch_do_prefetch (const char* uri)
|
||||
{
|
||||
SoupURI* s_uri;
|
||||
|
||||
if (!uri)
|
||||
return FALSE;
|
||||
s_uri = soup_uri_new (uri);
|
||||
if (!s_uri || !s_uri->host)
|
||||
return FALSE;
|
||||
|
||||
#if GLIB_CHECK_VERSION (2, 22, 0)
|
||||
if (g_hostname_is_ip_address (s_uri->host))
|
||||
#else
|
||||
if (g_ascii_isdigit (s_uri->host[0]) && g_strstr_len (s_uri->host, 4, "."))
|
||||
#endif
|
||||
{
|
||||
soup_uri_free (s_uri);
|
||||
return FALSE;
|
||||
}
|
||||
if (!g_str_has_prefix (uri, "http"))
|
||||
{
|
||||
soup_uri_free (s_uri);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!g_regex_match_simple (s_uri->host, hosts,
|
||||
G_REGEX_CASELESS, G_REGEX_MATCH_NOTEMPTY))
|
||||
{
|
||||
SoupAddress* address;
|
||||
gchar* new_hosts;
|
||||
|
||||
address = soup_address_new (s_uri->host, SOUP_ADDRESS_ANY_PORT);
|
||||
soup_address_resolve_async (address, 0, 0, 0, 0);
|
||||
g_object_unref (address);
|
||||
|
||||
if (host_count > MAXHOSTS)
|
||||
{
|
||||
katze_assign (hosts, g_strdup (""));
|
||||
host_count = 0;
|
||||
}
|
||||
host_count++;
|
||||
new_hosts = g_strdup_printf ("%s|%s", hosts, s_uri->host);
|
||||
katze_assign (hosts, new_hosts);
|
||||
}
|
||||
soup_uri_free (s_uri);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
dnsprefetch_prefetch_cb (WebKitWebView* web_view,
|
||||
const gchar* title,
|
||||
const char* uri,
|
||||
gpointer user_data)
|
||||
{
|
||||
dnsprefetch_do_prefetch (uri);
|
||||
}
|
||||
|
||||
static void
|
||||
dnsprefetch_add_tab_cb (MidoriBrowser* browser,
|
||||
MidoriView* view)
|
||||
{
|
||||
GtkWidget* web_view = gtk_bin_get_child (GTK_BIN (view));
|
||||
g_signal_connect (web_view, "hovering-over-link",
|
||||
G_CALLBACK (dnsprefetch_prefetch_cb), 0);
|
||||
}
|
||||
|
||||
static void
|
||||
dnsprefetch_deactivate_cb (MidoriExtension* extension,
|
||||
MidoriBrowser* browser);
|
||||
|
||||
static void
|
||||
dnsprefetch_add_tab_foreach_cb (MidoriView* view,
|
||||
MidoriBrowser* browser)
|
||||
{
|
||||
dnsprefetch_add_tab_cb (browser, view);
|
||||
}
|
||||
|
||||
static void
|
||||
dnsprefetch_app_add_browser_cb (MidoriApp* app,
|
||||
MidoriBrowser* browser,
|
||||
MidoriExtension* extension)
|
||||
{
|
||||
midori_browser_foreach (browser,
|
||||
(GtkCallback)dnsprefetch_add_tab_foreach_cb, browser);
|
||||
g_signal_connect (browser, "add-tab",
|
||||
G_CALLBACK (dnsprefetch_add_tab_cb), 0);
|
||||
g_signal_connect (extension, "deactivate",
|
||||
G_CALLBACK (dnsprefetch_deactivate_cb), browser);
|
||||
}
|
||||
|
||||
static void
|
||||
dnsprefetch_deactivate_tabs (MidoriView* view,
|
||||
MidoriBrowser* browser)
|
||||
{
|
||||
GtkWidget* web_view = gtk_bin_get_child (GTK_BIN (view));
|
||||
g_signal_handlers_disconnect_by_func (
|
||||
browser, dnsprefetch_add_tab_cb, 0);
|
||||
g_signal_handlers_disconnect_by_func (
|
||||
web_view, dnsprefetch_do_prefetch, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
dnsprefetch_deactivate_cb (MidoriExtension* extension,
|
||||
MidoriBrowser* browser)
|
||||
{
|
||||
MidoriApp* app = midori_extension_get_app (extension);
|
||||
|
||||
katze_assign (hosts, g_strdup (""));
|
||||
host_count = 0;
|
||||
|
||||
g_signal_handlers_disconnect_by_func (
|
||||
extension, dnsprefetch_deactivate_cb, browser);
|
||||
g_signal_handlers_disconnect_by_func (
|
||||
app, dnsprefetch_app_add_browser_cb, extension);
|
||||
midori_browser_foreach (browser, (GtkCallback)dnsprefetch_deactivate_tabs, browser);
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
dnsprefetch_activate_cb (MidoriExtension* extension,
|
||||
MidoriApp* app)
|
||||
{
|
||||
KatzeArray* browsers;
|
||||
MidoriBrowser* browser;
|
||||
guint i;
|
||||
|
||||
katze_assign (hosts, g_strdup (""));
|
||||
host_count = 0;
|
||||
|
||||
browsers = katze_object_get_object (app, "browsers");
|
||||
i = 0;
|
||||
while ((browser = katze_array_get_nth_item (browsers, i++)))
|
||||
dnsprefetch_app_add_browser_cb (app, browser, extension);
|
||||
g_signal_connect (app, "add-browser",
|
||||
G_CALLBACK (dnsprefetch_app_add_browser_cb), extension);
|
||||
|
||||
g_object_unref (browsers);
|
||||
}
|
||||
|
||||
#if G_ENABLE_DEBUG
|
||||
static void
|
||||
dnsprefetch_parse (void)
|
||||
{
|
||||
g_assert (!dnsprefetch_do_prefetch (NULL));
|
||||
g_assert (dnsprefetch_do_prefetch ("http://google.com"));
|
||||
g_assert (dnsprefetch_do_prefetch ("http://google.com"));
|
||||
g_assert (dnsprefetch_do_prefetch ("http://googlecom"));
|
||||
g_assert (dnsprefetch_do_prefetch ("http://1kino.com"));
|
||||
g_assert (dnsprefetch_do_prefetch ("http://"));
|
||||
g_assert (!dnsprefetch_do_prefetch ("http:/"));
|
||||
g_assert (!dnsprefetch_do_prefetch ("http"));
|
||||
g_assert (!dnsprefetch_do_prefetch ("ftp://ftphost.org"));
|
||||
g_assert (!dnsprefetch_do_prefetch ("http://10.0.0.1"));
|
||||
g_assert (!dnsprefetch_do_prefetch ("about:blank"));
|
||||
g_assert (!dnsprefetch_do_prefetch ("javascript: alert()"));
|
||||
}
|
||||
|
||||
void
|
||||
extension_test (void)
|
||||
{
|
||||
katze_assign (hosts, g_strdup (""));
|
||||
host_count = 0;
|
||||
g_test_add_func ("/extensions/dnsprefetch/parse", dnsprefetch_parse);
|
||||
}
|
||||
#endif
|
||||
|
||||
MidoriExtension*
|
||||
extension_init (void)
|
||||
{
|
||||
MidoriExtension* extension = g_object_new (MIDORI_TYPE_EXTENSION,
|
||||
"name", _("DNS prefetching"),
|
||||
"description", _("Prefetch IP addresses of hovered links"),
|
||||
"version", "0.1",
|
||||
"authors", "Alexander V. Butenko <a.butenka@gmail.com>",
|
||||
NULL);
|
||||
g_signal_connect (extension, "activate",
|
||||
G_CALLBACK (dnsprefetch_activate_cb), NULL);
|
||||
|
||||
return extension;
|
||||
}
|
|
@ -263,7 +263,6 @@ parse_feed (gchar* data,
|
|||
xerror->message);
|
||||
xmlResetLastError ();
|
||||
}
|
||||
xmlCleanupParser ();
|
||||
xmlMemoryDump ();
|
||||
|
||||
return *error ? FALSE : TRUE;
|
||||
|
|
|
@ -105,6 +105,14 @@ feed_deactivate_cb (MidoriExtension* extension,
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
feed_dialog_response_cb (GtkWidget* dialog,
|
||||
gint response,
|
||||
gpointer data)
|
||||
{
|
||||
gtk_widget_destroy (dialog);
|
||||
}
|
||||
|
||||
static KatzeArray*
|
||||
feed_add_item (KatzeArray* feeds,
|
||||
const gchar* uri)
|
||||
|
@ -126,8 +134,8 @@ feed_add_item (KatzeArray* feeds,
|
|||
_("Feed '%s' already exists"), uri);
|
||||
gtk_window_set_title (GTK_WINDOW (dialog), EXTENSION_NAME);
|
||||
gtk_widget_show (dialog);
|
||||
g_signal_connect_swapped (dialog, "response",
|
||||
G_CALLBACK (gtk_widget_destroy), dialog);
|
||||
g_signal_connect (dialog, "response",
|
||||
G_CALLBACK (feed_dialog_response_cb), NULL);
|
||||
|
||||
}
|
||||
else
|
||||
|
|
|
@ -31,22 +31,24 @@ static gchar* jsforms;
|
|||
static gboolean
|
||||
formhistory_prepare_js ()
|
||||
{
|
||||
gchar* data_name;
|
||||
gchar* data_path;
|
||||
gchar* autosuggest;
|
||||
gchar* style;
|
||||
guint i;
|
||||
gchar* file;
|
||||
|
||||
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))
|
||||
data_name = g_build_filename (PACKAGE_NAME, "res", NULL);
|
||||
data_path = sokoke_find_data_filename (data_name);
|
||||
g_free (data_name);
|
||||
file = g_build_filename (data_path, G_DIR_SEPARATOR_S, "autosuggestcontrol.js",NULL);
|
||||
if (!g_file_get_contents (file, &autosuggest, NULL, NULL))
|
||||
return FALSE;
|
||||
g_file_get_contents (file, &autosuggest, NULL, NULL);
|
||||
g_strchomp (autosuggest);
|
||||
|
||||
file = g_build_filename (data_path,"/autosuggestcontrol.css",NULL);
|
||||
if (!g_file_test (file, G_FILE_TEST_EXISTS))
|
||||
file = g_build_filename (data_path, G_DIR_SEPARATOR_S, "autosuggestcontrol.css",NULL);
|
||||
if(!g_file_get_contents (file, &style, NULL, NULL))
|
||||
return FALSE;
|
||||
g_file_get_contents (file, &style, NULL, NULL);
|
||||
g_strchomp (style);
|
||||
i = 0;
|
||||
while (style[i])
|
||||
|
@ -58,15 +60,17 @@ formhistory_prepare_js ()
|
|||
|
||||
jsforms = g_strdup_printf (
|
||||
"%s"
|
||||
"window.addEventListener (\"load\", function () { initSuggestions (); }, true);"
|
||||
"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);"
|
||||
" if (document.getElementById('formhistory'))"
|
||||
" return;"
|
||||
" initSuggestions ();"
|
||||
" var mystyle = document.createElement('style');"
|
||||
" mystyle.setAttribute('type', 'text/css');"
|
||||
" mystyle.setAttribute('id', 'formhistory');"
|
||||
" mystyle.appendChild(document.createTextNode('%s'));"
|
||||
" var head = document.getElementsByTagName('head')[0];"
|
||||
" if (head) head.appendChild(mystyle);"
|
||||
"}, true);",
|
||||
autosuggest,
|
||||
style);
|
||||
|
@ -191,7 +195,6 @@ formhistory_navigation_decision_cb (WebKitWebView* web_view,
|
|||
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 "|||" */
|
||||
|
@ -203,18 +206,19 @@ formhistory_navigation_decision_cb (WebKitWebView* web_view,
|
|||
" var eid = inputs[i].getAttribute('id');"
|
||||
" if (!ename && eid)"
|
||||
" ename=eid;"
|
||||
" out += ename+'|,|'+inputs[i].value +'|,|'+inputs[i].type +'|||';"
|
||||
" if (inputs[i].getAttribute('autocomplete') != 'off')"
|
||||
" 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)
|
||||
if (webkit_web_navigation_action_get_reason (action) == WEBKIT_WEB_NAVIGATION_REASON_FORM_SUBMITTED)
|
||||
{
|
||||
JSContextRef js_context = webkit_web_frame_get_global_context (web_frame);
|
||||
gchar* value = sokoke_js_script_eval (js_context, script, NULL);
|
||||
if (value)
|
||||
if (value && *value)
|
||||
{
|
||||
gpointer db = g_object_get_data (G_OBJECT (extension), "formhistory-db");
|
||||
gchar** inputs = g_strsplit (value, "|||", 0);
|
||||
|
@ -286,13 +290,15 @@ formhistory_session_request_queued_cb (SoupSession* session,
|
|||
#endif
|
||||
|
||||
static void
|
||||
formhistory_window_object_cleared_cb (GtkWidget* web_view,
|
||||
formhistory_window_object_cleared_cb (WebKitWebView* web_view,
|
||||
WebKitWebFrame* web_frame,
|
||||
JSContextRef js_context,
|
||||
JSObjectRef js_window)
|
||||
{
|
||||
webkit_web_view_execute_script (WEBKIT_WEB_VIEW (web_view),
|
||||
formhistory_build_js ());
|
||||
gchar* script;
|
||||
script = formhistory_build_js ();
|
||||
sokoke_js_script_eval (js_context, script, NULL);
|
||||
g_free (script);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -343,8 +349,6 @@ formhistory_deactivate_tabs (MidoriView* view,
|
|||
MidoriExtension* extension)
|
||||
{
|
||||
GtkWidget* web_view = gtk_bin_get_child (GTK_BIN (view));
|
||||
g_signal_handlers_disconnect_by_func (
|
||||
browser, formhistory_add_tab_cb, extension);
|
||||
g_signal_handlers_disconnect_by_func (
|
||||
web_view, formhistory_window_object_cleared_cb, NULL);
|
||||
#if WEBKIT_CHECK_VERSION (1, 1, 4)
|
||||
|
@ -365,6 +369,8 @@ formhistory_deactivate_cb (MidoriExtension* extension,
|
|||
sqlite3* db;
|
||||
#endif
|
||||
|
||||
g_signal_handlers_disconnect_by_func (
|
||||
browser, formhistory_add_tab_cb, extension);
|
||||
g_signal_handlers_disconnect_by_func (
|
||||
extension, formhistory_deactivate_cb, browser);
|
||||
g_signal_handlers_disconnect_by_func (
|
||||
|
@ -372,7 +378,7 @@ formhistory_deactivate_cb (MidoriExtension* extension,
|
|||
midori_browser_foreach (browser,
|
||||
(GtkCallback)formhistory_deactivate_tabs, extension);
|
||||
|
||||
jsforms = "";
|
||||
katze_assign (jsforms, NULL);
|
||||
if (global_keys)
|
||||
g_hash_table_destroy (global_keys);
|
||||
|
||||
|
@ -429,6 +435,8 @@ 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(!jsforms)
|
||||
formhistory_prepare_js ();
|
||||
#if HAVE_SQLITE
|
||||
config_dir = midori_extension_get_config_dir (extension);
|
||||
katze_mkdir_with_parents (config_dir, 0700);
|
||||
|
@ -498,7 +506,7 @@ extension_init (void)
|
|||
|
||||
if (formhistory_prepare_js ())
|
||||
{
|
||||
ver = "0.1";
|
||||
ver = "1.0";
|
||||
desc = g_strdup (_("Stores history of entered form data"));
|
||||
}
|
||||
else
|
||||
|
|
|
@ -132,6 +132,14 @@ shortcuts_hotkey_for_action (GtkAction* action,
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
shortcuts_preferences_response_cb (GtkWidget* dialog,
|
||||
gint response,
|
||||
gpointer data)
|
||||
{
|
||||
gtk_widget_destroy (dialog);
|
||||
}
|
||||
|
||||
static GtkWidget*
|
||||
shortcuts_get_preferences_dialog (MidoriExtension* extension)
|
||||
{
|
||||
|
@ -172,7 +180,7 @@ shortcuts_get_preferences_dialog (MidoriExtension* extension)
|
|||
sokoke_widget_get_text_size (dialog, "M", &width, &height);
|
||||
gtk_window_set_default_size (GTK_WINDOW (dialog), width * 52, height * 24);
|
||||
g_signal_connect (dialog, "response",
|
||||
G_CALLBACK (gtk_widget_destroy), dialog);
|
||||
G_CALLBACK (shortcuts_preferences_response_cb), NULL);
|
||||
if ((xfce_heading = sokoke_xfce_header_new (
|
||||
gtk_window_get_icon_name (GTK_WINDOW (dialog)), dialog_title)))
|
||||
gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
|
||||
|
|
|
@ -13,8 +13,6 @@
|
|||
|
||||
#include "config.h"
|
||||
|
||||
#if !HAVE_HILDON
|
||||
|
||||
typedef struct
|
||||
{
|
||||
GtkWidget *dialog;
|
||||
|
@ -604,24 +602,16 @@ static void tb_editor_activate_cb(MidoriExtension *extension, MidoriApp *app)
|
|||
g_object_unref(browsers);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
MidoriExtension *extension_init(void)
|
||||
{
|
||||
MidoriExtension* extension = g_object_new(MIDORI_TYPE_EXTENSION,
|
||||
"name", _("Toolbar Editor"),
|
||||
#if !HAVE_HILDON
|
||||
"description", _("Easily edit the toolbar layout"),
|
||||
"version", "0.1",
|
||||
#else
|
||||
"description", _("Not available on this platform"),
|
||||
#endif
|
||||
"authors", "Enrico Tröger <enrico(dot)troeger(at)uvena(dot)de>",
|
||||
NULL);
|
||||
|
||||
#if !HAVE_HILDON
|
||||
g_signal_connect(extension, "activate", G_CALLBACK(tb_editor_activate_cb), NULL);
|
||||
#endif
|
||||
|
||||
return extension;
|
||||
}
|
||||
|
|
|
@ -21,8 +21,6 @@
|
|||
#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*
|
||||
|
@ -43,7 +41,8 @@ web_cache_get_cached_path (MidoriExtension* extension,
|
|||
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);
|
||||
/* FIXME: Wrong place? */
|
||||
katze_mkdir_with_parents (sub_path, 0700);
|
||||
g_free (folder);
|
||||
|
||||
encoded = soup_uri_encode (uri, "/");
|
||||
|
@ -61,65 +60,6 @@ web_cache_get_cached_path (MidoriExtension* extension,
|
|||
}
|
||||
|
||||
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)
|
||||
{
|
||||
|
@ -131,11 +71,15 @@ web_cache_save_headers (SoupMessage* msg,
|
|||
|
||||
soup_message_headers_iter_init (&iter, hdrs);
|
||||
dscfd = g_fopen (dsc_filename, "w");
|
||||
g_free (dsc_filename);
|
||||
if (!dscfd)
|
||||
return FALSE;
|
||||
|
||||
while (soup_message_headers_iter_next (&iter, &name, &value))
|
||||
g_fprintf (dscfd, "%s: %s\n", name, value);
|
||||
fclose (dscfd);
|
||||
|
||||
g_free (dsc_filename);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
GHashTable*
|
||||
|
@ -144,59 +88,60 @@ web_cache_get_headers (gchar* filename)
|
|||
GHashTable* headers;
|
||||
FILE* file;
|
||||
gchar* dsc_filename;
|
||||
gchar line[128];
|
||||
|
||||
if (!filename)
|
||||
return NULL;
|
||||
|
||||
/* use g_access() instead of g_file_test for better performance */
|
||||
if (g_access (filename, F_OK) != 0)
|
||||
return NULL;
|
||||
|
||||
dsc_filename = g_strdup_printf ("%s.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))
|
||||
if (!(file = g_fopen (dsc_filename, "r")))
|
||||
{
|
||||
g_hash_table_destroy (headers);
|
||||
g_free (dsc_filename);
|
||||
return headers;
|
||||
return NULL;
|
||||
}
|
||||
if ((file = g_fopen (dsc_filename, "r")))
|
||||
while (fgets (line, 128, file))
|
||||
{
|
||||
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);
|
||||
}
|
||||
gchar** data;
|
||||
|
||||
if (line == NULL)
|
||||
continue;
|
||||
|
||||
g_strchomp (line);
|
||||
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
|
||||
static GFile*
|
||||
web_cache_tmp_prepare (gchar* filename)
|
||||
{
|
||||
gchar* tmp_filename = g_strdup_printf ("%s.tmp", filename);
|
||||
GFile *file;
|
||||
|
||||
/* 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))
|
||||
gchar* tmp_filename = g_strdup_printf ("%s.tmp", filename);
|
||||
if (g_access (tmp_filename, F_OK) == 0)
|
||||
{
|
||||
g_free (tmp_filename);
|
||||
return FALSE;
|
||||
return NULL;
|
||||
}
|
||||
g_file_set_contents (tmp_filename, "", -1, NULL);
|
||||
file = g_file_new_for_path (tmp_filename);
|
||||
g_free (tmp_filename);
|
||||
return TRUE;
|
||||
|
||||
return file;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -204,27 +149,36 @@ web_cache_set_content_type (SoupMessage* msg,
|
|||
SoupBuffer* buffer)
|
||||
{
|
||||
#if WEBKIT_CHECK_VERSION (1, 1, 15)
|
||||
const char *ct;
|
||||
gchar* sniffed_type;
|
||||
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);
|
||||
if ((sniffed_type = soup_content_sniffer_sniff (sniffer, msg, buffer, NULL)))
|
||||
{
|
||||
g_signal_emit_by_name (msg, "content-sniffed", sniffed_type, NULL);
|
||||
g_free (sniffed_type);
|
||||
}
|
||||
else
|
||||
{
|
||||
const gchar* content_type = soup_message_headers_get_one (
|
||||
msg->response_headers, "Content-Type");
|
||||
g_signal_emit_by_name (msg, "content-sniffed", content_type, NULL);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
web_cache_message_finished_cb (SoupMessage* msg,
|
||||
gchar* filename)
|
||||
web_cache_message_finished_cb (SoupMessage* msg,
|
||||
GOutputStream* stream)
|
||||
{
|
||||
gchar* headers;
|
||||
gchar* tmp_headers;
|
||||
gchar* tmp_data;
|
||||
gchar* filename;
|
||||
|
||||
filename = g_object_get_data (G_OBJECT (stream), "filename");
|
||||
headers = g_strdup_printf ("%s.dsc", filename);
|
||||
tmp_headers = g_strdup_printf ("%s.dsc.tmp", filename);
|
||||
tmp_data = g_strdup_printf ("%s.tmp", filename);
|
||||
g_output_stream_close (stream, NULL, NULL);
|
||||
|
||||
if (msg->status_code == SOUP_STATUS_OK)
|
||||
{
|
||||
|
@ -237,92 +191,108 @@ web_cache_message_finished_cb (SoupMessage* msg,
|
|||
g_unlink (tmp_headers);
|
||||
}
|
||||
|
||||
g_object_unref (stream);
|
||||
g_free (headers);
|
||||
g_free (tmp_headers);
|
||||
g_free (tmp_data);
|
||||
}
|
||||
|
||||
static void web_cache_pause_message (SoupMessage* msg)
|
||||
{
|
||||
SoupSession* session;
|
||||
session = g_object_get_data (G_OBJECT (msg), "session");
|
||||
soup_session_pause_message (session, msg);
|
||||
}
|
||||
|
||||
static void web_cache_unpause_message (SoupMessage* msg)
|
||||
{
|
||||
SoupSession* session;
|
||||
session = g_object_get_data (G_OBJECT (msg), "session");
|
||||
soup_session_unpause_message (session, msg);
|
||||
}
|
||||
|
||||
static void
|
||||
web_cache_message_got_chunk_cb (SoupMessage* msg,
|
||||
SoupBuffer* chunk,
|
||||
gchar* filename)
|
||||
GOutputStream* stream)
|
||||
{
|
||||
GFile *file;
|
||||
GOutputStream *stream;
|
||||
gchar *tmp_filename;
|
||||
|
||||
if (!chunk->data || !chunk->length)
|
||||
return;
|
||||
/* FIXME g_output_stream_write_async (stream, chunk->data, chunk->length,
|
||||
G_PRIORITY_DEFAULT, NULL, NULL, (gpointer)chunk->length); */
|
||||
g_output_stream_write (stream, chunk->data, chunk->length, NULL, NULL);
|
||||
}
|
||||
|
||||
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)))
|
||||
static void
|
||||
web_cache_message_rewrite_async_cb (GFile *file,
|
||||
GAsyncResult* res,
|
||||
SoupMessage* msg)
|
||||
{
|
||||
SoupBuffer *buffer;
|
||||
char *data;
|
||||
gsize length;
|
||||
GError *error = NULL;
|
||||
|
||||
if (g_file_load_contents_finish (file, res, &data, &length, NULL, &error))
|
||||
{
|
||||
g_output_stream_write (stream, chunk->data, chunk->length, NULL, NULL);
|
||||
g_object_unref (stream);
|
||||
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);
|
||||
/* FIXME? */
|
||||
web_cache_unpause_message (msg);
|
||||
g_signal_emit_by_name (msg, "got-chunk", buffer, NULL);
|
||||
soup_buffer_free (buffer);
|
||||
g_free (data);
|
||||
soup_message_got_body (msg);
|
||||
soup_message_finished (msg);
|
||||
}
|
||||
g_object_unref (file);
|
||||
g_free (tmp_filename);
|
||||
g_object_unref (msg);
|
||||
}
|
||||
|
||||
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;
|
||||
GFile *file;
|
||||
|
||||
GHashTable* cache_headers = web_cache_get_headers (filename);
|
||||
if (!cache_headers)
|
||||
return;
|
||||
|
||||
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);
|
||||
g_hash_table_destroy (cache_headers);
|
||||
|
||||
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
|
||||
/* FIXME? It seems libsoup already said "goodbye" by the time
|
||||
the asynchronous function is starting to send data */
|
||||
web_cache_pause_message (msg);
|
||||
file = g_file_new_for_path (filename);
|
||||
g_free (filename);
|
||||
g_object_ref (msg);
|
||||
g_file_load_contents_async (file, NULL,
|
||||
(GAsyncReadyCallback)web_cache_message_rewrite_async_cb, msg);
|
||||
}
|
||||
|
||||
static void
|
||||
web_cache_mesage_got_headers_cb (SoupMessage* msg,
|
||||
MidoriExtension* extension)
|
||||
web_cache_mesage_got_headers_cb (SoupMessage* msg,
|
||||
gchar* filename)
|
||||
{
|
||||
SoupURI* soup_uri = soup_message_get_uri (msg);
|
||||
gchar* uri;
|
||||
gchar* filename;
|
||||
const gchar* nocache;
|
||||
SoupMessageHeaders *hdrs = msg->response_headers;
|
||||
const char* cl;
|
||||
|
||||
/* 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");
|
||||
cl = soup_message_headers_get_one (hdrs, "Content-Length");
|
||||
if (cl && atoi (cl) > MAXLENGTH)
|
||||
return;
|
||||
|
||||
|
@ -335,98 +305,64 @@ web_cache_mesage_got_headers_cb (SoupMessage* msg,
|
|||
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_debug ("loading from cache: %s", filename); */
|
||||
g_signal_handlers_disconnect_by_func (msg,
|
||||
web_cache_mesage_got_headers_cb, extension);
|
||||
web_cache_mesage_got_headers_cb, filename);
|
||||
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))
|
||||
GFile* file;
|
||||
GOutputStream* ostream;
|
||||
|
||||
/* g_debug ("updating cache: %s", filename); */
|
||||
if (!(file = 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);
|
||||
if (!web_cache_save_headers (msg, filename))
|
||||
return;
|
||||
|
||||
#if GLIB_CHECK_VERSION (2, 20, 0)
|
||||
ostream = (GOutputStream*)g_file_append_to (file,
|
||||
G_FILE_CREATE_PRIVATE | G_FILE_CREATE_REPLACE_DESTINATION, NULL, NULL);
|
||||
#else
|
||||
g_unlink (filename);
|
||||
ostream = (GOutputStream*)g_file_append_to (file,
|
||||
G_FILE_CREATE_PRIVATE, NULL, NULL);
|
||||
#endif
|
||||
g_object_unref (file);
|
||||
|
||||
if (!ostream)
|
||||
return;
|
||||
|
||||
g_object_set_data_full (G_OBJECT (ostream), "filename",
|
||||
filename, (GDestroyNotify)g_free);
|
||||
g_signal_connect (msg, "got-chunk",
|
||||
G_CALLBACK (web_cache_message_got_chunk_cb), ostream);
|
||||
g_signal_connect (msg, "finished",
|
||||
G_CALLBACK (web_cache_message_finished_cb), filename);
|
||||
G_CALLBACK (web_cache_message_finished_cb), ostream);
|
||||
}
|
||||
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 ("");
|
||||
gchar* uri = soup_uri_to_string (soup_uri, FALSE);
|
||||
|
||||
/* 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"))
|
||||
if (uri && 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;
|
||||
GHashTable* cache_headers;
|
||||
gchar* etag;
|
||||
gchar* last_modified;
|
||||
|
||||
cache_headers = web_cache_get_headers (filename);
|
||||
cache_headers = web_cache_get_headers (filename);
|
||||
if (cache_headers)
|
||||
{
|
||||
etag = g_hash_table_lookup (cache_headers, "ETag");
|
||||
last_modified = g_hash_table_lookup (cache_headers, "Last-Modified");
|
||||
if (etag)
|
||||
|
@ -435,52 +371,16 @@ web_cache_session_request_queued_cb (SoupSession* session,
|
|||
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_hash_table_destroy (cache_headers);
|
||||
}
|
||||
g_object_set_data (G_OBJECT (msg), "session", session);
|
||||
g_signal_connect (msg, "got-headers",
|
||||
G_CALLBACK (web_cache_mesage_got_headers_cb), filename);
|
||||
|
||||
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,
|
||||
|
@ -499,23 +399,11 @@ 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);
|
||||
|
@ -524,18 +412,6 @@ web_cache_app_add_browser_cb (MidoriApp* app,
|
|||
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)
|
||||
|
@ -549,13 +425,10 @@ web_cache_deactivate_cb (MidoriExtension* extension,
|
|||
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
|
||||
|
|
|
@ -29,3 +29,5 @@ for extension in extensions:
|
|||
obj.source = source
|
||||
obj.uselib = 'UNIQUE LIBSOUP GIO GTK SQLITE WEBKIT LIBXML HILDON'
|
||||
obj.install_path = '${LIBDIR}/midori'
|
||||
if bld.env['platform'] == 'win32':
|
||||
obj.uselib_local = 'midori'
|
||||
|
|
|
@ -166,7 +166,7 @@ katze_array_class_init (KatzeArrayClass* class)
|
|||
G_STRUCT_OFFSET (KatzeArrayClass, move_item),
|
||||
0,
|
||||
NULL,
|
||||
katze_cclosure_marshal_VOID__POINTER_INT,
|
||||
midori_cclosure_marshal_VOID__POINTER_INT,
|
||||
G_TYPE_NONE, 2,
|
||||
G_TYPE_POINTER,
|
||||
G_TYPE_INT);
|
||||
|
|
|
@ -33,7 +33,7 @@ typedef struct _KatzeArray KatzeArray;
|
|||
typedef struct _KatzeArrayClass KatzeArrayClass;
|
||||
|
||||
GType
|
||||
katze_array_get_type (void);
|
||||
katze_array_get_type (void) G_GNUC_CONST;
|
||||
|
||||
KatzeArray*
|
||||
katze_array_new (GType type);
|
||||
|
|
|
@ -12,7 +12,6 @@
|
|||
|
||||
#include "katze-arrayaction.h"
|
||||
|
||||
#include "katze-net.h"
|
||||
#include "katze-utils.h"
|
||||
#include "marshal.h"
|
||||
|
||||
|
@ -29,7 +28,6 @@ struct _KatzeArrayAction
|
|||
GtkAction parent_instance;
|
||||
|
||||
KatzeArray* array;
|
||||
KatzeNet* net;
|
||||
gboolean reversed;
|
||||
};
|
||||
|
||||
|
@ -136,7 +134,7 @@ katze_array_action_class_init (KatzeArrayActionClass* class)
|
|||
0,
|
||||
0,
|
||||
NULL,
|
||||
katze_cclosure_marshal_BOOLEAN__OBJECT_UINT,
|
||||
midori_cclosure_marshal_BOOLEAN__OBJECT_UINT,
|
||||
G_TYPE_BOOLEAN, 2,
|
||||
KATZE_TYPE_ITEM, G_TYPE_UINT);
|
||||
|
||||
|
@ -182,7 +180,6 @@ static void
|
|||
katze_array_action_init (KatzeArrayAction* array_action)
|
||||
{
|
||||
array_action->array = NULL;
|
||||
array_action->net = katze_net_new ();
|
||||
array_action->reversed = FALSE;
|
||||
}
|
||||
|
||||
|
@ -192,7 +189,6 @@ katze_array_action_finalize (GObject* object)
|
|||
KatzeArrayAction* array_action = KATZE_ARRAY_ACTION (object);
|
||||
|
||||
katze_object_assign (array_action->array, NULL);
|
||||
katze_object_assign (array_action->net, NULL);
|
||||
|
||||
G_OBJECT_CLASS (katze_array_action_parent_class)->finalize (object);
|
||||
}
|
||||
|
|
|
@ -35,7 +35,7 @@ typedef struct _KatzeArrayAction KatzeArrayAction;
|
|||
typedef struct _KatzeArrayActionClass KatzeArrayActionClass;
|
||||
|
||||
GType
|
||||
katze_array_action_get_type (void);
|
||||
katze_array_action_get_type (void) G_GNUC_CONST;
|
||||
|
||||
KatzeArray*
|
||||
katze_array_action_get_array (KatzeArrayAction* array_action);
|
||||
|
|
|
@ -20,6 +20,10 @@
|
|||
#include <glib/gi18n.h>
|
||||
#include <glib/gstdio.h>
|
||||
|
||||
#if !GTK_CHECK_VERSION (2, 14, 0)
|
||||
#define gtk_dialog_get_content_area(dialog) dialog->vbox
|
||||
#endif
|
||||
|
||||
struct _KatzeHttpAuth
|
||||
{
|
||||
GObject parent_instance;
|
||||
|
@ -110,6 +114,7 @@ authentication_message_got_headers_cb (SoupMessage* msg,
|
|||
fprintf (file, "%s\t%s\t%s\n", opaque_info,
|
||||
login->username, login->password);
|
||||
fclose (file);
|
||||
g_chmod (save->http_auth->filename, 0600);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -215,9 +220,9 @@ katze_http_auth_session_authenticate_cb (SoupSession* session,
|
|||
gtk_window_set_icon_name (GTK_WINDOW (dialog),
|
||||
GTK_STOCK_DIALOG_AUTHENTICATION);
|
||||
gtk_container_set_border_width (GTK_CONTAINER (dialog), 5);
|
||||
gtk_container_set_border_width (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), 5);
|
||||
gtk_container_set_border_width (GTK_CONTAINER (gtk_dialog_get_content_area (GTK_DIALOG (dialog))), 5);
|
||||
|
||||
gtk_box_set_spacing (GTK_BOX (GTK_DIALOG (dialog)->vbox), 5);
|
||||
gtk_box_set_spacing (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog))), 5);
|
||||
hbox = gtk_hbox_new (FALSE, 6);
|
||||
image = gtk_image_new_from_stock (GTK_STOCK_DIALOG_AUTHENTICATION,
|
||||
GTK_ICON_SIZE_DIALOG);
|
||||
|
@ -225,14 +230,14 @@ katze_http_auth_session_authenticate_cb (SoupSession* session,
|
|||
label = gtk_label_new (_("A username and a password are required\n"
|
||||
"to open this location:"));
|
||||
gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
|
||||
gtk_container_add (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), hbox);
|
||||
gtk_container_add (GTK_CONTAINER (gtk_dialog_get_content_area (GTK_DIALOG (dialog))), hbox);
|
||||
label = gtk_label_new (soup_auth_get_host (auth));
|
||||
gtk_container_add (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), label);
|
||||
gtk_container_add (GTK_CONTAINER (gtk_dialog_get_content_area (GTK_DIALOG (dialog))), label);
|
||||
/* If the realm is merely the host, omit the realm label */
|
||||
if (g_strcmp0 (soup_auth_get_host (auth), soup_auth_get_realm (auth)))
|
||||
{
|
||||
label = gtk_label_new (soup_auth_get_realm (auth));
|
||||
gtk_container_add (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), label);
|
||||
gtk_container_add (GTK_CONTAINER (gtk_dialog_get_content_area (GTK_DIALOG (dialog))), label);
|
||||
}
|
||||
sizegroup = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
|
||||
hbox = gtk_hbox_new (FALSE, 6);
|
||||
|
@ -247,28 +252,30 @@ katze_http_auth_session_authenticate_cb (SoupSession* session,
|
|||
gtk_box_pack_start (GTK_BOX (hbox), entry, TRUE, TRUE, 0);
|
||||
gtk_entry_set_activates_default (GTK_ENTRY (entry), TRUE);
|
||||
g_object_set_data (G_OBJECT (dialog), "username", entry);
|
||||
gtk_container_add (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), hbox);
|
||||
gtk_container_add (GTK_CONTAINER (gtk_dialog_get_content_area (GTK_DIALOG (dialog))), hbox);
|
||||
hbox = gtk_hbox_new (FALSE, 6);
|
||||
label = gtk_label_new (_("Password"));
|
||||
align = gtk_alignment_new (0, 0.5, 0, 0);
|
||||
gtk_container_add (GTK_CONTAINER (align), label);
|
||||
gtk_size_group_add_widget (sizegroup, align);
|
||||
gtk_box_pack_start (GTK_BOX (hbox), align, TRUE, TRUE, 0);
|
||||
entry = gtk_entry_new_with_max_length (32);
|
||||
entry = gtk_entry_new ();
|
||||
gtk_entry_set_max_length (GTK_ENTRY (entry), 32);
|
||||
if (login)
|
||||
gtk_entry_set_text (GTK_ENTRY (entry), login->password);
|
||||
gtk_entry_set_visibility (GTK_ENTRY (entry), FALSE);
|
||||
gtk_box_pack_start (GTK_BOX (hbox), entry, TRUE, TRUE, 0);
|
||||
gtk_entry_set_activates_default (GTK_ENTRY (entry), TRUE);
|
||||
g_object_set_data (G_OBJECT (dialog), "password", entry);
|
||||
gtk_container_add (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), hbox);
|
||||
gtk_container_add (GTK_CONTAINER (gtk_dialog_get_content_area (GTK_DIALOG (dialog))), hbox);
|
||||
hbox = gtk_hbox_new (FALSE, 6);
|
||||
label = gtk_check_button_new_with_mnemonic (_("_Remember password"));
|
||||
gtk_box_pack_start (GTK_BOX (hbox), label, TRUE, TRUE, 0);
|
||||
g_object_set_data (G_OBJECT (dialog), "remember", label);
|
||||
gtk_container_add (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), hbox);
|
||||
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (label), (login != NULL));
|
||||
gtk_container_add (GTK_CONTAINER (gtk_dialog_get_content_area (GTK_DIALOG (dialog))), hbox);
|
||||
gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
|
||||
gtk_widget_show_all (GTK_DIALOG (dialog)->vbox);
|
||||
gtk_widget_show_all (gtk_dialog_get_content_area (GTK_DIALOG (dialog)));
|
||||
|
||||
g_object_set_data (G_OBJECT (dialog), "session", session);
|
||||
g_object_set_data (G_OBJECT (dialog), "msg", msg);
|
||||
|
|
|
@ -35,7 +35,7 @@ typedef struct _KatzeHttpAuth KatzeHttpAuth;
|
|||
typedef struct _KatzeHttpAuthClass KatzeHttpAuthClass;
|
||||
|
||||
GType
|
||||
katze_http_auth_get_type (void);
|
||||
katze_http_auth_get_type (void) G_GNUC_CONST;
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
|
|
@ -35,7 +35,7 @@ typedef struct _KatzeHttpCookies KatzeHttpCookies;
|
|||
typedef struct _KatzeHttpCookiesClass KatzeHttpCookiesClass;
|
||||
|
||||
GType
|
||||
katze_http_cookies_get_type (void);
|
||||
katze_http_cookies_get_type (void) G_GNUC_CONST;
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
|
|
@ -56,7 +56,7 @@ struct _KatzeItemClass
|
|||
};
|
||||
|
||||
GType
|
||||
katze_item_get_type (void);
|
||||
katze_item_get_type (void) G_GNUC_CONST;
|
||||
|
||||
KatzeItem*
|
||||
katze_item_new (void);
|
||||
|
|
|
@ -13,8 +13,13 @@
|
|||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#if HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include "katze-net.h"
|
||||
|
||||
#include <glib/gstdio.h>
|
||||
#include <libsoup/soup.h>
|
||||
#include <webkit/webkit.h>
|
||||
|
||||
|
@ -254,7 +259,7 @@ katze_net_local_cb (KatzeNetPriv* priv)
|
|||
request = priv->request;
|
||||
filename = g_filename_from_uri (request->uri, NULL, NULL);
|
||||
|
||||
if (!filename || !g_file_test (filename, G_FILE_TEST_EXISTS))
|
||||
if (!filename || g_access (filename, F_OK) != 0)
|
||||
{
|
||||
request->status = KATZE_NET_NOT_FOUND;
|
||||
if (priv->status_cb)
|
||||
|
@ -429,6 +434,7 @@ katze_net_icon_transfer_cb (KatzeNetRequest* request,
|
|||
GdkPixbuf* pixbuf_scaled;
|
||||
gint icon_width, icon_height;
|
||||
size_t ret;
|
||||
GtkSettings* settings;
|
||||
|
||||
if (request->status == KATZE_NET_MOVED)
|
||||
return;
|
||||
|
@ -474,7 +480,14 @@ katze_net_icon_transfer_cb (KatzeNetRequest* request,
|
|||
return;
|
||||
}
|
||||
}
|
||||
gtk_icon_size_lookup (GTK_ICON_SIZE_MENU, &icon_width, &icon_height);
|
||||
|
||||
if (priv->widget)
|
||||
settings = gtk_widget_get_settings (priv->widget);
|
||||
else
|
||||
settings = gtk_settings_get_for_screen (gdk_screen_get_default ());
|
||||
|
||||
gtk_icon_size_lookup_for_settings (settings, GTK_ICON_SIZE_MENU,
|
||||
&icon_width, &icon_height);
|
||||
pixbuf_scaled = gdk_pixbuf_scale_simple (pixbuf, icon_width, icon_height,
|
||||
GDK_INTERP_BILINEAR);
|
||||
g_object_unref (pixbuf);
|
||||
|
@ -531,6 +544,7 @@ katze_net_load_icon (KatzeNet* net,
|
|||
GdkPixbuf* pixbuf;
|
||||
gint icon_width, icon_height;
|
||||
GdkPixbuf* pixbuf_scaled;
|
||||
GtkSettings* settings;
|
||||
|
||||
g_return_val_if_fail (KATZE_IS_NET (net), NULL);
|
||||
g_return_val_if_fail (!widget || GTK_IS_WIDGET (widget), NULL);
|
||||
|
@ -594,7 +608,14 @@ katze_net_load_icon (KatzeNet* net,
|
|||
else
|
||||
return NULL;
|
||||
}
|
||||
gtk_icon_size_lookup (GTK_ICON_SIZE_MENU, &icon_width, &icon_height);
|
||||
|
||||
if (widget)
|
||||
settings = gtk_widget_get_settings (widget);
|
||||
else
|
||||
settings = gtk_settings_get_for_screen (gdk_screen_get_default ());
|
||||
|
||||
gtk_icon_size_lookup_for_settings (settings, GTK_ICON_SIZE_MENU,
|
||||
&icon_width, &icon_height);
|
||||
pixbuf_scaled = gdk_pixbuf_scale_simple (pixbuf, icon_width, icon_height,
|
||||
GDK_INTERP_BILINEAR);
|
||||
g_object_unref (pixbuf);
|
||||
|
|
|
@ -35,7 +35,7 @@ typedef struct _KatzeNet KatzeNet;
|
|||
typedef struct _KatzeNetClass KatzeNetClass;
|
||||
|
||||
GType
|
||||
katze_net_get_type (void);
|
||||
katze_net_get_type (void) G_GNUC_CONST;
|
||||
|
||||
KatzeNet*
|
||||
katze_net_new (void);
|
||||
|
|
|
@ -23,6 +23,10 @@
|
|||
#include <string.h>
|
||||
#include <glib/gi18n.h>
|
||||
|
||||
#if !GTK_CHECK_VERSION (2, 14, 0)
|
||||
#define gtk_dialog_get_content_area(dialog) dialog->vbox
|
||||
#endif
|
||||
|
||||
struct _KatzePreferencesPrivate
|
||||
{
|
||||
#if HAVE_HILDON
|
||||
|
@ -177,7 +181,7 @@ katze_preferences_prepare (KatzePreferences* preferences)
|
|||
GtkWidget* viewport;
|
||||
|
||||
priv->scrolled = katze_scrolled_new (NULL, NULL);
|
||||
gtk_box_pack_end (GTK_BOX (GTK_DIALOG (preferences)->vbox),
|
||||
gtk_box_pack_end (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (preferences))),
|
||||
priv->scrolled, TRUE, TRUE, 4);
|
||||
viewport = gtk_viewport_new (NULL, NULL);
|
||||
gtk_viewport_set_shadow_type (GTK_VIEWPORT (viewport), GTK_SHADOW_NONE);
|
||||
|
@ -201,14 +205,14 @@ katze_preferences_prepare (KatzePreferences* preferences)
|
|||
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),
|
||||
gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (preferences))),
|
||||
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);
|
||||
gtk_box_pack_end (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (preferences))),
|
||||
priv->notebook, TRUE, TRUE, 4);
|
||||
|
||||
priv->sizegroup = NULL;
|
||||
priv->sizegroup2 = NULL;
|
||||
|
@ -233,7 +237,7 @@ katze_preferences_prepare (KatzePreferences* preferences)
|
|||
gtk_box_pack_end (GTK_BOX (GTK_DIALOG (preferences)->action_area),
|
||||
hbox, FALSE, FALSE, 0);
|
||||
#endif
|
||||
gtk_widget_show_all (GTK_DIALOG (preferences)->vbox);
|
||||
gtk_widget_show_all (gtk_dialog_get_content_area (GTK_DIALOG (preferences)));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -46,7 +46,7 @@ struct _KatzePreferencesClass
|
|||
};
|
||||
|
||||
GType
|
||||
katze_preferences_get_type (void);
|
||||
katze_preferences_get_type (void) G_GNUC_CONST;
|
||||
|
||||
GtkWidget*
|
||||
katze_preferences_new (GtkWindow* parent);
|
||||
|
|
|
@ -18,6 +18,26 @@
|
|||
#include "katze-scrolled.h"
|
||||
#include "katze-utils.h"
|
||||
|
||||
#if !GTK_CHECK_VERSION (2, 14, 0)
|
||||
#define gtk_adjustment_get_page_size(adj) adj->page_size
|
||||
#define gtk_adjustment_get_upper(adj) adj->upper
|
||||
#define gtk_adjustment_get_lower(adj) adj->lower
|
||||
#define gtk_adjustment_get_value(adj) adj->value
|
||||
#define gtk_widget_get_window(wdgt) wdgt->window
|
||||
#endif
|
||||
#if !GTK_CHECK_VERSION (2, 18, 0)
|
||||
#define gtk_widget_set_window(wdgt, wndw) wdgt->window = wndw
|
||||
#define gtk_widget_get_allocation(wdgt, alloc) *alloc = wdgt->allocation
|
||||
#define gtk_widget_is_drawable GTK_WIDGET_DRAWABLE
|
||||
#define gtk_widget_get_drawable GTK_WIDGET_VISIBLE
|
||||
#define gtk_widget_get_visible(wdgt) GTK_WIDGET_VISIBLE (wdgt)
|
||||
#endif
|
||||
#if !GTK_CHECK_VERSION (2, 19, 6)
|
||||
#define gtk_widget_set_realized(wdgt, real) \
|
||||
if (real) GTK_WIDGET_SET_FLAGS (wdgt, GTK_REALIZED); \
|
||||
else GTK_WIDGET_UNSET_FLAGS (wdgt, GTK_REALIZED)
|
||||
#endif
|
||||
|
||||
#define DEFAULT_INTERVAL 50
|
||||
#define DEFAULT_DECELERATION 0.7
|
||||
#define DEFAULT_DRAGGING_STOPPED_DELAY 100
|
||||
|
@ -265,7 +285,7 @@ on_expose_event (GtkWidget* widget,
|
|||
KatzeScrolledPrivate* priv = scrolled->priv;
|
||||
gboolean ret = FALSE;
|
||||
|
||||
if (GTK_WIDGET_DRAWABLE (widget))
|
||||
if (gtk_widget_is_drawable (widget))
|
||||
{
|
||||
if (event->window == priv->horizontal_scrollbar_window)
|
||||
{
|
||||
|
@ -305,19 +325,27 @@ adjust_scrollbar (KatzeScrolled* scrolled,
|
|||
{
|
||||
KatzeScrolledPrivate* priv = scrolled->priv;
|
||||
GtkWidget* widget = GTK_WIDGET (scrolled);
|
||||
gdouble page_size, upper, lower, value;
|
||||
gint x, y;
|
||||
gint size;
|
||||
double position;
|
||||
GtkAllocation allocation;
|
||||
GtkWidget* window;
|
||||
|
||||
if (adjustment->page_size >= adjustment->upper - adjustment->lower)
|
||||
page_size = gtk_adjustment_get_page_size (adjustment);
|
||||
upper = gtk_adjustment_get_upper (adjustment);
|
||||
lower = gtk_adjustment_get_lower (adjustment);
|
||||
value = gtk_adjustment_get_value (adjustment);
|
||||
|
||||
if (page_size >= upper - lower)
|
||||
{
|
||||
*previous_size = 0;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
size = ((double)adjustment->page_size) / (adjustment->upper - adjustment->lower) * (horizontal
|
||||
? widget->allocation.height : widget->allocation.width);
|
||||
gtk_widget_get_allocation (widget, &allocation);
|
||||
size = page_size / (upper - lower)
|
||||
* (horizontal ? allocation.height : allocation.width);
|
||||
if (size != *previous_size)
|
||||
{
|
||||
*previous_size = size;
|
||||
|
@ -341,18 +369,18 @@ adjust_scrollbar (KatzeScrolled* scrolled,
|
|||
}
|
||||
}
|
||||
|
||||
position = (adjustment->value - adjustment->lower) / (adjustment->upper - adjustment->lower);
|
||||
position = (value - lower) / (upper - lower);
|
||||
window = gtk_widget_get_toplevel (widget);
|
||||
if (horizontal)
|
||||
{
|
||||
gtk_widget_translate_coordinates (widget, window,
|
||||
widget->allocation.width - 20, position * widget->allocation.height, &x, &y);
|
||||
allocation.width - 20, position * allocation.height, &x, &y);
|
||||
gdk_window_move (scrollbar_window, x, y);
|
||||
}
|
||||
else
|
||||
{
|
||||
gtk_widget_translate_coordinates (widget, window,
|
||||
position * widget->allocation.width, widget->allocation.height - 20, &x, &y);
|
||||
position * allocation.width, allocation.height - 20, &x, &y);
|
||||
gdk_window_move (scrollbar_window, x, y);
|
||||
}
|
||||
|
||||
|
@ -418,35 +446,45 @@ do_timeout_scroll (KatzeScrolled* scrolled)
|
|||
GtkScrolledWindow* gtk_scrolled = GTK_SCROLLED_WINDOW (scrolled);
|
||||
GtkAdjustment* hadjustment;
|
||||
GtkAdjustment* vadjustment;
|
||||
gdouble hvalue;
|
||||
gdouble vvalue;
|
||||
gdouble hpage_size, hupper, hlower, hvalue, new_hvalue;
|
||||
gdouble vpage_size, vupper, vlower, vvalue, new_vvalue;
|
||||
|
||||
hadjustment = gtk_scrolled_window_get_hadjustment (gtk_scrolled);
|
||||
vadjustment = gtk_scrolled_window_get_vadjustment (gtk_scrolled);
|
||||
hvalue = calculate_timeout_scroll_values (hadjustment->value,
|
||||
hadjustment->upper - hadjustment->page_size,
|
||||
hpage_size = gtk_adjustment_get_page_size (hadjustment);
|
||||
hupper = gtk_adjustment_get_upper (hadjustment);
|
||||
hlower = gtk_adjustment_get_lower (hadjustment);
|
||||
hvalue = gtk_adjustment_get_value (hadjustment);
|
||||
new_hvalue = calculate_timeout_scroll_values (hvalue,
|
||||
hupper - hpage_size,
|
||||
&priv->horizontal_speed,
|
||||
priv->horizontal_deceleration,
|
||||
&priv->vertical_deceleration,
|
||||
priv->deceleration);
|
||||
vvalue = calculate_timeout_scroll_values (vadjustment->value,
|
||||
vadjustment->upper - vadjustment->page_size,
|
||||
|
||||
vadjustment = gtk_scrolled_window_get_vadjustment (gtk_scrolled);
|
||||
vpage_size = gtk_adjustment_get_page_size (vadjustment);
|
||||
vupper = gtk_adjustment_get_upper (vadjustment);
|
||||
vlower = gtk_adjustment_get_lower (vadjustment);
|
||||
vvalue = gtk_adjustment_get_value (vadjustment);
|
||||
new_vvalue = calculate_timeout_scroll_values (vvalue,
|
||||
vupper - vpage_size,
|
||||
&priv->vertical_speed,
|
||||
priv->vertical_deceleration,
|
||||
&priv->horizontal_deceleration,
|
||||
priv->deceleration);
|
||||
if (vvalue != vadjustment->value)
|
||||
|
||||
if (new_vvalue != vvalue)
|
||||
{
|
||||
if (hvalue != hadjustment->value)
|
||||
if (new_hvalue != hvalue)
|
||||
{
|
||||
disable_hadjustment (scrolled);
|
||||
gtk_adjustment_set_value (hadjustment, hvalue);
|
||||
gtk_adjustment_set_value (hadjustment, new_hvalue);
|
||||
enable_hadjustment (scrolled);
|
||||
}
|
||||
gtk_adjustment_set_value (vadjustment, vvalue);
|
||||
gtk_adjustment_set_value (vadjustment, new_vvalue);
|
||||
}
|
||||
else if (hvalue != hadjustment->value)
|
||||
gtk_adjustment_set_value (hadjustment, hvalue);
|
||||
else if (new_hvalue != hvalue)
|
||||
gtk_adjustment_set_value (hadjustment, new_hvalue);
|
||||
|
||||
adjust_scrollbar (scrolled, priv->horizontal_scrollbar_window,
|
||||
gtk_scrolled_window_get_hadjustment (gtk_scrolled),
|
||||
|
@ -510,13 +548,14 @@ do_motion_scroll (KatzeScrolled* scrolled,
|
|||
guint32 timestamp)
|
||||
{
|
||||
KatzeScrolledPrivate* priv = scrolled->priv;
|
||||
GtkAdjustment* hadjustment;
|
||||
GtkAdjustment* vadjustment;
|
||||
gdouble hvalue;
|
||||
gdouble vvalue;
|
||||
|
||||
if (priv->dragged || gtk_drag_check_threshold (widget, priv->start_x, priv->start_y, x, y))
|
||||
{
|
||||
GtkAdjustment* hadjustment;
|
||||
GtkAdjustment* vadjustment;
|
||||
gdouble hpage_size, hupper, hvalue, new_hvalue;
|
||||
gdouble vpage_size, vupper, vvalue, new_vvalue;
|
||||
|
||||
if (timestamp - priv->previous_time > priv->dragging_stopped_delay || !priv->dragged)
|
||||
{
|
||||
priv->dragged = TRUE;
|
||||
|
@ -554,23 +593,30 @@ do_motion_scroll (KatzeScrolled* scrolled,
|
|||
}
|
||||
|
||||
hadjustment = gtk_scrolled_window_get_hadjustment (GTK_SCROLLED_WINDOW (scrolled));
|
||||
hpage_size = gtk_adjustment_get_page_size (hadjustment);
|
||||
hupper = gtk_adjustment_get_upper (hadjustment);
|
||||
hvalue = gtk_adjustment_get_value (hadjustment);
|
||||
new_hvalue = calculate_motion_scroll_values (hvalue,
|
||||
hupper - hpage_size, x, priv->previous_x);
|
||||
|
||||
vadjustment = gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (scrolled));
|
||||
hvalue = calculate_motion_scroll_values (hadjustment->value,
|
||||
hadjustment->upper - hadjustment->page_size, x, priv->previous_x);
|
||||
vvalue = calculate_motion_scroll_values (vadjustment->value,
|
||||
vadjustment->upper - vadjustment->page_size, y, priv->previous_y);
|
||||
if (vvalue != vadjustment->value)
|
||||
vpage_size = gtk_adjustment_get_page_size (vadjustment);
|
||||
vupper = gtk_adjustment_get_upper (vadjustment);
|
||||
vvalue = gtk_adjustment_get_value (vadjustment);
|
||||
new_vvalue = calculate_motion_scroll_values (vvalue,
|
||||
vupper - vpage_size, y, priv->previous_y);
|
||||
if (new_vvalue != vvalue)
|
||||
{
|
||||
if (hvalue != hadjustment->value)
|
||||
if (new_hvalue != hvalue)
|
||||
{
|
||||
disable_hadjustment (scrolled);
|
||||
gtk_adjustment_set_value (hadjustment, hvalue);
|
||||
gtk_adjustment_set_value (hadjustment, new_hvalue);
|
||||
enable_hadjustment (scrolled);
|
||||
}
|
||||
gtk_adjustment_set_value (vadjustment, vvalue);
|
||||
gtk_adjustment_set_value (vadjustment, new_vvalue);
|
||||
}
|
||||
else if (hvalue != hadjustment->value)
|
||||
gtk_adjustment_set_value (hadjustment, hvalue);
|
||||
else if (new_hvalue != hvalue)
|
||||
gtk_adjustment_set_value (hadjustment, new_hvalue);
|
||||
}
|
||||
|
||||
priv->previous_y = y;
|
||||
|
@ -611,7 +657,8 @@ button_press_event (GtkWidget* widget,
|
|||
g_source_remove (priv->scrolling_timeout_id);
|
||||
priv->scrolling_timeout_id = 0;
|
||||
}
|
||||
gdk_window_get_pointer (GTK_WIDGET (scrolled)->window, &x, &y, &mask);
|
||||
gdk_window_get_pointer (gtk_widget_get_window (GTK_WIDGET (scrolled)),
|
||||
&x, &y, &mask);
|
||||
/* do_motion_scroll (scrolled, widget, x, y, event->time); */
|
||||
}
|
||||
else
|
||||
|
@ -627,24 +674,29 @@ button_press_event (GtkWidget* widget,
|
|||
priv->dragged = FALSE;
|
||||
priv->previous_time = event->time;
|
||||
}
|
||||
gdk_window_get_pointer (GTK_WIDGET (scrolled)->window, &x, &y, &mask);
|
||||
gdk_window_get_pointer (gtk_widget_get_window (GTK_WIDGET (scrolled)),
|
||||
&x, &y, &mask);
|
||||
priv->start_x = priv->previous_x = priv->farest_x = x;
|
||||
priv->start_y = priv->previous_y = priv->farest_y = y;
|
||||
priv->start_time = event->time;
|
||||
}
|
||||
|
||||
if (priv->scrolling_hints && !GTK_SCROLLED_WINDOW (scrolled)->hscrollbar_visible &&
|
||||
adjust_scrollbar (scrolled, priv->horizontal_scrollbar_window,
|
||||
gtk_scrolled_window_get_hadjustment (GTK_SCROLLED_WINDOW (scrolled)),
|
||||
&priv->horizontal_scrollbar_size, FALSE))
|
||||
if (priv->scrolling_hints
|
||||
&& !gtk_widget_get_visible (gtk_scrolled_window_get_hscrollbar (
|
||||
GTK_SCROLLED_WINDOW (scrolled)))
|
||||
&& adjust_scrollbar (scrolled, priv->horizontal_scrollbar_window,
|
||||
gtk_scrolled_window_get_hadjustment (GTK_SCROLLED_WINDOW (scrolled)),
|
||||
&priv->horizontal_scrollbar_size, FALSE))
|
||||
{
|
||||
gdk_window_raise (priv->horizontal_scrollbar_window);
|
||||
gdk_window_show (priv->horizontal_scrollbar_window);
|
||||
}
|
||||
if (priv->scrolling_hints && !GTK_SCROLLED_WINDOW (scrolled)->vscrollbar_visible &&
|
||||
adjust_scrollbar (scrolled, priv->vertical_scrollbar_window,
|
||||
gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (scrolled)),
|
||||
&priv->vertical_scrollbar_size, TRUE))
|
||||
if (priv->scrolling_hints
|
||||
&& !gtk_widget_get_visible (gtk_scrolled_window_get_vscrollbar (
|
||||
GTK_SCROLLED_WINDOW (scrolled)))
|
||||
&& adjust_scrollbar (scrolled, priv->vertical_scrollbar_window,
|
||||
gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (scrolled)),
|
||||
&priv->vertical_scrollbar_size, TRUE))
|
||||
{
|
||||
gdk_window_raise (priv->vertical_scrollbar_window);
|
||||
gdk_window_show (priv->vertical_scrollbar_window);
|
||||
|
@ -668,7 +720,8 @@ button_release_event (GtkWidget* widget,
|
|||
gint y;
|
||||
GdkModifierType mask;
|
||||
|
||||
gdk_window_get_pointer (GTK_WIDGET (scrolled)->window, &x, &y, &mask);
|
||||
gdk_window_get_pointer (gtk_widget_get_window (GTK_WIDGET (scrolled)),
|
||||
&x, &y, &mask);
|
||||
if (priv->press_received &&
|
||||
gtk_drag_check_threshold (widget, priv->start_x, priv->start_y, x, y)) {
|
||||
priv->dragged = TRUE;
|
||||
|
@ -713,7 +766,8 @@ motion_notify_event (GtkWidget* widget,
|
|||
|
||||
if (priv->press_received)
|
||||
{
|
||||
gdk_window_get_pointer (GTK_WIDGET (scrolled)->window, &x, &y, &mask);
|
||||
gdk_window_get_pointer (gtk_widget_get_window (GTK_WIDGET (scrolled)),
|
||||
&x, &y, &mask);
|
||||
do_motion_scroll (scrolled, widget, x, y, event->time);
|
||||
}
|
||||
|
||||
|
@ -756,7 +810,8 @@ katze_scrolled_event_handler (GdkEvent* event,
|
|||
crossing.type = GDK_LEAVE_NOTIFY;
|
||||
crossing.window = event->motion.window;
|
||||
crossing.send_event = event->motion.send_event;
|
||||
crossing.subwindow = GTK_WIDGET (current_scrolled_window)->window;
|
||||
crossing.subwindow = gtk_widget_get_window (
|
||||
GTK_WIDGET (current_scrolled_window));
|
||||
crossing.time = event->motion.time;
|
||||
crossing.x = event->motion.x;
|
||||
crossing.y = event->motion.y;
|
||||
|
@ -787,7 +842,8 @@ katze_scrolled_event_handler (GdkEvent* event,
|
|||
crossing.type = GDK_ENTER_NOTIFY;
|
||||
crossing.window = event->button.window;
|
||||
crossing.send_event = event->button.send_event;
|
||||
crossing.subwindow = GTK_WIDGET (current_scrolled_window)->window;
|
||||
crossing.subwindow = gtk_widget_get_window (
|
||||
GTK_WIDGET (current_scrolled_window));
|
||||
crossing.time = event->button.time;
|
||||
crossing.x = event->button.x;
|
||||
crossing.y = event->button.y;
|
||||
|
@ -821,6 +877,7 @@ katze_scrolled_realize (GtkWidget* widget)
|
|||
KatzeScrolledPrivate* priv = scrolled->priv;
|
||||
gboolean drag_scrolling;
|
||||
GtkPolicyType policy;
|
||||
GdkWindow* window;
|
||||
GdkWindowAttr attr;
|
||||
GdkColor color;
|
||||
|
||||
|
@ -831,15 +888,16 @@ katze_scrolled_realize (GtkWidget* widget)
|
|||
g_object_set (scrolled, "drag-scrolling", drag_scrolling,
|
||||
"hscrollbar-policy", policy, "vscrollbar-policy", policy, NULL);
|
||||
|
||||
widget->window = g_object_ref (gtk_widget_get_parent_window (widget));
|
||||
window = g_object_ref (gtk_widget_get_parent_window (widget));
|
||||
gtk_widget_set_window (widget, window);
|
||||
|
||||
attr.height = attr.width = 10;
|
||||
attr.event_mask = GDK_EXPOSURE_MASK;
|
||||
attr.wclass = GDK_INPUT_OUTPUT;
|
||||
attr.window_type = GDK_WINDOW_CHILD;
|
||||
attr.override_redirect = TRUE;
|
||||
priv->vertical_scrollbar_window = gdk_window_new (widget->window, &attr, 0);
|
||||
priv->horizontal_scrollbar_window = gdk_window_new (widget->window, &attr, 0);
|
||||
priv->vertical_scrollbar_window = gdk_window_new (window, &attr, 0);
|
||||
priv->horizontal_scrollbar_window = gdk_window_new (window, &attr, 0);
|
||||
|
||||
gdk_window_set_user_data (priv->vertical_scrollbar_window, widget);
|
||||
gdk_window_set_user_data (priv->horizontal_scrollbar_window, widget);
|
||||
|
@ -847,18 +905,18 @@ katze_scrolled_realize (GtkWidget* widget)
|
|||
G_CALLBACK (on_expose_event), scrolled);
|
||||
|
||||
color.red = color.green = color.blue = 0x9999;
|
||||
gdk_rgb_find_color (gdk_colormap_get_system (), &color);
|
||||
gdk_rgb_find_color (gtk_widget_get_colormap (widget), &color);
|
||||
gdk_window_set_background (priv->vertical_scrollbar_window, &color);
|
||||
gdk_window_set_background (priv->horizontal_scrollbar_window, &color);
|
||||
|
||||
priv->hilight_gc = gdk_gc_new (widget->window);
|
||||
priv->hilight_gc = gdk_gc_new (window);
|
||||
color.red = color.green = color.blue = 0xcccc;
|
||||
gdk_gc_set_rgb_fg_color (priv->hilight_gc, &color);
|
||||
priv->shadow_gc = gdk_gc_new (widget->window);
|
||||
priv->shadow_gc = gdk_gc_new (window);
|
||||
color.red = color.green = color.blue = 0x6666;
|
||||
gdk_gc_set_rgb_fg_color (priv->shadow_gc, &color);
|
||||
|
||||
GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);
|
||||
gtk_widget_set_realized (widget, TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
@ -48,7 +48,7 @@ struct _KatzeScrolledClass
|
|||
};
|
||||
|
||||
GType
|
||||
katze_scrolled_get_type (void);
|
||||
katze_scrolled_get_type (void) G_GNUC_CONST;
|
||||
|
||||
GtkWidget*
|
||||
katze_scrolled_new (GtkAdjustment* hadjustment,
|
||||
|
|
|
@ -36,7 +36,7 @@ typedef struct _KatzeSeparatorAction KatzeSeparatorAction;
|
|||
typedef struct _KatzeSeparatorActionClass KatzeSeparatorActionClass;
|
||||
|
||||
GType
|
||||
katze_separator_action_get_type (void);
|
||||
katze_separator_action_get_type (void) G_GNUC_CONST;
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
|
|
@ -16,6 +16,13 @@
|
|||
#include <glib/gi18n.h>
|
||||
#include <math.h>
|
||||
|
||||
#if !GTK_CHECK_VERSION (2, 18, 0)
|
||||
#define gtk_widget_get_allocation(wdgt, alloc) *alloc = wdgt->allocation
|
||||
#define gtk_widget_set_has_window(wdgt, wnd) \
|
||||
if (wnd) GTK_WIDGET_UNSET_FLAGS (wdgt, GTK_NO_WINDOW); \
|
||||
else GTK_WIDGET_SET_FLAGS (wdgt, GTK_NO_WINDOW)
|
||||
#endif
|
||||
|
||||
struct _KatzeThrobber
|
||||
{
|
||||
GtkMisc parent_instance;
|
||||
|
@ -108,15 +115,20 @@ katze_throbber_timeout_destroy (KatzeThrobber* throbber);
|
|||
static void
|
||||
katze_throbber_class_init (KatzeThrobberClass* class)
|
||||
{
|
||||
GObjectClass* gobject_class = G_OBJECT_CLASS (class);
|
||||
GObjectClass* gobject_class;
|
||||
GtkObjectClass* object_class;
|
||||
GtkWidgetClass* widget_class;
|
||||
GParamFlags flags = G_PARAM_READWRITE | G_PARAM_CONSTRUCT;
|
||||
|
||||
gobject_class = G_OBJECT_CLASS (class);
|
||||
gobject_class->dispose = katze_throbber_dispose;
|
||||
gobject_class->set_property = katze_throbber_set_property;
|
||||
gobject_class->get_property = katze_throbber_get_property;
|
||||
|
||||
GtkObjectClass* object_class = GTK_OBJECT_CLASS (class);
|
||||
object_class = GTK_OBJECT_CLASS (class);
|
||||
object_class->destroy = katze_throbber_destroy;
|
||||
|
||||
GtkWidgetClass* widget_class = GTK_WIDGET_CLASS (class);
|
||||
widget_class = GTK_WIDGET_CLASS (class);
|
||||
widget_class->realize = katze_throbber_realize;
|
||||
widget_class->unrealize = katze_throbber_unrealize;
|
||||
widget_class->map = katze_throbber_map;
|
||||
|
@ -126,8 +138,6 @@ katze_throbber_class_init (KatzeThrobberClass* class)
|
|||
widget_class->size_request = katze_throbber_size_request;
|
||||
widget_class->expose_event = katze_throbber_expose_event;
|
||||
|
||||
GParamFlags flags = G_PARAM_READWRITE | G_PARAM_CONSTRUCT;
|
||||
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_ICON_SIZE,
|
||||
g_param_spec_int (
|
||||
|
@ -195,7 +205,7 @@ katze_throbber_class_init (KatzeThrobberClass* class)
|
|||
static void
|
||||
katze_throbber_init (KatzeThrobber *throbber)
|
||||
{
|
||||
GTK_WIDGET_SET_FLAGS (throbber, GTK_NO_WINDOW);
|
||||
gtk_widget_set_has_window (GTK_WIDGET (throbber), FALSE);
|
||||
|
||||
throbber->timer_id = -1;
|
||||
}
|
||||
|
@ -790,16 +800,20 @@ katze_throbber_aligned_coords (GtkWidget* widget,
|
|||
{
|
||||
gfloat xalign, yalign;
|
||||
gint xpad, ypad;
|
||||
GtkAllocation allocation;
|
||||
GtkRequisition requisition;
|
||||
|
||||
gtk_misc_get_alignment (GTK_MISC (widget), &xalign, &yalign);
|
||||
if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL)
|
||||
xalign = 1.0f - xalign;
|
||||
gtk_misc_get_padding (GTK_MISC (widget), &xpad, &ypad);
|
||||
|
||||
*ax = floor (widget->allocation.x + xpad
|
||||
+ ((widget->allocation.width - widget->requisition.width) * xalign));
|
||||
*ay = floor (widget->allocation.y + ypad
|
||||
+ ((widget->allocation.height - widget->requisition.height) * yalign));
|
||||
gtk_widget_get_allocation (widget, &allocation);
|
||||
gtk_widget_size_request (widget, &requisition);
|
||||
*ax = floor (allocation.x + xpad
|
||||
+ ((allocation.width - requisition.width) * xalign));
|
||||
*ay = floor (allocation.y + ypad
|
||||
+ ((allocation.height - requisition.height) * yalign));
|
||||
}
|
||||
|
||||
static gboolean
|
||||
|
@ -855,6 +869,8 @@ katze_throbber_expose_event (GtkWidget* widget,
|
|||
}
|
||||
else
|
||||
{
|
||||
gint cols, rows;
|
||||
|
||||
if (G_UNLIKELY (throbber->icon_name && !throbber->pixbuf))
|
||||
{
|
||||
icon_theme_changed (KATZE_THROBBER (widget));
|
||||
|
@ -868,8 +884,8 @@ katze_throbber_expose_event (GtkWidget* widget,
|
|||
}
|
||||
}
|
||||
|
||||
gint cols = gdk_pixbuf_get_width (throbber->pixbuf) / throbber->width;
|
||||
gint rows = gdk_pixbuf_get_height (throbber->pixbuf) / throbber->height;
|
||||
cols = gdk_pixbuf_get_width (throbber->pixbuf) / throbber->width;
|
||||
rows = gdk_pixbuf_get_height (throbber->pixbuf) / throbber->height;
|
||||
|
||||
if (G_UNLIKELY (cols == 1 && cols == rows))
|
||||
{
|
||||
|
|
|
@ -45,7 +45,7 @@ struct _KatzeThrobberClass
|
|||
};
|
||||
|
||||
GType
|
||||
katze_throbber_get_type (void);
|
||||
katze_throbber_get_type (void) G_GNUC_CONST;
|
||||
|
||||
GtkWidget*
|
||||
katze_throbber_new (void);
|
||||
|
|
|
@ -21,22 +21,33 @@
|
|||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#if HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_HILDON_2_2
|
||||
#include <hildon/hildon.h>
|
||||
#endif
|
||||
|
||||
#if !GTK_CHECK_VERSION (2, 18, 0)
|
||||
#define gtk_widget_get_has_window(wdgt) !GTK_WIDGET_NO_WINDOW (wdgt)
|
||||
#define gtk_widget_get_allocation(wdgt, alloc) *alloc = wdgt->allocation
|
||||
#endif
|
||||
|
||||
static void
|
||||
proxy_toggle_button_toggled_cb (GtkToggleButton* button,
|
||||
GObject* object)
|
||||
{
|
||||
gboolean toggled;
|
||||
const gchar* property;
|
||||
|
||||
#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");
|
||||
property = g_object_get_data (G_OBJECT (button), "property");
|
||||
g_object_set (object, property, toggled, NULL);
|
||||
}
|
||||
|
||||
|
@ -616,8 +627,12 @@ katze_property_proxy (gpointer object,
|
|||
GtkComboBox* combo;
|
||||
GList* apps;
|
||||
const gchar* app_type = &hint[12];
|
||||
GtkSettings* settings;
|
||||
gint icon_width = 16;
|
||||
gtk_icon_size_lookup (GTK_ICON_SIZE_MENU, &icon_width, NULL);
|
||||
|
||||
settings = gtk_settings_get_for_screen (gdk_screen_get_default ());
|
||||
gtk_icon_size_lookup_for_settings (settings, 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);
|
||||
|
@ -906,21 +921,24 @@ katze_widget_popup_position_menu (GtkMenu* menu,
|
|||
{
|
||||
gint wx, wy;
|
||||
gint menu_width;
|
||||
GtkAllocation allocation;
|
||||
GtkRequisition menu_req;
|
||||
GtkRequisition widget_req;
|
||||
KatzePopupInfo* info = user_data;
|
||||
GtkWidget* widget = info->widget;
|
||||
gint widget_height;
|
||||
|
||||
gtk_widget_get_allocation (widget, &allocation);
|
||||
|
||||
/* Retrieve size and position of both widget and menu */
|
||||
if (GTK_WIDGET_NO_WINDOW (widget))
|
||||
if (!gtk_widget_get_has_window (widget))
|
||||
{
|
||||
gdk_window_get_position (widget->window, &wx, &wy);
|
||||
wx += widget->allocation.x;
|
||||
wy += widget->allocation.y;
|
||||
gdk_window_get_position (gtk_widget_get_window (widget), &wx, &wy);
|
||||
wx += allocation.x;
|
||||
wy += allocation.y;
|
||||
}
|
||||
else
|
||||
gdk_window_get_origin (widget->window, &wx, &wy);
|
||||
gdk_window_get_origin (gtk_widget_get_window (widget), &wx, &wy);
|
||||
gtk_widget_size_request (GTK_WIDGET (menu), &menu_req);
|
||||
gtk_widget_size_request (widget, &widget_req);
|
||||
menu_width = menu_req.width;
|
||||
|
@ -931,7 +949,7 @@ katze_widget_popup_position_menu (GtkMenu* menu,
|
|||
; /* Do nothing? */
|
||||
else if (info->position == KATZE_MENU_POSITION_RIGHT)
|
||||
{
|
||||
*x = wx + widget->allocation.width - menu_width;
|
||||
*x = wx + allocation.width - menu_width;
|
||||
*y = wy + widget_height;
|
||||
} else if (info->position == KATZE_MENU_POSITION_LEFT)
|
||||
{
|
||||
|
@ -1340,7 +1358,8 @@ katze_mkdir_with_parents (const gchar* pathname,
|
|||
{
|
||||
gchar* fn, *p;
|
||||
|
||||
if (g_file_test (pathname, G_FILE_TEST_EXISTS))
|
||||
/* Use g_access instead of g_file_test for better performance */
|
||||
if (g_access (pathname, F_OK) == 0)
|
||||
return 0;
|
||||
|
||||
fn = g_strdup (pathname);
|
||||
|
@ -1360,7 +1379,7 @@ katze_mkdir_with_parents (const gchar* pathname,
|
|||
else
|
||||
*p = '\0';
|
||||
|
||||
if (!g_file_test (fn, G_FILE_TEST_EXISTS))
|
||||
if (g_access (fn, F_OK) != 0)
|
||||
{
|
||||
if (g_mkdir (fn, mode) == -1)
|
||||
{
|
||||
|
@ -1452,17 +1471,18 @@ katze_load_cached_icon (const gchar* uri,
|
|||
i++;
|
||||
if (uri[i] == '/')
|
||||
{
|
||||
icon_uri = g_strdup (uri);
|
||||
icon_uri[i] = '\0';
|
||||
icon_uri = g_strdup_printf ("%s/favicon.ico", icon_uri);
|
||||
gchar* ticon_uri = g_strdup (uri);
|
||||
ticon_uri[i] = '\0';
|
||||
icon_uri = g_strdup_printf ("%s/favicon.ico", ticon_uri);
|
||||
g_free (ticon_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 (icon_uri);
|
||||
g_free (checksum);
|
||||
path = g_build_filename (g_get_user_cache_dir (), PACKAGE_NAME,
|
||||
"icons", filename, NULL);
|
||||
|
@ -1477,3 +1497,96 @@ katze_load_cached_icon (const gchar* uri,
|
|||
return icon || !widget ? icon : gtk_widget_render_icon (widget,
|
||||
GTK_STOCK_FILE, GTK_ICON_SIZE_MENU, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* katze_collfold:
|
||||
* @str: a non-NULL UTF-8 string
|
||||
*
|
||||
* Computes a string without case and decomposited so
|
||||
* it can be used for comparison.
|
||||
*
|
||||
* Return value: a normalized string
|
||||
*
|
||||
* Since: 0.2.3
|
||||
**/
|
||||
gchar*
|
||||
katze_collfold (const gchar* str)
|
||||
{
|
||||
GString* result = g_string_new (NULL);
|
||||
const gchar* p = str;
|
||||
|
||||
while (*p)
|
||||
{
|
||||
gunichar ch = g_unichar_tolower (g_utf8_get_char (p));
|
||||
gsize len;
|
||||
gunichar* sch = g_unicode_canonical_decomposition (ch, &len);
|
||||
guint i = 0;
|
||||
while (i < len)
|
||||
g_string_append_unichar (result, sch[i++]);
|
||||
|
||||
p = g_utf8_next_char (p);
|
||||
}
|
||||
|
||||
return g_string_free (result, FALSE);
|
||||
}
|
||||
|
||||
/**
|
||||
* katze_utf8_stristr:
|
||||
* @haystack: a non-NULL UTF-8 string
|
||||
* @needle: a normalized non-NULL UTF-8 string
|
||||
*
|
||||
* Determines whether @needle is in @haystack, disregarding
|
||||
* differences in case.
|
||||
*
|
||||
* Return value: %TRUE if @needle is found in @haystack
|
||||
*
|
||||
* Since: 0.2.3
|
||||
**/
|
||||
gboolean
|
||||
katze_utf8_stristr (const gchar* haystack,
|
||||
const gchar* needle)
|
||||
{
|
||||
#if 0 /* 0,000159 seconds */
|
||||
/* Too slow for use in completion */
|
||||
gchar* nhaystack = g_utf8_normalize (haystack, -1, G_NORMALIZE_DEFAULT);
|
||||
const gchar *p = nhaystack;
|
||||
gsize len = strlen (needle);
|
||||
gsize i;
|
||||
|
||||
while (*p)
|
||||
{
|
||||
for (i = 0; i < len; i++)
|
||||
if (g_unichar_tolower (g_utf8_get_char (p + i))
|
||||
!= g_unichar_tolower (g_utf8_get_char (needle + i)))
|
||||
goto next;
|
||||
|
||||
g_free (nhaystack);
|
||||
return TRUE;
|
||||
|
||||
next:
|
||||
p = g_utf8_next_char (p);
|
||||
}
|
||||
|
||||
g_free (nhaystack);
|
||||
return FALSE;
|
||||
#else /* 0,000044 seconds */
|
||||
/* No unicode matching */
|
||||
const gchar *p = haystack;
|
||||
gsize len = strlen (needle);
|
||||
gsize i;
|
||||
|
||||
while (*p)
|
||||
{
|
||||
for (i = 0; i < len; i++)
|
||||
if (g_ascii_tolower (p[i]) != g_ascii_tolower (needle[i]))
|
||||
goto next;
|
||||
|
||||
return TRUE;
|
||||
|
||||
next:
|
||||
p++;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -151,6 +151,13 @@ GdkPixbuf*
|
|||
katze_load_cached_icon (const gchar* uri,
|
||||
GtkWidget* widget);
|
||||
|
||||
gchar*
|
||||
katze_collfold (const gchar* str);
|
||||
|
||||
gboolean
|
||||
katze_utf8_stristr (const gchar* haystack,
|
||||
const gchar* needle);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __KATZE_UTILS_H__ */
|
||||
|
|
|
@ -1,2 +0,0 @@
|
|||
VOID:POINTER,INT
|
||||
BOOLEAN:OBJECT,UINT
|
|
@ -1,14 +0,0 @@
|
|||
#! /usr/bin/env python
|
||||
# WAF build script for midori
|
||||
# This file is licensed under the terms of the expat license, see the file EXPAT.
|
||||
|
||||
import platform
|
||||
|
||||
obj = bld.new_task_gen ('cc', 'staticlib')
|
||||
obj.name = 'katze'
|
||||
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 HILDON LIBXML WEBKIT'
|
||||
obj.install_path = None
|
|
@ -1,67 +0,0 @@
|
|||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
#include "compat.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#if !GTK_CHECK_VERSION (2, 14, 0)
|
||||
|
||||
gboolean
|
||||
gtk_show_uri (GdkScreen* screen,
|
||||
const gchar* uri,
|
||||
guint32 timestamp,
|
||||
GError** error)
|
||||
{
|
||||
g_return_val_if_fail (uri != NULL, FALSE);
|
||||
|
||||
return g_app_info_launch_default_for_uri (uri, NULL, NULL);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if !GTK_CHECK_VERSION(2, 12, 0)
|
||||
|
||||
void
|
||||
gtk_widget_set_has_tooltip (GtkWidget* widget,
|
||||
gboolean has_tooltip)
|
||||
{
|
||||
/* Do nothing */
|
||||
}
|
||||
|
||||
void
|
||||
gtk_widget_set_tooltip_text (GtkWidget* widget,
|
||||
const gchar* text)
|
||||
{
|
||||
if (text && *text)
|
||||
{
|
||||
static GtkTooltips* tooltips = NULL;
|
||||
if (G_UNLIKELY (!tooltips))
|
||||
tooltips = gtk_tooltips_new ();
|
||||
gtk_tooltips_set_tip (tooltips, widget, text, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
gtk_tool_item_set_tooltip_text (GtkToolItem* toolitem,
|
||||
const gchar* text)
|
||||
{
|
||||
if (text && *text)
|
||||
{
|
||||
static GtkTooltips* tooltips = NULL;
|
||||
if (G_UNLIKELY (!tooltips))
|
||||
tooltips = gtk_tooltips_new ();
|
||||
|
||||
gtk_tool_item_set_tooltip (toolitem, tooltips, text, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,56 +0,0 @@
|
|||
/*
|
||||
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 __COMPAT_H__
|
||||
#define __COMPAT_H__
|
||||
|
||||
#if HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <webkit/webkit.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#if !GLIB_CHECK_VERSION (2, 14, 0)
|
||||
#define G_PARAM_STATIC_STRINGS \
|
||||
(G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB)
|
||||
#endif
|
||||
|
||||
#if !GTK_CHECK_VERSION (2, 14, 0)
|
||||
|
||||
gboolean
|
||||
gtk_show_uri (GdkScreen* screen,
|
||||
const gchar* uri,
|
||||
guint32 timestamp,
|
||||
GError** error);
|
||||
|
||||
#endif
|
||||
|
||||
#if !GTK_CHECK_VERSION(2, 12, 0)
|
||||
|
||||
void
|
||||
gtk_widget_set_has_tooltip (GtkWidget* widget,
|
||||
gboolean has_tooltip);
|
||||
|
||||
void
|
||||
gtk_widget_set_tooltip_text (GtkWidget* widget,
|
||||
const gchar* text);
|
||||
|
||||
void
|
||||
gtk_tool_item_set_tooltip_text (GtkToolItem* toolitem,
|
||||
const gchar* text);
|
||||
|
||||
#endif
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __COMPAT_H__ */
|
|
@ -86,6 +86,7 @@ typedef struct
|
|||
|
||||
typedef struct _GtkIconEntryPrivate
|
||||
{
|
||||
gdouble fraction;
|
||||
EntryIconInfo icons[MAX_ICONS];
|
||||
|
||||
gulong icon_released_id;
|
||||
|
@ -314,9 +315,313 @@ gtk_icon_entry_editable_init (GtkEditableClass *iface)
|
|||
{
|
||||
};
|
||||
|
||||
/* GTK+/ GtkEntry internal helper function
|
||||
Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
|
||||
Modified by the GTK+ Team and others 1997-2000
|
||||
Copied from Gtk+ 2.13, whitespace adjusted */
|
||||
static void
|
||||
gtk_entry_get_pixel_ranges (GtkEntry *entry,
|
||||
gint **ranges,
|
||||
gint *n_ranges)
|
||||
{
|
||||
gint start_char, end_char;
|
||||
|
||||
if (gtk_editable_get_selection_bounds (GTK_EDITABLE (entry),
|
||||
&start_char, &end_char))
|
||||
{
|
||||
PangoLayout *layout = gtk_entry_get_layout (entry);
|
||||
PangoLayoutLine *line = pango_layout_get_lines (layout)->data;
|
||||
const char *text = pango_layout_get_text (layout);
|
||||
gsize start_index = g_utf8_offset_to_pointer (text, start_char) - text;
|
||||
gsize end_index = g_utf8_offset_to_pointer (text, end_char) - text;
|
||||
gint real_n_ranges, i;
|
||||
|
||||
pango_layout_line_get_x_ranges (line,
|
||||
start_index, end_index, ranges, &real_n_ranges);
|
||||
|
||||
if (ranges)
|
||||
{
|
||||
gint *r = *ranges;
|
||||
|
||||
for (i = 0; i < real_n_ranges; ++i)
|
||||
{
|
||||
r[2 * i + 1] = (r[2 * i + 1] - r[2 * i]) / PANGO_SCALE;
|
||||
r[2 * i] = r[2 * i] / PANGO_SCALE;
|
||||
}
|
||||
}
|
||||
|
||||
if (n_ranges)
|
||||
*n_ranges = real_n_ranges;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (n_ranges)
|
||||
*n_ranges = 0;
|
||||
if (ranges)
|
||||
*ranges = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* GTK+/ GtkEntry internal helper function
|
||||
Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
|
||||
Modified by the GTK+ Team and others 1997-2000
|
||||
Copied from Gtk+ 2.13, whitespace adjusted
|
||||
Code adjusted to not rely on internal qdata */
|
||||
static void
|
||||
_gtk_entry_effective_inner_border (GtkEntry *entry,
|
||||
GtkBorder *border)
|
||||
{
|
||||
static const GtkBorder default_inner_border = { 2, 2, 2, 2 };
|
||||
GtkBorder *tmp_border;
|
||||
|
||||
tmp_border = (GtkBorder*) gtk_entry_get_inner_border (entry);
|
||||
|
||||
if (tmp_border)
|
||||
{
|
||||
*border = *tmp_border;
|
||||
return;
|
||||
}
|
||||
|
||||
gtk_widget_style_get (GTK_WIDGET (entry), "inner-border", &tmp_border, NULL);
|
||||
|
||||
if (tmp_border)
|
||||
{
|
||||
*border = *tmp_border;
|
||||
gtk_border_free (tmp_border);
|
||||
return;
|
||||
}
|
||||
|
||||
*border = default_inner_border;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_entry_borders (GtkEntry* entry,
|
||||
gint* xborder,
|
||||
gint* yborder,
|
||||
gboolean* interior_focus,
|
||||
gint* focus_width)
|
||||
{
|
||||
GtkWidget *widget = GTK_WIDGET (entry);
|
||||
|
||||
if (entry->has_frame)
|
||||
{
|
||||
*xborder = widget->style->xthickness;
|
||||
*yborder = widget->style->ythickness;
|
||||
}
|
||||
else
|
||||
{
|
||||
*xborder = 0;
|
||||
*yborder = 0;
|
||||
}
|
||||
|
||||
gtk_widget_style_get (widget, "interior-focus", interior_focus,
|
||||
"focus-line-width", focus_width, NULL);
|
||||
|
||||
if (interior_focus)
|
||||
{
|
||||
*xborder += *focus_width;
|
||||
*yborder += *focus_width;
|
||||
}
|
||||
}
|
||||
|
||||
/* GTK+/ GtkEntry internal helper function
|
||||
Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
|
||||
Modified by the GTK+ Team and others 1997-2000
|
||||
Copied from Gtk+ 2.13, whitespace adjusted */
|
||||
static void
|
||||
gtk_entry_get_text_area_size (GtkEntry *entry,
|
||||
gint *x,
|
||||
gint *y,
|
||||
gint *width,
|
||||
gint *height)
|
||||
{
|
||||
gint frame_height;
|
||||
gint xborder, yborder;
|
||||
gboolean interior_focus;
|
||||
gint focus_width;
|
||||
GtkRequisition requisition;
|
||||
GtkWidget *widget = GTK_WIDGET (entry);
|
||||
|
||||
gtk_widget_get_child_requisition (widget, &requisition);
|
||||
gtk_entry_borders (entry, &xborder, &yborder, &interior_focus, &focus_width);
|
||||
|
||||
if (GTK_WIDGET_REALIZED (widget))
|
||||
gdk_drawable_get_size (widget->window, NULL, &frame_height);
|
||||
else
|
||||
frame_height = requisition.height;
|
||||
|
||||
if (GTK_WIDGET_HAS_FOCUS (widget) && interior_focus)
|
||||
frame_height -= 2 * focus_width;
|
||||
|
||||
if (x)
|
||||
*x = xborder;
|
||||
|
||||
if (y)
|
||||
*y = frame_height / 2 - (requisition.height - yborder * 2) / 2;
|
||||
|
||||
if (width)
|
||||
*width = GTK_WIDGET (entry)->allocation.width - xborder * 2;
|
||||
|
||||
if (height)
|
||||
*height = requisition.height - yborder * 2;
|
||||
}
|
||||
|
||||
/* GTK+/ GtkEntry internal helper function
|
||||
Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
|
||||
Modified by the GTK+ Team and others 1997-2000
|
||||
Copied from Gtk+ 2.13, whitespace adjusted */
|
||||
static void
|
||||
get_layout_position (GtkEntry *entry,
|
||||
gint *x,
|
||||
gint *y)
|
||||
{
|
||||
PangoLayout *layout;
|
||||
PangoRectangle logical_rect;
|
||||
gint area_width, area_height;
|
||||
GtkBorder inner_border;
|
||||
gint y_pos;
|
||||
PangoLayoutLine *line;
|
||||
|
||||
layout = gtk_entry_get_layout (entry);
|
||||
|
||||
gtk_entry_get_text_area_size (entry, NULL, NULL, &area_width, &area_height);
|
||||
_gtk_entry_effective_inner_border (entry, &inner_border);
|
||||
|
||||
area_height = PANGO_SCALE *
|
||||
(area_height - inner_border.top - inner_border.bottom);
|
||||
|
||||
line = pango_layout_get_lines (layout)->data;
|
||||
pango_layout_line_get_extents (line, NULL, &logical_rect);
|
||||
|
||||
/* Align primarily for locale's ascent/descent */
|
||||
y_pos = ((area_height - entry->ascent - entry->descent) / 2 +
|
||||
entry->ascent + logical_rect.y);
|
||||
|
||||
/* Now see if we need to adjust to fit in actual drawn string */
|
||||
if (logical_rect.height > area_height)
|
||||
y_pos = (area_height - logical_rect.height) / 2;
|
||||
else if (y_pos < 0)
|
||||
y_pos = 0;
|
||||
else if (y_pos + logical_rect.height > area_height)
|
||||
y_pos = area_height - logical_rect.height;
|
||||
|
||||
y_pos = inner_border.top + y_pos / PANGO_SCALE;
|
||||
|
||||
if (x)
|
||||
*x = inner_border.left - entry->scroll_offset;
|
||||
|
||||
if (y)
|
||||
*y = y_pos;
|
||||
}
|
||||
|
||||
/* GTK+/ GtkEntry internal helper function
|
||||
Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
|
||||
Modified by the GTK+ Team and others 1997-2000
|
||||
Copied from Gtk+ 2.13, whitespace adjusted
|
||||
Code adjusted to not rely on internal _gtk_entry_ensure_layout */
|
||||
static void
|
||||
gtk_entry_draw_text (GtkEntry *entry)
|
||||
{
|
||||
GtkWidget *widget;
|
||||
|
||||
if (!entry->visible && entry->invisible_char == 0)
|
||||
return;
|
||||
|
||||
if (GTK_WIDGET_DRAWABLE (entry))
|
||||
{
|
||||
PangoLayout *layout = gtk_entry_get_layout (entry);
|
||||
cairo_t *cr;
|
||||
gint x, y;
|
||||
gint start_pos, end_pos;
|
||||
|
||||
widget = GTK_WIDGET (entry);
|
||||
|
||||
get_layout_position (entry, &x, &y);
|
||||
|
||||
cr = gdk_cairo_create (entry->text_area);
|
||||
|
||||
cairo_move_to (cr, x, y);
|
||||
gdk_cairo_set_source_color (cr, &widget->style->text [widget->state]);
|
||||
pango_cairo_show_layout (cr, layout);
|
||||
|
||||
if (gtk_editable_get_selection_bounds (GTK_EDITABLE (entry),
|
||||
&start_pos, &end_pos))
|
||||
{
|
||||
gint *ranges;
|
||||
gint n_ranges, i;
|
||||
PangoRectangle logical_rect;
|
||||
GdkColor *selection_color, *text_color;
|
||||
GtkBorder inner_border;
|
||||
|
||||
pango_layout_get_pixel_extents (layout, NULL, &logical_rect);
|
||||
gtk_entry_get_pixel_ranges (entry, &ranges, &n_ranges);
|
||||
|
||||
if (GTK_WIDGET_HAS_FOCUS (entry))
|
||||
{
|
||||
selection_color = &widget->style->base [GTK_STATE_SELECTED];
|
||||
text_color = &widget->style->text [GTK_STATE_SELECTED];
|
||||
}
|
||||
else
|
||||
{
|
||||
selection_color = &widget->style->base [GTK_STATE_ACTIVE];
|
||||
text_color = &widget->style->text [GTK_STATE_ACTIVE];
|
||||
}
|
||||
|
||||
_gtk_entry_effective_inner_border (entry, &inner_border);
|
||||
|
||||
for (i = 0; i < n_ranges; ++i)
|
||||
cairo_rectangle (cr,
|
||||
inner_border.left -
|
||||
entry->scroll_offset + ranges[2 * i],
|
||||
y,
|
||||
ranges[2 * i + 1],
|
||||
logical_rect.height);
|
||||
|
||||
cairo_clip (cr);
|
||||
|
||||
gdk_cairo_set_source_color (cr, selection_color);
|
||||
cairo_paint (cr);
|
||||
|
||||
cairo_move_to (cr, x, y);
|
||||
gdk_cairo_set_source_color (cr, text_color);
|
||||
pango_cairo_show_layout (cr, layout);
|
||||
|
||||
g_free (ranges);
|
||||
}
|
||||
|
||||
cairo_destroy (cr);
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
entry_expose_event (GtkWidget* entry,
|
||||
GdkEventExpose* event,
|
||||
GtkIconEntry* icon_entry)
|
||||
{
|
||||
GtkIconEntryPrivate *priv;
|
||||
GdkWindow* text_area;
|
||||
gint width, height;
|
||||
|
||||
priv = GTK_ICON_ENTRY_GET_PRIVATE (icon_entry);
|
||||
text_area = GTK_ENTRY (entry)->text_area;
|
||||
gdk_drawable_get_size (text_area, &width, &height);
|
||||
|
||||
if (priv->fraction > 0.0)
|
||||
{
|
||||
gtk_paint_box (entry->style, text_area,
|
||||
GTK_STATE_SELECTED, GTK_SHADOW_OUT,
|
||||
&event->area, entry, "entry-progress",
|
||||
0, 0, priv->fraction * width, height);
|
||||
gtk_entry_draw_text (GTK_ENTRY (entry));
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_icon_entry_init (GtkIconEntry *entry)
|
||||
{
|
||||
g_signal_connect_after (entry, "expose-event",
|
||||
G_CALLBACK (entry_expose_event), entry);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -1380,7 +1685,7 @@ gtk_icon_entry_set_icon_from_gicon (const GtkIconEntry *entry,
|
|||
GTK_ICON_SIZE_MENU,
|
||||
&width, &height);
|
||||
|
||||
#if #GTK_CHECK_VERSION (2, 14, 0)
|
||||
#if GTK_CHECK_VERSION (2, 14, 0)
|
||||
info = gtk_icon_theme_lookup_by_gicon (icon_theme,
|
||||
icon,
|
||||
MIN (width, height), 0);
|
||||
|
@ -1609,4 +1914,19 @@ gtk_icon_entry_set_icon_sensitive (const GtkIconEntry *icon_entry,
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
gtk_icon_entry_set_progress_fraction (GtkIconEntry *icon_entry,
|
||||
gdouble fraction)
|
||||
{
|
||||
GtkIconEntryPrivate *priv;
|
||||
|
||||
g_return_if_fail (GTK_IS_ICON_ENTRY (icon_entry));
|
||||
|
||||
priv = GTK_ICON_ENTRY_GET_PRIVATE (icon_entry);
|
||||
priv->fraction = CLAMP (fraction, 0.0, 1.0);
|
||||
|
||||
if (GTK_ENTRY (icon_entry)->text_area)
|
||||
gdk_window_invalidate_rect (GTK_ENTRY (icon_entry)->text_area, NULL, FALSE);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -46,6 +46,7 @@ G_BEGIN_DECLS
|
|||
GtkEntryIconPosition position,
|
||||
GdkPixbuf* pixbuf);
|
||||
#define gtk_icon_entry_set_icon_highlight gtk_entry_set_icon_activatable
|
||||
#define gtk_icon_entry_set_progress_fraction gtk_entry_set_progress_fraction
|
||||
#else
|
||||
|
||||
#define GTK_TYPE_ICON_ENTRY (gtk_icon_entry_get_type())
|
||||
|
@ -130,6 +131,9 @@ void gtk_icon_entry_set_icon_sensitive (const GtkIconEntry *icon_entr
|
|||
GtkIconEntryPosition icon_pos,
|
||||
gboolean sensitive);
|
||||
|
||||
void gtk_icon_entry_set_progress_fraction (GtkIconEntry *icon_entry,
|
||||
gdouble fraction);
|
||||
|
||||
#endif
|
||||
|
||||
G_END_DECLS
|
||||
|
|
736
midori/main.c
736
midori/main.c
File diff suppressed because it is too large
Load diff
|
@ -1,8 +1,10 @@
|
|||
BOOLEAN:OBJECT
|
||||
BOOLEAN:OBJECT,UINT
|
||||
BOOLEAN:VOID
|
||||
OBJECT:OBJECT
|
||||
VOID:BOOLEAN,STRING
|
||||
VOID:OBJECT,ENUM
|
||||
VOID:POINTER,INT
|
||||
VOID:STRING,BOOLEAN
|
||||
VOID:STRING,INT,STRING
|
||||
VOID:STRING,STRING
|
||||
|
|
|
@ -62,7 +62,7 @@ struct _MidoriApp
|
|||
|
||||
MidoriAppInstance instance;
|
||||
|
||||
#if !HAVE_HILDON
|
||||
#if !HAVE_HILDON || !HAVE_LIBNOTIFY
|
||||
gchar* program_notify_send;
|
||||
#endif
|
||||
};
|
||||
|
@ -172,7 +172,10 @@ midori_browser_destroy_cb (MidoriBrowser* browser,
|
|||
g_signal_emit (app, signals[REMOVE_BROWSER], 0, browser);
|
||||
katze_array_remove_item (app->browsers, browser);
|
||||
if (!katze_array_is_empty (app->browsers))
|
||||
{
|
||||
app->browser = katze_array_get_nth_item (app->browsers, 0);
|
||||
return FALSE;
|
||||
}
|
||||
midori_app_quit (app);
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -206,8 +209,10 @@ _midori_app_add_browser (MidoriApp* app,
|
|||
|
||||
app->browser = browser;
|
||||
#if HAVE_UNIQUE
|
||||
/* We *do not* let unique watch windows because that includes
|
||||
bringing windows in the foreground, even from other workspaces.
|
||||
if (app->instance)
|
||||
unique_app_watch_window (app->instance, GTK_WINDOW (browser));
|
||||
unique_app_watch_window (app->instance, GTK_WINDOW (browser)); */
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -391,6 +396,15 @@ midori_app_class_init (MidoriAppClass* class)
|
|||
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
|
||||
}
|
||||
|
||||
static void
|
||||
midori_app_raise_window (GtkWindow* window,
|
||||
GdkScreen* screen)
|
||||
{
|
||||
gtk_window_set_screen (window, screen);
|
||||
gtk_window_present (window);
|
||||
gtk_window_deiconify (window);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
midori_app_command_received (MidoriApp* app,
|
||||
const gchar* command,
|
||||
|
@ -410,8 +424,7 @@ midori_app_command_received (MidoriApp* app,
|
|||
if (!app->browser)
|
||||
return FALSE;
|
||||
|
||||
gtk_window_set_screen (GTK_WINDOW (app->browser), screen);
|
||||
gtk_window_present (GTK_WINDOW (app->browser));
|
||||
midori_app_raise_window (GTK_WINDOW (app->browser), screen);
|
||||
return TRUE;
|
||||
}
|
||||
else if (g_str_equal (command, "new"))
|
||||
|
@ -421,8 +434,8 @@ midori_app_command_received (MidoriApp* app,
|
|||
/* FIXME: Should open the homepage according to settings */
|
||||
midori_browser_add_uri (browser, "");
|
||||
midori_browser_activate_action (browser, "Location");
|
||||
gtk_window_set_screen (GTK_WINDOW (app->browser), screen);
|
||||
gtk_widget_show (GTK_WIDGET (browser));
|
||||
midori_app_raise_window (GTK_WINDOW (browser), screen);
|
||||
return TRUE;
|
||||
}
|
||||
else if (g_str_equal (command, "open"))
|
||||
|
@ -430,8 +443,6 @@ midori_app_command_received (MidoriApp* app,
|
|||
if (!app->browser)
|
||||
return FALSE;
|
||||
|
||||
gtk_window_set_screen (GTK_WINDOW (app->browser), screen);
|
||||
gtk_window_present (GTK_WINDOW (app->browser));
|
||||
if (!uris)
|
||||
return FALSE;
|
||||
else
|
||||
|
@ -446,15 +457,19 @@ midori_app_command_received (MidoriApp* app,
|
|||
{
|
||||
browser = midori_app_create_browser (app);
|
||||
midori_app_add_browser (app, browser);
|
||||
gtk_window_set_screen (GTK_WINDOW (app->browser), screen);
|
||||
gtk_widget_show (GTK_WIDGET (browser));
|
||||
}
|
||||
else
|
||||
browser = app->browser;
|
||||
|
||||
midori_app_raise_window (GTK_WINDOW (browser), screen);
|
||||
|
||||
first = (open_external_pages_in == MIDORI_NEW_PAGE_CURRENT);
|
||||
while (*uris)
|
||||
{
|
||||
gchar* fixed_uri = sokoke_magic_uri (*uris, NULL);
|
||||
gchar* fixed_uri = sokoke_magic_uri (*uris);
|
||||
if (!fixed_uri)
|
||||
fixed_uri = g_strdup (*uris);
|
||||
if (first)
|
||||
{
|
||||
midori_browser_set_current_uri (browser, fixed_uri);
|
||||
|
@ -605,8 +620,6 @@ midori_app_io_channel_watch_cb (GIOChannel* channel,
|
|||
}
|
||||
}
|
||||
|
||||
gtk_window_present (GTK_WINDOW (app->browser));
|
||||
|
||||
fd_close (sock);
|
||||
|
||||
return TRUE;
|
||||
|
@ -706,9 +719,10 @@ midori_app_init (MidoriApp* app)
|
|||
|
||||
#if HAVE_LIBNOTIFY
|
||||
notify_init ("midori");
|
||||
#else
|
||||
app->program_notify_send = g_find_program_in_path ("notify-send");
|
||||
#endif
|
||||
|
||||
app->program_notify_send = g_find_program_in_path ("notify-send");
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -739,8 +753,9 @@ midori_app_finalize (GObject* object)
|
|||
#if HAVE_LIBNOTIFY
|
||||
if (notify_is_initted ())
|
||||
notify_uninit ();
|
||||
#else
|
||||
katze_assign (app->program_notify_send, NULL);
|
||||
#endif
|
||||
katze_assign (app->program_notify_send, NULL);
|
||||
|
||||
G_OBJECT_CLASS (midori_app_parent_class)->finalize (object);
|
||||
}
|
||||
|
@ -1165,8 +1180,7 @@ midori_app_send_notification (MidoriApp* app,
|
|||
sent = notify_notification_show (note, NULL);
|
||||
g_object_unref (note);
|
||||
}
|
||||
#endif
|
||||
|
||||
#else
|
||||
/* Fall back to the command line program "notify-send" */
|
||||
if (!sent && app->program_notify_send)
|
||||
{
|
||||
|
@ -1182,4 +1196,5 @@ midori_app_send_notification (MidoriApp* app,
|
|||
g_free (command);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -36,7 +36,7 @@ typedef struct _MidoriApp MidoriApp;
|
|||
typedef struct _MidoriAppClass MidoriAppClass;
|
||||
|
||||
GType
|
||||
midori_app_get_type (void);
|
||||
midori_app_get_type (void) G_GNUC_CONST;
|
||||
|
||||
MidoriApp*
|
||||
midori_app_new (void);
|
||||
|
|
|
@ -23,6 +23,10 @@
|
|||
#include <libxml/tree.h>
|
||||
#endif
|
||||
|
||||
#if HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#define katze_str_equal(str1, str2) !strcmp (str1, str2)
|
||||
|
||||
static void
|
||||
|
@ -416,7 +420,7 @@ midori_array_from_file (KatzeArray* array,
|
|||
g_return_val_if_fail (filename != NULL, FALSE);
|
||||
g_return_val_if_fail (!error || !*error, FALSE);
|
||||
|
||||
if (!g_file_test (filename, G_FILE_TEST_EXISTS))
|
||||
if (g_access (filename, F_OK) != 0)
|
||||
{
|
||||
/* File doesn't exist */
|
||||
if (error)
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -75,7 +75,7 @@ struct _MidoriBrowserClass
|
|||
};
|
||||
|
||||
GType
|
||||
midori_browser_get_type (void);
|
||||
midori_browser_get_type (void) G_GNUC_CONST;
|
||||
|
||||
MidoriBrowser*
|
||||
midori_browser_new (void);
|
||||
|
|
|
@ -46,7 +46,7 @@ struct _MidoriExtensionClass
|
|||
};
|
||||
|
||||
GType
|
||||
midori_extension_get_type (void);
|
||||
midori_extension_get_type (void) G_GNUC_CONST;
|
||||
|
||||
gboolean
|
||||
midori_extension_is_prepared (MidoriExtension* extension);
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -12,8 +12,6 @@
|
|||
#ifndef __MIDORI_LOCATION_ACTION_H__
|
||||
#define __MIDORI_LOCATION_ACTION_H__
|
||||
|
||||
#include "midori-locationentry.h"
|
||||
|
||||
#include <katze/katze.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
@ -35,7 +33,7 @@ typedef struct _MidoriLocationAction MidoriLocationAction;
|
|||
typedef struct _MidoriLocationActionClass MidoriLocationActionClass;
|
||||
|
||||
GType
|
||||
midori_location_action_get_type (void);
|
||||
midori_location_action_get_type (void) G_GNUC_CONST;
|
||||
|
||||
void
|
||||
midori_location_action_freeze (MidoriLocationAction* location_action);
|
||||
|
|
|
@ -1,441 +0,0 @@
|
|||
/*
|
||||
Copyright (C) 2008 Dale Whittaker <dayul@users.sf.net>
|
||||
|
||||
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-locationentry.h"
|
||||
|
||||
#include "gtkiconentry.h"
|
||||
#include "sokoke.h"
|
||||
#include <gdk/gdkkeysyms.h>
|
||||
|
||||
struct _MidoriLocationEntry
|
||||
{
|
||||
GtkComboBoxEntry parent_instance;
|
||||
|
||||
gdouble progress;
|
||||
};
|
||||
|
||||
struct _MidoriLocationEntryClass
|
||||
{
|
||||
GtkComboBoxEntryClass parent_class;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (MidoriLocationEntry,
|
||||
midori_location_entry, GTK_TYPE_COMBO_BOX_ENTRY)
|
||||
|
||||
static gboolean
|
||||
entry_key_press_event (GtkWidget* widget,
|
||||
GdkEventKey* event,
|
||||
MidoriLocationEntry* location_entry);
|
||||
|
||||
static void
|
||||
midori_location_entry_class_init (MidoriLocationEntryClass* class)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
#if !GTK_CHECK_VERSION (2, 16, 0)
|
||||
|
||||
/* GTK+/ GtkEntry internal helper function
|
||||
Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
|
||||
Modified by the GTK+ Team and others 1997-2000
|
||||
Copied from Gtk+ 2.13, whitespace adjusted */
|
||||
static void
|
||||
gtk_entry_get_pixel_ranges (GtkEntry *entry,
|
||||
gint **ranges,
|
||||
gint *n_ranges)
|
||||
{
|
||||
gint start_char, end_char;
|
||||
|
||||
if (gtk_editable_get_selection_bounds (GTK_EDITABLE (entry),
|
||||
&start_char, &end_char))
|
||||
{
|
||||
PangoLayout *layout = gtk_entry_get_layout (entry);
|
||||
PangoLayoutLine *line = pango_layout_get_lines (layout)->data;
|
||||
const char *text = pango_layout_get_text (layout);
|
||||
gsize start_index = g_utf8_offset_to_pointer (text, start_char) - text;
|
||||
gsize end_index = g_utf8_offset_to_pointer (text, end_char) - text;
|
||||
gint real_n_ranges, i;
|
||||
|
||||
pango_layout_line_get_x_ranges (line,
|
||||
start_index, end_index, ranges, &real_n_ranges);
|
||||
|
||||
if (ranges)
|
||||
{
|
||||
gint *r = *ranges;
|
||||
|
||||
for (i = 0; i < real_n_ranges; ++i)
|
||||
{
|
||||
r[2 * i + 1] = (r[2 * i + 1] - r[2 * i]) / PANGO_SCALE;
|
||||
r[2 * i] = r[2 * i] / PANGO_SCALE;
|
||||
}
|
||||
}
|
||||
|
||||
if (n_ranges)
|
||||
*n_ranges = real_n_ranges;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (n_ranges)
|
||||
*n_ranges = 0;
|
||||
if (ranges)
|
||||
*ranges = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* GTK+/ GtkEntry internal helper function
|
||||
Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
|
||||
Modified by the GTK+ Team and others 1997-2000
|
||||
Copied from Gtk+ 2.13, whitespace adjusted
|
||||
Code adjusted to not rely on internal qdata */
|
||||
static void
|
||||
_gtk_entry_effective_inner_border (GtkEntry *entry,
|
||||
GtkBorder *border)
|
||||
{
|
||||
static const GtkBorder default_inner_border = { 2, 2, 2, 2 };
|
||||
GtkBorder *tmp_border;
|
||||
|
||||
tmp_border = (GtkBorder*) gtk_entry_get_inner_border (entry);
|
||||
|
||||
if (tmp_border)
|
||||
{
|
||||
*border = *tmp_border;
|
||||
return;
|
||||
}
|
||||
|
||||
gtk_widget_style_get (GTK_WIDGET (entry), "inner-border", &tmp_border, NULL);
|
||||
|
||||
if (tmp_border)
|
||||
{
|
||||
*border = *tmp_border;
|
||||
gtk_border_free (tmp_border);
|
||||
return;
|
||||
}
|
||||
|
||||
*border = default_inner_border;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_entry_borders (GtkEntry* entry,
|
||||
gint* xborder,
|
||||
gint* yborder,
|
||||
gboolean* interior_focus,
|
||||
gint* focus_width)
|
||||
{
|
||||
GtkWidget *widget = GTK_WIDGET (entry);
|
||||
|
||||
if (entry->has_frame)
|
||||
{
|
||||
*xborder = widget->style->xthickness;
|
||||
*yborder = widget->style->ythickness;
|
||||
}
|
||||
else
|
||||
{
|
||||
*xborder = 0;
|
||||
*yborder = 0;
|
||||
}
|
||||
|
||||
gtk_widget_style_get (widget, "interior-focus", interior_focus,
|
||||
"focus-line-width", focus_width, NULL);
|
||||
|
||||
if (interior_focus)
|
||||
{
|
||||
*xborder += *focus_width;
|
||||
*yborder += *focus_width;
|
||||
}
|
||||
}
|
||||
|
||||
/* GTK+/ GtkEntry internal helper function
|
||||
Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
|
||||
Modified by the GTK+ Team and others 1997-2000
|
||||
Copied from Gtk+ 2.13, whitespace adjusted */
|
||||
static void
|
||||
gtk_entry_get_text_area_size (GtkEntry *entry,
|
||||
gint *x,
|
||||
gint *y,
|
||||
gint *width,
|
||||
gint *height)
|
||||
{
|
||||
gint frame_height;
|
||||
gint xborder, yborder;
|
||||
gboolean interior_focus;
|
||||
gint focus_width;
|
||||
GtkRequisition requisition;
|
||||
GtkWidget *widget = GTK_WIDGET (entry);
|
||||
|
||||
gtk_widget_get_child_requisition (widget, &requisition);
|
||||
gtk_entry_borders (entry, &xborder, &yborder, &interior_focus, &focus_width);
|
||||
|
||||
if (GTK_WIDGET_REALIZED (widget))
|
||||
gdk_drawable_get_size (widget->window, NULL, &frame_height);
|
||||
else
|
||||
frame_height = requisition.height;
|
||||
|
||||
if (GTK_WIDGET_HAS_FOCUS (widget) && interior_focus)
|
||||
frame_height -= 2 * focus_width;
|
||||
|
||||
if (x)
|
||||
*x = xborder;
|
||||
|
||||
if (y)
|
||||
*y = frame_height / 2 - (requisition.height - yborder * 2) / 2;
|
||||
|
||||
if (width)
|
||||
*width = GTK_WIDGET (entry)->allocation.width - xborder * 2;
|
||||
|
||||
if (height)
|
||||
*height = requisition.height - yborder * 2;
|
||||
}
|
||||
|
||||
/* GTK+/ GtkEntry internal helper function
|
||||
Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
|
||||
Modified by the GTK+ Team and others 1997-2000
|
||||
Copied from Gtk+ 2.13, whitespace adjusted */
|
||||
static void
|
||||
get_layout_position (GtkEntry *entry,
|
||||
gint *x,
|
||||
gint *y)
|
||||
{
|
||||
PangoLayout *layout;
|
||||
PangoRectangle logical_rect;
|
||||
gint area_width, area_height;
|
||||
GtkBorder inner_border;
|
||||
gint y_pos;
|
||||
PangoLayoutLine *line;
|
||||
|
||||
layout = gtk_entry_get_layout (entry);
|
||||
|
||||
gtk_entry_get_text_area_size (entry, NULL, NULL, &area_width, &area_height);
|
||||
_gtk_entry_effective_inner_border (entry, &inner_border);
|
||||
|
||||
area_height = PANGO_SCALE *
|
||||
(area_height - inner_border.top - inner_border.bottom);
|
||||
|
||||
line = pango_layout_get_lines (layout)->data;
|
||||
pango_layout_line_get_extents (line, NULL, &logical_rect);
|
||||
|
||||
/* Align primarily for locale's ascent/descent */
|
||||
y_pos = ((area_height - entry->ascent - entry->descent) / 2 +
|
||||
entry->ascent + logical_rect.y);
|
||||
|
||||
/* Now see if we need to adjust to fit in actual drawn string */
|
||||
if (logical_rect.height > area_height)
|
||||
y_pos = (area_height - logical_rect.height) / 2;
|
||||
else if (y_pos < 0)
|
||||
y_pos = 0;
|
||||
else if (y_pos + logical_rect.height > area_height)
|
||||
y_pos = area_height - logical_rect.height;
|
||||
|
||||
y_pos = inner_border.top + y_pos / PANGO_SCALE;
|
||||
|
||||
if (x)
|
||||
*x = inner_border.left - entry->scroll_offset;
|
||||
|
||||
if (y)
|
||||
*y = y_pos;
|
||||
}
|
||||
|
||||
/* GTK+/ GtkEntry internal helper function
|
||||
Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
|
||||
Modified by the GTK+ Team and others 1997-2000
|
||||
Copied from Gtk+ 2.13, whitespace adjusted
|
||||
Code adjusted to not rely on internal _gtk_entry_ensure_layout */
|
||||
static void
|
||||
gtk_entry_draw_text (GtkEntry *entry)
|
||||
{
|
||||
GtkWidget *widget;
|
||||
|
||||
if (!entry->visible && entry->invisible_char == 0)
|
||||
return;
|
||||
|
||||
if (GTK_WIDGET_DRAWABLE (entry))
|
||||
{
|
||||
PangoLayout *layout = gtk_entry_get_layout (entry);
|
||||
cairo_t *cr;
|
||||
gint x, y;
|
||||
gint start_pos, end_pos;
|
||||
|
||||
widget = GTK_WIDGET (entry);
|
||||
|
||||
get_layout_position (entry, &x, &y);
|
||||
|
||||
cr = gdk_cairo_create (entry->text_area);
|
||||
|
||||
cairo_move_to (cr, x, y);
|
||||
gdk_cairo_set_source_color (cr, &widget->style->text [widget->state]);
|
||||
pango_cairo_show_layout (cr, layout);
|
||||
|
||||
if (gtk_editable_get_selection_bounds (GTK_EDITABLE (entry),
|
||||
&start_pos, &end_pos))
|
||||
{
|
||||
gint *ranges;
|
||||
gint n_ranges, i;
|
||||
PangoRectangle logical_rect;
|
||||
GdkColor *selection_color, *text_color;
|
||||
GtkBorder inner_border;
|
||||
|
||||
pango_layout_get_pixel_extents (layout, NULL, &logical_rect);
|
||||
gtk_entry_get_pixel_ranges (entry, &ranges, &n_ranges);
|
||||
|
||||
if (GTK_WIDGET_HAS_FOCUS (entry))
|
||||
{
|
||||
selection_color = &widget->style->base [GTK_STATE_SELECTED];
|
||||
text_color = &widget->style->text [GTK_STATE_SELECTED];
|
||||
}
|
||||
else
|
||||
{
|
||||
selection_color = &widget->style->base [GTK_STATE_ACTIVE];
|
||||
text_color = &widget->style->text [GTK_STATE_ACTIVE];
|
||||
}
|
||||
|
||||
_gtk_entry_effective_inner_border (entry, &inner_border);
|
||||
|
||||
for (i = 0; i < n_ranges; ++i)
|
||||
cairo_rectangle (cr,
|
||||
inner_border.left -
|
||||
entry->scroll_offset + ranges[2 * i],
|
||||
y,
|
||||
ranges[2 * i + 1],
|
||||
logical_rect.height);
|
||||
|
||||
cairo_clip (cr);
|
||||
|
||||
gdk_cairo_set_source_color (cr, selection_color);
|
||||
cairo_paint (cr);
|
||||
|
||||
cairo_move_to (cr, x, y);
|
||||
gdk_cairo_set_source_color (cr, text_color);
|
||||
pango_cairo_show_layout (cr, layout);
|
||||
|
||||
g_free (ranges);
|
||||
}
|
||||
|
||||
cairo_destroy (cr);
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
entry_expose_event (GtkWidget* entry,
|
||||
GdkEventExpose* event,
|
||||
MidoriLocationEntry* location_entry)
|
||||
{
|
||||
GdkWindow* text_area;
|
||||
gint width, height;
|
||||
|
||||
text_area = GTK_ENTRY (entry)->text_area;
|
||||
|
||||
gdk_drawable_get_size (text_area, &width, &height);
|
||||
|
||||
if (location_entry->progress > 0.0)
|
||||
{
|
||||
gtk_paint_box (entry->style, text_area,
|
||||
GTK_STATE_SELECTED, GTK_SHADOW_OUT,
|
||||
&event->area, entry, "bar",
|
||||
0, 0, location_entry->progress * width, height);
|
||||
gtk_entry_draw_text (GTK_ENTRY (entry));
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void
|
||||
midori_location_entry_set_progress (MidoriLocationEntry* location_entry,
|
||||
gdouble progress)
|
||||
{
|
||||
GtkWidget* child;
|
||||
|
||||
g_return_if_fail (MIDORI_IS_LOCATION_ENTRY (location_entry));
|
||||
|
||||
location_entry->progress = CLAMP (progress, 0.0, 1.0);
|
||||
|
||||
child = gtk_bin_get_child (GTK_BIN (location_entry));
|
||||
#if !GTK_CHECK_VERSION (2, 16, 0)
|
||||
if (GTK_ENTRY (child)->text_area)
|
||||
gdk_window_invalidate_rect (GTK_ENTRY (child)->text_area, NULL, FALSE);
|
||||
#else
|
||||
gtk_entry_set_progress_fraction (GTK_ENTRY (child), progress);
|
||||
#endif
|
||||
}
|
||||
|
||||
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"
|
||||
" GtkComboBox::appears-as-list = 1\n }\n"
|
||||
"widget_class \"*MidoriLocationEntry\" "
|
||||
"style \"midori-location-entry-style\"\n");
|
||||
|
||||
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 ();
|
||||
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),
|
||||
GTK_ICON_ENTRY_SECONDARY, TRUE);
|
||||
#endif
|
||||
g_signal_connect_after (entry, "key-press-event",
|
||||
G_CALLBACK (entry_key_press_event), location_entry);
|
||||
#if !GTK_CHECK_VERSION (2, 16, 0)
|
||||
g_signal_connect_after (entry, "expose-event",
|
||||
G_CALLBACK (entry_expose_event), location_entry);
|
||||
#endif
|
||||
gtk_widget_show (entry);
|
||||
gtk_container_add (GTK_CONTAINER (location_entry), entry);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
entry_key_press_event (GtkWidget* widget,
|
||||
GdkEventKey* event,
|
||||
MidoriLocationEntry* location_entry)
|
||||
{
|
||||
switch (event->keyval)
|
||||
{
|
||||
case GDK_Down:
|
||||
case GDK_Up:
|
||||
{
|
||||
if (!katze_object_get_boolean (location_entry, "popup-shown"))
|
||||
gtk_combo_box_popup (GTK_COMBO_BOX (location_entry));
|
||||
return TRUE;
|
||||
}
|
||||
case GDK_Page_Up:
|
||||
case GDK_Page_Down:
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* midori_location_entry_new:
|
||||
*
|
||||
* Creates a new #MidoriLocationEntry.
|
||||
*
|
||||
* Return value: a new #MidoriLocationEntry
|
||||
**/
|
||||
GtkWidget*
|
||||
midori_location_entry_new (void)
|
||||
{
|
||||
return g_object_new (MIDORI_TYPE_LOCATION_ENTRY, NULL);
|
||||
}
|
|
@ -1,41 +0,0 @@
|
|||
/*
|
||||
Copyright (C) 2008 Dale Whittaker <dayul@users.sf.net>
|
||||
|
||||
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 __MIDORI_LOCATION_ENTRY_H__
|
||||
#define __MIDORI_LOCATION_ENTRY_H__
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define MIDORI_TYPE_LOCATION_ENTRY (midori_location_entry_get_type ())
|
||||
#define MIDORI_LOCATION_ENTRY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), MIDORI_TYPE_LOCATION_ENTRY, MidoriLocationEntry))
|
||||
#define MIDORI_LOCATION_ENTRY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), MIDORI_TYPE_LOCATION_ENTRY, MidoriLocationEntryClass))
|
||||
#define MIDORI_IS_LOCATION_ENTRY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MIDORI_TYPE_LOCATION_ENTRY))
|
||||
#define MIDORI_IS_LOCATION_ENTRY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), MIDORI_TYPE_LOCATION_ENTRY))
|
||||
#define MIDORI_LOCATION_ENTRY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), MIDORI_TYPE_LOCATION_ENTRY, MidoriLocationEntryClass))
|
||||
|
||||
typedef struct _MidoriLocationEntry MidoriLocationEntry;
|
||||
typedef struct _MidoriLocationEntryClass MidoriLocationEntryClass;
|
||||
|
||||
GType
|
||||
midori_location_entry_get_type (void);
|
||||
|
||||
GtkWidget*
|
||||
midori_location_entry_new (void);
|
||||
|
||||
void
|
||||
midori_location_entry_set_progress (MidoriLocationEntry* location_entry,
|
||||
gdouble progress);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __MIDORI_LOCATION_ENTRY_H__ */
|
|
@ -13,7 +13,6 @@
|
|||
|
||||
#include "midori-view.h"
|
||||
|
||||
#include "compat.h"
|
||||
#include "marshal.h"
|
||||
#include "sokoke.h"
|
||||
|
||||
|
@ -33,6 +32,7 @@ struct _MidoriPanel
|
|||
GtkWidget* toolbar;
|
||||
GtkToolItem* button_align;
|
||||
GtkToolItem* button_detach;
|
||||
GtkToolItem* button_controls;
|
||||
GtkWidget* toolbar_label;
|
||||
GtkWidget* frame;
|
||||
GtkWidget* toolbook;
|
||||
|
@ -197,7 +197,7 @@ midori_panel_class_init (MidoriPanelClass* class)
|
|||
*
|
||||
* Whether to show panel titles.
|
||||
*
|
||||
* Since: 0.1.9
|
||||
* Deprecated: 0.2.3
|
||||
*/
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_SHOW_TITLES,
|
||||
|
@ -405,14 +405,13 @@ midori_panel_init (MidoriPanel* panel)
|
|||
|
||||
/* Create the sidebar */
|
||||
panel->toolbar = gtk_toolbar_new ();
|
||||
gtk_toolbar_set_style (GTK_TOOLBAR (panel->toolbar), GTK_TOOLBAR_BOTH);
|
||||
gtk_toolbar_set_icon_size (GTK_TOOLBAR (panel->toolbar),
|
||||
GTK_ICON_SIZE_BUTTON);
|
||||
g_object_set (panel->toolbar, "orientation", GTK_ORIENTATION_VERTICAL, NULL);
|
||||
gtk_box_pack_start (GTK_BOX (panel), panel->toolbar, FALSE, FALSE, 0);
|
||||
gtk_toolbar_set_style (GTK_TOOLBAR (panel->toolbar), GTK_TOOLBAR_ICONS);
|
||||
gtk_toolbar_set_icon_size (GTK_TOOLBAR (panel->toolbar), GTK_ICON_SIZE_BUTTON);
|
||||
gtk_toolbar_set_show_arrow (GTK_TOOLBAR (panel->toolbar), FALSE);
|
||||
gtk_widget_show_all (panel->toolbar);
|
||||
vbox = gtk_vbox_new (FALSE, 0);
|
||||
gtk_box_pack_start (GTK_BOX (panel), vbox, TRUE, TRUE, 0);
|
||||
gtk_box_pack_end (GTK_BOX (vbox), panel->toolbar, FALSE, FALSE, 0);
|
||||
|
||||
/* Create the titlebar */
|
||||
labelbar = gtk_toolbar_new ();
|
||||
|
@ -518,13 +517,16 @@ midori_panel_set_property (GObject* object,
|
|||
break;
|
||||
case PROP_SHOW_TITLES:
|
||||
panel->show_titles = g_value_get_boolean (value);
|
||||
gtk_toolbar_set_style (GTK_TOOLBAR (panel->toolbar),
|
||||
panel->show_titles ? GTK_TOOLBAR_BOTH : GTK_TOOLBAR_ICONS);
|
||||
/* Ignore */
|
||||
break;
|
||||
case PROP_SHOW_CONTROLS:
|
||||
panel->show_controls = g_value_get_boolean (value);
|
||||
sokoke_widget_set_visible (panel->labelbar, panel->show_controls);
|
||||
sokoke_widget_set_visible (panel->toolbar, panel->show_controls);
|
||||
if (panel->button_controls)
|
||||
gtk_toggle_tool_button_set_active (
|
||||
GTK_TOGGLE_TOOL_BUTTON (panel->button_controls),
|
||||
!panel->show_controls);
|
||||
break;
|
||||
case PROP_RIGHT_ALIGNED:
|
||||
midori_panel_set_right_aligned (panel, g_value_get_boolean (value));
|
||||
|
@ -692,54 +694,6 @@ midori_panel_construct_tool_item (MidoriPanel* panel,
|
|||
return GTK_TOOL_ITEM (toolitem);
|
||||
}
|
||||
|
||||
#if !HAVE_HILDON
|
||||
static void
|
||||
midori_panel_show_titles_toggled_cb (GtkWidget* menuitem,
|
||||
MidoriPanel* panel)
|
||||
{
|
||||
g_object_set (panel, "show-titles", !panel->show_titles, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
midori_panel_show_controls_toggled_cb (GtkWidget* menuitem,
|
||||
MidoriPanel* panel)
|
||||
{
|
||||
g_object_set (panel, "show-controls", !panel->show_controls, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
midori_panel_options_clicked_cb (GtkToolItem* toolitem,
|
||||
MidoriPanel* panel)
|
||||
{
|
||||
gint n;
|
||||
GtkWidget* viewable;
|
||||
GtkWidget* menu;
|
||||
GtkWidget* menuitem;
|
||||
|
||||
n = midori_panel_get_current_page (panel);
|
||||
viewable = midori_panel_get_nth_page (panel, n);
|
||||
menu = gtk_menu_new ();
|
||||
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);
|
||||
g_signal_connect (menuitem, "toggled",
|
||||
G_CALLBACK (midori_panel_show_titles_toggled_cb), panel);
|
||||
gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
|
||||
gtk_widget_show (menuitem);
|
||||
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);
|
||||
g_signal_connect (menuitem, "toggled",
|
||||
G_CALLBACK (midori_panel_show_controls_toggled_cb), panel);
|
||||
gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
|
||||
gtk_widget_show (menuitem);
|
||||
g_signal_emit_by_name (viewable, "populate-option-menu", menu);
|
||||
|
||||
katze_widget_popup (GTK_WIDGET (toolitem), GTK_MENU (menu),
|
||||
NULL, KATZE_MENU_POSITION_LEFT);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
midori_panel_action_activate_cb (GtkRadioAction* action,
|
||||
MidoriPanel* panel)
|
||||
|
@ -767,6 +721,16 @@ midori_panel_action_activate_cb (GtkRadioAction* action,
|
|||
}
|
||||
}
|
||||
|
||||
#if !HAVE_HILDON
|
||||
static void
|
||||
midori_panel_show_controls_toggled_cb (GtkWidget* menuitem,
|
||||
MidoriPanel* panel)
|
||||
{
|
||||
if (panel->show_controls != !gtk_toggle_tool_button_get_active (GTK_TOGGLE_TOOL_BUTTON (menuitem)))
|
||||
g_object_set (panel, "show-controls", !panel->show_controls, NULL);
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* midori_panel_append_page:
|
||||
* @panel: a #MidoriPanel
|
||||
|
@ -830,12 +794,15 @@ midori_panel_append_page (MidoriPanel* panel,
|
|||
|
||||
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"));
|
||||
toolitem = gtk_toggle_tool_button_new_from_stock (GTK_STOCK_PROPERTIES);
|
||||
gtk_tool_item_set_tooltip_text (toolitem, _("Hide operating controls"));
|
||||
gtk_toggle_tool_button_set_active (GTK_TOGGLE_TOOL_BUTTON (toolitem),
|
||||
!panel->show_controls);
|
||||
g_signal_connect (toolitem, "clicked",
|
||||
G_CALLBACK (midori_panel_options_clicked_cb), panel);
|
||||
G_CALLBACK (midori_panel_show_controls_toggled_cb), panel);
|
||||
gtk_toolbar_insert (GTK_TOOLBAR (toolbar), toolitem, 0);
|
||||
gtk_widget_show (GTK_WIDGET (toolitem));
|
||||
panel->button_controls = toolitem;
|
||||
#endif
|
||||
gtk_widget_show (toolbar);
|
||||
gtk_container_add (GTK_CONTAINER (panel->toolbook), toolbar);
|
||||
|
@ -848,19 +815,19 @@ midori_panel_append_page (MidoriPanel* panel,
|
|||
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);
|
||||
midori_viewable_get_label (viewable),
|
||||
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);
|
||||
gtk_action_connect_accelerator (action);
|
||||
}
|
||||
if (n > 0)
|
||||
g_object_set (action, "group", g_object_get_data (
|
||||
|
@ -1021,11 +988,19 @@ midori_panel_set_current_page (MidoriPanel* panel,
|
|||
|
||||
if ((viewable = midori_panel_get_nth_page (panel, n)))
|
||||
{
|
||||
GtkWidget* toolbar;
|
||||
GList* items;
|
||||
const gchar* label;
|
||||
|
||||
if (!GTK_WIDGET_VISIBLE (viewable))
|
||||
return;
|
||||
|
||||
gtk_notebook_set_current_page (GTK_NOTEBOOK (panel->toolbook), n);
|
||||
toolbar = gtk_notebook_get_nth_page (GTK_NOTEBOOK (panel->toolbook), n);
|
||||
items = gtk_container_get_children (GTK_CONTAINER (toolbar));
|
||||
sokoke_widget_set_visible (panel->toolbook,
|
||||
g_list_nth_data (items, 1) != NULL);
|
||||
g_list_free (items);
|
||||
gtk_notebook_set_current_page (GTK_NOTEBOOK (panel->notebook), n);
|
||||
label = midori_viewable_get_label (MIDORI_VIEWABLE (viewable));
|
||||
g_object_set (panel->toolbar_label, "label", label, NULL);
|
||||
|
|
|
@ -37,7 +37,7 @@ typedef struct _MidoriPanel MidoriPanel;
|
|||
typedef struct _MidoriPanelClass MidoriPanelClass;
|
||||
|
||||
GType
|
||||
midori_panel_get_type (void);
|
||||
midori_panel_get_type (void) G_GNUC_CONST;
|
||||
|
||||
GtkWidget*
|
||||
midori_panel_new (void);
|
||||
|
|
|
@ -16,7 +16,6 @@
|
|||
#endif
|
||||
|
||||
#include "sokoke.h"
|
||||
#include "compat.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <glib/gi18n.h>
|
||||
|
@ -390,7 +389,11 @@ midori_preferences_set_settings (MidoriPreferences* preferences,
|
|||
GTK_WIDGET (parent) : GTK_WIDGET (preferences)))
|
||||
button = katze_property_proxy (settings, "kinetic-scrolling", NULL);
|
||||
else
|
||||
button = katze_property_proxy (settings, "open-panels-in-windows", NULL);
|
||||
{
|
||||
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"));
|
||||
}
|
||||
#else
|
||||
button = katze_property_proxy (settings, "middle-click-opens-selection", NULL);
|
||||
#endif
|
||||
|
@ -398,21 +401,15 @@ midori_preferences_set_settings (MidoriPreferences* preferences,
|
|||
#if !HAVE_HILDON
|
||||
button = katze_property_proxy (settings, "enable-scripts", NULL);
|
||||
INDENTED_ADD (button);
|
||||
button = katze_property_proxy (settings, "open-panels-in-windows", NULL);
|
||||
SPANNED_ADD (button);
|
||||
button = katze_property_proxy (settings, "enable-plugins", NULL);
|
||||
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"));
|
||||
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);
|
||||
#endif
|
||||
button = katze_property_proxy (settings, "zoom-text-and-images", NULL);
|
||||
INDENTED_ADD (button);
|
||||
button = katze_property_proxy (settings, "find-while-typing", NULL);
|
||||
SPANNED_ADD (button);
|
||||
button = katze_property_proxy (settings, "zoom-text-and-images", NULL);
|
||||
INDENTED_ADD (button);
|
||||
#if WEBKIT_CHECK_VERSION (1, 1, 6)
|
||||
FRAME_NEW (_("Spell Checking"));
|
||||
/* FIXME: Provide a nice dictionary selection */
|
||||
|
@ -420,6 +417,8 @@ midori_preferences_set_settings (MidoriPreferences* preferences,
|
|||
gtk_button_set_label (GTK_BUTTON (button), _("Enable Spell Checking"));
|
||||
gtk_widget_set_tooltip_text (button, _("Enable spell checking while typing"));
|
||||
INDENTED_ADD (button);
|
||||
button = gtk_label_new (_("Spelling dictionaries:"));
|
||||
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 "
|
||||
|
@ -469,7 +468,7 @@ midori_preferences_set_settings (MidoriPreferences* preferences,
|
|||
SPANNED_ADD (entry);
|
||||
label = katze_property_label (settings, "download-manager");
|
||||
INDENTED_ADD (label);
|
||||
entry = katze_property_proxy (settings, "download-manager", "application-Network");
|
||||
entry = katze_property_proxy (settings, "download-manager", "application-FileTransfer");
|
||||
SPANNED_ADD (entry);
|
||||
label = katze_property_label (settings, "news-aggregator");
|
||||
INDENTED_ADD (label);
|
||||
|
@ -494,8 +493,13 @@ midori_preferences_set_settings (MidoriPreferences* preferences,
|
|||
#endif
|
||||
label = katze_property_label (settings, "identify-as");
|
||||
INDENTED_ADD (label);
|
||||
button = katze_property_proxy (settings, "identify-as", "custom-ident-string");
|
||||
button = katze_property_proxy (settings, "identify-as", "custom-user-agent");
|
||||
SPANNED_ADD (button);
|
||||
label = katze_property_label (settings, "preferred-languages");
|
||||
INDENTED_ADD (label);
|
||||
entry = katze_property_proxy (settings, "preferred-languages", NULL);
|
||||
SPANNED_ADD (entry);
|
||||
|
||||
|
||||
/* Page "Privacy" */
|
||||
PAGE_NEW (GTK_STOCK_INDEX, _("Privacy"));
|
||||
|
@ -504,14 +508,19 @@ midori_preferences_set_settings (MidoriPreferences* preferences,
|
|||
INDENTED_ADD (label);
|
||||
button = katze_property_proxy (settings, "accept-cookies", NULL);
|
||||
SPANNED_ADD (button);
|
||||
button = katze_property_proxy (settings, "original-cookies-only", NULL);
|
||||
INDENTED_ADD (button);
|
||||
label = katze_property_label (settings, "maximum-cookie-age");
|
||||
INDENTED_ADD (label);
|
||||
entry = katze_property_proxy (settings, "maximum-cookie-age", NULL);
|
||||
SPANNED_ADD (entry);
|
||||
label = gtk_label_new (_("days"));
|
||||
SPANNED_ADD (label);
|
||||
#if WEBKIT_CHECK_VERSION (1, 1, 8)
|
||||
INDENTED_ADD (katze_property_proxy (settings, "enable-html5-database", NULL));
|
||||
SPANNED_ADD (katze_property_proxy (settings, "enable-html5-local-storage", NULL));
|
||||
#endif
|
||||
#if WEBKIT_CHECK_VERSION (1, 1, 13)
|
||||
INDENTED_ADD (katze_property_proxy (settings, "enable-offline-web-application-cache", NULL));
|
||||
#endif
|
||||
FRAME_NEW (_("History"));
|
||||
button = katze_property_label (settings, "maximum-history-age");
|
||||
INDENTED_ADD (button);
|
||||
|
|
|
@ -40,7 +40,7 @@ struct _MidoriPreferencesClass
|
|||
};
|
||||
|
||||
GType
|
||||
midori_preferences_get_type (void);
|
||||
midori_preferences_get_type (void) G_GNUC_CONST;
|
||||
|
||||
GtkWidget*
|
||||
midori_preferences_new (GtkWindow* parent,
|
||||
|
|
|
@ -28,8 +28,6 @@ struct _MidoriSearchAction
|
|||
KatzeItem* default_item;
|
||||
gchar* text;
|
||||
|
||||
KatzeNet* net;
|
||||
|
||||
GtkWidget* last_proxy;
|
||||
|
||||
GtkWidget* dialog;
|
||||
|
@ -193,8 +191,6 @@ midori_search_action_init (MidoriSearchAction* search_action)
|
|||
search_action->default_item = NULL;
|
||||
search_action->text = NULL;
|
||||
|
||||
search_action->net = katze_net_new ();
|
||||
|
||||
search_action->last_proxy = NULL;
|
||||
|
||||
search_action->dialog = NULL;
|
||||
|
@ -211,8 +207,6 @@ midori_search_action_finalize (GObject* object)
|
|||
|
||||
katze_assign (search_action->text, NULL);
|
||||
|
||||
katze_object_assign (search_action->net, NULL);
|
||||
|
||||
G_OBJECT_CLASS (midori_search_action_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
|
@ -357,15 +351,15 @@ midori_search_action_key_press_event_cb (GtkWidget* entry,
|
|||
case GDK_Return:
|
||||
text = gtk_entry_get_text (GTK_ENTRY (entry));
|
||||
g_signal_emit (search_action, signals[SUBMIT], 0, text,
|
||||
(event->state & GDK_MOD1_MASK) ? TRUE : FALSE);
|
||||
MIDORI_MOD_NEW_TAB (event->state));
|
||||
search_action->last_proxy = entry;
|
||||
return TRUE;
|
||||
case GDK_Up:
|
||||
if (event->state & GDK_CONTROL_MASK)
|
||||
if (MIDORI_MOD_SCROLL (event->state))
|
||||
_midori_search_action_move_index (search_action, - 1);
|
||||
return TRUE;
|
||||
case GDK_Down:
|
||||
if (event->state & GDK_CONTROL_MASK)
|
||||
if (MIDORI_MOD_SCROLL (event->state))
|
||||
_midori_search_action_move_index (search_action, + 1);
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -413,6 +407,9 @@ midori_search_action_get_icon (KatzeItem* item,
|
|||
{
|
||||
const gchar* icon;
|
||||
|
||||
if ((icon = katze_item_get_uri (item)) && (g_strstr_len (icon, 8, "://")))
|
||||
return katze_load_cached_icon (icon, widget);
|
||||
|
||||
if ((icon = katze_item_get_icon (item)) && *icon)
|
||||
{
|
||||
GdkScreen* screen;
|
||||
|
@ -421,15 +418,12 @@ midori_search_action_get_icon (KatzeItem* item,
|
|||
screen = gtk_widget_get_screen (widget);
|
||||
icon_theme = gtk_icon_theme_get_for_screen (screen);
|
||||
if (gtk_icon_theme_has_icon (icon_theme, icon))
|
||||
{
|
||||
*icon_name = icon;
|
||||
else
|
||||
*icon_name = GTK_STOCK_FILE;
|
||||
return NULL;
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if ((icon = katze_item_get_uri (item)) && (g_strstr_len (icon, 8, "://")))
|
||||
return katze_load_cached_icon (icon, widget);
|
||||
|
||||
*icon_name = GTK_STOCK_FILE;
|
||||
return NULL;
|
||||
}
|
||||
|
@ -440,10 +434,6 @@ midori_search_action_icon_released_cb (GtkWidget* entry,
|
|||
gint button,
|
||||
GtkAction* action)
|
||||
{
|
||||
|
||||
if (icon_pos == GTK_ICON_ENTRY_SECONDARY)
|
||||
return;
|
||||
|
||||
KatzeArray* search_engines;
|
||||
GtkWidget* menu;
|
||||
guint i;
|
||||
|
@ -452,6 +442,9 @@ midori_search_action_icon_released_cb (GtkWidget* entry,
|
|||
GdkPixbuf* icon;
|
||||
GtkWidget* image;
|
||||
|
||||
if (icon_pos == GTK_ICON_ENTRY_SECONDARY)
|
||||
return;
|
||||
|
||||
search_engines = MIDORI_SEARCH_ACTION (action)->search_engines;
|
||||
menu = gtk_menu_new ();
|
||||
i = 0;
|
||||
|
@ -812,7 +805,8 @@ midori_search_action_dialog_render_tick_cb (GtkTreeViewColumn* column,
|
|||
gtk_tree_model_get (model, iter, 0, &item, -1);
|
||||
|
||||
search_action = g_object_get_data (G_OBJECT (treeview), "search-action");
|
||||
gtk_icon_size_lookup (GTK_ICON_SIZE_MENU, &width, NULL);
|
||||
gtk_icon_size_lookup_for_settings (gtk_widget_get_settings (treeview),
|
||||
GTK_ICON_SIZE_MENU, &width, NULL);
|
||||
g_object_set (renderer, "stock-id",
|
||||
search_action->default_item == item ? GTK_STOCK_YES : NULL,
|
||||
"width", width + 4, NULL);
|
||||
|
@ -1189,6 +1183,14 @@ midori_search_action_treeview_destroy_cb (GtkWidget* treeview,
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
midori_search_action_dialog_respnse_cb (GtkWidget* dialog,
|
||||
gint response,
|
||||
gpointer data)
|
||||
{
|
||||
gtk_widget_destroy (dialog);
|
||||
}
|
||||
|
||||
/**
|
||||
* midori_search_action_get_dialog:
|
||||
* @search_action: a #MidoriSearchAction
|
||||
|
@ -1251,7 +1253,7 @@ midori_search_action_get_dialog (MidoriSearchAction* search_action)
|
|||
sokoke_widget_get_text_size (dialog, "M", &width, &height);
|
||||
gtk_window_set_default_size (GTK_WINDOW (dialog), width * 52, -1);
|
||||
g_signal_connect (dialog, "response",
|
||||
G_CALLBACK (gtk_widget_destroy), dialog);
|
||||
G_CALLBACK (midori_search_action_dialog_respnse_cb), NULL);
|
||||
/* TODO: Do we want tooltips for explainations or can we omit that?
|
||||
We need mnemonics */
|
||||
if ((xfce_heading = sokoke_xfce_header_new (
|
||||
|
|
|
@ -33,7 +33,7 @@ typedef struct _MidoriSearchAction MidoriSearchAction;
|
|||
typedef struct _MidoriSearchActionClass MidoriSearchActionClass;
|
||||
|
||||
GType
|
||||
midori_search_action_get_type (void);
|
||||
midori_search_action_get_type (void) G_GNUC_CONST;
|
||||
|
||||
const gchar*
|
||||
midori_search_action_get_text (MidoriSearchAction* action);
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -61,7 +61,7 @@ typedef struct _MidoriView MidoriView;
|
|||
typedef struct _MidoriViewClass MidoriViewClass;
|
||||
|
||||
GType
|
||||
midori_view_get_type (void);
|
||||
midori_view_get_type (void) G_GNUC_CONST;
|
||||
|
||||
GtkWidget*
|
||||
midori_view_new (KatzeNet* net);
|
||||
|
@ -160,6 +160,12 @@ midori_view_can_go_forward (MidoriView* view);
|
|||
void
|
||||
midori_view_go_forward (MidoriView* view);
|
||||
|
||||
const gchar*
|
||||
midori_view_get_previous_page (MidoriView* view);
|
||||
|
||||
const gchar*
|
||||
midori_view_get_next_page (MidoriView* view);
|
||||
|
||||
gboolean
|
||||
midori_view_can_print (MidoriView* view);
|
||||
|
||||
|
|
|
@ -84,7 +84,7 @@ midori_viewable_base_init (MidoriViewableIface* iface)
|
|||
* Emitted when an Option menu is displayed, for instance
|
||||
* when the user clicks the Options button in the panel.
|
||||
*
|
||||
* Since: 0.1.9
|
||||
* Deprecated: 0.2.3
|
||||
*/
|
||||
signals[POPULATE_OPTION_MENU] = g_signal_new (
|
||||
"populate-option-menu",
|
||||
|
|
|
@ -50,7 +50,7 @@ struct _MidoriViewableIface
|
|||
};
|
||||
|
||||
GType
|
||||
midori_viewable_get_type (void);
|
||||
midori_viewable_get_type (void) G_GNUC_CONST;
|
||||
|
||||
GtkWidget*
|
||||
midori_viewable_new_from_uri (const gchar* uri);
|
||||
|
|
|
@ -86,6 +86,7 @@ struct _MidoriWebSettings
|
|||
gboolean remember_last_downloaded_files;
|
||||
|
||||
gchar* http_proxy;
|
||||
gchar* http_accept_language;
|
||||
gboolean auto_detect_proxy;
|
||||
MidoriIdentity identify_as;
|
||||
gchar* ident_string;
|
||||
|
@ -153,6 +154,11 @@ enum
|
|||
PROP_AUTO_LOAD_IMAGES,
|
||||
PROP_ENABLE_SCRIPTS,
|
||||
PROP_ENABLE_PLUGINS,
|
||||
PROP_ENABLE_DEVELOPER_EXTRAS,
|
||||
PROP_ENABLE_HTML5_DATABASE,
|
||||
PROP_ENABLE_HTML5_LOCAL_STORAGE,
|
||||
PROP_ENABLE_OFFLINE_WEB_APPLICATION_CACHE,
|
||||
PROP_ENABLE_PAGE_CACHE,
|
||||
PROP_ZOOM_TEXT_AND_IMAGES,
|
||||
PROP_FIND_WHILE_TYPING,
|
||||
PROP_KINETIC_SCROLLING,
|
||||
|
@ -167,7 +173,8 @@ enum
|
|||
PROP_HTTP_PROXY,
|
||||
PROP_AUTO_DETECT_PROXY,
|
||||
PROP_IDENTIFY_AS,
|
||||
PROP_IDENT_STRING,
|
||||
PROP_USER_AGENT,
|
||||
PROP_PREFERRED_LANGUAGES,
|
||||
|
||||
PROP_CLEAR_PRIVATE_DATA
|
||||
};
|
||||
|
@ -525,7 +532,7 @@ midori_web_settings_class_init (MidoriWebSettingsClass* class)
|
|||
"toolbar-items",
|
||||
_("Toolbar Items"),
|
||||
_("The items to show on the toolbar"),
|
||||
"TabNew,Back,Forward,ReloadStop,Location,Panel,Search,Trash",
|
||||
"TabNew,Back,Forward,Next,ReloadStop,Location,Panel,Search,Trash",
|
||||
flags));
|
||||
|
||||
g_object_class_install_property (gobject_class,
|
||||
|
@ -646,7 +653,7 @@ midori_web_settings_class_init (MidoriWebSettingsClass* class)
|
|||
_("The folder downloaded files are saved to"),
|
||||
midori_get_download_dir (),
|
||||
#if WEBKIT_CHECK_VERSION (1, 1, 3)
|
||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||
flags));
|
||||
#else
|
||||
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
|
||||
#endif
|
||||
|
@ -668,7 +675,7 @@ midori_web_settings_class_init (MidoriWebSettingsClass* class)
|
|||
_("Whether to ask for the destination folder when downloading a file"),
|
||||
FALSE,
|
||||
#if WEBKIT_CHECK_VERSION (1, 1, 15)
|
||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||
flags));
|
||||
#else
|
||||
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
|
||||
#endif
|
||||
|
@ -688,7 +695,7 @@ midori_web_settings_class_init (MidoriWebSettingsClass* class)
|
|||
_("Whether to show a notification when a transfer has been completed"),
|
||||
TRUE,
|
||||
#if WEBKIT_CHECK_VERSION (1, 1, 3)
|
||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||
flags));
|
||||
#else
|
||||
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
|
||||
#endif
|
||||
|
@ -733,7 +740,7 @@ midori_web_settings_class_init (MidoriWebSettingsClass* class)
|
|||
"location-entry-search",
|
||||
_("Location entry Search"),
|
||||
_("The search to perform inside the location entry"),
|
||||
"http://www.google.com/search?q=%s",
|
||||
NULL,
|
||||
flags));
|
||||
|
||||
g_object_class_install_property (gobject_class,
|
||||
|
@ -773,7 +780,7 @@ midori_web_settings_class_init (MidoriWebSettingsClass* class)
|
|||
_("Where to open new pages"),
|
||||
MIDORI_TYPE_NEW_PAGE,
|
||||
MIDORI_NEW_PAGE_TAB,
|
||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||
flags));
|
||||
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_OPEN_EXTERNAL_PAGES_IN,
|
||||
|
@ -783,7 +790,7 @@ midori_web_settings_class_init (MidoriWebSettingsClass* class)
|
|||
_("Where to open externally opened pages"),
|
||||
MIDORI_TYPE_NEW_PAGE,
|
||||
MIDORI_NEW_PAGE_TAB,
|
||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||
flags));
|
||||
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_MIDDLE_CLICK_OPENS_SELECTION,
|
||||
|
@ -819,7 +826,7 @@ midori_web_settings_class_init (MidoriWebSettingsClass* class)
|
|||
_("Open popups in tabs"),
|
||||
_("Whether to open popup windows in tabs"),
|
||||
TRUE,
|
||||
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
|
||||
flags));
|
||||
|
||||
|
||||
/* Override properties to localize them for preference proxies */
|
||||
|
@ -847,6 +854,49 @@ midori_web_settings_class_init (MidoriWebSettingsClass* class)
|
|||
_("Enable embedded Netscape plugin objects"),
|
||||
TRUE,
|
||||
flags));
|
||||
/* Override properties to override defaults */
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_ENABLE_DEVELOPER_EXTRAS,
|
||||
g_param_spec_boolean (
|
||||
"enable-developer-extras",
|
||||
"Enable developer tools",
|
||||
"Enable special extensions for developers",
|
||||
TRUE,
|
||||
flags));
|
||||
#if WEBKIT_CHECK_VERSION (1, 1, 8)
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_ENABLE_HTML5_DATABASE,
|
||||
g_param_spec_boolean ("enable-html5-database",
|
||||
_("Enable HTML5 database support"),
|
||||
_("Whether to enable HTML5 database support"),
|
||||
FALSE,
|
||||
flags));
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_ENABLE_HTML5_LOCAL_STORAGE,
|
||||
g_param_spec_boolean ("enable-html5-local-storage",
|
||||
_("Enable HTML5 local storage support"),
|
||||
_("Whether to enable HTML5 local storage support"),
|
||||
FALSE,
|
||||
flags));
|
||||
#endif
|
||||
#if WEBKIT_CHECK_VERSION (1, 1, 13)
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_ENABLE_OFFLINE_WEB_APPLICATION_CACHE,
|
||||
g_param_spec_boolean ("enable-offline-web-application-cache",
|
||||
_("Enable offline web application cache"),
|
||||
_("Whether to enable offline web application cache"),
|
||||
FALSE,
|
||||
flags));
|
||||
#endif
|
||||
#if WEBKIT_CHECK_VERSION (1, 1, 18)
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_ENABLE_PAGE_CACHE,
|
||||
g_param_spec_boolean ("enable-page-cache",
|
||||
"Enable page cache",
|
||||
"Whether the page cache should be used",
|
||||
TRUE,
|
||||
flags));
|
||||
#endif
|
||||
|
||||
/**
|
||||
* MidoriWebSettings:zoom-text-and-images:
|
||||
|
@ -862,7 +912,7 @@ midori_web_settings_class_init (MidoriWebSettingsClass* class)
|
|||
_("Zoom Text and Images"),
|
||||
_("Whether to zoom text and images"),
|
||||
FALSE,
|
||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||
flags));
|
||||
|
||||
/**
|
||||
* MidoriWebSettings:find-while-typing:
|
||||
|
@ -904,8 +954,15 @@ midori_web_settings_class_init (MidoriWebSettingsClass* class)
|
|||
_("What type of cookies to accept"),
|
||||
MIDORI_TYPE_ACCEPT_COOKIES,
|
||||
MIDORI_ACCEPT_COOKIES_ALL,
|
||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||
flags));
|
||||
|
||||
/**
|
||||
* MidoriWebSettings:original-cookies-only:
|
||||
*
|
||||
* Accept cookies from the original website only.
|
||||
*
|
||||
* Deprecated: 0.2.3: This value is not used.
|
||||
*/
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_ORIGINAL_COOKIES_ONLY,
|
||||
g_param_spec_boolean (
|
||||
|
@ -913,7 +970,7 @@ midori_web_settings_class_init (MidoriWebSettingsClass* class)
|
|||
_("Original cookies only"),
|
||||
_("Accept cookies from the original website only"),
|
||||
FALSE,
|
||||
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
|
||||
flags));
|
||||
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_MAXIMUM_COOKIE_AGE,
|
||||
|
@ -922,7 +979,7 @@ midori_web_settings_class_init (MidoriWebSettingsClass* class)
|
|||
_("Maximum cookie age"),
|
||||
_("The maximum number of days to save cookies for"),
|
||||
0, G_MAXINT, 30,
|
||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||
flags));
|
||||
|
||||
|
||||
|
||||
|
@ -958,7 +1015,7 @@ midori_web_settings_class_init (MidoriWebSettingsClass* class)
|
|||
_("Remember last downloaded files"),
|
||||
_("Whether the last downloaded files are saved"),
|
||||
TRUE,
|
||||
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
|
||||
flags));
|
||||
|
||||
|
||||
|
||||
|
@ -969,7 +1026,7 @@ midori_web_settings_class_init (MidoriWebSettingsClass* class)
|
|||
_("Proxy Server"),
|
||||
_("The proxy server used for HTTP connections"),
|
||||
NULL,
|
||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||
flags));
|
||||
|
||||
/**
|
||||
* MidoriWebSettings:auto-detect-proxy:
|
||||
|
@ -985,7 +1042,7 @@ midori_web_settings_class_init (MidoriWebSettingsClass* class)
|
|||
_("Detect proxy server automatically"),
|
||||
_("Whether to detect the proxy server automatically from the environment"),
|
||||
TRUE,
|
||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||
flags));
|
||||
|
||||
/**
|
||||
* MidoriWebSettings:identify-as:
|
||||
|
@ -1003,23 +1060,39 @@ midori_web_settings_class_init (MidoriWebSettingsClass* class)
|
|||
_("What to identify as to web pages"),
|
||||
MIDORI_TYPE_IDENTITY,
|
||||
MIDORI_IDENT_MIDORI,
|
||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||
flags));
|
||||
|
||||
/**
|
||||
* MidoriWebSettings:ident-string:
|
||||
*
|
||||
* The browser identification string.
|
||||
*
|
||||
* Since: 0.1.2
|
||||
*/
|
||||
* MidoriWebSettings:user-agent:
|
||||
*
|
||||
* The browser identification string.
|
||||
*
|
||||
* Since: 0.2.3
|
||||
*/
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_IDENT_STRING,
|
||||
PROP_USER_AGENT,
|
||||
g_param_spec_string (
|
||||
"ident-string",
|
||||
"user-agent",
|
||||
_("Identification string"),
|
||||
_("The application identification string"),
|
||||
NULL,
|
||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||
flags));
|
||||
|
||||
/**
|
||||
* MidoriWebSettings:preferred-languages:
|
||||
*
|
||||
* A comma separated list of languages preferred for rendering multilingual webpages.
|
||||
*
|
||||
* Since: 0.2.3
|
||||
*/
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_PREFERRED_LANGUAGES,
|
||||
g_param_spec_string (
|
||||
"preferred-languages",
|
||||
_("Preferred languages"),
|
||||
_("A comma separated list of languages preferred for rendering multilingual webpages, for example \"de\", \"ru,nl\" or \"en-us;q=1.0, fr-fr;q=0.667\""),
|
||||
NULL,
|
||||
flags));
|
||||
|
||||
/**
|
||||
* MidoriWebSettings:clear-private-data:
|
||||
|
@ -1115,7 +1188,7 @@ get_sys_name (void)
|
|||
{
|
||||
struct utsname name;
|
||||
if (uname (&name) != -1)
|
||||
sys_name = g_strdup_printf ("%s %s", name.sysname, name.machine);
|
||||
sys_name = g_strdup(name.sysname);
|
||||
else
|
||||
sys_name = "Unix";
|
||||
}
|
||||
|
@ -1141,15 +1214,10 @@ generate_ident_string (MidoriIdentity identify_as)
|
|||
|
||||
const gchar* os =
|
||||
#if HAVE_OSX
|
||||
/* #if defined (HAVE_X86) */
|
||||
"Intel Mac OS X";
|
||||
/* #else
|
||||
"PPC Mac OS X";
|
||||
#endif */
|
||||
"Mac OS X";
|
||||
#elif defined (G_OS_UNIX)
|
||||
get_sys_name ();
|
||||
#elif defined (G_OS_WIN32)
|
||||
// FIXME: Windows NT version
|
||||
"Windows";
|
||||
#else
|
||||
"Unknown";
|
||||
|
@ -1157,8 +1225,7 @@ generate_ident_string (MidoriIdentity identify_as)
|
|||
|
||||
const gchar* appname = "Midori/"
|
||||
G_STRINGIFY (MIDORI_MAJOR_VERSION) "."
|
||||
G_STRINGIFY (MIDORI_MINOR_VERSION) "."
|
||||
G_STRINGIFY (MIDORI_MICRO_VERSION);
|
||||
G_STRINGIFY (MIDORI_MINOR_VERSION);
|
||||
|
||||
const gchar* lang = pango_language_to_string (gtk_get_default_language ());
|
||||
|
||||
|
@ -1184,8 +1251,8 @@ generate_ident_string (MidoriIdentity identify_as)
|
|||
"Safari/419.3 %s",
|
||||
os, lang, appname);
|
||||
case MIDORI_IDENT_FIREFOX:
|
||||
return g_strdup_printf ("Mozilla/5.0 (%s; U; %s; %s; rv:1.8.1) "
|
||||
"Gecko/20061010 Firefox/2.0 %s",
|
||||
return g_strdup_printf ("Mozilla/5.0 (%s; U; %s; %s; rv:1.9.0.2) "
|
||||
"Gecko/2008092313 Firefox/3.8 %s",
|
||||
platform, os, lang, appname);
|
||||
case MIDORI_IDENT_EXPLORER:
|
||||
return g_strdup_printf ("Mozilla/4.0 (compatible; "
|
||||
|
@ -1369,6 +1436,32 @@ midori_web_settings_set_property (GObject* object,
|
|||
g_object_set (web_settings, "WebKitWebSettings::enable-plugins",
|
||||
g_value_get_boolean (value), NULL);
|
||||
break;
|
||||
case PROP_ENABLE_DEVELOPER_EXTRAS:
|
||||
g_object_set (web_settings, "WebKitWebSettings::enable-developer-extras",
|
||||
g_value_get_boolean (value), NULL);
|
||||
break;
|
||||
#if WEBKIT_CHECK_VERSION (1, 1, 8)
|
||||
case PROP_ENABLE_HTML5_DATABASE:
|
||||
g_object_set (web_settings, "WebKitWebSettings::enable-html5-database",
|
||||
g_value_get_boolean (value), NULL);
|
||||
break;
|
||||
case PROP_ENABLE_HTML5_LOCAL_STORAGE:
|
||||
g_object_set (web_settings, "WebKitWebSettings::enable-html5-local-storage",
|
||||
g_value_get_boolean (value), NULL);
|
||||
break;
|
||||
#endif
|
||||
#if WEBKIT_CHECK_VERSION (1, 1, 13)
|
||||
case PROP_ENABLE_OFFLINE_WEB_APPLICATION_CACHE:
|
||||
g_object_set (web_settings, "WebKitWebSettings::enable-offline-web-application-cache",
|
||||
g_value_get_boolean (value), NULL);
|
||||
break;
|
||||
#endif
|
||||
#if WEBKIT_CHECK_VERSION (1, 1, 18)
|
||||
case PROP_ENABLE_PAGE_CACHE:
|
||||
g_object_set (web_settings, "WebKitWebSettings::enable-page-cache",
|
||||
g_value_get_boolean (value), NULL);
|
||||
break;
|
||||
#endif
|
||||
case PROP_ZOOM_TEXT_AND_IMAGES:
|
||||
web_settings->zoom_text_and_images = g_value_get_boolean (value);
|
||||
break;
|
||||
|
@ -1412,18 +1505,21 @@ midori_web_settings_set_property (GObject* object,
|
|||
katze_assign (web_settings->ident_string, string);
|
||||
#if WEBKIT_CHECK_VERSION (1, 1, 11)
|
||||
g_object_set (web_settings, "user-agent", string, NULL);
|
||||
#else
|
||||
g_object_notify (object, "user-agent");
|
||||
#endif
|
||||
g_object_notify (object, "ident-string");
|
||||
}
|
||||
break;
|
||||
case PROP_IDENT_STRING:
|
||||
case PROP_USER_AGENT:
|
||||
if (web_settings->identify_as == MIDORI_IDENT_CUSTOM)
|
||||
{
|
||||
katze_assign (web_settings->ident_string, g_value_dup_string (value));
|
||||
#if WEBKIT_CHECK_VERSION (1, 1, 11)
|
||||
g_object_set (web_settings, "user-agent", web_settings->ident_string, NULL);
|
||||
#endif
|
||||
}
|
||||
#if WEBKIT_CHECK_VERSION (1, 1, 11)
|
||||
g_object_set (web_settings, "WebKitWebSettings::user-agent",
|
||||
web_settings->ident_string, NULL);
|
||||
#endif
|
||||
break;
|
||||
case PROP_PREFERRED_LANGUAGES:
|
||||
katze_assign (web_settings->http_accept_language, g_value_dup_string (value));
|
||||
break;
|
||||
case PROP_CLEAR_PRIVATE_DATA:
|
||||
web_settings->clear_private_data = g_value_get_int (value);
|
||||
|
@ -1584,6 +1680,32 @@ midori_web_settings_get_property (GObject* object,
|
|||
g_value_set_boolean (value, katze_object_get_boolean (web_settings,
|
||||
"WebKitWebSettings::enable-plugins"));
|
||||
break;
|
||||
case PROP_ENABLE_DEVELOPER_EXTRAS:
|
||||
g_value_set_boolean (value, katze_object_get_boolean (web_settings,
|
||||
"WebKitWebSettings::enable-developer-extras"));
|
||||
break;
|
||||
#if WEBKIT_CHECK_VERSION (1, 1, 8)
|
||||
case PROP_ENABLE_HTML5_DATABASE:
|
||||
g_value_set_boolean (value, katze_object_get_boolean (web_settings,
|
||||
"WebKitWebSettings::enable-html5-database"));
|
||||
break;
|
||||
case PROP_ENABLE_HTML5_LOCAL_STORAGE:
|
||||
g_value_set_boolean (value, katze_object_get_boolean (web_settings,
|
||||
"WebKitWebSettings::enable-html5-local-storage"));
|
||||
break;
|
||||
#endif
|
||||
#if WEBKIT_CHECK_VERSION (1, 1, 13)
|
||||
case PROP_ENABLE_OFFLINE_WEB_APPLICATION_CACHE:
|
||||
g_value_set_boolean (value, katze_object_get_boolean (web_settings,
|
||||
"WebKitWebSettings::enable-offline-web-application-cache"));
|
||||
break;
|
||||
#endif
|
||||
#if WEBKIT_CHECK_VERSION (1, 1, 18)
|
||||
case PROP_ENABLE_PAGE_CACHE:
|
||||
g_value_set_boolean (value, katze_object_get_boolean (web_settings,
|
||||
"WebKitWebSettings::enable-page-cache"));
|
||||
break;
|
||||
#endif
|
||||
case PROP_ZOOM_TEXT_AND_IMAGES:
|
||||
g_value_set_boolean (value, web_settings->zoom_text_and_images);
|
||||
break;
|
||||
|
@ -1622,7 +1744,7 @@ midori_web_settings_get_property (GObject* object,
|
|||
case PROP_IDENTIFY_AS:
|
||||
g_value_set_enum (value, web_settings->identify_as);
|
||||
break;
|
||||
case PROP_IDENT_STRING:
|
||||
case PROP_USER_AGENT:
|
||||
if (!g_strcmp0 (web_settings->ident_string, ""))
|
||||
{
|
||||
gchar* string = generate_ident_string (web_settings->identify_as);
|
||||
|
@ -1630,6 +1752,9 @@ midori_web_settings_get_property (GObject* object,
|
|||
}
|
||||
g_value_set_string (value, web_settings->ident_string);
|
||||
break;
|
||||
case PROP_PREFERRED_LANGUAGES:
|
||||
g_value_set_string (value, web_settings->http_accept_language);
|
||||
break;
|
||||
case PROP_CLEAR_PRIVATE_DATA:
|
||||
g_value_set_int (value, web_settings->clear_private_data);
|
||||
break;
|
||||
|
|
|
@ -149,7 +149,7 @@ midori_identity_get_type (void) G_GNUC_CONST;
|
|||
(midori_identity_get_type ())
|
||||
|
||||
GType
|
||||
midori_web_settings_get_type (void);
|
||||
midori_web_settings_get_type (void) G_GNUC_CONST;
|
||||
|
||||
MidoriWebSettings*
|
||||
midori_web_settings_new (void);
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
#include "midori-browser.h"
|
||||
#include "midori-extension.h"
|
||||
#include "midori-locationaction.h"
|
||||
#include "midori-locationentry.h"
|
||||
#include "midori-panel.h"
|
||||
#include "midori-preferences.h"
|
||||
#include "midori-searchaction.h"
|
||||
|
|
|
@ -142,6 +142,11 @@ GSourceFuncs sock_watch_funcs = {
|
|||
NULL
|
||||
};
|
||||
|
||||
gint fd_recv (gint fd,
|
||||
gchar *buf,
|
||||
gint len,
|
||||
gint flags);
|
||||
|
||||
#ifdef G_OS_WIN32
|
||||
static SockInfo *sock_find_from_fd (gint fd);
|
||||
#endif
|
||||
|
|
456
midori/sokoke.c
456
midori/sokoke.c
|
@ -1,6 +1,7 @@
|
|||
/*
|
||||
Copyright (C) 2007-2009 Christian Dywan <christian@twotoasts.de>
|
||||
Copyright (C) 2009 Dale Whittaker <dayul@users.sf.net>
|
||||
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
|
||||
|
@ -16,7 +17,6 @@
|
|||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include "compat.h"
|
||||
#include "midori-stock.h"
|
||||
|
||||
#if HAVE_UNISTD_H
|
||||
|
@ -51,6 +51,44 @@
|
|||
#include <hildon-uri.h>
|
||||
#endif
|
||||
|
||||
#if !GTK_CHECK_VERSION(2, 12, 0)
|
||||
|
||||
void
|
||||
gtk_widget_set_has_tooltip (GtkWidget* widget,
|
||||
gboolean has_tooltip)
|
||||
{
|
||||
/* Do nothing */
|
||||
}
|
||||
|
||||
void
|
||||
gtk_widget_set_tooltip_text (GtkWidget* widget,
|
||||
const gchar* text)
|
||||
{
|
||||
if (text && *text)
|
||||
{
|
||||
static GtkTooltips* tooltips = NULL;
|
||||
if (G_UNLIKELY (!tooltips))
|
||||
tooltips = gtk_tooltips_new ();
|
||||
gtk_tooltips_set_tip (tooltips, widget, text, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
gtk_tool_item_set_tooltip_text (GtkToolItem* toolitem,
|
||||
const gchar* text)
|
||||
{
|
||||
if (text && *text)
|
||||
{
|
||||
static GtkTooltips* tooltips = NULL;
|
||||
if (G_UNLIKELY (!tooltips))
|
||||
tooltips = gtk_tooltips_new ();
|
||||
|
||||
gtk_tool_item_set_tooltip (toolitem, tooltips, text, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static gchar*
|
||||
sokoke_js_string_utf8 (JSStringRef js_string)
|
||||
{
|
||||
|
@ -80,16 +118,23 @@ sokoke_js_script_eval (JSContextRef js_context,
|
|||
JSValueRef js_exception = NULL;
|
||||
JSValueRef js_value = JSEvaluateScript (js_context, js_script,
|
||||
JSContextGetGlobalObject (js_context), NULL, 0, &js_exception);
|
||||
if (!js_value && exception)
|
||||
JSStringRelease (js_script);
|
||||
|
||||
if (!js_value)
|
||||
{
|
||||
JSStringRef js_message = JSValueToStringCopy (js_context,
|
||||
js_exception, NULL);
|
||||
value = sokoke_js_string_utf8 (js_message);
|
||||
if (exception)
|
||||
*exception = sokoke_js_string_utf8 (js_message);
|
||||
*exception = value;
|
||||
else
|
||||
{
|
||||
g_warning ("%s", value);
|
||||
g_free (value);
|
||||
}
|
||||
JSStringRelease (js_message);
|
||||
js_value = JSValueMakeNull (js_context);
|
||||
return NULL;
|
||||
}
|
||||
JSStringRelease (js_script);
|
||||
|
||||
js_value_string = JSValueToStringCopy (js_context, js_value, NULL);
|
||||
value = sokoke_js_string_utf8 (js_value_string);
|
||||
|
@ -97,6 +142,14 @@ sokoke_js_script_eval (JSContextRef js_context,
|
|||
return value;
|
||||
}
|
||||
|
||||
static void
|
||||
sokoke_message_dialog_response_cb (GtkWidget* dialog,
|
||||
gint response,
|
||||
gpointer data)
|
||||
{
|
||||
gtk_widget_destroy (dialog);
|
||||
}
|
||||
|
||||
void
|
||||
sokoke_message_dialog (GtkMessageType message_type,
|
||||
const gchar* short_message,
|
||||
|
@ -112,8 +165,8 @@ sokoke_message_dialog (GtkMessageType message_type,
|
|||
"%s", short_message);
|
||||
gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
|
||||
"%s", detailed_message);
|
||||
g_signal_connect_swapped (dialog, "response",
|
||||
G_CALLBACK (gtk_widget_destroy), dialog);
|
||||
g_signal_connect (dialog, "response",
|
||||
G_CALLBACK (sokoke_message_dialog_response_cb), NULL);
|
||||
gtk_widget_show (dialog);
|
||||
}
|
||||
|
||||
|
@ -223,6 +276,73 @@ sokoke_show_uri (GdkScreen* screen,
|
|||
#if HAVE_HILDON
|
||||
HildonURIAction* action = hildon_uri_get_default_action_by_uri (uri, NULL);
|
||||
return hildon_uri_open (uri, action, error);
|
||||
|
||||
#elif defined (G_OS_WIN32)
|
||||
|
||||
const gchar* fallbacks [] = { "explorer" };
|
||||
gsize i;
|
||||
GAppInfo *app_info;
|
||||
GFile *file;
|
||||
gchar *free_uri;
|
||||
|
||||
g_return_val_if_fail (uri != NULL, FALSE);
|
||||
g_return_val_if_fail (!error || !*error, FALSE);
|
||||
g_return_val_if_fail (GDK_IS_SCREEN (screen) || !screen, FALSE);
|
||||
|
||||
file = g_file_new_for_uri (uri);
|
||||
app_info = g_file_query_default_handler (file, NULL, error);
|
||||
|
||||
if (app_info != NULL)
|
||||
{
|
||||
GdkAppLaunchContext *context;
|
||||
gboolean result;
|
||||
GList l;
|
||||
|
||||
context = gdk_app_launch_context_new ();
|
||||
gdk_app_launch_context_set_screen (context, screen);
|
||||
gdk_app_launch_context_set_timestamp (context, timestamp);
|
||||
|
||||
l.data = (char *)file;
|
||||
l.next = l.prev = NULL;
|
||||
result = g_app_info_launch (app_info, &l, (GAppLaunchContext*)context, error);
|
||||
|
||||
g_object_unref (context);
|
||||
g_object_unref (app_info);
|
||||
g_object_unref (file);
|
||||
|
||||
if (result)
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
g_object_unref (file);
|
||||
|
||||
free_uri = g_filename_from_uri (uri, NULL, NULL);
|
||||
if (free_uri)
|
||||
{
|
||||
gchar *quoted = g_shell_quote (free_uri);
|
||||
uri = quoted;
|
||||
g_free (free_uri);
|
||||
free_uri = quoted;
|
||||
}
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (fallbacks); i++)
|
||||
{
|
||||
gchar* command = g_strconcat (fallbacks[i], " ", uri, NULL);
|
||||
gboolean result = g_spawn_command_line_async (command, error);
|
||||
g_free (command);
|
||||
if (result)
|
||||
{
|
||||
g_free (free_uri);
|
||||
return TRUE;
|
||||
}
|
||||
if (error)
|
||||
*error = NULL;
|
||||
}
|
||||
|
||||
g_free (free_uri);
|
||||
|
||||
return FALSE;
|
||||
|
||||
#else
|
||||
|
||||
const gchar* fallbacks [] = { "xdg-open", "exo-open", "gnome-open" };
|
||||
|
@ -232,8 +352,13 @@ sokoke_show_uri (GdkScreen* screen,
|
|||
g_return_val_if_fail (uri != NULL, FALSE);
|
||||
g_return_val_if_fail (!error || !*error, FALSE);
|
||||
|
||||
#if GTK_CHECK_VERSION (2, 14, 0)
|
||||
if (gtk_show_uri (screen, uri, timestamp, error))
|
||||
return TRUE;
|
||||
#else
|
||||
if (g_app_info_launch_default_for_uri (uri, NULL, NULL))
|
||||
return TRUE;
|
||||
#endif
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (fallbacks); i++)
|
||||
{
|
||||
|
@ -320,9 +445,13 @@ sokoke_spawn_program (const gchar* command,
|
|||
else
|
||||
{
|
||||
/* FIXME: Implement Hildon specific version */
|
||||
gchar* uri_format;
|
||||
gchar* command_ready;
|
||||
gchar** argv;
|
||||
|
||||
if ((uri_format = strstr (command, "%u")))
|
||||
uri_format[1] = 's';
|
||||
|
||||
if (strstr (command, "%s"))
|
||||
command_ready = g_strdup_printf (command, argument);
|
||||
else
|
||||
|
@ -362,9 +491,9 @@ sokoke_spawn_program (const gchar* command,
|
|||
* @uri: an URI string
|
||||
* @path: location of a string pointer
|
||||
*
|
||||
* Returns the hostname of the specified URI,
|
||||
* and stores the path in @path.
|
||||
* @path is at least set to ""
|
||||
* Returns the hostname of the specified URI.
|
||||
*
|
||||
* If there is a path, it is stored in @path.
|
||||
*
|
||||
* Return value: a newly allocated hostname
|
||||
**/
|
||||
|
@ -374,24 +503,17 @@ sokoke_hostname_from_uri (const gchar* uri,
|
|||
{
|
||||
gchar* hostname;
|
||||
|
||||
*path = "";
|
||||
if ((hostname = g_utf8_strchr (uri, -1, '/')))
|
||||
if ((hostname = strchr (uri, '/')))
|
||||
{
|
||||
if (hostname[1] == '/')
|
||||
hostname += 2;
|
||||
if ((*path = g_utf8_strchr (hostname, -1, '/')))
|
||||
{
|
||||
gulong offset = g_utf8_pointer_to_offset (hostname, *path);
|
||||
gchar* buffer = g_malloc0 (offset + 1);
|
||||
g_utf8_strncpy (buffer, hostname, offset);
|
||||
hostname = buffer;
|
||||
}
|
||||
if ((*path = strchr (hostname, '/')))
|
||||
return g_strndup (hostname, *path - hostname);
|
||||
else
|
||||
hostname = g_strdup (hostname);
|
||||
return g_strdup (hostname);
|
||||
}
|
||||
else
|
||||
hostname = g_strdup (uri);
|
||||
return hostname;
|
||||
|
||||
return g_strdup (uri);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -441,9 +563,12 @@ sokoke_hostname_to_ascii (const gchar* hostname)
|
|||
gchar*
|
||||
sokoke_uri_to_ascii (const gchar* uri)
|
||||
{
|
||||
gchar* proto;
|
||||
gchar* proto = NULL;
|
||||
gchar* path = NULL;
|
||||
gchar* hostname;
|
||||
gchar* encoded;
|
||||
|
||||
if ((proto = g_utf8_strchr (uri, -1, ':')))
|
||||
if (strchr (uri, '/') && (proto = strchr (uri, ':')))
|
||||
{
|
||||
gulong offset;
|
||||
gchar* buffer;
|
||||
|
@ -454,9 +579,8 @@ sokoke_uri_to_ascii (const gchar* uri)
|
|||
proto = buffer;
|
||||
}
|
||||
|
||||
gchar* path;
|
||||
gchar* hostname = sokoke_hostname_from_uri (uri, &path);
|
||||
gchar* encoded = sokoke_hostname_to_ascii (hostname);
|
||||
hostname = sokoke_hostname_from_uri (uri, &path);
|
||||
encoded = sokoke_hostname_to_ascii (hostname);
|
||||
|
||||
if (encoded)
|
||||
{
|
||||
|
@ -499,9 +623,11 @@ gchar* sokoke_search_uri (const gchar* uri,
|
|||
gchar* escaped;
|
||||
gchar* search;
|
||||
|
||||
g_return_val_if_fail (uri != NULL, NULL);
|
||||
g_return_val_if_fail (keywords != NULL, NULL);
|
||||
|
||||
if (!uri)
|
||||
return g_strdup (keywords);
|
||||
|
||||
escaped = g_uri_escape_string (keywords, " :/", TRUE);
|
||||
if (strstr (uri, "%s"))
|
||||
search = g_strdup_printf (uri, escaped);
|
||||
|
@ -514,32 +640,29 @@ gchar* sokoke_search_uri (const gchar* uri,
|
|||
/**
|
||||
* sokoke_magic_uri:
|
||||
* @uri: a string typed by a user
|
||||
* @search_engines: search engines
|
||||
*
|
||||
* Takes a string that was typed by a user,
|
||||
* guesses what it is, and returns an URI.
|
||||
*
|
||||
* Return value: a newly allocated URI
|
||||
* If it was a search, %NULL will be returned.
|
||||
*
|
||||
* Return value: a newly allocated URI, or %NULL
|
||||
**/
|
||||
gchar*
|
||||
sokoke_magic_uri (const gchar* uri,
|
||||
KatzeArray* search_engines)
|
||||
sokoke_magic_uri (const gchar* uri)
|
||||
{
|
||||
gchar** parts;
|
||||
gchar* search;
|
||||
const gchar* search_uri;
|
||||
KatzeItem* item;
|
||||
|
||||
g_return_val_if_fail (uri, NULL);
|
||||
g_return_val_if_fail (!search_engines ||
|
||||
katze_array_is_a (search_engines, KATZE_TYPE_ITEM), NULL);
|
||||
|
||||
/* 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:"))
|
||||
if (!strncmp (uri, "javascript:", 11)
|
||||
|| !strncmp (uri, "mailto:", 7)
|
||||
|| !strncmp (uri, "tel:", 4)
|
||||
|| !strncmp (uri, "callto:", 7)
|
||||
|| !strncmp (uri, "data:", 5)
|
||||
|| !strncmp (uri, "about:", 6))
|
||||
return g_strdup (uri);
|
||||
/* Add file:// if we have a local path */
|
||||
if (g_path_is_absolute (uri))
|
||||
|
@ -556,38 +679,26 @@ sokoke_magic_uri (const gchar* uri,
|
|||
((search = strchr (uri, ':')) || (search = strchr (uri, '@'))) &&
|
||||
search[0] && !g_ascii_isalpha (search[1]))
|
||||
return sokoke_idn_to_punycode (g_strconcat ("http://", uri, NULL));
|
||||
if (!strcmp (uri, "localhost") || g_str_has_prefix (uri, "localhost/"))
|
||||
if (!strncmp (uri, "localhost", 9) && (uri[9] == '\0' || uri[9] == '/'))
|
||||
return g_strconcat ("http://", uri, NULL);
|
||||
parts = g_strsplit (uri, ".", 0);
|
||||
if (!search && parts[0] && parts[1])
|
||||
if (!search)
|
||||
{
|
||||
if (!(parts[1][1] == '\0' && !g_ascii_isalpha (parts[1][0])))
|
||||
if (!strchr (parts[0], ' ') && !strchr (parts[1], ' '))
|
||||
{
|
||||
search = g_strconcat ("http://", uri, NULL);
|
||||
g_strfreev (parts);
|
||||
return sokoke_idn_to_punycode (search);
|
||||
}
|
||||
}
|
||||
g_strfreev (parts);
|
||||
/* We don't want to search? So return early. */
|
||||
if (!search_engines)
|
||||
return g_strdup (uri);
|
||||
search = NULL;
|
||||
search_uri = NULL;
|
||||
/* Do we have a keyword and a string? */
|
||||
parts = g_strsplit (uri, " ", 2);
|
||||
if (parts[0])
|
||||
if ((item = katze_array_find_token (search_engines, parts[0])))
|
||||
parts = g_strsplit (uri, ".", 0);
|
||||
if (parts[0] && parts[1])
|
||||
{
|
||||
search_uri = katze_item_get_uri (item);
|
||||
search = sokoke_search_uri (search_uri, parts[1] ? parts[1] : "");
|
||||
if (!(parts[1][1] == '\0' && !g_ascii_isalpha (parts[1][0])))
|
||||
if (!strchr (parts[0], ' ') && !strchr (parts[1], ' '))
|
||||
{
|
||||
search = g_strconcat ("http://", uri, NULL);
|
||||
g_strfreev (parts);
|
||||
return sokoke_idn_to_punycode (search);
|
||||
}
|
||||
}
|
||||
g_strfreev (parts);
|
||||
return search;
|
||||
g_strfreev (parts);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* sokoke_format_uri_for_display:
|
||||
* @uri: an URI string
|
||||
|
@ -604,7 +715,7 @@ sokoke_format_uri_for_display (const gchar* uri)
|
|||
{
|
||||
gchar* unescaped = g_uri_unescape_string (uri, " +");
|
||||
#ifdef HAVE_LIBSOUP_2_27_90
|
||||
gchar* path;
|
||||
gchar* path = NULL;
|
||||
gchar* hostname;
|
||||
gchar* decoded;
|
||||
|
||||
|
@ -1079,6 +1190,37 @@ sokoke_time_t_to_julian (const time_t* timestamp)
|
|||
return julian;
|
||||
}
|
||||
|
||||
/**
|
||||
* sokoke_days_between:
|
||||
* @day1: a time_t timestamp value
|
||||
* @day2: a time_t timestamp value
|
||||
*
|
||||
* Calculates the number of days between two timestamps.
|
||||
*
|
||||
* Return value: an integer.
|
||||
**/
|
||||
gint
|
||||
sokoke_days_between (const time_t* day1,
|
||||
const time_t* day2)
|
||||
{
|
||||
GDate* date1;
|
||||
GDate* date2;
|
||||
gint age;
|
||||
|
||||
date1 = g_date_new ();
|
||||
date2 = g_date_new ();
|
||||
|
||||
g_date_set_time_t (date1, *day1);
|
||||
g_date_set_time_t (date2, *day2);
|
||||
|
||||
age = g_date_days_between (date1, date2);
|
||||
|
||||
g_date_free (date1);
|
||||
g_date_free (date2);
|
||||
|
||||
return age;
|
||||
}
|
||||
|
||||
/**
|
||||
* sokoke_register_stock_items:
|
||||
*
|
||||
|
@ -1287,7 +1429,7 @@ sokoke_find_config_filename (const gchar* folder,
|
|||
while ((config_dir = config_dirs[i++]))
|
||||
{
|
||||
gchar* path = g_build_filename (config_dir, PACKAGE_NAME, folder, filename, NULL);
|
||||
if (g_file_test (path, G_FILE_TEST_EXISTS))
|
||||
if (g_access (path, F_OK) == 0)
|
||||
return path;
|
||||
g_free (path);
|
||||
}
|
||||
|
@ -1313,13 +1455,32 @@ sokoke_find_data_filename (const gchar* filename)
|
|||
while ((data_dir = data_dirs[i++]))
|
||||
{
|
||||
gchar* path = g_build_filename (data_dir, filename, NULL);
|
||||
if (g_file_test (path, G_FILE_TEST_EXISTS))
|
||||
if (g_access (path, F_OK) == 0)
|
||||
return path;
|
||||
g_free (path);
|
||||
}
|
||||
return g_build_filename (MDATADIR, filename, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* sokoke_get_argv:
|
||||
* @argument_vector: %NULL
|
||||
*
|
||||
* Retrieves the argument vector passed at program startup.
|
||||
*
|
||||
* Return value: the argument vector
|
||||
**/
|
||||
gchar**
|
||||
sokoke_get_argv (gchar** argument_vector)
|
||||
{
|
||||
static gchar** stored_argv = NULL;
|
||||
|
||||
if (!stored_argv)
|
||||
stored_argv = g_strdupv (argument_vector);
|
||||
|
||||
return stored_argv;
|
||||
}
|
||||
|
||||
#if !WEBKIT_CHECK_VERSION (1, 1, 14)
|
||||
static void
|
||||
res_server_handler_cb (SoupServer* res_server,
|
||||
|
@ -1463,6 +1624,10 @@ sokoke_window_activate_key (GtkWindow* window,
|
|||
if (gtk_window_activate_key (window, event))
|
||||
return TRUE;
|
||||
|
||||
/* Hack to allow Ctrl + Shift + Tab */
|
||||
if (event->keyval == 65056)
|
||||
event->keyval = GDK_Tab;
|
||||
|
||||
/* 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 ()));
|
||||
|
@ -1511,3 +1676,152 @@ sokoke_file_chooser_dialog_new (const gchar* title,
|
|||
#endif
|
||||
return dialog;
|
||||
}
|
||||
|
||||
/**
|
||||
* sokoke_prefetch_uri:
|
||||
* @uri: an URI string
|
||||
*
|
||||
* Attempts to prefetch the specified URI, that is
|
||||
* it tries to resolve the hostname in advance.
|
||||
*
|
||||
* Return value: %TRUE on success
|
||||
**/
|
||||
gboolean
|
||||
sokoke_prefetch_uri (const char* uri)
|
||||
{
|
||||
#define MAXHOSTS 50
|
||||
static gchar* hosts = NULL;
|
||||
static gint host_count = G_MAXINT;
|
||||
|
||||
SoupURI* s_uri;
|
||||
|
||||
if (!uri)
|
||||
return FALSE;
|
||||
s_uri = soup_uri_new (uri);
|
||||
if (!s_uri || !s_uri->host)
|
||||
return FALSE;
|
||||
|
||||
#if GLIB_CHECK_VERSION (2, 22, 0)
|
||||
if (g_hostname_is_ip_address (s_uri->host))
|
||||
#else
|
||||
if (g_ascii_isdigit (s_uri->host[0]) && g_strstr_len (s_uri->host, 4, "."))
|
||||
#endif
|
||||
{
|
||||
soup_uri_free (s_uri);
|
||||
return FALSE;
|
||||
}
|
||||
if (!g_str_has_prefix (uri, "http"))
|
||||
{
|
||||
soup_uri_free (s_uri);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!hosts ||
|
||||
!g_regex_match_simple (s_uri->host, hosts,
|
||||
G_REGEX_CASELESS, G_REGEX_MATCH_NOTEMPTY))
|
||||
{
|
||||
SoupAddress* address;
|
||||
gchar* new_hosts;
|
||||
|
||||
address = soup_address_new (s_uri->host, SOUP_ADDRESS_ANY_PORT);
|
||||
soup_address_resolve_async (address, 0, 0, 0, 0);
|
||||
g_object_unref (address);
|
||||
|
||||
if (host_count > MAXHOSTS)
|
||||
{
|
||||
katze_assign (hosts, g_strdup (""));
|
||||
host_count = 0;
|
||||
}
|
||||
host_count++;
|
||||
new_hosts = g_strdup_printf ("%s|%s", hosts, s_uri->host);
|
||||
katze_assign (hosts, new_hosts);
|
||||
}
|
||||
soup_uri_free (s_uri);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Provide a new way for SoupSession to assume an 'Accept-Language'
|
||||
string automatically from the return value of g_get_language_names(),
|
||||
properly formatted according to RFC2616.
|
||||
Copyright (C) 2009 Mario Sanchez Prada <msanchez@igalia.com>
|
||||
Copyright (C) 2009 Dan Winship <danw@gnome.org>
|
||||
Mostly copied from libSoup 2.29, coding style adjusted */
|
||||
|
||||
/* Converts a language in POSIX format and to be RFC2616 compliant */
|
||||
/* Based on code from epiphany-webkit (ephy_langs_append_languages()) */
|
||||
static gchar *
|
||||
sokoke_posix_lang_to_rfc2616 (const gchar *language)
|
||||
{
|
||||
if (!strchr (language, '.') && !strchr (language, '@') && language[0] != 'C')
|
||||
/* change to lowercase and '_' to '-' */
|
||||
return g_strdelimit (g_ascii_strdown (language, -1), "_", '-');
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Adds a quality value to a string (any value between 0 and 1). */
|
||||
static gchar *
|
||||
sokoke_add_quality_value (const gchar *str,
|
||||
float qvalue)
|
||||
{
|
||||
if ((qvalue >= 0.0) && (qvalue <= 1.0))
|
||||
{
|
||||
int qv_int = (qvalue * 1000 + 0.5);
|
||||
return g_strdup_printf ("%s;q=%d.%d",
|
||||
str, (int) (qv_int / 1000), qv_int % 1000);
|
||||
}
|
||||
|
||||
return g_strdup (str);
|
||||
}
|
||||
|
||||
/* Returns a RFC2616 compliant languages list from system locales */
|
||||
gchar *
|
||||
sokoke_accept_languages (const gchar* const * lang_names)
|
||||
{
|
||||
GArray *langs_garray = NULL;
|
||||
char *cur_lang = NULL;
|
||||
char *prev_lang = NULL;
|
||||
char **langs_array;
|
||||
char *langs_str;
|
||||
float delta;
|
||||
int i, n_lang_names;
|
||||
|
||||
/* Calculate delta for setting the quality values */
|
||||
n_lang_names = g_strv_length ((gchar **)lang_names);
|
||||
delta = 0.999 / (n_lang_names - 1);
|
||||
|
||||
/* Build the array of languages */
|
||||
langs_garray = g_array_new (TRUE, FALSE, sizeof (char*));
|
||||
for (i = 0; lang_names[i] != NULL; i++)
|
||||
{
|
||||
cur_lang = sokoke_posix_lang_to_rfc2616 (lang_names[i]);
|
||||
|
||||
/* Apart from getting a valid RFC2616 compliant
|
||||
language, also get rid of extra variants */
|
||||
if (cur_lang && (!prev_lang ||
|
||||
(!strcmp (prev_lang, cur_lang) || !strstr (prev_lang, cur_lang))))
|
||||
{
|
||||
|
||||
gchar *qv_lang = NULL;
|
||||
|
||||
/* Save reference for further comparison */
|
||||
prev_lang = cur_lang;
|
||||
|
||||
/* Add the quality value and append it */
|
||||
qv_lang = sokoke_add_quality_value (cur_lang, 1 - i * delta);
|
||||
g_array_append_val (langs_garray, qv_lang);
|
||||
}
|
||||
}
|
||||
|
||||
/* Fallback: add "en" if list is empty */
|
||||
if (langs_garray->len == 0)
|
||||
{
|
||||
gchar* fallback = g_strdup ("en");
|
||||
g_array_append_val (langs_garray, fallback);
|
||||
}
|
||||
|
||||
langs_array = (char **) g_array_free (langs_garray, FALSE);
|
||||
langs_str = g_strjoinv (", ", langs_array);
|
||||
|
||||
return langs_str;
|
||||
}
|
||||
|
|
|
@ -13,19 +13,54 @@
|
|||
#ifndef __SOKOKE_H__
|
||||
#define __SOKOKE_H__ 1
|
||||
|
||||
/* Common behavior modifiers */
|
||||
#define MIDORI_MOD_NEW_WINDOW(state) (state & GDK_SHIFT_MASK)
|
||||
#define MIDORI_MOD_NEW_TAB(state) (state & GDK_CONTROL_MASK)
|
||||
#define MIDORI_MOD_BACKGROUND(state) (state & GDK_SHIFT_MASK)
|
||||
#define MIDORI_MOD_SCROLL(state) (state & GDK_CONTROL_MASK)
|
||||
|
||||
#include <katze/katze.h>
|
||||
|
||||
#include <webkit/webkit.h>
|
||||
#include <JavaScriptCore/JavaScript.h>
|
||||
|
||||
#if !GLIB_CHECK_VERSION (2, 14, 0)
|
||||
#define G_PARAM_STATIC_STRINGS \
|
||||
(G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB)
|
||||
#define gtk_dialog_get_content_area(dlg) dlg->vbox
|
||||
#endif
|
||||
|
||||
#if !GTK_CHECK_VERSION (2, 16, 0)
|
||||
#define GTK_ACTIVATABLE GTK_WIDGET
|
||||
#define gtk_activatable_get_related_action gtk_widget_get_action
|
||||
#endif
|
||||
|
||||
#if !GTK_CHECK_VERSION (2, 18, 0)
|
||||
#define gtk_widget_is_toplevel(widget) GTK_WIDGET_TOPLEVEL (widget)
|
||||
#define gtk_widget_has_focus(widget) GTK_WIDGET_HAS_FOCUS (widget)
|
||||
#endif
|
||||
|
||||
#if !GTK_CHECK_VERSION(2, 12, 0)
|
||||
|
||||
void
|
||||
gtk_widget_set_has_tooltip (GtkWidget* widget,
|
||||
gboolean has_tooltip);
|
||||
|
||||
void
|
||||
gtk_widget_set_tooltip_text (GtkWidget* widget,
|
||||
const gchar* text);
|
||||
|
||||
void
|
||||
gtk_tool_item_set_tooltip_text (GtkToolItem* toolitem,
|
||||
const gchar* text);
|
||||
|
||||
#endif
|
||||
|
||||
gchar*
|
||||
sokoke_js_script_eval (JSContextRef js_context,
|
||||
const gchar* script,
|
||||
gchar** exception);
|
||||
|
||||
/* 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,
|
||||
|
@ -60,8 +95,7 @@ gchar*
|
|||
sokoke_uri_to_ascii (const gchar* uri);
|
||||
|
||||
gchar*
|
||||
sokoke_magic_uri (const gchar* uri,
|
||||
KatzeArray* search_engines);
|
||||
sokoke_magic_uri (const gchar* uri);
|
||||
|
||||
gchar*
|
||||
sokoke_format_uri_for_display (const gchar* uri);
|
||||
|
@ -144,6 +178,10 @@ sokoke_action_create_popup_menu_item (GtkAction* action);
|
|||
gint64
|
||||
sokoke_time_t_to_julian (const time_t* timestamp);
|
||||
|
||||
gint
|
||||
sokoke_days_between (const time_t* day1,
|
||||
const time_t* day2);
|
||||
|
||||
void
|
||||
sokoke_register_stock_items (void);
|
||||
|
||||
|
@ -161,6 +199,9 @@ sokoke_find_config_filename (const gchar* folder,
|
|||
gchar*
|
||||
sokoke_find_data_filename (const gchar* filename);
|
||||
|
||||
gchar**
|
||||
sokoke_get_argv (gchar** argument_vector);
|
||||
|
||||
#if !WEBKIT_CHECK_VERSION (1, 1, 14)
|
||||
SoupServer*
|
||||
sokoke_get_res_server (void);
|
||||
|
@ -179,4 +220,10 @@ sokoke_file_chooser_dialog_new (const gchar* title,
|
|||
GtkWindow* window,
|
||||
GtkFileChooserAction action);
|
||||
|
||||
gboolean
|
||||
sokoke_prefetch_uri (const char* uri);
|
||||
|
||||
gchar *
|
||||
sokoke_accept_languages (const gchar* const * lang_names);
|
||||
|
||||
#endif /* !__SOKOKE_H__ */
|
||||
|
|
|
@ -4,32 +4,35 @@
|
|||
|
||||
import platform
|
||||
|
||||
obj = bld.new_task_gen ('cc', 'staticlib')
|
||||
obj.name = 'midori-core'
|
||||
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 LIBNOTIFY WEBKIT LIBXML ' \
|
||||
'WS2_32 OPENSSL ' \
|
||||
'HILDON HILDON_FM'
|
||||
obj.uselib_local = 'katze'
|
||||
obj.install_path = None
|
||||
progressive = True
|
||||
libs = 'M UNIQUE LIBSOUP GMODULE GTHREAD LIBIDN GIO GTK SQLITE ' \
|
||||
'LIBNOTIFY WEBKIT LIBXML X11 WS2_32 OPENSSL HILDON HILDON_FM'
|
||||
|
||||
obj = bld.new_task_gen ('cc', 'staticlib')
|
||||
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 X11'
|
||||
obj.uselib_local = 'midori-core'
|
||||
obj.install_path = None
|
||||
if progressive or Options.commands['check']:
|
||||
obj = bld.new_task_gen ('cc', 'staticlib')
|
||||
obj.target = 'midori-core'
|
||||
obj.includes = '.. ../katze .'
|
||||
obj.find_sources_in_dirs ('../katze . ../panels', excludes=['main.c'])
|
||||
obj.uselib = libs
|
||||
obj.add_marshal_file ('marshal.list', 'midori_cclosure_marshal')
|
||||
obj.install_path = None
|
||||
bld.add_group ()
|
||||
|
||||
obj = bld.new_task_gen ('cc', 'program')
|
||||
obj.target = 'midori'
|
||||
obj.includes = '. .. ../panels'
|
||||
obj.source = 'main.c'
|
||||
if bld.env['WINRC']:
|
||||
obj.source += ' ../data/midori.rc'
|
||||
obj.uselib = 'UNIQUE LIBSOUP GMODULE GTHREAD GIO GTK SQLITE WEBKIT LIBXML'
|
||||
obj.uselib_local = 'panels'
|
||||
if progressive:
|
||||
obj = bld.new_task_gen ('cc', 'program')
|
||||
obj.target = 'midori'
|
||||
obj.includes = '.. ../katze . ../panels'
|
||||
obj.source = './main.c'
|
||||
obj.uselib = libs
|
||||
obj.uselib_local = 'midori-core'
|
||||
if bld.env['WINRC']:
|
||||
obj.source += ' ../data/midori.rc'
|
||||
else:
|
||||
obj = bld.new_task_gen ('cc', 'program')
|
||||
obj.target = 'midori'
|
||||
obj.includes = '.. ../katze . ../panels'
|
||||
obj.find_sources_in_dirs ('../katze . ../panels')
|
||||
obj.add_marshal_file ('marshal.list', 'midori_cclosure_marshal')
|
||||
obj.uselib = libs
|
||||
if bld.env['WINRC']:
|
||||
obj.source += ' ../data/midori.rc'
|
||||
|
|
|
@ -22,9 +22,14 @@
|
|||
#include <webkit/webkit.h>
|
||||
#include <JavaScriptCore/JavaScript.h>
|
||||
#include <glib/gi18n.h>
|
||||
#include <glib/gstdio.h>
|
||||
#include <string.h>
|
||||
#include <gio/gio.h>
|
||||
|
||||
#if HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
struct _MidoriAddons
|
||||
{
|
||||
GtkVBox parent_instance;
|
||||
|
@ -212,14 +217,20 @@ _addons_get_directories (MidoriAddons* addons)
|
|||
{
|
||||
path = g_build_path (G_DIR_SEPARATOR_S, g_get_user_data_dir (),
|
||||
PACKAGE_NAME, folders[i], NULL);
|
||||
directories = g_slist_prepend (directories, path);
|
||||
if (g_access (path, X_OK) == 0)
|
||||
directories = g_slist_prepend (directories, path);
|
||||
else
|
||||
g_free (path);
|
||||
|
||||
datadirs = g_get_system_data_dirs ();
|
||||
while (*datadirs)
|
||||
{
|
||||
path = g_build_path (G_DIR_SEPARATOR_S, *datadirs,
|
||||
PACKAGE_NAME, folders[i], NULL);
|
||||
directories = g_slist_prepend (directories, path);
|
||||
if (g_access (path, X_OK) == 0)
|
||||
directories = g_slist_prepend (directories, path);
|
||||
else
|
||||
g_free (path);
|
||||
datadirs++;
|
||||
}
|
||||
}
|
||||
|
@ -796,8 +807,12 @@ midori_web_widget_context_ready_cb (GtkWidget* web_widget,
|
|||
gchar* message;
|
||||
|
||||
uri = katze_object_get_string (web_widget, "uri");
|
||||
if (!uri)
|
||||
/* Don't run scripts or styles on blank or special pages */
|
||||
if (!(uri && *uri && strncmp (uri, "about:", 6)))
|
||||
{
|
||||
g_free (uri);
|
||||
return;
|
||||
}
|
||||
|
||||
elements = addons->elements;
|
||||
while (elements)
|
||||
|
|
|
@ -46,7 +46,6 @@ struct _MidoriBookmarks
|
|||
GtkWidget* treeview;
|
||||
MidoriApp* app;
|
||||
KatzeArray* array;
|
||||
KatzeNet* net;
|
||||
};
|
||||
|
||||
struct _MidoriBookmarksClass
|
||||
|
@ -906,8 +905,6 @@ midori_bookmarks_init (MidoriBookmarks* bookmarks)
|
|||
GtkCellRenderer* renderer_pixbuf;
|
||||
GtkCellRenderer* renderer_text;
|
||||
|
||||
bookmarks->net = katze_net_new ();
|
||||
|
||||
/* Create the treeview */
|
||||
model = midori_bookmark_store_new (1, KATZE_TYPE_ITEM);
|
||||
treeview = gtk_tree_view_new_with_model (GTK_TREE_MODEL (model));
|
||||
|
@ -952,7 +949,6 @@ midori_bookmarks_finalize (GObject* object)
|
|||
midori_bookmarks_disconnect_folder (bookmarks, bookmarks->array);
|
||||
if (bookmarks->app)
|
||||
g_object_unref (bookmarks->app);
|
||||
g_object_unref (bookmarks->net);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -219,6 +219,7 @@ midori_console_treeview_render_text_cb (GtkTreeViewColumn* column,
|
|||
|
||||
gtk_tree_model_get (model, iter, 0, &message, 1, &line, 2, &source_id, -1);
|
||||
|
||||
g_strchomp (message);
|
||||
text = g_strdup_printf ("%d @ %s\n%s", line, source_id, message);
|
||||
g_object_set (renderer, "text", text, NULL);
|
||||
g_free (text);
|
||||
|
|
|
@ -103,14 +103,10 @@ midori_extensions_get_toolbar (MidoriViewable* extensions)
|
|||
if (!MIDORI_EXTENSIONS (extensions)->toolbar)
|
||||
{
|
||||
GtkWidget* toolbar;
|
||||
GtkToolItem* toolitem;
|
||||
|
||||
toolbar = gtk_toolbar_new ();
|
||||
gtk_toolbar_set_style (GTK_TOOLBAR (toolbar), GTK_TOOLBAR_BOTH_HORIZ);
|
||||
gtk_toolbar_set_icon_size (GTK_TOOLBAR (toolbar), GTK_ICON_SIZE_BUTTON);
|
||||
toolitem = gtk_tool_item_new ();
|
||||
gtk_toolbar_insert (GTK_TOOLBAR (toolbar), toolitem, -1);
|
||||
gtk_widget_show (GTK_WIDGET (toolitem));
|
||||
|
||||
MIDORI_EXTENSIONS (extensions)->toolbar = toolbar;
|
||||
}
|
||||
|
@ -227,7 +223,7 @@ midori_extensions_treeview_render_tick_cb (GtkTreeViewColumn* column,
|
|||
|
||||
g_object_set (renderer,
|
||||
"activatable", midori_extension_is_prepared (extension),
|
||||
"active", midori_extension_is_active (extension),
|
||||
"active", midori_extension_is_active (extension) || g_object_get_data (G_OBJECT (extension), "static"),
|
||||
NULL);
|
||||
|
||||
g_object_unref (extension);
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include "midori-viewable.h"
|
||||
|
||||
#include "sokoke.h"
|
||||
#include "gtkiconentry.h"
|
||||
|
||||
#include <glib/gi18n.h>
|
||||
#include <string.h>
|
||||
|
@ -31,6 +32,14 @@ midori_browser_edit_bookmark_dialog_new (MidoriBrowser* browser,
|
|||
gboolean new_bookmark,
|
||||
gboolean is_folder);
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#if HAVE_SQLITE
|
||||
#include <sqlite3.h>
|
||||
#endif
|
||||
|
||||
#define COMPLETION_DELAY 150
|
||||
|
||||
struct _MidoriHistory
|
||||
{
|
||||
GtkVBox parent_instance;
|
||||
|
@ -42,7 +51,9 @@ struct _MidoriHistory
|
|||
GtkWidget* treeview;
|
||||
MidoriApp* app;
|
||||
KatzeArray* array;
|
||||
KatzeNet* net;
|
||||
|
||||
gint filter_timeout;
|
||||
gchar* filter;
|
||||
};
|
||||
|
||||
struct _MidoriHistoryClass
|
||||
|
@ -114,6 +125,217 @@ midori_history_get_stock_id (MidoriViewable* viewable)
|
|||
return STOCK_HISTORY;
|
||||
}
|
||||
|
||||
#if HAVE_SQLITE
|
||||
static void
|
||||
midori_history_clear_db (MidoriHistory* history)
|
||||
{
|
||||
gchar* sqlcmd;
|
||||
sqlite3* db;
|
||||
char* errmsg = NULL;
|
||||
|
||||
db = g_object_get_data (G_OBJECT (history->array), "db");
|
||||
sqlcmd = sqlite3_mprintf ("DELETE FROM history");
|
||||
|
||||
if (sqlite3_exec (db, sqlcmd, NULL, NULL, &errmsg) != SQLITE_OK)
|
||||
{
|
||||
g_printerr (_("Failed to remove history item: %s\n"), errmsg);
|
||||
sqlite3_free (errmsg);
|
||||
}
|
||||
|
||||
sqlite3_free (sqlcmd);
|
||||
}
|
||||
|
||||
static void
|
||||
midori_history_remove_item_from_db (MidoriHistory* history,
|
||||
KatzeItem* item)
|
||||
{
|
||||
gchar* sqlcmd;
|
||||
sqlite3* db;
|
||||
char* errmsg = NULL;
|
||||
|
||||
db = g_object_get_data (G_OBJECT (history->array), "db");
|
||||
|
||||
if (katze_item_get_uri (item))
|
||||
sqlcmd = sqlite3_mprintf (
|
||||
"DELETE FROM history WHERE uri = '%q' AND"
|
||||
" title = '%q' AND date = %llu",
|
||||
katze_item_get_uri (item),
|
||||
katze_item_get_name (item),
|
||||
katze_item_get_added (item));
|
||||
else
|
||||
sqlcmd = sqlite3_mprintf (
|
||||
"DELETE FROM history WHERE day = %d", katze_item_get_added (item));
|
||||
|
||||
if (sqlite3_exec (db, sqlcmd, NULL, NULL, &errmsg) != SQLITE_OK)
|
||||
{
|
||||
g_printerr (_("Failed to remove history item: %s\n"), errmsg);
|
||||
sqlite3_free (errmsg);
|
||||
}
|
||||
|
||||
sqlite3_free (sqlcmd);
|
||||
}
|
||||
|
||||
/**
|
||||
* midori_history_read_from_db:
|
||||
* @history: a #MidoriHistory
|
||||
* @model: a #GtkTreeStore
|
||||
* @parent: a #GtkTreeIter, or %NULL
|
||||
* @req_day: the timestamp of one day, or 0
|
||||
* @filter: a filter string to search for
|
||||
*
|
||||
* Populates the model according to parameters:
|
||||
* 1. If @req_day is 0, all dates are added as folders.
|
||||
* 2. If @req_day is given, all pages for that day are added.
|
||||
* 3. If @filter is given, all pages matching the filter are added.
|
||||
**/
|
||||
static gboolean
|
||||
midori_history_read_from_db (MidoriHistory* history,
|
||||
GtkTreeStore* model,
|
||||
GtkTreeIter* parent,
|
||||
int req_day,
|
||||
const gchar* filter)
|
||||
{
|
||||
sqlite3* db;
|
||||
sqlite3_stmt* statement;
|
||||
gint result;
|
||||
const gchar* sqlcmd;
|
||||
time_t current_time;
|
||||
|
||||
GtkTreeIter iter;
|
||||
GtkTreeIter root_iter;
|
||||
|
||||
db = g_object_get_data (G_OBJECT (history->array), "db");
|
||||
|
||||
if (filter && *filter)
|
||||
{
|
||||
gchar* filterstr;
|
||||
|
||||
sqlcmd = "SELECT uri, title, day FROM history_view "
|
||||
"WHERE uri LIKE ? or title LIKE ? GROUP BY uri "
|
||||
"UNION ALL "
|
||||
"SELECT replace(uri, '%s', title) AS uri, title, day "
|
||||
"FROM search_view WHERE title LIKE ?1 GROUP BY uri "
|
||||
"ORDER BY day ASC";
|
||||
result = sqlite3_prepare_v2 (db, sqlcmd, -1, &statement, NULL);
|
||||
filterstr = g_strdup_printf ("%%%s%%", filter);
|
||||
sqlite3_bind_text (statement, 1, filterstr, -1, g_free);
|
||||
sqlite3_bind_text (statement, 2, g_strdup (filterstr), -1, g_free);
|
||||
req_day = -1;
|
||||
}
|
||||
else if (req_day == 0)
|
||||
{
|
||||
sqlcmd = "SELECT day, date FROM history GROUP BY day ORDER BY day ASC";
|
||||
result = sqlite3_prepare_v2 (db, sqlcmd, -1, &statement, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
sqlcmd = "SELECT uri, title, date, day "
|
||||
"FROM history WHERE day = ? "
|
||||
"GROUP BY uri ORDER BY date ASC";
|
||||
result = sqlite3_prepare_v2 (db, sqlcmd, -1, &statement, NULL);
|
||||
sqlite3_bind_int64 (statement, 1, req_day);
|
||||
}
|
||||
|
||||
if (result != SQLITE_OK)
|
||||
return FALSE;
|
||||
|
||||
if (req_day == 0)
|
||||
current_time = time (NULL);
|
||||
|
||||
while ((result = sqlite3_step (statement)) == SQLITE_ROW)
|
||||
{
|
||||
KatzeItem* item;
|
||||
const unsigned char* uri;
|
||||
const unsigned char* title;
|
||||
sqlite3_int64 date;
|
||||
sqlite3_int64 day;
|
||||
|
||||
if (req_day == 0)
|
||||
{
|
||||
gint age;
|
||||
gchar token[50];
|
||||
gchar* sdate;
|
||||
|
||||
day = sqlite3_column_int64 (statement, 0);
|
||||
date = sqlite3_column_int64 (statement, 1);
|
||||
|
||||
item = katze_item_new ();
|
||||
katze_item_set_added (item, day);
|
||||
age = sokoke_days_between ((time_t*)&date, ¤t_time);
|
||||
|
||||
/* 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 || age < 0)
|
||||
{
|
||||
strftime (token, sizeof (token), "%x", localtime ((time_t*)&date));
|
||||
sdate = token;
|
||||
}
|
||||
else if (age > 6)
|
||||
sdate = _("A week ago");
|
||||
else if (age > 1)
|
||||
sdate = g_strdup_printf (ngettext ("%d day ago",
|
||||
"%d days ago", (gint)age), (gint)age);
|
||||
else if (age == 0)
|
||||
sdate = _("Today");
|
||||
else
|
||||
sdate = _("Yesterday");
|
||||
|
||||
gtk_tree_store_insert_with_values (model, &root_iter, NULL,
|
||||
0, 0, item, 1, sdate, -1);
|
||||
/* That's an invisible dummy, so we always have an expander */
|
||||
gtk_tree_store_insert_with_values (model, &iter, &root_iter,
|
||||
0, 0, NULL, 1, NULL, -1);
|
||||
|
||||
if (age > 1 && age < 7)
|
||||
g_free (sdate);
|
||||
}
|
||||
else
|
||||
{
|
||||
uri = sqlite3_column_text (statement, 0);
|
||||
title = sqlite3_column_text (statement, 1);
|
||||
date = sqlite3_column_int64 (statement, 2);
|
||||
day = sqlite3_column_int64 (statement, 3);
|
||||
if (!uri)
|
||||
continue;
|
||||
|
||||
item = katze_item_new ();
|
||||
katze_item_set_added (item, date);
|
||||
katze_item_set_uri (item, (gchar*)uri);
|
||||
katze_item_set_name (item, (gchar*)title);
|
||||
gtk_tree_store_insert_with_values (model, NULL, parent,
|
||||
0, 0, item, 1, katze_item_get_name (item), -1);
|
||||
}
|
||||
}
|
||||
|
||||
if (req_day != 0 && !(filter && *filter))
|
||||
{
|
||||
/* Remove invisible dummy row */
|
||||
GtkTreeIter child;
|
||||
gint last = gtk_tree_model_iter_n_children (GTK_TREE_MODEL (model), parent);
|
||||
gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (model), &child, parent, last - 1);
|
||||
gtk_tree_store_remove (model, &child);
|
||||
}
|
||||
|
||||
if (result != SQLITE_DONE)
|
||||
g_print (_("Failed to execute database statement: %s\n"),
|
||||
sqlite3_errmsg (db));
|
||||
|
||||
sqlite3_finalize (statement);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
midori_history_add_clicked_cb (GtkWidget* toolitem)
|
||||
{
|
||||
|
@ -133,16 +355,10 @@ midori_history_delete_clicked_cb (GtkWidget* toolitem,
|
|||
&model, &iter))
|
||||
{
|
||||
KatzeItem* item;
|
||||
KatzeArray* parent;
|
||||
|
||||
gtk_tree_model_get (model, &iter, 0, &item, -1);
|
||||
|
||||
/* FIXME: Even toplevel items should technically have a parent */
|
||||
g_return_if_fail (katze_item_get_parent (item));
|
||||
|
||||
parent = katze_item_get_parent (item);
|
||||
katze_array_remove_item (parent, item);
|
||||
|
||||
midori_history_remove_item_from_db (history, item);
|
||||
gtk_tree_store_remove (GTK_TREE_STORE (model), &iter);
|
||||
g_object_unref (item);
|
||||
}
|
||||
}
|
||||
|
@ -165,7 +381,7 @@ midori_history_clear_clicked_cb (GtkWidget* toolitem,
|
|||
if (result != GTK_RESPONSE_YES)
|
||||
return;
|
||||
|
||||
katze_array_clear (history->array);
|
||||
midori_history_clear_db (history);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -185,11 +401,12 @@ midori_history_cursor_or_row_changed_cb (GtkTreeView* treeview,
|
|||
|
||||
gtk_tree_model_get (model, &iter, 0, &item, -1);
|
||||
|
||||
is_page = !KATZE_IS_ARRAY (item) && katze_item_get_uri (item);
|
||||
is_page = item && katze_item_get_uri (item);
|
||||
gtk_widget_set_sensitive (history->bookmark, is_page);
|
||||
gtk_widget_set_sensitive (history->delete, TRUE);
|
||||
|
||||
g_object_unref (item);
|
||||
if (item)
|
||||
g_object_unref (item);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -197,6 +414,7 @@ midori_history_cursor_or_row_changed_cb (GtkTreeView* treeview,
|
|||
gtk_widget_set_sensitive (history->delete, FALSE);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static GtkWidget*
|
||||
midori_history_get_toolbar (MidoriViewable* viewable)
|
||||
|
@ -206,12 +424,15 @@ midori_history_get_toolbar (MidoriViewable* viewable)
|
|||
if (!history->toolbar)
|
||||
{
|
||||
GtkWidget* toolbar;
|
||||
#if HAVE_SQLITE
|
||||
GtkToolItem* toolitem;
|
||||
#endif
|
||||
|
||||
toolbar = gtk_toolbar_new ();
|
||||
gtk_toolbar_set_style (GTK_TOOLBAR (toolbar), GTK_TOOLBAR_BOTH_HORIZ);
|
||||
gtk_toolbar_set_icon_size (GTK_TOOLBAR (toolbar), GTK_ICON_SIZE_BUTTON);
|
||||
history->toolbar = toolbar;
|
||||
#if HAVE_SQLITE
|
||||
toolitem = gtk_tool_button_new_from_stock (STOCK_BOOKMARK_ADD);
|
||||
gtk_widget_set_tooltip_text (GTK_WIDGET (toolitem),
|
||||
_("Bookmark the selected history item"));
|
||||
|
@ -245,6 +466,7 @@ midori_history_get_toolbar (MidoriViewable* viewable)
|
|||
G_CALLBACK (gtk_widget_destroyed), &history->delete);
|
||||
g_signal_connect (history->clear, "destroy",
|
||||
G_CALLBACK (gtk_widget_destroyed), &history->clear);
|
||||
#endif
|
||||
}
|
||||
|
||||
return history->toolbar;
|
||||
|
@ -258,222 +480,6 @@ midori_history_viewable_iface_init (MidoriViewableIface* iface)
|
|||
iface->get_toolbar = midori_history_get_toolbar;
|
||||
}
|
||||
|
||||
static void
|
||||
midori_history_add_item_cb (KatzeArray* array,
|
||||
KatzeItem* added_item,
|
||||
MidoriHistory* history);
|
||||
|
||||
static void
|
||||
midori_history_remove_item_cb (KatzeArray* array,
|
||||
KatzeItem* removed_item,
|
||||
MidoriHistory* history);
|
||||
|
||||
static void
|
||||
midori_history_clear_cb (KatzeArray* array,
|
||||
MidoriHistory* history);
|
||||
|
||||
static void
|
||||
midori_history_disconnect_folder (MidoriHistory* history,
|
||||
KatzeArray* array,
|
||||
gboolean unref)
|
||||
{
|
||||
KatzeItem* item;
|
||||
guint i;
|
||||
|
||||
g_return_if_fail (KATZE_IS_ARRAY (array));
|
||||
|
||||
g_signal_handlers_disconnect_by_func (array,
|
||||
midori_history_add_item_cb, history);
|
||||
g_signal_handlers_disconnect_by_func (array,
|
||||
midori_history_remove_item_cb, history);
|
||||
g_signal_handlers_disconnect_by_func (array,
|
||||
midori_history_clear_cb, history);
|
||||
|
||||
i = 0;
|
||||
while ((item = katze_array_get_nth_item (array, i++)))
|
||||
{
|
||||
if (KATZE_IS_ARRAY (item))
|
||||
midori_history_disconnect_folder (history, KATZE_ARRAY (item), unref);
|
||||
if (unref)
|
||||
g_object_unref (item);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
midori_history_add_item_cb (KatzeArray* array,
|
||||
KatzeItem* added_item,
|
||||
MidoriHistory* history)
|
||||
{
|
||||
GtkTreeModel* model;
|
||||
GtkTreeIter iter;
|
||||
guint i;
|
||||
|
||||
g_return_if_fail (KATZE_IS_ARRAY (array));
|
||||
g_return_if_fail (KATZE_IS_ITEM (added_item));
|
||||
g_return_if_fail (MIDORI_IS_HISTORY (history));
|
||||
|
||||
if (KATZE_IS_ARRAY (added_item))
|
||||
{
|
||||
g_signal_connect (added_item, "add-item",
|
||||
G_CALLBACK (midori_history_add_item_cb), history);
|
||||
g_signal_connect (added_item, "remove-item",
|
||||
G_CALLBACK (midori_history_remove_item_cb), history);
|
||||
g_signal_connect (added_item, "clear",
|
||||
G_CALLBACK (midori_history_clear_cb), history);
|
||||
}
|
||||
|
||||
g_object_ref (added_item);
|
||||
model = gtk_tree_view_get_model (GTK_TREE_VIEW (history->treeview));
|
||||
|
||||
if (array == history->array)
|
||||
{
|
||||
gtk_tree_store_insert_with_values (GTK_TREE_STORE (model),
|
||||
&iter, NULL, 0, 0, added_item, -1);
|
||||
return;
|
||||
}
|
||||
|
||||
i = 0;
|
||||
/* FIXME: Recurse over children of folders, too */
|
||||
while (gtk_tree_model_iter_nth_child (model, &iter, NULL, i))
|
||||
{
|
||||
KatzeItem* item;
|
||||
|
||||
gtk_tree_model_get (model, &iter, 0, &item, -1);
|
||||
if (item == (KatzeItem*)array)
|
||||
{
|
||||
GtkTreeIter child_iter;
|
||||
|
||||
gtk_tree_store_insert_with_values (GTK_TREE_STORE (model),
|
||||
&child_iter, &iter, 0, 0, added_item, -1);
|
||||
break;
|
||||
}
|
||||
g_object_unref (item);
|
||||
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
midori_history_remove_iter (GtkTreeModel* model,
|
||||
GtkTreeIter* parent,
|
||||
KatzeItem* removed_item)
|
||||
{
|
||||
guint i;
|
||||
GtkTreeIter iter;
|
||||
|
||||
i = 0;
|
||||
while (gtk_tree_model_iter_nth_child (model, &iter, parent, i))
|
||||
{
|
||||
KatzeItem* item;
|
||||
|
||||
gtk_tree_model_get (model, &iter, 0, &item, -1);
|
||||
|
||||
if (item == removed_item)
|
||||
{
|
||||
gtk_tree_store_remove (GTK_TREE_STORE (model), &iter);
|
||||
g_object_unref (item);
|
||||
break;
|
||||
}
|
||||
|
||||
if (KATZE_IS_ARRAY (item))
|
||||
midori_history_remove_iter (model, &iter, removed_item);
|
||||
|
||||
g_object_unref (item);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
midori_history_remove_item_cb (KatzeArray* array,
|
||||
KatzeItem* removed_item,
|
||||
MidoriHistory* history)
|
||||
{
|
||||
GtkTreeModel* model;
|
||||
|
||||
g_assert (KATZE_IS_ARRAY (array));
|
||||
g_assert (KATZE_IS_ITEM (removed_item));
|
||||
|
||||
if (KATZE_IS_ARRAY (removed_item))
|
||||
midori_history_disconnect_folder (history, KATZE_ARRAY (removed_item), TRUE);
|
||||
|
||||
model = gtk_tree_view_get_model (GTK_TREE_VIEW (history->treeview));
|
||||
midori_history_remove_iter (model, NULL, removed_item);
|
||||
g_object_unref (removed_item);
|
||||
}
|
||||
|
||||
static void
|
||||
midori_history_clear_cb (KatzeArray* array,
|
||||
MidoriHistory* history)
|
||||
{
|
||||
GtkTreeView* treeview;
|
||||
GtkTreeStore* store;
|
||||
|
||||
g_assert (KATZE_IS_ARRAY (array));
|
||||
|
||||
if (array == history->array)
|
||||
{
|
||||
treeview = GTK_TREE_VIEW (history->treeview);
|
||||
store = GTK_TREE_STORE (gtk_tree_view_get_model (treeview));
|
||||
gtk_tree_store_clear (store);
|
||||
}
|
||||
else
|
||||
{
|
||||
KatzeItem* item;
|
||||
guint i;
|
||||
|
||||
i = 0;
|
||||
while ((item = katze_array_get_nth_item (array, i++)))
|
||||
midori_history_remove_item_cb (array, item, history);
|
||||
}
|
||||
|
||||
midori_history_disconnect_folder (history, array, TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
midori_history_insert_item (MidoriHistory* history,
|
||||
GtkTreeStore* treestore,
|
||||
GtkTreeIter* parent,
|
||||
KatzeItem* item,
|
||||
gint64 day)
|
||||
{
|
||||
GtkTreeIter iter;
|
||||
gint64 age = -1;
|
||||
|
||||
g_return_if_fail (KATZE_IS_ITEM (item));
|
||||
|
||||
if (KATZE_IS_ARRAY (item))
|
||||
{
|
||||
GtkTreeIter* piter;
|
||||
gint64 pday;
|
||||
guint i;
|
||||
KatzeItem* child;
|
||||
|
||||
g_signal_connect (item, "add-item",
|
||||
G_CALLBACK (midori_history_add_item_cb), history);
|
||||
g_signal_connect (item, "remove-item",
|
||||
G_CALLBACK (midori_history_remove_item_cb), history);
|
||||
g_signal_connect (item, "clear",
|
||||
G_CALLBACK (midori_history_clear_cb), history);
|
||||
|
||||
piter = parent;
|
||||
if ((pday = katze_item_get_added (item)))
|
||||
{
|
||||
age = day - pday;
|
||||
gtk_tree_store_insert_with_values (treestore, &iter, parent,
|
||||
0, 0, item, 1, age, -1);
|
||||
piter = &iter;
|
||||
}
|
||||
i = 0;
|
||||
while ((child = katze_array_get_nth_item (KATZE_ARRAY (item), i++)))
|
||||
midori_history_insert_item (history, treestore, piter, child, day);
|
||||
}
|
||||
else
|
||||
{
|
||||
gtk_tree_store_insert_with_values (treestore, &iter, parent,
|
||||
0, 0, item, 1, age, -1);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
midori_history_set_app (MidoriHistory* history,
|
||||
MidoriApp* app)
|
||||
|
@ -482,26 +488,22 @@ midori_history_set_app (MidoriHistory* history,
|
|||
|
||||
if (history->array)
|
||||
{
|
||||
midori_history_disconnect_folder (history, history->array, TRUE);
|
||||
g_object_unref (history->array);
|
||||
model = gtk_tree_view_get_model (GTK_TREE_VIEW (history->treeview));
|
||||
gtk_tree_store_clear (GTK_TREE_STORE (model));
|
||||
}
|
||||
|
||||
katze_assign (history->app, app);
|
||||
if (!app)
|
||||
return;
|
||||
|
||||
g_object_ref (app);
|
||||
history->array = katze_object_get_object (app, "history");
|
||||
if (history->array)
|
||||
{
|
||||
time_t now = time (NULL);
|
||||
gint64 day = sokoke_time_t_to_julian (&now);
|
||||
|
||||
model = gtk_tree_view_get_model (GTK_TREE_VIEW (history->treeview));
|
||||
midori_history_insert_item (history, GTK_TREE_STORE (model),
|
||||
NULL, KATZE_ITEM (history->array), day);
|
||||
}
|
||||
history->array = katze_object_get_object (app, "history");
|
||||
model = gtk_tree_view_get_model (GTK_TREE_VIEW (history->treeview));
|
||||
#if HAVE_SQLITE
|
||||
if (history->array)
|
||||
midori_history_read_from_db (history, GTK_TREE_STORE (model), NULL, 0, NULL);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -550,89 +552,28 @@ midori_history_treeview_render_icon_cb (GtkTreeViewColumn* column,
|
|||
GtkWidget* treeview)
|
||||
{
|
||||
KatzeItem* item;
|
||||
GdkPixbuf* pixbuf = NULL;
|
||||
GdkPixbuf* pixbuf;
|
||||
|
||||
gtk_tree_model_get (model, iter, 0, &item, -1);
|
||||
|
||||
g_assert (KATZE_IS_ITEM (item));
|
||||
|
||||
if (KATZE_IS_ARRAY (item))
|
||||
if (!item)
|
||||
pixbuf = NULL;
|
||||
else if (katze_item_get_uri (item))
|
||||
pixbuf = katze_load_cached_icon (katze_item_get_uri (item), treeview);
|
||||
else
|
||||
pixbuf = gtk_widget_render_icon (treeview, GTK_STOCK_DIRECTORY,
|
||||
GTK_ICON_SIZE_MENU, NULL);
|
||||
else
|
||||
pixbuf = katze_load_cached_icon (katze_item_get_uri (item), treeview);
|
||||
|
||||
g_object_set (renderer, "pixbuf", pixbuf, NULL);
|
||||
|
||||
if (pixbuf)
|
||||
g_object_unref (pixbuf);
|
||||
|
||||
g_object_unref (item);
|
||||
}
|
||||
|
||||
static void
|
||||
midori_history_treeview_render_text_cb (GtkTreeViewColumn* column,
|
||||
GtkCellRenderer* renderer,
|
||||
GtkTreeModel* model,
|
||||
GtkTreeIter* iter,
|
||||
MidoriHistory* history)
|
||||
{
|
||||
KatzeItem* item;
|
||||
gint64 age;
|
||||
|
||||
gtk_tree_model_get (model, iter, 0, &item, 1, &age, -1);
|
||||
|
||||
g_assert (KATZE_IS_ITEM (item));
|
||||
|
||||
if (KATZE_IS_ARRAY (item))
|
||||
{
|
||||
gchar* sdate;
|
||||
|
||||
/* 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 || age < 0)
|
||||
{
|
||||
g_object_set (renderer, "text", katze_item_get_name (item), NULL);
|
||||
}
|
||||
else if (age > 6)
|
||||
{
|
||||
sdate = _("A week ago");
|
||||
g_object_set (renderer, "text", sdate, NULL);
|
||||
}
|
||||
else if (age > 1)
|
||||
{
|
||||
sdate = g_strdup_printf (ngettext ("%d day ago",
|
||||
"%d days ago", (gint)age), (gint)age);
|
||||
g_object_set (renderer, "text", sdate, NULL);
|
||||
g_free (sdate);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (age == 0)
|
||||
sdate = _("Today");
|
||||
else
|
||||
sdate = _("Yesterday");
|
||||
g_object_set (renderer, "text", sdate, NULL);
|
||||
}
|
||||
g_object_unref (pixbuf);
|
||||
g_object_unref (item);
|
||||
}
|
||||
else
|
||||
g_object_set (renderer, "text", katze_item_get_name (item), NULL);
|
||||
|
||||
g_object_unref (item);
|
||||
}
|
||||
|
||||
#if HAVE_SQLITE
|
||||
static void
|
||||
midori_history_row_activated_cb (GtkTreeView* treeview,
|
||||
GtkTreePath* path,
|
||||
|
@ -649,6 +590,10 @@ midori_history_row_activated_cb (GtkTreeView* treeview,
|
|||
if (gtk_tree_model_get_iter (model, &iter, path))
|
||||
{
|
||||
gtk_tree_model_get (model, &iter, 0, &item, -1);
|
||||
|
||||
if (!item)
|
||||
return;
|
||||
|
||||
uri = katze_item_get_uri (item);
|
||||
if (uri && *uri)
|
||||
{
|
||||
|
@ -791,22 +736,6 @@ midori_history_bookmark_activate_cb (GtkWidget* menuitem,
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
midori_history_delete_activate_cb (GtkWidget* menuitem,
|
||||
MidoriHistory* history)
|
||||
{
|
||||
KatzeItem* item;
|
||||
KatzeArray* parent;
|
||||
|
||||
item = (KatzeItem*)g_object_get_data (G_OBJECT (menuitem), "KatzeItem");
|
||||
|
||||
/* FIXME: Even toplevel items should technically have a parent */
|
||||
g_return_if_fail (katze_item_get_parent (item));
|
||||
|
||||
parent = katze_item_get_parent (item);
|
||||
katze_array_remove_item (parent, item);
|
||||
}
|
||||
|
||||
static void
|
||||
midori_history_popup (GtkWidget* widget,
|
||||
GdkEventButton* event,
|
||||
|
@ -836,7 +765,7 @@ midori_history_popup (GtkWidget* widget,
|
|||
gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
|
||||
gtk_widget_show (menuitem);
|
||||
midori_history_popup_item (menu, GTK_STOCK_DELETE, NULL,
|
||||
item, midori_history_delete_activate_cb, history);
|
||||
item, midori_history_delete_clicked_cb, history);
|
||||
|
||||
katze_widget_popup (widget, GTK_MENU (menu), event, KATZE_MENU_POSITION_CURSOR);
|
||||
}
|
||||
|
@ -858,6 +787,9 @@ midori_history_button_release_event_cb (GtkWidget* widget,
|
|||
|
||||
gtk_tree_model_get (model, &iter, 0, &item, -1);
|
||||
|
||||
if (!item)
|
||||
return FALSE;
|
||||
|
||||
if (event->button == 2)
|
||||
{
|
||||
const gchar* uri = katze_item_get_uri (item);
|
||||
|
@ -895,13 +827,10 @@ midori_history_key_release_event_cb (GtkWidget* widget,
|
|||
if (katze_tree_view_get_selected_iter (GTK_TREE_VIEW (widget), &model, &iter))
|
||||
{
|
||||
KatzeItem* item;
|
||||
KatzeArray* parent;
|
||||
|
||||
gtk_tree_model_get (model, &iter, 0, &item, -1);
|
||||
|
||||
parent = katze_item_get_parent (item);
|
||||
katze_array_remove_item (parent, item);
|
||||
|
||||
midori_history_remove_item_from_db (history, item);
|
||||
gtk_tree_store_remove (GTK_TREE_STORE (model), &iter);
|
||||
g_object_unref (item);
|
||||
}
|
||||
|
||||
|
@ -924,20 +853,110 @@ midori_history_popup_menu_cb (GtkWidget* widget,
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
midori_history_row_expanded_cb (GtkTreeView* treeview,
|
||||
GtkTreeIter* iter,
|
||||
GtkTreePath* path,
|
||||
MidoriHistory* history)
|
||||
{
|
||||
GtkTreeModel* model;
|
||||
KatzeItem* item;
|
||||
|
||||
model = gtk_tree_view_get_model (GTK_TREE_VIEW (treeview));
|
||||
gtk_tree_model_get (model, iter, 0, &item, -1);
|
||||
midori_history_read_from_db (history, GTK_TREE_STORE (model),
|
||||
iter, katze_item_get_added (item), NULL);
|
||||
g_object_unref (item);
|
||||
}
|
||||
|
||||
static void
|
||||
midori_history_row_collapsed_cb (GtkTreeView *treeview,
|
||||
GtkTreeIter *parent,
|
||||
GtkTreePath *path,
|
||||
gpointer user_data)
|
||||
{
|
||||
GtkTreeModel* model;
|
||||
GtkTreeStore* treestore;
|
||||
GtkTreeIter child;
|
||||
|
||||
model = gtk_tree_view_get_model (GTK_TREE_VIEW (treeview));
|
||||
treestore = GTK_TREE_STORE (model);
|
||||
while (gtk_tree_model_iter_nth_child (model, &child, parent, 0))
|
||||
gtk_tree_store_remove (treestore, &child);
|
||||
/* That's an invisible dummy, so we always have an expander */
|
||||
gtk_tree_store_insert_with_values (treestore, &child, parent,
|
||||
0, 0, NULL, 1, NULL, -1);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
midori_history_filter_timeout_cb (gpointer data)
|
||||
{
|
||||
MidoriHistory* history = data;
|
||||
GtkTreeModel* model;
|
||||
GtkTreeStore* treestore;
|
||||
|
||||
model = gtk_tree_view_get_model (GTK_TREE_VIEW (history->treeview));
|
||||
treestore = GTK_TREE_STORE (model);
|
||||
|
||||
gtk_tree_store_clear (treestore);
|
||||
midori_history_read_from_db (history, treestore, NULL, 0, history->filter);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
midori_history_filter_entry_changed_cb (GtkEntry* entry,
|
||||
MidoriHistory* history)
|
||||
{
|
||||
if (history->filter_timeout)
|
||||
g_source_remove (history->filter_timeout);
|
||||
history->filter_timeout = g_timeout_add (COMPLETION_DELAY,
|
||||
midori_history_filter_timeout_cb, history);
|
||||
katze_assign (history->filter, g_strdup (gtk_entry_get_text (entry)));
|
||||
}
|
||||
#endif
|
||||
static void
|
||||
midori_history_filter_entry_clear_cb (GtkEntry* entry,
|
||||
gint icon_pos,
|
||||
gint button,
|
||||
MidoriHistory* history)
|
||||
{
|
||||
if (icon_pos == GTK_ICON_ENTRY_SECONDARY)
|
||||
gtk_entry_set_text (entry, "");
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
midori_history_init (MidoriHistory* history)
|
||||
{
|
||||
GtkWidget* entry;
|
||||
GtkWidget* box;
|
||||
GtkTreeStore* model;
|
||||
GtkWidget* treeview;
|
||||
GtkTreeViewColumn* column;
|
||||
GtkCellRenderer* renderer_pixbuf;
|
||||
GtkCellRenderer* renderer_text;
|
||||
|
||||
history->net = katze_net_new ();
|
||||
/* FIXME: Dereference the net on finalization */
|
||||
/* Create the filter entry */
|
||||
entry = gtk_icon_entry_new ();
|
||||
gtk_icon_entry_set_icon_from_stock (GTK_ICON_ENTRY (entry),
|
||||
GTK_ICON_ENTRY_SECONDARY, GTK_STOCK_CLEAR);
|
||||
gtk_icon_entry_set_icon_highlight (GTK_ICON_ENTRY (entry),
|
||||
GTK_ICON_ENTRY_SECONDARY, TRUE);
|
||||
g_signal_connect (entry, "icon-release",
|
||||
G_CALLBACK (midori_history_filter_entry_clear_cb), history);
|
||||
#if HAVE_SQLITE
|
||||
g_signal_connect (entry, "changed",
|
||||
G_CALLBACK (midori_history_filter_entry_changed_cb), history);
|
||||
#endif
|
||||
box = gtk_hbox_new (FALSE, 0);
|
||||
gtk_box_pack_start (GTK_BOX (box), gtk_label_new (_("Filter:")), FALSE, FALSE, 3);
|
||||
gtk_box_pack_start (GTK_BOX (box), entry, TRUE, TRUE, 3);
|
||||
gtk_widget_show_all (box);
|
||||
gtk_box_pack_start (GTK_BOX (history), box, FALSE, FALSE, 5);
|
||||
|
||||
/* Create the treeview */
|
||||
model = gtk_tree_store_new (2, KATZE_TYPE_ITEM, G_TYPE_INT64);
|
||||
model = gtk_tree_store_new (2, KATZE_TYPE_ITEM, G_TYPE_STRING);
|
||||
treeview = gtk_tree_view_new_with_model (GTK_TREE_MODEL (model));
|
||||
gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (treeview), FALSE);
|
||||
column = gtk_tree_view_column_new ();
|
||||
|
@ -948,11 +967,11 @@ midori_history_init (MidoriHistory* history)
|
|||
treeview, NULL);
|
||||
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)midori_history_treeview_render_text_cb,
|
||||
history, NULL);
|
||||
gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (column), renderer_text,
|
||||
"text", 1, NULL);
|
||||
gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column);
|
||||
g_object_unref (model);
|
||||
#if HAVE_SQLITE
|
||||
g_object_connect (treeview,
|
||||
"signal::row-activated",
|
||||
midori_history_row_activated_cb, history,
|
||||
|
@ -964,12 +983,20 @@ midori_history_init (MidoriHistory* history)
|
|||
midori_history_button_release_event_cb, history,
|
||||
"signal::key-release-event",
|
||||
midori_history_key_release_event_cb, history,
|
||||
"signal::row-expanded",
|
||||
midori_history_row_expanded_cb, history,
|
||||
"signal::row-collapsed",
|
||||
midori_history_row_collapsed_cb, history,
|
||||
"signal::popup-menu",
|
||||
midori_history_popup_menu_cb, history,
|
||||
NULL);
|
||||
#endif
|
||||
gtk_widget_show (treeview);
|
||||
gtk_box_pack_start (GTK_BOX (history), treeview, TRUE, TRUE, 0);
|
||||
history->treeview = treeview;
|
||||
/* FIXME: We need to connect a signal here, to add new pages into history */
|
||||
|
||||
history->filter = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -982,8 +1009,8 @@ midori_history_finalize (GObject* object)
|
|||
|
||||
/* FIXME: We don't unref items (last argument is FALSE) because
|
||||
our reference counting is incorrect. */
|
||||
midori_history_disconnect_folder (history, history->array, FALSE);
|
||||
g_object_unref (history->array);
|
||||
katze_assign (history->filter, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,291 +0,0 @@
|
|||
/*
|
||||
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-plugins.h"
|
||||
|
||||
#include "midori-app.h"
|
||||
#include "midori-stock.h"
|
||||
#include "midori-viewable.h"
|
||||
|
||||
#include "sokoke.h"
|
||||
#include <string.h>
|
||||
#include <glib/gi18n.h>
|
||||
|
||||
struct _MidoriPlugins
|
||||
{
|
||||
GtkVBox parent_instance;
|
||||
|
||||
GtkWidget* toolbar;
|
||||
GtkWidget* treeview;
|
||||
MidoriApp* app;
|
||||
};
|
||||
|
||||
struct _MidoriPluginsClass
|
||||
{
|
||||
GtkVBoxClass parent_class;
|
||||
};
|
||||
|
||||
static void
|
||||
midori_plugins_viewable_iface_init (MidoriViewableIface* iface);
|
||||
|
||||
G_DEFINE_TYPE_WITH_CODE (MidoriPlugins, midori_plugins, GTK_TYPE_VBOX,
|
||||
G_IMPLEMENT_INTERFACE (MIDORI_TYPE_VIEWABLE,
|
||||
midori_plugins_viewable_iface_init));
|
||||
|
||||
enum
|
||||
{
|
||||
PROP_0,
|
||||
|
||||
PROP_APP
|
||||
};
|
||||
|
||||
static void
|
||||
midori_plugins_set_property (GObject* object,
|
||||
guint prop_id,
|
||||
const GValue* value,
|
||||
GParamSpec* pspec);
|
||||
|
||||
static void
|
||||
midori_plugins_get_property (GObject* object,
|
||||
guint prop_id,
|
||||
GValue* value,
|
||||
GParamSpec* pspec);
|
||||
|
||||
static void
|
||||
midori_plugins_class_init (MidoriPluginsClass* class)
|
||||
{
|
||||
GObjectClass* gobject_class;
|
||||
GParamFlags flags;
|
||||
|
||||
gobject_class = G_OBJECT_CLASS (class);
|
||||
gobject_class->set_property = midori_plugins_set_property;
|
||||
gobject_class->get_property = midori_plugins_get_property;
|
||||
|
||||
flags = G_PARAM_READWRITE | G_PARAM_CONSTRUCT;
|
||||
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_APP,
|
||||
g_param_spec_object (
|
||||
"app",
|
||||
"App",
|
||||
"The app",
|
||||
MIDORI_TYPE_APP,
|
||||
flags));
|
||||
}
|
||||
|
||||
static const gchar*
|
||||
midori_plugins_get_label (MidoriViewable* viewable)
|
||||
{
|
||||
return _("Netscape plugins");
|
||||
}
|
||||
|
||||
static const gchar*
|
||||
midori_plugins_get_stock_id (MidoriViewable* viewable)
|
||||
{
|
||||
return STOCK_PLUGINS;
|
||||
}
|
||||
|
||||
static GtkWidget*
|
||||
midori_plugins_get_toolbar (MidoriViewable* plugins)
|
||||
{
|
||||
if (!MIDORI_PLUGINS (plugins)->toolbar)
|
||||
{
|
||||
GtkWidget* toolbar;
|
||||
GtkToolItem* toolitem;
|
||||
|
||||
toolbar = gtk_toolbar_new ();
|
||||
gtk_toolbar_set_style (GTK_TOOLBAR (toolbar), GTK_TOOLBAR_BOTH_HORIZ);
|
||||
gtk_toolbar_set_icon_size (GTK_TOOLBAR (toolbar), GTK_ICON_SIZE_BUTTON);
|
||||
toolitem = gtk_tool_item_new ();
|
||||
gtk_toolbar_insert (GTK_TOOLBAR (toolbar), toolitem, -1);
|
||||
gtk_widget_show (GTK_WIDGET (toolitem));
|
||||
|
||||
MIDORI_PLUGINS (plugins)->toolbar = toolbar;
|
||||
}
|
||||
|
||||
return MIDORI_PLUGINS (plugins)->toolbar;
|
||||
}
|
||||
|
||||
static void
|
||||
midori_plugins_viewable_iface_init (MidoriViewableIface* iface)
|
||||
{
|
||||
iface->get_stock_id = midori_plugins_get_stock_id;
|
||||
iface->get_label = midori_plugins_get_label;
|
||||
iface->get_toolbar = midori_plugins_get_toolbar;
|
||||
}
|
||||
|
||||
static void
|
||||
midori_plugins_set_property (GObject* object,
|
||||
guint prop_id,
|
||||
const GValue* value,
|
||||
GParamSpec* pspec)
|
||||
{
|
||||
MidoriPlugins* plugins = MIDORI_PLUGINS (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_APP:
|
||||
plugins->app = g_value_get_object (value);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
midori_plugins_get_property (GObject* object,
|
||||
guint prop_id,
|
||||
GValue* value,
|
||||
GParamSpec* pspec)
|
||||
{
|
||||
MidoriPlugins* plugins = MIDORI_PLUGINS (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_APP:
|
||||
g_value_set_object (value, plugins->app);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
midori_plugins_treeview_render_icon_cb (GtkTreeViewColumn* column,
|
||||
GtkCellRenderer* renderer,
|
||||
GtkTreeModel* model,
|
||||
GtkTreeIter* iter,
|
||||
GtkWidget* treeview)
|
||||
{
|
||||
g_object_set (renderer, "stock-id", GTK_STOCK_EXECUTE, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
midori_plugins_treeview_render_text_cb (GtkTreeViewColumn* column,
|
||||
GtkCellRenderer* renderer,
|
||||
GtkTreeModel* model,
|
||||
GtkTreeIter* iter,
|
||||
GtkWidget* treeview)
|
||||
{
|
||||
gchar* name;
|
||||
gchar* text;
|
||||
gchar* description;
|
||||
|
||||
gtk_tree_model_get (model, iter, 0, &name, 1, &description, -1);
|
||||
|
||||
text = g_strdup_printf ("%s\n%s", name, description);
|
||||
g_free (name);
|
||||
g_free (description);
|
||||
g_object_set (renderer, "text", text, NULL);
|
||||
g_free (text);
|
||||
}
|
||||
|
||||
static void
|
||||
midori_plugins_add_item (MidoriPlugins* plugins,
|
||||
const gchar* name,
|
||||
const gchar* description)
|
||||
{
|
||||
gchar* desc;
|
||||
GtkTreeIter iter;
|
||||
GtkTreeModel* model;
|
||||
|
||||
desc = g_strdup (description);
|
||||
if (desc)
|
||||
{
|
||||
gsize i, n;
|
||||
|
||||
n = strlen (desc);
|
||||
for (i = 0; i < n; i++)
|
||||
if (desc[i] == ';')
|
||||
desc[i] = '\n';
|
||||
}
|
||||
model = gtk_tree_view_get_model (GTK_TREE_VIEW (plugins->treeview));
|
||||
gtk_list_store_append (GTK_LIST_STORE (model), &iter);
|
||||
gtk_list_store_set (GTK_LIST_STORE (model), &iter,
|
||||
0, name, 1, desc, -1);
|
||||
g_free (desc);
|
||||
}
|
||||
|
||||
static void
|
||||
midori_plugins_init (MidoriPlugins* plugins)
|
||||
{
|
||||
/* Create the treeview */
|
||||
GtkTreeViewColumn* column;
|
||||
GtkCellRenderer* renderer_text;
|
||||
GtkCellRenderer* renderer_pixbuf;
|
||||
GtkListStore* liststore = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_STRING);
|
||||
|
||||
plugins->treeview = gtk_tree_view_new_with_model (GTK_TREE_MODEL (liststore));
|
||||
gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (plugins->treeview), FALSE);
|
||||
column = gtk_tree_view_column_new ();
|
||||
renderer_pixbuf = gtk_cell_renderer_pixbuf_new ();
|
||||
gtk_tree_view_column_pack_start (column, renderer_pixbuf, FALSE);
|
||||
gtk_tree_view_column_set_cell_data_func (column, renderer_pixbuf,
|
||||
(GtkTreeCellDataFunc)midori_plugins_treeview_render_icon_cb,
|
||||
plugins->treeview, NULL);
|
||||
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)midori_plugins_treeview_render_text_cb,
|
||||
plugins->treeview, NULL);
|
||||
gtk_tree_view_append_column (GTK_TREE_VIEW (plugins->treeview), column);
|
||||
g_object_unref (liststore);
|
||||
gtk_widget_show (plugins->treeview);
|
||||
gtk_box_pack_start (GTK_BOX (plugins), plugins->treeview, TRUE, TRUE, 0);
|
||||
|
||||
if (1)
|
||||
{
|
||||
/* FIXME: WebKit should have API to obtain the list of plugins. */
|
||||
/* FIXME: Monitor folders for newly added and removes files */
|
||||
GtkWidget* web_view = webkit_web_view_new ();
|
||||
WebKitWebFrame* web_frame = webkit_web_view_get_main_frame (WEBKIT_WEB_VIEW (web_view));
|
||||
JSContextRef js_context = webkit_web_frame_get_global_context (web_frame);
|
||||
/* This snippet joins the available plugins into a string like this:
|
||||
URI1|title1,URI2|title2
|
||||
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) "
|
||||
"{ f.push (l[i].name + '|' + l[i].filename); } return f; }"
|
||||
"plugins (navigator.plugins)", NULL);
|
||||
gchar** items = g_strsplit (value, ",", 0);
|
||||
guint i = 0;
|
||||
|
||||
if (items != NULL)
|
||||
while (items[i] != NULL)
|
||||
{
|
||||
gchar** parts = g_strsplit (items[i], "|", 2);
|
||||
if (parts && *parts && !g_str_equal (parts[1], "undefined"))
|
||||
midori_plugins_add_item (plugins, *parts, parts[1]);
|
||||
g_strfreev (parts);
|
||||
i++;
|
||||
}
|
||||
g_strfreev (items);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* midori_plugins_new:
|
||||
*
|
||||
* Creates a new empty plugins.
|
||||
*
|
||||
* Return value: a new #MidoriPlugins
|
||||
*
|
||||
* Since: 0.1.3
|
||||
**/
|
||||
GtkWidget*
|
||||
midori_plugins_new (void)
|
||||
{
|
||||
MidoriPlugins* plugins = g_object_new (MIDORI_TYPE_PLUGINS, NULL);
|
||||
|
||||
return GTK_WIDGET (plugins);
|
||||
}
|
|
@ -1,43 +0,0 @@
|
|||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
#ifndef __MIDORI_PLUGINS_H__
|
||||
#define __MIDORI_PLUGINS_H__
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define MIDORI_TYPE_PLUGINS \
|
||||
(midori_plugins_get_type ())
|
||||
#define MIDORI_PLUGINS(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_CAST ((obj), MIDORI_TYPE_PLUGINS, MidoriPlugins))
|
||||
#define MIDORI_PLUGINS_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_CAST ((klass), MIDORI_TYPE_PLUGINS, MidoriPluginsClass))
|
||||
#define MIDORI_IS_PLUGINS(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_TYPE ((obj), MIDORI_TYPE_PLUGINS))
|
||||
#define MIDORI_IS_PLUGINS_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_TYPE ((klass), MIDORI_TYPE_PLUGINS))
|
||||
#define MIDORI_PLUGINS_GET_CLASS(obj) \
|
||||
(G_TYPE_INSTANCE_GET_CLASS ((obj), MIDORI_TYPE_PLUGINS, MidoriPluginsClass))
|
||||
|
||||
typedef struct _MidoriPlugins MidoriPlugins;
|
||||
typedef struct _MidoriPluginsClass MidoriPluginsClass;
|
||||
|
||||
GType
|
||||
midori_plugins_get_type (void);
|
||||
|
||||
GtkWidget*
|
||||
midori_plugins_new (void);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __MIDORI_PLUGINS_H__ */
|
|
@ -17,7 +17,6 @@
|
|||
#include "midori-view.h"
|
||||
|
||||
#include "sokoke.h"
|
||||
#include "compat.h"
|
||||
#include <glib/gi18n.h>
|
||||
|
||||
struct _MidoriTransfers
|
||||
|
|
|
@ -1,2 +0,0 @@
|
|||
# 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 no pl pt pt_BR ro ru sk sr sr@latin sv tr uk zh_CN zh_TW
|
|
@ -6,7 +6,6 @@ midori/midori-app.c
|
|||
midori/midori-array.c
|
||||
midori/midori-browser.c
|
||||
midori/midori-locationaction.c
|
||||
midori/midori-locationentry.c
|
||||
midori/midori-panel.c
|
||||
midori/midori-websettings.c
|
||||
midori/midori-view.c
|
||||
|
@ -18,7 +17,6 @@ panels/midori-bookmarks.c
|
|||
panels/midori-console.c
|
||||
panels/midori-extensions.c
|
||||
panels/midori-history.c
|
||||
panels/midori-plugins.c
|
||||
panels/midori-transfers.c
|
||||
katze/katze-http-auth.c
|
||||
katze/katze-throbber.c
|
||||
|
@ -32,7 +30,6 @@ extensions/colorful-tabs.c
|
|||
extensions/cookie-manager/cookie-manager.c
|
||||
extensions/cookie-manager/cookie-manager-page.c
|
||||
extensions/cookie-manager/main.c
|
||||
extensions/dnsprefetch.c
|
||||
extensions/feed-panel/feed-atom.c
|
||||
extensions/feed-panel/feed-panel.c
|
||||
extensions/feed-panel/feed-parse.c
|
||||
|
|
2046
po/en_GB.po
2046
po/en_GB.po
File diff suppressed because it is too large
Load diff
2343
po/midori.pot
2343
po/midori.pot
File diff suppressed because it is too large
Load diff
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue