Imported Upstream version 0.2.4
This commit is contained in:
parent
67e400912e
commit
9eaa210044
109 changed files with 29999 additions and 24286 deletions
.gitignoreChangeLogHACKINGINSTALLTODOTRANSLATE
data
extensions
adblock.ccolorful-tabs.c
cookie-manager
dnsprefetch.cfeed-panel
formhistory.cshortcuts.ctoolbar-editor.cweb-cache.cwscript_buildkatze
katze-array.ckatze-array.hkatze-arrayaction.ckatze-arrayaction.hkatze-http-auth.ckatze-http-auth.hkatze-http-cookies.hkatze-item.hkatze-net.ckatze-net.hkatze-preferences.ckatze-preferences.hkatze-scrolled.ckatze-scrolled.hkatze-separatoraction.hkatze-throbber.ckatze-throbber.hkatze-utils.ckatze-utils.hmarshal.listwscript_build
midori
compat.ccompat.hgtkiconentry.cgtkiconentry.hmain.cmarshal.listmidori-app.cmidori-app.hmidori-array.cmidori-browser.cmidori-browser.hmidori-extension.hmidori-locationaction.cmidori-locationaction.hmidori-locationentry.cmidori-locationentry.hmidori-panel.cmidori-panel.hmidori-preferences.cmidori-preferences.hmidori-searchaction.cmidori-searchaction.hmidori-view.cmidori-view.hmidori-viewable.cmidori-viewable.hmidori-websettings.cmidori-websettings.hmidori.hsocket.csokoke.csokoke.hwscript_build
panels
midori-addons.cmidori-bookmarks.cmidori-console.cmidori-extensions.cmidori-history.cmidori-plugins.cmidori-plugins.hmidori-transfers.c
po
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…
Add table
Add a link
Reference in a new issue