Merge branch 'upstream-unstable'

This commit is contained in:
Yves-Alexis Perez 2012-09-20 07:36:31 +02:00
commit fae7cfdb3d
142 changed files with 38150 additions and 36603 deletions

View file

@ -1,5 +1,67 @@
This file is licensed under the terms of the expat license, see the file EXPAT.
v0.4.7:
Unify download behavior: link fingerprints, space check, clearing, tooltips
GIO-based check for enough space and permissions, GIO-based themed icons
Show opener/ tab domain in download dialog:
http://lcamtuf.coredump.cx/fldl/ http://lcamtuf.coredump.cx/switch/
Extension to download with a specific command line
Size in download dialog and fallback filename heuristic
Windows: GTK+3, Faenza icons, gdb helper, Netscape plugins,
ship CA bundle, fix View source, --portable/ -P on Windows
Granite (Beta): about dialog, static notebook, no "New Tab" in toolbar, Print → Share
Support building with Wayland-enabled GTK+3
Theming: content view, secondary toolbar class, drop old icon names, bigger error icon
Introduce --plain mode equivalent to GtkLauncher, lazy URLs for --snapshot/ -s
Log bookmarks, history and downloads to zeitgeist
Show security details and export certificates with GCR, error out instead of colored urlbar
Only allow data: URLs in urlbar for images
Recognize and cache HSTS, system-wide /etc/xdg/midori/hsts
Strip HTTP Host to outsmart some filter proxies
Completion: Fix PageUp/Down, Shift+Tab and wrap: This is consistent with GTK+ (excluding Tab) and Firefox
Change Focus Current Tab to Ctrl+Alt+Home
Fix Shift+Space for scrolling upwards
Control+Alt+R: Readable mode
Handle access key in link hints
Drop speed dial keyboard access in favour of "." link hints
No Open, Bookmark bar, Customize toolbar, Inspect page in app menu; split panel menu
Use ellipsises instead of period thresomes
Hinted text in bookmarks, history and cookie manager
Ellipsize panels (except for Transfers)
Add icon to bookmark dialog and remove labels
Validate proxy server IP and render invalid URLs in GTK+3
Rename "Toplevel" folder to "Bookmarks"
Chrome identification option; "Automatic" user agent is Chrome-based
Search: Create engines from search forms, remove "icon" field
Copy Image s/Address// always copy both URL and data
Rework debugging by introducing MIDORI_DEBUG; about:paths
Adblock: Refresh filters based on file time and meta data, abp: links
Optionally save website including resources
Merged NextForward akin to StopReload
PanedAction, Viewable, SpeedDial, (most of) Settings, Paths in Vala
Improved database: requires sqlite 3.6.19 and 0.2.6 in import dialog
Confirm Caret Browsing before enabling it
Support for custom items in Statusbar Features (see FAQ)
Draggable favicon as URL or text, URL icon for URL entries
Remember if inspector was attached
Open tabs in the background by default
RTL support in special/ error pages
Fix progressbar text with GTK+3
Build fix: More robust GTK+2 version check
Ensure progress in urlbar and tab match
Zoom text and images by default
Don't mixup tokens starting with the same letters
Seemless running out of build folder
No speed dial in --app/ --private, fix layout with many tiles
Add X-GNOME-Fullname to .desktop and translate desktop shortcuts
Delayed Load extension
v0.4.6:
+ Fix crasher in geolocation infobar
+ Fix crasher in about:version on some systems

13
INSTALL
View file

@ -53,9 +53,9 @@ If the problem is a warning and not a crash, try this:
If you are interested in HTTP communication, try this:
'MIDORI_SOUP_DEBUG=2 _build/default/midori/midori'
'MIDORI_DEBUG=headers _build/default/midori/midori'
Where '2' can be a level between 0 and 3.
Where 'headers' can be replaced with 'body' to get full message contents.
If you are interested in (non-) touchscreen behaviour, try this:
@ -65,17 +65,16 @@ If you are interested in (non-) touchscreen behaviour, try this:
If you want to "dry run" without WebKitGTK+ rendering, try this:
'MIDORI_UNARMED=1 _build/default/midori/midori'
'MIDORI_DEBUG=unarmed _build/default/midori/midori'
If you want to test bookmarks, you can enable database tracing:
'MIDORI_BOOKMARKS_DEBUG=1 _build/default/midori/midori'
'MIDORI_DEBUG=bookmarks _build/default/midori/midori'
To disable Netscape plugins, use MOZ_PLUGIN_PATH=/.
To debug extensions you can specify the path:
'export MIDORI_EXTENSION_PATH=_build/default/extensions'
When running from the build folder, extensions will also be located
in the build folder (setting MIDORI_EXTENSION_PATH is no longer needed).
For further information a tutorial for gdb and
reading up on how you can install debugging

4
README
View file

@ -11,10 +11,10 @@ Midori is a lightweight web browser.
* Straightforward bookmark management.
* Customizable interface, extensions written in C and Vala.
Requirements: GLib 2.22, GTK+ 2.10, WebkitGTK+ 1.1.17, libXML2,
Requirements: GLib 2.22, GTK+ 2.16, WebkitGTK+ 1.1.17, libXML2,
libsoup 2.27.90, sqlite 3.0, Vala 0.14
Optional: GTK+ 3.0, Unique 0.9, libnotify
Optional: GTK+ 3.0, Unique 0.9, libnotify, gcr
For installation instructions read INSTALL.

View file

@ -18,15 +18,20 @@ body {
-webkit-border-radius: 1em;
}
icon {
#icon {
float: left;
padding-left: 1%;
padding-top: 1%;
}
html[dir="rtl"] #icon {
float: right;
padding-right: 1%;
}
#main {
float: right;
width: 90%;
width: 75%;
}
h1 {
@ -38,8 +43,16 @@ h1 {
}
#logo {
position: absolute; right: 15px; bottom: 15px;
z-index: -1;
position: absolute; bottom: 15px;
z-index: -1;
}
html[dir="ltr"] #logo {
right: 15px;
}
html[dir="rtl"] #logo {
left: 15px;
}
button span,

View file

@ -2,7 +2,7 @@
Error page template for Midori.
This file is licensed under the terms of the expat license, see the file EXPAT.
-->
<html>
<html dir="{dir}">
<head>
<title>{title}</title>
<link rel="shortcut icon" href="{icon}" />

View file

@ -8,29 +8,64 @@ Stylesheet for Midori's documentation based on a version of Enrico Troeger.
@media screen {
body {
background-color: #f6fff3;
color: #404040;
margin-left: 0.4em;
width: 60em;
font-size: 90%;
html, body {
width: 100% !important;
height: 100% !important;
margin: 0 !important;
padding: 0 !important;
}
a {
color: #013100;
* {
background: #f6fff3 !important;
color: #404040 !important;
font-size: 14pt !important;
font-family: serif !important;
text-align: justify !important;
line-height: 1.4em !important;
word-spacing: 0.4mm !important;
letter-spacing: 0.2mm !important;
-webkit-column-count: auto !important;
-webkit-column-width: auto !important;
-webkit-box-shadow: none !important;
width: auto !important;
word-wrap: break-word !important;
}
a:visited {
color: #7E558E;
div, p {
padding: 5pt !important;
}
li {
padding-left: 5pt !important;
}
img, *[accesskey], form *, form, iframe,
*[id^=navigation], *[id$=navigation], *[id*=navigation], .collapsed, .expanded {
display: none !important
}
/* FIXME: we want "images bigger than 50px here" */
img[width] {
display: inline !important
}
:link, :link * {
color: #013100 !important;
text-decoration: underline !important;
}
:visited, :visited * {
color: #7E558E !important;
text-decoration: underline !important;
}
a:hover {
text-decoration: none;
text-decoration: none !important;
}
h1, h2, h3 {
font-family: sans-serif;
color: #002a00;
font-family: serif !important;
color: #002a00 !important;
}
h1 {

View file

@ -7,7 +7,7 @@
<title>midori:faq</title>
<meta name="generator" content="DokuWiki"/>
<meta name="robots" content="noindex,nofollow"/>
<meta name="date" content="2012-05-11T19:02:21+0200"/>
<meta name="date" content="2012-09-18T16:25:52+0200"/>
<meta name="keywords" content="midori,faq"/>
<link rel="search" type="application/opensearchdescription+xml" href="/lib/exe/opensearch.php" title="Xfce Wiki"/>
<link rel="start" href="/"/>
@ -37,6 +37,7 @@ var NS='midori';var JSINFO = {"id":"midori:faq","namespace":"midori"};
<li class="level1"><div class="li"><span class="li"><a href="#getting_started" class="toc">Getting started</a></span></div></li>
<li class="level1"><div class="li"><span class="li"><a href="#common_problems" class="toc">Common problems</a></span></div>
<ul class="toc">
<li class="level2"><div class="li"><span class="li"><a href="#security_features" class="toc">Security features</a></span></div></li>
<li class="level2"><div class="li"><span class="li"><a href="#flash_doesn_t_work" class="toc">Flash doesn&#039;t work</a></span></div></li>
</ul>
</li>
@ -50,6 +51,7 @@ var NS='midori';var JSINFO = {"id":"midori:faq","namespace":"midori"};
<ul class="toc">
<li class="level2"><div class="li"><span class="li"><a href="#web_applications" class="toc">Web Applications</a></span></div></li>
<li class="level2"><div class="li"><span class="li"><a href="#private_browsing" class="toc">Private Browsing</a></span></div></li>
<li class="level2"><div class="li"><span class="li"><a href="#portable_modewin32" class="toc">Portable mode/ Win32</a></span></div></li>
<li class="level2"><div class="li"><span class="li"><a href="#kiosk_mode" class="toc">Kiosk mode</a></span></div></li>
</ul>
</li>
@ -75,9 +77,12 @@ var NS='midori';var JSINFO = {"id":"midori:faq","namespace":"midori"};
<p>
This is a list of frequently asked questions about the Midori Web Browser. Anyone feel free to improve and/ or extend this page, but keep it clean and easy to read for other Xfce users.
</p>
<p>
This is a snapshot of Frequently Asked Questions designated for offline viewing. The most recent version of this document can be found <a href="http://wiki.xfce.org/midori/faq">in the Xfce wiki</a>.
<p/>
</div>
<!-- EDIT1 SECTION "Midori - Frequently asked questions" [1-289] -->
<h1 class="sectionedit2"><a name="getting_started" id="getting_started">Getting started</a></h1>
<div class="level1">
@ -127,7 +132,7 @@ Midori and all delivered artwork are licensed under the LGPL2.
</p>
</div>
<!-- EDIT2 SECTION "Getting started" [290-1188] -->
<h1 class="sectionedit3"><a name="common_problems" id="common_problems">Common problems</a></h1>
<div class="level1">
@ -223,8 +228,49 @@ export XDG_CACHE_HOME=/dev/shm
</p>
</div>
<!-- EDIT3 SECTION "Common problems" [1189-3299] -->
<h2 class="sectionedit4"><a name="flash_doesn_t_work" id="flash_doesn_t_work">Flash doesn&#039;t work</a></h2>
<h2 class="sectionedit4"><a name="security_features" id="security_features">Security features</a></h2>
<div class="level2">
</div>
<h4><a name="hstshttp_strict_transport_security" id="hstshttp_strict_transport_security">HSTS/ HTTP Strict Transport Security</a></h4>
<div class="level4">
<p>
Midori &gt;= 0.4.7 automatically picks up the Strict-Transport-Security header and caches sites locally. By design, there&#039;s no UI. System administrators can however place a pre-loaded cache at /etc/xdg/midori/hsts.
</p>
</div>
<h4><a name="certificate_handling" id="certificate_handling">Certificate Handling</a></h4>
<div class="level4">
<p>
Midori &gt;= 0.4.7 supports <a href="/midori/gcr" class="wikilink2" title="midori:gcr" rel="nofollow">http://git.gnome.org/browse/gcr/tree/gcr</a> for certificate display and management, you can click the lock in the urlbar to see detailed information. Earlier versions, or one without gcr will not handle certificates beyond the lock icon in the urlbar.
</p>
</div>
<h5><a name="error_granting_trustcouldn_t_find_a_place_to_store_the_imported_certificate" id="error_granting_trustcouldn_t_find_a_place_to_store_the_imported_certificate">Error granting trust: Couldn&#039;t find a place to store the imported certificate</a></h5>
<div class="level5">
<p>
No key store is available or it&#039;s incorrectly setup. By default GNOME keyring can do this. Under Xfce it is recommended to enable “GNOME services” under “Session and Startup settings”. Otherwise this can occur if a script doesn&#039;t correctly send the output of “gnome-keyring startup” to the environment.
</p>
</div>
<h5><a name="a_testcase_for_self-signed_certificates" id="a_testcase_for_self-signed_certificates">A testcase for self-signed certificates</a></h5>
<div class="level5">
<p>
<a href="https://selfsigned.notyours.dk:444/menu.gif" class="urlextern" title="https://selfsigned.notyours.dk:444/menu.gif" rel="nofollow">https://selfsigned.notyours.dk:444/menu.gif</a>
</p>
</div>
<h2 class="sectionedit5"><a name="flash_doesn_t_work" id="flash_doesn_t_work">Flash doesn&#039;t work</a></h2>
<div class="level2">
</div>
@ -233,7 +279,12 @@ export XDG_CACHE_HOME=/dev/shm
<div class="level4">
<p>
WebKitGTK+ and thusly Midori on Windows doesn&#039;t support Flash or any other plugins. If WebKitGTK+ adds the feature in the future, we will support it. For now there&#039;s nothing we can do.
WebKitGTK+ and thusly Midori on Windows doesn&#039;t support Flash or any other plugins. If WebKitGTK+ adds the feature in the future, we will support it. For now there&#039;s nothing we can do.
</p>
<p>
Starting with WebkitGTK+ 1.8.2 (Midori 0.4.7) Netscape plugins are now supported.
Midori should pick them up from standard netscape plugins locations.
</p>
</div>
@ -256,11 +307,17 @@ You can either run that above line and run Midori in the same terminal afterward
</div>
<h4><a name="flash_is_crashing_all_the_time" id="flash_is_crashing_all_the_time">Flash is crashing all the time</a></h4>
<h4><a name="flash_is_crashingno_flash_with_gtk_3" id="flash_is_crashingno_flash_with_gtk_3">Flash is crashing/ No Flash with GTK+3</a></h4>
<div class="level4">
<p>
Try searching for a package named nspluginwrapper or similar in your distribution repositories. It implements plugins in their own process so they can&#039;t drag down the whole browser.
nspluginwrapper is a program that runs Flash and other Netscape plugins in a separate process. So a crash can&#039;t cresh the whole browser and Flash, which is GTK+2 can run in GTK+3.
</p>
<p>
sudo apt-get install nspluginwrapper
sudo nspluginwrapper -i /usr/lib/flashplugin-installer/libflashplayer.so
nspluginwrapper -v -a -n -i
</p>
</div>
@ -275,6 +332,15 @@ That&#039;s a problem with WebKit. You can work around it to some extent if you
</div>
<h4><a name="bit_encryption_isn_t_supported" id="bit_encryption_isn_t_supported">256-bit encryption isn&#039;t supported?</a></h4>
<div class="level4">
<p>
There&#039;s no official support right now. It&#039;s possible to <a href="https://opensource.conformal.com/fluxbb/viewtopic.php?pid=1332#p1332" class="urlextern" title="https://opensource.conformal.com/fluxbb/viewtopic.php?pid=1332#p1332" rel="nofollow">patch glib-networking to enable 256-bit SSL</a>.
</p>
</div>
<h4><a name="scroll_with_middle_mouse_buttonpan-scrolling" id="scroll_with_middle_mouse_buttonpan-scrolling">Scroll with middle mouse button/ pan-scrolling</a></h4>
<div class="level4">
@ -283,7 +349,8 @@ That&#039;s a problem with WebKit. You can work around it to some extent if you
</p>
<p>
Bug: <a href="https://bugs.launchpad.net/webkit/+bug/871425" class="urlextern" title="https://bugs.launchpad.net/webkit/+bug/871425" rel="nofollow">https://bugs.launchpad.net/webkit/+bug/871425</a>
Bug: <a href="https://bugs.launchpad.net/webkit/+bug/871425" class="urlextern" title="https://bugs.launchpad.net/webkit/+bug/871425" rel="nofollow">https://bugs.launchpad.net/webkit/+bug/871425</a><br/>
Upstream Bug: <a href="https://bugs.webkit.org/show_bug.cgi?id=50561" class="urlextern" title="https://bugs.webkit.org/show_bug.cgi?id=50561" rel="nofollow">https://bugs.webkit.org/show_bug.cgi?id=50561</a>
</p>
@ -455,17 +522,76 @@ Edit→Preferences→Behavior and check “Enable Spell Checking”.
</p>
<p>
Now while typing any errors should get underlined in red. To get suggestions, highlight the word and right-click. Should see a list of suggestions on the top of the menu.
Now while typing any errors should get underlined in red. To get suggestions, highlight the word and right-click. You should see a list of suggestions at the top of the menu.
</p>
<p>
On Windows <a href="http://download.services.openoffice.org/files/contrib/dictionaries/" class="urlextern" title="http://download.services.openoffice.org/files/contrib/dictionaries/" rel="nofollow">you need to download OpenOffice dictionaries</a>, find the zipped file(s) for your locale(s) and unpack the contents into share/myspell/dicts/ in your Midori installation. The folder should contain *.aff and *.dic files
</p>
</div>
<!-- EDIT4 SECTION "Flash doesn't work" [3300-8989] -->
<h1 class="sectionedit5"><a name="privacy" id="privacy">Privacy</a></h1>
<h4><a name="is_it_possible_to_disable_same_origin_policy_what_webkit_settings_not_in_the_preferences_can_i_change" id="is_it_possible_to_disable_same_origin_policy_what_webkit_settings_not_in_the_preferences_can_i_change">Is it possible to disable Same Origin Policy? What Webkit settings not in the preferences can I change?</a></h4>
<div class="level4">
<p>
You can change <a href="http://webkitgtk.org/reference/webkitgtk/stable/WebKitWebSettings.html" class="urlextern" title="http://webkitgtk.org/reference/webkitgtk/stable/WebKitWebSettings.html" rel="nofollow">all values of WebKitWebSettings</a> in the config file (~/.config/midori/config on unices, %APPDATA%\midori\config [please check :)] on Windows). For example, to disable Same Origin Policy for local files, add
</p>
<pre class="code">enable-universal-access-from-file-uris=true</pre>
<p>
to your config file.
</p>
</div>
<h4><a name="how_do_i_change_the_proxy_server_from_the_toolbar_or_statusbar" id="how_do_i_change_the_proxy_server_from_the_toolbar_or_statusbar">How do I change the proxy server from the toolbar or statusbar?</a></h4>
<div class="level4">
<ol>
<li class="level1"><div class="li"> Activate the Statusbar Features plugin.</div>
</li>
<li class="level1"><div class="li"> Close Midori.</div>
</li>
<li class="level1"><div class="li"> Create a folder ~/.config/midori/extensions/libstatusbar-features.so/</div>
</li>
<li class="level1"><div class="li"> Create a text file “config”</div>
</li>
<li class="level1"><div class="li"> Type the following for the default setup:</div>
</li>
</ol>
<pre class="code"> [settings]
items=auto-load-images;enable-scripts;enable-plugins;identify-as;zoom-level</pre>
<p>
Add button types separated by semicolon:
</p>
<ul>
<li class="level1"><div class="li"> proxy-type Proxy Server</div>
</li>
<li class="level1"><div class="li"> preferred-encoding Character Set/ Encoding</div>
</li>
<li class="level1"><div class="li"> enable-spell-checking Spell Check</div>
</li>
<li class="level1"><div class="li"> zoom-text-and-images Only zoom in text, or text and images</div>
</li>
<li class="level1"><div class="li"> first-party-cookies-only First party cookies only</div>
</li>
<li class="level1"><div class="li"> site-data-rules see <a href="#blacklist_cookies" title="midori:faq &crarr;" class="wikilink1">Blacklisting cookies</a></div>
</li>
</ul>
<p>
Most settings listed at <a href="http://webkitgtk.org/reference/webkitgtk/stable/WebKitWebSettings.html" class="urlextern" title="http://webkitgtk.org/reference/webkitgtk/stable/WebKitWebSettings.html" rel="nofollow">http://webkitgtk.org/reference/webkitgtk/stable/WebKitWebSettings.html</a> will also work as button types.
</p>
</div>
<h1 class="sectionedit6"><a name="privacy" id="privacy">Privacy</a></h1>
<div class="level1">
</div>
<!-- EDIT5 SECTION "Privacy" [8990-9012] -->
<h2 class="sectionedit6"><a name="blacklist_cookies" id="blacklist_cookies">Blacklist cookies</a></h2>
<h2 class="sectionedit7"><a name="blacklist_cookies" id="blacklist_cookies">Blacklist cookies</a></h2>
<div class="level2">
<p>
@ -490,8 +616,8 @@ The feature is currently experimental and will change in future versions.
</p>
</div>
<!-- EDIT6 SECTION "Blacklist cookies" [9013-9549] -->
<h2 class="sectionedit7"><a name="adblock" id="adblock">Adblock</a></h2>
<h2 class="sectionedit8"><a name="adblock" id="adblock">Adblock</a></h2>
<div class="level2">
<p>
@ -499,13 +625,13 @@ The Advertisement Blocker can be activated under Extensions. It uses the same li
</p>
</div>
<!-- EDIT7 SECTION "Adblock" [9550-9805] -->
<h1 class="sectionedit8"><a name="modes" id="modes">Modes</a></h1>
<h1 class="sectionedit9"><a name="modes" id="modes">Modes</a></h1>
<div class="level1">
</div>
<!-- EDIT8 SECTION "Modes" [9806-9826] -->
<h2 class="sectionedit9"><a name="web_applications" id="web_applications">Web Applications</a></h2>
<h2 class="sectionedit10"><a name="web_applications" id="web_applications">Web Applications</a></h2>
<div class="level2">
<p>
@ -525,8 +651,8 @@ There are two closely related features to open websites as dedicated windows of
</p>
</div>
<!-- EDIT9 SECTION "Web Applications" [9827-10343] -->
<h2 class="sectionedit10"><a name="private_browsing" id="private_browsing">Private Browsing</a></h2>
<h2 class="sectionedit11"><a name="private_browsing" id="private_browsing">Private Browsing</a></h2>
<div class="level2">
<p>
@ -551,8 +677,17 @@ The same options available to -a/ app can be used for private browsing mode.
</p>
</div>
<!-- EDIT10 SECTION "Private Browsing" [10344-11263] -->
<h2 class="sectionedit11"><a name="kiosk_mode" id="kiosk_mode">Kiosk mode</a></h2>
<h2 class="sectionedit12"><a name="portable_modewin32" id="portable_modewin32">Portable mode/ Win32</a></h2>
<div class="level2">
<p>
On Windows builds, -P/ portable causes all data to be written to the “profile” folder in the Midori folder. Everything, including temporary files and cache, is stored in a sub-folder without touching the system. So Midori can be run eg. from a USB stick on different machines.
</p>
</div>
<h2 class="sectionedit13"><a name="kiosk_mode" id="kiosk_mode">Kiosk mode</a></h2>
<div class="level2">
<p>
@ -583,8 +718,8 @@ Any links outside end up in an error page. All images and other files won&#039;t
</p>
</div>
<!-- EDIT11 SECTION "Kiosk mode" [11264-12301] -->
<h1 class="sectionedit12"><a name="proxy_servers" id="proxy_servers">Proxy servers</a></h1>
<h1 class="sectionedit14"><a name="proxy_servers" id="proxy_servers">Proxy servers</a></h1>
<div class="level1">
<p>
@ -638,7 +773,11 @@ Mousehole is a scriptable proxy server written in Ruby.
<div class="level4">
<p>
Currently only <acronym title="Hyper Text Transfer Protocol">HTTP</acronym> proxy servers are supported directly. A way to use SOCKS on Unix is to use tsocks with <acronym title="Secure Shell">SSH</acronym> as follows:
The coming libSoup 2.40 will support SOCKS proxies, <a href="https://bugzilla.gnome.org/show_bug.cgi?id=553269" class="urlextern" title="https://bugzilla.gnome.org/show_bug.cgi?id=553269" rel="nofollow">see the relevant bug report</a>.
</p>
<p>
libSoup &lt; 2.40 only supports <acronym title="Hyper Text Transfer Protocol">HTTP</acronym> proxy servers directly. A way to use SOCKS on Unix is to use tsocks with <acronym title="Secure Shell">SSH</acronym> as follows:
</p>
<ol>
<li class="level1"><div class="li"> Install &#039;tsocks&#039;</div>
@ -663,8 +802,8 @@ server_port = 5555</pre>
</ol>
</div>
<!-- EDIT12 SECTION "Proxy servers" [12302-13990] -->
<h1 class="sectionedit13"><a name="keyboard_hotkeys" id="keyboard_hotkeys">Keyboard Hotkeys</a></h1>
<h1 class="sectionedit15"><a name="keyboard_hotkeys" id="keyboard_hotkeys">Keyboard Hotkeys</a></h1>
<div class="level1">
</div>
@ -689,7 +828,7 @@ You can also use the arrow keys to do the same.
<div class="level4">
<p>
To enable Hints in Midori [similar to those vimperator provides in Firefox], press .
To enable Hints in Midori, similar to vimperator in Firefox or xxxterm, press .
</p>
<p>
@ -745,8 +884,8 @@ When using Ctrl+f to bring up Find, use Ctrl+f again or ESC. When using ”/”
</p>
</div>
<!-- EDIT13 SECTION "Keyboard Hotkeys" [13991-15328] -->
<h1 class="sectionedit14"><a name="mouse_gestures" id="mouse_gestures">Mouse Gestures</a></h1>
<h1 class="sectionedit16"><a name="mouse_gestures" id="mouse_gestures">Mouse Gestures</a></h1>
<div class="level1">
<p>
@ -775,8 +914,8 @@ Additionally, there are programs allowing mouse gestures system-wide, for exampl
</p>
</div>
<!-- EDIT14 SECTION "Mouse Gestures" [15329-16004] -->
<h1 class="sectionedit15"><a name="user_scripts_and_styles" id="user_scripts_and_styles">User scripts and styles</a></h1>
<h1 class="sectionedit17"><a name="user_scripts_and_styles" id="user_scripts_and_styles">User scripts and styles</a></h1>
<div class="level1">
<p>
@ -836,8 +975,8 @@ You can also use <a href="http://rightfootin.blogspot.com/2009/04/flashblock-wan
</p>
</div>
<!-- EDIT15 SECTION "User scripts and styles" [16005-18559] -->
<h2 class="sectionedit16"><a name="user_styles" id="user_styles">User styles</a></h2>
<h2 class="sectionedit18"><a name="user_styles" id="user_styles">User styles</a></h2>
<div class="level2">
<p>

28
data/gtk3.css Normal file
View file

@ -0,0 +1,28 @@
.notebook tab .button {
-GtkButton-default-border: 0;
-GtkButton-default-outside-border: 0;
-GtkButton-inner-border: 0;
-GtkWidget-focus-line-width: 0;
-GtkWidget-focus-padding: 0;
padding: 0;
}
GtkOverlay > * {
padding: 4px;
border-style: solid;
border-radius: 0 5px 0 0;
border-width: 1px 1px 0 0;
}
GtkOverlay MidoriFindbar {
border-radius: 0 0 0 5px;
border-width: 0 0 1px 1px; /* top right bottom left */
}
/* Kill grey backround on inactive buttons */
GtkDrawingArea,
GtkImage,
GtkImage:insensitive,
GtkImage:selected {
background-color: @transparent;
}

View file

@ -3,6 +3,7 @@ Version=1.0
Type=Application
_Name=Midori
_GenericName=Web Browser
_X-GNOME-Fullname=Midori Web Browser
_Comment=Browse the Web
_X-GNOME-Keywords=Internet;WWW;Explorer
_X-AppInstall-Keywords=Internet;WWW;Explorer
@ -17,17 +18,17 @@ X-Osso-Service=midori
X-Ayatana-Desktop-Shortcuts=TabNew;WindowNew;Private
[TabNew Shortcut Group]
Name=New _Tab
_Name=New Tab
Exec=midori -e TabNew
TargetEnvironment=Unity
[WindowNew Shortcut Group]
Name=New _Window
_Name=New Window
Exec=midori -e WindowNew
TargetEnvironment=Unity
[Private Shortcut Group]
Name=New P_rivate Browsing Window
_Name=New Private Browsing Window
Exec=midori --private
TargetEnvironment=Unity

View file

@ -114,22 +114,6 @@
display:none;
}
div.osd {
top: 9px;
position: fixed;
width: 100%;
text-align: right;
}
div.osd span {
border: 1px solid #999;
background-color: #f5f5f5;
padding: 8px;
color: #999;
-webkit-border-bottom-left-radius: 10px;
visibility: hidden;
}
.selected {
outline: 1px dotted black;
background-color: #eef;
@ -138,75 +122,44 @@
<script type="text/javascript">
var getAction = function (id)
{
var s = document.getElementById(id).childNodes[0];
if (s.className == 'preview')
return true;
function add_tile (ev) {
ev.preventDefault();
var url = prompt ("{enter_shortcut_address}", "http://");
if (!url) return false;
if (!url)
return false;
if (url.indexOf ("://") == -1)
url = "http://" + url;
var id = ev.target.parentNode.parentNode.id;
console.log ("speed_dial-save-add " + id + " " + url + " ");
return false;
}
var renameShortcut = function (id)
{
var old_name = document.getElementById(id).childNodes[1].textContent;
function rename_tile (ev) {
var old_name = ev.target.textContent;
var name = prompt ("{enter_shortcut_name}", old_name);
if (!name) return;
if (!name)
return;
var id = ev.target.parentNode.id;
console.log ("speed_dial-save-rename " + id + " " + name);
}
var clearShortcut = function (id)
{
if(!confirm("{are_you_sure}"))
function delete_tile (ev) {
ev.preventDefault();
if (!confirm("{are_you_sure}"))
return;
var id = ev.target.parentNode.parentNode.id;
console.log ("speed_dial-save-delete " + id);
}
var key_id = 's';
var key_timeout;
document.onkeypress = function ()
{
key_id = key_id + String.fromCharCode (event.which);
clearTimeout (key_timeout);
document.getElementById('dialing').innerText = key_id.substr(1);
document.getElementById('dialing').style.visibility = 'visible';
var div = document.getElementById(key_id);
if (div)
{
if (key_id.substr(1) > 9)
{
if (getAction (key_id))
document.location = div.childNodes[0].childNodes[1].href;
key_id = 's';
}
else
key_timeout = setTimeout ('if (getAction (key_id)) document.location = document.getElementById(key_id).childNodes[0].childNodes[1].href; key_id = \'s\'', 1000);
}
else
key_id = 's';
if (key_id.length <= 1)
document.getElementById('dialing').style.visibility = 'hidden';
return false;
}
var firstNode, secondNode;
var cursor;
var dial = document.getElementsByClassName("shortcut");
var get_dial_div = function (ele) {
var dial_div;
@ -215,10 +168,14 @@
if (ele.className == 'title')
dial_div = ele.parentNode;
if (ele.className.indexOf ('shortcut') != -1)
dial_dir = ele;
dial_div = ele;
return dial_div;
}
var click = function (ev) {
function click (ev) {
if (ev == undefined)
return;
ev.preventDefault();
var ele = ev.target;
cursor = ele.style.cursor;
@ -229,10 +186,13 @@
eparent.className = 'shortcut selected';
firstNode = eparent.id;
}
document.RemoveEventListener('click', click, false);
};
var up = function (ev) {
function up (ev) {
if (ev == undefined)
return;
ev.preventDefault();
ele = ev.target;
var eparent = get_dial_div (ele);
@ -244,17 +204,19 @@
swap();
};
var over = function (ev) {
function over (ev) {
if (ev == undefined)
return;
ev.preventDefault();
var ele = ev.target;
var eparent = get_dial_div (ele);
var dial = document.getElementsByClassName("shortcut");
if (firstNode != undefined)
{
eparent.className = 'shortcut selected';
for (var i = 0; i <= dial.length; i++) {
for (var i = 0; i < dial.length; i++) {
if (eparent.id != firstNode.id && dial[i].id != eparent.id) {
dial[i].className = 'shortcut';
}
@ -267,13 +229,33 @@
console.log ("speed_dial-save-swap " + firstNode + " " + secondNode);
};
document.addEventListener('mousedown', click, false);
document.addEventListener('mouseup', up, false);
document.addEventListener('mouseover', over, false);
function init () {
var new_tile = document.getElementsByClassName ("preview new");
new_tile[0].addEventListener ('click', add_tile, false);
var titles = document.getElementsByClassName ("title");
var len = titles.length;
for (var i = 0; i < len; i++) {
if (titles[i].parentNode.childNodes[0].className != "preview new")
titles[i].addEventListener ('click', rename_tile, false);
}
var crosses = document.getElementsByClassName ("cross");
var len = crosses.length;
for (var i = 0; i < len; i++)
crosses[i].addEventListener ('click', delete_tile, false);
var occupied_tiles = document.getElementsByClassName ("shortcut");
var len = occupied_tiles.length;
for (var i = 0; i < len; i++) {
if (occupied_tiles[i].childNodes[0].className != "preview new") {
occupied_tiles[i].addEventListener('mousedown', click, false);
occupied_tiles[i].addEventListener('mouseover', over, false);
occupied_tiles[i].addEventListener('mouseup', up, false);
}
}
}
</script>
</head>
<body>
<div class="osd" >
<span id="dialing"></span>
</div>
<body onload="init ();">
<div id="content">

View file

@ -10,6 +10,7 @@
See the file COPYING for the full license text.
*/
#include <midori/midori.h>
#include "midori-core.h"
#include <glib/gstdio.h>
#include "config.h"
@ -29,7 +30,7 @@
(__filter[4] != '-' && __filter[5] != '-')
#ifdef G_ENABLE_DEBUG
#define adblock_debug(dmsg, darg1, darg2) \
do { if (debug == 1) g_debug (dmsg, darg1, darg2); } while (0)
do { if (midori_debug ("adblock:match")) g_debug (dmsg, darg1, darg2); } while (0)
#else
#define adblock_debug(dmsg, darg1, darg2) /* nothing */
#endif
@ -41,12 +42,14 @@ static GHashTable* urlcache = NULL;
static GHashTable* blockcssprivate = NULL;
static GHashTable* navigationwhitelist = NULL;
static GString* blockcss = NULL;
#ifdef G_ENABLE_DEBUG
static guint debug;
#endif
static GList* update_list = NULL;
static gboolean update_done = FALSE;
static void
adblock_parse_file (gchar* path);
static gboolean
adblock_parse_file (gchar* path);
adblock_file_is_up_to_date (gchar* path);
static void
adblock_reload_rules (MidoriExtension* extension,
@ -164,9 +167,26 @@ adblock_download_notify_status_cb (WebKitDownload* download,
GParamSpec* pspec,
MidoriExtension* extension)
{
if (webkit_download_get_status (download) != WEBKIT_DOWNLOAD_STATUS_FINISHED)
if (update_done)
return;
adblock_reload_rules (extension, FALSE);
if (webkit_download_get_status (download) == WEBKIT_DOWNLOAD_STATUS_FINISHED)
{
GList* li = NULL;
for (li = update_list; li != NULL; li = g_list_next (li))
{
gchar* uri = g_strdup (webkit_download_get_destination_uri (download) + 7);
if (g_strcmp0 (li->data, uri))
update_list = g_list_remove (update_list, li->data);
g_free (uri);
}
}
if (g_list_length (update_list) == 0)
{
adblock_reload_rules (extension, FALSE);
update_done = TRUE;
}
}
static gchar*
@ -182,8 +202,7 @@ adblock_get_filename_for_uri (const gchar* uri)
if (!strncmp (uri, "file", 4))
return g_strndup (uri + 7, strlen (uri) - 7);
folder = g_build_filename (g_get_user_cache_dir (), PACKAGE_NAME,
"adblock", NULL);
folder = g_build_filename (midori_paths_get_cache_dir (), "adblock", NULL);
katze_mkdir_with_parents (folder, 0700);
filename = g_compute_checksum_for_string (G_CHECKSUM_MD5, uri, -1);
@ -226,7 +245,7 @@ adblock_reload_rules (MidoriExtension* extension,
continue;
}
if (!adblock_parse_file (path))
if (!adblock_file_is_up_to_date (path))
{
WebKitNetworkRequest* request;
WebKitDownload* download;
@ -236,11 +255,14 @@ adblock_reload_rules (MidoriExtension* extension,
download = webkit_download_new (request);
g_object_unref (request);
webkit_download_set_destination_uri (download, destination);
update_list = g_list_prepend (update_list, path);
g_free (destination);
g_signal_connect (download, "notify::status",
G_CALLBACK (adblock_download_notify_status_cb), extension);
webkit_download_start (download);
}
else
adblock_parse_file (path);
g_free (path);
i++;
}
@ -480,6 +502,8 @@ adblock_get_preferences_dialog (MidoriExtension* extension)
GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE,
#endif
NULL);
katze_widget_add_class (gtk_dialog_get_widget_for_response (
GTK_DIALOG (dialog), GTK_RESPONSE_HELP), "help_button");
content_area = gtk_dialog_get_content_area (GTK_DIALOG (dialog));
g_signal_connect (dialog, "destroy",
G_CALLBACK (gtk_widget_destroyed), &dialog);
@ -505,8 +529,10 @@ adblock_get_preferences_dialog (MidoriExtension* extension)
"and click \"Add\" to add it to the list. "
"You can find more lists at %s."),
#if GTK_CHECK_VERSION (2, 18, 0)
"<a href=\"http://adblockplus.org/en/subscriptions\">adblockplus.org/en/subscriptions</a> "
"<a href=\"http://easylist.adblockplus.org/\">easylist.adblockplus.org</a>");
#else
"<u>http://adblockplus.org/en/subscriptions</u> "
"<u>http://easylist.adblockplus.org/</u>");
#endif
#if GTK_CHECK_VERSION (2, 18, 0)
@ -571,6 +597,7 @@ adblock_get_preferences_dialog (MidoriExtension* extension)
vbox = gtk_vbox_new (FALSE, 4);
gtk_box_pack_start (GTK_BOX (hbox), vbox, FALSE, FALSE, 4);
button = gtk_button_new_from_stock (GTK_STOCK_ADD);
g_object_set_data (G_OBJECT (dialog), "entry", entry);
g_object_set_data (G_OBJECT (button), "entry", entry);
g_signal_connect (button, "clicked",
G_CALLBACK (adblock_preferences_add_clicked_cb), liststore);
@ -619,8 +646,9 @@ adblock_get_preferences_dialog (MidoriExtension* extension)
return dialog;
}
static void
adblock_open_preferences_cb (MidoriExtension* extension)
static GtkWidget*
adblock_show_preferences_dialog (MidoriExtension* extension,
const gchar* uri)
{
static GtkWidget* dialog = NULL;
@ -633,6 +661,19 @@ adblock_open_preferences_cb (MidoriExtension* extension)
}
else
gtk_window_present (GTK_WINDOW (dialog));
if (uri != NULL)
{
GtkWidget* entry = g_object_get_data (G_OBJECT (dialog), "entry");
gtk_entry_set_text (GTK_ENTRY (entry), uri);
}
return dialog;
}
static void
adblock_open_preferences_cb (MidoriExtension* extension)
{
adblock_show_preferences_dialog (extension, NULL);
}
static inline gint
@ -791,8 +832,29 @@ adblock_navigation_policy_decision_requested_cb (WebKitWebView* web_
WebKitNetworkRequest* request,
WebKitWebNavigationAction* action,
WebKitWebPolicyDecision* decision,
MidoriView* view)
MidoriExtension* extension)
{
const gchar* uri = webkit_network_request_get_uri (request);
if (g_str_has_prefix (uri, "abp:"))
{
gchar** parts;
gchar* filter;
if (g_str_has_prefix (uri, "abp:subscribe?location="))
uri = &uri[23];
else if (g_str_has_prefix (uri, "abp://subscribe?location="))
uri = &uri[25];
else
return FALSE;
parts = g_strsplit (uri, "&", 2);
filter = soup_uri_decode (parts[0]);
webkit_web_policy_decision_ignore (decision);
adblock_show_preferences_dialog (extension, filter);
g_free (filter);
g_strfreev (parts);
return TRUE;
}
if (web_frame == webkit_web_view_get_main_frame (web_view))
{
const gchar* req_uri = webkit_network_request_get_uri (request);
@ -843,7 +905,7 @@ adblock_resource_request_starting_cb (WebKitWebView* web_view,
}
#ifdef G_ENABLE_DEBUG
if (debug == 2)
if (midori_debug ("adblock:time"))
g_test_timer_start ();
#endif
if (adblock_is_matched (req_uri, page_uri))
@ -854,7 +916,7 @@ adblock_resource_request_starting_cb (WebKitWebView* web_view,
g_object_set_data (G_OBJECT (web_view), "blocked-uris", blocked_uris);
}
#ifdef G_ENABLE_DEBUG
if (debug == 2)
if (midori_debug ("adblock:time"))
g_debug ("match: %f%s", g_test_timer_elapsed (), "seconds");
#endif
@ -1019,7 +1081,7 @@ adblock_add_tab_cb (MidoriBrowser* browser,
g_signal_connect_after (web_view, "populate-popup",
G_CALLBACK (adblock_populate_popup_cb), extension);
g_signal_connect (web_view, "navigation-policy-decision-requested",
G_CALLBACK (adblock_navigation_policy_decision_requested_cb), view);
G_CALLBACK (adblock_navigation_policy_decision_requested_cb), extension);
g_signal_connect (web_view, "resource-request-starting",
G_CALLBACK (adblock_resource_request_starting_cb), view);
g_signal_connect (web_view, "load-finished",
@ -1281,7 +1343,7 @@ adblock_frame_add (gchar* line)
g_string_append (blockcss, line);
}
static inline void
static void
adblock_update_css_hash (gchar* domain,
gchar* value)
{
@ -1478,7 +1540,156 @@ adblock_parse_line (gchar* line)
return adblock_add_url_pattern ("", "uri", line);
}
static GDateMonth
str_month_name_to_gdate (const gchar* month)
{
guint i;
const gchar* months[] = {
"", "January", "February", "March", "April", "May", "June",
"July", "August", "September", "October", "November", "December"
};
for (i = 0; i < G_N_ELEMENTS (months); i++)
{
if (strncmp (month, months[i], 3) == 0)
return i;
}
return 0;
}
static gboolean
adblock_file_is_up_to_date (gchar* path)
{
FILE* file;
gchar line[2000];
/* Check a chunk of header for update info */
if ((file = g_fopen (path, "r")))
{
gint days_to_expire = 0;
gchar* timestamp = NULL;
guint i;
gboolean found_meta = FALSE;
gint fs_days_elapsed, days_elapsed = 0, least_days;
for (i = 0; i <= 15; i++)
{
fgets (line, 2000, file);
if (strncmp ("! Expires", line, 9) == 0)
{
gchar** parts = g_strsplit (line, " ", 4);
days_to_expire = atoi (parts[2]);
g_strfreev (parts);
found_meta = TRUE;
}
if (strncmp ("! This list expires after", line, 25) == 0)
{
gchar** parts = g_strsplit (line, " ", 7);
if (strncmp (parts[6], "days", 4) == 0)
days_to_expire = atoi (parts[5]);
if (strncmp (parts[6], "hours", 5) == 0)
days_to_expire = (atoi (parts[5])) / 24;
g_strfreev (parts);
found_meta = TRUE;
}
if (strncmp ("! Last modified", line, 15) == 0
|| strncmp ("! Updated", line, 9) == 0)
{
gchar** parts = g_strsplit (line, ":", 2);
timestamp = g_strdup (parts[1] + 1);
g_strchomp (timestamp);
g_strfreev (parts);
found_meta = TRUE;
}
}
if (!found_meta)
{
g_print ("Adblock: no metadata found in %s (broken download?)\n", path);
return FALSE;
}
/* query filesystem about file change, maybe there is no update yet
* or there is no "modified" metadata to check, otherwise we will repeatedly
* download files that have no new updates */
{
GDate* current = g_date_new ();
GDate* fs_mod_date = g_date_new ();
GTimeVal mod_time;
GFile* filter_file = g_file_new_for_path (path);
GFileInfo* info = g_file_query_info (filter_file, "time:modified", 0, NULL, NULL);
g_file_info_get_modification_time (info, &mod_time);
g_date_set_time_t (current, time (NULL));
g_date_set_time_val (fs_mod_date, &mod_time);
fs_days_elapsed = g_date_days_between (fs_mod_date, current);
g_date_free (current);
g_date_free (fs_mod_date);
}
/* If there is no update metadata but file is valid, assume one week */
if ((!days_to_expire && !timestamp) && fs_days_elapsed < 7)
return TRUE;
if (days_to_expire && timestamp != NULL)
{
GDate* current = g_date_new ();
GDate* mod_date = g_date_new ();
gchar** parts;
gboolean use_dots = FALSE;
/* Common dates are 20 Mar 2012, 20.08.2012 */
if (g_strrstr (timestamp, "."))
{
use_dots = TRUE;
parts = g_strsplit (timestamp, ".", 4);
}
else
parts = g_strsplit (timestamp, " ", 4);
g_date_set_day (mod_date, atoi (parts[0]));
if (use_dots)
g_date_set_month (mod_date, atoi (parts[1]));
else
g_date_set_month (mod_date, str_month_name_to_gdate (parts[1]));
g_date_set_year (mod_date, atoi (parts[2]));
g_strfreev (parts);
g_date_set_time_t (current, time (NULL));
days_elapsed = g_date_days_between (mod_date, current);
g_date_free (current);
g_date_free (mod_date);
g_free (timestamp);
}
/* File from the future? Assume up to date */
if (days_elapsed < 0)
{
g_print ("Adblock: file %s appears to be from the future,"
"check your system clock!\n", path);
return TRUE;
}
least_days = days_elapsed < fs_days_elapsed ? days_elapsed : fs_days_elapsed;
if (least_days < days_to_expire)
return TRUE;
else
return FALSE;
return TRUE;
}
return FALSE;
}
static void
adblock_parse_file (gchar* path)
{
FILE* file;
@ -1489,9 +1700,7 @@ adblock_parse_file (gchar* path)
while (fgets (line, 2000, file))
adblock_parse_line (line);
fclose (file);
return TRUE;
}
return FALSE;
}
static void
@ -1510,7 +1719,7 @@ adblock_deactivate_tabs (MidoriView* view,
g_signal_handlers_disconnect_by_func (
web_view, adblock_load_finished_cb, view);
g_signal_handlers_disconnect_by_func (
web_view, adblock_navigation_policy_decision_requested_cb, view);
web_view, adblock_navigation_policy_decision_requested_cb, extension);
}
static void
@ -1546,25 +1755,9 @@ static void
adblock_activate_cb (MidoriExtension* extension,
MidoriApp* app)
{
#ifdef G_ENABLE_DEBUG
const gchar* debug_mode;
#endif
KatzeArray* browsers;
MidoriBrowser* browser;
#ifdef G_ENABLE_DEBUG
debug_mode = g_getenv ("MIDORI_ADBLOCK");
if (debug_mode)
{
if (*debug_mode == '1')
debug = 1;
else if (*debug_mode == '2')
debug = 2;
else
debug = 0;
}
#endif
adblock_reload_rules (extension, FALSE);
browsers = katze_object_get_object (app, "browsers");
@ -1597,6 +1790,57 @@ test_adblock_parse (void)
g_assert_cmpstr (adblock_parse_line ("http://bla.blub/*"), ==, "http://bla.blub/");
}
static void
test_subscription_update (void)
{
gint temp;
gchar* filename;
temp = g_file_open_tmp ("midori_adblock_update_test_XXXXXX", &filename, NULL);
close (temp);
g_file_set_contents (filename, "", -1, NULL);
g_assert (!adblock_file_is_up_to_date (filename));
g_file_set_contents (filename,
"[Adblock Plus 1.1]\n"
"! Checksum: 48f6Qdo4PsNogsurLvQ71w\n"
"! Title: EasyList\n"
"! Last modified: 05 Sep 2010 11:00 UTC\n"
"! This list expires after 48 hours\n",
-1, NULL);
g_assert (!adblock_file_is_up_to_date (filename));
g_file_set_contents (filename,
"[Adblock Plus 1.1]\n"
"! Checksum: 48f6Qdo4PsNogsurLvQ71w\n"
"! Title: EasyList\n"
"! Last modified: 05.09.2010 11:00 UTC\n"
"! Expires: 2 days (update frequency)\n",
-1, NULL);
g_assert (!adblock_file_is_up_to_date (filename));
g_file_set_contents (filename,
"[Adblock Plus 1.1]\n"
"! Checksum: 48f6Qdo4PsNogsurLvQ71w\n"
"! Title: EasyList\n"
"! Updated: 05 Nov 2014 11:00 UTC\n"
"! Expires: 5 days (update frequency)\n",
-1, NULL);
g_assert (adblock_file_is_up_to_date (filename));
g_file_set_contents (filename,
"[Adblock]\n"
"! dutchblock v3\n"
"! This list expires after 14 days\n"
"|http://b*.mookie1.com/\n",
-1, NULL);
g_assert (adblock_file_is_up_to_date (filename));
g_unlink (filename);
g_free (filename);
}
static void
test_adblock_pattern (void)
{
@ -1660,6 +1904,7 @@ extension_test (void)
{
g_test_add_func ("/extensions/adblock/parse", test_adblock_parse);
g_test_add_func ("/extensions/adblock/pattern", test_adblock_pattern);
g_test_add_func ("/extensions/adblock/update", test_subscription_update);
}
#endif

View file

@ -14,6 +14,7 @@
/* This extensions add support for user addons: userscripts and userstyles */
#include <midori/midori.h>
#include "midori-core.h"
#include <glib/gstdio.h>
#include "config.h"
@ -182,8 +183,8 @@ addons_install_response (GtkWidget* infobar,
if (!filename)
filename = g_path_get_basename (uri);
folder_path = g_build_path (G_DIR_SEPARATOR_S, g_get_user_data_dir (),
PACKAGE_NAME, folder, NULL);
folder_path = g_build_path (G_DIR_SEPARATOR_S,
midori_paths_get_user_data_dir (), PACKAGE_NAME, folder, NULL);
if (!g_file_test (folder_path, G_FILE_TEST_EXISTS))
katze_mkdir_with_parents (folder_path, 0700);
@ -293,13 +294,13 @@ addons_button_add_clicked_cb (GtkToolItem* toolitem,
if (addons->kind == ADDONS_USER_SCRIPTS)
{
addons_type = g_strdup ("userscripts");
path = g_build_path (G_DIR_SEPARATOR_S, g_get_user_data_dir (),
path = g_build_path (G_DIR_SEPARATOR_S, midori_paths_get_user_data_dir (),
PACKAGE_NAME, "scripts", NULL);
}
else if (addons->kind == ADDONS_USER_STYLES)
{
addons_type = g_strdup ("userstyles");
path = g_build_path (G_DIR_SEPARATOR_S, g_get_user_data_dir (),
path = g_build_path (G_DIR_SEPARATOR_S, midori_paths_get_user_data_dir (),
PACKAGE_NAME, "styles", NULL);
}
else
@ -336,23 +337,13 @@ addons_button_add_clicked_cb (GtkToolItem* toolitem,
if (!g_file_test (path, G_FILE_TEST_EXISTS))
katze_mkdir_with_parents (path, 0700);
#if !GTK_CHECK_VERSION (2, 14, 0)
files = gtk_file_chooser_get_filenames (GTK_FILE_CHOOSER (dialog));
#else
files = gtk_file_chooser_get_files (GTK_FILE_CHOOSER (dialog));
#endif
while (files)
{
GFile* src_file;
GError* error = NULL;
#if !GTK_CHECK_VERSION (2, 14, 0)
src_file = g_file_new_for_path (files);
#else
src_file = files->data;
#endif
if (G_IS_FILE (src_file))
{
GFile* dest_file;
@ -491,7 +482,7 @@ addons_open_in_editor_clicked_cb (GtkWidget* toolitem,
g_object_get (settings, "text-editor", &text_editor, NULL);
if (text_editor && *text_editor)
sokoke_spawn_program (text_editor, element->fullpath);
sokoke_spawn_program (text_editor, TRUE, element->fullpath, TRUE);
else
{
gchar* element_uri = g_filename_to_uri (element->fullpath, NULL, NULL);
@ -522,10 +513,13 @@ addons_open_target_folder_clicked_cb (GtkWidget* toolitem,
folder = g_path_get_dirname (element->fullpath);
}
else
folder = g_build_path (G_DIR_SEPARATOR_S, g_get_user_data_dir (),
PACKAGE_NAME,
addons->kind == ADDONS_USER_SCRIPTS
? "scripts" : "styles", NULL);
{
folder = g_build_path (G_DIR_SEPARATOR_S, midori_paths_get_user_data_dir (),
PACKAGE_NAME, addons->kind == ADDONS_USER_SCRIPTS
? "scripts" : "styles", NULL);
katze_mkdir_with_parents (folder, 0700);
}
folder_uri = g_filename_to_uri (folder, NULL, NULL);
g_free (folder);
@ -783,11 +777,10 @@ addons_treeview_render_text_cb (GtkTreeViewColumn* column,
gtk_tree_model_get (model, iter, 0, &element, -1);
g_object_set (renderer, "text", element->displayname, NULL);
if (!element->enabled)
g_object_set (renderer, "sensitive", false, NULL);
else
g_object_set (renderer, "sensitive", true, NULL);
g_object_set (renderer, "text", element->displayname,
"sensitive", element->enabled,
"ellipsize", PANGO_ELLIPSIZE_END,
NULL);
}
static void
@ -831,19 +824,16 @@ addons_get_directories (AddonsKind kind)
else
g_assert_not_reached ();
path = g_build_path (G_DIR_SEPARATOR_S, g_get_user_data_dir (),
path = g_build_path (G_DIR_SEPARATOR_S, midori_paths_get_user_data_dir (),
PACKAGE_NAME, folder_name, NULL);
if (g_access (path, X_OK) == 0)
directories = g_slist_prepend (directories, path);
else
g_free (path);
directories = g_slist_prepend (directories, path);
datadirs = g_get_system_data_dirs ();
while (*datadirs)
{
path = g_build_path (G_DIR_SEPARATOR_S, *datadirs,
PACKAGE_NAME, folder_name, NULL);
if (g_slist_find (directories, path) == NULL && g_access (path, X_OK) == 0)
if (g_slist_find (directories, path) == NULL)
directories = g_slist_prepend (directories, path);
else
g_free (path);
@ -1335,8 +1325,9 @@ addons_init (Addons* addons)
G_CALLBACK (addons_cell_renderer_toggled_cb), addons);
gtk_tree_view_append_column (GTK_TREE_VIEW (addons->treeview), column);
column = gtk_tree_view_column_new ();
gtk_tree_view_column_set_expand (column, TRUE);
renderer_text = gtk_cell_renderer_text_new ();
gtk_tree_view_column_pack_start (column, renderer_text, FALSE);
gtk_tree_view_column_pack_start (column, renderer_text, TRUE);
gtk_tree_view_column_set_cell_data_func (column, renderer_text,
(GtkTreeCellDataFunc)addons_treeview_render_text_cb,
addons->treeview, NULL);
@ -1687,10 +1678,10 @@ addons_save_settings (MidoriApp* app,
config_dir = midori_extension_get_config_dir (extension);
config_file = g_build_filename (config_dir, "addons", NULL);
katze_mkdir_with_parents (config_dir, 0700);
if (config_dir != NULL)
katze_mkdir_with_parents (config_dir, 0700);
sokoke_key_file_save_to_file (keyfile, config_file, &error);
/* If the folder is /, this is a test run, thus no error */
if (error && !g_str_equal (config_dir, "/"))
if (error && midori_extension_get_config_dir (extension) != NULL)
{
g_warning (_("The configuration of the extension '%s' couldn't be saved: %s\n"),
_("User addons"), error->message);

View file

@ -702,7 +702,6 @@ static gchar *cm_get_domain_description_text(const gchar *domain, gint cookie_co
}
#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)
{
@ -731,8 +730,6 @@ static gboolean cm_tree_query_tooltip(GtkWidget *widget, gint x, gint y, gboolea
return FALSE;
}
#endif
static gboolean cm_filter_match(const gchar *haystack, const gchar *needle)
{
@ -812,25 +809,20 @@ static void cm_filter_entry_changed_cb(GtkEditable *editable, CookieManagerPage
if (priv->ignore_changed_filter)
return;
text = gtk_entry_get_text(GTK_ENTRY(editable));
if (!g_object_get_data (G_OBJECT (editable), "sokoke_has_default"))
text = gtk_entry_get_text(GTK_ENTRY(editable));
else
text = NULL;
cm_filter_tree(cmp, text);
cookie_manager_update_filter(priv->parent, text);
if (*text != '\0')
gtk_tree_view_expand_all(GTK_TREE_VIEW(priv->treeview));
else
if (text && *text)
gtk_tree_view_collapse_all(GTK_TREE_VIEW(priv->treeview));
else
gtk_tree_view_expand_all(GTK_TREE_VIEW(priv->treeview));
}
static void cm_filter_entry_clear_icon_released_cb(GtkIconEntry *e, gint pos, gint btn, gpointer data)
{
if (pos == GTK_ICON_ENTRY_SECONDARY)
gtk_entry_set_text(GTK_ENTRY(e), "");
}
static void cm_tree_selection_changed_cb(GtkTreeSelection *selection, CookieManagerPage *cmp)
{
GList *rows;
@ -1002,6 +994,7 @@ static void cm_tree_render_text_cb(GtkTreeViewColumn *column, GtkCellRenderer *r
}
else
g_object_set(renderer, "text", name, NULL);
g_object_set (renderer, "ellipsize", PANGO_ELLIPSIZE_END, NULL);
g_free(name);
}
@ -1022,6 +1015,7 @@ static GtkWidget *cm_tree_prepare(CookieManagerPage *cmp)
renderer = gtk_cell_renderer_text_new();
column = gtk_tree_view_column_new_with_attributes(
_("Name"), renderer, "text", COOKIE_MANAGER_COL_NAME, NULL);
gtk_tree_view_column_set_expand (column, TRUE);
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);
@ -1045,10 +1039,8 @@ static GtkWidget *cm_tree_prepare(CookieManagerPage *cmp)
g_signal_connect(treeview, "popup-menu", G_CALLBACK(cm_tree_popup_menu_cb), cmp);
/* tooltips */
#if GTK_CHECK_VERSION(2, 12, 0)
gtk_widget_set_has_tooltip(treeview, TRUE);
g_signal_connect(treeview, "query-tooltip", G_CALLBACK(cm_tree_query_tooltip), cmp);
#endif
/* drag'n'drop */
gtk_tree_view_enable_model_drag_source(
@ -1100,7 +1092,6 @@ static void cookie_manager_page_init(CookieManagerPage *self)
GtkWidget *desc_swin;
GtkWidget *paned;
GtkWidget *filter_hbox;
GtkWidget *filter_label;
GtkWidget *treeview;
CookieManagerPagePrivate *priv;
@ -1132,29 +1123,15 @@ static void cookie_manager_page_init(CookieManagerPage *self)
tree_swin = gtk_scrolled_window_new(NULL, NULL);
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(tree_swin),
GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(tree_swin), GTK_SHADOW_IN);
gtk_container_add(GTK_CONTAINER(tree_swin), treeview);
gtk_widget_show(tree_swin);
filter_label = gtk_label_new(_("Filter:"));
gtk_widget_show(filter_label);
priv->filter_entry = gtk_icon_entry_new();
gtk_widget_set_tooltip_text(priv->filter_entry,
_("Enter a filter string to show only cookies whose name or domain "
"field match the entered filter"));
priv->filter_entry = sokoke_search_entry_new (_("Search Cookies by Name or Domain"));
gtk_widget_show(priv->filter_entry);
gtk_icon_entry_set_icon_from_stock(GTK_ICON_ENTRY(priv->filter_entry),
GTK_ICON_ENTRY_SECONDARY, GTK_STOCK_CLEAR);
gtk_icon_entry_set_icon_highlight(GTK_ICON_ENTRY (priv->filter_entry),
GTK_ICON_ENTRY_SECONDARY, TRUE);
g_signal_connect(priv->filter_entry, "icon-release",
G_CALLBACK(cm_filter_entry_clear_icon_released_cb), NULL);
g_signal_connect(priv->filter_entry, "changed", G_CALLBACK(cm_filter_entry_changed_cb), self);
g_signal_connect(priv->filter_entry, "activate", G_CALLBACK(cm_filter_entry_changed_cb), self);
filter_hbox = gtk_hbox_new(FALSE, 0);
gtk_box_pack_start(GTK_BOX(filter_hbox), filter_label, FALSE, FALSE, 3);
gtk_box_pack_start(GTK_BOX(filter_hbox), priv->filter_entry, TRUE, TRUE, 3);
gtk_widget_show(filter_hbox);

View file

@ -0,0 +1,231 @@
/*
Copyright (C) 2012 André Stösel <andre@stoesel.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.
*/
using Gtk;
using Katze;
using Midori;
namespace DelayedLoad {
private class PreferencesDialog : Dialog {
protected Manager dl_manager;
protected Scale slider;
public PreferencesDialog (Manager manager) {
this.dl_manager = manager;
this.title = _("Preferences for %s").printf ( _("Delayed load"));
if (this.get_class ().find_property ("has-separator") != null)
this.set ("has-separator", false);
this.border_width = 5;
this.set_modal (true);
this.set_default_size (350, 100);
this.create_widgets ();
this.response.connect (response_cb);
}
private void response_cb (Dialog source, int response_id) {
switch (response_id) {
case ResponseType.APPLY:
this.dl_manager.set_integer ("delay", (int) (this.slider.get_value () * 1000));
this.dl_manager.preferences_changed ();
this.destroy ();
break;
case ResponseType.CANCEL:
this.destroy ();
break;
}
}
private void create_widgets () {
Label text = new Label (_("Delay in seconds until loading the page:"));
#if HAVE_GTK3
this.slider = new Scale.with_range (Orientation.HORIZONTAL, 0, 15, 0.1);
#else
this.slider = new HScale.with_range (0, 15, 0.1);
#endif
int delay = this.dl_manager.get_integer ("delay");
if (delay > 0)
this.slider.set_value ((float)delay / 1000);
#if HAVE_GTK3
Gtk.Box vbox = get_content_area () as Gtk.Box;
vbox.pack_start (text, false, false, 0);
vbox.pack_start (this.slider, false, true, 0);
#else
this.vbox.pack_start (text, false, false, 0);
this.vbox.pack_start (this.slider, false, true, 0);
#endif
this.add_button (Gtk.STOCK_CANCEL, ResponseType.CANCEL);
this.add_button (Gtk.STOCK_APPLY, ResponseType.APPLY);
this.show_all ();
}
}
private class TabShaker : GLib.Object {
public unowned Midori.Browser browser;
public GLib.PtrArray tasks;
public bool reload_tab () {
if (tasks.len == 1) {
Midori.View? view = browser.tab as Midori.View;
Midori.View scheduled_view = tasks.index (0) as Midori.View;
if (scheduled_view == view) {
Katze.Item item = view.get_proxy_item ();
item.ref();
int64 delay = item.get_meta_integer ("delay");
if (delay == -2) {
view.reload (true);
}
}
}
tasks.remove_index (0);
return false;
}
public TabShaker (Midori.Browser browser) {
this.browser = browser;
}
construct {
this.tasks = new GLib.PtrArray ();
}
}
private class Manager : Midori.Extension {
private int timeout = 0;
private bool timeout_handler = false;
private HashTable<Midori.Browser, TabShaker> tasks;
public signal void preferences_changed ();
private void preferences_changed_cb () {
this.timeout = get_integer ("delay");
}
private void show_preferences () {
PreferencesDialog dialog = new PreferencesDialog (this);
dialog.show ();
}
private void schedule_reload (Midori.Browser browser, Midori.View view) {
if (this.timeout == 0)
view.reload (true);
else {
unowned TabShaker shaker = tasks.get (browser);
if (shaker != null) {
shaker.tasks.add (view);
Timeout.add (this.timeout, shaker.reload_tab);
}
}
}
private void tab_changed (Midori.View? old_view, Midori.View? new_view) {
if (new_view != null) {
Midori.App app = get_app ();
Midori.Browser browser = app.browser;
Katze.Item item = new_view.get_proxy_item ();
item.ref();
int64 delay = item.get_meta_integer ("delay");
if (delay == -2 && new_view.progress < 1.0) {
this.schedule_reload (browser, new_view);
}
}
}
private bool reload_first_tab () {
Midori.App app = get_app ();
Midori.Browser? browser = app.browser;
Midori.View? view = browser.tab as Midori.View;
if (view != null) {
Katze.Item item = view.get_proxy_item ();
item.ref();
int64 delay = item.get_meta_integer ("delay");
if (delay != 1) {
unowned WebKit.WebView web_view = view.get_web_view ();
WebKit.LoadStatus load_status = web_view.load_status;
if (load_status == WebKit.LoadStatus.FINISHED) {
if (this.timeout != 0)
this.tasks.set (browser, new TabShaker (browser));
if (view.progress < 1.0)
this.schedule_reload (browser, view);
return false;
}
}
}
return true;
}
private void browser_added (Midori.Browser browser) {
browser.switch_tab.connect_after (this.tab_changed);
}
private void browser_removed (Midori.Browser browser) {
browser.switch_tab.disconnect (this.tab_changed);
}
public void activated (Midori.App app) {
/* FIXME: override behavior without changing the preference */
app.settings.load_on_startup = MidoriStartup.DELAYED_PAGES;
this.preferences_changed ();
Midori.Browser? focused_browser = app.browser;
if (focused_browser == null)
Timeout.add (50, this.reload_first_tab);
foreach (Midori.Browser browser in app.get_browsers ()) {
browser_added (browser);
}
app.add_browser.connect (browser_added);
}
public void deactivated () {
Midori.App app = get_app ();
foreach (Midori.Browser browser in app.get_browsers ()) {
browser_removed (browser);
}
app.add_browser.disconnect (browser_added);
}
internal Manager () {
GLib.Object (name: _("Delayed load"),
description: _("Delay page load until you actually use the tab."),
version: "0.1",
authors: "André Stösel <andre@stoesel.de>");
install_integer ("delay", 0);
activate.connect (this.activated);
deactivate.connect (this.deactivated);
open_preferences.connect (show_preferences);
preferences_changed.connect (preferences_changed_cb);
this.tasks = new HashTable<Midori.Browser, TabShaker> (GLib.direct_hash, GLib.direct_equal);
}
}
}
public Midori.Extension extension_init () {
return new DelayedLoad.Manager ();
}

View file

@ -35,9 +35,9 @@ namespace EDM {
private GLib.PtrArray download_managers = new GLib.PtrArray ();
public bool download_requested (Midori.View view, WebKit.Download download) {
if (download.get_data<void*> ("save-as-download") == null
&& download.get_data<void*> ("open-download") == null
&& download.get_data<void*> ("cancel-download") == null) {
Midori.DownloadType download_type = download.get_data<Midori.DownloadType> ("midori-download-type");
if (download_type == Midori.DownloadType.SAVE) {
var dlReq = new DownloadRequest ();
dlReq.uri = download.get_uri ();
@ -206,6 +206,100 @@ namespace EDM {
this.deactivate.connect (deactivated);
}
}
private class CommandLinePreferences : Dialog {
protected Entry input;
protected CommandLine commandline;
public CommandLinePreferences(CommandLine cl) {
this.commandline = cl;
string ext_name;
this.get ("name",out ext_name);
this.title = _("Preferences for %s").printf (ext_name);
if (this.get_class ().find_property ("has-separator") != null)
this.set ("has-separator", false);
this.border_width = 5;
this.set_modal (true);
this.set_default_size (400, 100);
this.create_widgets ();
this.response.connect (response_cb);
}
private void response_cb (Dialog source, int response_id) {
switch (response_id) {
case ResponseType.APPLY:
this.commandline.set_string ("commandline", this.input.get_text ());
this.destroy ();
break;
case ResponseType.CANCEL:
this.destroy ();
break;
}
}
private void create_widgets () {
Label text = new Label (_("Command:"));
this.input = new Entry ();
this.input.set_text (this.commandline.get_string ("commandline"));
#if HAVE_GTK3
Gtk.Box vbox = get_content_area () as Gtk.Box;
vbox.pack_start (text, false, false, 0);
vbox.pack_start (this.input, false, true, 0);
#else
this.vbox.pack_start (text, false, false, 0);
this.vbox.pack_start (this.input, false, true, 0);
#endif
this.add_button (Gtk.STOCK_CANCEL, ResponseType.CANCEL);
this.add_button (Gtk.STOCK_APPLY, ResponseType.APPLY);
this.show_all ();
}
}
private class CommandLine : ExternalDownloadManager {
private void show_preferences () {
CommandLinePreferences dialog = new CommandLinePreferences (this);
dialog.show ();
}
public override bool download (DownloadRequest dlReq) {
try {
string cmd = this.get_string ("commandline");
cmd = cmd.replace("{REFERER}", GLib.Shell.quote (dlReq.referer));
if (dlReq.cookie_header != null) {
cmd = cmd.replace("{COOKIES}", GLib.Shell.quote ("Cookie: " + dlReq.cookie_header));
} else {
cmd = cmd.replace("{COOKIES}", "\'\'");
}
cmd = cmd.replace("{URL}", GLib.Shell.quote (dlReq.uri));
GLib.Process.spawn_command_line_async (cmd);
return true;
} catch (Error e) {
this.handle_exception (e);
}
return false;
}
internal CommandLine () {
GLib.Object (name: _("External Download Manager - CommandLine"),
description: _("Download files with a specified command"),
version: "0.1" + Midori.VERSION_SUFFIX,
authors: "André Stösel <andre@stoesel.de>",
key: "commandline");
this.install_string ("commandline", "wget --no-check-certificate --referer={REFERER} --header={COOKIES} {URL}");
this.activate.connect (activated);
this.deactivate.connect (deactivated);
this.open_preferences.connect (show_preferences);
}
}
}
public Katze.Array extension_init () {
@ -214,6 +308,7 @@ public Katze.Array extension_init () {
var extensions = new Katze.Array( typeof (Midori.Extension));
extensions.add_item (new EDM.Aria2 ());
extensions.add_item (new EDM.SteadyFlow ());
extensions.add_item (new EDM.CommandLine ());
return extensions;
}

View file

@ -27,7 +27,7 @@ formhistory_construct_popup_gui (FormHistoryPriv* priv)
guint i;
gchar* file;
file = sokoke_find_data_filename ("autosuggestcontrol.js", TRUE);
file = midori_app_find_res_filename ("autosuggestcontrol.js");
if (!g_file_get_contents (file, &autosuggest, NULL, NULL))
{
g_free (file);
@ -35,7 +35,7 @@ formhistory_construct_popup_gui (FormHistoryPriv* priv)
}
g_strchomp (autosuggest);
katze_assign (file, sokoke_find_data_filename ("autosuggestcontrol.css", TRUE));
katze_assign (file, midori_app_find_res_filename ("autosuggestcontrol.css"));
if (!g_file_get_contents (file, &style, NULL, NULL))
{
g_free (file);

View file

@ -522,12 +522,12 @@ formhistory_activate_cb (MidoriExtension* extension,
formhistory_construct_popup_gui (priv);
config_dir = midori_extension_get_config_dir (extension);
katze_mkdir_with_parents (config_dir, 0700);
if (config_dir != NULL)
katze_mkdir_with_parents (config_dir, 0700);
filename = g_build_filename (config_dir, "forms.db", NULL);
if (sqlite3_open (filename, &db) != SQLITE_OK)
{
/* If the folder is /, this is a test run, thus no error */
if (!g_str_equal (midori_extension_get_config_dir (extension), "/"))
if (config_dir != NULL)
g_warning (_("Failed to open database: %s\n"), sqlite3_errmsg (db));
sqlite3_close (db);
}

View file

@ -462,7 +462,7 @@ namespace HistoryList {
tab_added (browser, tab);
browser.add_tab.connect (tab_added);
browser.remove_tab.connect (tab_removed);
browser.notify["tab"].connect (this.tab_changed);
browser.switch_tab.connect (this.tab_changed);
}
void browser_removed (Midori.Browser browser) {
@ -491,7 +491,7 @@ namespace HistoryList {
browser.add_tab.disconnect (tab_added);
browser.remove_tab.disconnect (tab_removed);
browser.notify["tab"].disconnect (this.tab_changed);
browser.switch_tab.disconnect (this.tab_changed);
}
void tab_added (Midori.Browser browser, Midori.View view) {
@ -520,21 +520,18 @@ namespace HistoryList {
}
}
void tab_changed (GLib.Object window, GLib.ParamSpec pspec) {
void tab_changed (Midori.View? old_view, Midori.View? new_view) {
if(this.ignoreNextChange) {
this.ignoreNextChange = false;
} else {
Midori.Browser browser = window as Midori.Browser;
Midori.View view = null;
Midori.View last_view = null;
browser.get ("tab", ref view);
last_view = browser.get_data<Midori.View?> ("history-list-last-change");
Midori.Browser? browser = Midori.Browser.get_for_widget (new_view);
Midori.View? last_view
= browser.get_data<Midori.View?> ("history-list-last-change");
if (last_view != null) {
this.tab_list_resort (browser, last_view);
}
browser.set_data<Midori.View?> ("history-list-last-change", view);
browser.set_data<Midori.View?> ("history-list-last-change", new_view);
}
}

View file

@ -107,6 +107,81 @@ statusbar_features_zoom_level_changed_cb (GtkWidget* combobox,
midori_view_set_zoom_level (view, zoom_level / 100.0);
}
GtkWidget*
statusbar_features_property_proxy (MidoriWebSettings* settings,
const gchar* property,
GtkWidget* toolbar)
{
const gchar* kind = NULL;
GtkWidget* button;
GtkWidget* image;
if (!strcmp (property, "auto-load-images")
|| !strcmp (property, "enable-scripts")
|| !strcmp (property, "enable-plugins"))
kind = "toggle";
else if (!strcmp (property, "identify-as"))
kind = "custom-user-agent";
else if (strstr (property, "font") != NULL)
kind = "font";
else if (!strcmp (property, "zoom-level"))
{
MidoriBrowser* browser = midori_browser_get_for_widget (toolbar);
gint i;
button = gtk_combo_box_text_new_with_entry ();
gtk_entry_set_width_chars (GTK_ENTRY (gtk_bin_get_child (GTK_BIN (button))), 4);
for (i = 0; i < G_N_ELEMENTS (zoom_levels); i++)
gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (button), zoom_levels[i].label);
g_signal_connect (button, "changed",
G_CALLBACK (statusbar_features_zoom_level_changed_cb), browser);
g_signal_connect (browser, "notify::tab",
G_CALLBACK (statusbar_features_browser_notify_tab_cb), button);
statusbar_features_browser_notify_tab_cb (browser, NULL, button);
return button;
}
button = katze_property_proxy (settings, property, kind);
if (GTK_IS_BIN (button))
{
GtkWidget* label = gtk_bin_get_child (GTK_BIN (button));
if (GTK_IS_LABEL (label))
gtk_label_set_ellipsize (GTK_LABEL (label), PANGO_ELLIPSIZE_END);
}
if (!strcmp (property, "auto-load-images"))
{
g_object_set_data (G_OBJECT (button), "feature-label", _("Images"));
image = gtk_image_new_from_stock (STOCK_IMAGE, GTK_ICON_SIZE_MENU);
gtk_button_set_image (GTK_BUTTON (button), image);
gtk_widget_set_tooltip_text (button, _("Load images automatically"));
statusbar_features_toolbar_notify_toolbar_style_cb (toolbar, NULL, button);
g_signal_connect (toolbar, "notify::toolbar-style",
G_CALLBACK (statusbar_features_toolbar_notify_toolbar_style_cb), button);
}
if (!strcmp (property, "enable-scripts"))
{
g_object_set_data (G_OBJECT (button), "feature-label", _("Scripts"));
image = gtk_image_new_from_stock (STOCK_SCRIPT, GTK_ICON_SIZE_MENU);
gtk_button_set_image (GTK_BUTTON (button), image);
gtk_widget_set_tooltip_text (button, _("Enable scripts"));
statusbar_features_toolbar_notify_toolbar_style_cb (toolbar, NULL, button);
g_signal_connect (toolbar, "notify::toolbar-style",
G_CALLBACK (statusbar_features_toolbar_notify_toolbar_style_cb), button);
}
else if (!strcmp (property, "enable-plugins"))
{
if (!midori_web_settings_has_plugin_support ())
gtk_widget_hide (button);
g_object_set_data (G_OBJECT (button), "feature-label", _("Netscape plugins"));
image = gtk_image_new_from_stock (STOCK_PLUGINS, GTK_ICON_SIZE_MENU);
gtk_button_set_image (GTK_BUTTON (button), image);
gtk_widget_set_tooltip_text (button, _("Enable Netscape plugins"));
statusbar_features_toolbar_notify_toolbar_style_cb (toolbar, NULL, button);
g_signal_connect (toolbar, "notify::toolbar-style",
G_CALLBACK (statusbar_features_toolbar_notify_toolbar_style_cb), button);
}
return button;
}
static void
statusbar_features_app_add_browser_cb (MidoriApp* app,
MidoriBrowser* browser,
@ -117,8 +192,8 @@ statusbar_features_app_add_browser_cb (MidoriApp* app,
MidoriWebSettings* settings;
GtkWidget* toolbar;
GtkWidget* button;
GtkWidget* image;
gsize i;
gchar** filters;
/* FIXME: Monitor each view and modify its settings individually
instead of merely replicating the global preferences. */
@ -127,52 +202,37 @@ statusbar_features_app_add_browser_cb (MidoriApp* app,
bbox = gtk_hbox_new (FALSE, 0);
settings = midori_browser_get_settings (browser);
toolbar = katze_object_get_object (browser, "navigationbar");
button = katze_property_proxy (settings, "auto-load-images", "toggle");
g_object_set_data (G_OBJECT (button), "feature-label", _("Images"));
image = gtk_image_new_from_stock (STOCK_IMAGE, GTK_ICON_SIZE_MENU);
gtk_button_set_image (GTK_BUTTON (button), image);
gtk_widget_set_tooltip_text (button, _("Load images automatically"));
statusbar_features_toolbar_notify_toolbar_style_cb (toolbar, NULL, button);
g_signal_connect (toolbar, "notify::toolbar-style",
G_CALLBACK (statusbar_features_toolbar_notify_toolbar_style_cb), button);
gtk_box_pack_start (GTK_BOX (bbox), button, FALSE, FALSE, 2);
button = katze_property_proxy (settings, "enable-scripts", "toggle");
g_object_set_data (G_OBJECT (button), "feature-label", _("Scripts"));
image = gtk_image_new_from_stock (STOCK_SCRIPTS, GTK_ICON_SIZE_MENU);
gtk_button_set_image (GTK_BUTTON (button), image);
gtk_widget_set_tooltip_text (button, _("Enable scripts"));
statusbar_features_toolbar_notify_toolbar_style_cb (toolbar, NULL, button);
g_signal_connect (toolbar, "notify::toolbar-style",
G_CALLBACK (statusbar_features_toolbar_notify_toolbar_style_cb), button);
gtk_box_pack_start (GTK_BOX (bbox), button, FALSE, FALSE, 2);
if (midori_web_settings_has_plugin_support ())
filters = midori_extension_get_string_list (extension, "items", NULL);
if (filters && *filters)
{
button = katze_property_proxy (settings, "enable-plugins", "toggle");
g_object_set_data (G_OBJECT (button), "feature-label", _("Netscape plugins"));
image = gtk_image_new_from_stock (STOCK_PLUGINS, GTK_ICON_SIZE_MENU);
gtk_button_set_image (GTK_BUTTON (button), image);
gtk_widget_set_tooltip_text (button, _("Enable Netscape plugins"));
statusbar_features_toolbar_notify_toolbar_style_cb (toolbar, NULL, button);
g_signal_connect (toolbar, "notify::toolbar-style",
G_CALLBACK (statusbar_features_toolbar_notify_toolbar_style_cb), button);
gtk_box_pack_start (GTK_BOX (bbox), button, FALSE, FALSE, 2);
i = 0;
while (filters[i] != NULL)
{
button = statusbar_features_property_proxy (settings, filters[i], toolbar);
gtk_box_pack_start (GTK_BOX (bbox), button, FALSE, FALSE, 2);
i++;
}
}
else
{
button = statusbar_features_property_proxy (settings, "auto-load-images", toolbar);
gtk_box_pack_start (GTK_BOX (bbox), button, FALSE, FALSE, 2);
button = statusbar_features_property_proxy (settings, "enable-scripts", toolbar);
gtk_box_pack_start (GTK_BOX (bbox), button, FALSE, FALSE, 2);
button = statusbar_features_property_proxy (settings, "enable-plugins", toolbar);
gtk_box_pack_start (GTK_BOX (bbox), button, FALSE, FALSE, 2);
button = statusbar_features_property_proxy (settings, "identify-as", toolbar);
gtk_box_pack_start (GTK_BOX (bbox), button, FALSE, FALSE, 2);
button = statusbar_features_property_proxy (settings, "zoom-level", toolbar);
gtk_box_pack_start (GTK_BOX (bbox), button, FALSE, FALSE, 2);
}
button = katze_property_proxy (settings, "identify-as", "custom-user-agent");
gtk_box_pack_start (GTK_BOX (bbox), button, FALSE, FALSE, 2);
button = gtk_combo_box_text_new_with_entry ();
gtk_entry_set_width_chars (GTK_ENTRY (gtk_bin_get_child (GTK_BIN (button))), 4);
for (i = 0; i < G_N_ELEMENTS (zoom_levels); i++)
gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (button), zoom_levels[i].label);
gtk_box_pack_start (GTK_BOX (bbox), button, FALSE, FALSE, 2);
g_signal_connect (button, "changed",
G_CALLBACK (statusbar_features_zoom_level_changed_cb), browser);
g_signal_connect (browser, "notify::tab",
G_CALLBACK (statusbar_features_browser_notify_tab_cb), button);
statusbar_features_browser_notify_tab_cb (browser, NULL, button);
gtk_widget_show_all (bbox);
gtk_box_pack_end (GTK_BOX (statusbar), bbox, FALSE, FALSE, 3);
g_object_unref (statusbar);
g_object_unref (toolbar);
g_strfreev (filters);
g_signal_connect (extension, "deactivate",
G_CALLBACK (statusbar_features_deactivate_cb), bbox);
}
@ -201,6 +261,7 @@ extension_init (void)
"version", "0.1" MIDORI_VERSION_SUFFIX,
"authors", "Christian Dywan <christian@twotoasts.de>",
NULL);
midori_extension_install_string_list (extension, "items", NULL, G_MAXSIZE);
g_signal_connect (extension, "activate",
G_CALLBACK (statusbar_features_activate_cb), NULL);

View file

@ -143,7 +143,6 @@ midori_extension_cursor_or_row_changed_cb (GtkTreeView* treeview,
/* Nothing to do */
}
#if GTK_CHECK_VERSION (2, 12, 0)
static gboolean
tab_panel_treeview_query_tooltip_cb (GtkWidget* treeview,
gint x,
@ -171,7 +170,6 @@ tab_panel_treeview_query_tooltip_cb (GtkWidget* treeview,
return TRUE;
}
#endif
static void
midori_extension_row_activated_cb (GtkTreeView* treeview,
@ -231,12 +229,12 @@ midori_extension_button_release_event_cb (GtkWidget* widget,
if (gtk_tree_view_get_path_at_pos (GTK_TREE_VIEW (widget),
event->x, event->y, NULL, &column, NULL, NULL)
&& column == gtk_tree_view_get_column (GTK_TREE_VIEW (widget), 1))
gtk_widget_destroy (view);
midori_browser_remove_tab (browser, view);
else
midori_browser_set_current_tab (browser, view);
}
else if (event->button == 2)
gtk_widget_destroy (view);
midori_browser_remove_tab (midori_browser_get_for_widget (widget), view);
else
tab_panel_popup (widget, event, view);
@ -534,11 +532,9 @@ tab_panel_app_add_browser_cb (MidoriApp* app,
treeview = gtk_tree_view_new_with_model (GTK_TREE_MODEL (model));
gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (treeview), FALSE);
gtk_tree_view_set_show_expanders (GTK_TREE_VIEW (treeview), FALSE);
#if GTK_CHECK_VERSION (2, 12, 0)
g_signal_connect (treeview, "query-tooltip",
G_CALLBACK (tab_panel_treeview_query_tooltip_cb), NULL);
gtk_widget_set_has_tooltip (treeview, TRUE);
#endif
column = gtk_tree_view_column_new ();
renderer_pixbuf = gtk_cell_renderer_pixbuf_new ();
gtk_tree_view_column_pack_start (column, renderer_pixbuf, FALSE);

View file

@ -46,8 +46,6 @@ static const GtkTargetEntry tb_editor_dnd_targets[] =
};
static const gint tb_editor_dnd_targets_len = G_N_ELEMENTS(tb_editor_dnd_targets);
static void tb_editor_browser_populate_tool_menu_cb(MidoriBrowser *browser, GtkWidget *menu, MidoriExtension *ext);
static void tb_editor_browser_populate_toolbar_menu_cb(MidoriBrowser *browser, GtkWidget *menu,
MidoriExtension *ext);
@ -58,7 +56,6 @@ static void tb_editor_deactivate_cb(MidoriExtension *extension, MidoriBrowser *b
{
MidoriApp *app = midori_extension_get_app(extension);
g_signal_handlers_disconnect_by_func(browser, tb_editor_browser_populate_tool_menu_cb, extension);
g_signal_handlers_disconnect_by_func(browser, tb_editor_browser_populate_toolbar_menu_cb, extension);
g_signal_handlers_disconnect_by_func(extension, tb_editor_deactivate_cb, browser);
g_signal_handlers_disconnect_by_func(app, tb_editor_app_add_browser_cb, extension);
@ -107,7 +104,12 @@ static GSList *tb_editor_array_to_list(const gchar **items)
name = items;
while (*name != NULL)
{
#ifdef HAVE_GRANITE
/* A "new tab" button is already part of the notebook */
if (*name[0] != '\0' && strcmp (*name, "TabNew"))
#else
if (*name[0] != '\0')
#endif
list = g_slist_append(list, g_strdup(*name));
name++;
}
@ -574,17 +576,6 @@ static void tb_editor_menu_configure_toolbar_activate_cb(GtkWidget *menuitem, Mi
g_free(tbw);
}
static void tb_editor_browser_populate_tool_menu_cb(MidoriBrowser *browser, GtkWidget *menu, MidoriExtension *ext)
{
GtkWidget *menuitem;
menuitem = gtk_menu_item_new_with_mnemonic (_("Customize _Toolbar..."));
g_signal_connect (menuitem, "activate",
G_CALLBACK (tb_editor_menu_configure_toolbar_activate_cb), browser);
gtk_widget_show (menuitem);
gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
}
static void tb_editor_browser_populate_toolbar_menu_cb(MidoriBrowser *browser, GtkWidget *menu,
MidoriExtension *ext)
{
@ -594,7 +585,7 @@ static void tb_editor_browser_populate_toolbar_menu_cb(MidoriBrowser *browser, G
separator = gtk_separator_menu_item_new ();
gtk_widget_show (separator);
gtk_menu_shell_append (GTK_MENU_SHELL (menu), separator);
menuitem = gtk_menu_item_new_with_mnemonic (_("_Customize..."));
menuitem = gtk_menu_item_new_with_mnemonic (_("_Customize Toolbar…"));
g_signal_connect (menuitem, "activate",
G_CALLBACK (tb_editor_menu_configure_toolbar_activate_cb), browser);
gtk_widget_show (menuitem);
@ -603,7 +594,6 @@ static void tb_editor_browser_populate_toolbar_menu_cb(MidoriBrowser *browser, G
static void tb_editor_app_add_browser_cb(MidoriApp *app, MidoriBrowser *browser, MidoriExtension *ext)
{
g_signal_connect(browser, "populate-tool-menu", G_CALLBACK(tb_editor_browser_populate_tool_menu_cb), ext);
g_signal_connect(browser, "populate-toolbar-menu", G_CALLBACK(tb_editor_browser_populate_toolbar_menu_cb), ext);
g_signal_connect(ext, "deactivate", G_CALLBACK(tb_editor_deactivate_cb), browser);
}

View file

@ -28,8 +28,7 @@ web_cache_get_cache_dir (void)
{
static gchar* cache_dir = NULL;
if (!cache_dir)
cache_dir = g_build_filename (g_get_user_cache_dir (),
PACKAGE_NAME, "web", NULL);
cache_dir = g_build_filename (midori_paths_get_cache_dir (), "web", NULL);
return cache_dir;
}

View file

@ -33,11 +33,11 @@ for extension in extensions:
obj = bld.new_task_gen ('cc', 'shlib')
obj.target = target
obj.includes = '..'
obj.includes = '.. ../katze ../midori'
obj.source = source
obj.uselib = 'UNIQUE LIBSOUP GIO GTK SQLITE WEBKIT LIBXML HILDON'
obj.vapi_dirs = '../midori ../katze'
obj.packages = 'glib-2.0 gio-2.0 libsoup-2.4 midori katze'
obj.packages = 'glib-2.0 gio-2.0 libsoup-2.4 midori midori-core katze'
if bld.env['HAVE_GTK3']:
obj.packages += ' gtk+-3.0 webkitgtk-3.0'
else:

View file

Before

Width:  |  Height:  |  Size: 832 B

After

Width:  |  Height:  |  Size: 832 B

View file

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

View file

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

View file

@ -41,4 +41,4 @@ def add_image (bld, category, name):
add_image (bld, 'categories', 'extension')
add_image (bld, 'apps', 'midori')
add_image (bld, 'status', 'news-feed')
add_image (bld, 'status', 'internet-news-reader')

View file

@ -71,17 +71,15 @@ gtk_entry_set_placeholder_text (GtkEntry* entry,
const gchar* default_text)
{
/* Note: The default text initially overwrites any previous text */
gchar* old_value = g_object_get_data (G_OBJECT (entry),
"sokoke_default_text");
g_object_set_data (G_OBJECT (entry), "sokoke_default_text",
(gpointer)default_text);
gchar* old_value = g_object_get_data (G_OBJECT (entry), "sokoke_default_text");
g_object_set_data (G_OBJECT (entry), "sokoke_default_text", (gpointer)default_text);
if (!old_value)
if (default_text == NULL)
g_object_set_data (G_OBJECT (entry), "sokoke_has_default", GINT_TO_POINTER (0));
else if (!old_value)
{
g_object_set_data (G_OBJECT (entry), "sokoke_has_default",
GINT_TO_POINTER (1));
sokoke_widget_set_pango_font_style (GTK_WIDGET (entry),
PANGO_STYLE_ITALIC);
g_object_set_data (G_OBJECT (entry), "sokoke_has_default", GINT_TO_POINTER (1));
sokoke_widget_set_pango_font_style (GTK_WIDGET (entry), PANGO_STYLE_ITALIC);
gtk_entry_set_text (entry, default_text);
g_signal_connect (entry, "drag-data-received",
G_CALLBACK (sokoke_on_entry_drag_data_received), NULL);
@ -92,13 +90,11 @@ gtk_entry_set_placeholder_text (GtkEntry* entry,
}
else if (!gtk_widget_has_focus (GTK_WIDGET (entry)))
{
gint has_default = GPOINTER_TO_INT (
g_object_get_data (G_OBJECT (entry), "sokoke_has_default"));
gint has_default = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (entry), "sokoke_has_default"));
if (has_default)
{
gtk_entry_set_text (entry, default_text);
sokoke_widget_set_pango_font_style (GTK_WIDGET (entry),
PANGO_STYLE_ITALIC);
sokoke_widget_set_pango_font_style (GTK_WIDGET (entry), PANGO_STYLE_ITALIC);
}
}
}
@ -110,41 +106,3 @@ gtk_entry_get_placeholder_text (GtkEntry* entry)
}
#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

View file

@ -39,25 +39,6 @@ G_BEGIN_DECLS
#define g_format_size(sz) g_format_size_for_display ((goffset)sz)
#endif
#if !GTK_CHECK_VERSION (2, 14, 0)
#define gtk_dialog_get_content_area(dlg) dlg->vbox
#define gtk_dialog_get_action_area(dlg) dlg->action_area
#define gtk_widget_get_window(wdgt) wdgt->window
#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
#endif
#if !GTK_CHECK_VERSION (2, 16, 0)
#define GTK_ACTIVATABLE GTK_WIDGET
#define gtk_activatable_get_related_action gtk_widget_get_action
#define gtk_menu_item_set_label(menuitem, label) \
gtk_label_set_label (GTK_LABEL (GTK_BIN (menuitem)->child), \
label ? label : "");
#define gtk_image_menu_item_set_always_show_image(menuitem, yesno) ()
#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)
@ -95,22 +76,6 @@ G_BEGIN_DECLS
const gchar* gtk_entry_get_placeholder_text (GtkEntry* entry);
#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
#if !GTK_CHECK_VERSION (2, 24 ,0)
#define gtk_combo_box_text_append_text gtk_combo_box_append_text
#define gtk_combo_box_text_new gtk_combo_box_new_text
@ -151,6 +116,10 @@ gtk_tool_item_set_tooltip_text (GtkToolItem* toolitem,
#define GDK_KEY_Return GDK_Return
#endif
#ifndef GDK_IS_X11_DISPLAY
#define GDK_IS_X11_DISPLAY(display) TRUE
#endif
G_END_DECLS
#endif

View file

@ -404,8 +404,13 @@ katze_array_find_token (KatzeArray* array,
for (items = array->items; items; items = g_list_next (items))
{
const gchar* found_token = ((KatzeItem*)items->data)->token;
if (found_token != NULL && !strncmp (token, found_token, token_length))
return items->data;
if (found_token != NULL)
{
guint bigger_item = strlen (found_token) > token_length ? strlen (found_token) : token_length;
if (strncmp (token, found_token, bigger_item) == 0)
return items->data;
}
}
return NULL;
}

View file

@ -207,7 +207,7 @@ katze_http_cookies_sqlite_jar_changed_cb (SoupCookieJar* jar,
}
}
if (g_getenv ("MIDORI_COOKIES_DEBUG") != NULL)
if (!g_strcmp0 (g_getenv ("MIDORI_DEBUG"), "cookies"))
http_cookies->counter++;
if (old_cookie) {

View file

@ -211,7 +211,7 @@ katze_http_cookies_update_jar (KatzeHttpCookies* http_cookies)
goto failed;
g_free (temporary_filename);
if (g_getenv ("MIDORI_COOKIES_DEBUG") != NULL)
if (!g_strcmp0 (g_getenv ("MIDORI_DEBUG"), "cookies"))
{
g_print ("KatzeHttpCookies: %d cookies changed\n", http_cookies->counter);
http_cookies->counter = 0;
@ -223,7 +223,7 @@ failed:
fclose (f);
g_unlink (temporary_filename);
g_free (temporary_filename);
if (g_getenv ("MIDORI_COOKIES_DEBUG") != NULL)
if (!g_strcmp0 (g_getenv ("MIDORI_DEBUG"), "cookies"))
g_print ("KatzeHttpCookies: Failed to write '%s'\n",
http_cookies->filename);
return FALSE;
@ -263,7 +263,7 @@ katze_http_cookies_jar_changed_cb (SoupCookieJar* jar,
}
}
if (g_getenv ("MIDORI_COOKIES_DEBUG") != NULL)
if (!g_strcmp0 (g_getenv ("MIDORI_DEBUG"), "cookies"))
http_cookies->counter++;
if (!http_cookies->timeout && (old_cookie || new_cookie->expires))

View file

@ -27,9 +27,6 @@
struct _KatzeNet
{
GObject parent_instance;
gchar* cache_path;
guint cache_size;
};
struct _KatzeNetClass
@ -54,37 +51,14 @@ katze_net_class_init (KatzeNetClass* class)
static void
katze_net_init (KatzeNet* net)
{
net->cache_path = g_build_filename (g_get_user_cache_dir (),
PACKAGE_NAME, NULL);
}
static void
katze_net_finalize (GObject* object)
{
KatzeNet* net = KATZE_NET (object);
katze_assign (net->cache_path, NULL);
G_OBJECT_CLASS (katze_net_parent_class)->finalize (object);
}
static KatzeNet*
katze_net_new (void)
{
static KatzeNet* net = NULL;
if (!net)
{
net = g_object_new (KATZE_TYPE_NET, NULL);
/* Since this is a "singleton", keep an extra reference */
g_object_ref (net);
}
else
g_object_ref (net);
return net;
}
typedef struct
{
KatzeNetStatusCb status_cb;
@ -109,29 +83,28 @@ katze_net_get_cached_path (KatzeNet* net,
const gchar* uri,
const gchar* subfolder)
{
gchar* cache_path;
gchar* checksum;
gchar* extension;
gchar* cached_filename;
gchar* cached_path;
net = katze_net_new ();
if (subfolder)
cache_path = g_build_filename (net->cache_path, subfolder, NULL);
else
cache_path = net->cache_path;
katze_mkdir_with_parents (cache_path, 0700);
checksum = g_compute_checksum_for_string (G_CHECKSUM_MD5, uri, -1);
extension = g_strrstr (uri, ".");
cached_filename = g_strdup_printf ("%s%s", checksum,
extension ? extension : "");
g_free (checksum);
cached_path = g_build_filename (cache_path, cached_filename, NULL);
g_free (cached_filename);
if (subfolder)
{
gchar* cache_path = g_build_filename (midori_paths_get_cache_dir (), subfolder, NULL);
katze_mkdir_with_parents (cache_path, 0700);
cached_path = g_build_filename (cache_path, cached_filename, NULL);
g_free (cache_path);
}
else
cached_path = g_build_filename (midori_paths_get_cache_dir (), cached_filename, NULL);
g_free (cached_filename);
return cached_path;
}

View file

@ -14,8 +14,6 @@
#include "katze-utils.h"
#include <gtk/gtk.h>
G_BEGIN_DECLS
#define KATZE_TYPE_NET \

View file

@ -15,6 +15,13 @@
#include <config.h>
#endif
#ifdef HAVE_GRANITE
#if HAVE_OSX
#error FIXME granite on OSX is not implemented
#endif
#include <granite.h>
#endif
#if HAVE_HILDON
#include "katze-scrolled.h"
#include <hildon/hildon.h>
@ -103,11 +110,8 @@ katze_preferences_init (KatzePreferences* preferences)
gtk_dialog_add_buttons (GTK_DIALOG (preferences),
GTK_STOCK_HELP, GTK_RESPONSE_HELP,
NULL);
#if GTK_CHECK_VERSION (3, 0, 0)
gtk_style_context_add_class (gtk_widget_get_style_context (
gtk_dialog_get_widget_for_response (GTK_DIALOG (preferences),
GTK_RESPONSE_HELP)), "help_button");
#endif
katze_widget_add_class (gtk_dialog_get_widget_for_response (
GTK_DIALOG (preferences), GTK_RESPONSE_HELP), "help_button");
gtk_dialog_add_buttons (GTK_DIALOG (preferences),
#if HAVE_HILDON
@ -202,7 +206,12 @@ katze_preferences_prepare (KatzePreferences* preferences)
g_signal_connect (priv->scrolled, "destroy",
G_CALLBACK (gtk_widget_destroyed), &priv->scrolled);
#else
#ifdef HAVE_GRANITE
/* FIXME: granite: should return GtkWidget* like GTK+ */
priv->notebook = (GtkWidget*)granite_widgets_static_notebook_new (FALSE);
#else
priv->notebook = gtk_notebook_new ();
#endif
gtk_container_set_border_width (GTK_CONTAINER (priv->notebook), 6);
#if HAVE_OSX
@ -296,8 +305,14 @@ katze_preferences_add_category (KatzePreferences* preferences,
priv->sizegroup = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
gtk_widget_show (priv->page);
gtk_container_set_border_width (GTK_CONTAINER (priv->page), 4);
#ifdef HAVE_GRANITE
granite_widgets_static_notebook_append_page (
GRANITE_WIDGETS_STATIC_NOTEBOOK (priv->notebook),
priv->page, GTK_LABEL (gtk_label_new (label)));
#else
gtk_notebook_append_page (GTK_NOTEBOOK (priv->notebook),
priv->page, gtk_label_new (label));
#endif
#if HAVE_OSX
priv->toolbutton = GTK_WIDGET (priv->toolbutton ?
gtk_radio_tool_button_new_from_widget (

View file

@ -277,7 +277,6 @@ proxy_combo_box_changed_cb (GtkComboBox* button,
if (custom_value)
{
#if GTK_CHECK_VERSION (2, 12, 0)
if (value == custom_value)
gtk_widget_set_tooltip_text (GTK_WIDGET (button), NULL);
else
@ -286,7 +285,6 @@ proxy_combo_box_changed_cb (GtkComboBox* button,
gtk_widget_set_tooltip_text (GTK_WIDGET (button), custom_text);
g_free (custom_text);
}
#endif
}
}
#endif
@ -523,14 +521,8 @@ katze_property_proxy (gpointer object,
string = g_strdup (G_PARAM_SPEC_STRING (pspec)->default_value);
gtk_file_chooser_set_uri (GTK_FILE_CHOOSER (widget),
string ? string : "");
#if GTK_CHECK_VERSION (2, 12, 0)
g_signal_connect (widget, "file-set",
G_CALLBACK (proxy_uri_file_set_cb), object);
#else
if (pspec->flags & G_PARAM_WRITABLE)
g_signal_connect (widget, "selection-changed",
G_CALLBACK (proxy_uri_file_set_cb), object);
#endif
}
else if (type == G_TYPE_PARAM_STRING && (_hint == I_("font")
|| _hint == I_("font-monospace")))
@ -818,11 +810,10 @@ katze_property_proxy (gpointer object,
G_CALLBACK (proxy_entry_focus_out_event_cb), object);
g_object_set_data_full (G_OBJECT (entry), "property",
g_strdup (custom), g_free);
gtk_widget_set_tooltip_text (widget, NULL);
}
#if GTK_CHECK_VERSION (2, 12, 0)
else
gtk_widget_set_tooltip_text (widget, custom_text);
#endif
g_free (custom_text);
@ -837,10 +828,6 @@ katze_property_proxy (gpointer object,
widget = gtk_label_new (gettext (nick));
g_free (string);
#if GTK_CHECK_VERSION (2, 12, 0)
if (!gtk_widget_get_tooltip_text (widget))
gtk_widget_set_tooltip_text (widget, g_param_spec_get_blurb (pspec));
#endif
gtk_widget_set_sensitive (widget, pspec->flags & G_PARAM_WRITABLE);
g_object_set_data_full (G_OBJECT (widget), "property",
@ -881,16 +868,8 @@ katze_property_label (gpointer object,
return gtk_label_new (property);
}
#ifdef HAVE_HILDON_2_2
if (G_PARAM_SPEC_TYPE (pspec) == G_TYPE_PARAM_ENUM)
return gtk_label_new (NULL);
#endif
nick = g_param_spec_get_nick (pspec);
widget = gtk_label_new (nick);
#if GTK_CHECK_VERSION (2, 12, 0)
gtk_widget_set_tooltip_text (widget, g_param_spec_get_blurb (pspec));
#endif
gtk_misc_set_alignment (GTK_MISC (widget), 0.0, 0.5);
return widget;
@ -1523,8 +1502,7 @@ katze_load_cached_icon (const gchar* 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);
path = g_build_filename (midori_paths_get_cache_dir (), "icons", filename, NULL);
g_free (filename);
if ((icon = gdk_pixbuf_new_from_file_at_size (path, 16, 16, NULL)))
{
@ -1546,6 +1524,13 @@ katze_uri_entry_changed_cb (GtkWidget* entry,
gboolean valid = midori_uri_is_location (uri);
if (!valid && g_object_get_data (G_OBJECT (entry), "allow_%s"))
valid = uri && g_str_has_prefix (uri, "%s");
if (!valid)
valid = midori_uri_is_ip_address (uri);
#if GTK_CHECK_VERSION (3, 2, 0)
g_object_set_data (G_OBJECT (entry), "invalid", GINT_TO_POINTER (*uri && !valid));
gtk_widget_queue_draw (entry);
#else
if (*uri && !valid)
{
GdkColor bg_color = { 0 };
@ -1560,11 +1545,34 @@ katze_uri_entry_changed_cb (GtkWidget* entry,
gtk_widget_modify_base (entry, GTK_STATE_NORMAL, NULL);
gtk_widget_modify_text (entry, GTK_STATE_NORMAL, NULL);
}
#endif
if (other_widget != NULL)
gtk_widget_set_sensitive (other_widget, valid);
}
#if GTK_CHECK_VERSION (3, 2, 0)
static gboolean
katze_uri_entry_draw_cb (GtkWidget* entry,
cairo_t* cr,
GtkWidget* other_widget)
{
const GdkRGBA color = { 0.9, 0., 0., 1. };
double width = gtk_widget_get_allocated_width (entry);
double height = gtk_widget_get_allocated_height (entry);
if (!g_object_get_data (G_OBJECT (entry), "invalid"))
return FALSE;
/* FIXME: error-underline-color requires GtkTextView */
gdk_cairo_set_source_rgba (cr, &color);
pango_cairo_show_error_underline (cr, width * 0.15, height / 1.9,
width * 0.75, height / 1.9 / 2);
return TRUE;
}
#endif
/**
* katze_uri_entry_new:
* @other_widget: a #GtkWidget, or %NULL
@ -1582,11 +1590,28 @@ GtkWidget*
katze_uri_entry_new (GtkWidget* other_widget)
{
GtkWidget* entry = gtk_entry_new ();
gtk_entry_set_icon_from_gicon (GTK_ENTRY (entry), GTK_ENTRY_ICON_PRIMARY,
g_themed_icon_new_with_default_fallbacks ("text-html-symbolic"));
g_signal_connect (entry, "changed",
G_CALLBACK (katze_uri_entry_changed_cb), other_widget);
#if GTK_CHECK_VERSION (3, 2, 0)
g_signal_connect_after (entry, "draw",
G_CALLBACK (katze_uri_entry_draw_cb), other_widget);
#endif
return entry;
}
void
katze_widget_add_class (GtkWidget* widget,
const gchar* class_name)
{
#if GTK_CHECK_VERSION (3,0,0)
GtkStyleContext* context = gtk_widget_get_style_context (widget);
gtk_style_context_add_class (context, class_name);
#endif
}
/**
* katze_assert_str_equal:
* @input: a string

View file

@ -160,6 +160,10 @@ katze_load_cached_icon (const gchar* uri,
GtkWidget*
katze_uri_entry_new (GtkWidget* other_widget);
void
katze_widget_add_class (GtkWidget* widget,
const gchar* class_name);
void
katze_assert_str_equal (const gchar* input,
const gchar* result,

View file

@ -3,9 +3,23 @@
[CCode (cprefix = "Katze", lower_case_cprefix = "katze_")]
namespace Katze {
public class Array : GLib.Object {
static string assert_str_equal (string input, string result, string expected);
[CCode (cheader_filename = "katze/katze.h")]
public class Array : Katze.Item {
public Array (GLib.Type type);
public void add_item (GLib.Object item);
}
[CCode (cheader_filename = "katze/katze.h")]
public class Item : GLib.Object {
public string? uri { get; set; }
public string? name { get; set; }
public string? text { get; set; }
public bool get_meta_boolean (string key);
public int64 get_meta_integer (string key);
public void set_meta_integer (string key, int64 value);
}
}

143
katze/midori-hsts.vala Normal file
View file

@ -0,0 +1,143 @@
/*
Copyright (C) 2012 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.
*/
namespace Midori {
public class HSTS : GLib.Object, Soup.SessionFeature {
public class Directive {
public Soup.Date? expires = null;
public bool sub_domains = false;
public Directive (bool include_sub_domains) {
expires = new Soup.Date.from_now (int.MAX);
sub_domains = include_sub_domains;
}
public Directive.from_header (string header) {
var param_list = Soup.header_parse_param_list (header);
if (param_list == null)
return;
string? max_age = param_list.lookup ("max-age");
if (max_age != null)
expires = new Soup.Date.from_now (max_age.to_int ());
// if (param_list.lookup_extended ("includeSubDomains", null, null))
if ("includeSubDomains" in header)
sub_domains = true;
Soup.header_free_param_list (param_list);
}
public bool is_valid () {
return expires != null && !expires.is_past ();
}
}
File file;
HashTable<string, Directive> whitelist;
bool debug = false;
public HSTS (owned string filename) {
whitelist = new HashTable<string, Directive> (str_hash, str_equal);
read_cache (File.new_for_path (Paths.get_preset_filename (null, "hsts")));
file = File.new_for_path (filename);
read_cache (file);
if (strcmp (Environment.get_variable ("MIDORI_DEBUG"), "hsts") == 0)
debug = true;
}
async void read_cache (File file) {
try {
var stream = new DataInputStream (yield file.read_async ());
do {
string? line = yield stream.read_line_async ();
if (line == null)
break;
string[] parts = line.split (" ", 2);
if (parts[0] == null || parts[1] == null)
break;
var directive = new Directive.from_header (parts[1]);
if (directive.is_valid ())
append_to_whitelist (parts[0], directive);
} while (true);
}
catch (Error error) { }
}
/* No sub-features */
public bool add_feature (Type type) { return false; }
public bool remove_feature (Type type) { return false; }
public bool has_feature (Type type) { return false; }
public void attach (Soup.Session session) { session.request_queued.connect (queued); }
public void detach (Soup.Session session) { /* FIXME disconnect */ }
/* Never called but required by the interface */
public void request_started (Soup.Session session, Soup.Message msg, Soup.Socket socket) { }
public void request_queued (Soup.Session session, Soup.Message message) { }
public void request_unqueued (Soup.Session session, Soup.Message msg) { }
bool should_secure_host (string host) {
Directive? directive = whitelist.lookup (host);
if (directive == null)
directive = whitelist.lookup ("*." + host);
return directive != null && directive.is_valid ();
}
void queued (Soup.Session session, Soup.Message message) {
if (should_secure_host (message.uri.host)) {
message.uri.set_scheme ("https");
session.requeue_message (message);
if (debug)
stdout.printf ("HSTS: Enforce %s\n", message.uri.host);
}
else if (message.uri.scheme == "http")
message.finished.connect (strict_transport_security_handled);
}
void append_to_whitelist (string host, Directive directive) {
whitelist.insert (host, directive);
if (directive.sub_domains)
whitelist.insert ("*." + host, directive);
}
async void append_to_cache (string host, string header) {
if (Midori.Paths.is_readonly ())
return;
try {
var stream = file.append_to/* FIXME _async*/ (FileCreateFlags.NONE);
yield stream.write_async ((host + " " + header + "\n").data);
yield stream.flush_async ();
}
catch (Error error) {
critical ("Failed to update %s: %s", file.get_path (), error.message);
}
}
void strict_transport_security_handled (Soup.Message message) {
if (message == null || message.uri == null)
return;
unowned string? hsts = message.response_headers.get_one ("Strict-Transport-Security");
if (hsts == null)
return;
var directive = new Directive.from_header (hsts);
if (directive.is_valid ()) {
append_to_whitelist (message.uri.host, directive);
append_to_cache (message.uri.host, hsts);
}
if (debug)
stdout.printf ("HSTS: '%s' sets '%s' valid? %s\n",
message.uri.host, hsts, directive.is_valid ().to_string ());
}
}
}

244
katze/midori-paths.vala Normal file
View file

@ -0,0 +1,244 @@
/*
Copyright (C) 2012 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.
*/
namespace GLib {
#if HAVE_WIN32
extern static string win32_get_package_installation_directory_of_module (void* hmodule = null);
#endif
}
extern const string LIBDIR;
extern const string MDATADIR;
extern const string PACKAGE_NAME;
extern const string SYSCONFDIR;
extern const string MIDORI_VERSION_SUFFIX;
namespace Midori {
public enum RuntimeMode {
UNDEFINED,
NORMAL,
APP,
PRIVATE,
PORTABLE
}
namespace Paths {
static string? exec_path = null;
static string[] command_line = null;
static RuntimeMode mode = RuntimeMode.UNDEFINED;
static string? config_dir = null;
static string? readonly_dir = null;
static string? cache_dir = null;
static string? user_data_dir = null;
static string? tmp_dir = null;
public static string get_readonly_config_dir () {
assert (mode != RuntimeMode.UNDEFINED);
return readonly_dir ?? config_dir;
}
public static string get_readonly_config_filename (string filename) {
assert (mode != RuntimeMode.UNDEFINED);
return Path.build_path (Path.DIR_SEPARATOR_S,
readonly_dir ?? config_dir, filename);
}
public bool is_readonly () {
assert (mode != RuntimeMode.UNDEFINED);
return readonly_dir != null;
}
public static void init (RuntimeMode new_mode, string? config_base) {
assert (mode == RuntimeMode.UNDEFINED);
assert (new_mode != RuntimeMode.UNDEFINED);
mode = new_mode;
if (mode == RuntimeMode.PORTABLE) {
config_dir = Path.build_path (Path.DIR_SEPARATOR_S,
exec_path, "profile", "config");
cache_dir = Path.build_path (Path.DIR_SEPARATOR_S,
exec_path, "profile", "cache");
user_data_dir = Path.build_path (Path.DIR_SEPARATOR_S,
exec_path, "profile", "misc");
tmp_dir = Path.build_path (Path.DIR_SEPARATOR_S,
exec_path, "profile", "tmp");
}
else if (mode == RuntimeMode.PRIVATE || mode == RuntimeMode.APP) {
/* Use mock folders in development builds */
if ("." in MIDORI_VERSION_SUFFIX)
config_dir = cache_dir = user_data_dir = config_base;
else
config_dir = cache_dir = user_data_dir = "/";
readonly_dir = config_base ?? Path.build_path (Path.DIR_SEPARATOR_S,
Environment.get_user_config_dir (), PACKAGE_NAME);
tmp_dir = Path.build_path (Path.DIR_SEPARATOR_S,
Environment.get_tmp_dir (), "midori-" + Environment.get_user_name ());
}
else {
config_dir = config_base ?? Path.build_path (Path.DIR_SEPARATOR_S,
Environment.get_user_config_dir (), PACKAGE_NAME);
cache_dir = Path.build_path (Path.DIR_SEPARATOR_S,
Environment.get_user_cache_dir (), PACKAGE_NAME);
user_data_dir = Environment.get_user_data_dir ();
tmp_dir = Path.build_path (Path.DIR_SEPARATOR_S,
Environment.get_tmp_dir (), "midori-" + Environment.get_user_name ());
}
if (strcmp (Environment.get_variable ("MIDORI_DEBUG"), "paths") == 0) {
stdout.printf ("config: %s\ncache: %s\nuser_data: %s\ntmp: %s\n",
config_dir, cache_dir, user_data_dir, tmp_dir);
}
}
public static unowned string get_config_dir () {
assert (config_dir != null);
return config_dir;
}
public static string get_config_filename (string filename) {
assert (mode != RuntimeMode.UNDEFINED);
assert (config_dir != null);
return Path.build_path (Path.DIR_SEPARATOR_S, config_dir, filename);
}
public static unowned string get_cache_dir () {
assert (cache_dir != null);
return cache_dir;
}
public static unowned string get_user_data_dir () {
assert (user_data_dir != null);
return user_data_dir;
}
public static unowned string get_tmp_dir () {
assert (tmp_dir != null);
return tmp_dir;
}
public static void init_exec_path (string[] new_command_line) {
assert (command_line == null);
command_line = new_command_line;
#if HAVE_WIN32
exec_path = win32_get_package_installation_directory_of_module ();
#else
string? executable;
try {
if (!Path.is_absolute (command_line[0])) {
string program = Environment.find_program_in_path (command_line[0]);
if (FileUtils.test (program, FileTest.IS_SYMLINK))
executable = FileUtils.read_link (program);
else
executable = program;
}
else
executable = FileUtils.read_link (command_line[0]);
}
catch (Error error) {
executable = command_line[0];
}
exec_path = File.new_for_path (executable).get_parent ().get_parent ().get_path ();
#endif
if (strcmp (Environment.get_variable ("MIDORI_DEBUG"), "paths") == 0) {
stdout.printf ("command_line: %s\nexec_path: %s\nres: %s\nlib: %s\n",
get_command_line_str (), exec_path,
get_res_filename (""), get_lib_path (PACKAGE_NAME));
}
}
public static unowned string[] get_command_line () {
assert (command_line != null);
return command_line;
}
public static string get_command_line_str () {
assert (command_line != null);
return "".joinv (" ", command_line).replace (Environment.get_home_dir (), "~");
}
public static string get_lib_path (string package) {
assert (command_line != null);
#if HAVE_WIN32
return Path.build_filename (exec_path, "lib", package);
#else
string path = Path.build_filename (exec_path, "lib", package);
if (Posix.access (path, Posix.F_OK) == 0)
return path;
if (package == PACKAGE_NAME) {
/* Fallback to build folder */
path = Path.build_filename ((File.new_for_path (exec_path).get_path ()), "extensions");
if (Posix.access (path, Posix.F_OK) == 0)
return path;
}
return Path.build_filename (LIBDIR, PACKAGE_NAME);
#endif
}
public static string get_res_filename (string filename) {
assert (command_line != null);
#if HAVE_WIN32
return Path.build_filename (exec_path, "share", PACKAGE_NAME, "res", filename);
#else
string path = Path.build_filename (exec_path, "share", PACKAGE_NAME, "res", filename);
if (Posix.access (path, Posix.F_OK) == 0)
return path;
/* Fallback to build folder */
path = Path.build_filename ((File.new_for_path (exec_path)
.get_parent ().get_parent ().get_path ()), "data", filename);
if (Posix.access (path, Posix.F_OK) == 0)
return path;
return Path.build_filename (MDATADIR, PACKAGE_NAME, "res", filename);
#endif
}
public static string get_data_filename (string filename, bool res) {
assert (command_line != null);
string res1 = res ? PACKAGE_NAME : "";
string res2 = res ? "res" : "";
#if HAVE_WIN32
return Path.build_filename (exec_path, "share", res1, res2, filename);
#else
string path = Path.build_filename (get_user_data_dir (), res1, res2, filename);
if (Posix.access (path, Posix.F_OK) == 0)
return path;
foreach (string data_dir in Environment.get_system_data_dirs ()) {
path = Path.build_filename (data_dir, res1, res2, filename);
if (Posix.access (path, Posix.F_OK) == 0)
return path;
}
return Path.build_filename (MDATADIR, res1, res2, filename);
#endif
}
public static string get_preset_filename (string? folder, string filename) {
assert (config_dir != null);
#if HAVE_WIN32
return Path.build_filename (exec_path, "etc", "xdg", PACKAGE_NAME, folder ?? "", filename);
#else
foreach (string config_dir in Environment.get_system_config_dirs ()) {
string path = Path.build_filename (config_dir, PACKAGE_NAME, folder ?? "", filename);
if (Posix.access (path, Posix.F_OK) == 0)
return path;
}
return Path.build_filename (SYSCONFDIR, "xdg", PACKAGE_NAME, folder ?? "", filename);
#endif
}
}
}

View file

@ -114,12 +114,7 @@ namespace Midori {
|| (uri.has_prefix ("geo:") && uri.chr (-1, ',') != null)
|| uri.has_prefix ("javascript:"));
}
public static bool is_email (string? uri) {
return uri != null
&& (uri.chr (-1, '@') != null || uri.has_prefix ("mailto:"))
/* :// and @ together would mean login credentials */
&& uri.str ("://") == null;
}
public static bool is_ip_address (string? uri) {
/* Quick check for IPv4 or IPv6, no validation.
FIXME: Schemes are not handled
@ -127,8 +122,11 @@ namespace Midori {
we'd have to separate the path from the URI first. */
if (uri == null)
return false;
/* Skip leading user/ password */
if (uri.chr (-1, '@') != null)
return is_ip_address (uri.split ("@")[1]);
/* IPv4 */
if (uri[0].isdigit () && (uri.chr (4, '.') != null))
if (uri[0] != '0' && uri[0].isdigit () && (uri.chr (4, '.') != null))
return true;
/* IPv6 */
if (uri[0].isalnum () && uri[1].isalnum ()
@ -142,25 +140,44 @@ namespace Midori {
&& uri.chr (-1, ' ') == null
&& (URI.is_location (uri) || uri.chr (-1, '.') != null);
}
public static string? get_folder (string uri) {
/* Base the start folder on the current view's uri if it is local */
try {
string? filename = Filename.from_uri (uri);
if (filename != null) {
string? dirname = Path.get_dirname (filename);
if (dirname != null && FileUtils.test (dirname, FileTest.IS_DIR))
return dirname;
}
}
catch (Error error) { }
return null;
}
public static GLib.ChecksumType get_fingerprint (string uri,
out string checksum, out string label) {
/* http://foo.bar/baz/spam.eggs#!algo!123456 */
unowned string display = null;
GLib.ChecksumType type = (GLib.ChecksumType)int.MAX;
unowned string delimiter = "#!md5!";
unowned string display = _("MD5-Checksum:");
GLib.ChecksumType type = GLib.ChecksumType.MD5;
unowned string? fragment = uri.str (delimiter);
if (fragment == null) {
delimiter = "#!sha1!";
if (fragment != null) {
display = _("MD5-Checksum:");
type = GLib.ChecksumType.MD5;
}
delimiter = "#!sha1!";
fragment = uri.str (delimiter);
if (fragment != null) {
display = _("SHA1-Checksum:");
type = GLib.ChecksumType.SHA1;
fragment = uri.str (delimiter);
}
if (fragment == null) {
type = (GLib.ChecksumType)int.MAX;
display = null;
}
/* No SHA256: no known usage and no need for strong encryption */
if (&checksum != null)
checksum = fragment != null
? fragment.offset (delimiter.length) : null;

File diff suppressed because it is too large Load diff

View file

@ -26,7 +26,6 @@
G_BEGIN_DECLS
#if GTK_CHECK_VERSION (2, 16, 0)
#define GtkIconEntry GtkEntry
#define GtkIconEntryPosition GtkEntryIconPosition
#define GTK_ICON_ENTRY_PRIMARY GTK_ENTRY_ICON_PRIMARY
@ -42,99 +41,9 @@ G_BEGIN_DECLS
GtkEntryIconPosition position,
GdkPixbuf* pixbuf);
#define gtk_icon_entry_set_tooltip gtk_entry_set_icon_tooltip_text
#define gtk_icon_entry_get_tooltip gtk_entry_get_icon_tooltip_text
#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())
#define GTK_ICON_ENTRY(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GTK_TYPE_ICON_ENTRY, GtkIconEntry))
#define GTK_ICON_ENTRY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), GTK_TYPE_ICON_ENTRY, GtkIconEntryClass))
#define GTK_IS_ICON_ENTRY(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), GTK_TYPE_ICON_ENTRY))
#define GTK_IS_ICON_ENTRY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), GTK_TYPE_ICON_ENTRY))
#define GTK_ICON_ENTRY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_ICON_ENTRY, GtkIconEntryClass))
typedef enum
{
GTK_ICON_ENTRY_PRIMARY,
GTK_ICON_ENTRY_SECONDARY
} GtkIconEntryPosition;
typedef struct _GtkIconEntry GtkIconEntry;
typedef struct _GtkIconEntryClass GtkIconEntryClass;
typedef struct _GtkIconEntryPrivate GtkIconEntryPrivate;
struct _GtkIconEntry
{
GtkEntry parent_object;
GtkIconEntryPrivate* priv;
};
struct _GtkIconEntryClass
{
GtkEntryClass parent_class;
/* Signals */
void (*icon_pressed) (GtkIconEntry *entry,
GtkIconEntryPosition icon_pos,
int button);
void (*icon_released) (GtkIconEntry *entry,
GtkIconEntryPosition icon_pos,
int button);
void (*gtk_reserved1) (void);
void (*gtk_reserved2) (void);
void (*gtk_reserved3) (void);
void (*gtk_reserved4) (void);
};
GType gtk_icon_entry_get_type (void) G_GNUC_CONST;
GtkWidget* gtk_icon_entry_new (void);
void gtk_icon_entry_set_icon_from_pixbuf (GtkIconEntry *entry,
GtkIconEntryPosition icon_pos,
GdkPixbuf *pixbuf);
void gtk_icon_entry_set_icon_from_stock (GtkIconEntry *entry,
GtkIconEntryPosition icon_pos,
const gchar *stock_id);
void gtk_icon_entry_set_icon_from_icon_name (GtkIconEntry *entry,
GtkIconEntryPosition icon_pos,
const gchar *icon_name);
void gtk_icon_entry_set_icon_from_gicon (const GtkIconEntry *entry,
GtkIconEntryPosition icon_pos,
GIcon *icon);
GdkPixbuf* gtk_icon_entry_get_pixbuf (const GtkIconEntry *entry,
GtkIconEntryPosition icon_pos);
GIcon* gtk_icon_entry_get_gicon (const GtkIconEntry *entry,
GtkIconEntryPosition icon_pos);
void gtk_icon_entry_set_icon_highlight (const GtkIconEntry *entry,
GtkIconEntryPosition icon_pos,
gboolean highlight);
gboolean gtk_icon_entry_get_icon_highlight (const GtkIconEntry *entry,
GtkIconEntryPosition icon_pos);
void gtk_icon_entry_set_cursor (const GtkIconEntry *icon_entry,
GtkIconEntryPosition icon_pos,
GdkCursorType cursor_type);
void gtk_icon_entry_set_tooltip (const GtkIconEntry *icon_entry,
GtkIconEntryPosition icon_pos,
const gchar *text);
void gtk_icon_entry_set_icon_sensitive (const GtkIconEntry *icon_entry,
GtkIconEntryPosition icon_pos,
gboolean sensitive);
void gtk_icon_entry_set_progress_fraction (GtkIconEntry *icon_entry,
gdouble fraction);
#endif
G_END_DECLS

File diff suppressed because it is too large Load diff

View file

@ -6,6 +6,7 @@ OBJECT:OBJECT
VOID:BOOLEAN,STRING
VOID:OBJECT,ENUM,BOOLEAN
VOID:OBJECT,INT,INT
VOID:OBJECT,OBJECT
VOID:POINTER,INT
VOID:STRING,BOOLEAN
VOID:STRING,INT,STRING

View file

@ -21,9 +21,11 @@
#include "midori-app.h"
#include "midori-platform.h"
#include "midori-core.h"
#include <string.h>
#include <gtk/gtk.h>
#include <glib/gstdio.h>
#include <glib/gi18n.h>
#if ENABLE_NLS
@ -227,6 +229,32 @@ _midori_app_add_browser (MidoriApp* app,
katze_array_add_item (app->browsers, browser);
#if GTK_CHECK_VERSION (3, 0, 0)
if (app->browser == NULL)
{
gchar* filename;
if ((filename = midori_paths_get_res_filename ("gtk3.css")))
{
GtkCssProvider* css_provider = gtk_css_provider_new ();
GError* error = NULL;
gtk_css_provider_load_from_path (css_provider, filename, &error);
if (error == NULL)
{
gtk_style_context_add_provider_for_screen (
gtk_widget_get_screen (GTK_WIDGET (browser)),
GTK_STYLE_PROVIDER (css_provider),
GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
}
else
{
g_warning ("Failed to load \"%s\": %s", filename, error->message);
g_error_free (error);
}
g_free (filename);
}
}
#endif
app->browser = browser;
#if HAVE_UNIQUE
/* We *do not* let unique watch windows because that includes
@ -723,7 +751,7 @@ midori_app_create_instance (MidoriApp* app)
{
#if HAVE_UNIQUE
const gchar* config = sokoke_set_config_dir (NULL);
const gchar* config = midori_paths_get_config_dir ();
gchar* name_hash;
name_hash = g_compute_checksum_for_string (G_CHECKSUM_MD5, config, -1);
katze_assign (app_name, g_strconcat ("midori", "_", name_hash, NULL));
@ -754,7 +782,7 @@ midori_app_create_instance (MidoriApp* app)
g_signal_connect (instance, "message-received",
G_CALLBACK (midori_browser_message_received_cb), app);
#else
instance = socket_init (instance_name, sokoke_set_config_dir (NULL), &exists);
instance = socket_init (instance_name, midori_paths_get_config_dir (), &exists);
g_object_set_data (G_OBJECT (app), "sock-exists",
exists ? (gpointer)0xdeadbeef : NULL);
if (instance != MidoriAppInstanceNull)
@ -1117,7 +1145,19 @@ midori_app_send_command (MidoriApp* app,
/* g_return_val_if_fail (MIDORI_IS_APP (app), FALSE); */
g_return_val_if_fail (command != NULL, FALSE);
if (!midori_app_instance_is_running (app))
if (midori_app_instance_is_running (app))
{
MidoriBrowser* browser = midori_browser_new ();
int i;
for (i=0; command && command[i]; i++)
{
gboolean action_known = (gtk_action_group_get_action (midori_browser_get_action_group (browser), command[i]) != NULL);
if (!action_known)
g_warning (_("Unexpected action '%s'."), command[i]);
}
gtk_widget_destroy (GTK_WIDGET (browser));
}
else
return midori_app_command_received (app, "command", command, NULL);
#if HAVE_HILDON
@ -1310,146 +1350,39 @@ midori_app_send_notification (MidoriApp* app,
*
* Since: 0.4.2
**/
void
midori_app_setup (gchar** argument_vector)
gboolean
midori_app_setup (gint *argc,
gchar** *argument_vector,
const GOptionEntry *entries,
GError* *error)
{
GtkIconSource* icon_source;
GtkIconSet* icon_set;
GtkIconFactory* factory;
gsize i;
gboolean success;
typedef struct
static GtkStockItem items[] =
{
const gchar* stock_id;
const gchar* label;
GdkModifierType modifier;
guint keyval;
const gchar* fallback;
} FatStockItem;
static FatStockItem items[] =
{
{ STOCK_EXTENSION, NULL, 0, 0, GTK_STOCK_CONVERT },
{ STOCK_IMAGE, NULL, 0, 0, GTK_STOCK_ORIENTATION_PORTRAIT },
{ STOCK_WEB_BROWSER, NULL, 0, 0, "gnome-web-browser" },
{ STOCK_NEWS_FEED, NULL, 0, 0, GTK_STOCK_INDEX },
{ STOCK_SCRIPT, NULL, 0, 0, GTK_STOCK_EXECUTE },
{ STOCK_STYLE, NULL, 0, 0, GTK_STOCK_SELECT_COLOR },
{ STOCK_TRANSFER, NULL, 0, 0, GTK_STOCK_SAVE },
{ STOCK_IMAGE },
{ STOCK_WEB_BROWSER },
{ STOCK_NEWS_FEED },
{ STOCK_STYLE },
{ STOCK_BOOKMARK, N_("_Bookmark"), 0, 0, GTK_STOCK_FILE },
{ STOCK_BOOKMARKS, N_("_Bookmarks"), GDK_CONTROL_MASK | GDK_SHIFT_MASK, GDK_KEY_B, GTK_STOCK_DIRECTORY },
{ STOCK_BOOKMARK_ADD, N_("Add Boo_kmark"), 0, 0, "stock_add-bookmark" },
{ STOCK_CONSOLE, N_("_Console"), 0, 0, GTK_STOCK_DIALOG_WARNING },
{ STOCK_EXTENSIONS, N_("_Extensions"), 0, 0, GTK_STOCK_CONVERT },
{ STOCK_HISTORY, N_("_History"), GDK_CONTROL_MASK | GDK_SHIFT_MASK, GDK_KEY_H, GTK_STOCK_SORT_ASCENDING },
{ STOCK_HOMEPAGE, N_("_Homepage"), 0, 0, GTK_STOCK_HOME },
{ STOCK_SCRIPTS, N_("_Userscripts"), 0, 0, GTK_STOCK_EXECUTE },
{ STOCK_TAB_NEW, N_("New _Tab"), 0, 0, GTK_STOCK_ADD },
{ STOCK_TRANSFERS, N_("_Transfers"), GDK_CONTROL_MASK | GDK_SHIFT_MASK, GDK_KEY_J, GTK_STOCK_SAVE },
{ STOCK_PLUGINS, N_("Netscape p_lugins"), 0, 0, GTK_STOCK_CONVERT },
{ STOCK_USER_TRASH, N_("_Closed Tabs"), 0, 0, "gtk-undo-ltr" },
{ STOCK_WINDOW_NEW, N_("New _Window"), 0, 0, GTK_STOCK_ADD },
{ GTK_STOCK_DIRECTORY, N_("New _Folder"), 0, 0, NULL },
{ STOCK_BOOKMARKS, N_("_Bookmarks"), GDK_CONTROL_MASK | GDK_SHIFT_MASK, GDK_KEY_B },
{ STOCK_BOOKMARK_ADD, N_("Add Boo_kmark") },
{ STOCK_EXTENSION, N_("_Extensions") },
{ STOCK_HISTORY, N_("_History"), GDK_CONTROL_MASK | GDK_SHIFT_MASK, GDK_KEY_H },
{ STOCK_SCRIPT, N_("_Userscripts") },
{ STOCK_STYLE, N_("User_styles") },
{ STOCK_TAB_NEW, N_("New _Tab") },
{ STOCK_TRANSFER, N_("_Transfers"), GDK_CONTROL_MASK | GDK_SHIFT_MASK, GDK_KEY_J },
{ STOCK_PLUGINS, N_("Netscape p_lugins") },
{ STOCK_USER_TRASH, N_("_Closed Tabs") },
{ STOCK_WINDOW_NEW, N_("New _Window") },
{ STOCK_FOLDER_NEW, N_("New _Folder") },
};
/* Preserve argument vector */
sokoke_get_argv (argument_vector);
/* libSoup uses threads, therefore if WebKit is built with libSoup
* or Midori is using it, we need to initialize threads. */
#if !GLIB_CHECK_VERSION (2, 32, 0)
if (!g_thread_supported ()) g_thread_init (NULL);
#endif
#if ENABLE_NLS
setlocale (LC_ALL, "");
if (g_getenv ("MIDORI_NLSPATH"))
bindtextdomain (GETTEXT_PACKAGE, g_getenv ("MIDORI_NLSPATH"));
else
#ifdef G_OS_WIN32
{
gchar* path = sokoke_find_data_filename ("locale", FALSE);
bindtextdomain (GETTEXT_PACKAGE, path);
g_free (path);
}
#else
bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
#endif
bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
textdomain (GETTEXT_PACKAGE);
#endif
g_type_init ();
factory = gtk_icon_factory_new ();
for (i = 0; i < G_N_ELEMENTS (items); i++)
{
icon_set = gtk_icon_set_new ();
icon_source = gtk_icon_source_new ();
if (items[i].fallback)
{
gtk_icon_source_set_icon_name (icon_source, items[i].fallback);
items[i].fallback = NULL;
gtk_icon_set_add_source (icon_set, icon_source);
}
gtk_icon_source_set_icon_name (icon_source, items[i].stock_id);
gtk_icon_set_add_source (icon_set, icon_source);
gtk_icon_source_free (icon_source);
gtk_icon_factory_add (factory, items[i].stock_id, icon_set);
gtk_icon_set_unref (icon_set);
}
gtk_stock_add_static ((GtkStockItem*)items, G_N_ELEMENTS (items));
gtk_icon_factory_add_default (factory);
g_object_unref (factory);
#if HAVE_HILDON
/* Maemo doesn't theme stock icons. So we map platform icons
to stock icons. These are all monochrome toolbar icons. */
typedef struct
{
const gchar* stock_id;
const gchar* icon_name;
} CompatItem;
static CompatItem compat_items[] =
{
{ GTK_STOCK_ADD, "general_add" },
{ GTK_STOCK_BOLD, "general_bold" },
{ GTK_STOCK_CLOSE, "general_close_b" },
{ GTK_STOCK_DELETE, "general_delete" },
{ GTK_STOCK_DIRECTORY, "general_toolbar_folder" },
{ GTK_STOCK_FIND, "general_search" },
{ GTK_STOCK_FULLSCREEN, "general_fullsize_b" },
{ GTK_STOCK_GO_BACK, "general_back" },
{ GTK_STOCK_GO_FORWARD, "general_forward" },
{ GTK_STOCK_GO_UP, "filemanager_folder_up" },
{ GTK_STOCK_GOTO_FIRST, "pdf_viewer_first_page" },
{ GTK_STOCK_GOTO_LAST, "pdf_viewer_last_page" },
{ GTK_STOCK_INFO, "general_information" },
{ GTK_STOCK_ITALIC, "general_italic" },
{ GTK_STOCK_JUMP_TO, "general_move_to_folder" },
{ GTK_STOCK_PREFERENCES,"general_settings" },
{ GTK_STOCK_REFRESH, "general_refresh" },
{ GTK_STOCK_SAVE, "notes_save" },
{ GTK_STOCK_STOP, "general_stop" },
{ GTK_STOCK_UNDERLINE, "notes_underline" },
{ GTK_STOCK_ZOOM_IN, "pdf_zoomin" },
{ GTK_STOCK_ZOOM_OUT, "pdf_zoomout" },
};
factory = gtk_icon_factory_new ();
for (i = 0; i < G_N_ELEMENTS (compat_items); i++)
{
icon_set = gtk_icon_set_new ();
icon_source = gtk_icon_source_new ();
gtk_icon_source_set_icon_name (icon_source, compat_items[i].icon_name);
gtk_icon_set_add_source (icon_set, icon_source);
gtk_icon_source_free (icon_source);
gtk_icon_factory_add (factory, compat_items[i].stock_id, icon_set);
gtk_icon_set_unref (icon_set);
}
gtk_icon_factory_add_default (factory);
g_object_unref (factory);
#endif
/* Print messages to stdout on Win32 console, cf. AbiWord
* http://svn.abisource.com/abiword/trunk/src/wp/main/win/Win32Main.cpp */
#ifdef _WIN32
@ -1472,5 +1405,90 @@ midori_app_setup (gchar** argument_vector)
}
}
#endif
/* libSoup uses threads, therefore if WebKit is built with libSoup
* or Midori is using it, we need to initialize threads. */
#if !GLIB_CHECK_VERSION (2, 32, 0)
if (!g_thread_supported ()) g_thread_init (NULL);
#endif
/* Midori.Paths uses GFile */
g_type_init ();
/* Preserve argument vector */
midori_paths_init_exec_path (*argument_vector, *argc);
#if ENABLE_NLS
if (g_getenv ("MIDORI_NLSPATH"))
bindtextdomain (GETTEXT_PACKAGE, g_getenv ("MIDORI_NLSPATH"));
else
#ifdef G_OS_WIN32
{
gchar* path = midori_paths_get_data_filename ("locale", FALSE);
bindtextdomain (GETTEXT_PACKAGE, path);
g_free (path);
}
#else
bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
#endif
bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
textdomain (GETTEXT_PACKAGE);
#endif
success = gtk_init_with_args (argc, argument_vector, _("[Addresses]"),
entries, GETTEXT_PACKAGE, error);
factory = gtk_icon_factory_new ();
for (i = 0; i < G_N_ELEMENTS (items); i++)
{
icon_set = gtk_icon_set_new ();
icon_source = gtk_icon_source_new ();
gtk_icon_source_set_icon_name (icon_source, items[i].stock_id);
gtk_icon_set_add_source (icon_set, icon_source);
gtk_icon_source_free (icon_source);
gtk_icon_factory_add (factory, items[i].stock_id, icon_set);
gtk_icon_set_unref (icon_set);
}
gtk_stock_add_static ((GtkStockItem*)items, G_N_ELEMENTS (items));
gtk_icon_factory_add_default (factory);
g_object_unref (factory);
return success;
}
gboolean
midori_debug (const gchar* token)
{
static const gchar* debug_token = NULL;
const gchar* debug = g_getenv ("MIDORI_DEBUG");
const gchar* debug_tokens = "headers body referer cookies paths hsts unarmed ";
const gchar* full_debug_tokens = "adblock:match adblock:time startup bookmarks ";
if (debug_token == NULL)
{
gchar* found_token;
if (debug && (found_token = strstr (full_debug_tokens, debug)) && *(found_token + strlen (debug)) == ' ')
{
#ifdef G_ENABLE_DEBUG
debug_token = g_intern_static_string (debug);
#else
g_warning ("Value '%s' for MIDORI_DEBUG requires a full debugging build.", debug);
#endif
}
else if (debug && (found_token = strstr (debug_tokens, debug)) && *(found_token + strlen (debug)) == ' ')
debug_token = g_intern_static_string (debug);
else if (debug)
g_warning ("Unrecognized value '%s' for MIDORI_DEBUG.", debug);
else
debug_token = "NONE";
if (!debug_token)
{
debug_token = "INVALID";
g_print ("Supported values: %s\nWith full debugging: %s\n",
debug_tokens, full_debug_tokens);
}
}
if (debug_token != g_intern_static_string ("NONE")
&& !strstr (debug_tokens, token) && !strstr (full_debug_tokens, token))
g_warning ("Token '%s' passed to midori_debug is not a known token.", token);
return debug_token == g_intern_static_string (token);
}

View file

@ -82,8 +82,14 @@ midori_app_send_notification (MidoriApp* app,
const gchar* title,
const gchar* message);
void
midori_app_setup (gchar** argument_vector);
gboolean
midori_app_setup (gint *argc,
gchar** *argument_vector,
const GOptionEntry *entries,
GError* *error);
gboolean
midori_debug (const gchar* token);
G_END_DECLS

View file

@ -982,24 +982,26 @@ katze_item_set_value_from_column (sqlite3_stmt* stmt,
item->added = date;
}
else if (g_str_equal (name, "day") || g_str_equal (name, "app")
|| g_str_equal (name, "toolbar"))
|| g_str_equal (name, "toolbar") || g_str_equal (name, "id")
|| g_str_equal (name, "parentid") || g_str_equal (name, "seq")
|| g_str_equal (name, "pos_panel") || g_str_equal (name, "pos_bar"))
{
gint value;
value = sqlite3_column_int64 (stmt, column);
katze_item_set_meta_integer (item, name, value);
}
else if (g_str_equal (name, "folder"))
{
const unsigned char* folder;
folder = sqlite3_column_text (stmt, column);
katze_item_set_meta_string (item, name, (gchar*)folder);
}
else if (g_str_equal (name, "desc"))
{
const unsigned char* text;
text = sqlite3_column_text (stmt, column);
item->text = g_strdup ((gchar*)text);
}
else if (g_str_equal (name, "sql"))
{
const unsigned char* sql;
sql = sqlite3_column_text (stmt, column);
katze_item_set_meta_string (item, name, (gchar*)sql);
}
else
g_warn_if_reached ();
}
@ -1102,7 +1104,7 @@ midori_array_query_recursive (KatzeArray* bookmarks,
return NULL;
sqlcmd = g_strdup_printf ("SELECT %s FROM bookmarks WHERE %s "
"ORDER BY title DESC", fields, condition);
"ORDER BY (uri='') ASC, title DESC", fields, condition);
if (strstr (condition, "%q"))
{
sqlcmd_value = sqlite3_mprintf (sqlcmd, value ? value : "");
@ -1120,10 +1122,14 @@ midori_array_query_recursive (KatzeArray* bookmarks,
{
if (KATZE_ITEM_IS_FOLDER (item))
{
gchar* parentid = g_strdup_printf ("%" G_GINT64_FORMAT,
katze_item_get_meta_integer (item, "id"));
KatzeArray* subarray = midori_array_query_recursive (bookmarks,
fields, "folder='%q'", item->name, TRUE);
fields, "parentid=%q", parentid, TRUE);
katze_item_set_name (KATZE_ITEM (subarray), item->name);
katze_array_add_item (array, subarray);
g_free (parentid);
}
}
g_list_free (list);

View file

@ -13,9 +13,17 @@
#include "midori-bookmarks.h"
#include "panels/midori-bookmarks.h"
#include "midori-array.h"
#include "sokoke.h"
#include "midori-core.h"
#include <glib/gstdio.h>
#include <glib/gi18n.h>
#include <config.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#ifdef G_ENABLE_DEBUG
void midori_bookmarks_dbtracer(void* dummy, const char* query)
{
@ -29,7 +37,7 @@ midori_bookmarks_add_item_cb (KatzeArray* array,
sqlite3* db)
{
midori_bookmarks_insert_item_db (db, item,
katze_item_get_meta_string (item, "folder"));
katze_item_get_meta_integer (item, "parentid"));
}
void
@ -40,19 +48,10 @@ midori_bookmarks_remove_item_cb (KatzeArray* array,
gchar* sqlcmd;
char* errmsg = NULL;
if (KATZE_ITEM_IS_BOOKMARK (item))
sqlcmd = sqlite3_mprintf (
"DELETE FROM bookmarks WHERE uri = '%q' "
" AND folder = '%q'",
katze_item_get_uri (item),
katze_str_non_null (katze_item_get_meta_string (item, "folder")));
else
sqlcmd = sqlite3_mprintf (
"DELETE FROM bookmarks WHERE title = '%q'"
" AND folder = '%q'",
katze_item_get_name (item),
katze_str_non_null (katze_item_get_meta_string (item, "folder")));
sqlcmd = sqlite3_mprintf (
"DELETE FROM bookmarks WHERE id = %" G_GINT64_FORMAT ";",
katze_item_get_meta_integer (item, "id"));
if (sqlite3_exec (db, sqlcmd, NULL, NULL, &errmsg) != SQLITE_OK)
{
@ -63,38 +62,258 @@ midori_bookmarks_remove_item_cb (KatzeArray* array,
sqlite3_free (sqlcmd);
}
#define _APPEND_TO_SQL_ERRORMSG(custom_errmsg) \
do { \
if (sql_errmsg) \
{ \
g_string_append_printf (errmsg_str, "%s : %s\n", custom_errmsg, sql_errmsg); \
sqlite3_free (sql_errmsg); \
} \
else \
g_string_append (errmsg_str, custom_errmsg); \
} while (0)
gboolean
midori_bookmarks_import_from_old_db (sqlite3* db,
const gchar* oldfile,
gchar** errmsg)
{
gint sql_errcode;
gboolean failure = FALSE;
gchar* sql_errmsg = NULL;
GString* errmsg_str = g_string_new (NULL);
gchar* attach_stmt = sqlite3_mprintf ("ATTACH DATABASE %Q AS old_db;", oldfile);
const gchar* convert_stmts =
"BEGIN TRANSACTION;"
"INSERT INTO main.bookmarks (parentid, title, uri, desc, app, toolbar) "
"SELECT NULL AS parentid, title, uri, desc, app, toolbar "
"FROM old_db.bookmarks;"
"UPDATE main.bookmarks SET parentid = ("
"SELECT id FROM main.bookmarks AS b1 WHERE b1.title = ("
"SELECT folder FROM old_db.bookmarks WHERE title = main.bookmarks.title));"
"COMMIT;";
const gchar* detach_stmt = "DETACH DATABASE old_db;";
*errmsg = NULL;
sql_errcode = sqlite3_exec (db, attach_stmt, NULL, NULL, &sql_errmsg);
sqlite3_free (attach_stmt);
if (sql_errcode != SQLITE_OK)
{
_APPEND_TO_SQL_ERRORMSG (_("failed to ATTACH old db"));
goto convert_failed;
}
if (sqlite3_exec (db, convert_stmts, NULL, NULL, &sql_errmsg) != SQLITE_OK)
{
failure = TRUE;
_APPEND_TO_SQL_ERRORMSG (_("failed to import from old db"));
/* try to get back to previous state */
if (sqlite3_exec (db, "ROLLBACK TRANSACTION;", NULL, NULL, &sql_errmsg) != SQLITE_OK)
_APPEND_TO_SQL_ERRORMSG (_("failed to rollback the transaction"));
}
if (sqlite3_exec (db, detach_stmt, NULL, NULL, &sql_errmsg) != SQLITE_OK)
_APPEND_TO_SQL_ERRORMSG (_("failed to DETACH "));
if (failure)
{
convert_failed:
*errmsg = g_string_free (errmsg_str, FALSE);
g_print ("ERRORR: %s\n", errmsg_str->str);
return FALSE;
}
return TRUE;
}
#undef _APPEND_TO_SQL_ERRORMSG
sqlite3*
midori_bookmarks_initialize (KatzeArray* array,
const gchar* filename,
char** errmsg)
{
sqlite3* db;
gchar* oldfile;
gchar* newfile;
gboolean newfile_did_exist, oldfile_exists;
const gchar* create_stmt;
gchar* sql_errmsg = NULL;
gchar* import_errmsg = NULL;
if (sqlite3_open (filename, &db) != SQLITE_OK)
g_return_val_if_fail (errmsg != NULL, NULL);
oldfile = g_build_filename (midori_paths_get_config_dir (), "bookmarks.db", NULL);
oldfile_exists = g_access (oldfile, F_OK) == 0;
newfile = g_build_filename (midori_paths_get_config_dir (), "bookmarks_v2.db", NULL);
newfile_did_exist = g_access (newfile, F_OK) == 0;
/* sqlite3_open will create the file if it did not exists already */
if (sqlite3_open (newfile, &db) != SQLITE_OK)
{
if (errmsg)
*errmsg = g_strdup_printf (_("Failed to open database: %s\n"),
sqlite3_errmsg (db));
sqlite3_close (db);
return NULL;
if (db)
*errmsg = g_strdup_printf (_("failed to open database: %s\n"),
sqlite3_errmsg (db));
else
*errmsg = g_strdup (_("failed to open database\n"));
goto init_failed;
}
#ifdef G_ENABLE_DEBUG
if (g_getenv ("MIDORI_BOOKMARKS_DEBUG"))
if (midori_debug ("bookmarks"))
sqlite3_trace (db, midori_bookmarks_dbtracer, NULL);
#endif
if (sqlite3_exec (db,
"CREATE TABLE IF NOT EXISTS "
"bookmarks (uri text, title text, folder text, "
"desc text, app integer, toolbar integer);",
NULL, NULL, errmsg) != SQLITE_OK)
create_stmt = /* Table structure */
"CREATE TABLE IF NOT EXISTS bookmarks "
"(id INTEGER PRIMARY KEY AUTOINCREMENT, "
"parentid INTEGER DEFAULT NULL, "
"title TEXT, uri TEXT, desc TEXT, app INTEGER, toolbar INTEGER, "
"pos_panel INTEGER, pos_bar INTEGER, "
"created DATE DEFAULT CURRENT_TIMESTAMP, "
"last_visit DATE, visit_count INTEGER DEFAULT 0, "
"nick TEXT, "
"FOREIGN KEY(parentid) REFERENCES bookmarks(id) "
"ON DELETE CASCADE); PRAGMA foreign_keys = ON;"
/* trigger: insert panel position */
"CREATE TRIGGER IF NOT EXISTS bookmarkInsertPosPanel "
"AFTER INSERT ON bookmarks FOR EACH ROW "
"BEGIN UPDATE bookmarks SET pos_panel = ("
"SELECT ifnull(MAX(pos_panel),0)+1 FROM bookmarks WHERE "
"(NEW.parentid IS NOT NULL AND parentid = NEW.parentid) "
"OR (NEW.parentid IS NULL AND parentid IS NULL)) "
"WHERE id = NEW.id; END;"
/* trigger: insert Bookmarkbar position */
"CREATE TRIGGER IF NOT EXISTS bookmarkInsertPosBar "
"AFTER INSERT ON bookmarks FOR EACH ROW WHEN NEW.toolbar=1 "
"BEGIN UPDATE bookmarks SET pos_bar = ("
"SELECT ifnull(MAX(pos_bar),0)+1 FROM bookmarks WHERE "
"((NEW.parentid IS NOT NULL AND parentid = NEW.parentid) "
"OR (NEW.parentid IS NULL AND parentid IS NULL)) AND toolbar=1) "
"WHERE id = NEW.id; END;"
/* trigger: update panel position */
"CREATE TRIGGER IF NOT EXISTS bookmarkUpdatePosPanel "
"BEFORE UPDATE OF parentid ON bookmarks FOR EACH ROW "
"WHEN ((NEW.parentid IS NULL OR OLD.parentid IS NULL) "
"AND NEW.parentid IS NOT OLD.parentid) OR "
"((NEW.parentid IS NOT NULL AND OLD.parentid IS NOT NULL) "
"AND NEW.parentid!=OLD.parentid) "
"BEGIN UPDATE bookmarks SET pos_panel = pos_panel-1 "
"WHERE ((OLD.parentid IS NOT NULL AND parentid = OLD.parentid) "
"OR (OLD.parentid IS NULL AND parentid IS NULL)) AND pos_panel > OLD.pos_panel; "
"UPDATE bookmarks SET pos_panel = ("
"SELECT ifnull(MAX(pos_panel),0)+1 FROM bookmarks "
"WHERE (NEW.parentid IS NOT NULL AND parentid = NEW.parentid) "
"OR (NEW.parentid IS NULL AND parentid IS NULL)) "
"WHERE id = OLD.id; END;"
/* trigger: update Bookmarkbar position */
"CREATE TRIGGER IF NOT EXISTS bookmarkUpdatePosBar0 "
"AFTER UPDATE OF parentid, toolbar ON bookmarks FOR EACH ROW "
"WHEN ((NEW.parentid IS NULL OR OLD.parentid IS NULL) "
"AND NEW.parentid IS NOT OLD.parentid) "
"OR ((NEW.parentid IS NOT NULL AND OLD.parentid IS NOT NULL) "
"AND NEW.parentid!=OLD.parentid) OR (OLD.toolbar=1 AND NEW.toolbar=0) "
"BEGIN UPDATE bookmarks SET pos_bar = NULL WHERE id = NEW.id; "
"UPDATE bookmarks SET pos_bar = pos_bar-1 "
"WHERE ((OLD.parentid IS NOT NULL AND parentid = OLD.parentid) "
"OR (OLD.parentid IS NULL AND parentid IS NULL)) AND pos_bar > OLD.pos_bar; END;"
/* trigger: update Bookmarkbar position */
"CREATE TRIGGER IF NOT EXISTS bookmarkUpdatePosBar1 "
"BEFORE UPDATE OF parentid, toolbar ON bookmarks FOR EACH ROW "
"WHEN ((NEW.parentid IS NULL OR OLD.parentid IS NULL) "
"AND NEW.parentid IS NOT OLD.parentid) OR "
"((NEW.parentid IS NOT NULL AND OLD.parentid IS NOT NULL) "
"AND NEW.parentid!=OLD.parentid) OR (OLD.toolbar=0 AND NEW.toolbar=1) "
"BEGIN UPDATE bookmarks SET pos_bar = ("
"SELECT ifnull(MAX(pos_bar),0)+1 FROM bookmarks WHERE "
"(NEW.parentid IS NOT NULL AND parentid = NEW.parentid) "
"OR (NEW.parentid IS NULL AND parentid IS NULL)) "
"WHERE id = OLD.id; END;"
/* trigger: delete panel position */
"CREATE TRIGGER IF NOT EXISTS bookmarkDeletePosPanel "
"AFTER DELETE ON bookmarks FOR EACH ROW "
"BEGIN UPDATE bookmarks SET pos_panel = pos_panel-1 "
"WHERE ((OLD.parentid IS NOT NULL AND parentid = OLD.parentid) "
"OR (OLD.parentid IS NULL AND parentid IS NULL)) AND pos_panel > OLD.pos_panel; END;"
/* trigger: delete Bookmarkbar position */
"CREATE TRIGGER IF NOT EXISTS bookmarkDeletePosBar "
"AFTER DELETE ON bookmarks FOR EACH ROW WHEN OLD.toolbar=1 "
"BEGIN UPDATE bookmarks SET pos_bar = pos_bar-1 "
"WHERE ((OLD.parentid IS NOT NULL AND parentid = OLD.parentid) "
"OR (OLD.parentid IS NULL AND parentid IS NULL)) AND pos_bar > OLD.pos_bar; END;";
if (newfile_did_exist)
{
/* we are done */
goto init_success;
}
else
{
/* initial creation */
if (sqlite3_exec (db, create_stmt, NULL, NULL, &sql_errmsg) != SQLITE_OK)
{
if (errmsg)
{
if (sql_errmsg)
{
*errmsg = g_strdup_printf (_("could not create bookmarks table: %s\n"), sql_errmsg);
sqlite3_free (sql_errmsg);
}
else
*errmsg = g_strdup (_("could not create bookmarks table"));
}
/* we can as well remove the new file */
g_unlink (newfile);
goto init_failed;
}
}
if (oldfile_exists)
/* import from old db */
if (!midori_bookmarks_import_from_old_db (db, oldfile, &import_errmsg))
{
if (errmsg)
{
if (import_errmsg)
{
*errmsg = g_strdup_printf (_("could not import from old database: %s\n"), import_errmsg);
g_free (import_errmsg);
}
else
*errmsg = g_strdup_printf (_("could not import from old database"));
}
}
init_success:
g_free (newfile);
g_free (oldfile);
g_signal_connect (array, "add-item",
G_CALLBACK (midori_bookmarks_add_item_cb), db);
g_signal_connect (array, "remove-item",
G_CALLBACK (midori_bookmarks_remove_item_cb), db);
return db;
init_failed:
g_free (newfile);
g_free (oldfile);
if (db)
sqlite3_close (db);
return NULL;
g_signal_connect (array, "add-item",
G_CALLBACK (midori_bookmarks_add_item_cb), db);
g_signal_connect (array, "remove-item",
G_CALLBACK (midori_bookmarks_remove_item_cb), db);
return db;
}
void
@ -112,5 +331,5 @@ midori_bookmarks_import (const gchar* filename,
g_error_free (error);
return;
}
midori_bookmarks_import_array_db (db, bookmarks, "");
midori_bookmarks_import_array_db (db, bookmarks, 0);
}

View file

@ -25,7 +25,6 @@ midori_bookmarks_remove_item_cb (KatzeArray* array,
sqlite3*
midori_bookmarks_initialize (KatzeArray* array,
const gchar* filename,
char** errmsg);
void

File diff suppressed because it is too large Load diff

View file

@ -159,6 +159,9 @@ midori_browser_page_num (MidoriBrowser* browser,
GList*
midori_browser_get_tabs (MidoriBrowser* browser);
gint
midori_browser_get_n_pages (MidoriBrowser* browser);
KatzeArray*
midori_browser_get_proxy_items (MidoriBrowser* browser);
@ -177,6 +180,11 @@ midori_browser_get_toolbar_actions (MidoriBrowser* browser);
MidoriWebSettings*
midori_browser_get_settings (MidoriBrowser* browser);
void
midori_browser_update_history (KatzeItem* item,
const gchar* type,
const gchar* event);
G_END_DECLS
#endif /* __MIDORI_BROWSER_H__ */

320
midori/midori-download.vala Normal file
View file

@ -0,0 +1,320 @@
/*
Copyright (C) 2012 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.
*/
namespace Sokoke {
extern static bool show_uri (Gdk.Screen screen, string uri, uint32 timestamp) throws Error;
extern static bool message_dialog (Gtk.MessageType type, string short, string detailed, bool modal);
}
namespace Midori {
namespace Download {
public static bool is_finished (WebKit.Download download) {
switch (download.status) {
case WebKit.DownloadStatus.FINISHED:
case WebKit.DownloadStatus.CANCELLED:
case WebKit.DownloadStatus.ERROR:
return true;
default:
return false;
}
}
public static int get_type (WebKit.Download download) {
return download.get_data<int> ("midori-download-type");
}
public static void set_type (WebKit.Download download, int type) {
download.set_data<int> ("midori-download-type", type);
}
public static double get_progress (WebKit.Download download) {
/* Avoid a bug in WebKit */
if (download.status == WebKit.DownloadStatus.CREATED)
return 0.0;
return download.progress;
}
public static string get_tooltip (WebKit.Download download) {
string filename = Path.get_basename (download.destination_uri);
/* i18n: Download tooltip (size): 4KB of 43MB */
string size = _("%s of %s").printf (
format_size (download.current_size),
format_size (download.total_size));
/* Finished, no speed or remaining time */
if (is_finished (download) || download.status == WebKit.DownloadStatus.CREATED)
return "%s\n%s".printf (filename, size);
uint64 total_size = download.total_size, current_size = download.current_size;
double elapsed = download.get_elapsed_time (),
diff = elapsed / current_size,
estimated = (total_size - current_size) * diff;
int hour = 3600, minute = 60;
int hours = (int)(estimated / hour),
minutes = (int)((estimated - (hours * hour)) / minute),
seconds = (int)((estimated - (hours * hour) - (minutes * minute)));
string hours_ = ngettext ("%d hour", "%d hours", hours).printf (hours);
string minutes_ = ngettext ("%d minute", "%d minutes", minutes).printf (minutes);
string seconds_ = ngettext ("%d second", "%d seconds", seconds).printf (seconds);
double last_time = download.get_data<int> ("last-time");
uint64 last_size = download.get_data<uint64> ("last-size");
string eta = "";
if (estimated > 0) {
if (hours > 0)
eta = hours_ + ", " + minutes_;
else if (minutes >= 10)
eta = minutes_;
else if (minutes < 10 && minutes > 0)
eta = minutes_ + ", " + seconds_;
else if (seconds > 0)
eta = seconds_;
if (eta != "")
/* i18n: Download tooltip (estimated time) : - 1 hour, 5 minutes remaning */
eta = _(" - %s remaining").printf (eta);
}
string speed;
if (elapsed != last_time) {
speed = format_size ((uint64)(
(current_size - last_size) / (elapsed - last_time)));
}
else
/* i18n: Unknown number of bytes, used for transfer rate like ?B/s */
speed = _("?B");
/* i18n: Download tooltip (transfer rate): (130KB/s) */
speed = _(" (%s/s)").printf (speed);
if (elapsed - last_time > 5.0) {
download.set_data<int> ("last-time", (int)elapsed);
download.set_data<uint64> ("last-size", current_size);
}
return "%s\n%s %s%s".printf (filename, size, speed, eta);
}
public static string get_content_type (WebKit.Download download, string? mime_type) {
string? content_type = ContentType.guess (download.suggested_filename, null, null);
if (content_type == null) {
content_type = ContentType.from_mime_type (mime_type);
if (content_type == null)
content_type = ContentType.from_mime_type ("application/octet-stream");
}
return content_type;
}
public static bool has_wrong_checksum (WebKit.Download download) {
int status = download.get_data<int> ("checksum-status");
if (status == 0) {
/* Link Fingerprint */
string? original_uri = download.network_request.get_data<string> ("midori-original-uri");
if (original_uri == null)
original_uri = download.get_uri ();
string? fingerprint;
ChecksumType checksum_type = URI.get_fingerprint (original_uri, out fingerprint, null);
/* By default, no wrong checksum */
status = 2;
if (fingerprint != null) {
try {
string filename = Filename.from_uri (download.destination_uri);
string contents;
size_t length;
bool y = FileUtils.get_contents (filename, out contents, out length);
string checksum = Checksum.compute_for_string (checksum_type, contents, length);
/* Checksums are case-insensitive */
if (!y || fingerprint.ascii_casecmp (checksum) != 0)
status = 1; /* wrong checksum */
}
catch (Error error) {
status = 1; /* wrong checksum */
}
}
download.set_data<int> ("checksum-status", status);
}
return status == 1;
}
public static bool action_clear (WebKit.Download download, Gtk.Widget widget) throws Error {
switch (download.status) {
case WebKit.DownloadStatus.CREATED:
case WebKit.DownloadStatus.STARTED:
download.cancel ();
break;
case WebKit.DownloadStatus.FINISHED:
if (open (download, widget))
return true;
break;
case WebKit.DownloadStatus.CANCELLED:
return true;
default:
critical ("action_clear: %d", download.status);
warn_if_reached ();
break;
}
return false;
}
public static string action_stock_id (WebKit.Download download) {
switch (download.status) {
case WebKit.DownloadStatus.CREATED:
case WebKit.DownloadStatus.STARTED:
return Gtk.Stock.CANCEL;
case WebKit.DownloadStatus.FINISHED:
if (has_wrong_checksum (download))
return Gtk.Stock.DIALOG_WARNING;
return Gtk.Stock.OPEN;
case WebKit.DownloadStatus.CANCELLED:
return Gtk.Stock.CLEAR;
default:
critical ("action_stock_id: %d", download.status);
warn_if_reached ();
return Gtk.Stock.MISSING_IMAGE;
}
}
public static bool open (WebKit.Download download, Gtk.Widget widget) throws Error {
if (!has_wrong_checksum (download))
return Sokoke.show_uri (widget.get_screen (),
download.destination_uri, Gtk.get_current_event_time ());
Sokoke.message_dialog (Gtk.MessageType.WARNING,
_("The downloaded file is erroneous."),
_("The checksum provided with the link did not match. This means the file is probably incomplete or was modified afterwards."),
true);
return false;
}
public unowned string fallback_extension (string? extension, string mime_type) {
if (extension != null && extension[0] != '\0')
return extension;
if ("css" in mime_type)
return ".css";
if ("javascript" in mime_type)
return ".js";
if ("html" in mime_type)
return ".htm";
if ("plain" in mime_type)
return ".txt";
return "";
}
public string clean_filename (string filename) {
#if HAVE_WIN32
return filename.delimit ("/\\<>:\"|?*", '_');
#else
return filename.delimit ("/", '_');
#endif
}
public string get_suggested_filename (WebKit.Download download) {
/* https://bugs.webkit.org/show_bug.cgi?id=83161
https://d19vezwu8eufl6.cloudfront.net/nlp/slides%2F03-01-FormalizingNB.pdf */
return clean_filename (download.get_suggested_filename ());
}
public string get_filename_suggestion_for_uri (string mime_type, string uri) {
/* Try to provide a good default filename, UTF-8 encoded */
string filename = clean_filename (Soup.URI.decode (uri));
/* Take the rest of the URI if needed */
if (filename.has_suffix ("/") || uri.index_of_char ('.') == -1)
return Path.build_filename (filename, fallback_extension (null, mime_type));
return filename;
}
public static string? get_extension_for_uri (string uri, out string basename = null) {
if (&basename != null)
basename = null;
/* Find the last slash and the last period *after* the last slash. */
int last_slash = uri.last_index_of_char ('/');
/* Huh, URI without slashes? */
if (last_slash == -1)
return null;
int period = uri.last_index_of_char ('.', last_slash);
if (period == -1)
return null;
/* The extension, or "." if it ended with a period */
string extension = uri.substring (period, -1);
if (&basename != null)
basename = uri.substring (0, period);
return extension;
}
public string get_unique_filename (string filename) {
if (Posix.access (filename, Posix.F_OK) == 0) {
string basename;
string? extension = get_extension_for_uri (filename, out basename);
string? new_filename = null;
int i = 0;
do {
new_filename = "%s-%d%s".printf (basename, i++, extension ?? "");
} while (Posix.access (new_filename, Posix.F_OK) == 0);
return new_filename;
}
return filename;
}
public string prepare_destination_uri (WebKit.Download download, string? folder) {
string suggested_filename = get_suggested_filename (download);
string basename = File.new_for_uri (suggested_filename).get_basename ();
string download_dir;
if (folder == null) {
download_dir = Paths.get_tmp_dir ();
Katze.mkdir_with_parents (download_dir, 0700);
}
else
download_dir = folder;
string destination_filename = Path.build_filename (download_dir, basename);
try {
return Filename.to_uri (get_unique_filename (destination_filename));
}
catch (Error error) {
return "file://" + destination_filename;
}
}
public static bool has_enough_space (WebKit.Download download, string uri) {
var folder = File.new_for_uri (uri).get_parent ();
bool can_write;
uint64 free_space;
try {
var info = folder.query_filesystem_info ("filesystem::free");
free_space = info.get_attribute_uint64 ("filesystem::free");
info = folder.query_info ("access::can-write", 0);
can_write = info.get_attribute_boolean ("access::can-write");
}
catch (Error error) {
can_write = false;
free_space = 0;
}
if (free_space < download.total_size || !can_write) {
string message;
string detailed_message;
if (!can_write) {
message = _("The file \"%s\" can't be saved in this folder.").printf (
Path.get_basename (uri));
detailed_message = _("You don't have permission to write in this location.");
}
else if (free_space < download.total_size) {
message = _("There is not enough free space to download \"%s\".").printf (
Path.get_basename (uri));
detailed_message = _("The file needs %s but only %s are left.").printf (
format_size (download.total_size), format_size (free_space));
}
else
assert_not_reached ();
Sokoke.message_dialog (Gtk.MessageType.ERROR, message, detailed_message, false);
return false;
}
return true;
}
}
}

View file

@ -14,6 +14,7 @@
#include <katze/katze.h>
#include "midori-platform.h"
#include "midori-core.h"
#include <glib/gi18n.h>
G_DEFINE_TYPE (MidoriExtension, midori_extension, G_TYPE_OBJECT);
@ -317,10 +318,10 @@ midori_extension_activate_cb (MidoriExtension* extension,
strlen (filename) - strlen ("." G_MODULE_SUFFIX));
else
filename = g_strdup (filename);
folder = g_strconcat ("extensions/", filename, NULL);
folder = g_build_filename ("extensions", filename, NULL);
g_free (filename);
katze_assign (config_file,
sokoke_find_config_filename (folder, "config"));
midori_paths_get_preset_filename (folder, "config"));
g_free (folder);
g_key_file_load_from_file (extension->priv->key_file, config_file,
G_KEY_FILE_KEEP_COMMENTS, NULL);
@ -340,29 +341,32 @@ midori_extension_activate_cb (MidoriExtension* extension,
if (setting->type == G_TYPE_BOOLEAN)
{
MESettingBoolean* setting_ = (MESettingBoolean*)setting;
if (extension->priv->key_file)
setting_->value = sokoke_key_file_get_boolean_default (
extension->priv->key_file,
"settings", setting->name, setting_->default_value, NULL);
if (extension->priv->key_file
&& g_key_file_has_key (extension->priv->key_file, "settings", setting_->name, NULL))
setting_->value = g_key_file_get_boolean (extension->priv->key_file,
"settings", setting->name, NULL);
else
setting_->value = setting_->default_value;
}
else if (setting->type == G_TYPE_INT)
{
MESettingInteger* setting_ = (MESettingInteger*)setting;
if (extension->priv->key_file)
setting_->value = sokoke_key_file_get_integer_default (
extension->priv->key_file,
"settings", setting->name, setting_->default_value, NULL);
if (extension->priv->key_file
&& g_key_file_has_key (extension->priv->key_file, "settings", setting_->name, NULL))
setting_->value = g_key_file_get_integer (extension->priv->key_file,
"settings", setting_->name, NULL);
else
setting_->value = setting_->default_value;
}
else if (setting->type == G_TYPE_STRING)
{
if (extension->priv->key_file)
setting->value = sokoke_key_file_get_string_default (
extension->priv->key_file,
"settings", setting->name, setting->default_value, NULL);
{
setting->value = g_key_file_get_string (
extension->priv->key_file, "settings", setting->name, NULL);
if (setting->value == NULL)
setting->value = setting->default_value;
}
else
setting->value = g_strdup (setting->default_value);
}
@ -371,10 +375,10 @@ midori_extension_activate_cb (MidoriExtension* extension,
MESettingStringList* setting_ = (MESettingStringList*)setting;
if (extension->priv->key_file)
{
setting_->value = sokoke_key_file_get_string_list_default (
extension->priv->key_file,
"settings", setting->name, &setting_->length,
setting_->default_value, &setting_->default_length, NULL);
setting_->value = g_key_file_get_string_list (extension->priv->key_file,
"settings", setting->name, &setting_->length, NULL);
if (setting_->value == NULL)
setting_->value = g_strdupv (setting_->default_value);
}
else
setting_->value = g_strdupv (setting_->default_value);
@ -645,10 +649,11 @@ midori_extension_get_config_dir (MidoriExtension* extension)
if (!extension->priv->config_dir)
{
gchar* filename = g_object_get_data (G_OBJECT (extension), "filename");
if (!filename)
return "/";
extension->priv->config_dir = g_build_filename (
sokoke_set_config_dir (NULL), "extensions", filename, NULL);
if (filename != NULL)
extension->priv->config_dir = g_build_filename (
midori_paths_get_config_dir (), "extensions", filename, NULL);
else
extension->priv->config_dir = NULL;
}
return extension->priv->config_dir;

View file

@ -376,10 +376,14 @@ midori_location_action_add_search_engines (MidoriLocationAction* action,
{
KatzeItem* item;
gint i = 0;
#ifndef G_OS_WIN32
GtkStyle* style;
#endif
gtk_widget_realize (action->treeview);
#ifndef G_OS_WIN32
style = gtk_widget_get_style (action->treeview);
#endif
/* FIXME: choose 3 most frequently except for default */
KATZE_ARRAY_FOREACH_ITEM (item, action->search_engines)
@ -397,7 +401,9 @@ midori_location_action_add_search_engines (MidoriLocationAction* action,
icon = midori_search_action_get_icon (item, action->treeview, NULL, FALSE);
gtk_list_store_insert_with_values (store, NULL, matches + i,
URI_COL, uri, TITLE_COL, desc, YALIGN_COL, 0.25,
#ifndef G_OS_WIN32
BACKGROUND_COL, style ? &style->bg[GTK_STATE_NORMAL] : NULL,
#endif
STYLE_COL, 1, FAVICON_COL, icon, -1);
g_free (uri);
g_free (title);
@ -409,9 +415,11 @@ midori_location_action_add_search_engines (MidoriLocationAction* action,
if (i > 2 && matches > 0)
{
gtk_list_store_insert_with_values (store, NULL, matches + i,
URI_COL, "about:search", TITLE_COL, _("Search with..."),
URI_COL, "about:search", TITLE_COL, _("Search with"),
YALIGN_COL, 0.25,
#ifndef G_OS_WIN32
BACKGROUND_COL, style ? &style->bg[GTK_STATE_NORMAL] : NULL,
#endif
STYLE_COL, 1, FAVICON_COL, NULL, -1);
i++;
break;
@ -814,15 +822,31 @@ midori_location_action_activate (GtkAction* action)
GTK_ACTION_CLASS (midori_location_action_parent_class)->activate (action);
}
static void
midori_location_action_entry_drag_data_get_cb (GtkWidget* entry,
GdkDragContext* context,
GtkSelectionData* data,
guint info,
guint32 time,
GtkAction* action)
{
if (gtk_entry_get_current_icon_drag_source (GTK_ENTRY (entry)) == GTK_ENTRY_ICON_PRIMARY)
{
const gchar* uri = gtk_entry_get_text (GTK_ENTRY (entry));
gchar** uris = g_strsplit (uri, uri, 1);
gtk_selection_data_set_uris (data, uris);
g_strfreev (uris);
}
}
static GtkWidget*
midori_location_action_create_tool_item (GtkAction* action)
{
GtkWidget* toolitem;
GtkWidget* alignment;
GtkWidget* entry;
#if HAVE_HILDON
HildonGtkInputMode mode;
#endif
GtkTargetList *targetlist;
toolitem = GTK_WIDGET (gtk_tool_item_new ());
gtk_tool_item_set_expand (GTK_TOOL_ITEM (toolitem), TRUE);
@ -831,46 +855,21 @@ midori_location_action_create_tool_item (GtkAction* action)
gtk_widget_show (alignment);
gtk_container_add (GTK_CONTAINER (toolitem), alignment);
#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 ();
/* Work-around icon being activatable by default */
gtk_icon_entry_set_icon_highlight (GTK_ICON_ENTRY (entry),
GTK_ICON_ENTRY_PRIMARY, FALSE);
GTK_ICON_ENTRY_PRIMARY, TRUE);
gtk_icon_entry_set_icon_highlight (GTK_ICON_ENTRY (entry),
GTK_ICON_ENTRY_SECONDARY, TRUE);
#endif
targetlist = gtk_target_list_new (NULL, 0);
gtk_target_list_add_uri_targets (targetlist, 0);
gtk_entry_set_icon_drag_source (GTK_ENTRY (entry), GTK_ENTRY_ICON_PRIMARY, targetlist, GDK_ACTION_ASK | GDK_ACTION_COPY | GDK_ACTION_LINK);
gtk_target_list_unref (targetlist);
g_signal_connect (entry, "drag-data-get",
G_CALLBACK (midori_location_action_entry_drag_data_get_cb), action);
gtk_widget_show (entry);
gtk_container_add (GTK_CONTAINER (alignment), entry);
#if GTK_CHECK_VERSION (3, 0, 0)
{
static const gchar default_style[] =
".security_unknown {\n"
"background-image: none;\n"
"background-color: #ef7070;\n"
"color: #000;\n"
"}\n"
".security_trusted {\n"
"background-image: none;\n"
"background-color: #d1eeb9;\n"
"color: #000;\n"
"}\n";
GtkCssProvider* css_provider;
GtkStyleContext* context;
css_provider = gtk_css_provider_new ();
context = gtk_widget_get_style_context (entry);
gtk_css_provider_load_from_data (css_provider, default_style, -1, NULL);
gtk_style_context_add_provider (context, GTK_STYLE_PROVIDER (css_provider),
GTK_STYLE_PROVIDER_PRIORITY_FALLBACK);
}
#endif
return toolitem;
}
@ -993,10 +992,6 @@ midori_location_action_key_press_event_cb (GtkEntry* entry,
/* Return FALSE to allow Escape to stop loading */
return FALSE;
}
case GDK_KEY_Page_Up:
case GDK_KEY_Page_Down:
if (!(location_action->popup && gtk_widget_get_visible (location_action->popup)))
return TRUE;
case GDK_KEY_Delete:
case GDK_KEY_KP_Delete:
{
@ -1045,7 +1040,12 @@ midori_location_action_key_press_event_cb (GtkEntry* entry,
case GDK_KEY_KP_Up:
case GDK_KEY_Tab:
case GDK_KEY_ISO_Left_Tab:
case GDK_KEY_Page_Down:
case GDK_KEY_Page_Up:
{
if ((event->keyval == GDK_KEY_Page_Up || event->keyval == GDK_KEY_Page_Down) &&
!(location_action->popup && gtk_widget_get_visible (location_action->popup)))
return TRUE;
if (location_action->popup && gtk_widget_get_visible (location_action->popup))
{
GtkTreeModel* model = location_action->completion_model;
@ -1055,35 +1055,62 @@ midori_location_action_key_press_event_cb (GtkEntry* entry,
gint selected = location_action->completion_index;
if (event->keyval == GDK_KEY_Down || event->keyval == GDK_KEY_KP_Down
|| event->keyval == GDK_KEY_Tab || event->keyval == GDK_KEY_ISO_Left_Tab)
selected = MIN (selected + 1, matches -1);
else if (event->keyval == GDK_KEY_Up || event->keyval == GDK_KEY_KP_Up)
|| ((event->keyval == GDK_KEY_Tab || event->keyval == GDK_KEY_ISO_Left_Tab)
&& !(event->state & GDK_SHIFT_MASK)))
{
selected = selected + 1;
if (selected == matches)
selected = -1;
}
else if (event->keyval == GDK_KEY_Up || event->keyval == GDK_KEY_KP_Up
|| ((event->keyval == GDK_KEY_Tab || event->keyval == GDK_KEY_ISO_Left_Tab)
&& (event->state & GDK_SHIFT_MASK)))
{
if (selected == -1)
selected = matches - 1;
else
selected = MAX (selected - 1, 0);
selected = selected - 1;
}
else if (event->keyval == GDK_KEY_Page_Down)
selected = MIN (selected + 14, matches -1);
{
if (selected == -1)
selected = 0;
else if (selected < matches - 1)
selected = MIN (selected + 14, matches -1);
else
selected = -1;
}
else if (event->keyval == GDK_KEY_Page_Up)
selected = MAX (selected - 14, 0);
{
if (selected == -1)
selected = matches - 1;
else if (selected > 0)
selected = MAX (selected - 14, 0);
else
selected = -1;
}
else if (event->keyval != GDK_KEY_KP_Delete && event->keyval != GDK_KEY_Delete)
g_assert_not_reached ();
path = gtk_tree_path_new_from_indices (selected, -1);
gtk_tree_view_set_cursor (GTK_TREE_VIEW (location_action->treeview),
path, NULL, FALSE);
gtk_tree_path_free (path);
if (gtk_tree_model_iter_nth_child (model, &iter, NULL, selected))
if (selected != -1)
{
gchar* uri;
gtk_tree_model_get (model, &iter, URI_COL, &uri, -1);
/* Update the layout without actually changing the text */
pango_layout_set_text (gtk_entry_get_layout (entry), uri, -1);
g_free (uri);
path = gtk_tree_path_new_from_indices (selected, -1);
gtk_tree_view_set_cursor (GTK_TREE_VIEW (location_action->treeview),
path, NULL, FALSE);
gtk_tree_path_free (path);
if (gtk_tree_model_iter_nth_child (model, &iter, NULL, selected))
{
gchar* uri;
gtk_tree_model_get (model, &iter, URI_COL, &uri, -1);
/* Update the layout without actually changing the text */
pango_layout_set_text (gtk_entry_get_layout (entry), uri, -1);
g_free (uri);
}
}
else
gtk_tree_selection_unselect_all (gtk_tree_view_get_selection (GTK_TREE_VIEW (location_action->treeview)));
location_action->completion_index = selected;
return TRUE;
}
@ -1147,12 +1174,237 @@ midori_location_action_focus_out_event_cb (GtkWidget* widget,
return FALSE;
}
#ifdef HAVE_GCR
#define GCR_API_SUBJECT_TO_CHANGE
#include <gcr/gcr.h>
#endif
#if defined (HAVE_LIBSOUP_2_34_0)
static GHashTable* message_map = NULL;
void
midori_map_add_message (SoupMessage* message)
{
SoupURI* uri = soup_message_get_uri (message);
if (message_map == NULL)
message_map = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref);
g_return_if_fail (uri && uri->host);
g_hash_table_insert (message_map, g_strdup (uri->host), g_object_ref (message));
}
SoupMessage*
midori_map_get_message (SoupMessage* message)
{
SoupURI* uri = soup_message_get_uri (message);
SoupMessage* full;
g_return_val_if_fail (uri && uri->host, message);
full = g_hash_table_lookup (message_map, uri->host);
g_return_val_if_fail (full, message);
return full;
}
#ifdef HAVE_GCR
typedef enum {
MIDORI_CERT_TRUST,
MIDORI_CERT_REVOKE,
MIDORI_CERT_EXPORT,
} MidoriCertTrust;
static void
midori_location_action_cert_response_cb (GtkWidget* dialog,
gint response,
GcrCertificate* gcr_cert)
{
gchar* peer = g_object_get_data (G_OBJECT (gcr_cert), "peer");
GError* error = NULL;
if (response == MIDORI_CERT_TRUST)
gcr_trust_add_pinned_certificate (gcr_cert, GCR_PURPOSE_SERVER_AUTH, peer, NULL, &error);
else if (response == MIDORI_CERT_REVOKE)
gcr_trust_remove_pinned_certificate (gcr_cert, GCR_PURPOSE_SERVER_AUTH, peer, NULL, &error);
else if (response == MIDORI_CERT_EXPORT)
{
/* FIXME: Would be nice if GcrCertificateExporter became public */
gchar* filename = g_strconcat (peer, ".crt", NULL);
GtkWidget* dialog = sokoke_file_chooser_dialog_new (_("Export certificate"),
NULL, GTK_FILE_CHOOSER_ACTION_SAVE);
gtk_file_chooser_set_do_overwrite_confirmation (GTK_FILE_CHOOSER (dialog), TRUE);
gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (dialog), filename);
g_free (filename);
if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_OK)
{
gsize n_data;
gconstpointer data = gcr_certificate_get_der_data (gcr_cert, &n_data);
g_return_if_fail (data);
filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
g_file_set_contents (filename, data, n_data, NULL);
g_free (filename);
}
gtk_widget_destroy (dialog);
}
if (error != NULL)
{
g_warning ("Error %s trust: %s", response == MIDORI_CERT_TRUST ?
"granting" : "revoking", error->message);
g_error_free (error);
}
gtk_widget_destroy (dialog);
}
#endif
const gchar*
midori_location_action_tls_flags_to_string (GTlsCertificateFlags tls_flags)
{
const gchar* tls_error;
if (tls_flags & G_TLS_CERTIFICATE_UNKNOWN_CA)
tls_error = _("The signing certificate authority is not known.");
else if (tls_flags & G_TLS_CERTIFICATE_BAD_IDENTITY)
tls_error = _("The certificate does not match the expected identity of the site that it was retrieved from.");
else if(tls_flags & G_TLS_CERTIFICATE_NOT_ACTIVATED)
tls_error = _("The certificate's activation time is still in the future.");
else if (tls_flags & G_TLS_CERTIFICATE_EXPIRED)
tls_error = _("The certificate has expired");
else if (tls_flags & G_TLS_CERTIFICATE_REVOKED)
tls_error = _("The certificate has been revoked according to the GTlsConnection's certificate revocation list.");
else if (tls_flags & G_TLS_CERTIFICATE_INSECURE)
tls_error = _("The certificate's algorithm is considered insecure.");
else if (tls_flags & G_TLS_CERTIFICATE_GENERIC_ERROR)
tls_error = _("Some other error occurred validating the certificate.");
else
tls_error = "Unknown GTLSCertificateFlags value";
return tls_error;
}
void
midori_location_action_show_page_info (GtkWidget* widget,
GtkBox* box,
GtkWidget* dialog)
{
MidoriBrowser* browser = midori_browser_get_for_widget (widget);
MidoriView* view = MIDORI_VIEW (midori_browser_get_current_tab (browser));
WebKitWebView* web_view = WEBKIT_WEB_VIEW (midori_view_get_web_view (view));
WebKitWebFrame* web_frame = webkit_web_view_get_main_frame (web_view);
WebKitWebDataSource* source = webkit_web_frame_get_data_source (web_frame);
WebKitNetworkRequest* request = webkit_web_data_source_get_request (source);
SoupMessage* message = midori_map_get_message (webkit_network_request_get_message (request));
GTlsCertificate* tls_cert;
GTlsCertificateFlags tls_flags;
g_return_if_fail (message);
g_object_get (message, "tls-certificate", &tls_cert, "tls-errors", &tls_flags, NULL);
if (tls_cert == NULL)
return;
#ifdef HAVE_GCR
GByteArray* der_cert;
GcrCertificate* gcr_cert;
GtkWidget* details;
SoupURI* uri = soup_message_get_uri (message);
g_object_get (tls_cert, "certificate", &der_cert, NULL);
gcr_cert = gcr_simple_certificate_new (
der_cert->data, der_cert->len);
g_byte_array_unref (der_cert);
details = (GtkWidget*)gcr_certificate_details_widget_new (gcr_cert);
gtk_widget_show (details);
gtk_container_add (GTK_CONTAINER (box), details);
if (gcr_trust_is_certificate_pinned (gcr_cert, GCR_PURPOSE_SERVER_AUTH, uri->host, NULL, NULL))
gtk_dialog_add_buttons (GTK_DIALOG (dialog),
("_Don't trust this website"), MIDORI_CERT_REVOKE, NULL);
else if (tls_flags > 0)
gtk_dialog_add_buttons (GTK_DIALOG (dialog),
("_Trust this website"), MIDORI_CERT_TRUST, NULL);
gtk_container_child_set (GTK_CONTAINER (gtk_dialog_get_action_area (GTK_DIALOG (dialog))),
gtk_dialog_add_button (GTK_DIALOG (dialog), _("_Export certificate"), MIDORI_CERT_EXPORT),
"secondary", TRUE, NULL);
g_object_set_data_full (G_OBJECT (gcr_cert), "peer", g_strdup (uri->host), (GDestroyNotify)g_free);
g_object_set_data_full (G_OBJECT (dialog), "gcr-cert", gcr_cert, (GDestroyNotify)g_object_unref);
g_signal_connect (dialog, "response",
G_CALLBACK (midori_location_action_cert_response_cb), gcr_cert);
/* With GTK+2 the scrolled contents can't communicate a natural size to the window */
#if !GTK_CHECK_VERSION (3, 0, 0)
gtk_window_set_default_size (GTK_WINDOW (dialog), 250, 200);
#endif
#else
const gchar* tls_error = midori_location_action_tls_flags_to_string (tls_flags);
if (!g_tls_certificate_get_issuer (tls_cert))
gtk_box_pack_start (box, gtk_label_new (_("Self-signed")), FALSE, FALSE, 0);
gtk_box_pack_start (box, gtk_label_new (tls_error), FALSE, FALSE, 0);
#endif
g_object_unref (tls_cert);
}
#endif
#ifndef HAVE_GRANITE
static gboolean
midori_location_action_dialog_focus_out_cb (GtkWidget* dialog,
GdkEvent* event,
gpointer user_data)
{
gtk_widget_destroy (dialog);
return TRUE;
}
#endif
static void
midori_location_action_icon_released_cb (GtkWidget* widget,
GtkIconEntryPosition icon_pos,
gint button,
GtkAction* action)
{
/* The dialog should "toggle" like a menu, as far as users go
FIXME: Half-working: the dialog closes but re-opens */
static GtkWidget* dialog = NULL;
if (icon_pos == GTK_ICON_ENTRY_PRIMARY && dialog != NULL)
gtk_widget_destroy (dialog);
if (icon_pos == GTK_ICON_ENTRY_PRIMARY)
{
const gchar* title = _("Security details");
GtkWidget* content_area;
GtkWidget* hbox;
#ifdef HAVE_GRANITE
gint root_x, root_y;
GdkRectangle icon_rect;
/* FIXME: granite: should return GtkWidget* like GTK+ */
dialog = (GtkWidget*)granite_widgets_pop_over_new ();
gchar* markup = g_strdup_printf ("<b>%s</b>", title);
GtkWidget* label = gtk_label_new (markup);
content_area = gtk_dialog_get_content_area (GTK_DIALOG (dialog));
g_free (markup);
gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
gtk_box_pack_start (GTK_BOX (content_area), label, FALSE, FALSE, 0);
gtk_entry_get_icon_area (GTK_ENTRY (widget), icon_pos, &icon_rect);
gdk_window_get_root_coords (gtk_widget_get_window (widget),
icon_rect.x + icon_rect.width / 2, icon_rect.y + icon_rect.height,
&root_x, &root_y);
granite_widgets_pop_over_move_to_coords (GRANITE_WIDGETS_POP_OVER (dialog),
root_x, root_y, TRUE);
#else
dialog = gtk_dialog_new_with_buttons (title, GTK_WINDOW (gtk_widget_get_toplevel (widget)),
GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_NO_SEPARATOR, NULL, NULL);
/* FIXME: check focus-in on the transient-for window instead of
focus-out-event */
g_signal_connect (dialog, "focus-out-event",
G_CALLBACK (midori_location_action_dialog_focus_out_cb), NULL);
content_area = gtk_dialog_get_content_area (GTK_DIALOG (dialog));
#endif
hbox = gtk_hbox_new (FALSE, 0);
gtk_box_pack_start (GTK_BOX (hbox), gtk_image_new_from_gicon (
gtk_entry_get_icon_gicon (GTK_ENTRY (widget), icon_pos), GTK_ICON_SIZE_DIALOG), FALSE, FALSE, 0);
gtk_box_pack_start (GTK_BOX (hbox),
gtk_label_new (gtk_icon_entry_get_tooltip (GTK_ICON_ENTRY (widget), icon_pos)), FALSE, FALSE, 0);
gtk_box_pack_start (GTK_BOX (content_area), hbox, FALSE, FALSE, 0);
#if defined (HAVE_LIBSOUP_2_34_0)
midori_location_action_show_page_info (widget, GTK_BOX (content_area), dialog);
#endif
g_signal_connect (dialog, "destroy", G_CALLBACK (gtk_widget_destroyed), &dialog);
gtk_widget_show_all (dialog);
}
if (icon_pos == GTK_ICON_ENTRY_SECONDARY)
{
gboolean result;
@ -1711,91 +1963,30 @@ midori_location_action_set_security_hint (MidoriLocationAction* location_action,
for (; proxies != NULL; proxies = g_slist_next (proxies))
if (GTK_IS_TOOL_ITEM (proxies->data))
{
#if !GTK_CHECK_VERSION (3, 0, 0)
const gchar* bg_color = NULL;
const gchar* fg_color = NULL;
#endif
GtkWidget* entry = midori_location_action_entry_for_proxy (proxies->data);
GdkScreen* screen = gtk_widget_get_screen (entry);
GtkIconTheme* icon_theme = gtk_icon_theme_get_for_screen (screen);
if (hint == MIDORI_SECURITY_UNKNOWN)
{
#if !GTK_CHECK_VERSION (3, 0, 0)
bg_color = "#ef7070";
fg_color = "#000";
#endif
#if !HAVE_HILDON
if (gtk_icon_theme_has_icon (icon_theme, "channel-insecure-symbolic"))
gtk_icon_entry_set_icon_from_icon_name (GTK_ICON_ENTRY (entry),
GTK_ICON_ENTRY_PRIMARY, "channel-insecure-symbolic");
else if (gtk_icon_theme_has_icon (icon_theme, "lock-insecure"))
gtk_icon_entry_set_icon_from_icon_name (GTK_ICON_ENTRY (entry),
GTK_ICON_ENTRY_PRIMARY, "lock-insecure");
else
gtk_icon_entry_set_icon_from_stock (GTK_ICON_ENTRY (entry),
GTK_ICON_ENTRY_PRIMARY, GTK_STOCK_INFO);
gchar* icon_names[] = { "channel-insecure-symbolic", "lock-insecure", "dialog-information", NULL };
gtk_entry_set_icon_from_gicon (GTK_ENTRY (entry), GTK_ICON_ENTRY_PRIMARY,
g_themed_icon_new_from_names (icon_names, -1));
gtk_icon_entry_set_tooltip (GTK_ICON_ENTRY (entry),
GTK_ICON_ENTRY_PRIMARY, _("Not verified"));
#endif
}
else if (hint == MIDORI_SECURITY_TRUSTED)
{
#if !GTK_CHECK_VERSION (3, 0, 0)
bg_color = "#d1eeb9";
fg_color = "#000";
#endif
#if !HAVE_HILDON
if (gtk_icon_theme_has_icon (icon_theme, "channel-secure-symbolic"))
gtk_icon_entry_set_icon_from_icon_name (GTK_ICON_ENTRY (entry),
GTK_ICON_ENTRY_PRIMARY, "channel-secure-symbolic");
else if (gtk_icon_theme_has_icon (icon_theme, "lock-secure"))
gtk_icon_entry_set_icon_from_icon_name (GTK_ICON_ENTRY (entry),
GTK_ICON_ENTRY_PRIMARY, "lock-secure");
else
gtk_icon_entry_set_icon_from_stock (GTK_ICON_ENTRY (entry),
GTK_ICON_ENTRY_PRIMARY, GTK_STOCK_DIALOG_AUTHENTICATION);
gchar* icon_names[] = { "channel-secure-symbolic", "lock-secure", "locked", NULL };
gtk_entry_set_icon_from_gicon (GTK_ENTRY (entry), GTK_ICON_ENTRY_PRIMARY,
g_themed_icon_new_from_names (icon_names, -1));
gtk_icon_entry_set_tooltip (GTK_ICON_ENTRY (entry),
GTK_ICON_ENTRY_PRIMARY, _("Verified and encrypted connection"));
#endif
}
else if (hint == MIDORI_SECURITY_NONE)
{
if (gtk_icon_theme_has_icon (icon_theme, "text-html-symbolic"))
gtk_icon_entry_set_icon_from_icon_name (GTK_ICON_ENTRY (entry),
GTK_ICON_ENTRY_PRIMARY, "text-html-symbolic");
else
gtk_icon_entry_set_icon_from_icon_name (GTK_ICON_ENTRY (entry),
GTK_ICON_ENTRY_PRIMARY, "text-html");
gtk_entry_set_icon_from_gicon (GTK_ENTRY (entry), GTK_ICON_ENTRY_PRIMARY,
g_themed_icon_new_with_default_fallbacks ("text-html-symbolic"));
gtk_icon_entry_set_tooltip (GTK_ICON_ENTRY (entry),
GTK_ICON_ENTRY_PRIMARY, _("Open, unencrypted connection"));
}
{
#if GTK_CHECK_VERSION (3, 0, 0)
GtkStyleContext* context = gtk_widget_get_style_context (entry);
if (hint == MIDORI_SECURITY_UNKNOWN)
{
gtk_style_context_add_class (context, "security_unknown");
gtk_style_context_remove_class (context, "security_trusted");
}
else if (hint == MIDORI_SECURITY_TRUSTED)
{
gtk_style_context_add_class (context, "security_trusted");
gtk_style_context_remove_class (context, "security_unknown");
}
else if (hint == MIDORI_SECURITY_NONE)
{
gtk_style_context_remove_class (context, "security_unknown");
gtk_style_context_remove_class (context, "security_trusted");
}
#else
GdkColor color = { 0 };
if (bg_color) gdk_color_parse (bg_color, &color);
gtk_widget_modify_base (entry, GTK_STATE_NORMAL, bg_color ? &color : NULL);
if (fg_color) gdk_color_parse (fg_color, &color);
gtk_widget_modify_text (entry, GTK_STATE_NORMAL, fg_color ? &color : NULL);
#endif
}
}
}

View file

@ -1,227 +0,0 @@
/*
Copyright (C) 2011 Peter Hatina <phatina@redhat.com>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
See the file COPYING for the full license text.
*/
#include <string.h>
#include <katze/katze.h>
#include "midori-panedaction.h"
struct _MidoriPanedActionChild
{
GtkWidget* widget;
gchar* name;
gboolean resize;
gboolean shrink;
};
struct _MidoriPanedAction
{
GtkAction parent_instance;
GtkWidget* hpaned;
GtkWidget* toolitem;
struct _MidoriPanedActionChild child1;
struct _MidoriPanedActionChild child2;
};
struct _MidoriPanedActionClass
{
GtkActionClass parent_class;
};
G_DEFINE_TYPE (MidoriPanedAction, midori_paned_action, GTK_TYPE_ACTION);
static GtkWidget*
midori_paned_action_create_tool_item (GtkAction *action);
static void
midori_paned_action_finalize (GObject* object);
static void
midori_paned_action_init (MidoriPanedAction* paned_action)
{
paned_action->hpaned = NULL;
paned_action->toolitem = NULL;
memset ((void*) &paned_action->child1, 0, sizeof (struct _MidoriPanedActionChild));
memset ((void*) &paned_action->child2, 0, sizeof (struct _MidoriPanedActionChild));
}
static void
midori_paned_action_finalize (GObject* object)
{
MidoriPanedAction* paned_action = MIDORI_PANED_ACTION (object);
g_object_unref (G_OBJECT (paned_action->toolitem));
g_object_unref (G_OBJECT (paned_action->hpaned));
katze_assign (paned_action->child1.name, NULL);
katze_assign (paned_action->child2.name, NULL);
G_OBJECT_CLASS (midori_paned_action_parent_class)->finalize (object);
}
static void
midori_paned_action_class_init (MidoriPanedActionClass* class)
{
GObjectClass* gobject_class;
GtkActionClass* action_class;
gobject_class = G_OBJECT_CLASS (class);
gobject_class->finalize = midori_paned_action_finalize;
action_class = GTK_ACTION_CLASS (class);
action_class->create_tool_item = midori_paned_action_create_tool_item;
}
static GtkWidget*
midori_paned_action_create_tool_item (GtkAction* action)
{
MidoriPanedAction* paned_action = MIDORI_PANED_ACTION (action);
GtkWidget* alignment = gtk_alignment_new (0.0f, 0.5f, 1.0f, 0.1f);
paned_action->hpaned = gtk_hpaned_new ();
paned_action->toolitem = GTK_WIDGET (gtk_tool_item_new ());
gtk_tool_item_set_expand (GTK_TOOL_ITEM (paned_action->toolitem), TRUE);
gtk_container_add (GTK_CONTAINER (paned_action->toolitem), alignment);
gtk_container_add (GTK_CONTAINER (alignment), GTK_WIDGET (paned_action->hpaned));
gtk_paned_pack1 (GTK_PANED (paned_action->hpaned),
paned_action->child1.widget,
paned_action->child1.resize,
paned_action->child1.shrink);
gtk_paned_pack2 (GTK_PANED (paned_action->hpaned),
paned_action->child2.widget,
paned_action->child2.resize,
paned_action->child2.shrink);
gtk_widget_show_all (GTK_WIDGET (paned_action->toolitem));
return paned_action->toolitem;
}
/**
* midori_paned_action_set_child1:
* @paned_action: a #MidoriPanedAction
* @child1: a #GtkWidget to be added into GtkHPaned container
* @name: string name for the child2
* @resize: should child1 expand when the MidoriPanedAction is resized
* @shrink: can child1 be made smaller than its requisition
**/
void
midori_paned_action_set_child1 (MidoriPanedAction* paned_action,
GtkWidget* child1,
const gchar* name,
gboolean resize,
gboolean shrink)
{
g_return_if_fail (MIDORI_IS_PANED_ACTION (paned_action));
katze_assign (paned_action->child1.name, g_strdup (name));
paned_action->child1.widget = child1;
paned_action->child1.resize = resize;
paned_action->child1.shrink = shrink;
}
/**
* midori_paned_action_set_child1:
* @paned_action: a #MidoriPanedAction
* @child2: a #GtkWidget to be added into GtkHPaned container
* @name: string name for the child2
* @resize: should child2 expand when the MidoriPanedAction is resized
* @shrink: can child2 be made smaller than its requisition
**/
void
midori_paned_action_set_child2 (MidoriPanedAction* paned_action,
GtkWidget* child2,
const gchar* name,
gboolean resize,
gboolean shrink)
{
g_return_if_fail (MIDORI_IS_PANED_ACTION (paned_action));
katze_assign (paned_action->child2.name, g_strdup (name));
paned_action->child2.widget = child2;
paned_action->child2.resize = resize;
paned_action->child2.shrink = shrink;
}
/**
* midori_paned_action_get_child1:
* @paned_action: a #MidoriPanedAction
*
* returns the first child held in GtkHPaned container
**/
GtkWidget*
midori_paned_action_get_child1 (MidoriPanedAction* paned_action)
{
g_return_val_if_fail (MIDORI_IS_PANED_ACTION (paned_action), NULL);
return paned_action->child1.widget;
}
/**
* midori_paned_action_get_child1:
* @paned_action: a #MidoriPanedAction
*
* returns the second child held in GtkHPaned container
**/
GtkWidget*
midori_paned_action_get_child2 (MidoriPanedAction* paned_action)
{
g_return_val_if_fail (MIDORI_IS_PANED_ACTION (paned_action), NULL);
return paned_action->child2.widget;
}
/**
* midori_paned_action_get_child1:
* @paned_action: a #MidoriPanedAction
* @name: string name for one of the children
*
* returns a child specified by its name
**/
GtkWidget*
midori_paned_action_get_child_by_name (MidoriPanedAction* paned_action,
const gchar* name)
{
g_return_val_if_fail (MIDORI_IS_PANED_ACTION (paned_action), NULL);
g_return_val_if_fail (name != NULL, NULL);
if (g_strcmp0 (name, paned_action->child1.name) == 0)
return midori_paned_action_get_child1 (paned_action);
else if (g_strcmp0 (name, paned_action->child2.name) == 0)
return midori_paned_action_get_child2 (paned_action);
return NULL;
}
/**
* midori_paned_action_get_child1_name:
* @paned_action a #MidoriPanedAction
*
* Returns: The name of the first child
**/
const gchar*
midori_paned_action_get_child1_name (MidoriPanedAction* paned_action)
{
g_return_val_if_fail (MIDORI_IS_PANED_ACTION (paned_action), NULL);
return paned_action->child1.name;
}
/**
* midori_paned_action_get_child2_name:
* @paned_action a #MidoriPanedAction
*
* Returns: The name of the second child
**/
const gchar*
midori_paned_action_get_child2_name (MidoriPanedAction* paned_action)
{
g_return_val_if_fail (MIDORI_IS_PANED_ACTION (paned_action), NULL);
return paned_action->child2.name;
}

View file

@ -1,70 +0,0 @@
/*
Copyright (C) 2011 Peter Hatina <phatina@redhat.com>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
See the file COPYING for the full license text.
*/
#ifndef __MIDORI_PANED_ACTION_H__
#define __MIDORI_PANED_ACTION_H__
#include <gtk/gtk.h>
G_BEGIN_DECLS
#define MIDORI_TYPE_PANED_ACTION \
(midori_paned_action_get_type ())
#define MIDORI_PANED_ACTION(obj) \
(G_TYPE_CHECK_INSTANCE_CAST ((obj), MIDORI_TYPE_PANED_ACTION, MidoriPanedAction))
#define MIDORI_PANED_ACTION_CLASS(klass) \
(G_TYPE_CHECK_CLASS_CAST ((klass), MIDORI_PANED_ACTION, MidoriPanedActionClass))
#define MIDORI_IS_PANED_ACTION(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE ((obj), MIDORI_TYPE_PANED_ACTION))
#define MIDORI_IS_PANED_ACTION_CLASS(klass) \
(G_TYPE_CHECK_CLASS_TYPE ((klass), MIDORI_TYPE_PANED_ACTION))
#define MIDORI_PANED_ACTION_GET_CLASS(obj) \
(G_TYPE_INSTANCE_GET_CLASS ((obj), MIDORI_TYPE_PANED_ACTION, MidoriPanedActionClass))
typedef struct _MidoriPanedAction MidoriPanedAction;
typedef struct _MidoriPanedActionClass MidoriPanedActionClass;
GType
midori_paned_action_get_type (void) G_GNUC_CONST;
void
midori_paned_action_set_child1 (MidoriPanedAction* paned_action,
GtkWidget* child1,
const gchar* name,
gboolean resize,
gboolean shrink);
void
midori_paned_action_set_child2 (MidoriPanedAction* paned_action,
GtkWidget* child2,
const gchar* name,
gboolean resize,
gboolean shrink);
GtkWidget*
midori_paned_action_get_child1 (MidoriPanedAction* paned_action);
GtkWidget*
midori_paned_action_get_child2 (MidoriPanedAction* paned_action);
GtkWidget*
midori_paned_action_get_child_by_name (MidoriPanedAction* paned_action,
const gchar* name);
const gchar*
midori_paned_action_get_child1_name (MidoriPanedAction* paned_action);
const gchar*
midori_paned_action_get_child2_name (MidoriPanedAction* paned_action);
G_END_DECLS
#endif // __MIDORI_PANED_ACTION_H__

View file

@ -0,0 +1,79 @@
/*
Copyright (C) 2011 Peter Hatina <phatina@redhat.com>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
See the file COPYING for the full license text.
*/
namespace Midori {
public class PanedAction : Gtk.Action {
Gtk.HPaned? hpaned = null;
Gtk.ToolItem? toolitem = null;
Child child1 = new Child();
Child child2 = new Child();
private struct Child {
protected Gtk.Widget widget;
string name;
bool resize;
bool shrink;
}
public override unowned Gtk.Widget create_tool_item () {
Gtk.Alignment alignment = new Gtk.Alignment (0.0f, 0.5f, 1.0f, 0.1f);
hpaned = new Gtk.HPaned ();
toolitem = new Gtk.ToolItem ();
toolitem.set_expand (true);
toolitem.add (alignment);
alignment.add (hpaned);
hpaned.pack1 (child1.widget, child1.resize, child1.shrink);
hpaned.pack2 (child2.widget, child2.resize, child2.shrink);
toolitem.show_all ();
return toolitem;
}
public void set_child1 (Gtk.Widget widget, string name, bool resize, bool shrink) {
child1.widget = widget;
child1.name = name;
child1.resize = resize;
child1.shrink = shrink;
}
public void set_child2 (Gtk.Widget widget, string name, bool resize, bool shrink) {
child2.widget = widget;
child2.name = name;
child2.resize = resize;
child2.shrink = shrink;
}
public Gtk.Widget? get_child1 () {
return child1.widget;
}
public Gtk.Widget? get_child2 () {
return child2.widget;
}
public Gtk.Widget? get_child_by_name (string name) {
if (name == child1.name)
return child1.widget;
else if (name == child2.name)
return child2.widget;
return null;
}
public string get_child1_name () {
return child1.name;
}
public string get_child2_name () {
return child2.name;
}
}
}

View file

@ -253,36 +253,6 @@ static GtkWidget*
_midori_panel_child_for_scrolled (MidoriPanel* panel,
GtkWidget* scrolled);
static gboolean
midori_panel_detached_window_delete_event_cb (GtkWidget* window,
GdkEvent* event,
MidoriPanel* panel)
{
/* FIXME: The panel will not end up at its original position */
/* FIXME: The menuitem may be mispositioned */
GtkWidget* vbox = gtk_bin_get_child (GTK_BIN (window));
GtkWidget* scrolled = g_object_get_data (G_OBJECT (window), "scrolled");
GtkWidget* toolbar = g_object_get_data (G_OBJECT (scrolled), "panel-toolbar");
GtkWidget* menuitem = g_object_get_data (G_OBJECT (scrolled), "panel-menuitem");
GtkWidget* viewable = _midori_panel_child_for_scrolled (panel, scrolled);
GtkToolItem* toolitem;
gint n;
g_object_ref (toolbar);
gtk_container_remove (GTK_CONTAINER (vbox), toolbar);
gtk_container_add (GTK_CONTAINER (panel->toolbook), toolbar);
g_object_unref (toolbar);
g_object_ref (scrolled);
gtk_container_remove (GTK_CONTAINER (vbox), scrolled);
n = gtk_notebook_append_page (GTK_NOTEBOOK (panel->notebook), scrolled, NULL);
g_object_unref (scrolled);
toolitem = midori_panel_construct_tool_item (panel, MIDORI_VIEWABLE (viewable));
if (menuitem)
g_object_set_data (G_OBJECT (menuitem), "toolitem", toolitem);
midori_panel_set_current_page (panel, n);
return FALSE;
}
static void
midori_panel_widget_destroy_cb (GtkWidget* viewable,
GtkWidget* widget)
@ -292,57 +262,6 @@ midori_panel_widget_destroy_cb (GtkWidget* viewable,
viewable, midori_panel_widget_destroy_cb, widget);
}
static void
midori_panel_detach_page (MidoriPanel* panel,
gint n)
{
GtkToolItem* toolitem = gtk_toolbar_get_nth_item (
GTK_TOOLBAR (panel->toolbar), n);
const gchar* title = gtk_tool_button_get_label (GTK_TOOL_BUTTON (toolitem));
GtkWidget* toolbar = gtk_notebook_get_nth_page (
GTK_NOTEBOOK (panel->toolbook), n);
GtkWidget* scrolled = gtk_notebook_get_nth_page (
GTK_NOTEBOOK (panel->notebook), n);
GtkWidget* vbox = gtk_vbox_new (FALSE, 0);
#if HAVE_HILDON
GtkWidget* window = hildon_window_new ();
hildon_program_add_window (hildon_program_get_instance (), HILDON_WINDOW (window));
#else
GtkWidget* window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_window_set_skip_taskbar_hint (GTK_WINDOW (window), TRUE);
gtk_window_set_default_size (GTK_WINDOW (window), 250, 400);
gtk_window_set_transient_for (GTK_WINDOW (window),
GTK_WINDOW (gtk_widget_get_toplevel (panel->notebook)));
#endif
gtk_widget_show (vbox);
gtk_container_add (GTK_CONTAINER (window), vbox);
g_object_set_data (G_OBJECT (window), "scrolled", scrolled);
gtk_window_set_title (GTK_WINDOW (window), title);
g_signal_handlers_disconnect_by_func (
_midori_panel_child_for_scrolled (panel, scrolled),
midori_panel_widget_destroy_cb, toolitem);
gtk_container_remove (GTK_CONTAINER (panel->toolbar), GTK_WIDGET (toolitem));
g_object_ref (toolbar);
gtk_container_remove (GTK_CONTAINER (panel->toolbook), toolbar);
#if HAVE_HILDON
hildon_window_add_toolbar (HILDON_WINDOW (window), GTK_TOOLBAR (toolbar));
#else
gtk_box_pack_start (GTK_BOX (vbox), toolbar, FALSE, FALSE, 0);
#endif
g_object_unref (toolbar);
g_object_set_data (G_OBJECT (scrolled), "panel-toolbar", toolbar);
g_object_ref (scrolled);
gtk_container_remove (GTK_CONTAINER (panel->notebook), scrolled);
gtk_box_pack_start (GTK_BOX (vbox), scrolled, TRUE, TRUE, 0);
g_object_unref (scrolled);
midori_panel_set_current_page (panel, n > 0 ? n - 1 : 0);
toolitem = gtk_toolbar_get_nth_item (GTK_TOOLBAR (panel->toolbar),
n > 0 ? n - 1 : 0);
g_signal_connect (window, "delete-event",
G_CALLBACK (midori_panel_detached_window_delete_event_cb), panel);
gtk_widget_show (window);
}
static void
midori_panel_button_align_clicked_cb (GtkWidget* toolitem,
MidoriPanel* panel)
@ -381,6 +300,7 @@ midori_panel_init (MidoriPanel* panel)
/* Create the titlebar */
labelbar = gtk_toolbar_new ();
katze_widget_add_class (labelbar, "secondary-toolbar");
panel->labelbar = labelbar;
gtk_toolbar_set_icon_size (GTK_TOOLBAR (labelbar), GTK_ICON_SIZE_MENU);
gtk_toolbar_set_style (GTK_TOOLBAR (labelbar), GTK_TOOLBAR_ICONS);
@ -426,6 +346,7 @@ midori_panel_init (MidoriPanel* panel)
/* Create the notebook */
panel->notebook = gtk_notebook_new ();
katze_widget_add_class (panel->notebook, "content-view");
gtk_notebook_set_show_border (GTK_NOTEBOOK (panel->notebook), FALSE);
gtk_notebook_set_show_tabs (GTK_NOTEBOOK (panel->notebook), FALSE);
panel->frame = gtk_frame_new (NULL);
@ -570,13 +491,15 @@ midori_panel_set_right_aligned (MidoriPanel* panel,
/* Private function, used by MidoriBrowser */
/* static */ GtkWidget*
midori_panel_construct_menu_item (MidoriPanel* panel,
MidoriViewable* viewable)
MidoriViewable* viewable,
gboolean popup)
{
GtkAction* action;
GtkWidget* menuitem;
action = g_object_get_data (G_OBJECT (viewable), "midori-panel-action");
menuitem = gtk_action_create_menu_item (action);
menuitem = popup ? sokoke_action_create_popup_menu_item (action)
: gtk_action_create_menu_item (action);
g_object_set_data (G_OBJECT (menuitem), "page", viewable);
if (gtk_widget_get_visible (GTK_WIDGET (viewable)))
@ -638,24 +561,9 @@ midori_panel_action_activate_cb (GtkRadioAction* action,
GtkWidget* viewable = g_object_get_data (G_OBJECT (action), "viewable");
gint n = midori_panel_page_num (panel, viewable);
/* If the panel is detached, focus the window */
if (n == -1)
{
GtkWidget* toplevel = gtk_widget_get_toplevel (viewable);
gtk_window_present (GTK_WINDOW (toplevel));
return;
}
if (panel->open_panels_in_windows
&& gtk_radio_action_get_current_value (action)
== katze_object_get_int (action, "value"))
midori_panel_detach_page (panel, n);
else
{
midori_panel_set_current_page (panel, n);
g_signal_emit (panel, signals[SWITCH_PAGE], 0, n);
gtk_widget_show (GTK_WIDGET (panel));
}
midori_panel_set_current_page (panel, n);
g_signal_emit (panel, signals[SWITCH_PAGE], 0, n);
gtk_widget_show (GTK_WIDGET (panel));
}
/**
@ -710,7 +618,7 @@ midori_panel_append_page (MidoriPanel* panel,
{
scrolled = gtk_scrolled_window_new (NULL, NULL);
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled),
GTK_POLICY_AUTOMATIC,
GTK_POLICY_NEVER,
GTK_POLICY_AUTOMATIC);
gtk_widget_set_can_focus (scrolled, TRUE);
gtk_widget_show (scrolled);

View file

@ -12,11 +12,7 @@
#ifndef __MIDORI_PANEL_H__
#define __MIDORI_PANEL_H__
#include <gtk/gtk.h>
#include <katze/katze.h>
#include "midori-viewable.h"
#include "midori-core.h"
G_BEGIN_DECLS

View file

@ -38,11 +38,6 @@
&& MIDORI_MOD_NEW_TAB(((GdkEventButton*)evt)->state)) \
|| (((GdkEventButton*)evt)->button == 2)))
#ifndef G_OS_WIN32
#define MIDORI_MODULE_PREFIX "lib"
#else
#define MIDORI_MODULE_PREFIX ""
#endif
#define MIDORI_MODULE_PREFIX "lib"
#endif /* !__MIDORI_PLATFORM_H__ */

View file

@ -11,6 +11,8 @@
#include "midori-preferences.h"
#include "midori-app.h"
#include "midori-core.h"
#include "midori-platform.h"
#include <string.h>
@ -292,7 +294,7 @@ midori_preferences_set_settings (MidoriPreferences* preferences,
#define SPANNED_ADD(__widget) \
katze_preferences_add_widget (_preferences, __widget, "spanned")
/* Page "General" */
if (!sokoke_is_app_or_private ())
if (!midori_paths_is_readonly ())
{
PAGE_NEW (GTK_STOCK_HOME, _("Startup"));
FRAME_NEW (NULL);
@ -300,7 +302,8 @@ midori_preferences_set_settings (MidoriPreferences* preferences,
INDENTED_ADD (label);
button = katze_property_proxy (settings, "load-on-startup", NULL);
SPANNED_ADD (button);
label = katze_property_label (settings, "homepage");
label = gtk_label_new (_("Homepage:"));
gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
INDENTED_ADD (label);
entry = katze_property_proxy (settings, "homepage", "address");
SPANNED_ADD (entry);
@ -350,7 +353,8 @@ midori_preferences_set_settings (MidoriPreferences* preferences,
button = katze_property_proxy (settings, "enforce-font-family", NULL);
INDENTED_ADD (button);
#endif
label = katze_property_label (settings, "preferred-encoding");
label = gtk_label_new (_("Preferred Encoding"));
gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
INDENTED_ADD (label);
button = katze_property_proxy (settings, "preferred-encoding", "custom-default-encoding");
SPANNED_ADD (button);
@ -360,12 +364,14 @@ midori_preferences_set_settings (MidoriPreferences* preferences,
FRAME_NEW (NULL);
#if !HAVE_HILDON
button = katze_property_proxy (settings, "auto-load-images", NULL);
gtk_button_set_label (GTK_BUTTON (button), _("Load images automatically"));
INDENTED_ADD (button);
button = katze_property_proxy (settings, "enable-spell-checking", NULL);
gtk_button_set_label (GTK_BUTTON (button), _("Enable Spell Checking"));
SPANNED_ADD (button);
/* Disable spell check option if there are no enchant modules */
{
gchar* enchant_path = sokoke_find_lib_path ("enchant");
gchar* enchant_path = midori_paths_get_lib_path ("enchant");
if (enchant_path == NULL)
{
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), FALSE);
@ -375,11 +381,15 @@ midori_preferences_set_settings (MidoriPreferences* preferences,
g_free (enchant_path);
}
button = katze_property_proxy (settings, "enable-scripts", NULL);
gtk_button_set_label (GTK_BUTTON (button), _("Enable scripts"));
INDENTED_ADD (button);
button = katze_property_proxy (settings, "enable-plugins", NULL);
gtk_button_set_label (GTK_BUTTON (button), _("Enable Netscape plugins"));
gtk_widget_set_sensitive (button, midori_web_settings_has_plugin_support ());
SPANNED_ADD (button);
#endif
button = katze_property_proxy (settings, "zoom-text-and-images", NULL);
gtk_button_set_label (GTK_BUTTON (button), _("Zoom Text and Images"));
INDENTED_ADD (button);
button = katze_property_proxy (settings, "javascript-can-open-windows-automatically", NULL);
gtk_button_set_label (GTK_BUTTON (button), _("Allow scripts to open popups"));
@ -387,30 +397,42 @@ midori_preferences_set_settings (MidoriPreferences* preferences,
SPANNED_ADD (button);
if (katze_widget_has_touchscreen_mode (parent ?
GTK_WIDGET (parent) : GTK_WIDGET (preferences)))
{
button = katze_property_proxy (settings, "kinetic-scrolling", NULL);
gtk_button_set_label (GTK_BUTTON (button), _("Kinetic scrolling"));
gtk_widget_set_tooltip_text (button, _("Whether scrolling should kinetically move according to speed"));
}
else
{
button = katze_property_proxy (settings, "middle-click-opens-selection", NULL);
gtk_button_set_label (GTK_BUTTON (button), _("Middle click opens Selection"));
gtk_widget_set_tooltip_text (button, _("Load an address from the selection via middle click"));
}
INDENTED_ADD (button);
button = katze_property_proxy (settings, "flash-window-on-new-bg-tabs", NULL);
SPANNED_ADD (button);
if (katze_object_has_property (settings, "enable-webgl"))
{
button = katze_property_proxy (settings, "enable-webgl", NULL);
INDENTED_ADD (button);
gtk_button_set_label (GTK_BUTTON (button), _("Enable WebGL support"));
SPANNED_ADD (button);
}
#ifndef G_OS_WIN32
button = katze_property_proxy (settings, "flash-window-on-new-bg-tabs", NULL);
gtk_button_set_label (GTK_BUTTON (button), _("Flash window on background tabs"));
INDENTED_ADD (button);
#endif
FRAME_NEW (NULL);
button = katze_property_label (settings, "preferred-languages");
button = gtk_label_new (_("Preferred languages"));
gtk_misc_set_alignment (GTK_MISC (button), 0.0, 0.5);
INDENTED_ADD (button);
entry = katze_property_proxy (settings, "preferred-languages", "languages");
gtk_widget_set_tooltip_text (entry, _("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\""));
SPANNED_ADD (entry);
#if !HAVE_HILDON
label = katze_property_label (settings, "download-folder");
label = gtk_label_new (_("Save downloaded files to:"));
gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
INDENTED_ADD (label);
button = katze_property_proxy (settings, "download-folder", "folder");
SPANNED_ADD (button);
#endif
/* Page "Interface" */
PAGE_NEW (GTK_STOCK_CONVERT, _("Browsing"));
@ -428,47 +450,51 @@ midori_preferences_set_settings (MidoriPreferences* preferences,
INDENTED_ADD (label);
button = katze_property_proxy (settings, "open-new-pages-in", NULL);
SPANNED_ADD (button);
#if !HAVE_HILDON
button = katze_property_proxy (settings, "close-buttons-on-tabs", NULL);
gtk_button_set_label (GTK_BUTTON (button), _("Close Buttons on Tabs"));
INDENTED_ADD (button);
#ifndef HAVE_GRANITE
button = katze_property_proxy (settings, "always-show-tabbar", NULL);
gtk_button_set_label (GTK_BUTTON (button), _("Always Show Tabbar"));
SPANNED_ADD (button);
#endif
#endif
button = katze_property_proxy (settings, "open-tabs-next-to-current", NULL);
gtk_button_set_label (GTK_BUTTON (button), _("Open Tabs next to Current"));
gtk_widget_set_tooltip_text (button, _("Whether to open new tabs next to the current tab or after the last one"));
INDENTED_ADD (button);
button = katze_property_proxy (settings, "open-tabs-in-the-background", NULL);
gtk_button_set_label (GTK_BUTTON (button), _("Open tabs in the background"));
SPANNED_ADD (button);
#if !HAVE_HILDON
INDENTED_ADD (gtk_label_new (NULL));
label = katze_property_label (settings, "text-editor");
label = gtk_label_new (_("Text Editor"));
gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
INDENTED_ADD (label);
entry = katze_property_proxy (settings, "text-editor", "application-text/plain");
SPANNED_ADD (entry);
label = katze_property_label (settings, "news-aggregator");
label = gtk_label_new (_("News Aggregator"));
gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
INDENTED_ADD (label);
entry = katze_property_proxy (settings, "news-aggregator", "application-News");
SPANNED_ADD (entry);
#endif
/* Page "Network" */
PAGE_NEW (GTK_STOCK_NETWORK, _("Network"));
FRAME_NEW (NULL);
#if !HAVE_HILDON
label = katze_property_label (settings, "proxy-type");
label = gtk_label_new (_("Proxy server"));
gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
INDENTED_ADD (label);
button = katze_property_proxy (settings, "proxy-type", NULL);
SPANNED_ADD (button);
label = gtk_label_new (_("Hostname"));
gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
INDENTED_ADD (label);
entry = katze_property_proxy (settings, "http-proxy", NULL);
entry = katze_property_proxy (settings, "http-proxy", "address");
SPANNED_ADD (entry);
g_signal_connect (settings, "notify::proxy-type",
G_CALLBACK (midori_preferences_notify_proxy_type_cb), entry);
midori_preferences_notify_proxy_type_cb (settings, NULL, entry);
label = katze_property_label (settings, "http-proxy-port");
label = gtk_label_new (_("Port"));
gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
INDENTED_ADD (label);
entry = katze_property_proxy (settings, "http-proxy-port", NULL);
@ -476,13 +502,14 @@ midori_preferences_set_settings (MidoriPreferences* preferences,
g_signal_connect (settings, "notify::proxy-type",
G_CALLBACK (midori_preferences_notify_proxy_type_cb), entry);
midori_preferences_notify_proxy_type_cb (settings, NULL, entry);
#endif
#if WEBKIT_CHECK_VERSION (1, 3, 11)
if (soup_session_get_feature (webkit_get_default_session (), SOUP_TYPE_CACHE))
{
label = katze_property_label (settings, "maximum-cache-size");
label = gtk_label_new (_("Web Cache"));
gtk_widget_set_tooltip_text (label, _("The maximum size of cached pages on disk"));
INDENTED_ADD (label);
button = katze_property_proxy (settings, "maximum-cache-size", NULL);
gtk_widget_set_tooltip_text (button, _("The maximum size of cached pages on disk"));
SPANNED_ADD (button);
label = gtk_label_new (_("MB"));
gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);

View file

@ -311,8 +311,7 @@ midori_search_action_create_tool_item (GtkAction* action)
GtkWidget* alignment;
toolitem = GTK_WIDGET (gtk_tool_item_new ());
entry = gtk_icon_entry_new ();
sokoke_entry_set_clear_button_visible (GTK_ENTRY (entry), TRUE);
entry = sokoke_search_entry_new (NULL);
gtk_icon_entry_set_icon_highlight (GTK_ICON_ENTRY (entry),
GTK_ICON_ENTRY_PRIMARY, TRUE);
alignment = gtk_alignment_new (0, 0.5, 1, 0.1);
@ -433,7 +432,7 @@ midori_search_action_get_icon (KatzeItem* item,
else if (gtk_icon_theme_has_icon (icon_theme, "edit-find-option"))
*icon_name = "edit-find-option";
else
*icon_name = "edit-find";
*icon_name = STOCK_EDIT_FIND;
return NULL;
}
@ -877,15 +876,189 @@ midori_search_action_editor_name_changed_cb (GtkWidget* entry,
GTK_RESPONSE_ACCEPT, text && *text);
}
static void
gchar*
midori_search_action_token_for_uri (const gchar* uri)
{
guint len, i;
gchar** parts;
gchar* hostname = NULL, *path = NULL;
path = midori_uri_parse_hostname (uri, NULL);
parts = g_strsplit (path, ".", -1);
g_free (path);
len = g_strv_length (parts);
if (len > 2)
{
for (i = len; i == 0; i--)
{
if (parts[i] && *parts[i])
if (strlen (parts[i]) > 3)
{
hostname = g_strdup (parts[i]);
break;
}
}
}
else
hostname = g_strdup (parts[0]);
if (!hostname)
hostname = g_strdup (parts[1]);
g_strfreev (parts);
if (strlen (hostname) > 4)
{
GString* str = g_string_new (NULL);
int j, count = 0;
for (j = 0; count < 4; j++)
{
if (hostname[j] == 'a'
|| hostname[j] == 'e'
|| hostname[j] == 'i'
|| hostname[j] == 'o'
|| hostname[j] == 'u')
continue;
else
{
g_string_append_c (str, hostname[j]);
count++;
}
}
return g_string_free (str, FALSE);
}
return g_strdup (hostname);
}
KatzeItem*
midori_search_action_get_engine_for_form (WebKitWebView* web_view,
PangoEllipsizeMode ellipsize)
{
#if WEBKIT_CHECK_VERSION (1, 5, 0)
WebKitDOMDocument* doc;
WebKitDOMHTMLFormElement* active_form;
WebKitDOMHTMLCollection* form_nodes;
WebKitDOMElement* active_element;
gchar* token_element;
const gchar* title;
GString* uri_str;
gulong form_len;
const gchar* action;
guint i;
KatzeItem* item;
gchar** parts;
#if WEBKIT_CHECK_VERSION (1, 9, 5)
doc = webkit_web_frame_get_dom_document (web_view);
#else
if (webkit_web_view_get_focused_frame (web_view) != webkit_web_view_get_main_frame (web_view))
return NULL;
doc = webkit_web_view_get_dom_document (web_view);
#endif
active_element = webkit_dom_html_document_get_active_element ((WebKitDOMHTMLDocument*)doc);
active_form = webkit_dom_html_input_element_get_form ((WebKitDOMHTMLInputElement*)active_element);
if (!active_form)
return NULL;
token_element = webkit_dom_element_get_attribute (active_element, "name");
form_nodes = webkit_dom_html_form_element_get_elements (active_form);
form_len = webkit_dom_html_form_element_get_length (active_form);
/* action NULL or "": relative path */
if ((action = webkit_dom_html_form_element_get_action (active_form)) && *action)
uri_str = g_string_new (action);
else
{
gchar* hostname = midori_uri_parse_hostname (webkit_web_view_get_uri (web_view), NULL);
uri_str = g_string_new ("http://");
g_string_append (uri_str, hostname);
g_free (hostname);
}
g_string_append_c (uri_str, '?');
for (i = 0; i < form_len; i++)
{
WebKitDOMNode* form_node = webkit_dom_html_collection_item (form_nodes, i);
WebKitDOMElement* form_element = (WebKitDOMElement*) form_node;
gchar* name = webkit_dom_element_get_attribute (form_element, "name");
if (name && *name)
{
if (!g_strcmp0 (token_element, name))
g_string_append_printf (uri_str, "%s=%s&", name, "\%s");
else
{
gchar* value;
if (!g_strcmp0 (webkit_dom_element_get_tag_name (form_element), "SELECT"))
{
WebKitDOMHTMLSelectElement* select_element = (WebKitDOMHTMLSelectElement*) form_element;
gulong pos = webkit_dom_html_select_element_get_selected_index (select_element);
WebKitDOMNode* selected_node = webkit_dom_html_select_element_item (select_element, pos);
WebKitDOMElement* selected_element = (WebKitDOMElement*) selected_node;
value = webkit_dom_element_get_attribute (selected_element, "value");
}
else
value = webkit_dom_element_get_attribute (form_element, "value");
g_string_append_printf (uri_str, "%s=%s&", name, value);
g_free (value);
}
g_free (name);
}
}
title = webkit_web_view_get_title (web_view);
item = katze_item_new ();
item->uri = g_string_free (uri_str, FALSE);
item->token = midori_search_action_token_for_uri (webkit_web_view_get_uri (web_view));
if (strstr (title, " - "))
parts = g_strsplit (title, " - ", 2);
else if (strstr (title, ": "))
parts = g_strsplit (title, ": ", 2);
else
parts = NULL;
if (parts != NULL)
{
/* See midori_view_set_title: title can be first or last */
if (ellipsize == PANGO_ELLIPSIZE_END)
{
item->name = g_strdup (parts[0]);
item->text = g_strdup (parts[1]);
}
else
{
item->name = g_strdup (parts[1]);
item->text = g_strdup (parts[2]);
}
g_strfreev (parts);
}
else
item->name = g_strdup (title);
g_free (token_element);
return item;
#else
return NULL;
#endif
}
void
midori_search_action_get_editor (MidoriSearchAction* search_action,
KatzeItem* item,
gboolean new_engine)
{
GtkWidget* toplevel;
GtkWidget* dialog;
GtkWidget* content_area;
GtkSizeGroup* sizegroup;
KatzeItem* item;
GtkWidget* hbox;
GtkWidget* label;
GtkTreeModel* liststore;
@ -894,7 +1067,6 @@ midori_search_action_get_editor (MidoriSearchAction* search_action,
GtkWidget* entry_name;
GtkWidget* entry_description;
GtkWidget* entry_uri;
GtkWidget* entry_icon;
GtkWidget* entry_token;
toplevel = gtk_widget_get_toplevel (search_action->treeview);
@ -914,7 +1086,6 @@ midori_search_action_get_editor (MidoriSearchAction* search_action,
if (new_engine)
{
item = katze_item_new ();
gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog),
GTK_RESPONSE_ACCEPT, FALSE);
}
@ -935,9 +1106,8 @@ midori_search_action_get_editor (MidoriSearchAction* search_action,
g_signal_connect (entry_name, "changed",
G_CALLBACK (midori_search_action_editor_name_changed_cb), dialog);
gtk_entry_set_activates_default (GTK_ENTRY (entry_name), TRUE);
if (!new_engine)
gtk_entry_set_text (GTK_ENTRY (entry_name),
katze_str_non_null (katze_item_get_name (item)));
gtk_entry_set_text (GTK_ENTRY (entry_name),
katze_str_non_null (katze_item_get_name (item)));
gtk_box_pack_start (GTK_BOX (hbox), entry_name, TRUE, TRUE, 0);
gtk_container_add (GTK_CONTAINER (content_area), hbox);
gtk_widget_show_all (hbox);
@ -949,8 +1119,7 @@ midori_search_action_get_editor (MidoriSearchAction* search_action,
gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
entry_description = gtk_entry_new ();
gtk_entry_set_activates_default (GTK_ENTRY (entry_description), TRUE);
if (!new_engine)
gtk_entry_set_text (GTK_ENTRY (entry_description)
gtk_entry_set_text (GTK_ENTRY (entry_description)
, katze_str_non_null (katze_item_get_text (item)));
gtk_box_pack_start (GTK_BOX (hbox), entry_description, TRUE, TRUE, 0);
gtk_container_add (GTK_CONTAINER (content_area), hbox);
@ -969,27 +1138,12 @@ midori_search_action_get_editor (MidoriSearchAction* search_action,
#endif
g_object_set_data (G_OBJECT (entry_uri), "allow_%s", (void*)1);
gtk_entry_set_activates_default (GTK_ENTRY (entry_uri), TRUE);
if (!new_engine)
gtk_entry_set_text (GTK_ENTRY (entry_uri)
, katze_str_non_null (katze_item_get_uri (item)));
gtk_entry_set_text (GTK_ENTRY (entry_uri),
katze_str_non_null (katze_item_get_uri (item)));
gtk_box_pack_start (GTK_BOX (hbox), entry_uri, TRUE, TRUE, 0);
gtk_container_add (GTK_CONTAINER (content_area), hbox);
gtk_widget_show_all (hbox);
hbox = gtk_hbox_new (FALSE, 8);
gtk_container_set_border_width (GTK_CONTAINER (hbox), 5);
label = gtk_label_new_with_mnemonic (_("_Icon:"));
gtk_size_group_add_widget (sizegroup, label);
gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
entry_icon = gtk_entry_new ();
gtk_entry_set_activates_default (GTK_ENTRY (entry_icon), TRUE);
if (!new_engine)
gtk_entry_set_text (GTK_ENTRY (entry_icon)
, katze_str_non_null (katze_item_get_icon (item)));
gtk_box_pack_start (GTK_BOX (hbox), entry_icon, TRUE, TRUE, 0);
gtk_container_add (GTK_CONTAINER (content_area), hbox);
gtk_widget_show_all (hbox);
hbox = gtk_hbox_new (FALSE, 8);
gtk_container_set_border_width (GTK_CONTAINER (hbox), 5);
label = gtk_label_new_with_mnemonic (_("_Token:"));
@ -997,8 +1151,7 @@ midori_search_action_get_editor (MidoriSearchAction* search_action,
gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
entry_token = gtk_entry_new ();
gtk_entry_set_activates_default (GTK_ENTRY (entry_token), TRUE);
if (!new_engine)
gtk_entry_set_text (GTK_ENTRY (entry_token)
gtk_entry_set_text (GTK_ENTRY (entry_token)
, katze_str_non_null (katze_item_get_token (item)));
gtk_box_pack_start (GTK_BOX (hbox), entry_token, TRUE, TRUE, 0);
gtk_container_add (GTK_CONTAINER (content_area), hbox);
@ -1011,7 +1164,6 @@ midori_search_action_get_editor (MidoriSearchAction* search_action,
"name", gtk_entry_get_text (GTK_ENTRY (entry_name)),
"text", gtk_entry_get_text (GTK_ENTRY (entry_description)),
"uri", gtk_entry_get_text (GTK_ENTRY (entry_uri)),
"icon", gtk_entry_get_text (GTK_ENTRY (entry_icon)),
"token", gtk_entry_get_text (GTK_ENTRY (entry_token)),
NULL);
@ -1036,7 +1188,7 @@ midori_search_action_activate_edit_cb (GtkTreeView *treeview,
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview));
if (gtk_tree_selection_get_selected (selection, NULL, NULL))
midori_search_action_get_editor (search_action, FALSE);
midori_search_action_get_editor (search_action, NULL, FALSE);
}
@ -1044,7 +1196,7 @@ static void
midori_search_action_dialog_add_cb (GtkWidget* widget,
MidoriSearchAction* search_action)
{
midori_search_action_get_editor (search_action, TRUE);
midori_search_action_get_editor (search_action, katze_item_new (), TRUE);
}
static void
@ -1057,7 +1209,7 @@ midori_search_action_dialog_edit_cb (GtkWidget* widget,
treeview = search_action->treeview;
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview));
if (gtk_tree_selection_get_selected (selection, NULL, NULL))
midori_search_action_get_editor (search_action, FALSE);
midori_search_action_get_editor (search_action, NULL, FALSE);
}
static void
@ -1305,6 +1457,8 @@ midori_search_action_get_dialog (MidoriSearchAction* search_action)
GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE,
#endif
NULL);
katze_widget_add_class (gtk_dialog_get_widget_for_response (
GTK_DIALOG (dialog), GTK_RESPONSE_HELP), "help_button");
g_signal_connect (dialog, "destroy",
G_CALLBACK (gtk_widget_destroyed), &search_action->dialog);
gtk_window_set_icon_name (GTK_WINDOW (dialog), GTK_STOCK_PROPERTIES);
@ -1339,6 +1493,11 @@ midori_search_action_get_dialog (MidoriSearchAction* search_action)
gtk_tree_view_column_set_cell_data_func (column, renderer_pixbuf,
(GtkTreeCellDataFunc)midori_search_action_dialog_render_tick_cb,
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_search_action_dialog_render_token,
treeview, NULL);
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,
@ -1349,11 +1508,6 @@ midori_search_action_get_dialog (MidoriSearchAction* search_action)
gtk_tree_view_column_set_cell_data_func (column, renderer_text,
(GtkTreeCellDataFunc)midori_search_action_dialog_render_text,
treeview, NULL);
renderer_text = gtk_cell_renderer_text_new ();
gtk_tree_view_column_pack_start (column, renderer_text, TRUE);
gtk_tree_view_column_set_cell_data_func (column, renderer_text,
(GtkTreeCellDataFunc)midori_search_action_dialog_render_token,
treeview, NULL);
gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column);
scrolled = gtk_scrolled_window_new (NULL, NULL);
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled),

View file

@ -13,6 +13,7 @@
#define __MIDORI_SEARCH_ACTION_H__
#include <katze/katze.h>
#include <webkit/webkit.h>
G_BEGIN_DECLS
@ -72,6 +73,15 @@ midori_search_action_set_default_item (MidoriSearchAction* search_action,
GtkWidget*
midori_search_action_get_dialog (MidoriSearchAction* search_action);
void
midori_search_action_get_editor (MidoriSearchAction* search_action,
KatzeItem* item,
gboolean new_engine);
KatzeItem*
midori_search_action_get_engine_for_form (WebKitWebView* web_view,
PangoEllipsizeMode ellipsize);
G_END_DECLS
#endif /* __MIDORI_SEARCH_ACTION_H__ */

109
midori/midori-settings.vala Normal file
View file

@ -0,0 +1,109 @@
/*
Copyright (C) 2008-2012 Christian Dywan <christian@twotoasts.de>
Copyright (C) 2011 Peter Hatina <phatina@redhat.com>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
See the file COPYING for the full license text.
*/
namespace Midori {
[CCode (cprefix = "MIDORI_WINDOW_")]
public enum WindowState {
NORMAL,
MINIMIZED,
MAXIMIZED,
FULLSCREEN
}
/* Since: 0.1.3 */
public class Settings : WebKit.WebSettings {
public bool remember_last_window_size { get; set; default = true; }
public int last_window_width { get; set; default = 0; }
public int last_window_height { get; set; default = 0; }
public int last_panel_position { get; set; default = 0; }
public int last_panel_page { get; set; default = 0; }
public int last_web_search { get; set; default = 0; }
/* Since: 0.4.3 */
// [IntegerType (min = 10, max = int.max)]
public int search_width { get; set; default = 200; }
/* Since: 0.4.7 */
public bool last_inspector_attached { get; set; default = false; }
/* Since: 0.1.3 */
public WindowState last_window_state { get; set; default = WindowState.NORMAL; }
public string? location_entry_search { get; set; default = null; }
/* Since: 0.1.7 */
public int clear_private_data { get; set; default = 0; }
/* Since: 0.2.9 */
public string? clear_data { get; set; default = null; }
public bool compact_sidepanel { get; set; default = false; }
/* Since: 0.2.2 */
public bool open_panels_in_windows { get; set; default = false; }
/* Since: 0.1.3 */
public bool right_align_sidepanel { get; set; default = false; }
public bool show_menubar { get; set; default = false; }
public bool show_navigationbar { get; set; default = true; }
public bool show_bookmarkbar { get; set; default = false; }
public bool show_panel { get; set; default = false; }
public bool show_statusbar { get; set; default = true; }
/* Since: 0.1.2 */
public bool show_crash_dialog { get; set; default = true; }
public string toolbar_items { get; set; default =
"TabNew,Back,NextForward,ReloadStop,BookmarkAdd,Location,Search,Trash,CompactMenu"; }
/* Since: 0.1.4 */
// [Deprecated (since = "0.4.7")]
public bool find_while_typing { get; set; default = false; }
public bool open_popups_in_tabs { get; set; default = true; }
/* Since: 0.1.3 */
public bool zoom_text_and_images { get; set; default = true; }
/* Since: 0.2.0 */
public bool kinetic_scrolling { get; set; default = true; }
public bool middle_click_opens_selection { get; set; default = true; }
public bool flash_window_on_new_bg_tabs { get; set; default = false; }
public bool close_buttons_on_tabs { get; set; default = true; }
public bool open_tabs_in_the_background { get; set; default = true; }
public bool open_tabs_next_to_current { get; set; default = true; }
public bool always_show_tabbar { get; set; default = true; }
public string homepage { get; set; default = "http://www.google.com"; }
static string default_download_folder () {
return Environment.get_user_special_dir (UserDirectory.DOWNLOAD)
?? Environment.get_home_dir ();
}
public string download_folder { get; set; default = default_download_folder (); }
public string? text_editor { get; set; default = null; }
/* Since: 0.1.6 */
public string? news_aggregator { get; set; default = null; }
public string http_proxy { get; set; default = null; }
/* Since: 0.4.2 */
// [IntegerType (min = 1, max = 65535)]
public int http_proxy_port { get; set; default = 8080; }
/* Since: 0.3.4 */
// [IntegerType (min = 0, int.max)]
public int maximum_cache_size { get; set; default = 100; }
/* Since: 0.3.4 */
public bool strip_referer { get; set; default = false; }
/* Since: 0.4.2 */
public bool first_party_cookies_only { get; set; default = true; }
// [IntegerType (min = 0, int.max)]
public int maximum_cookie_age { get; set; default = 30; }
// [IntegerType (min = 0, int.max)]
public int maximum_history_age { get; set; default = 30; }
/* Since: 0.4.7 */
public bool delay_saving (string property) {
return property.has_prefix ("last-")
|| property == "user-stylesheet-uri"
|| property.has_suffix ("-width");
}
}
}

View file

@ -0,0 +1,401 @@
/*
Copyright (C) 2011-2012 Christian Dywan <christian@twotoats.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.
*/
namespace Katze {
extern static string mkdir_with_parents (string pathname, int mode);
}
namespace Sokoke {
extern static string js_script_eval (void* ctx, string script, void* error);
}
namespace Midori {
public errordomain SpeedDialError {
INVALID_MESSAGE,
NO_ACTION,
NO_ID,
NO_URL,
NO_TITLE,
NO_ID2,
INVALID_ACTION,
}
public class SpeedDial : GLib.Object {
string filename;
string? html = null;
List<Spec> thumb_queue = null;
WebKit.WebView thumb_view = null;
Spec? spec = null;
public GLib.KeyFile keyfile;
public bool close_buttons_left { get; set; default = false; }
public signal void refresh ();
public class Spec {
public string dial_id;
public string uri;
public Spec (string dial_id, string uri) {
this.dial_id = dial_id;
this.uri = uri;
}
}
public SpeedDial (string new_filename, string? fallback = null) {
filename = new_filename;
keyfile = new GLib.KeyFile ();
try {
keyfile.load_from_file (filename, GLib.KeyFileFlags.NONE);
}
catch (GLib.Error io_error) {
string json;
size_t len;
try {
FileUtils.get_contents (fallback ?? (filename + ".json"),
out json, out len);
}
catch (GLib.Error fallback_error) {
json = "'{}'";
len = 4;
}
var script = new StringBuilder.sized (len);
script.append ("var json = JSON.parse (");
script.append_len (json, (ssize_t)len);
script.append ("""
);
var keyfile = '';
for (var i in json['shortcuts']) {
var tile = json['shortcuts'][i];
keyfile += '[Dial ' + tile['id'].substring (1) + ']\n'
+ 'uri=' + tile['href'] + '\n'
+ 'img=' + tile['img'] + '\n'
+ 'title=' + tile['title'] + '\n\n';
}
var columns = json['width'] ? json['width'] : 3;
var rows = json['shortcuts'] ? json['shortcuts'].length / columns : 0;
keyfile += '[settings]\n'
+ 'columns=' + columns + '\n'
+ 'rows=' + (rows > 3 ? rows : 3) + '\n\n';
keyfile;
""");
try {
keyfile.load_from_data (
Sokoke.js_script_eval (null, script.str, null),
-1, 0);
}
catch (GLib.Error eval_error) {
GLib.critical ("Failed to parse %s as speed dial JSON: %s",
fallback ?? (filename + ".json"), eval_error.message);
}
Katze.mkdir_with_parents (
Path.build_path (Path.DIR_SEPARATOR_S,
Environment.get_user_cache_dir (),
"midori", "thumbnails"), 0700);
foreach (string tile in keyfile.get_groups ()) {
try {
string img = keyfile.get_string (tile, "img");
keyfile.remove_key (tile, "img");
string uri = keyfile.get_string (tile, "uri");
if (img != null && uri[0] != '\0' && uri[0] != '#') {
uchar[] decoded = Base64.decode (img);
FileUtils.set_data (build_thumbnail_path (uri), decoded);
}
}
catch (GLib.Error img_error) {
/* img and uri can be missing */
}
}
}
}
public string get_next_free_slot (out uint count = null) {
uint slot_count = 0;
foreach (string tile in keyfile.get_groups ()) {
try {
if (keyfile.has_key (tile, "uri"))
slot_count++;
}
catch (KeyFileError error) { }
}
if (&count != null)
count = slot_count;
uint slot = 1;
while (slot <= slot_count) {
string tile = "Dial %u".printf (slot);
if (!keyfile.has_group (tile))
return tile;
slot++;
}
return "Dial %u".printf (slot_count + 1);
}
public void add (string uri, string title, Gdk.Pixbuf img) {
string id = get_next_free_slot ();
add_with_id (id, uri, title, img);
}
public void add_with_id (string id, string uri, string title, Gdk.Pixbuf img) {
keyfile.set_string (id, "uri", uri);
keyfile.set_string (id, "title", title);
Katze.mkdir_with_parents (Path.build_path (Path.DIR_SEPARATOR_S,
Paths.get_cache_dir (), "thumbnails"), 0700);
string filename = build_thumbnail_path (uri);
try {
img.save (filename, "png", null, "compression", "7", null);
}
catch (Error error) {
critical ("Failed to save speed dial thumbnail: %s", error.message);
}
save ();
}
string build_thumbnail_path (string filename) {
string thumbnail = Checksum.compute_for_string (ChecksumType.MD5, filename) + ".png";
return Path.build_filename (Paths.get_cache_dir (), "thumbnails", thumbnail);
}
public unowned string get_html () throws Error {
bool load_missing = true;
if (html != null)
return html;
string? head = null;
string filename = Paths.get_res_filename ("speeddial-head.html");
if (keyfile != null
&& FileUtils.get_contents (filename, out head, null)) {
string header = head.replace ("{title}", _("Speed Dial")).
replace ("{click_to_add}", _("Click to add a shortcut")).
replace ("{enter_shortcut_address}", _("Enter shortcut address")).
replace ("{enter_shortcut_name}", _("Enter shortcut title")).
replace ("{are_you_sure}", _("Are you sure you want to delete this shortcut?"));
var markup = new StringBuilder (header);
uint slot_count = 1;
string dial_id = get_next_free_slot (out slot_count);
uint next_slot = dial_id.substring (5, -1).to_int ();
/* Try to guess the best X by X grid size */
uint grid_index = 3;
while ((grid_index * grid_index) < slot_count)
grid_index++;
/* Percent width size of one slot */
uint slot_size = (100 / grid_index);
/* No editing in private/ app mode or without scripts */
markup.append_printf (
"%s<style>.cross { display:none }</style>%s" +
"<style> div.shortcut { height: %d%%; width: %d%%; }</style>\n",
Paths.is_readonly () ? "" : "<noscript>",
Paths.is_readonly () ? "" : "</noscript>",
slot_size + 1, slot_size - 4);
/* Combined width of slots should always be less than 100%.
* Use half of the remaining percentage as a margin size */
uint div_factor;
if (slot_size * grid_index >= 100 && grid_index > 4)
div_factor = 8;
else
div_factor = 2;
uint margin = (100 - ((slot_size - 4) * grid_index)) / div_factor;
if (margin > 9)
margin = margin % 10;
markup.append_printf (
"<style> body { overflow:hidden } #content { margin-left: %u%%; }</style>", margin);
if (close_buttons_left)
markup.append_printf (
"<style>.cross { left: -14px }</style>");
foreach (string tile in keyfile.get_groups ()) {
try {
string uri = keyfile.get_string (tile, "uri");
if (uri != null && uri.str ("://") != null && tile.has_prefix ("Dial ")) {
string title = keyfile.get_string (tile, "title");
string thumb_filename = build_thumbnail_path (uri);
uint slot = tile.substring (5, -1).to_int ();
string encoded;
try {
uint8[] thumb;
FileUtils.get_data (thumb_filename, out thumb);
encoded = Base64.encode (thumb);
}
catch (FileError error) {
encoded = null;
if (load_missing)
get_thumb (tile, uri);
}
markup.append_printf ("""
<div class="shortcut" id="%u"><div class="preview">
<a class="cross" href="#"></a>
<a href="%s"><img src="data:image/png;base64,%s" title='%s'></a>
</div><div class="title">%s</div></div>
""",
slot, uri, encoded ?? "", title, title ?? "");
}
else if (tile != "settings")
keyfile.remove_group (tile);
}
catch (KeyFileError error) { }
}
markup.append_printf ("""
<div class="shortcut" id="%u"><div class="preview new">
<a class="add" href="#"></a>
</div><div class="title">%s</div></div>
""",
next_slot, _("Click to add a shortcut"));
markup.append_printf ("</div>\n</body>\n</html>\n");
html = markup.str;
}
else
html = "";
return html;
}
public void save_message (string message) throws Error {
if (!message.has_prefix ("speed_dial-save-"))
throw new SpeedDialError.INVALID_MESSAGE ("Invalid message '%s'", message);
string msg = message.substring (16, -1);
string[] parts = msg.split (" ", 4);
if (parts[0] == null)
throw new SpeedDialError.NO_ACTION ("No action.");
string action = parts[0];
if (parts[1] == null)
throw new SpeedDialError.NO_ID ("No ID argument.");
string dial_id = "Dial " + parts[1];
if (action == "delete") {
string uri = keyfile.get_string (dial_id, "uri");
string file_path = build_thumbnail_path (uri);
keyfile.remove_group (dial_id);
FileUtils.unlink (file_path);
}
else if (action == "add") {
if (parts[2] == null)
throw new SpeedDialError.NO_URL ("No URL argument.");
keyfile.set_string (dial_id, "uri", parts[2]);
get_thumb (dial_id, parts[2]);
}
else if (action == "rename") {
if (parts[2] == null)
throw new SpeedDialError.NO_TITLE ("No title argument.");
string title = parts[2];
keyfile.set_string (dial_id, "title", title);
}
else if (action == "swap") {
if (parts[2] == null)
throw new SpeedDialError.NO_ID2 ("No ID2 argument.");
string dial2_id = "Dial " + parts[2];
string uri = keyfile.get_string (dial_id, "uri");
string title = keyfile.get_string (dial_id, "title");
string uri2 = keyfile.get_string (dial2_id, "uri");
string title2 = keyfile.get_string (dial2_id, "title");
keyfile.set_string (dial_id, "uri", uri2);
keyfile.set_string (dial2_id, "uri", uri);
keyfile.set_string (dial_id, "title", title2);
keyfile.set_string (dial2_id, "title", title);
}
else
throw new SpeedDialError.INVALID_ACTION ("Invalid action '%s'", action);
save ();
}
void save () {
html = null;
try {
FileUtils.set_contents (filename, keyfile.to_data ());
}
catch (Error error) {
critical ("Failed to update speed dial: %s", error.message);
}
refresh ();
}
void load_status (GLib.Object thumb_view_, ParamSpec pspec) {
if (thumb_view.load_status != WebKit.LoadStatus.FINISHED)
return;
return_if_fail (spec != null);
#if HAVE_OFFSCREEN
var img = (thumb_view.parent as Gtk.OffscreenWindow).get_pixbuf ();
var pixbuf_scaled = img.scale_simple (240, 160, Gdk.InterpType.TILES);
img = pixbuf_scaled;
#else
thumb_view.realize ();
var img = midori_view_web_view_get_snapshot (thumb_view, 240, 160);
#endif
unowned string title = thumb_view.get_title ();
add_with_id (spec.dial_id, spec.uri, title ?? spec.uri, img);
thumb_queue.remove (spec);
if (thumb_queue != null && thumb_queue.data != null) {
spec = thumb_queue.data;
thumb_view.load_uri (spec.uri);
}
else
/* disconnect_by_func (thumb_view, load_status) */;
}
void get_thumb (string dial_id, string uri) {
if (thumb_view == null) {
thumb_view = new WebKit.WebView ();
var settings = new WebKit.WebSettings ();
settings. set ("enable-scripts", false,
"enable-plugins", false,
"auto-load-images", true,
"enable-html5-database", false,
"enable-html5-local-storage", false);
if (settings.get_class ().find_property ("enable-java-applet") != null)
settings.set ("enable-java-applet", false);
thumb_view.settings = settings;
#if HAVE_OFFSCREEN
var offscreen = new Gtk.OffscreenWindow ();
offscreen.add (thumb_view);
thumb_view.set_size_request (800, 600);
offscreen.show_all ();
#else
/* What we are doing here is a bit of a hack. In order to render a
thumbnail we need a new view and load the url in it. But it has
to be visible and packed in a container. So we secretly pack it
into the notebook of the parent browser. */
notebook.add (thumb_view);
thumb_view.destroy.connect (Gtk.widget_destroyed);
/* We use an empty label. It's not invisible but hard to spot. */
notebook.set_tab_label (thumb_view, new Gtk.EventBox ());
thumb_view.show ();
#endif
}
thumb_queue.append (new Spec (dial_id, uri));
if (thumb_queue.nth_data (1) != null)
return;
spec = thumb_queue.data;
thumb_view.notify["load-status"].connect (load_status);
thumb_view.load_uri (spec.uri);
}
}
}

View file

@ -12,42 +12,28 @@
#ifndef __MIDORI_STOCK_H__
#define __MIDORI_STOCK_H__ 1
/* Custom stock items
/* Stock items */
We should distribute these
Names should match with epiphany and/ or xdg spec */
#define STOCK_BOOKMARK "stock_bookmark"
#define STOCK_BOOKMARKS "user-bookmarks"
#define STOCK_CONSOLE "terminal"
#define STOCK_EXTENSION "extension"
#define STOCK_EXTENSIONS "extension"
#define STOCK_HISTORY "document-open-recent"
#define STOCK_WEB_BROWSER "web-browser"
#define STOCK_NEWS_FEED "news-feed"
#define STOCK_STYLE "gnome-settings-theme"
#define STOCK_NEWS_FEED "internet-news-reader"
#define STOCK_STYLE "preferences-desktop-theme"
#define STOCK_TRANSFER "package"
#define STOCK_TRANSFERS "package"
#define STOCK_PLUGINS "gnome-mime-application-x-shockwave-flash"
#define STOCK_PLUGINS "application-x-shockwave-flash"
#define STOCK_BOOKMARK_ADD "bookmark-new"
#define STOCK_HOMEPAGE "go-home"
#define STOCK_IMAGE "gnome-mime-image"
#define STOCK_IMAGE "image-x-generic"
#define STOCK_NETWORK_OFFLINE "network-offline"
#define STOCK_SCRIPT "stock_script"
#define STOCK_SCRIPTS "gnome-settings-theme"
#define STOCK_SEND "stock_mail-send"
#define STOCK_TAB_NEW "stock_new-tab"
#define STOCK_USER_TRASH "gnome-stock-trash"
#define STOCK_WINDOW_NEW "stock_new-window"
#if defined (HAVE_HILDON) && HAVE_HILDON
#undef STOCK_BOOKMARKS
#define STOCK_BOOKMARKS "general_mybookmarks_folder"
#undef STOCK_NEWS_FEED
#define STOCK_NEWS_FEED "general_rss"
#undef STOCK_WEB_BROWSER
#define STOCK_WEB_BROWSER "general_web"
#endif
#define STOCK_SCRIPT "text-x-javascript"
#define STOCK_SEND "mail-send"
#define STOCK_TAB_NEW "tab-new"
#define STOCK_USER_TRASH "user-trash"
#define STOCK_WINDOW_NEW "window-new"
#define STOCK_FOLDER_NEW "folder-new"
#define STOCK_EDIT_CLEAR "edit-clear"
#define STOCK_EDIT_FIND "edit-find"
#define STOCK_STOP "stop"
#define STOCK_URL "text-html"
#endif /* !__MIDORI_STOCK_H__ */

File diff suppressed because it is too large Load diff

View file

@ -16,6 +16,10 @@
#include <katze/katze.h>
#ifdef HAVE_GRANITE
#include <granite/granite.h>
#endif
G_BEGIN_DECLS
#define MIDORI_LOAD_PROVISIONAL WEBKIT_LOAD_PROVISIONAL
@ -53,6 +57,15 @@ midori_security_get_type (void) G_GNUC_CONST;
#define MIDORI_TYPE_SECURITY \
(midori_security_get_type ())
typedef enum
{
MIDORI_DOWNLOAD_CANCEL,
MIDORI_DOWNLOAD_OPEN,
MIDORI_DOWNLOAD_SAVE,
MIDORI_DOWNLOAD_SAVE_AS,
MIDORI_DOWNLOAD_OPEN_IN_VIEWER,
} MidoriDownloadType;
#define MIDORI_VIEW(obj) \
(G_TYPE_CHECK_INSTANCE_CAST ((obj), MIDORI_TYPE_VIEW, MidoriView))
#define MIDORI_VIEW_CLASS(klass) \
@ -142,8 +155,17 @@ midori_view_get_tab_menu (MidoriView* view);
PangoEllipsizeMode
midori_view_get_label_ellipsize (MidoriView* view);
#ifdef HAVE_GRANITE
GraniteWidgetsTab*
midori_view_get_tab (MidoriView* view);
void
midori_view_set_tab (MidoriView* view,
GraniteWidgetsTab* tab);
#else
GtkWidget*
midori_view_get_proxy_tab_label (MidoriView* view);
#endif
KatzeItem*
midori_view_get_proxy_item (MidoriView* view);
@ -161,9 +183,6 @@ void
midori_view_set_zoom_level (MidoriView* view,
gfloat zoom_level);
gboolean
midori_view_can_reload (MidoriView* view);
void
midori_view_reload (MidoriView* view,
gboolean from_cache);
@ -197,9 +216,6 @@ midori_view_get_previous_page (MidoriView* view);
const gchar*
midori_view_get_next_page (MidoriView* view);
gboolean
midori_view_can_print (MidoriView* view);
void
midori_view_print (MidoriView* view);
@ -214,9 +230,6 @@ midori_view_save_source (MidoriView* view,
const gchar* uri,
const gchar* outfile);
gboolean
midori_view_can_find (MidoriView* view);
void
midori_view_unmark_text_matches (MidoriView* view);
@ -268,9 +281,9 @@ midori_view_add_info_bar (MidoriView* view,
const gchar* first_button_text,
...);
void
midori_view_save_speed_dial_config (MidoriView* view,
GKeyFile* key_file);
const gchar*
midori_view_fallback_extension (MidoriView* view,
const gchar* extension);
G_END_DECLS

View file

@ -1,163 +0,0 @@
/*
Copyright (C) 2008 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-viewable.h"
#include <glib/gi18n.h>
enum {
POPULATE_OPTION_MENU,
LAST_SIGNAL
};
static guint signals[LAST_SIGNAL];
static void
midori_viewable_base_init (MidoriViewableIface* iface);
static void
midori_viewable_base_finalize (MidoriViewableIface* iface);
GType
midori_viewable_get_type (void)
{
static GType viewable_type = 0;
if (!viewable_type)
{
const GTypeInfo viewable_info =
{
sizeof (MidoriViewableIface),
(GBaseInitFunc) midori_viewable_base_init,
(GBaseFinalizeFunc) midori_viewable_base_finalize,
};
viewable_type = g_type_register_static (G_TYPE_INTERFACE,
"MidoriViewable",
&viewable_info, 0);
g_type_interface_add_prerequisite (viewable_type, GTK_TYPE_WIDGET);
}
return viewable_type;
}
static const gchar*
midori_viewable_default_get_stock_id (MidoriViewable* viewable)
{
return NULL;
}
static const gchar*
midori_viewable_default_get_label (MidoriViewable* viewable)
{
return NULL;
}
static GtkWidget*
midori_viewable_default_get_toolbar (MidoriViewable* viewable)
{
return NULL;
}
static void
midori_viewable_base_init (MidoriViewableIface* iface)
{
static gboolean initialized = FALSE;
if (initialized)
return;
/**
* MidoriViewable::populate-option-menu:
* @viewable: the object on which the signal is emitted
* @menu: the #GtkMenu to populate
*
* Emitted when an Option menu is displayed, for instance
* when the user clicks the Options button in the panel.
*
* Deprecated: 0.2.3
*/
signals[POPULATE_OPTION_MENU] = g_signal_new (
"populate-option-menu",
G_TYPE_FROM_INTERFACE (iface),
(GSignalFlags)(G_SIGNAL_RUN_LAST),
0,
0,
NULL,
g_cclosure_marshal_VOID__OBJECT,
G_TYPE_NONE, 1,
GTK_TYPE_MENU);
iface->get_stock_id = midori_viewable_default_get_stock_id;
iface->get_label = midori_viewable_default_get_label;
iface->get_toolbar = midori_viewable_default_get_toolbar;
initialized = TRUE;
}
static void
midori_viewable_base_finalize (MidoriViewableIface* iface)
{
}
/**
* midori_viewable_get_stock_id:
* @viewable: a #MidoriViewable
*
* Retrieves the stock ID of the viewable.
*
* Return value: a stock ID
**/
const gchar*
midori_viewable_get_stock_id (MidoriViewable* viewable)
{
g_return_val_if_fail (MIDORI_IS_VIEWABLE (viewable), NULL);
return MIDORI_VIEWABLE_GET_IFACE (viewable)->get_stock_id (viewable);
}
/**
* midori_viewable_get_label:
* @viewable: a #MidoriViewable
*
* Retrieves the label of the viewable.
*
* Return value: a label string
**/
const gchar*
midori_viewable_get_label (MidoriViewable* viewable)
{
g_return_val_if_fail (MIDORI_IS_VIEWABLE (viewable), NULL);
return MIDORI_VIEWABLE_GET_IFACE (viewable)->get_label (viewable);
}
/**
* midori_viewable_get_toolbar:
* @viewable: a #MidoriViewable
*
* Retrieves the toolbar of the viewable.
*
* Return value: a toolbar
**/
GtkWidget*
midori_viewable_get_toolbar (MidoriViewable* viewable)
{
GtkWidget* toolbar;
g_return_val_if_fail (MIDORI_IS_VIEWABLE (viewable), NULL);
toolbar = MIDORI_VIEWABLE_GET_IFACE (viewable)->get_toolbar (viewable);
if (!toolbar)
toolbar = gtk_toolbar_new ();
return toolbar;
}

View file

@ -1,61 +0,0 @@
/*
Copyright (C) 2008 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_VIEWABLE_H__
#define __MIDORI_VIEWABLE_H__
#include <katze/katze.h>
G_BEGIN_DECLS
#define MIDORI_TYPE_VIEWABLE \
(midori_viewable_get_type ())
#define MIDORI_VIEWABLE(obj) \
(G_TYPE_CHECK_INSTANCE_CAST ((obj), MIDORI_TYPE_VIEWABLE, MidoriViewable))
#define MIDORI_IS_VIEWABLE(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE ((obj), MIDORI_TYPE_VIEWABLE))
#define MIDORI_VIEWABLE_GET_IFACE(inst) \
(G_TYPE_INSTANCE_GET_INTERFACE ((inst), MIDORI_TYPE_VIEWABLE, \
MidoriViewableIface))
typedef struct _MidoriViewable MidoriViewable;
typedef struct _MidoriViewableIface MidoriViewableIface;
struct _MidoriViewableIface
{
GTypeInterface base_iface;
/* Virtual functions */
const gchar*
(*get_stock_id) (MidoriViewable* viewable);
const gchar*
(*get_label) (MidoriViewable* viewable);
GtkWidget*
(*get_toolbar) (MidoriViewable* viewable);
};
GType
midori_viewable_get_type (void) G_GNUC_CONST;
const gchar*
midori_viewable_get_stock_id (MidoriViewable* viewable);
const gchar*
midori_viewable_get_label (MidoriViewable* viewable);
GtkWidget*
midori_viewable_get_toolbar (MidoriViewable* viewable);
G_END_DECLS
#endif /* __MIDORI_VIEWABLE_H__ */

View file

@ -0,0 +1,23 @@
/*
Copyright (C) 2008 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.
*/
namespace Midori {
public interface Viewable {
public abstract unowned string get_stock_id ();
public abstract unowned string get_label ();
public abstract Gtk.Widget get_toolbar ();
/* Emitted when an Option menu is displayed, for instance
* when the user clicks the Options button in the panel.
* Deprecated: 0.2.3 */
public signal void populate_option_menu (Gtk.Menu menu);
}
}

File diff suppressed because it is too large Load diff

View file

@ -34,8 +34,6 @@ G_BEGIN_DECLS
typedef struct _MidoriWebSettings MidoriWebSettings;
typedef struct _MidoriWebSettingsClass MidoriWebSettingsClass;
#define MIDORI_PARAM_DELAY_SAVING (1 << 8)
enum
{
MIDORI_CLEAR_NONE = 0,
@ -49,20 +47,6 @@ enum
MIDORI_CLEAR_SESSION = 128,
};
typedef enum
{
MIDORI_WINDOW_NORMAL,
MIDORI_WINDOW_MINIMIZED,
MIDORI_WINDOW_MAXIMIZED,
MIDORI_WINDOW_FULLSCREEN,
} MidoriWindowState;
GType
midori_window_state_get_type (void) G_GNUC_CONST;
#define MIDORI_TYPE_WINDOW_STATE \
(midori_window_state_get_type ())
/* values >= MIDORI_STARTUP_LAST_OPEN_PAGES mean session is saved */
typedef enum
{
@ -142,6 +126,7 @@ typedef enum
{
MIDORI_IDENT_MIDORI /* Automatic */,
MIDORI_IDENT_GENUINE /* Midori */,
MIDORI_IDENT_CHROME,
MIDORI_IDENT_SAFARI,
MIDORI_IDENT_IPHONE,
MIDORI_IDENT_FIREFOX,
@ -189,6 +174,9 @@ MidoriSiteDataPolicy
midori_web_settings_get_site_data_policy (MidoriWebSettings* settings,
const gchar* uri);
const gchar*
midori_web_settings_get_accept_language (MidoriWebSettings* settings);
G_END_DECLS
#endif /* __MIDORI_WEB_SETTINGS_H__ */

View file

@ -22,7 +22,6 @@
#include "midori-preferences.h"
#include "midori-searchaction.h"
#include "midori-view.h"
#include "midori-viewable.h"
#include "midori-websettings.h"
#include "midori-platform.h"
#include <midori/midori-core.h> /* Vala API */

View file

@ -14,19 +14,19 @@ namespace Midori {
[NoAccessorMethod]
public string name { get; set; }
[NoAccessorMethod]
public Midori.WebSettings settings { get; set; }
public Midori.WebSettings settings { owned get; set; }
[NoAccessorMethod]
public GLib.Object bookmarks { get; set; }
public Katze.Array bookmarks { get; set; }
[NoAccessorMethod]
public GLib.Object trash { get; set; }
public Katze.Array trash { get; set; }
[NoAccessorMethod]
public GLib.Object search_engines { get; set; }
public Katze.Array search_engines { get; set; }
[NoAccessorMethod]
public GLib.Object history { get; set; }
public Katze.Array history { get; set; }
[NoAccessorMethod]
public GLib.Object extensions { get; set; }
public Katze.Array extensions { get; set; }
[NoAccessorMethod]
public GLib.Object browsers { get; }
public Katze.Array browsers { get; }
public Browser? browser { get; }
[HasEmitter]
@ -35,18 +35,20 @@ namespace Midori {
[HasEmitter]
public signal void quit ();
}
[CCode (cheader_filename = "midori/midori.h")]
public class Browser : Gtk.Window {
public Browser ();
public int add_item (GLib.Object item);
public int add_item (Katze.Item item);
public int add_uri (string uri);
public unowned View get_nth_tab (int n);
public GLib.List<weak View> get_tabs ();
public void block_action (Gtk.Action action);
public void unblock_action (Gtk.Action action);
public unowned Gtk.ActionGroup get_action_group ();
public unowned Browser get_for_widget (Gtk.Widget widget);
public static unowned Browser get_for_widget (Gtk.Widget widget);
public unowned string[] get_toolbar_actions ();
public unowned GLib.Object get_proxy_items ();
public unowned Katze.Array get_proxy_items ();
[NoAccessorMethod]
public Gtk.MenuBar menubar { owned get; }
@ -67,13 +69,13 @@ namespace Midori {
public string statusbar_text { owned get; set; }
public Midori.WebSettings settings { get; set; }
[NoAccessorMethod]
public GLib.Object bookmarks { owned get; set; }
public Katze.Array? bookmarks { owned get; set; }
[NoAccessorMethod]
public GLib.Object trash { owned get; set; }
public Katze.Array? trash { owned get; set; }
[NoAccessorMethod]
public GLib.Object search_engines { owned get; set; }
public Katze.Array? search_engines { owned get; set; }
[NoAccessorMethod]
public GLib.Object history { owned get; set; }
public Katze.Array? history { owned get; set; }
[NoAccessorMethod]
public bool show_tabs { get; set; }
@ -82,9 +84,10 @@ namespace Midori {
public signal void add_tab (View tab);
[HasEmitter]
public signal void remove_tab (View tab);
public signal void switch_tab (View? old_view, View? new_view);
[HasEmitter]
public signal void activate_action (string name);
public signal void add_download (GLib.Object download);
public signal void add_download (WebKit.Download download);
public signal void populate_tool_menu (Gtk.Menu menu);
[HasEmitter]
public signal void quit ();
@ -125,6 +128,7 @@ namespace Midori {
public signal void open_preferences ();
}
[CCode (cheader_filename = "midori/midori.h")]
public class View : Gtk.VBox {
[CCode (type = "GtkWidget*")]
public View (GLib.Object net);
@ -142,9 +146,8 @@ namespace Midori {
public Gtk.Menu get_tab_menu ();
public Pango.EllipsizeMode get_label_ellipsize ();
public Gtk.Label get_proxy_tab_label ();
public GLib.Object get_proxy_item ();
public Katze.Item get_proxy_item ();
public bool can_view_source ();
public bool can_find ();
public void search_text (string text, bool case_sensitive, bool forward);
public void mark_text_matches (string text, bool case_sensitive);
public void set_highlight_text_matches (bool highlight);
@ -152,6 +155,7 @@ namespace Midori {
public Gdk.Pixbuf get_snapshot (int width, int height);
public unowned WebKit.WebView get_web_view ();
public void populate_popup (Gtk.Menu menu, bool manual);
public void reload (bool from_cache);
public string uri { get; }
public string title { get; }
@ -162,7 +166,7 @@ namespace Midori {
public double progress { get; set; }
public bool minimized { get; }
public float zoom_level { get; }
public GLib.Object news_feeds { get; }
public Katze.Array news_feeds { get; }
public string statusbar_text { get; }
public WebSettings settings { get; set; }
public GLib.Object net { get; }
@ -172,8 +176,32 @@ namespace Midori {
}
[CCode (cheader_filename = "midori/midori.h")]
public class SearchAction : Gtk.Action {
public static Katze.Item? get_engine_for_form (WebKit.WebView web_view, Pango.EllipsizeMode ellipsize);
}
[CCode (cheader_filename = "midori/midori-view.h", cprefix = "MIDORI_DOWNLOAD_")]
public enum DownloadType {
CANCEL,
OPEN,
SAVE,
SAVE_AS,
OPEN_IN_VIEWER
}
public class WebSettings : WebKit.WebSettings {
public WebSettings ();
[NoAccessorMethod]
public MidoriStartup load_on_startup { get; set; }
}
[CCode (cheader_filename = "midori/midori-websettings.h", cprefix = "MIDORI_STARTUP_")]
public enum MidoriStartup {
BLANK_PAGE,
HOMEPAGE,
LAST_OPEN_PAGES,
DELAYED_PAGES
}
[CCode (cheader_filename = "midori/sokoke.h", lower_case_cprefix = "sokoke_")]

View file

@ -15,6 +15,7 @@
#include "midori-core.h"
#include "midori-platform.h"
#include "midori-app.h"
#include <config.h>
#if HAVE_UNISTD_H
@ -63,15 +64,18 @@ sokoke_js_script_eval (JSContextRef js_context,
const gchar* script,
gchar** exception)
{
JSGlobalContextRef temporary_context = NULL;
gchar* value;
JSStringRef js_value_string;
JSStringRef js_script;
JSValueRef js_exception = NULL;
JSValueRef js_value;
g_return_val_if_fail (js_context, FALSE);
g_return_val_if_fail (script, FALSE);
if (!js_context)
js_context = temporary_context = JSGlobalContextCreateInGroup (NULL, NULL);
js_script = JSStringCreateWithUTF8CString (script);
js_value = JSEvaluateScript (js_context, js_script,
JSContextGetGlobalObject (js_context), NULL, 0, &js_exception);
@ -81,6 +85,8 @@ sokoke_js_script_eval (JSContextRef js_context,
{
JSStringRef js_message = JSValueToStringCopy (js_context,
js_exception, NULL);
g_return_val_if_fail (js_message != NULL, NULL);
value = sokoke_js_string_utf8 (js_message);
if (exception)
*exception = value;
@ -90,12 +96,16 @@ sokoke_js_script_eval (JSContextRef js_context,
g_free (value);
}
JSStringRelease (js_message);
if (temporary_context)
JSGlobalContextRelease (temporary_context);
return NULL;
}
js_value_string = JSValueToStringCopy (js_context, js_value, NULL);
value = sokoke_js_string_utf8 (js_value_string);
JSStringRelease (js_value_string);
if (temporary_context)
JSGlobalContextRelease (temporary_context);
return value;
}
@ -196,7 +206,6 @@ sokoke_show_uri_with_mime_type (GdkScreen* screen,
!g_str_has_prefix (uri, "file://"));
g_free (content_type);
files = g_list_prepend (NULL, file);
#if GTK_CHECK_VERSION (2, 14, 0)
#if GTK_CHECK_VERSION (3, 0, 0)
context = gdk_display_get_app_launch_context (gdk_screen_get_display (screen));
#else
@ -204,9 +213,6 @@ sokoke_show_uri_with_mime_type (GdkScreen* screen,
#endif
gdk_app_launch_context_set_screen (context, screen);
gdk_app_launch_context_set_timestamp (context, timestamp);
#else
context = g_app_launch_context_new ();
#endif
success = g_app_info_launch (app_info, files, context, error);
@ -227,7 +233,7 @@ sokoke_open_with_response_cb (GtkWidget* dialog,
{
const gchar* command = gtk_entry_get_text (entry);
const gchar* uri = g_object_get_data (G_OBJECT (dialog), "uri");
sokoke_spawn_program (command, uri);
sokoke_spawn_program (command, FALSE, uri, TRUE);
}
gtk_widget_destroy (dialog);
}
@ -313,13 +319,8 @@ sokoke_show_uri (GdkScreen* screen,
sokoke_recursive_fork_protection (uri, TRUE);
#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
#if !GLIB_CHECK_VERSION (2, 28, 0)
info = sokoke_default_for_uri (uri, &scheme);
@ -378,117 +379,122 @@ sokoke_show_uri (GdkScreen* screen,
#endif
}
/**
* sokoke_prepare_command:
* @command: the command, properly quoted
* @argument: any arguments, properly quoted
* @quote_command: if %TRUE, @command will be quoted
* @quote_argument: if %TRUE, @argument will be quoted, ie. a URI or filename
*
* If @command contains %s, @argument will be quoted and inserted into
* @command, which is left unquoted regardless of @quote_command.
*
* Return value: the command prepared for spawning
**/
gchar*
sokoke_prepare_command (const gchar* command,
gboolean quote_command,
const gchar* argument,
gboolean quote_argument)
{
g_return_val_if_fail (command != NULL, FALSE);
g_return_val_if_fail (argument != NULL, FALSE);
if (midori_debug ("paths"))
g_print ("Preparing command: %s %d %s %d\n",
command, quote_command, argument, quote_argument);
{
gchar* uri_format;
gchar* real_command;
gchar* command_ready;
/* .desktop files accept %u, %U, %f, %F as URI/ filename, we treat it like %s */
real_command = g_strdup (command);
if ((uri_format = strstr (real_command, "%u"))
|| (uri_format = strstr (real_command, "%U"))
|| (uri_format = strstr (real_command, "%f"))
|| (uri_format = strstr (real_command, "%F")))
uri_format[1] = 's';
if (strstr (real_command, "%s"))
{
gchar* argument_quoted = quote_argument ? g_shell_quote (argument) : g_strdup (argument);
command_ready = g_strdup_printf (real_command, argument_quoted);
g_free (argument_quoted);
}
else if (quote_argument)
{
gchar* quoted_command = quote_command ? g_shell_quote (real_command) : g_strdup (real_command);
gchar* argument_quoted = g_shell_quote (argument);
command_ready = g_strconcat (quoted_command, " ", argument_quoted, NULL);
g_free (argument_quoted);
g_free (quoted_command);
}
else
{
gchar* quoted_command = quote_command ? g_shell_quote (real_command) : g_strdup (real_command);
command_ready = g_strconcat (quoted_command, " ", argument, NULL);
g_free (quoted_command);
}
g_free (real_command);
return command_ready;
}
}
/**
* sokoke_spawn_program:
* @command: the command, properly quoted
* @argument: any arguments, properly quoted
* @quote_command: if %TRUE, @command will be quoted
* @quote_argument: if %TRUE, @argument will be quoted, ie. a URI or filename
*
* If @command contains %s, @argument will be quoted and inserted into
* @command, which is left unquoted regardless of @quote_command.
*
* Return value: %TRUE on success, %FALSE if an error occurred
**/
gboolean
sokoke_spawn_program (const gchar* command,
const gchar* argument)
gboolean quote_command,
const gchar* argument,
gboolean quote_argument)
{
GError* error;
gchar* command_ready;
gchar** argv;
g_return_val_if_fail (command != NULL, FALSE);
g_return_val_if_fail (argument != NULL, FALSE);
if (!g_strstr_len (argument, 8, "://")
&& !g_str_has_prefix (argument, "about:"))
command_ready = sokoke_prepare_command (command, quote_command, argument, quote_argument);
g_print ("Launching command: %s\n", command_ready);
error = NULL;
if (!g_shell_parse_argv (command_ready, NULL, &argv, &error))
{
gboolean success;
#if HAVE_HILDON
osso_context_t* osso;
DBusConnection* dbus;
osso = osso_initialize (PACKAGE_NAME, PACKAGE_VERSION, FALSE, NULL);
if (!osso)
{
sokoke_message_dialog (GTK_MESSAGE_ERROR,
_("Could not run external program."),
"Failed to initialize libosso", FALSE);
return FALSE;
}
dbus = (DBusConnection *) osso_get_dbus_connection (osso);
if (!dbus)
{
osso_deinitialize (osso);
sokoke_message_dialog (GTK_MESSAGE_ERROR,
_("Could not run external program."),
"Failed to get dbus connection from osso context", FALSE);
return FALSE;
}
error = NULL;
/* FIXME: This is not correct, find a proper way to do this */
success = (osso_application_top (osso, command, argument) == OSSO_OK);
osso_deinitialize (osso);
#else
GAppInfo* info;
GFile* file;
GList* files;
info = g_app_info_create_from_commandline (command,
NULL, G_APP_INFO_CREATE_NONE, NULL);
file = g_file_new_for_commandline_arg (argument);
files = g_list_append (NULL, file);
error = NULL;
success = g_app_info_launch (info, files, NULL, &error);
g_object_unref (file);
g_list_free (files);
#endif
if (!success)
{
sokoke_message_dialog (GTK_MESSAGE_ERROR,
_("Could not run external program."),
error ? error->message : "", FALSE);
if (error)
g_error_free (error);
return FALSE;
}
}
else
{
/* FIXME: Implement Hildon specific version */
gchar* uri_format;
gchar* argument_quoted;
gchar* command_ready;
gchar** argv;
if ((uri_format = strstr (command, "%u")))
uri_format[1] = 's';
argument_quoted = g_shell_quote (argument);
if (strstr (command, "%s"))
command_ready = g_strdup_printf (command, argument_quoted);
else
command_ready = g_strconcat (command, " ", argument_quoted, NULL);
g_free (argument_quoted);
error = NULL;
if (!g_shell_parse_argv (command_ready, NULL, &argv, &error))
{
sokoke_message_dialog (GTK_MESSAGE_ERROR,
_("Could not run external program."),
error->message, FALSE);
g_error_free (error);
g_free (command_ready);
return FALSE;
}
sokoke_message_dialog (GTK_MESSAGE_ERROR,
_("Could not run external program."),
error->message, FALSE);
g_error_free (error);
g_free (command_ready);
return FALSE;
}
g_free (command_ready);
error = NULL;
if (!g_spawn_async (NULL, argv, NULL,
(GSpawnFlags)G_SPAWN_SEARCH_PATH | G_SPAWN_DO_NOT_REAP_CHILD,
NULL, NULL, NULL, &error))
{
sokoke_message_dialog (GTK_MESSAGE_ERROR,
_("Could not run external program."),
error->message, FALSE);
g_error_free (error);
}
g_strfreev (argv);
error = NULL;
if (!g_spawn_async (NULL, argv, NULL,
(GSpawnFlags)G_SPAWN_SEARCH_PATH | G_SPAWN_DO_NOT_REAP_CHILD,
NULL, NULL, NULL, &error))
{
sokoke_message_dialog (GTK_MESSAGE_ERROR,
_("Could not run external program."),
error->message, FALSE);
g_error_free (error);
}
g_strfreev (argv);
return TRUE;
}
@ -496,24 +502,20 @@ void
sokoke_spawn_app (const gchar* uri,
gboolean private)
{
const gchar* executable = sokoke_get_argv (NULL)[0];
/* "midori"
"/usr/bin/midori"
"c:/Program Files/Midori/bin/midori.exe" */
gchar* quoted = g_shell_quote (executable);
gchar* command;
const gchar* executable = midori_paths_get_command_line (NULL)[0];
gchar* uri_quoted = g_shell_quote (uri);
gchar* argument;
if (private)
{
gchar* quoted_config = g_shell_quote (sokoke_set_config_dir (NULL));
command = g_strconcat (quoted, " -c ", quoted_config,
" -p", NULL);
g_free (quoted_config);
gchar* config_quoted = g_shell_quote (midori_paths_get_config_dir ());
argument = g_strconcat ("-c ", config_quoted,
" -p ", uri_quoted, NULL);
}
else
command = g_strconcat (quoted, " -a", NULL);
g_free (quoted);
sokoke_spawn_program (command, uri);
g_free (command);
argument = g_strconcat ("-a ", uri_quoted, NULL);
g_free (uri_quoted);
sokoke_spawn_program (executable, TRUE, argument, FALSE);
g_free (argument);
}
static void
@ -686,26 +688,29 @@ sokoke_get_desktop (void)
}
else
{
/* Are we running in Xfce <= 4.6? */
GdkDisplay* display = gdk_display_get_default ();
Display* xdisplay = GDK_DISPLAY_XDISPLAY (display);
Window root_window = RootWindow (xdisplay, 0);
Atom save_mode_atom = gdk_x11_get_xatom_by_name_for_display (
display, "_DT_SAVE_MODE");
Atom actual_type;
int actual_format;
unsigned long n_items, bytes;
gchar* value;
int status = XGetWindowProperty (xdisplay, root_window,
save_mode_atom, 0, (~0L),
False, AnyPropertyType, &actual_type, &actual_format,
&n_items, &bytes, (unsigned char**)&value);
if (status == Success)
{
if (n_items == 6 && !strncmp (value, "xfce4", 6))
desktop = SOKOKE_DESKTOP_XFCE;
XFree (value);
}
/* Are we running in Xfce <= 4.6? */
GdkDisplay* display = gdk_display_get_default ();
if (GDK_IS_X11_DISPLAY (display))
{
Display* xdisplay = GDK_DISPLAY_XDISPLAY (display);
Window root_window = RootWindow (xdisplay, 0);
Atom save_mode_atom = gdk_x11_get_xatom_by_name_for_display (
display, "_DT_SAVE_MODE");
Atom actual_type;
int actual_format;
unsigned long n_items, bytes;
gchar* value;
int status = XGetWindowProperty (xdisplay, root_window,
save_mode_atom, 0, (~0L),
False, AnyPropertyType, &actual_type, &actual_format,
&n_items, &bytes, (unsigned char**)&value);
if (status == Success)
{
if (n_items == 6 && !strncmp (value, "xfce4", 6))
desktop = SOKOKE_DESKTOP_XFCE;
XFree (value);
}
}
}
}
@ -786,72 +791,6 @@ sokoke_xfce_header_new (const gchar* icon,
return NULL;
}
gchar*
sokoke_key_file_get_string_default (GKeyFile* key_file,
const gchar* group,
const gchar* key,
const gchar* default_value,
GError** error)
{
gchar* value = g_key_file_get_string (key_file, group, key, error);
return value == NULL ? g_strdup (default_value) : value;
}
gint
sokoke_key_file_get_integer_default (GKeyFile* key_file,
const gchar* group,
const gchar* key,
const gint default_value,
GError** error)
{
if (!g_key_file_has_key (key_file, group, key, NULL))
return default_value;
return g_key_file_get_integer (key_file, group, key, error);
}
gdouble
sokoke_key_file_get_double_default (GKeyFile* key_file,
const gchar* group,
const gchar* key,
const gdouble default_value,
GError** error)
{
if (!g_key_file_has_key (key_file, group, key, NULL))
return default_value;
return g_key_file_get_double (key_file, group, key, error);
}
gboolean
sokoke_key_file_get_boolean_default (GKeyFile* key_file,
const gchar* group,
const gchar* key,
const gboolean default_value,
GError** error)
{
if (!g_key_file_has_key (key_file, group, key, NULL))
return default_value;
return g_key_file_get_boolean (key_file, group, key, error);
}
gchar**
sokoke_key_file_get_string_list_default (GKeyFile* key_file,
const gchar* group,
const gchar* key,
gsize* length,
gchar** default_value,
gsize* default_length,
GError* error)
{
gchar** value = g_key_file_get_string_list (key_file, group, key, length, NULL);
if (!value)
{
value = g_strdupv (default_value);
if (length)
*length = *default_length;
}
return value;
}
gboolean
sokoke_key_file_save_to_file (GKeyFile* key_file,
const gchar* filename,
@ -978,42 +917,6 @@ sokoke_time_t_to_julian (const time_t* timestamp)
return julian;
}
/**
* sokoke_set_config_dir:
* @new_config_dir: an absolute path, or %NULL
*
* Retrieves and/ or sets the base configuration folder.
*
* "/" means no configuration is saved.
*
* Return value: the configuration folder, or %NULL
**/
const gchar*
sokoke_set_config_dir (const gchar* new_config_dir)
{
static gchar* config_dir = NULL;
if (config_dir)
return config_dir;
if (!new_config_dir)
config_dir = g_build_filename (g_get_user_config_dir (),
PACKAGE_NAME, NULL);
else
{
g_return_val_if_fail (g_path_is_absolute (new_config_dir), NULL);
katze_assign (config_dir, g_strdup (new_config_dir));
}
return config_dir;
}
gboolean
sokoke_is_app_or_private (void)
{
return !strcmp ("/", sokoke_set_config_dir (NULL));
}
/**
* sokoke_remove_path:
* @path: an absolute path
@ -1053,150 +956,6 @@ sokoke_remove_path (const gchar* path,
return TRUE;
}
/**
* sokoke_find_config_filename:
* @folder: a subfolder
* @filename: a filename or relative path
*
* Looks for the specified filename in the system config
* directories, depending on the platform.
*
* Return value: a full path
**/
gchar*
sokoke_find_config_filename (const gchar* folder,
const gchar* filename)
{
const gchar* const* config_dirs = g_get_system_config_dirs ();
guint i = 0;
const gchar* config_dir;
gchar* path;
if (!folder)
folder = "";
while ((config_dir = config_dirs[i++]))
{
path = g_build_filename (config_dir, PACKAGE_NAME, folder, filename, NULL);
if (g_access (path, F_OK) == 0)
return path;
g_free (path);
}
#ifdef G_OS_WIN32
config_dir = g_win32_get_package_installation_directory_of_module (NULL);
path = g_build_filename (config_dir, "etc", "xdg", PACKAGE_NAME, folder, filename, NULL);
if (g_access (path, F_OK) == 0)
return path;
g_free (path);
#endif
return g_build_filename (SYSCONFDIR, "xdg", PACKAGE_NAME, folder, filename, NULL);
}
/**
* sokoke_find_lib_path:
* @folder: the lib subfolder
*
* Looks for the specified folder in the lib directories.
*
* Return value: a newly allocated full path, or %NULL
**/
gchar* sokoke_find_lib_path (const gchar* folder)
{
#ifdef G_OS_WIN32
gchar* path = g_win32_get_package_installation_directory_of_module (NULL);
gchar* lib_path = g_build_filename (path, "lib", folder ? folder : "", NULL);
g_free (path);
if (g_access (lib_path, F_OK) == 0)
return lib_path;
#else
const gchar* lib_dirs[] =
{
LIBDIR,
"/usr/local/lib",
"/usr/lib",
NULL
};
guint i;
for (i = 0; i < G_N_ELEMENTS (lib_dirs); i++)
{
gchar* lib_path = g_build_filename (lib_dirs[i], folder ? folder : "", NULL);
if (g_access (lib_path, F_OK) == 0)
return lib_path;
else
g_free (lib_path);
}
#endif
return NULL;
}
/**
* sokoke_find_data_filename:
* @filename: a filename or relative path
*
* Looks for the specified filename in the system data
* directories, depending on the platform.
*
* Return value: a newly allocated full path
**/
gchar*
sokoke_find_data_filename (const gchar* filename,
gboolean res)
{
const gchar* res1 = res ? PACKAGE_NAME : "";
const gchar* res2 = res ? "res" : "";
const gchar* const* data_dirs = g_get_system_data_dirs ();
guint i = 0;
const gchar* data_dir;
gchar* path;
#ifdef G_OS_WIN32
gchar* install_path = g_win32_get_package_installation_directory_of_module (NULL);
path = g_build_filename (install_path, "share", res1, res2, filename, NULL);
g_free (install_path);
if (g_access (path, F_OK) == 0)
return path;
g_free (path);
#endif
path = g_build_filename (g_get_user_data_dir (), res1, res2, filename, NULL);
if (g_access (path, F_OK) == 0)
return path;
g_free (path);
while ((data_dir = data_dirs[i++]))
{
path = g_build_filename (data_dir, res1, res2, filename, NULL);
if (g_access (path, F_OK) == 0)
return path;
g_free (path);
}
return g_build_filename (MDATADIR, res1, res2, 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;
}
gchar*
sokoke_replace_variables (const gchar* template,
const gchar* variable_first, ...)
@ -1419,92 +1178,6 @@ sokoke_recursive_fork_protection (const gchar* uri,
return g_strcmp0 (fork_uri, uri) == 0 ? FALSE : 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;
}
/**
* sokoke_register_privacy_item:
* @name: the name of the privacy item
@ -1539,114 +1212,43 @@ sokoke_register_privacy_item (const gchar* name,
return NULL;
}
static void
sokoke_widget_clipboard_owner_clear_func (GtkClipboard* clipboard,
gpointer user_data)
{
g_object_unref (user_data);
}
void
sokoke_widget_copy_clipboard (GtkWidget* widget,
const gchar* text)
sokoke_widget_copy_clipboard (GtkWidget* widget,
const gchar* text,
GtkClipboardGetFunc get_cb,
gpointer owner)
{
GdkDisplay* display = gtk_widget_get_display (widget);
GtkClipboard* clipboard;
clipboard = gtk_clipboard_get_for_display (display, GDK_SELECTION_CLIPBOARD);
gtk_clipboard_set_text (clipboard, text ? text : "", -1);
g_return_if_fail (text != NULL);
clipboard = gtk_clipboard_get_for_display (display, GDK_SELECTION_PRIMARY);
gtk_clipboard_set_text (clipboard, text ? text : "", -1);
}
gtk_clipboard_set_text (clipboard, text, -1);
gchar*
sokoke_build_thumbnail_path (const gchar* name)
{
gchar* path = NULL;
if (name != NULL)
{
gchar* checksum = g_compute_checksum_for_string (G_CHECKSUM_MD5, name, -1);
gchar* filename = g_strdup_printf ("%s.png", checksum);
path = g_build_filename (g_get_user_cache_dir (), "midori", "thumbnails",
filename, NULL);
g_free (filename);
g_free (checksum);
}
return path;
}
gchar*
midori_download_prepare_tooltip_text (WebKitDownload* download)
{
gdouble* last_time;
guint64* last_size;
gint hour = 3600, min = 60;
gint hours_left, minutes_left, seconds_left;
guint64 total_size = webkit_download_get_total_size (download);
guint64 current_size = webkit_download_get_current_size (download);
gdouble time_elapsed = webkit_download_get_elapsed_time (download);
gdouble time_estimated, time_diff;
gchar* current, *total, *download_speed;
gchar* hours_str, *minutes_str, *seconds_str;
GString* tooltip = g_string_new (NULL);
time_diff = time_elapsed / current_size;
time_estimated = (total_size - current_size) * time_diff;
hours_left = time_estimated / hour;
minutes_left = (time_estimated - (hours_left * hour)) / min;
seconds_left = (time_estimated - (hours_left * hour) - (minutes_left * min));
hours_str = g_strdup_printf (ngettext ("%d hour", "%d hours", hours_left), hours_left);
minutes_str = g_strdup_printf (ngettext ("%d minute", "%d minutes", minutes_left), minutes_left);
seconds_str = g_strdup_printf (ngettext ("%d second", "%d seconds", seconds_left), seconds_left);
current = g_format_size (current_size);
total = g_format_size (total_size);
last_time = g_object_get_data (G_OBJECT (download), "last-time");
last_size = g_object_get_data (G_OBJECT (download), "last-size");
/* i18n: Download tooltip (size): 4KB of 43MB */
g_string_append_printf (tooltip, _("%s of %s"), current, total);
g_free (current);
g_free (total);
if (time_elapsed != *last_time)
download_speed = g_format_size (
(current_size - *last_size) / (time_elapsed - *last_time));
clipboard = gtk_clipboard_get_for_display (display, GDK_SELECTION_CLIPBOARD);
if (get_cb == NULL)
gtk_clipboard_set_text (clipboard, text, -1);
else
/* i18n: Unknown number of bytes, used for transfer rate like ?B/s */
download_speed = g_strdup (_("?B"));
/* i18n: Download tooltip (transfer rate): (130KB/s) */
g_string_append_printf (tooltip, _(" (%s/s)"), download_speed);
g_free (download_speed);
if (time_estimated > 0)
{
gchar* eta = NULL;
if (hours_left > 0)
eta = g_strdup_printf ("%s, %s", hours_str, minutes_str);
else if (minutes_left >= 10)
eta = g_strdup_printf ("%s", minutes_str);
else if (minutes_left < 10 && minutes_left > 0)
eta = g_strdup_printf ("%s, %s", minutes_str, seconds_str);
else if (seconds_left > 0)
eta = g_strdup_printf ("%s", seconds_str);
if (eta != NULL)
{
/* i18n: Download tooltip (estimated time) : - 1 hour, 5 minutes remaning */
g_string_append_printf (tooltip, _(" - %s remaining"), eta);
g_free (eta);
}
GtkTargetList* target_list = gtk_target_list_new (NULL, 0);
GtkTargetEntry* targets;
gint n_targets;
gtk_target_list_add_text_targets (target_list, 0);
gtk_target_list_add_image_targets (target_list, 0, TRUE);
targets = gtk_target_table_new_from_list (target_list, &n_targets);
gtk_clipboard_set_with_owner (clipboard, targets, n_targets, get_cb,
sokoke_widget_clipboard_owner_clear_func, owner);
gtk_target_table_free (targets, n_targets);
gtk_target_list_unref (target_list);
}
g_free (hours_str);
g_free (seconds_str);
g_free (minutes_str);
if (time_elapsed - *last_time > 5.0)
{
*last_time = time_elapsed;
*last_size = current_size;
}
return g_string_free (tooltip, FALSE);
}
static gboolean
@ -1696,15 +1298,15 @@ sokoke_entry_icon_released_cb (GtkEntry* entry,
gtk_widget_grab_focus (GTK_WIDGET (entry));
}
void
sokoke_entry_set_clear_button_visible (GtkEntry* entry,
gboolean visible)
GtkWidget*
sokoke_search_entry_new (const gchar* placeholder_text)
{
g_return_if_fail (GTK_IS_ENTRY (entry));
gtk_icon_entry_set_icon_highlight (GTK_ICON_ENTRY (entry),
GTK_ICON_ENTRY_SECONDARY, TRUE);
if (visible)
GtkWidget* entry = gtk_entry_new ();
gtk_entry_set_placeholder_text (GTK_ENTRY (entry), placeholder_text);
gtk_entry_set_icon_from_stock (GTK_ENTRY (entry),
GTK_ENTRY_ICON_PRIMARY, GTK_STOCK_FIND);
gtk_icon_entry_set_icon_highlight (GTK_ENTRY (entry),
GTK_ENTRY_ICON_SECONDARY, TRUE);
{
g_object_connect (entry,
"signal::icon-release",
@ -1715,35 +1317,8 @@ sokoke_entry_set_clear_button_visible (GtkEntry* entry,
G_CALLBACK (sokoke_entry_focus_out_event_cb), entry,
"signal::changed",
G_CALLBACK (sokoke_entry_changed_cb), entry, NULL);
sokoke_entry_changed_cb ((GtkEditable*)entry, entry);
}
else
{
g_object_disconnect (entry,
"any_signal::icon-release",
G_CALLBACK (sokoke_entry_icon_released_cb), NULL,
"any_signal::focus-in-event",
G_CALLBACK (sokoke_entry_focus_out_event_cb), entry,
"any_signal::focus-out-event",
G_CALLBACK (sokoke_entry_focus_out_event_cb), entry,
"any_signal::changed",
G_CALLBACK (sokoke_entry_changed_cb), entry, NULL);
gtk_icon_entry_set_icon_from_stock (
GTK_ICON_ENTRY (entry), GTK_ICON_ENTRY_SECONDARY, NULL);
sokoke_entry_changed_cb ((GtkEditable*)entry, GTK_ENTRY (entry));
}
}
gchar*
sokoke_get_download_filename (WebKitDownload* download)
{
/* https://bugs.webkit.org/show_bug.cgi?id=83161 */
/* https://d19vezwu8eufl6.cloudfront.net/nlp/slides%2F03-01-FormalizingNB.pdf */
gchar* filename = g_strdup (webkit_download_get_suggested_filename (download));
#ifdef G_OS_WIN32
g_strdelimit (filename, "/\\<>:\"|?*", '_');
#else
g_strdelimit (filename, "/", '_');
#endif
return filename;
return entry;
}

View file

@ -42,9 +42,17 @@ sokoke_show_uri (GdkScreen* screen,
guint32 timestamp,
GError** error);
gchar*
sokoke_prepare_command (const gchar* command,
gboolean quote_command,
const gchar* argument,
gboolean quote_argument);
gboolean
sokoke_spawn_program (const gchar* command,
const gchar* argument);
gboolean quote_command,
const gchar* argument,
gboolean quote_argument);
void
sokoke_spawn_app (const gchar* uri,
@ -64,47 +72,6 @@ GtkWidget*
sokoke_xfce_header_new (const gchar* icon,
const gchar* title);
void
sokoke_entry_set_default_text (GtkEntry* entry,
const gchar* default_text);
gchar*
sokoke_key_file_get_string_default (GKeyFile* key_file,
const gchar* group,
const gchar* key,
const gchar* default_value,
GError** error);
gint
sokoke_key_file_get_integer_default (GKeyFile* key_file,
const gchar* group,
const gchar* key,
const gint default_value,
GError** error);
gdouble
sokoke_key_file_get_double_default (GKeyFile* key_file,
const gchar* group,
const gchar* key,
gdouble default_value,
GError** error);
gboolean
sokoke_key_file_get_boolean_default (GKeyFile* key_file,
const gchar* group,
const gchar* key,
gboolean default_value,
GError** error);
gchar**
sokoke_key_file_get_string_list_default (GKeyFile* key_file,
const gchar* group,
const gchar* key,
gsize* length,
gchar** default_value,
gsize* default_length,
GError* error);
gboolean
sokoke_key_file_save_to_file (GKeyFile* key_file,
const gchar* filename,
@ -122,30 +89,10 @@ sokoke_action_create_popup_menu_item (GtkAction* action);
gint64
sokoke_time_t_to_julian (const time_t* timestamp);
const gchar*
sokoke_set_config_dir (const gchar* new_config_dir);
gboolean
sokoke_is_app_or_private (void);
gboolean
sokoke_remove_path (const gchar* path,
gboolean ignore_errors);
gchar*
sokoke_find_config_filename (const gchar* folder,
const gchar* filename);
gchar*
sokoke_find_lib_path (const gchar* folder);
gchar*
sokoke_find_data_filename (const gchar* filename,
gboolean res);
gchar**
sokoke_get_argv (gchar** argument_vector);
gchar*
sokoke_replace_variables (const gchar* template,
const gchar* variable_first, ...);
@ -170,14 +117,9 @@ sokoke_prefetch_uri (MidoriWebSettings* settings,
gboolean
sokoke_resolve_hostname (const gchar* hostname);
gchar *
sokoke_accept_languages (const gchar* const * lang_names);
gboolean
sokoke_recursive_fork_protection (const gchar* uri,
gboolean set_uri);
gchar*
sokoke_get_download_filename (WebKitDownload* download);
typedef struct
{
@ -192,17 +134,12 @@ sokoke_register_privacy_item (const gchar* name,
GCallback clear);
void
sokoke_widget_copy_clipboard (GtkWidget* widget,
const gchar* text);
sokoke_widget_copy_clipboard (GtkWidget* widget,
const gchar* text,
GtkClipboardGetFunc get_cb,
gpointer owner);
gchar*
sokoke_build_thumbnail_path (const gchar* name);
gchar*
midori_download_prepare_tooltip_text (WebKitDownload* download);
void
sokoke_entry_set_clear_button_visible (GtkEntry* entry,
gboolean visible);
GtkWidget*
sokoke_search_entry_new (const gchar* placeholder_text);
#endif /* !__SOKOKE_H__ */

View file

@ -8,9 +8,9 @@ import platform
progressive = True
libs = 'M UNIQUE LIBSOUP GMODULE GTHREAD LIBIDN GIO GTK SQLITE ' \
'LIBNOTIFY WEBKIT JAVASCRIPTCOREGTK LIBXML X11 XSS WS2_32 HILDON' \
'HILDON_FM GRANITE'
'HILDON_FM GCR GRANITE ZEITGEIST'
if progressive or Options.commands['check']:
if progressive:
obj = bld.new_task_gen ('cc', 'staticlib')
obj.target = 'midori-core'
obj.includes = '.. ../katze . ../toolbars'
@ -18,10 +18,14 @@ if progressive or Options.commands['check']:
obj.uselib = libs
obj.add_marshal_file ('marshal.list', 'midori_cclosure_marshal')
obj.install_path = None
obj.packages = 'glib-2.0 gio-2.0 gtk+-2.0 libsoup-2.4 webkit-1.0'
obj.vapi_dirs = '../midori ../katze'
obj.packages = 'glib-2.0 gio-2.0 libsoup-2.4 posix'
if bld.env['HAVE_GTK3']:
obj.packages += ' gtk+-3.0 webkitgtk-3.0'
else:
obj.packages += ' gtk+-2.0 webkit-1.0'
bld.add_group ()
if progressive:
obj = bld.new_task_gen ('cc', 'program')
obj.target = 'midori'
obj.includes = '.. ../katze . ../panels'
@ -30,12 +34,3 @@ if progressive:
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 ../toolbars'
obj.find_sources_in_dirs ('../katze . ../panels ../toolbars')
obj.add_marshal_file ('marshal.list', 'midori_cclosure_marshal')
obj.uselib = libs
if bld.env['WINRC']:
obj.source += ' ../data/midori.rc'

View file

@ -16,7 +16,7 @@
#include "midori-browser.h"
#include "midori-platform.h"
#include "midori-view.h"
#include "midori-viewable.h"
#include "midori-core.h"
#include <glib/gi18n.h>
#include <string.h>
@ -120,66 +120,87 @@ midori_bookmarks_get_stock_id (MidoriViewable* viewable)
return STOCK_BOOKMARKS;
}
/* TODO: Function never used */
void
midori_bookmarks_export_array_db (sqlite3* db,
KatzeArray* array,
const gchar* folder)
midori_bookmarks_export_array_db (sqlite3* db,
KatzeArray* array,
gint64 parentid)
{
KatzeArray* root_array;
KatzeArray* subarray;
KatzeItem* item;
GList* list;
gchar* parent_id;
if (!(root_array = midori_array_query (array, "*", "folder='%q'", folder)))
parent_id = g_strdup_printf ("%" G_GINT64_FORMAT, parentid);
if (!(root_array = midori_array_query (array, "*", "parentid = %q", parent_id)))
{
g_free (parent_id);
return;
}
KATZE_ARRAY_FOREACH_ITEM_L (item, root_array, list)
{
if (KATZE_ITEM_IS_FOLDER (item))
{
subarray = katze_array_new (KATZE_TYPE_ARRAY);
katze_item_set_name (KATZE_ITEM (subarray), katze_item_get_name (item));
midori_bookmarks_export_array_db (db, subarray, katze_item_get_name (item));
midori_bookmarks_export_array_db (db, subarray,
katze_item_get_meta_integer (item, "parentid"));
katze_array_add_item (array, subarray);
}
else
katze_array_add_item (array, item);
}
g_free (parent_id);
g_list_free (list);
}
void
midori_bookmarks_import_array_db (sqlite3* db,
KatzeArray* array,
const gchar* folder)
midori_bookmarks_import_array_db (sqlite3* db,
KatzeArray* array,
gint64 parentid)
{
GList* list;
KatzeItem* item;
gint64 id;
if (!db)
return;
KATZE_ARRAY_FOREACH_ITEM_L (item, array, list)
{
id = midori_bookmarks_insert_item_db (db, item, parentid);
if (KATZE_IS_ARRAY (item))
midori_bookmarks_import_array_db (db, KATZE_ARRAY (item), folder);
midori_bookmarks_insert_item_db (db, item, folder);
midori_bookmarks_import_array_db (db, KATZE_ARRAY (item), id);
}
g_list_free (list);
}
static KatzeArray*
midori_bookmarks_read_from_db (MidoriBookmarks* bookmarks,
const gchar* folder,
gint64 parentid,
const gchar* keyword)
{
KatzeArray* array;
if (keyword && *keyword)
array = midori_array_query (bookmarks->array,
"uri, title, desc, app, toolbar, folder", "title LIKE '%%%q%%'", keyword);
"id, parentid, title, uri, desc, app, toolbar, pos_panel, pos_bar", "title LIKE '%%%q%%'", keyword);
else
array = midori_array_query (bookmarks->array,
"uri, title, desc, app, toolbar, folder", "folder = '%q'", folder);
{
if (parentid > 0)
{
gchar* parent_id = g_strdup_printf ("%" G_GINT64_FORMAT, parentid);
array = midori_array_query (bookmarks->array,
"id, parentid, title, uri, desc, app, toolbar, pos_panel, pos_bar", "parentid = %q", parent_id);
g_free (parent_id);
}
else
array = midori_array_query (bookmarks->array,
"id, parentid, title, uri, desc, app, toolbar, pos_panel, pos_bar", "parentid IS NULL", NULL);
}
return array ? array : katze_array_new (KATZE_TYPE_ITEM);
}
@ -187,7 +208,7 @@ static void
midori_bookmarks_read_from_db_to_model (MidoriBookmarks* bookmarks,
GtkTreeStore* model,
GtkTreeIter* parent,
const gchar* folder,
gint64 parentid,
const gchar* keyword)
{
KatzeArray* array;
@ -195,7 +216,7 @@ midori_bookmarks_read_from_db_to_model (MidoriBookmarks* bookmarks,
KatzeItem* item;
GtkTreeIter child;
array = midori_bookmarks_read_from_db (bookmarks, folder, keyword);
array = midori_bookmarks_read_from_db (bookmarks, parentid, keyword);
katze_bookmark_populate_tree_view (array, model, parent);
/* Remove invisible dummy row */
last = gtk_tree_model_iter_n_children (GTK_TREE_MODEL (model), parent);
@ -209,23 +230,30 @@ midori_bookmarks_read_from_db_to_model (MidoriBookmarks* bookmarks,
g_object_unref (item);
}
void
midori_bookmarks_insert_item_db (sqlite3* db,
KatzeItem* item,
const gchar* folder)
gint64
midori_bookmarks_insert_item_db (sqlite3* db,
KatzeItem* item,
gint64 parentid)
{
gchar* sqlcmd;
char* errmsg = NULL;
KatzeItem* old_parent;
const gchar* parent;
gchar* new_parentid;
gchar* id = NULL;
const gchar* uri = NULL;
const gchar* desc = NULL;
gint64 seq = 0;
/* Bookmarks must have a name, import may produce invalid items */
g_return_if_fail (katze_item_get_name (item));
g_return_val_if_fail (katze_item_get_name (item), seq);
if (!db)
return;
return seq;
if (katze_item_get_meta_integer (item, "id") > 0)
id = g_strdup_printf ("%" G_GINT64_FORMAT, katze_item_get_meta_integer(item, "id"));
else
id = g_strdup_printf ("NULL");
if (KATZE_ITEM_IS_BOOKMARK (item))
uri = katze_item_get_uri (item);
@ -235,30 +263,57 @@ midori_bookmarks_insert_item_db (sqlite3* db,
/* Use folder, otherwise fallback to parent folder */
old_parent = katze_item_get_parent (item);
if (folder && *folder)
parent = folder;
else if (old_parent && katze_item_get_name (old_parent))
parent = katze_item_get_name (old_parent);
if (parentid > 0)
new_parentid = g_strdup_printf ("%" G_GINT64_FORMAT, parentid);
else if (old_parent && katze_item_get_meta_integer (old_parent, "id") > 0)
new_parentid = g_strdup_printf ("%" G_GINT64_FORMAT, katze_item_get_meta_integer (old_parent, "id"));
else
parent = "";
new_parentid = g_strdup_printf ("NULL");
sqlcmd = sqlite3_mprintf (
"INSERT into bookmarks (uri, title, desc, folder, toolbar, app) values"
" ('%q', '%q', '%q', '%q', %d, %d)",
uri ? uri : "",
"INSERT INTO bookmarks (id, parentid, title, uri, desc, toolbar, app) "
"VALUES (%q, %q, '%q', '%q', '%q', %d, %d)",
id,
new_parentid,
katze_item_get_name (item),
desc ? desc : "",
parent,
katze_str_non_null (uri),
katze_str_non_null (desc),
katze_item_get_meta_boolean (item, "toolbar"),
katze_item_get_meta_boolean (item, "app"));
if (sqlite3_exec (db, sqlcmd, NULL, NULL, &errmsg) != SQLITE_OK)
if (sqlite3_exec (db, sqlcmd, NULL, NULL, &errmsg) == SQLITE_OK)
{
/* Get insert id */
if (g_str_equal (id, "NULL"))
{
KatzeArray* seq_array;
sqlite3_free (sqlcmd);
sqlcmd = sqlite3_mprintf (
"SELECT seq FROM sqlite_sequence WHERE name = 'bookmarks'");
seq_array = katze_array_from_sqlite (db, sqlcmd);
if (katze_array_get_nth_item (seq_array, 0))
{
KatzeItem* seq_item = katze_array_get_nth_item (seq_array, 0);
seq = katze_item_get_meta_integer (seq_item, "seq");
katze_item_set_meta_integer (item, "id", seq);
}
g_object_unref (seq_array);
}
}
else
{
g_printerr (_("Failed to add bookmark item: %s\n"), errmsg);
sqlite3_free (errmsg);
}
sqlite3_free (sqlcmd);
g_free (new_parentid);
g_free (id);
return seq;
}
static void
@ -268,15 +323,9 @@ midori_bookmarks_add_item_cb (KatzeArray* array,
{
GtkTreeModel* model;
model = gtk_tree_view_get_model (GTK_TREE_VIEW (bookmarks->treeview));
if (!g_strcmp0 (katze_item_get_meta_string (item, "folder"), ""))
gtk_tree_store_insert_with_values (GTK_TREE_STORE (model),
NULL, NULL, G_MAXINT, 0, item, -1);
else
{
gtk_tree_store_clear (GTK_TREE_STORE (model));
midori_bookmarks_read_from_db_to_model (bookmarks,
GTK_TREE_STORE (model), NULL, NULL, bookmarks->filter);
}
gtk_tree_store_clear (GTK_TREE_STORE (model));
midori_bookmarks_read_from_db_to_model (bookmarks,
GTK_TREE_STORE (model), NULL, 0, bookmarks->filter);
}
static void
@ -287,7 +336,7 @@ midori_bookmarks_remove_item_cb (KatzeArray* array,
GtkTreeModel* model = gtk_tree_view_get_model (GTK_TREE_VIEW (bookmarks->treeview));
gtk_tree_store_clear (GTK_TREE_STORE (model));
midori_bookmarks_read_from_db_to_model (bookmarks,
GTK_TREE_STORE (model), NULL, NULL, bookmarks->filter);
GTK_TREE_STORE (model), NULL, 0, bookmarks->filter);
}
static void
@ -297,7 +346,7 @@ midori_bookmarks_update_cb (KatzeArray* array,
GtkTreeModel* model = gtk_tree_view_get_model (GTK_TREE_VIEW (bookmarks->treeview));
gtk_tree_store_clear (GTK_TREE_STORE (model));
midori_bookmarks_read_from_db_to_model (bookmarks,
GTK_TREE_STORE (model), NULL, NULL, bookmarks->filter);
GTK_TREE_STORE (model), NULL, 0, bookmarks->filter);
}
@ -310,7 +359,7 @@ midori_bookmarks_row_changed_cb (GtkTreeModel* model,
KatzeItem* item;
GtkTreeIter parent;
KatzeItem* new_parent = NULL;
const gchar* parent_name;
gint64 parentid;
gtk_tree_model_get (model, iter, 0, &item, -1);
@ -320,15 +369,15 @@ midori_bookmarks_row_changed_cb (GtkTreeModel* model,
/* Bookmarks must not be moved into non-folder items */
if (!KATZE_ITEM_IS_FOLDER (new_parent))
parent_name = "";
parentid = 0;
else
parent_name = katze_item_get_name (new_parent);
parentid = katze_item_get_meta_integer (new_parent, "id");
}
else
parent_name = "";
parentid = 0;
katze_array_remove_item (bookmarks->array, item);
katze_item_set_meta_string (item, "folder", parent_name);
katze_item_set_meta_integer (item, "parentid", parentid);
katze_array_add_item (bookmarks->array, item);
g_object_unref (item);
@ -359,14 +408,24 @@ midori_bookmarks_edit_clicked_cb (GtkWidget* toolitem,
{
KatzeItem* item;
MidoriBrowser* browser;
gint64 parentid;
gtk_tree_model_get (model, &iter, 0, &item, -1);
g_assert (!KATZE_ITEM_IS_SEPARATOR (item));
browser = midori_browser_get_for_widget (bookmarks->treeview);
parentid = katze_item_get_meta_integer (item, "parentid");
midori_browser_edit_bookmark_dialog_new (
browser, item, FALSE, KATZE_ITEM_IS_FOLDER (item), NULL);
if (katze_item_get_meta_integer (item, "parentid") != parentid)
{
gtk_tree_store_clear (GTK_TREE_STORE (model));
midori_bookmarks_read_from_db_to_model (bookmarks, GTK_TREE_STORE (model),
NULL, 0, NULL);
}
g_object_unref (item);
}
}
@ -382,6 +441,47 @@ midori_bookmarks_toolbar_update (MidoriBookmarks *bookmarks)
gtk_widget_set_sensitive (GTK_WIDGET (bookmarks->edit), selected);
}
gboolean
midori_bookmarks_update_item_db (sqlite3* db,
KatzeItem* item)
{
gchar* sqlcmd;
char* errmsg = NULL;
gchar* parentid;
gboolean updated;
if (katze_item_get_meta_integer (item, "parentid") > 0)
parentid = g_strdup_printf ("%" G_GINT64_FORMAT,
katze_item_get_meta_integer (item, "parentid"));
else
parentid = g_strdup_printf ("NULL");
sqlcmd = sqlite3_mprintf (
"UPDATE bookmarks SET "
"parentid=%q, title='%q', uri='%q', desc='%q', toolbar=%d, app=%d "
"WHERE id = %" G_GINT64_FORMAT ";",
parentid,
katze_item_get_name (item),
katze_str_non_null (katze_item_get_uri (item)),
katze_str_non_null (katze_item_get_meta_string (item, "desc")),
katze_item_get_meta_boolean (item, "toolbar"),
katze_item_get_meta_boolean (item, "app"),
katze_item_get_meta_integer (item, "id"));
updated = TRUE;
if (sqlite3_exec (db, sqlcmd, NULL, NULL, &errmsg) != SQLITE_OK)
{
updated = FALSE;
g_printerr (_("Failed to update bookmark : %s\n"), errmsg);
sqlite3_free (errmsg);
}
sqlite3_free (sqlcmd);
g_free (parentid);
return updated;
}
static void
midori_bookmarks_delete_clicked_cb (GtkWidget* toolitem,
MidoriBookmarks* bookmarks)
@ -421,7 +521,7 @@ midori_bookmarks_get_toolbar (MidoriViewable* viewable)
gtk_toolbar_set_icon_size (GTK_TOOLBAR (toolbar), GTK_ICON_SIZE_BUTTON);
gtk_toolbar_set_show_arrow (GTK_TOOLBAR (toolbar), FALSE);
bookmarks->toolbar = toolbar;
toolitem = gtk_tool_button_new_from_stock (GTK_STOCK_ADD);
toolitem = gtk_tool_button_new_from_stock (STOCK_BOOKMARK_ADD);
gtk_widget_set_name (GTK_WIDGET (toolitem), "BookmarkAdd");
gtk_widget_set_tooltip_text (GTK_WIDGET (toolitem),
_("Add a new bookmark"));
@ -452,7 +552,7 @@ midori_bookmarks_get_toolbar (MidoriViewable* viewable)
gtk_tool_item_set_expand (toolitem, TRUE);
gtk_toolbar_insert (GTK_TOOLBAR (toolbar), toolitem, -1);
gtk_widget_show (GTK_WIDGET (toolitem));
toolitem = gtk_tool_button_new_from_stock (GTK_STOCK_DIRECTORY);
toolitem = gtk_tool_button_new_from_stock (STOCK_FOLDER_NEW);
gtk_widget_set_name (GTK_WIDGET (toolitem), "BookmarkFolderAdd");
gtk_widget_set_tooltip_text (GTK_WIDGET (toolitem),
_("Add a new folder"));
@ -496,8 +596,8 @@ midori_bookmarks_set_app (MidoriBookmarks* bookmarks,
g_object_ref (app);
bookmarks->array = katze_object_get_object (app, "bookmarks");
midori_bookmarks_read_from_db_to_model (bookmarks, GTK_TREE_STORE (model), NULL, "", NULL);
g_signal_connect (bookmarks->array, "add-item",
midori_bookmarks_read_from_db_to_model (bookmarks, GTK_TREE_STORE (model), NULL, 0, NULL);
g_signal_connect_after (bookmarks->array, "add-item",
G_CALLBACK (midori_bookmarks_add_item_cb), bookmarks);
g_signal_connect (bookmarks->array, "remove-item",
G_CALLBACK (midori_bookmarks_remove_item_cb), bookmarks);
@ -588,8 +688,11 @@ midori_bookmarks_treeview_render_text_cb (GtkTreeViewColumn* column,
gtk_tree_model_get (model, iter, 0, &item, -1);
if (item && katze_item_get_name (item))
{
g_object_set (renderer, "markup", NULL,
"ellipsize", PANGO_ELLIPSIZE_END,
"text", katze_item_get_name (item), NULL);
}
else
g_object_set (renderer, "markup", _("<i>Separator</i>"), NULL);
@ -687,7 +790,9 @@ midori_bookmarks_open_in_tab_activate_cb (GtkWidget* menuitem,
KatzeItem* child;
KatzeArray* array;
array = midori_bookmarks_read_from_db (bookmarks, katze_item_get_name (item), NULL);
array = midori_bookmarks_read_from_db (bookmarks,
katze_item_get_meta_integer (item, "parentid"), NULL);
g_return_if_fail (KATZE_IS_ARRAY (array));
KATZE_ARRAY_FOREACH_ITEM (child, array)
{
@ -843,7 +948,7 @@ midori_bookmarks_row_expanded_cb (GtkTreeView* treeview,
model = gtk_tree_view_get_model (GTK_TREE_VIEW (treeview));
gtk_tree_model_get (model, iter, 0, &item, -1);
midori_bookmarks_read_from_db_to_model (bookmarks, GTK_TREE_STORE (model),
iter, katze_item_get_name (item), NULL);
iter, katze_item_get_meta_integer (item, "id"), NULL);
g_object_unref (item);
}
@ -885,7 +990,7 @@ midori_bookmarks_filter_timeout_cb (gpointer data)
gtk_tree_store_clear (treestore);
midori_bookmarks_read_from_db_to_model (bookmarks,
treestore, NULL, NULL, bookmarks->filter);
treestore, NULL, 0, bookmarks->filter);
return FALSE;
}
@ -896,21 +1001,16 @@ midori_bookmarks_filter_entry_changed_cb (GtkEntry* entry,
{
if (bookmarks->filter_timeout)
g_source_remove (bookmarks->filter_timeout);
katze_assign (bookmarks->filter, g_strdup (gtk_entry_get_text (entry)));
if (!g_object_get_data (G_OBJECT (entry), "sokoke_has_default"))
katze_assign (bookmarks->filter, g_strdup (gtk_entry_get_text (entry)));
else
katze_assign (bookmarks->filter, NULL);
bookmarks->filter_timeout = g_timeout_add (COMPLETION_DELAY,
midori_bookmarks_filter_timeout_cb, bookmarks);
}
static void
midori_bookmarks_filter_entry_clear_cb (GtkEntry* entry,
gint icon_pos,
gint button,
MidoriBookmarks* bookmarks)
{
if (icon_pos == GTK_ICON_ENTRY_SECONDARY)
gtk_entry_set_text (entry, "");
}
static void
midori_bookmarks_init (MidoriBookmarks* bookmarks)
{
@ -924,14 +1024,8 @@ midori_bookmarks_init (MidoriBookmarks* bookmarks)
GtkTreeSelection* selection;
/* Create the filter entry */
entry = gtk_icon_entry_new ();
gtk_icon_entry_set_icon_from_stock (GTK_ICON_ENTRY (entry),
GTK_ICON_ENTRY_PRIMARY,
GTK_STOCK_FIND);
sokoke_entry_set_clear_button_visible (GTK_ENTRY (entry), TRUE);
g_signal_connect (entry, "icon-release",
G_CALLBACK (midori_bookmarks_filter_entry_clear_cb), bookmarks);
g_signal_connect (entry, "changed",
entry = sokoke_search_entry_new (_("Search Bookmarks"));
g_signal_connect_after (entry, "changed",
G_CALLBACK (midori_bookmarks_filter_entry_changed_cb), bookmarks);
box = gtk_hbox_new (FALSE, 0);
gtk_box_pack_start (GTK_BOX (box), entry, TRUE, TRUE, 3);
@ -944,14 +1038,14 @@ midori_bookmarks_init (MidoriBookmarks* bookmarks)
gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (treeview), FALSE);
gtk_tree_view_set_tooltip_column (GTK_TREE_VIEW (treeview), 1);
column = gtk_tree_view_column_new ();
gtk_tree_view_column_set_sizing (column, GTK_TREE_VIEW_COLUMN_AUTOSIZE);
gtk_tree_view_column_set_expand (column, TRUE);
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_bookmarks_treeview_render_icon_cb,
treeview, NULL);
renderer_text = gtk_cell_renderer_text_new ();
gtk_tree_view_column_pack_start (column, renderer_text, FALSE);
gtk_tree_view_column_pack_start (column, renderer_text, TRUE);
gtk_tree_view_column_set_cell_data_func (column, renderer_text,
(GtkTreeCellDataFunc)midori_bookmarks_treeview_render_text_cb,
treeview, NULL);

View file

@ -40,15 +40,19 @@ midori_bookmarks_get_type (void);
GtkWidget*
midori_bookmarks_new (void);
void
midori_bookmarks_insert_item_db (sqlite3* db,
KatzeItem* item,
const gchar* folder);
gint64
midori_bookmarks_insert_item_db (sqlite3* db,
KatzeItem* item,
gint64 parentid);
void
midori_bookmarks_import_array_db (sqlite3* db,
KatzeArray* array,
const gchar* folder);
midori_bookmarks_import_array_db (sqlite3* db,
KatzeArray* array,
gint64 parentid);
gboolean
midori_bookmarks_update_item_db (sqlite3* db,
KatzeItem* item);
G_END_DECLS

View file

@ -14,7 +14,6 @@
#include "midori-app.h"
#include "midori-extension.h"
#include "midori-platform.h"
#include "midori-viewable.h"
#include "midori-core.h"
#include <glib/gi18n.h>
@ -94,7 +93,7 @@ midori_extensions_get_label (MidoriViewable* viewable)
static const gchar*
midori_extensions_get_stock_id (MidoriViewable* viewable)
{
return STOCK_EXTENSIONS;
return STOCK_EXTENSION;
}
static GtkWidget*
@ -285,6 +284,7 @@ midori_extensions_treeview_render_text_cb (GtkTreeViewColumn* column,
g_object_set (renderer,
"markup", text,
"ellipsize", PANGO_ELLIPSIZE_END,
"sensitive", midori_extension_is_prepared (extension),
NULL);
@ -305,13 +305,17 @@ midori_extensions_treeview_row_activated_cb (GtkTreeView* treeview,
if (gtk_tree_model_get_iter (model, &iter, path))
{
MidoriExtension* extension;
KatzeArray* array = katze_object_get_object (extensions->app, "extensions");
gtk_tree_model_get (model, &iter, 0, &extension, -1);
if (midori_extension_is_active (extension))
midori_extension_deactivate (extension);
else if (midori_extension_is_prepared (extension))
g_signal_emit_by_name (extension, "activate", extensions->app);
/* Make it easy for listeners to see that extensions changed */
katze_array_update (array);
g_object_unref (array);
g_object_unref (extension);
}
}
@ -328,13 +332,17 @@ midori_extensions_cell_renderer_toggled_cb (GtkCellRendererToggle* renderer,
if (gtk_tree_model_get_iter_from_string (model, &iter, path))
{
MidoriExtension* extension;
KatzeArray* array = katze_object_get_object (extensions->app, "extensions");
gtk_tree_model_get (model, &iter, 0, &extension, -1);
if (midori_extension_is_active (extension))
midori_extension_deactivate (extension);
else if (midori_extension_is_prepared (extension))
g_signal_emit_by_name (extension, "activate", extensions->app);
/* Make it easy for listeners to see that extensions changed */
katze_array_update (array);
g_object_unref (array);
g_object_unref (extension);
}
}
@ -454,10 +462,9 @@ midori_extensions_init (MidoriExtensions* extensions)
extensions->treeview, NULL);
gtk_tree_view_append_column (GTK_TREE_VIEW (extensions->treeview), column);
column = gtk_tree_view_column_new ();
gtk_tree_view_column_set_sizing (column, GTK_TREE_VIEW_COLUMN_AUTOSIZE);
renderer_text = gtk_cell_renderer_text_new ();
gtk_tree_view_column_pack_start (column, renderer_text, FALSE);
gtk_tree_view_column_set_expand (column, TRUE);
renderer_text = gtk_cell_renderer_text_new ();
gtk_tree_view_column_pack_start (column, renderer_text, TRUE);
gtk_tree_view_column_set_cell_data_func (column, renderer_text,
(GtkTreeCellDataFunc)midori_extensions_treeview_render_text_cb,
extensions->treeview, NULL);

View file

@ -16,7 +16,7 @@
#include "midori-browser.h"
#include "midori-platform.h"
#include "midori-view.h"
#include "midori-viewable.h"
#include "midori-core.h"
#include <glib/gi18n.h>
#include <string.h>
@ -624,11 +624,14 @@ midori_history_treeview_render_text_cb (GtkTreeViewColumn* column,
if (KATZE_ITEM_IS_BOOKMARK (item))
g_object_set (renderer, "markup", NULL,
"ellipsize", PANGO_ELLIPSIZE_END,
"text", katze_item_get_name (item), NULL);
else if (KATZE_ITEM_IS_FOLDER (item))
{
gchar* formatted = midori_history_format_date (item);
g_object_set (renderer, "markup", NULL, "text", formatted, NULL);
g_object_set (renderer, "markup", NULL, "text", formatted,
"ellipsize", PANGO_ELLIPSIZE_END,
NULL);
g_free (formatted);
}
else
@ -964,17 +967,11 @@ midori_history_filter_entry_changed_cb (GtkEntry* entry,
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)));
}
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, "");
if (!g_object_get_data (G_OBJECT (entry), "sokoke_has_default"))
katze_assign (history->filter, g_strdup (gtk_entry_get_text (entry)));
else
katze_assign (history->filter, NULL);
}
static void
@ -997,14 +994,8 @@ midori_history_init (MidoriHistory* history)
GtkTreeSelection* selection;
/* Create the filter entry */
entry = gtk_icon_entry_new ();
gtk_icon_entry_set_icon_from_stock (GTK_ICON_ENTRY (entry),
GTK_ICON_ENTRY_PRIMARY,
GTK_STOCK_FIND);
sokoke_entry_set_clear_button_visible (GTK_ENTRY (entry), TRUE);
g_signal_connect (entry, "icon-release",
G_CALLBACK (midori_history_filter_entry_clear_cb), history);
g_signal_connect (entry, "changed",
entry = sokoke_search_entry_new (_("Search History"));
g_signal_connect_after (entry, "changed",
G_CALLBACK (midori_history_filter_entry_changed_cb), history);
box = gtk_hbox_new (FALSE, 0);
gtk_box_pack_start (GTK_BOX (box), entry, TRUE, TRUE, 3);
@ -1017,14 +1008,14 @@ midori_history_init (MidoriHistory* history)
gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (treeview), FALSE);
gtk_tree_view_set_tooltip_column (GTK_TREE_VIEW (treeview), 1);
column = gtk_tree_view_column_new ();
gtk_tree_view_column_set_sizing (column, GTK_TREE_VIEW_COLUMN_AUTOSIZE);
gtk_tree_view_column_set_expand (column, TRUE);
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_history_treeview_render_icon_cb,
treeview, NULL);
renderer_text = gtk_cell_renderer_text_new ();
gtk_tree_view_column_pack_start (column, renderer_text, FALSE);
gtk_tree_view_column_pack_start (column, renderer_text, TRUE);
gtk_tree_view_column_set_cell_data_func (column, renderer_text,
(GtkTreeCellDataFunc)midori_history_treeview_render_text_cb,
treeview, NULL);

View file

@ -15,6 +15,7 @@
#include "midori-browser.h"
#include "midori-platform.h"
#include "midori-view.h"
#include "midori-core.h"
#include <glib/gi18n.h>
@ -89,7 +90,7 @@ midori_transfers_get_label (MidoriViewable* viewable)
static const gchar*
midori_transfers_get_stock_id (MidoriViewable* viewable)
{
return STOCK_TRANSFERS;
return STOCK_TRANSFER;
}
static void
@ -103,13 +104,10 @@ midori_transfers_button_clear_clicked_cb (GtkToolItem* toolitem,
while ((gtk_tree_model_iter_nth_child (model, &iter, NULL, n++)))
{
WebKitDownload* download;
WebKitDownloadStatus status;
gtk_tree_model_get (model, &iter, 1, &download, -1);
status = webkit_download_get_status (download);
if (status == WEBKIT_DOWNLOAD_STATUS_FINISHED
|| status == WEBKIT_DOWNLOAD_STATUS_CANCELLED)
if (midori_download_is_finished (download))
{
gtk_list_store_remove (GTK_LIST_STORE (model), &iter);
n--; /* Decrement n since we just removed it */
@ -240,9 +238,21 @@ midori_transfers_treeview_render_icon_cb (GtkTreeViewColumn* column,
GtkTreeIter* iter,
GtkWidget* treeview)
{
g_object_set (renderer, "stock-id", STOCK_TRANSFER,
WebKitDownload* download;
gchar* content_type;
GIcon* icon;
gtk_tree_model_get (model, iter, 1, &download, -1);
content_type = midori_download_get_content_type (download, NULL);
icon = g_content_type_get_icon (content_type);
g_themed_icon_append_name (G_THEMED_ICON (icon), "text-html");
g_object_set (renderer, "gicon", icon,
"stock-size", GTK_ICON_SIZE_DND,
"xpad", 1, "ypad", 12, NULL);
g_free (content_type);
g_object_unref (icon);
g_object_unref (download);
}
static void
@ -253,34 +263,17 @@ midori_transfers_treeview_render_text_cb (GtkTreeViewColumn* column,
GtkWidget* treeview)
{
WebKitDownload* download;
gchar* current;
gchar* total;
gchar* size_text;
gchar* text;
gchar* filename;
gchar* tooltip;
gdouble progress;
gtk_tree_model_get (model, iter, 1, &download, -1);
/* FIXME: Ellipsize filename */
current = g_format_size (webkit_download_get_current_size (download));
total = g_format_size (webkit_download_get_total_size (download));
size_text = g_strdup_printf (_("%s of %s"), current, total);
g_free (current);
g_free (total);
filename = sokoke_get_download_filename (download);
text = g_strdup_printf ("%s\n%s", filename, size_text);
g_free (filename);
g_free (size_text);
/* Avoid a bug in WebKit */
if (webkit_download_get_status (download) != WEBKIT_DOWNLOAD_STATUS_CREATED)
progress = webkit_download_get_progress (download);
else
progress = 0.0;
g_object_set (renderer, "text", text,
tooltip = midori_download_get_tooltip (download);
progress = midori_download_get_progress (download);
g_object_set (renderer, "text", tooltip,
"value", (gint)(progress * 100),
"xpad", 1, "ypad", 6, NULL);
g_free (text);
g_free (tooltip);
g_object_unref (download);
}
@ -296,17 +289,7 @@ midori_transfers_treeview_render_button_cb (GtkTreeViewColumn* column,
gtk_tree_model_get (model, iter, 1, &download, -1);
switch (webkit_download_get_status (download))
{
case WEBKIT_DOWNLOAD_STATUS_STARTED:
stock_id = GTK_STOCK_CANCEL;
break;
case WEBKIT_DOWNLOAD_STATUS_FINISHED:
stock_id = GTK_STOCK_OPEN;
break;
default:
stock_id = GTK_STOCK_CLEAR;
}
stock_id = midori_download_action_stock_id (download);
g_object_set (renderer, "stock-id", stock_id,
"stock-size", GTK_ICON_SIZE_MENU, NULL);
@ -327,25 +310,8 @@ midori_transfers_treeview_row_activated_cb (GtkTreeView* treeview,
gtk_tree_model_get (model, &iter, 1, &download, -1);
switch (webkit_download_get_status (download))
{
case WEBKIT_DOWNLOAD_STATUS_STARTED:
webkit_download_cancel (download);
break;
case WEBKIT_DOWNLOAD_STATUS_FINISHED:
{
const gchar* uri;
uri = webkit_download_get_destination_uri (download);
sokoke_show_uri (gtk_widget_get_screen (GTK_WIDGET (
treeview)), uri, gtk_get_current_event_time (), NULL);
break;
}
case WEBKIT_DOWNLOAD_STATUS_CANCELLED:
/* FIXME: Remove this item from the model */
default:
break;
}
if (midori_download_action_clear (download, GTK_WIDGET (treeview), NULL))
gtk_list_store_remove (GTK_LIST_STORE (model), &iter);
g_object_unref (download);
}
}
@ -530,7 +496,7 @@ midori_transfers_init (MidoriTransfers* transfers)
transfers->treeview = gtk_tree_view_new_with_model (GTK_TREE_MODEL (treestore));
gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (transfers->treeview), FALSE);
column = gtk_tree_view_column_new ();
gtk_tree_view_column_set_sizing (column, GTK_TREE_VIEW_COLUMN_AUTOSIZE);
gtk_tree_view_column_set_expand (column, TRUE);
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,

View file

@ -12,11 +12,7 @@
#ifndef __MIDORI_TRANSFERS_H__
#define __MIDORI_TRANSFERS_H__
#include <gtk/gtk.h>
#include <katze/katze.h>
#include "midori-viewable.h"
#include "midori-core.h"
G_BEGIN_DECLS

View file

@ -9,8 +9,11 @@ midori/midori-browser.c
midori/midori-extension.c
midori/midori-locationaction.c
midori/midori-panel.c
midori/midori-settings.vala
midori/midori-websettings.c
midori/midori-view.c
midori/midori-download.vala
midori/midori-speeddial.vala
midori/midori-preferences.c
midori/midori-searchaction.c
midori/sokoke.c
@ -27,6 +30,8 @@ katze/katze-item.c
katze/katze-array.c
katze/katze-arrayaction.c
katze/katze-preferences.c
katze/midori-uri.vala
katze/midori-paths.vala
extensions/adblock.c
extensions/addons.c
extensions/colorful-tabs.c

1280
po/ar.po

File diff suppressed because it is too large Load diff

View file

@ -594,15 +594,15 @@ msgid "_Manage Search Engines"
msgstr "_Alministrar motores de gueta"
#: ../midori/midori-browser.c:4282
msgid "Add, edit and remove search engines..."
msgstr "Amestar, editar y quitar motores de gueta..."
msgid "Add, edit and remove search engines"
msgstr "Amestar, editar y quitar motores de gueta"
#: ../midori/midori-browser.c:4285
msgid "_Clear Private Data"
msgstr "_Desaniciar datos privaos"
#: ../midori/midori-browser.c:4286
msgid "Clear private data..."
msgid "Clear private data"
msgstr "Desaniciar datos privaos"
#: ../midori/midori-browser.c:4290
@ -741,24 +741,24 @@ msgstr "Occidental (ISO-8859-1)"
#: ../midori/midori-browser.c:4368
#: ../midori/midori-websettings.c:219
#: ../midori/midori-websettings.c:291
msgid "Custom..."
msgstr "Personalizáu..."
msgid "Custom"
msgstr "Personalizáu"
#: ../midori/midori-browser.c:4806
msgid "_Separator"
msgstr "_Separtador"
#: ../midori/midori-browser.c:4813
msgid "_Location..."
msgstr "_Allugamientu..."
msgid "_Location"
msgstr "_Allugamientu"
#: ../midori/midori-browser.c:4815
msgid "Open a particular location"
msgstr "Abrir una direición en particular"
#: ../midori/midori-browser.c:4839
msgid "_Web Search..."
msgstr "_Guetar n'internet..."
msgid "_Web Search"
msgstr "_Guetar n'internet"
#: ../midori/midori-browser.c:4841
msgid "Run a web search"
@ -1960,8 +1960,8 @@ msgid "Configure Advertisement filters"
msgstr "Configurar los filtros de publicidá"
#: ../extensions/adblock.c:304
msgid "Configure _Advertisement filters..."
msgstr "Configurar filtros de p_ublicidá..."
msgid "Configure _Advertisement filters"
msgstr "Configurar filtros de p_ublicidá"
#: ../extensions/adblock.c:562
msgid "Advertisement blocker"
@ -2176,8 +2176,8 @@ msgid "Customize Keyboard shortcuts"
msgstr "Personalizar los atayos del tecláu"
#: ../extensions/shortcuts.c:264
msgid "Customize Sh_ortcuts..."
msgstr "Personalizar los ac_cesos direutos..."
msgid "Customize Sh_ortcuts"
msgstr "Personalizar los ac_cesos direutos"
#: ../extensions/shortcuts.c:303
msgid "Shortcuts"
@ -2233,8 +2233,8 @@ msgid "Displayed Items"
msgstr "Elementos usaos"
#: ../extensions/toolbar-editor.c:579
msgid "Customize _Toolbar..."
msgstr "Personalizar la barra de _xeres..."
msgid "Customize _Toolbar"
msgstr "Personalizar la barra de _xeres"
#: ../extensions/toolbar-editor.c:611
msgid "Toolbar Editor"
@ -2256,7 +2256,7 @@ msgstr "Editar cenciellamente el diseñu de la barra de herramienta"
#~ msgstr "Al entamar Midori cargar:"
#~ msgid "Download Folder"
#~ msgstr "Carpeta de descargues"
#~ msgid "Configure _Toolbar..."
#~ msgid "Configure _Toolbar"
#~ msgstr "Configurar la _Barra de xeres"
#~ msgid "_Quick Find"
#~ msgstr "Gueta _rápida"

3168
po/be.po

File diff suppressed because it is too large Load diff

View file

@ -604,7 +604,7 @@ msgid "Firefox (%s)"
msgstr "Firefox (%s)"
#: ../midori/midori-browser.c:4239
msgid "Import bookmarks..."
msgid "Import bookmarks"
msgstr "Importa les adreces d'interès…"
#: ../midori/midori-browser.c:4242 ../midori/midori-browser.c:5372
@ -711,8 +711,8 @@ msgid "Open a file"
msgstr "Obre un fitxer"
#: ../midori/midori-browser.c:5228
msgid "_Save Page As..."
msgstr "_Desa pàgina com..."
msgid "_Save Page As"
msgstr "_Desa pàgina com"
#: ../midori/midori-browser.c:5229
msgid "Save to a file"
@ -759,7 +759,7 @@ msgid "_Edit"
msgstr "_Edita"
#: ../midori/midori-browser.c:5282
msgid "_Find..."
msgid "_Find"
msgstr "_Cerca…"
#: ../midori/midori-browser.c:5283
@ -933,7 +933,7 @@ msgid "_Frequent Questions"
msgstr "_Preguntes freqüents"
#: ../midori/midori-browser.c:5421
msgid "_Report a Problem..."
msgid "_Report a Problem"
msgstr "Informa d'un _error…"
#: ../midori/midori-browser.c:5433
@ -991,7 +991,7 @@ msgstr "Occidental (ISO-8859-1)"
#: ../midori/midori-browser.c:5480 ../midori/midori-websettings.c:242
#: ../midori/midori-websettings.c:317 ../katze/katze-utils.c:641
msgid "Custom..."
msgid "Custom"
msgstr "Personalitzat…"
#: ../midori/midori-browser.c:5985
@ -999,7 +999,7 @@ msgid "_Separator"
msgstr "_Separador"
#: ../midori/midori-browser.c:5992
msgid "_Location..."
msgid "_Location"
msgstr "_Ubicació…"
#: ../midori/midori-browser.c:5994
@ -1007,7 +1007,7 @@ msgid "Open a particular location"
msgstr "Obre una ubicació"
#: ../midori/midori-browser.c:6016
msgid "_Web Search..."
msgid "_Web Search"
msgstr "Cerca _web…"
#: ../midori/midori-browser.c:6018
@ -1065,7 +1065,7 @@ msgid "Search with %s"
msgstr "Cerca amb %s"
#: ../midori/midori-locationaction.c:412
msgid "Search with..."
msgid "Search with"
msgstr "Cerca amb…"
#: ../midori/midori-locationaction.c:537
@ -2761,7 +2761,7 @@ msgid "Customize Keyboard shortcuts"
msgstr "Configura les dreceres de teclat"
#: ../extensions/shortcuts.c:283
msgid "Customize Sh_ortcuts..."
msgid "Customize Sh_ortcuts"
msgstr "Configura les _dreceres…"
#: ../extensions/shortcuts.c:320
@ -2841,11 +2841,11 @@ msgid "Displayed Items"
msgstr "Elements mostrats"
#: ../extensions/toolbar-editor.c:581
msgid "Customize _Toolbar..."
msgid "Customize _Toolbar"
msgstr "Personalitza la barra d'e_ines…"
#: ../extensions/toolbar-editor.c:597
msgid "_Customize..."
msgid "_Customize"
msgstr "_Configura…"
#: ../extensions/toolbar-editor.c:627
@ -2956,13 +2956,13 @@ msgstr "Empra el disc com a memòria cau de comunicacions HTTP"
#~ msgid "Add a new bookmark folder"
#~ msgstr "Afegeix una carpeta d'adreces d'interès"
#~ msgid "Add, edit and remove search engines..."
#~ msgid "Add, edit and remove search engines"
#~ msgstr "Afegeix, edita o treu ginys de cerca…"
#~ msgid "Clear private data..."
#~ msgid "Clear private data"
#~ msgstr "Neteja les dades privades…"
#~ msgid "Inspect page details and access developer tools..."
#~ msgid "Inspect page details and access developer tools"
#~ msgstr ""
#~ "Inspecciona els detalls de la pàgina i accedeix a les eines per "
#~ "desenvolupadors…"
@ -3221,7 +3221,7 @@ msgstr "Empra el disc com a memòria cau de comunicacions HTTP"
#~ msgid "Delete old cookies after 1 year"
#~ msgstr "Esborrar les galetes antigues després d'un any"
#~ msgid "Configure _Advertisement filters..."
#~ msgid "Configure _Advertisement filters"
#~ msgstr "Configura els filtres de _publicitat…"
#~ msgid "Open target folder for selected addon"

2368
po/cs.po

File diff suppressed because it is too large Load diff

1422
po/da.po

File diff suppressed because it is too large Load diff

2286
po/de.po

File diff suppressed because it is too large Load diff

1601
po/el.po

File diff suppressed because it is too large Load diff

View file

@ -595,8 +595,8 @@ msgid "Firefox (%s)"
msgstr "Firefox (%s)"
#: ../midori/midori-browser.c:4239
msgid "Import bookmarks..."
msgstr "Import bookmarks..."
msgid "Import bookmarks"
msgstr "Import bookmarks"
#: ../midori/midori-browser.c:4242 ../midori/midori-browser.c:5372
msgid "_Import bookmarks"
@ -702,8 +702,8 @@ msgid "Open a file"
msgstr "Open a file"
#: ../midori/midori-browser.c:5228
msgid "_Save Page As..."
msgstr "_Save Page As..."
msgid "_Save Page As"
msgstr "_Save Page As"
#: ../midori/midori-browser.c:5229
msgid "Save to a file"
@ -750,8 +750,8 @@ msgid "_Edit"
msgstr "_Edit"
#: ../midori/midori-browser.c:5282
msgid "_Find..."
msgstr "_Find..."
msgid "_Find"
msgstr "_Find"
#: ../midori/midori-browser.c:5283
msgid "Find a word or phrase in the page"
@ -924,8 +924,8 @@ msgid "_Frequent Questions"
msgstr "_Frequent Questions"
#: ../midori/midori-browser.c:5421
msgid "_Report a Problem..."
msgstr "_Report a Problem..."
msgid "_Report a Problem"
msgstr "_Report a Problem"
#: ../midori/midori-browser.c:5433
msgid "_Menubar"
@ -982,24 +982,24 @@ msgstr "Western (ISO-8859-1)"
#: ../midori/midori-browser.c:5480 ../midori/midori-websettings.c:242
#: ../midori/midori-websettings.c:317 ../katze/katze-utils.c:641
msgid "Custom..."
msgstr "Custom..."
msgid "Custom"
msgstr "Custom"
#: ../midori/midori-browser.c:5985
msgid "_Separator"
msgstr "_Separator"
#: ../midori/midori-browser.c:5992
msgid "_Location..."
msgstr "_Location..."
msgid "_Location"
msgstr "_Location"
#: ../midori/midori-browser.c:5994
msgid "Open a particular location"
msgstr "Open a particular location"
#: ../midori/midori-browser.c:6016
msgid "_Web Search..."
msgstr "_Web Search..."
msgid "_Web Search"
msgstr "_Web Search"
#: ../midori/midori-browser.c:6018
msgid "Run a web search"
@ -1056,8 +1056,8 @@ msgid "Search with %s"
msgstr "Search with %s"
#: ../midori/midori-locationaction.c:412
msgid "Search with..."
msgstr "Search with..."
msgid "Search with"
msgstr "Search with"
#: ../midori/midori-locationaction.c:537
#, c-format
@ -2738,8 +2738,8 @@ msgid "Customize Keyboard shortcuts"
msgstr "Customise Keyboard shortcuts"
#: ../extensions/shortcuts.c:283
msgid "Customize Sh_ortcuts..."
msgstr "Customise Sh_ortcuts..."
msgid "Customize Sh_ortcuts"
msgstr "Customise Sh_ortcuts"
#: ../extensions/shortcuts.c:320
msgid "Shortcuts"
@ -2818,12 +2818,12 @@ msgid "Displayed Items"
msgstr "Displayed Items"
#: ../extensions/toolbar-editor.c:581
msgid "Customize _Toolbar..."
msgstr "Customise _Toolbar..."
msgid "Customize _Toolbar"
msgstr "Customise _Toolbar"
#: ../extensions/toolbar-editor.c:597
msgid "_Customize..."
msgstr "_Customise..."
msgid "_Customize"
msgstr "_Customise"
#: ../extensions/toolbar-editor.c:627
msgid "Toolbar Editor"
@ -2933,14 +2933,14 @@ msgstr "Cache HTTP communication on disk"
#~ msgid "Add a new bookmark folder"
#~ msgstr "Add a new bookmark folder"
#~ msgid "Add, edit and remove search engines..."
#~ msgstr "Add, edit and remove search engines..."
#~ msgid "Add, edit and remove search engines"
#~ msgstr "Add, edit and remove search engines"
#~ msgid "Clear private data..."
#~ msgstr "Clear private data..."
#~ msgid "Clear private data"
#~ msgstr "Clear private data"
#~ msgid "Inspect page details and access developer tools..."
#~ msgstr "Inspect page details and access developer tools..."
#~ msgid "Inspect page details and access developer tools"
#~ msgstr "Inspect page details and access developer tools"
#~ msgid "Switch to the previous tab"
#~ msgstr "Switch to the previous tab"
@ -3164,8 +3164,8 @@ msgstr "Cache HTTP communication on disk"
#~ msgid "days"
#~ msgstr "days"
#~ msgid "Configure _Advertisement filters..."
#~ msgstr "Configure _Advertisement filters..."
#~ msgid "Configure _Advertisement filters"
#~ msgstr "Configure _Advertisement filters"
#~ msgid "Open target folder for selected addon"
#~ msgstr "Open target folder for selected addon"

View file

@ -587,8 +587,8 @@ msgid "Firefox (%s)"
msgstr "Fajrfokso (%s)"
#: ../midori/midori-browser.c:4152
msgid "Import bookmarks..."
msgstr "Importi legosignojn..."
msgid "Import bookmarks"
msgstr "Importi legosignojn"
#: ../midori/midori-browser.c:4155 ../midori/midori-browser.c:5244
msgid "_Import bookmarks"
@ -688,8 +688,8 @@ msgid "Open a file"
msgstr "Malfermi dosieron"
#: ../midori/midori-browser.c:5100
msgid "_Save Page As..."
msgstr "Kon_servi paĝon kiel..."
msgid "_Save Page As"
msgstr "Kon_servi paĝon kiel"
#: ../midori/midori-browser.c:5101
msgid "Save to a file"
@ -736,8 +736,8 @@ msgid "_Edit"
msgstr "R_edakti"
#: ../midori/midori-browser.c:5154
msgid "_Find..."
msgstr "_Trovi..."
msgid "_Find"
msgstr "_Trovi"
#: ../midori/midori-browser.c:5155
msgid "Find a word or phrase in the page"
@ -910,7 +910,7 @@ msgid "_Frequent Questions"
msgstr ""
#: ../midori/midori-browser.c:5293
msgid "_Report a Problem..."
msgid "_Report a Problem"
msgstr ""
#: ../midori/midori-browser.c:5305
@ -968,7 +968,7 @@ msgstr ""
#: ../midori/midori-browser.c:5352 ../midori/midori-websettings.c:238
#: ../midori/midori-websettings.c:313 ../katze/katze-utils.c:635
msgid "Custom..."
msgid "Custom"
msgstr ""
#: ../midori/midori-browser.c:5858
@ -976,7 +976,7 @@ msgid "_Separator"
msgstr ""
#: ../midori/midori-browser.c:5865
msgid "_Location..."
msgid "_Location"
msgstr ""
#: ../midori/midori-browser.c:5867
@ -984,7 +984,7 @@ msgid "Open a particular location"
msgstr ""
#: ../midori/midori-browser.c:5889
msgid "_Web Search..."
msgid "_Web Search"
msgstr ""
#: ../midori/midori-browser.c:5891
@ -2695,7 +2695,7 @@ msgid "Customize Keyboard shortcuts"
msgstr ""
#: ../extensions/shortcuts.c:283
msgid "Customize Sh_ortcuts..."
msgid "Customize Sh_ortcuts"
msgstr ""
#: ../extensions/shortcuts.c:320
@ -2773,11 +2773,11 @@ msgid "Displayed Items"
msgstr ""
#: ../extensions/toolbar-editor.c:581
msgid "Customize _Toolbar..."
msgid "Customize _Toolbar"
msgstr ""
#: ../extensions/toolbar-editor.c:597
msgid "_Customize..."
msgid "_Customize"
msgstr ""
#: ../extensions/toolbar-editor.c:627

2584
po/es.po

File diff suppressed because it is too large Load diff

View file

@ -532,7 +532,7 @@ msgid "_Manage Search Engines"
msgstr "_Halda otsingumootoreid"
#: ../midori/midori-browser.c:3196
msgid "Add, edit and remove search engines..."
msgid "Add, edit and remove search engines"
msgstr "Lisa, muuda ja eemalda otsingumootoreid"
#: ../midori/midori-browser.c:3200
@ -642,16 +642,16 @@ msgid "Show statusbar"
msgstr "Näita olekuriba"
#: ../midori/midori-browser.c:3669
msgid "_Location..."
msgstr "_Asukoht..."
msgid "_Location"
msgstr "_Asukoht"
#: ../midori/midori-browser.c:3671
msgid "Open a particular location"
msgstr "Ava kindel asukoht"
#: ../midori/midori-browser.c:3695
msgid "_Web Search..."
msgstr "_Veebiotsing..."
msgid "_Web Search"
msgstr "_Veebiotsing"
#: ../midori/midori-browser.c:3697
msgid "Run a web search"
@ -751,8 +751,8 @@ msgid "Western (ISO-8859-1)"
msgstr "Lääne (ISO-8859-1)"
#: ../midori/midori-websettings.c:153
msgid "Custom..."
msgstr "Kohandatud..."
msgid "Custom"
msgstr "Kohandatud"
#: ../midori/midori-websettings.c:168
msgid "New tab"
@ -1478,8 +1478,8 @@ msgstr ""
#~ msgid "Redo the last modification"
#~ msgstr "Tee viimane muudatus uuesti"
#~ msgid "Open in Page_holder..."
#~ msgstr "Ava lehe_hoidjas..."
#~ msgid "Open in Page_holder"
#~ msgstr "Ava lehe_hoidjas"
#~ msgid "Open the current page in the pageholder"
#~ msgstr "Ava käesolev lehekülg lehehoidjas"
@ -1487,8 +1487,8 @@ msgstr ""
#~ msgid "_Manage Bookmarks"
#~ msgstr "_Halda järjehoidjaid"
#~ msgid "Add, edit and remove bookmarks..."
#~ msgstr "Lisa, muuda ja eemalda järjehoidjaid..."
#~ msgid "Add, edit and remove bookmarks"
#~ msgstr "Lisa, muuda ja eemalda järjehoidjaid"
#~ msgid "Open the selected bookmark in a new tab"
#~ msgstr "Ava valitud järjehoidja uuel kaardil"

1623
po/eu.po

File diff suppressed because it is too large Load diff

View file

@ -459,8 +459,8 @@ msgid "Epiphany"
msgstr "Epiphany"
#: ../midori/midori-browser.c:4016
msgid "Import bookmarks..."
msgstr "Tuo kirjanmerkit..."
msgid "Import bookmarks"
msgstr "Tuo kirjanmerkit"
#: ../midori/midori-browser.c:4019 ../midori/midori-browser.c:4957
msgid "_Import bookmarks"
@ -792,24 +792,24 @@ msgid "_Manage Search Engines"
msgstr "_Hallitse hakukoneita"
#: ../midori/midori-browser.c:4964
msgid "Add, edit and remove search engines..."
msgstr "Lisää, muokkaa ja poista hakukoneita..."
msgid "Add, edit and remove search engines"
msgstr "Lisää, muokkaa ja poista hakukoneita"
#: ../midori/midori-browser.c:4967
msgid "_Clear Private Data"
msgstr "_Poista yksityisyystietoja"
#: ../midori/midori-browser.c:4968
msgid "Clear private data..."
msgstr "Poista yksityisyystietoja..."
msgid "Clear private data"
msgstr "Poista yksityisyystietoja"
#: ../midori/midori-browser.c:4972
msgid "_Inspect Page"
msgstr "_Tutki sivua"
#: ../midori/midori-browser.c:4973
msgid "Inspect page details and access developer tools..."
msgstr "Tutki sivun ominaisuuksia ja käytä kehitystyökaluja..."
msgid "Inspect page details and access developer tools"
msgstr "Tutki sivun ominaisuuksia ja käytä kehitystyökaluja"
#: ../midori/midori-browser.c:4978
msgid "_Previous Tab"
@ -978,23 +978,23 @@ msgstr "Länsimainen (ISO-8859-1)"
#: ../midori/midori-browser.c:5070 ../midori/midori-websettings.c:229
#: ../midori/midori-websettings.c:320 ../katze/katze-utils.c:706
msgid "Custom..."
msgstr "Mukautettu..."
msgid "Custom"
msgstr "Mukautettu"
#: ../midori/midori-browser.c:5591
msgid "_Separator"
msgstr "_Erotin"
#: ../midori/midori-browser.c:5598
msgid "_Location..."
msgstr "_Sijainti..."
msgid "_Location"
msgstr "_Sijainti"
#: ../midori/midori-browser.c:5600
msgid "Open a particular location"
msgstr "Avaa tarkka sijainti"
#: ../midori/midori-browser.c:5624
msgid "_Web Search..."
msgid "_Web Search"
msgstr "_Verkkohaku"
#: ../midori/midori-browser.c:5626
@ -2370,8 +2370,8 @@ msgstr ""
"napsauttamalla \"Lisää\". Löydät lisää listoja osoitteesta %s."
#: ../extensions/adblock.c:587
msgid "Configure _Advertisement filters..."
msgstr "Säädä _mainossuodattimia..."
msgid "Configure _Advertisement filters"
msgstr "Säädä _mainossuodattimia"
#: ../extensions/adblock.c:841
msgid "Edit rule"
@ -2788,7 +2788,7 @@ msgid "Customize Keyboard shortcuts"
msgstr "Muokkaa pikanäppäimiä"
#: ../extensions/shortcuts.c:276
msgid "Customize Sh_ortcuts..."
msgid "Customize Sh_ortcuts"
msgstr "Muokkaa pika_näppäimiä,,,"
#: ../extensions/shortcuts.c:313
@ -2868,8 +2868,8 @@ msgid "Displayed Items"
msgstr "Käytössä"
#: ../extensions/toolbar-editor.c:575
msgid "Customize _Toolbar..."
msgstr "Mukauta työ_kalupalkkia..."
msgid "Customize _Toolbar"
msgstr "Mukauta työ_kalupalkkia"
#: ../extensions/toolbar-editor.c:604
msgid "Toolbar Editor"

Some files were not shown because too many files have changed in this diff Show more