Imported Upstream version 0.4.3+dfsg
This commit is contained in:
parent
fd240475ed
commit
405f565df8
230 changed files with 59174 additions and 63293 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -2,7 +2,7 @@ Makefile
|
|||
|
||||
.waf-*
|
||||
.lock-wscript
|
||||
_build
|
||||
_build_
|
||||
|
||||
po/.intltool-merge-cache
|
||||
po/LINGUAS
|
||||
|
|
129
ChangeLog
129
ChangeLog
|
@ -1,134 +1,5 @@
|
|||
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
|
||||
+ Fix crasher opening bookmarks from Unity global menu
|
||||
+ Use WebKitFaviconDatabase as of WebKit 1.8.0
|
||||
+ Use midori-prefixed temp folder in midori_view_save_source
|
||||
+ Fix cancelling downloads with SteadyFlow or Aria2
|
||||
+ Fix crash dialog instead of opening tab in a running window
|
||||
+ Fix page icons in multi-frame sites (gmail, tumbler)
|
||||
+ Distinguish Simplified and Traditional Chinese
|
||||
+ Support go-jump-symbolic
|
||||
+ Handle empty tabs due to download links with a target
|
||||
+ Handle frame load interrupted in the unholy trinity
|
||||
+ Fix libsoup version check and wrong SSL status in location
|
||||
|
||||
v0.4.5:
|
||||
+ Work around black border around widgets on Win32
|
||||
+ Whitelist direct/ re-directed navigation requests in adblock
|
||||
+ Require Vala 0.14
|
||||
+ Provide geolocation diagnostics in about:geolocation
|
||||
+ List available about: URLs and app instance name in about:version
|
||||
+ Replace illegal characters in download filenames
|
||||
+ Tweak app options on Win32 and use ShellExecuteEx in sokoke_show_uri
|
||||
+ Use sokoke_show_uri in midori_browser_download_status_cb
|
||||
+ External Download manager Steadyflow and Aria2 (with cookies)
|
||||
+ Ensure adblock config folder when blocking images
|
||||
+ Use sqlite WAL mode for history if available
|
||||
+ Allow relative -c/ --config path
|
||||
+ Context menus on Back and Forward toolbar items
|
||||
+ Always show the tabbar by default
|
||||
+ Use ubuntu-bug if it exists
|
||||
+ Show inline find while typing and statusbar text in overlay with GTK+ 3.2
|
||||
+ Esc/ closing "downloads still active" should cancel, not continue
|
||||
+ Optional Granite support for notebook and bookmark dialog as pop-over
|
||||
+ Ctrl+j to toggle statusbar aka downloads
|
||||
+ Show at most 3 search engines in completion
|
||||
+ Don't replace existing onclick/ blur with autosuggest
|
||||
+ Implement low_memory_profile for FreeBSD and Win32
|
||||
+ Use var in internal javascript, to fix Google apps
|
||||
+ Handle download requests in frames
|
||||
|
||||
v0.4.4:
|
||||
+ Disable page cache with < 352 MB RAM
|
||||
+ Display filename in download dialog
|
||||
+ Fix box packing in GTK+3 (in most cases)
|
||||
+ Enable experimental HTML5 fullscreen API
|
||||
+ Harden IPv6 address recognition in location
|
||||
+ Experimental site data policy support (see FAQ)
|
||||
+ Close tabs by middle clicking close button
|
||||
+ Merge cookies and other data in Clear Private Data
|
||||
+ Improve KatzeArrayAction for Unity menuproxy compatibility
|
||||
+ Use GDateTime for history to avoid broken C runtimes
|
||||
+ Add Midori tag to DuckDuckGo default URI
|
||||
+ Rewrite completion popup resizing
|
||||
+ Streamline page icon loading stages and fallbacks
|
||||
+ Disable clipboard work-around for WebKit >= 1.4.3
|
||||
+ Re-word .desktop entry as an action
|
||||
+ Display informative text in private browsing
|
||||
+ Consistent clear icons in entries
|
||||
+ Revised download filename generation
|
||||
+ Add 'Open in Image Viewer' menu item
|
||||
+ Formhistory 2.0 with GDOM support
|
||||
+ Handle javascript: and mailto: links better
|
||||
+ Handle = key in Ukrainian layout better
|
||||
+ Fix bookmark export and deletion of bookmark folders
|
||||
+ Speed dial shortcut re-reordering by DND
|
||||
|
||||
v0.4.3:
|
||||
+ Implement about:widgets to test rendering
|
||||
+ Fix resizing of inspector by applying a minimum size
|
||||
|
|
23
INSTALL
23
INSTALL
|
@ -37,7 +37,7 @@ Midori is now built with debugging symbols.
|
|||
|
||||
Make sure you have installed 'gdb', the GNU Debugger.
|
||||
|
||||
Run Midori as 'gdb _build/default/midori/midori'.
|
||||
Run Midori as 'gdb _build_/default/midori/midori'.
|
||||
|
||||
Inside gdb, type 'run'.
|
||||
|
||||
|
@ -49,32 +49,27 @@ function names and line numbers.
|
|||
|
||||
If the problem is a warning and not a crash, try this:
|
||||
|
||||
'G_DEBUG=all gdb _build/default/midori/midori'
|
||||
'G_DEBUG=all gdb _build_/default/midori/midori'
|
||||
|
||||
If you are interested in HTTP communication, try this:
|
||||
|
||||
'MIDORI_DEBUG=headers _build/default/midori/midori'
|
||||
'MIDORI_SOUP_DEBUG=2 _build_/default/midori/midori'
|
||||
|
||||
Where 'headers' can be replaced with 'body' to get full message contents.
|
||||
Where '2' can be a level between 0 and 3.
|
||||
|
||||
If you are interested in (non-) touchscreen behaviour, try this:
|
||||
|
||||
'MIDORI_TOUCHSCREEN=1 _build/default/midori/midori', or
|
||||
'MIDORI_TOUCHSCREEN=1 _build_/default/midori/midori', or
|
||||
|
||||
'MIDORI_TOUCHSCREEN=0 _build/default/midori/midori'
|
||||
'MIDORI_TOUCHSCREEN=0 _build_/default/midori/midori'
|
||||
|
||||
If you want to "dry run" without WebKitGTK+ rendering, try this:
|
||||
|
||||
'MIDORI_DEBUG=unarmed _build/default/midori/midori'
|
||||
'MIDORI_UNARMED=1 _build_/default/midori/midori'
|
||||
|
||||
If you want to test bookmarks, you can enable database tracing:
|
||||
To debug extensions you can specify the path:
|
||||
|
||||
'MIDORI_DEBUG=bookmarks _build/default/midori/midori'
|
||||
|
||||
To disable Netscape plugins, use MOZ_PLUGIN_PATH=/.
|
||||
|
||||
When running from the build folder, extensions will also be located
|
||||
in the build folder (setting MIDORI_EXTENSION_PATH is no longer needed).
|
||||
'export MIDORI_EXTENSION_PATH=_build_/default/extensions'
|
||||
|
||||
For further information a tutorial for gdb and
|
||||
reading up on how you can install debugging
|
||||
|
|
16
README
16
README
|
@ -2,19 +2,19 @@ This file is licensed under the terms of the expat license, see the file EXPAT.
|
|||
|
||||
Midori is a lightweight web browser.
|
||||
|
||||
* Full integration with GTK+2 and GTK+3.
|
||||
* Fast rendering with WebKit and HTML5 video with GStreamer.
|
||||
* Full integration with GTK+2.
|
||||
* Fast rendering with WebKit.
|
||||
* Tabs, windows and session management.
|
||||
* History completion and configurable Web Search.
|
||||
* Flexibly configurable Web Search.
|
||||
* User scripts and user styles support.
|
||||
* Adblock Plus compatible, external download manager support.
|
||||
* Straightforward bookmark management.
|
||||
* Customizable interface, extensions written in C and Vala.
|
||||
* Customizable and extensible interface.
|
||||
* Extensions written in C.
|
||||
|
||||
Requirements: GLib 2.22, GTK+ 2.16, WebkitGTK+ 1.1.17, libXML2,
|
||||
libsoup 2.27.90, sqlite 3.0, Vala 0.14
|
||||
Requirements: GLib 2.22, GTK+ 2.10, WebkitGTK+ 1.1.17, libXML2,
|
||||
libsoup 2.27.90, sqlite 3.0, Vala 0.10
|
||||
|
||||
Optional: GTK+ 3.0, Unique 0.9, libnotify, gcr
|
||||
Optional: GTK+ 3.0, Unique 0.9, libnotify
|
||||
|
||||
For installation instructions read INSTALL.
|
||||
|
||||
|
|
2
configure
vendored
2
configure
vendored
|
@ -130,7 +130,7 @@ clean:
|
|||
|
||||
distclean:
|
||||
@$WAF distclean
|
||||
@-rm -rf _build
|
||||
@-rm -rf _build_
|
||||
@-rm -f Makefile
|
||||
|
||||
check:
|
||||
|
|
|
@ -1,70 +0,0 @@
|
|||
/*
|
||||
about: page style template for Midori.
|
||||
This file is licensed under the terms of the expat license, see the file EXPAT.
|
||||
*/
|
||||
body {
|
||||
background-color: #eee;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
#container {
|
||||
background: #f6fff3;
|
||||
min-width: 70%;
|
||||
max-width: 70%;
|
||||
margin: 2em auto 1em;
|
||||
padding: 1em;
|
||||
border: 0.2em solid #9acb7f;
|
||||
-webkit-border-radius: 1em;
|
||||
}
|
||||
|
||||
#icon {
|
||||
float: left;
|
||||
padding-left: 1%;
|
||||
padding-top: 1%;
|
||||
}
|
||||
|
||||
html[dir="rtl"] #icon {
|
||||
float: right;
|
||||
padding-right: 1%;
|
||||
}
|
||||
|
||||
#main {
|
||||
float: right;
|
||||
width: 75%;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 1.4em;
|
||||
font-weight: bold;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
#logo {
|
||||
position: absolute; bottom: 15px;
|
||||
z-index: -1;
|
||||
}
|
||||
|
||||
html[dir="ltr"] #logo {
|
||||
right: 15px;
|
||||
}
|
||||
|
||||
html[dir="rtl"] #logo {
|
||||
left: 15px;
|
||||
}
|
||||
|
||||
button span,
|
||||
button img {
|
||||
vertical-align: middle;
|
||||
padding: 2px 1px;
|
||||
}
|
||||
|
||||
message {
|
||||
font-size: 1.1em;
|
||||
}
|
||||
|
||||
description {
|
||||
font-size: 1em;
|
||||
}
|
|
@ -186,10 +186,10 @@ AutoSuggestControl.prototype.init = function () {
|
|||
};
|
||||
|
||||
//assign onblur event handler (hides suggestions)
|
||||
if (!this.textbox.onblur)
|
||||
this.textbox.onblur = function () { oThis.hideSuggestions(); };
|
||||
if (!this.textbox.onclick)
|
||||
this.textbox.onclick = function () { oThis.hideSuggestions(); };
|
||||
this.textbox.onblur =
|
||||
this.textbox.onclick = function () {
|
||||
oThis.hideSuggestions();
|
||||
};
|
||||
|
||||
//create the suggestions dropdown
|
||||
this.createDropDown();
|
||||
|
@ -299,7 +299,7 @@ function initSuggestions () {
|
|||
if (inputs.length == 0)
|
||||
return false;
|
||||
|
||||
for (var i=0;i<inputs.length;i++)
|
||||
for (i=0;i<inputs.length;i++)
|
||||
{
|
||||
var ename = inputs[i].getAttribute("name");
|
||||
var eid = inputs[i].getAttribute("id");
|
||||
|
|
|
@ -2,11 +2,67 @@
|
|||
Error page template for Midori.
|
||||
This file is licensed under the terms of the expat license, see the file EXPAT.
|
||||
-->
|
||||
<html dir="{dir}">
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<title>{title}</title>
|
||||
<link rel="shortcut icon" href="{icon}" />
|
||||
<link rel="stylesheet" type="text/css" href="res://about.css" />
|
||||
<style type="text/css">
|
||||
body {
|
||||
background-color: #eee;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
#container {
|
||||
background: #f6fff3;
|
||||
min-width: 70%;
|
||||
max-width: 70%;
|
||||
margin: 2em auto 1em;
|
||||
padding: 1em;
|
||||
border: 0.2em solid #9acb7f;
|
||||
-webkit-border-radius: 1em;
|
||||
}
|
||||
|
||||
icon {
|
||||
float: left;
|
||||
padding-left: 1%;
|
||||
padding-top: 1%;
|
||||
}
|
||||
|
||||
#main {
|
||||
float: right;
|
||||
width: 90%;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 1.4em;
|
||||
font-weight: bold;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
#logo {
|
||||
position: absolute; right: 15px; bottom: 15px;
|
||||
z-index: -1;
|
||||
}
|
||||
|
||||
button span,
|
||||
button img {
|
||||
vertical-align: middle;
|
||||
padding: 2px 1px;
|
||||
}
|
||||
|
||||
message {
|
||||
font-size: 1.1em;
|
||||
}
|
||||
|
||||
description {
|
||||
font-size: 1em;
|
||||
}
|
||||
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="container">
|
||||
|
|
61
data/faq.css
61
data/faq.css
|
@ -8,64 +8,29 @@ Stylesheet for Midori's documentation based on a version of Enrico Troeger.
|
|||
|
||||
@media screen {
|
||||
|
||||
html, body {
|
||||
width: 100% !important;
|
||||
height: 100% !important;
|
||||
margin: 0 !important;
|
||||
padding: 0 !important;
|
||||
body {
|
||||
background-color: #f6fff3;
|
||||
color: #404040;
|
||||
margin-left: 0.4em;
|
||||
width: 60em;
|
||||
font-size: 90%;
|
||||
}
|
||||
|
||||
* {
|
||||
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 {
|
||||
color: #013100;
|
||||
}
|
||||
|
||||
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:visited {
|
||||
color: #7E558E;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
text-decoration: none !important;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
h1, h2, h3 {
|
||||
font-family: serif !important;
|
||||
color: #002a00 !important;
|
||||
font-family: sans-serif;
|
||||
color: #002a00;
|
||||
}
|
||||
|
||||
h1 {
|
||||
|
|
495
data/faq.html
495
data/faq.html
|
@ -7,7 +7,7 @@
|
|||
<title>midori:faq</title>
|
||||
<meta name="generator" content="DokuWiki"/>
|
||||
<meta name="robots" content="noindex,nofollow"/>
|
||||
<meta name="date" content="2012-09-18T16:25:52+0200"/>
|
||||
<meta name="date" content="2011-11-08T02:51:30+0100"/>
|
||||
<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="/"/>
|
||||
|
@ -17,13 +17,11 @@
|
|||
<link rel="alternate" type="text/html" title="Plain HTML" href="/_export/xhtml/midori/faq"/>
|
||||
<link rel="alternate" type="text/plain" title="Wiki Markup" href="/_export/raw/midori/faq"/>
|
||||
<link rel="canonical" href="http://wiki.xfce.org/midori/faq"/>
|
||||
<link rel="stylesheet" href="faq.css" />
|
||||
<link rel="stylesheet" href="faq.css" />
|
||||
<link rel="stylesheet" href="faq.css" />
|
||||
<link rel="stylesheet" type="text/css" href="faq.css" />
|
||||
<script type="text/javascript"><!--//--><![CDATA[//><!--
|
||||
var NS='midori';var JSINFO = {"id":"midori:faq","namespace":"midori"};
|
||||
var NS='midori';var SIG=' --- //[[christian@twotoasts.de|Christian Dywan]] 2011/11/11 00:07//';var JSINFO = {"id":"midori:faq","namespace":"midori"};
|
||||
//--><!]]></script>
|
||||
<script type="text/javascript" charset="utf-8" src="/lib/exe/js.php?tseed=1334991875"></script>
|
||||
<script type="text/javascript" charset="utf-8" src="/lib/exe/js.php?tseed=1316333533"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div class="dokuwiki export">
|
||||
|
@ -34,35 +32,31 @@ var NS='midori';var JSINFO = {"id":"midori:faq","namespace":"midori"};
|
|||
|
||||
<ul class="toc">
|
||||
<li class="level1"><div class="li"><span class="li"><a href="#midori_-_frequently_asked_questions" class="toc">Midori - Frequently asked questions</a></span></div></li>
|
||||
<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>
|
||||
<li class="level1"><div class="li"><span class="li"><a href="#getting_started" class="toc">Getting started</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't work</a></span></div></li>
|
||||
<li class="level2"><div class="li"><span class="li"><a href="#about_midori" class="toc">About Midori</a></span></div></li>
|
||||
<li class="level2"><div class="li"><span class="li"><a href="#common_problems" class="toc">Common problems</a></span></div></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li class="level1"><div class="li"><span class="li"><a href="#privacy" class="toc">Privacy</a></span></div>
|
||||
<ul class="toc">
|
||||
<li class="level2"><div class="li"><span class="li"><a href="#blacklist_cookies" class="toc">Blacklist cookies</a></span></div></li>
|
||||
<li class="level2"><div class="li"><span class="li"><a href="#adblock" class="toc">Adblock</a></span></div></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li class="level1"><div class="li"><span class="li"><a href="#modes" class="toc">Modes</a></span></div>
|
||||
<li class="level1"><div class="li"><span class="li"><a href="#features" class="toc">Features</a></span></div>
|
||||
<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>
|
||||
<li class="level2"><div class="li"><span class="li"><a href="#proxy_servers" class="toc">Proxy servers</a></span></div></li>
|
||||
<li class="level2"><div class="li"><span class="li"><a href="#using_the_keyboard" class="toc">Using the Keyboard</a></span></div>
|
||||
<ul class="toc">
|
||||
<li class="level3"><div class="li"><span class="li"><a href="#hjkl" class="toc">HJKL</a></span></div></li>
|
||||
<li class="level3"><div class="li"><span class="li"><a href="#following_links" class="toc">Following Links</a></span></div></li>
|
||||
<li class="level3"><div class="li"><span class="li"><a href="#use_ctrl_shift_tab_to_switch_between_pages" class="toc">Use Ctrl(+Shift)+Tab to switch between pages</a></span></div></li>
|
||||
<li class="level3"><div class="li"><span class="li"><a href="#customizing_keyboard_shortcuts" class="toc">Customizing keyboard shortcuts</a></span></div></li>
|
||||
<li class="level3"><div class="li"><span class="li"><a href="#using_find" class="toc">Using Find</a></span></div></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li class="level1"><div class="li"><span class="li"><a href="#proxy_servers" class="toc">Proxy servers</a></span></div></li>
|
||||
<li class="level1"><div class="li"><span class="li"><a href="#keyboard_hotkeys" class="toc">Keyboard Hotkeys</a></span></div></li>
|
||||
<li class="level1"><div class="li"><span class="li"><a href="#mouse_gestures" class="toc">Mouse Gestures</a></span></div></li>
|
||||
<li class="level1"><div class="li"><span class="li"><a href="#user_scripts_and_styles" class="toc">User scripts and styles</a></span></div>
|
||||
<ul class="toc">
|
||||
<li class="level2"><div class="li"><span class="li"><a href="#user_styles" class="toc">User styles</a></span></div></li>
|
||||
</ul></li>
|
||||
</ul>
|
||||
<li class="level2"><div class="li"><span class="li"><a href="#mouse_gestures" class="toc">Mouse Gestures</a></span></div></li>
|
||||
<li class="level2"><div class="li"><span class="li"><a href="#spell_check" class="toc">Spell check</a></span></div></li>
|
||||
<li class="level2"><div class="li"><span class="li"><a href="#user_scripts" class="toc">User scripts</a></span></div></li>
|
||||
<li class="level2"><div class="li"><span class="li"><a href="#user_styles" class="toc">User styles</a></span></div></li></ul>
|
||||
</li></ul>
|
||||
</div>
|
||||
</div>
|
||||
<!-- TOC END -->
|
||||
|
@ -82,10 +76,15 @@ This is a snapshot of Frequently Asked Questions designated for offline viewing.
|
|||
<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">
|
||||
|
||||
</div>
|
||||
<!-- EDIT2 SECTION "Getting started" [290-319] -->
|
||||
<h2 class="sectionedit3"><a name="about_midori" id="about_midori">About Midori</a></h2>
|
||||
<div class="level2">
|
||||
|
||||
</div>
|
||||
|
||||
<h4><a name="what_is_midori_and_why_should_i_use_it" id="what_is_midori_and_why_should_i_use_it">What is "Midori" and why should I use it?</a></h4>
|
||||
|
@ -132,9 +131,9 @@ Midori and all delivered artwork are licensed under the LGPL2.
|
|||
</p>
|
||||
|
||||
</div>
|
||||
|
||||
<h1 class="sectionedit3"><a name="common_problems" id="common_problems">Common problems</a></h1>
|
||||
<div class="level1">
|
||||
<!-- EDIT3 SECTION "About Midori" [320-1212] -->
|
||||
<h2 class="sectionedit4"><a name="common_problems" id="common_problems">Common problems</a></h2>
|
||||
<div class="level2">
|
||||
|
||||
</div>
|
||||
|
||||
|
@ -194,12 +193,6 @@ Use a smaller toolbar:
|
|||
</p>
|
||||
<pre class="code">gtk-toolbar-icon-size = GTK_ICON_SIZE_SMALL_TOOLBAR</pre>
|
||||
|
||||
<p>
|
||||
Only for those not running a complete DE like Xfce, Elementary, etc…<br/>
|
||||
|
||||
There is a preference: Preferences → Browsing → Toolbar Style: Small icons
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Enable changing hotkeys while hovering menu items:
|
||||
</p>
|
||||
|
@ -216,80 +209,7 @@ There appears to be an issue with Glib 2.16. The recommended solution is to upgr
|
|||
|
||||
</div>
|
||||
|
||||
<h4><a name="how_can_i_change_the_cache_folder_to_tmpfs" id="how_can_i_change_the_cache_folder_to_tmpfs">How can I change the cache folder (to tmpfs)?</a></h4>
|
||||
<div class="level4">
|
||||
|
||||
<p>
|
||||
On Linux and BSD, you can set XDG_CACHE_HOME for all applications, or just Midori. Midori saves icons and cache files in that location. The default is ~/.cache.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
export XDG_CACHE_HOME=/dev/shm
|
||||
</p>
|
||||
|
||||
</div>
|
||||
|
||||
<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 >= 0.4.7 automatically picks up the Strict-Transport-Security header and caches sites locally. By design, there'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 >= 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't find a place to store the imported certificate</a></h5>
|
||||
<div class="level5">
|
||||
|
||||
<p>
|
||||
No key store is available or it'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'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't work</a></h2>
|
||||
<div class="level2">
|
||||
|
||||
</div>
|
||||
|
||||
<h4><a name="windows_support" id="windows_support">Windows support</a></h4>
|
||||
<div class="level4">
|
||||
|
||||
<p>
|
||||
WebKitGTK+ and thusly Midori on Windows doesn't support Flash or any other plugins. If WebKitGTK+ adds the feature in the future, we will support it. For now there'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>
|
||||
|
||||
<h4><a name="netscape_plugins_on_linux_bsd_and_os_x" id="netscape_plugins_on_linux_bsd_and_os_x">Netscape plugins on Linux, BSD and OS X</a></h4>
|
||||
<h4><a name="flashnetscape_plugins_don_t_work" id="flashnetscape_plugins_don_t_work">Flash/ Netscape plugins don't work</a></h4>
|
||||
<div class="level4">
|
||||
|
||||
<p>
|
||||
|
@ -307,17 +227,11 @@ You can either run that above line and run Midori in the same terminal afterward
|
|||
|
||||
</div>
|
||||
|
||||
<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>
|
||||
<h4><a name="flash_is_crashing_all_the_time" id="flash_is_crashing_all_the_time">Flash is crashing all the time</a></h4>
|
||||
<div class="level4">
|
||||
|
||||
<p>
|
||||
nspluginwrapper is a program that runs Flash and other Netscape plugins in a separate process. So a crash can'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
|
||||
Try searching for a package named nspluginwrapper or similar in your distribution repositories. It implements plugins in their own process so they can't drag down the whole browser.
|
||||
</p>
|
||||
|
||||
</div>
|
||||
|
@ -332,28 +246,13 @@ That'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't supported?</a></h4>
|
||||
<div class="level4">
|
||||
|
||||
<p>
|
||||
There's no official support right now. It'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>
|
||||
<h4><a name="scroll_with_middle_mouse_button" id="scroll_with_middle_mouse_button">Scroll with middle mouse button</a></h4>
|
||||
<div class="level4">
|
||||
|
||||
<p>
|
||||
<a href="http://ubuntuforums.org/showthread.php?t=478418" class="urlextern" title="http://ubuntuforums.org/showthread.php?t=478418" rel="nofollow">http://ubuntuforums.org/showthread.php?t=478418</a>
|
||||
</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><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>
|
||||
|
||||
</div>
|
||||
|
||||
<h4><a name="html5_video_doesn_t_play" id="html5_video_doesn_t_play">HTML5 Video doesn't play</a></h4>
|
||||
|
@ -367,6 +266,8 @@ You need to have GStreamer plugins installed which implement the codecs.
|
|||
</li>
|
||||
<li class="level1"><div class="li"> You may need gstreamer0.10-alsa for ALSA, depending on your distribution.</div>
|
||||
</li>
|
||||
<li class="level1"><div class="li"> With Arch Linux, you may need to install liboil explicitly if it is not installed already (see <a href="https://bugs.archlinux.org/task/20945" class="urlextern" title="https://bugs.archlinux.org/task/20945" rel="nofollow">this</a> bug report).</div>
|
||||
</li>
|
||||
<li class="level1"><div class="li"> You need plugins for Theora, gstreamer0.10-base and <acronym title="Moving Picture Experts Group">MPEG</acronym>-4 incluing aac (e.g. gst-plugins-faad), gstreamer0.10-bad. For WebM, you'll need plugins for vorbis (-base), matroska (-good), and vp8 (-bad). Have a look at <a href="http://www.gstreamer.net/documentation/plugins.html" class="urlextern" title="http://www.gstreamer.net/documentation/plugins.html" rel="nofollow">http://www.gstreamer.net/documentation/plugins.html</a> for details.</div>
|
||||
</li>
|
||||
<li class="level1"><div class="li"> For Youtube or Vimeo, you need WebKitGTK+ 1.1.20 or newer.</div>
|
||||
|
@ -392,6 +293,36 @@ icedtea6 version 1.8 and above has been known to crash midori. If this is the c
|
|||
|
||||
</div>
|
||||
|
||||
<h4><a name="are_socks_proxy_servers_supported" id="are_socks_proxy_servers_supported">Are SOCKS proxy servers supported?</a></h4>
|
||||
<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:
|
||||
</p>
|
||||
<ol>
|
||||
<li class="level1"><div class="li"> Install 'tsocks'</div>
|
||||
</li>
|
||||
<li class="level1"><div class="li"> Open /etc/tsocks.conf in an editor</div>
|
||||
</li>
|
||||
<li class="level1"><div class="li"> Type something like this, you can choose the port freely: <pre class="code">server = 127.0.0.1
|
||||
server_type = 5
|
||||
server_port = 5555</pre>
|
||||
</div>
|
||||
</li>
|
||||
<li class="level1"><div class="li"> Open an <acronym title="Secure Shell">SSH</acronym> connection with the same port: <pre class="code"> ssh -D localhost:5555 myhost.com </pre>
|
||||
</div>
|
||||
</li>
|
||||
<li class="level1"><div class="li"> Run Midori with “tsocks” in front of it: <pre class="code"> tsocks midori </pre>
|
||||
</div>
|
||||
</li>
|
||||
<li class="level1"><div class="li"> Now you can use for example <a href="http://www.whatsmyip.org/" class="urlextern" title="http://www.whatsmyip.org/" rel="nofollow">http://www.whatsmyip.org/</a> to verify that you are using a SOCKS connection. The IP address should match the one of your <acronym title="Secure Shell">SSH</acronym> host. Remember to keep the <acronym title="Secure Shell">SSH</acronym> login running, and don't suspend it, otherwise it won't work.</div>
|
||||
</li>
|
||||
<li class="level1"><div class="li"> If the connection fails for some reason, you should see a connection error.</div>
|
||||
</li>
|
||||
</ol>
|
||||
|
||||
</div>
|
||||
|
||||
<h4><a name="how_do_i_get_rid_of_the_menubar" id="how_do_i_get_rid_of_the_menubar">How do I get rid of the menubar?</a></h4>
|
||||
<div class="level4">
|
||||
|
||||
|
@ -500,138 +431,25 @@ As of git 2011-03-05 02:40:00 UTC and Midori 0.3.3 you can
|
|||
<p>
|
||||
Add a line to ~/.local/share/applications/mimeapps.list:
|
||||
</p>
|
||||
<pre class="code">x-scheme-handler/magnet=transmission-gtk.desktop</pre>
|
||||
<pre class="code"> x-scheme-handler/magnet=transmission-gtk.desktop</pre>
|
||||
|
||||
<p>
|
||||
Or install an application which advertises the scheme like so:
|
||||
</p>
|
||||
<pre class="code">MimeType=x-scheme-handler/magnet;</pre>
|
||||
<pre class="code"> MimeType=x-scheme-handler/magnet;</pre>
|
||||
|
||||
<p>
|
||||
Note that incomplete .desktop files will silently fail and it will look as if it doesn't exist.
|
||||
</p>
|
||||
|
||||
</div>
|
||||
|
||||
<h4><a name="spell_check" id="spell_check">Spell check</a></h4>
|
||||
<div class="level4">
|
||||
|
||||
<p>
|
||||
First enable spell checking:
|
||||
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. 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>
|
||||
|
||||
<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 ↵" 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>
|
||||
<!-- EDIT4 SECTION "Common problems" [1213-8946] -->
|
||||
<h1 class="sectionedit5"><a name="features" id="features">Features</a></h1>
|
||||
<div class="level1">
|
||||
|
||||
</div>
|
||||
|
||||
<h2 class="sectionedit7"><a name="blacklist_cookies" id="blacklist_cookies">Blacklist cookies</a></h2>
|
||||
<div class="level2">
|
||||
|
||||
<p>
|
||||
As of Midori 0.4.4 you can add a hidden option to ~/.config/midori/config like so:
|
||||
</p>
|
||||
<pre class="code">site-data-rules=-google.com,-facebook.com,!bugzilla.gnome.org,+bugs.launchpad.net</pre>
|
||||
<ol>
|
||||
<li class="level1"><div class="li"> Values prefixed with ”-” are always blocked</div>
|
||||
</li>
|
||||
<li class="level1"><div class="li"> Values prefixed with ”+” are always accepted</div>
|
||||
</li>
|
||||
<li class="level1"><div class="li"> Values prefixed with ”!” are not cleared in Clear Private Data</div>
|
||||
</li>
|
||||
<li class="level1"><div class="li"> No wildcards.</div>
|
||||
</li>
|
||||
<li class="level1"><div class="li"> LSO, local storage and application caches ignore all policies.</div>
|
||||
</li>
|
||||
</ol>
|
||||
|
||||
<p>
|
||||
The feature is currently experimental and will change in future versions.
|
||||
</p>
|
||||
|
||||
</div>
|
||||
|
||||
<h2 class="sectionedit8"><a name="adblock" id="adblock">Adblock</a></h2>
|
||||
<div class="level2">
|
||||
|
||||
<p>
|
||||
The Advertisement Blocker can be activated under Extensions. It uses the same lists as Adblock Plus. URLs are blocked completely and never loaded. Lists can be added through the option button on the right side in the extension list.
|
||||
</p>
|
||||
|
||||
</div>
|
||||
|
||||
<h1 class="sectionedit9"><a name="modes" id="modes">Modes</a></h1>
|
||||
<div class="level1">
|
||||
|
||||
</div>
|
||||
|
||||
<h2 class="sectionedit10"><a name="web_applications" id="web_applications">Web Applications</a></h2>
|
||||
<!-- EDIT5 SECTION "Features" [8947-8969] -->
|
||||
<h2 class="sectionedit6"><a name="web_applications" id="web_applications">Web Applications</a></h2>
|
||||
<div class="level2">
|
||||
|
||||
<p>
|
||||
|
@ -651,13 +469,13 @@ There are two closely related features to open websites as dedicated windows of
|
|||
</p>
|
||||
|
||||
</div>
|
||||
|
||||
<h2 class="sectionedit11"><a name="private_browsing" id="private_browsing">Private Browsing</a></h2>
|
||||
<!-- EDIT6 SECTION "Web Applications" [8970-9486] -->
|
||||
<h2 class="sectionedit7"><a name="private_browsing" id="private_browsing">Private Browsing</a></h2>
|
||||
<div class="level2">
|
||||
|
||||
<p>
|
||||
File menu/ App Menu button → Private Browsing
|
||||
</p>
|
||||
<ol>
|
||||
<li class="level1"><div class="li"> File menu/ App Menu button → Private Browsing</div>
|
||||
</li>
|
||||
</ol>
|
||||
|
||||
<p>
|
||||
A private window is a separate process, so crashes don't affect the normal browser session. No sensitive data such as cookies, history or bookmarks are stored. No extensions are loaded. Panels are not available.
|
||||
|
@ -677,51 +495,10 @@ The same options available to -a/ –app can be used for private browsing mode.
|
|||
</p>
|
||||
|
||||
</div>
|
||||
|
||||
<h2 class="sectionedit12"><a name="portable_modewin32" id="portable_modewin32">Portable mode/ Win32</a></h2>
|
||||
<!-- EDIT7 SECTION "Private Browsing" [9487-10410] -->
|
||||
<h2 class="sectionedit8"><a name="proxy_servers" id="proxy_servers">Proxy servers</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>
|
||||
There is no specific mode, instead you use several command line switches. A typical fullscreen setup with no toolbar that opens about:blank and resets the session after 2 minutes of inactivity for instance:
|
||||
</p>
|
||||
<pre class="code bash">midori <span class="re5">-i</span> <span class="nu0">120</span> <span class="re5">-e</span> Fullscreen <span class="re5">-e</span> Navigationbar <span class="re5">-a</span> about:blank</pre>
|
||||
|
||||
<p>
|
||||
Available commands for -e can be listed with “midori –help-execute”.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
If needed, a customized profile can be created with “midori -c /path/to/folder”. Using the shortcut editor extension, keyboard shortcuts can be removed as needed. Afterwards just append ”-c /path/to/folder” to the kiosk mode command line.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
To restrict pages that can be opened, you can use a regular expression. The expression is a blacklist. To block undesirable sites you can do something like:
|
||||
</p>
|
||||
<pre class="code bash"><span class="re5">-b</span> <span class="st_h">'youtube|youporn'</span></pre>
|
||||
|
||||
<p>
|
||||
By negating the expression you can also whitelist pages.
|
||||
</p>
|
||||
<pre class="code bash"><span class="re5">-b</span> <span class="st_h">'^(?!.*?(gmail|mail\.google|accounts\.google)).*'</span></pre>
|
||||
|
||||
<p>
|
||||
Any links outside end up in an error page. All images and other files won't be loaded.
|
||||
</p>
|
||||
|
||||
</div>
|
||||
|
||||
<h1 class="sectionedit14"><a name="proxy_servers" id="proxy_servers">Proxy servers</a></h1>
|
||||
<div class="level1">
|
||||
|
||||
<p>
|
||||
By running a local proxy you can modify web content even before it has reached Midori. That allows you to do things similar to what user scripts and user styles provide and even others that neither is suitable for.
|
||||
</p>
|
||||
|
@ -768,48 +545,14 @@ Mousehole is a scriptable proxy server written in Ruby.
|
|||
</p>
|
||||
|
||||
</div>
|
||||
|
||||
<h4><a name="are_socks_proxy_servers_supported" id="are_socks_proxy_servers_supported">Are SOCKS proxy servers supported?</a></h4>
|
||||
<div class="level4">
|
||||
|
||||
<p>
|
||||
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 < 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 'tsocks'</div>
|
||||
</li>
|
||||
<li class="level1"><div class="li"> Open /etc/tsocks.conf in an editor</div>
|
||||
</li>
|
||||
<li class="level1"><div class="li"> Type something like this, you can choose the port freely: <pre class="code">server = 127.0.0.1
|
||||
server_type = 5
|
||||
server_port = 5555</pre>
|
||||
</div>
|
||||
</li>
|
||||
<li class="level1"><div class="li"> Open an <acronym title="Secure Shell">SSH</acronym> connection with the same port: <pre class="code"> ssh -D localhost:5555 myhost.com </pre>
|
||||
</div>
|
||||
</li>
|
||||
<li class="level1"><div class="li"> Run Midori with “tsocks” in front of it: <pre class="code"> tsocks midori </pre>
|
||||
</div>
|
||||
</li>
|
||||
<li class="level1"><div class="li"> Now you can use for example <a href="http://www.whatsmyip.org/" class="urlextern" title="http://www.whatsmyip.org/" rel="nofollow">http://www.whatsmyip.org/</a> to verify that you are using a SOCKS connection. The IP address should match the one of your <acronym title="Secure Shell">SSH</acronym> host. Remember to keep the <acronym title="Secure Shell">SSH</acronym> login running, and don't suspend it, otherwise it won't work.</div>
|
||||
</li>
|
||||
<li class="level1"><div class="li"> If the connection fails for some reason, you should see a connection error.</div>
|
||||
</li>
|
||||
</ol>
|
||||
<!-- EDIT8 SECTION "Proxy servers" [10411-11241] -->
|
||||
<h2 class="sectionedit9"><a name="using_the_keyboard" id="using_the_keyboard">Using the Keyboard</a></h2>
|
||||
<div class="level2">
|
||||
|
||||
</div>
|
||||
|
||||
<h1 class="sectionedit15"><a name="keyboard_hotkeys" id="keyboard_hotkeys">Keyboard Hotkeys</a></h1>
|
||||
<div class="level1">
|
||||
|
||||
</div>
|
||||
|
||||
<h4><a name="hjkl" id="hjkl">HJKL</a></h4>
|
||||
<div class="level4">
|
||||
<!-- EDIT9 SECTION "Using the Keyboard" [11242-11273] -->
|
||||
<h3 class="sectionedit10"><a name="hjkl" id="hjkl">HJKL</a></h3>
|
||||
<div class="level3">
|
||||
|
||||
<p>
|
||||
You can use the Vim-like key bindings [hjkl] to navigate a page. h=left j=down k=up l=right In a picture:
|
||||
|
@ -823,12 +566,12 @@ You can also use the arrow keys to do the same.
|
|||
</p>
|
||||
|
||||
</div>
|
||||
|
||||
<h4><a name="following_links" id="following_links">Following Links</a></h4>
|
||||
<div class="level4">
|
||||
<!-- EDIT10 SECTION "HJKL" [11274-11481] -->
|
||||
<h3 class="sectionedit11"><a name="following_links" id="following_links">Following Links</a></h3>
|
||||
<div class="level3">
|
||||
|
||||
<p>
|
||||
To enable Hints in Midori, similar to vimperator in Firefox or xxxterm, press .
|
||||
To enable Hints in Midori [similar to those vimperator provides in Firefox], press .
|
||||
</p>
|
||||
|
||||
<p>
|
||||
|
@ -836,9 +579,9 @@ With hints enabled, type the link number, and press Enter to open the link in th
|
|||
</p>
|
||||
|
||||
</div>
|
||||
|
||||
<h4><a name="use_ctrl_shift_tab_to_switch_between_pages" id="use_ctrl_shift_tab_to_switch_between_pages">Use Ctrl(+Shift)+Tab to switch between pages</a></h4>
|
||||
<div class="level4">
|
||||
<!-- EDIT11 SECTION "Following Links" [11482-11813] -->
|
||||
<h3 class="sectionedit12"><a name="use_ctrl_shift_tab_to_switch_between_pages" id="use_ctrl_shift_tab_to_switch_between_pages">Use Ctrl(+Shift)+Tab to switch between pages</a></h3>
|
||||
<div class="level3">
|
||||
|
||||
<p>
|
||||
Since Midori 0.3.5 Ctrl+Tab is supported by default.
|
||||
|
@ -849,18 +592,18 @@ In older versions you can enable the History List extension under Tools → Exte
|
|||
</p>
|
||||
|
||||
</div>
|
||||
|
||||
<h4><a name="customizing_keyboard_shortcuts" id="customizing_keyboard_shortcuts">Customizing keyboard shortcuts</a></h4>
|
||||
<div class="level4">
|
||||
<!-- EDIT12 SECTION "Use Ctrl(+Shift)+Tab to switch between pages" [11814-12012] -->
|
||||
<h3 class="sectionedit13"><a name="customizing_keyboard_shortcuts" id="customizing_keyboard_shortcuts">Customizing keyboard shortcuts</a></h3>
|
||||
<div class="level3">
|
||||
|
||||
<p>
|
||||
Enable the Shortcuts extension Tools → Extensions. To edit a keybinding Tools → Customize Shortcuts…
|
||||
</p>
|
||||
|
||||
</div>
|
||||
|
||||
<h4><a name="using_find" id="using_find">Using Find</a></h4>
|
||||
<div class="level4">
|
||||
<!-- EDIT13 SECTION "Customizing keyboard shortcuts" [12013-12162] -->
|
||||
<h3 class="sectionedit14"><a name="using_find" id="using_find">Using Find</a></h3>
|
||||
<div class="level3">
|
||||
|
||||
<p>
|
||||
Default shortcuts for Find are:
|
||||
|
@ -869,7 +612,7 @@ Default shortcuts for Find are:
|
|||
<p>
|
||||
Find: Ctrl+f ”/” and ”,”<br/>
|
||||
|
||||
FindNext: Ctrl+g and Enter<br/>
|
||||
FindNext: Ctrl+g<br/>
|
||||
|
||||
FindPrevious: Shift+Ctrl+g<br/>
|
||||
|
||||
|
@ -884,9 +627,9 @@ When using Ctrl+f to bring up Find, use Ctrl+f again or ESC. When using ”/”
|
|||
</p>
|
||||
|
||||
</div>
|
||||
|
||||
<h1 class="sectionedit16"><a name="mouse_gestures" id="mouse_gestures">Mouse Gestures</a></h1>
|
||||
<div class="level1">
|
||||
<!-- EDIT14 SECTION "Using Find" [12163-12579] -->
|
||||
<h2 class="sectionedit15"><a name="mouse_gestures" id="mouse_gestures">Mouse Gestures</a></h2>
|
||||
<div class="level2">
|
||||
|
||||
<p>
|
||||
By default the right mouse button initiates gestures.
|
||||
|
@ -914,9 +657,28 @@ Additionally, there are programs allowing mouse gestures system-wide, for exampl
|
|||
</p>
|
||||
|
||||
</div>
|
||||
<!-- EDIT15 SECTION "Mouse Gestures" [12580-13253] -->
|
||||
<h2 class="sectionedit16"><a name="spell_check" id="spell_check">Spell check</a></h2>
|
||||
<div class="level2">
|
||||
|
||||
<h1 class="sectionedit17"><a name="user_scripts_and_styles" id="user_scripts_and_styles">User scripts and styles</a></h1>
|
||||
<div class="level1">
|
||||
<p>
|
||||
First enable spell checking:
|
||||
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.
|
||||
</p>
|
||||
|
||||
</div>
|
||||
<!-- EDIT16 SECTION "Spell check" [13254-13543] -->
|
||||
<h2 class="sectionedit17"><a name="user_scripts" id="user_scripts">User scripts</a></h2>
|
||||
<div class="level2">
|
||||
|
||||
</div>
|
||||
|
||||
<h4><a name="overview" id="overview">Overview</a></h4>
|
||||
<div class="level4">
|
||||
|
||||
<p>
|
||||
UserScripts are scripts applied on some, or on all web pages. They can modify pages locally to add or alter functionality. That includes fixing bugs in web pages. User scripts are also available in other browsers, in the form of <a href="http://www.greasespot.net" class="urlextern" title="http://www.greasespot.net" rel="nofollow">Mozilla's Greasemonkey</a> or <a href="http://www.opera.com/support/tutorials/userjs/" class="urlextern" title="http://www.opera.com/support/tutorials/userjs/" rel="nofollow">Opera's User JavaScript</a>.
|
||||
|
@ -975,10 +737,15 @@ You can also use <a href="http://rightfootin.blogspot.com/2009/04/flashblock-wan
|
|||
</p>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- EDIT17 SECTION "User scripts" [13544-16104] -->
|
||||
<h2 class="sectionedit18"><a name="user_styles" id="user_styles">User styles</a></h2>
|
||||
<div class="level2">
|
||||
|
||||
</div>
|
||||
|
||||
<h4><a name="overview1" id="overview1">Overview</a></h4>
|
||||
<div class="level4">
|
||||
|
||||
<p>
|
||||
User styles are <acronym title="Cascading Style Sheets">CSS</acronym> Cascading Style sheets that are loaded locally and applied on top of web pages, similar to User scripts, in order to add or alter functionality and also fix bugs.
|
||||
</p>
|
||||
|
@ -1037,6 +804,6 @@ Customize as needed:
|
|||
}</pre>
|
||||
|
||||
</div>
|
||||
<!-- EDIT16 SECTION "User styles" [18560-] --></div>
|
||||
<!-- EDIT18 SECTION "User styles" [16105-] --></div>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -1,28 +0,0 @@
|
|||
.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;
|
||||
}
|
|
@ -3,8 +3,7 @@ Version=1.0
|
|||
Type=Application
|
||||
_Name=Midori
|
||||
_GenericName=Web Browser
|
||||
_X-GNOME-Fullname=Midori Web Browser
|
||||
_Comment=Browse the Web
|
||||
_Comment=Lightweight web browser
|
||||
_X-GNOME-Keywords=Internet;WWW;Explorer
|
||||
_X-AppInstall-Keywords=Internet;WWW;Explorer
|
||||
Categories=GTK;Network;WebBrowser;
|
||||
|
@ -18,17 +17,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 Private Browsing Window
|
||||
Name=New P_rivate Browsing Window
|
||||
Exec=midori --private
|
||||
TargetEnvironment=Unity
|
||||
|
||||
|
|
|
@ -55,7 +55,10 @@
|
|||
width: 85%;
|
||||
height: 75%;
|
||||
margin: auto;
|
||||
-webkit-box-shadow: 0 2px 5px rgba(0,0,0,.3), 0 0 0px #fff inset;
|
||||
-webkit-box-shadow: 0 4px 18px rgba(0,0,0,.3), 0 0 2px #fff inset;
|
||||
background-image: -webkit-gradient(
|
||||
linear, center top, center bottom,
|
||||
from(#f6f6f6), to(#e3e3e3));
|
||||
border: 1px solid #bcbcbc;
|
||||
border-bottom-color: #a0a0a0;
|
||||
position: relative;
|
||||
|
@ -72,15 +75,9 @@
|
|||
div.shortcut .preview.new .add {
|
||||
display: block;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
width: 50%;
|
||||
margin: 0 auto;
|
||||
cursor: pointer;
|
||||
-webkit-box-shadow: 0 2px 5px rgba(0,0,0,.3), 0 0 0px #fff inset;
|
||||
background-image: -webkit-gradient(
|
||||
linear, center top, center bottom,
|
||||
from(#f6f6f6), to(#e3e3e3));
|
||||
background-repeat: repeat-x;
|
||||
-webkit-border-radius: 3px;
|
||||
}
|
||||
|
||||
.title {
|
||||
|
@ -114,148 +111,95 @@
|
|||
display:none;
|
||||
}
|
||||
|
||||
.selected {
|
||||
outline: 1px dotted black;
|
||||
background-color: #eef;
|
||||
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;
|
||||
}
|
||||
</style>
|
||||
|
||||
<script type="text/javascript">
|
||||
|
||||
function add_tile (ev) {
|
||||
ev.preventDefault();
|
||||
var getAction = function (id)
|
||||
{
|
||||
var s = document.getElementById(id).childNodes[0];
|
||||
if (s.className == 'preview')
|
||||
return true;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
function rename_tile (ev) {
|
||||
var old_name = ev.target.textContent;
|
||||
var renameShortcut = function (id)
|
||||
{
|
||||
var old_name = document.getElementById(id).childNodes[1].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);
|
||||
}
|
||||
|
||||
function delete_tile (ev) {
|
||||
ev.preventDefault();
|
||||
|
||||
if (!confirm("{are_you_sure}"))
|
||||
var clearShortcut = function (id)
|
||||
{
|
||||
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;
|
||||
|
||||
var firstNode, secondNode;
|
||||
var cursor;
|
||||
|
||||
var get_dial_div = function (ele) {
|
||||
var dial_div;
|
||||
if (ele.nodeName == 'IMG')
|
||||
dial_div = ele.parentNode.parentNode.parentNode;
|
||||
if (ele.className == 'title')
|
||||
dial_div = ele.parentNode;
|
||||
if (ele.className.indexOf ('shortcut') != -1)
|
||||
dial_div = ele;
|
||||
return dial_div;
|
||||
}
|
||||
|
||||
function click (ev) {
|
||||
if (ev == undefined)
|
||||
return;
|
||||
|
||||
ev.preventDefault();
|
||||
var ele = ev.target;
|
||||
cursor = ele.style.cursor;
|
||||
ele.style.cursor = 'move';
|
||||
|
||||
var eparent = get_dial_div (ele);
|
||||
if (eparent != undefined) {
|
||||
eparent.className = 'shortcut selected';
|
||||
firstNode = eparent.id;
|
||||
}
|
||||
};
|
||||
|
||||
function up (ev) {
|
||||
if (ev == undefined)
|
||||
return;
|
||||
|
||||
ev.preventDefault();
|
||||
ele = ev.target;
|
||||
var eparent = get_dial_div (ele);
|
||||
|
||||
ele.style.cursor = cursor;
|
||||
secondNode = eparent.id;
|
||||
|
||||
/* ommit just mere clicking the dial */
|
||||
if (firstNode != secondNode && firstNode != undefined)
|
||||
swap();
|
||||
};
|
||||
|
||||
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)
|
||||
document.onkeypress = function ()
|
||||
{
|
||||
eparent.className = 'shortcut selected';
|
||||
for (var i = 0; i < dial.length; i++) {
|
||||
if (eparent.id != firstNode.id && dial[i].id != eparent.id) {
|
||||
dial[i].className = 'shortcut';
|
||||
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);
|
||||
}
|
||||
}
|
||||
ele.style.cursor = cursor;
|
||||
else
|
||||
key_id = 's';
|
||||
|
||||
if (key_id.length <= 1)
|
||||
document.getElementById('dialing').style.visibility = 'hidden';
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function swap () {
|
||||
console.log ("speed_dial-save-swap " + firstNode + " " + secondNode);
|
||||
};
|
||||
|
||||
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 onload="init ();">
|
||||
<body>
|
||||
<div class="osd" >
|
||||
<span id="dialing"></span>
|
||||
</div>
|
||||
<div id="content">
|
||||
|
|
|
@ -6,20 +6,18 @@ import pproc as subprocess
|
|||
import os
|
||||
import Utils
|
||||
|
||||
blddir = '_build' # recognized by ack
|
||||
|
||||
for module in ('midori', 'katze'):
|
||||
try:
|
||||
if not os.access (blddir, os.F_OK):
|
||||
Utils.check_dir (blddir)
|
||||
if not os.access (blddir + '/docs', os.F_OK):
|
||||
Utils.check_dir (blddir + '/docs')
|
||||
if not os.access (blddir + '/docs/api', os.F_OK):
|
||||
Utils.check_dir (blddir + '/docs/api')
|
||||
if not os.access ('_build_', os.F_OK):
|
||||
Utils.check_dir ('_build_')
|
||||
if not os.access ('_build_/docs', os.F_OK):
|
||||
Utils.check_dir ('_build_/docs')
|
||||
if not os.access ('_build_/docs/api', os.F_OK):
|
||||
Utils.check_dir ('_build_/docs/api')
|
||||
subprocess.call (['gtkdoc-scan', '--module=' + module,
|
||||
'--source-dir=' + module, '--output-dir=' + blddir + '/docs/api/' + module,
|
||||
'--source-dir=' + module, '--output-dir=_build_/docs/api/' + module,
|
||||
'--rebuild-sections', '--rebuild-types'])
|
||||
os.chdir (blddir + '/docs/api/' + module)
|
||||
os.chdir ('_build_/docs/api/' + module)
|
||||
subprocess.call (['gtkdoc-mktmpl', '--module=' + module,
|
||||
'--output-dir=.' + module])
|
||||
subprocess.call (['gtkdoc-mkdb', '--module=' + module,
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -14,7 +14,6 @@
|
|||
/* 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"
|
||||
|
@ -183,8 +182,8 @@ addons_install_response (GtkWidget* infobar,
|
|||
|
||||
if (!filename)
|
||||
filename = g_path_get_basename (uri);
|
||||
folder_path = g_build_path (G_DIR_SEPARATOR_S,
|
||||
midori_paths_get_user_data_dir (), PACKAGE_NAME, folder, NULL);
|
||||
folder_path = g_build_path (G_DIR_SEPARATOR_S, g_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);
|
||||
|
@ -294,13 +293,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, midori_paths_get_user_data_dir (),
|
||||
path = g_build_path (G_DIR_SEPARATOR_S, g_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, midori_paths_get_user_data_dir (),
|
||||
path = g_build_path (G_DIR_SEPARATOR_S, g_get_user_data_dir (),
|
||||
PACKAGE_NAME, "styles", NULL);
|
||||
}
|
||||
else
|
||||
|
@ -337,13 +336,23 @@ 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;
|
||||
|
@ -482,7 +491,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, TRUE, element->fullpath, TRUE);
|
||||
sokoke_spawn_program (text_editor, element->fullpath);
|
||||
else
|
||||
{
|
||||
gchar* element_uri = g_filename_to_uri (element->fullpath, NULL, NULL);
|
||||
|
@ -513,13 +522,10 @@ addons_open_target_folder_clicked_cb (GtkWidget* toolitem,
|
|||
folder = g_path_get_dirname (element->fullpath);
|
||||
}
|
||||
else
|
||||
{
|
||||
folder = g_build_path (G_DIR_SEPARATOR_S, midori_paths_get_user_data_dir (),
|
||||
PACKAGE_NAME, addons->kind == ADDONS_USER_SCRIPTS
|
||||
folder = g_build_path (G_DIR_SEPARATOR_S, g_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);
|
||||
|
||||
|
@ -777,10 +783,11 @@ addons_treeview_render_text_cb (GtkTreeViewColumn* column,
|
|||
|
||||
gtk_tree_model_get (model, iter, 0, &element, -1);
|
||||
|
||||
g_object_set (renderer, "text", element->displayname,
|
||||
"sensitive", element->enabled,
|
||||
"ellipsize", PANGO_ELLIPSIZE_END,
|
||||
NULL);
|
||||
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);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -824,16 +831,19 @@ addons_get_directories (AddonsKind kind)
|
|||
else
|
||||
g_assert_not_reached ();
|
||||
|
||||
path = g_build_path (G_DIR_SEPARATOR_S, midori_paths_get_user_data_dir (),
|
||||
path = g_build_path (G_DIR_SEPARATOR_S, g_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);
|
||||
|
||||
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)
|
||||
if (g_slist_find (directories, path) == NULL && g_access (path, X_OK) == 0)
|
||||
directories = g_slist_prepend (directories, path);
|
||||
else
|
||||
g_free (path);
|
||||
|
@ -1325,9 +1335,8 @@ 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, TRUE);
|
||||
gtk_tree_view_column_pack_start (column, renderer_text, FALSE);
|
||||
gtk_tree_view_column_set_cell_data_func (column, renderer_text,
|
||||
(GtkTreeCellDataFunc)addons_treeview_render_text_cb,
|
||||
addons->treeview, NULL);
|
||||
|
@ -1678,10 +1687,10 @@ addons_save_settings (MidoriApp* app,
|
|||
|
||||
config_dir = midori_extension_get_config_dir (extension);
|
||||
config_file = g_build_filename (config_dir, "addons", NULL);
|
||||
if (config_dir != NULL)
|
||||
katze_mkdir_with_parents (config_dir, 0700);
|
||||
sokoke_key_file_save_to_file (keyfile, config_file, &error);
|
||||
if (error && midori_extension_get_config_dir (extension) != NULL)
|
||||
/* If the folder is /, this is a test run, thus no error */
|
||||
if (error && !g_str_equal (config_dir, "/"))
|
||||
{
|
||||
g_warning (_("The configuration of the extension '%s' couldn't be saved: %s\n"),
|
||||
_("User addons"), error->message);
|
||||
|
|
|
@ -48,10 +48,11 @@ colorful_tabs_view_notify_uri_cb (MidoriView* view,
|
|||
|
||||
if (!midori_uri_is_blank (midori_view_get_display_uri (view))
|
||||
&& (hostname = midori_uri_parse_hostname (midori_view_get_display_uri (view), NULL))
|
||||
&& midori_view_get_icon_uri (view) != NULL)
|
||||
&& katze_object_get_enum (view, "load-status") == MIDORI_LOAD_FINISHED)
|
||||
{
|
||||
icon = midori_view_get_icon (view);
|
||||
if (icon != NULL)
|
||||
|
||||
if (midori_view_get_icon_uri (view) != NULL)
|
||||
{
|
||||
GdkPixbuf* newpix;
|
||||
guchar* pixels;
|
||||
|
|
|
@ -702,6 +702,7 @@ 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)
|
||||
{
|
||||
|
@ -730,6 +731,8 @@ 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)
|
||||
{
|
||||
|
@ -809,20 +812,25 @@ static void cm_filter_entry_changed_cb(GtkEditable *editable, CookieManagerPage
|
|||
if (priv->ignore_changed_filter)
|
||||
return;
|
||||
|
||||
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 && *text)
|
||||
gtk_tree_view_collapse_all(GTK_TREE_VIEW(priv->treeview));
|
||||
else
|
||||
if (*text != '\0')
|
||||
gtk_tree_view_expand_all(GTK_TREE_VIEW(priv->treeview));
|
||||
else
|
||||
gtk_tree_view_collapse_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;
|
||||
|
@ -994,7 +1002,6 @@ 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);
|
||||
}
|
||||
|
@ -1015,7 +1022,6 @@ 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);
|
||||
|
@ -1039,8 +1045,10 @@ 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(
|
||||
|
@ -1092,6 +1100,7 @@ static void cookie_manager_page_init(CookieManagerPage *self)
|
|||
GtkWidget *desc_swin;
|
||||
GtkWidget *paned;
|
||||
GtkWidget *filter_hbox;
|
||||
GtkWidget *filter_label;
|
||||
GtkWidget *treeview;
|
||||
CookieManagerPagePrivate *priv;
|
||||
|
||||
|
@ -1123,15 +1132,29 @@ 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);
|
||||
|
||||
priv->filter_entry = sokoke_search_entry_new (_("Search Cookies by Name or Domain"));
|
||||
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"));
|
||||
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);
|
||||
|
||||
|
|
|
@ -1,231 +0,0 @@
|
|||
/*
|
||||
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 ();
|
||||
}
|
||||
|
|
@ -1,314 +0,0 @@
|
|||
/*
|
||||
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 Soup;
|
||||
using Katze;
|
||||
using Midori;
|
||||
using WebKit;
|
||||
|
||||
namespace EDM {
|
||||
[DBus (name = "net.launchpad.steadyflow.App")]
|
||||
interface SteadyflowInterface : GLib.Object {
|
||||
public abstract void AddFile (string url) throws IOError;
|
||||
}
|
||||
|
||||
private class DownloadRequest : GLib.Object {
|
||||
public string uri;
|
||||
public string auth;
|
||||
public string referer;
|
||||
public string? cookie_header;
|
||||
}
|
||||
|
||||
internal Manager manager;
|
||||
|
||||
private class Manager : GLib.Object {
|
||||
private CookieJar cookie_jar;
|
||||
private GLib.PtrArray download_managers = new GLib.PtrArray ();
|
||||
|
||||
public bool download_requested (Midori.View view, WebKit.Download download) {
|
||||
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 ();
|
||||
|
||||
var request = download.get_network_request ();
|
||||
var message = request.get_message ();
|
||||
weak MessageHeaders headers = message.request_headers;
|
||||
|
||||
dlReq.auth = headers.get ("Authorization");
|
||||
dlReq.referer = headers.get ("Referer");
|
||||
dlReq.cookie_header = this.cookie_jar.get_cookies (new Soup.URI (dlReq.uri), true);
|
||||
|
||||
for (var i = 0 ; i < download_managers.len; i++) {
|
||||
var dm = download_managers.index (i) as ExternalDownloadManager;
|
||||
if (dm.download (dlReq))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void tab_added (Midori.Browser browser, Midori.View view) {
|
||||
view.download_requested.connect (download_requested);
|
||||
}
|
||||
|
||||
public void tab_removed (Midori.Browser browser, Midori.View view) {
|
||||
view.download_requested.disconnect(download_requested);
|
||||
}
|
||||
|
||||
public void browser_added (Midori.Browser browser) {
|
||||
foreach (var tab in browser.get_tabs ())
|
||||
tab_added (browser, tab);
|
||||
browser.add_tab.connect (tab_added);
|
||||
browser.remove_tab.connect (tab_removed);
|
||||
}
|
||||
|
||||
public void browser_removed (Midori.Browser browser) {
|
||||
foreach (var tab in browser.get_tabs ())
|
||||
tab_removed (browser, tab);
|
||||
browser.add_tab.disconnect (tab_added);
|
||||
browser.remove_tab.disconnect (tab_removed);
|
||||
}
|
||||
|
||||
public void activated (Midori.Extension extension, Midori.App app) {
|
||||
this.download_managers.add (extension);
|
||||
if (this.download_managers.len == 1) {
|
||||
foreach (var browser in app.get_browsers ())
|
||||
browser_added (browser);
|
||||
app.add_browser.connect (browser_added);
|
||||
}
|
||||
}
|
||||
|
||||
public void deactivated (Midori.Extension extension) {
|
||||
this.download_managers.remove (extension);
|
||||
if (this.download_managers.len == 0) {
|
||||
var app = extension.get_app ();
|
||||
foreach (var browser in app.get_browsers ())
|
||||
browser_removed (browser);
|
||||
app.add_browser.disconnect (browser_added);
|
||||
}
|
||||
}
|
||||
|
||||
construct {
|
||||
var session = WebKit.get_default_session ();
|
||||
this.cookie_jar = session.get_feature (typeof (CookieJar)) as CookieJar;
|
||||
}
|
||||
}
|
||||
|
||||
private abstract class ExternalDownloadManager : Midori.Extension {
|
||||
public void activated (Midori.App app) {
|
||||
manager.activated (this, app);
|
||||
}
|
||||
|
||||
public void deactivated () {
|
||||
manager.deactivated (this);
|
||||
}
|
||||
|
||||
public void handle_exception (GLib.Error error) {
|
||||
string ext_name;
|
||||
this.get ("name",out ext_name);
|
||||
var dialog = new MessageDialog (null, DialogFlags.MODAL,
|
||||
MessageType.ERROR, ButtonsType.CLOSE,
|
||||
_("An error occurred when attempting to download a file with the following plugin:\n" +
|
||||
"%s\n\n" +
|
||||
"Error:\n%s\n\n" +
|
||||
"Carry on without this plugin."
|
||||
),
|
||||
ext_name, error.message);
|
||||
dialog.response.connect ((a) => { dialog.destroy (); });
|
||||
dialog.run ();
|
||||
}
|
||||
|
||||
public abstract bool download (DownloadRequest dlReq);
|
||||
}
|
||||
|
||||
private class Aria2 : ExternalDownloadManager {
|
||||
public override bool download (DownloadRequest dlReq) {
|
||||
var url = value_array_new ();
|
||||
value_array_insert (url, 0, typeof (string), dlReq.uri);
|
||||
|
||||
GLib.HashTable<string, GLib.Value?> options = value_hash_new ();
|
||||
var referer = new GLib.Value (typeof (string));
|
||||
referer.set_string (dlReq.referer);
|
||||
options.insert ("referer", referer);
|
||||
|
||||
var headers = value_array_new ();
|
||||
if (dlReq.cookie_header != null) {
|
||||
value_array_insert (headers, 0, typeof (string), "Cookie: %s".printf(dlReq.cookie_header));
|
||||
}
|
||||
|
||||
if (headers.n_values > 0)
|
||||
options.insert ("header", headers);
|
||||
|
||||
var message = XMLRPC.request_new ("http://127.0.0.1:6800/rpc",
|
||||
"aria2.addUri",
|
||||
typeof (ValueArray), url,
|
||||
typeof(HashTable), options);
|
||||
var session = new SessionSync ();
|
||||
session.send_message (message);
|
||||
|
||||
try {
|
||||
Value v;
|
||||
XMLRPC.parse_method_response ((string) message.response_body.flatten ().data, -1, out v);
|
||||
return true;
|
||||
} catch (Error e) {
|
||||
this.handle_exception (e);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
internal Aria2 () {
|
||||
GLib.Object (name: _("External Download Manager - Aria2"),
|
||||
description: _("Download files with Aria2"),
|
||||
version: "0.1" + Midori.VERSION_SUFFIX,
|
||||
authors: "André Stösel <andre@stoesel.de>",
|
||||
key: "aria2");
|
||||
|
||||
this.activate.connect (activated);
|
||||
this.deactivate.connect (deactivated);
|
||||
}
|
||||
}
|
||||
|
||||
private class SteadyFlow : ExternalDownloadManager {
|
||||
public override bool download (DownloadRequest dlReq) {
|
||||
try {
|
||||
SteadyflowInterface dm = Bus.get_proxy_sync (
|
||||
BusType.SESSION,
|
||||
"net.launchpad.steadyflow.App",
|
||||
"/net/launchpad/steadyflow/app");
|
||||
dm.AddFile (dlReq.uri);
|
||||
return true;
|
||||
} catch (Error e) {
|
||||
this.handle_exception (e);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
internal SteadyFlow () {
|
||||
GLib.Object (name: _("External Download Manager - SteadyFlow"),
|
||||
description: _("Download files with SteadyFlow"),
|
||||
version: "0.1" + Midori.VERSION_SUFFIX,
|
||||
authors: "André Stösel <andre@stoesel.de>",
|
||||
key: "steadyflow");
|
||||
|
||||
this.activate.connect (activated);
|
||||
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 () {
|
||||
EDM.manager = new EDM.Manager();
|
||||
|
||||
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;
|
||||
}
|
||||
|
|
@ -840,8 +840,7 @@ feed_panel_init (FeedPanel* panel)
|
|||
|
||||
webview = webkit_web_view_new ();
|
||||
#if GTK_CHECK_VERSION(3,0,0)
|
||||
font_desc = (PangoFontDescription*)gtk_style_context_get_font (
|
||||
gtk_widget_get_style_context (treeview), GTK_STATE_FLAG_NORMAL);
|
||||
font_desc = gtk_style_context_get_font(gtk_widget_get_style_context(treeview), GTK_STATE_FLAG_NORMAL);
|
||||
#else
|
||||
font_desc = treeview->style->font_desc;
|
||||
#endif
|
||||
|
|
600
extensions/formhistory.c
Normal file
600
extensions/formhistory.c
Normal file
|
@ -0,0 +1,600 @@
|
|||
/*
|
||||
Copyright (C) 2009 Alexander Butenko <a.butenka@gmail.com>
|
||||
Copyright (C) 2009 Christian Dywan <christian@twotoasts.de>
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
*/
|
||||
|
||||
#define MAXCHARS 60
|
||||
#define MINCHARS 2
|
||||
|
||||
#include <midori/midori.h>
|
||||
#include <glib/gstdio.h>
|
||||
|
||||
#include "config.h"
|
||||
#if HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
static GHashTable* global_keys;
|
||||
static gchar* jsforms;
|
||||
|
||||
|
||||
static void
|
||||
formhistory_toggle_state_cb (GtkAction* action,
|
||||
MidoriBrowser* browser);
|
||||
|
||||
static gboolean
|
||||
formhistory_prepare_js ()
|
||||
{
|
||||
gchar* autosuggest;
|
||||
gchar* style;
|
||||
guint i;
|
||||
gchar* file;
|
||||
|
||||
file = sokoke_find_data_filename ("autosuggestcontrol.js", TRUE);
|
||||
if (!g_file_get_contents (file, &autosuggest, NULL, NULL))
|
||||
{
|
||||
g_free (file);
|
||||
return FALSE;
|
||||
}
|
||||
g_strchomp (autosuggest);
|
||||
|
||||
katze_assign (file, sokoke_find_data_filename ("autosuggestcontrol.css", TRUE));
|
||||
if (!g_file_get_contents (file, &style, NULL, NULL))
|
||||
{
|
||||
g_free (file);
|
||||
return FALSE;
|
||||
}
|
||||
g_strchomp (style);
|
||||
i = 0;
|
||||
while (style[i])
|
||||
{
|
||||
if (style[i] == '\n')
|
||||
style[i] = ' ';
|
||||
i++;
|
||||
}
|
||||
|
||||
jsforms = g_strdup_printf (
|
||||
"%s"
|
||||
"window.addEventListener ('DOMContentLoaded',"
|
||||
"function () {"
|
||||
" if (document.getElementById('formhistory'))"
|
||||
" return;"
|
||||
" if (!initSuggestions ())"
|
||||
" return;"
|
||||
" var mystyle = document.createElement('style');"
|
||||
" mystyle.setAttribute('type', 'text/css');"
|
||||
" mystyle.setAttribute('id', 'formhistory');"
|
||||
" mystyle.appendChild(document.createTextNode('%s'));"
|
||||
" var head = document.getElementsByTagName('head')[0];"
|
||||
" if (head) head.appendChild(mystyle);"
|
||||
"}, true);",
|
||||
autosuggest,
|
||||
style);
|
||||
g_strstrip (jsforms);
|
||||
g_free (file);
|
||||
g_free (style);
|
||||
g_free (autosuggest);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gchar*
|
||||
formhistory_fixup_value (char* value)
|
||||
{
|
||||
guint i = 0;
|
||||
g_strchomp (value);
|
||||
while (value[i])
|
||||
{
|
||||
if (value[i] == '\n')
|
||||
value[i] = ' ';
|
||||
else if (value[i] == '"')
|
||||
value[i] = '\'';
|
||||
i++;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
static gchar*
|
||||
formhistory_build_js ()
|
||||
{
|
||||
GString* suggestions;
|
||||
GHashTableIter iter;
|
||||
gpointer key, value;
|
||||
|
||||
suggestions = g_string_new (
|
||||
"function FormSuggestions(eid) { "
|
||||
"arr = new Array();");
|
||||
g_hash_table_iter_init (&iter, global_keys);
|
||||
while (g_hash_table_iter_next (&iter, &key, &value))
|
||||
{
|
||||
g_string_append_printf (suggestions, " arr[\"%s\"] = [%s]; ",
|
||||
(gchar*)key, (gchar*)value);
|
||||
}
|
||||
g_string_append (suggestions, "this.suggestions = arr[eid]; }");
|
||||
g_string_append (suggestions, jsforms);
|
||||
return g_string_free (suggestions, FALSE);
|
||||
}
|
||||
|
||||
static void
|
||||
formhistory_update_database (gpointer db,
|
||||
const gchar* key,
|
||||
const gchar* value)
|
||||
{
|
||||
gchar* sqlcmd;
|
||||
gchar* errmsg;
|
||||
gint success;
|
||||
|
||||
sqlcmd = sqlite3_mprintf ("INSERT INTO forms VALUES"
|
||||
"('%q', '%q', '%q')",
|
||||
NULL, key, value);
|
||||
success = sqlite3_exec (db, sqlcmd, NULL, NULL, &errmsg);
|
||||
sqlite3_free (sqlcmd);
|
||||
if (success != SQLITE_OK)
|
||||
{
|
||||
g_printerr (_("Failed to add form value: %s\n"), errmsg);
|
||||
g_free (errmsg);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
formhistory_update_main_hash (gchar* key,
|
||||
gchar* value)
|
||||
{
|
||||
guint length;
|
||||
gchar* tmp;
|
||||
|
||||
if (!(value && *value))
|
||||
return FALSE;
|
||||
length = strlen (value);
|
||||
if (length > MAXCHARS || length < MINCHARS)
|
||||
return FALSE;
|
||||
|
||||
formhistory_fixup_value (key);
|
||||
formhistory_fixup_value (value);
|
||||
if ((tmp = g_hash_table_lookup (global_keys, (gpointer)key)))
|
||||
{
|
||||
gchar* rvalue = g_strdup_printf ("\"%s\"",value);
|
||||
gchar* patt = g_regex_escape_string (rvalue, -1);
|
||||
if (!g_regex_match_simple (patt, tmp,
|
||||
G_REGEX_CASELESS, G_REGEX_MATCH_NOTEMPTY))
|
||||
{
|
||||
gchar* new_value = g_strdup_printf ("%s%s,", tmp, rvalue);
|
||||
g_hash_table_insert (global_keys, g_strdup (key), new_value);
|
||||
g_free (rvalue);
|
||||
g_free (patt);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_free (rvalue);
|
||||
g_free (patt);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
gchar* new_value = g_strdup_printf ("\"%s\",",value);
|
||||
g_hash_table_replace (global_keys, g_strdup (key), new_value);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
formhistory_navigation_decision_cb (WebKitWebView* web_view,
|
||||
WebKitWebFrame* web_frame,
|
||||
WebKitNetworkRequest* request,
|
||||
WebKitWebNavigationAction* action,
|
||||
WebKitWebPolicyDecision* decision,
|
||||
MidoriExtension* extension)
|
||||
{
|
||||
/* The script returns form data in the form "field_name|,|value|,|field_type".
|
||||
We are handling only input fields with 'text' or 'password' type.
|
||||
The field separator is "|||" */
|
||||
const gchar* script = "function dumpForm (inputs) {"
|
||||
" var out = '';"
|
||||
" for (i=0;i<inputs.length;i++) {"
|
||||
" if (inputs[i].getAttribute('autocomplete') == 'off')"
|
||||
" continue;"
|
||||
" if (inputs[i].value && (inputs[i].type == 'text' || inputs[i].type == 'password')) {"
|
||||
" var ename = inputs[i].getAttribute('name');"
|
||||
" var eid = inputs[i].getAttribute('id');"
|
||||
" if (!ename && eid)"
|
||||
" ename=eid;"
|
||||
" if (inputs[i].getAttribute('autocomplete') != 'off')"
|
||||
" out += ename+'|,|'+inputs[i].value +'|,|'+inputs[i].type +'|||';"
|
||||
" }"
|
||||
" }"
|
||||
" return out;"
|
||||
"}"
|
||||
"dumpForm (document.getElementsByTagName('input'))";
|
||||
|
||||
if (webkit_web_navigation_action_get_reason (action) == WEBKIT_WEB_NAVIGATION_REASON_FORM_SUBMITTED)
|
||||
{
|
||||
JSContextRef js_context = webkit_web_frame_get_global_context (web_frame);
|
||||
gchar* value = sokoke_js_script_eval (js_context, script, NULL);
|
||||
if (value && *value)
|
||||
{
|
||||
gpointer db = g_object_get_data (G_OBJECT (extension), "formhistory-db");
|
||||
gchar** inputs = g_strsplit (value, "|||", 0);
|
||||
guint i = 0;
|
||||
while (inputs[i] != NULL)
|
||||
{
|
||||
gchar** parts = g_strsplit (inputs[i], "|,|", 3);
|
||||
if (parts && parts[0] && parts[1] && parts[2])
|
||||
{
|
||||
/* FIXME: We need to handle passwords */
|
||||
if (strcmp (parts[2], "password"))
|
||||
{
|
||||
if (formhistory_update_main_hash (parts[0], parts[1]))
|
||||
formhistory_update_database (db, parts[0], parts[1]);
|
||||
}
|
||||
}
|
||||
g_strfreev (parts);
|
||||
i++;
|
||||
}
|
||||
g_strfreev (inputs);
|
||||
g_free (value);
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
formhistory_window_object_cleared_cb (WebKitWebView* web_view,
|
||||
WebKitWebFrame* web_frame,
|
||||
JSContextRef js_context,
|
||||
JSObjectRef js_window)
|
||||
{
|
||||
gchar* script;
|
||||
const gchar* page_uri;
|
||||
|
||||
page_uri = webkit_web_frame_get_uri (web_frame);
|
||||
if (!midori_uri_is_http (page_uri))
|
||||
return;
|
||||
|
||||
script = formhistory_build_js ();
|
||||
sokoke_js_script_eval (js_context, script, NULL);
|
||||
g_free (script);
|
||||
}
|
||||
|
||||
static void
|
||||
formhistory_add_tab_cb (MidoriBrowser* browser,
|
||||
MidoriView* view,
|
||||
MidoriExtension* extension)
|
||||
{
|
||||
GtkWidget* web_view = midori_view_get_web_view (view);
|
||||
g_signal_connect (web_view, "window-object-cleared",
|
||||
G_CALLBACK (formhistory_window_object_cleared_cb), NULL);
|
||||
g_signal_connect (web_view, "navigation-policy-decision-requested",
|
||||
G_CALLBACK (formhistory_navigation_decision_cb), extension);
|
||||
}
|
||||
|
||||
static void
|
||||
formhistory_deactivate_cb (MidoriExtension* extension,
|
||||
MidoriBrowser* browser);
|
||||
|
||||
static void
|
||||
formhistory_add_tab_foreach_cb (MidoriView* view,
|
||||
MidoriBrowser* browser,
|
||||
MidoriExtension* extension)
|
||||
{
|
||||
formhistory_add_tab_cb (browser, view, extension);
|
||||
}
|
||||
|
||||
static void
|
||||
formhistory_app_add_browser_cb (MidoriApp* app,
|
||||
MidoriBrowser* browser,
|
||||
MidoriExtension* extension)
|
||||
{
|
||||
GtkAccelGroup* acg = gtk_accel_group_new ();
|
||||
GtkActionGroup* action_group = midori_browser_get_action_group (browser);
|
||||
GtkAction* action = gtk_action_new ("FormHistoryToggleState",
|
||||
_("Toggle form history state"),
|
||||
_("Activate or deactivate form history for the current tab."), NULL);
|
||||
gtk_window_add_accel_group (GTK_WINDOW (browser), acg);
|
||||
|
||||
g_object_set_data (G_OBJECT (browser), "FormHistoryExtension", extension);
|
||||
|
||||
g_signal_connect (action, "activate",
|
||||
G_CALLBACK (formhistory_toggle_state_cb), browser);
|
||||
|
||||
gtk_action_group_add_action_with_accel (action_group, action, "<Ctrl><Shift>F");
|
||||
gtk_action_set_accel_group (action, acg);
|
||||
gtk_action_connect_accelerator (action);
|
||||
|
||||
if (midori_extension_get_boolean (extension, "always-load"))
|
||||
{
|
||||
midori_browser_foreach (browser,
|
||||
(GtkCallback)formhistory_add_tab_foreach_cb, extension);
|
||||
g_signal_connect (browser, "add-tab",
|
||||
G_CALLBACK (formhistory_add_tab_cb), extension);
|
||||
}
|
||||
g_signal_connect (extension, "deactivate",
|
||||
G_CALLBACK (formhistory_deactivate_cb), browser);
|
||||
}
|
||||
|
||||
static void
|
||||
formhistory_deactivate_tabs (MidoriView* view,
|
||||
MidoriBrowser* browser,
|
||||
MidoriExtension* extension)
|
||||
{
|
||||
GtkWidget* web_view = midori_view_get_web_view (view);
|
||||
g_signal_handlers_disconnect_by_func (
|
||||
web_view, formhistory_window_object_cleared_cb, NULL);
|
||||
g_signal_handlers_disconnect_by_func (
|
||||
web_view, formhistory_navigation_decision_cb, extension);
|
||||
}
|
||||
|
||||
static void
|
||||
formhistory_deactivate_cb (MidoriExtension* extension,
|
||||
MidoriBrowser* browser)
|
||||
{
|
||||
MidoriApp* app = midori_extension_get_app (extension);
|
||||
sqlite3* db;
|
||||
|
||||
GtkActionGroup* action_group = midori_browser_get_action_group (browser);
|
||||
GtkAction* action;
|
||||
|
||||
g_signal_handlers_disconnect_by_func (
|
||||
browser, formhistory_add_tab_cb, extension);
|
||||
g_signal_handlers_disconnect_by_func (
|
||||
extension, formhistory_deactivate_cb, browser);
|
||||
g_signal_handlers_disconnect_by_func (
|
||||
app, formhistory_app_add_browser_cb, extension);
|
||||
midori_browser_foreach (browser,
|
||||
(GtkCallback)formhistory_deactivate_tabs, extension);
|
||||
|
||||
g_object_set_data (G_OBJECT (browser), "FormHistoryExtension", NULL);
|
||||
action = gtk_action_group_get_action ( action_group, "FormHistoryToggleState");
|
||||
if (action != NULL)
|
||||
{
|
||||
gtk_action_group_remove_action (action_group, action);
|
||||
g_object_unref (action);
|
||||
}
|
||||
|
||||
katze_assign (jsforms, NULL);
|
||||
if (global_keys)
|
||||
g_hash_table_destroy (global_keys);
|
||||
|
||||
if ((db = g_object_get_data (G_OBJECT (extension), "formhistory-db")))
|
||||
sqlite3_close (db);
|
||||
}
|
||||
|
||||
static int
|
||||
formhistory_add_field (gpointer data,
|
||||
int argc,
|
||||
char** argv,
|
||||
char** colname)
|
||||
{
|
||||
gint i;
|
||||
gint ncols = 3;
|
||||
|
||||
/* Test whether have the right number of columns */
|
||||
g_return_val_if_fail (argc % ncols == 0, 1);
|
||||
|
||||
for (i = 0; i < (argc - ncols) + 1; i++)
|
||||
{
|
||||
if (argv[i])
|
||||
{
|
||||
if (colname[i] && !g_ascii_strcasecmp (colname[i], "domain")
|
||||
&& colname[i + 1] && !g_ascii_strcasecmp (colname[i + 1], "field")
|
||||
&& colname[i + 2] && !g_ascii_strcasecmp (colname[i + 2], "value"))
|
||||
{
|
||||
gchar* key = argv[i + 1];
|
||||
formhistory_update_main_hash (g_strdup (key), g_strdup (argv[i + 2]));
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
formhistory_activate_cb (MidoriExtension* extension,
|
||||
MidoriApp* app)
|
||||
{
|
||||
const gchar* config_dir;
|
||||
gchar* filename;
|
||||
sqlite3* db;
|
||||
char* errmsg = NULL, *errmsg2 = NULL;
|
||||
KatzeArray* browsers;
|
||||
MidoriBrowser* browser;
|
||||
|
||||
global_keys = g_hash_table_new_full (g_str_hash, g_str_equal,
|
||||
(GDestroyNotify)g_free,
|
||||
(GDestroyNotify)g_free);
|
||||
if(!jsforms)
|
||||
formhistory_prepare_js ();
|
||||
config_dir = midori_extension_get_config_dir (extension);
|
||||
katze_mkdir_with_parents (config_dir, 0700);
|
||||
filename = g_build_filename (config_dir, "forms.db", NULL);
|
||||
if (sqlite3_open (filename, &db) != SQLITE_OK)
|
||||
{
|
||||
/* If the folder is /, this is a test run, thus no error */
|
||||
if (!g_str_equal (midori_extension_get_config_dir (extension), "/"))
|
||||
g_warning (_("Failed to open database: %s\n"), sqlite3_errmsg (db));
|
||||
sqlite3_close (db);
|
||||
}
|
||||
g_free (filename);
|
||||
if ((sqlite3_exec (db, "CREATE TABLE IF NOT EXISTS "
|
||||
"forms (domain text, field text, value text)",
|
||||
NULL, NULL, &errmsg) == SQLITE_OK)
|
||||
&& (sqlite3_exec (db, "SELECT domain, field, value FROM forms ",
|
||||
formhistory_add_field,
|
||||
NULL, &errmsg2) == SQLITE_OK))
|
||||
g_object_set_data (G_OBJECT (extension), "formhistory-db", db);
|
||||
else
|
||||
{
|
||||
if (errmsg)
|
||||
{
|
||||
g_critical (_("Failed to execute database statement: %s\n"), errmsg);
|
||||
sqlite3_free (errmsg);
|
||||
if (errmsg2)
|
||||
{
|
||||
g_critical (_("Failed to execute database statement: %s\n"), errmsg2);
|
||||
sqlite3_free (errmsg2);
|
||||
}
|
||||
}
|
||||
sqlite3_close (db);
|
||||
}
|
||||
|
||||
browsers = katze_object_get_object (app, "browsers");
|
||||
KATZE_ARRAY_FOREACH_ITEM (browser, browsers)
|
||||
formhistory_app_add_browser_cb (app, browser, extension);
|
||||
g_signal_connect (app, "add-browser",
|
||||
G_CALLBACK (formhistory_app_add_browser_cb), extension);
|
||||
|
||||
g_object_unref (browsers);
|
||||
}
|
||||
|
||||
static void
|
||||
formhistory_preferences_response_cb (GtkWidget* dialog,
|
||||
gint response_id,
|
||||
MidoriExtension* extension)
|
||||
{
|
||||
GtkWidget* checkbox;
|
||||
gboolean old_state;
|
||||
gboolean new_state;
|
||||
MidoriApp* app;
|
||||
KatzeArray* browsers;
|
||||
MidoriBrowser* browser;
|
||||
|
||||
if (response_id == GTK_RESPONSE_APPLY)
|
||||
{
|
||||
checkbox = g_object_get_data (G_OBJECT (dialog), "always-load-checkbox");
|
||||
new_state = !gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (checkbox));
|
||||
old_state = midori_extension_get_boolean (extension, "always-load");
|
||||
|
||||
if (old_state != new_state)
|
||||
{
|
||||
midori_extension_set_boolean (extension, "always-load", new_state);
|
||||
|
||||
app = midori_extension_get_app (extension);
|
||||
browsers = katze_object_get_object (app, "browsers");
|
||||
KATZE_ARRAY_FOREACH_ITEM (browser, browsers)
|
||||
{
|
||||
midori_browser_foreach (browser,
|
||||
(GtkCallback)formhistory_deactivate_tabs, extension);
|
||||
g_signal_handlers_disconnect_by_func (
|
||||
browser, formhistory_add_tab_cb, extension);
|
||||
|
||||
if (new_state)
|
||||
{
|
||||
midori_browser_foreach (browser,
|
||||
(GtkCallback)formhistory_add_tab_foreach_cb, extension);
|
||||
g_signal_connect (browser, "add-tab",
|
||||
G_CALLBACK (formhistory_add_tab_cb), extension);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
gtk_widget_destroy (dialog);
|
||||
}
|
||||
|
||||
static void
|
||||
formhistory_preferences_cb (MidoriExtension* extension)
|
||||
{
|
||||
GtkWidget* dialog;
|
||||
GtkWidget* content_area;
|
||||
GtkWidget* checkbox;
|
||||
|
||||
dialog = gtk_dialog_new ();
|
||||
|
||||
gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
|
||||
|
||||
gtk_dialog_add_button (GTK_DIALOG (dialog), GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL);
|
||||
gtk_dialog_add_button (GTK_DIALOG (dialog), GTK_STOCK_APPLY, GTK_RESPONSE_APPLY);
|
||||
|
||||
content_area = gtk_dialog_get_content_area (GTK_DIALOG (dialog));
|
||||
checkbox = gtk_check_button_new_with_label (_("only activate form history via hotkey (Ctrl+Shift+F) per tab"));
|
||||
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (checkbox),
|
||||
!midori_extension_get_boolean (extension, "always-load"));
|
||||
g_object_set_data (G_OBJECT (dialog), "always-load-checkbox", checkbox);
|
||||
gtk_container_add (GTK_CONTAINER (content_area), checkbox);
|
||||
|
||||
g_signal_connect (dialog,
|
||||
"response",
|
||||
G_CALLBACK (formhistory_preferences_response_cb),
|
||||
extension);
|
||||
gtk_widget_show_all (dialog);
|
||||
}
|
||||
|
||||
static void
|
||||
formhistory_toggle_state_cb (GtkAction* action,
|
||||
MidoriBrowser* browser)
|
||||
{
|
||||
MidoriView* view = MIDORI_VIEW (midori_browser_get_current_tab (browser));
|
||||
MidoriExtension* extension = g_object_get_data (G_OBJECT (browser), "FormHistoryExtension");
|
||||
GtkWidget* web_view = midori_view_get_web_view (view);
|
||||
|
||||
if (g_signal_handler_find (web_view, G_SIGNAL_MATCH_FUNC,
|
||||
g_signal_lookup ("window-object-cleared", MIDORI_TYPE_VIEW), 0, NULL,
|
||||
formhistory_window_object_cleared_cb, extension))
|
||||
{
|
||||
formhistory_deactivate_tabs (view, browser, extension);
|
||||
} else {
|
||||
formhistory_add_tab_cb (browser, view, extension);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#if G_ENABLE_DEBUG
|
||||
/*
|
||||
<html>
|
||||
<head>
|
||||
<title>autosuggest testcase</title>
|
||||
</head>
|
||||
<body>
|
||||
<form method=post>
|
||||
<p><input type="text" id="txt1" /></p>
|
||||
<p><input type="text" name="txt2" /></p>
|
||||
<input type=submit>
|
||||
</form>
|
||||
</body>
|
||||
</html> */
|
||||
#endif
|
||||
|
||||
MidoriExtension*
|
||||
extension_init (void)
|
||||
{
|
||||
gboolean should_init = TRUE;
|
||||
const gchar* ver;
|
||||
gchar* desc;
|
||||
MidoriExtension* extension;
|
||||
|
||||
if (formhistory_prepare_js ())
|
||||
{
|
||||
ver = "1.0" MIDORI_VERSION_SUFFIX;
|
||||
desc = g_strdup (_("Stores history of entered form data"));
|
||||
}
|
||||
else
|
||||
{
|
||||
desc = g_strdup_printf (_("Not available: %s"),
|
||||
_("Resource files not installed"));
|
||||
ver = NULL;
|
||||
should_init = FALSE;
|
||||
}
|
||||
|
||||
extension = g_object_new (MIDORI_TYPE_EXTENSION,
|
||||
"name", _("Form history filler"),
|
||||
"description", desc,
|
||||
"version", ver,
|
||||
"authors", "Alexander V. Butenko <a.butenka@gmail.com>",
|
||||
NULL);
|
||||
|
||||
g_free (desc);
|
||||
|
||||
if (should_init)
|
||||
{
|
||||
midori_extension_install_boolean (extension, "always-load", TRUE);
|
||||
g_signal_connect (extension, "activate",
|
||||
G_CALLBACK (formhistory_activate_cb), NULL);
|
||||
g_signal_connect (extension, "open-preferences",
|
||||
G_CALLBACK (formhistory_preferences_cb), NULL);
|
||||
}
|
||||
|
||||
return extension;
|
||||
}
|
|
@ -1,74 +0,0 @@
|
|||
/*
|
||||
Copyright (C) 2009-2012 Alexander Butenko <a.butenka@gmail.com>
|
||||
Copyright (C) 2009-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.
|
||||
*/
|
||||
|
||||
#ifndef __FORMHISTORY_FRONTEND_H__
|
||||
#define __FORMHISTORY_FRONTEND_H__
|
||||
#include <midori/midori.h>
|
||||
#include <glib/gstdio.h>
|
||||
|
||||
#include "config.h"
|
||||
#if HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#if WEBKIT_CHECK_VERSION (1, 3, 1)
|
||||
#define FORMHISTORY_USE_GDOM 1
|
||||
#else
|
||||
#define FORMHISTORY_USE_JS 1
|
||||
#endif
|
||||
#define MAXPASSSIZE 64
|
||||
|
||||
typedef struct
|
||||
{
|
||||
sqlite3* db;
|
||||
#ifdef FORMHISTORY_USE_GDOM
|
||||
WebKitDOMElement* element;
|
||||
int completion_timeout;
|
||||
GtkTreeModel* completion_model;
|
||||
GtkWidget* treeview;
|
||||
GtkWidget* popup;
|
||||
gchar* oldkeyword;
|
||||
glong selection_index;
|
||||
#else
|
||||
gchar* jsforms;
|
||||
#endif
|
||||
gchar* master_password;
|
||||
int master_password_canceled;
|
||||
} FormHistoryPriv;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
gchar* domain;
|
||||
gchar* form_data;
|
||||
FormHistoryPriv* priv;
|
||||
} FormhistoryPasswordEntry;
|
||||
|
||||
FormHistoryPriv*
|
||||
formhistory_private_new ();
|
||||
|
||||
void
|
||||
formhistory_private_destroy (FormHistoryPriv *priv);
|
||||
|
||||
gboolean
|
||||
formhistory_construct_popup_gui (FormHistoryPriv* priv);
|
||||
|
||||
void
|
||||
formhistory_setup_suggestions (WebKitWebView* web_view,
|
||||
JSContextRef js_context,
|
||||
MidoriExtension* extension);
|
||||
|
||||
#ifdef FORMHISTORY_USE_GDOM
|
||||
void
|
||||
formhistory_suggestions_hide_cb (WebKitDOMElement* element,
|
||||
WebKitDOMEvent* dom_event,
|
||||
FormHistoryPriv* priv);
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -1,516 +0,0 @@
|
|||
/*
|
||||
Copyright (C) 2009-2012 Alexander Butenko <a.butenka@gmail.com>
|
||||
Copyright (C) 2009-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.
|
||||
*/
|
||||
#include "formhistory-frontend.h"
|
||||
#ifdef FORMHISTORY_USE_GDOM
|
||||
#define COMPLETION_DELAY 200
|
||||
|
||||
FormHistoryPriv*
|
||||
formhistory_private_new ()
|
||||
{
|
||||
FormHistoryPriv* priv;
|
||||
|
||||
priv = g_slice_new (FormHistoryPriv);
|
||||
priv->oldkeyword = g_strdup ("");
|
||||
priv->selection_index = -1;
|
||||
return priv;
|
||||
}
|
||||
|
||||
void
|
||||
formhistory_suggestions_hide_cb (WebKitDOMElement* element,
|
||||
WebKitDOMEvent* dom_event,
|
||||
FormHistoryPriv* priv)
|
||||
{
|
||||
if (gtk_widget_get_visible (priv->popup))
|
||||
gtk_widget_hide (priv->popup);
|
||||
priv->selection_index = -1;
|
||||
}
|
||||
|
||||
static void
|
||||
formhistory_suggestion_set (GtkTreePath* path,
|
||||
FormHistoryPriv* priv)
|
||||
{
|
||||
GtkTreeIter iter;
|
||||
gchar* value;
|
||||
|
||||
if (!gtk_tree_model_get_iter (priv->completion_model, &iter, path))
|
||||
return;
|
||||
|
||||
gtk_tree_model_get (priv->completion_model, &iter, 0, &value, -1);
|
||||
g_object_set (priv->element, "value", value, NULL);
|
||||
g_free (value);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
formhistory_suggestion_selected_cb (GtkWidget* treeview,
|
||||
GdkEventButton* event,
|
||||
FormHistoryPriv* priv)
|
||||
|
||||
{
|
||||
GtkTreePath* path;
|
||||
|
||||
if (gtk_tree_view_get_path_at_pos (GTK_TREE_VIEW (treeview),
|
||||
event->x, event->y, &path, NULL, NULL, NULL))
|
||||
{
|
||||
formhistory_suggestion_set (path, priv);
|
||||
formhistory_suggestions_hide_cb (NULL, NULL, priv);
|
||||
gtk_tree_path_free (path);
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
static void
|
||||
formhistory_suggestion_remove (GtkTreePath* path,
|
||||
FormHistoryPriv* priv)
|
||||
{
|
||||
GtkTreeIter iter;
|
||||
gchar* sqlcmd;
|
||||
char* errmsg = NULL;
|
||||
gchar* name;
|
||||
gchar* value;
|
||||
|
||||
if (!gtk_tree_model_get_iter (priv->completion_model, &iter, path))
|
||||
return;
|
||||
|
||||
if (!priv->db)
|
||||
return;
|
||||
|
||||
gtk_tree_model_get (priv->completion_model, &iter, 0, &value, -1);
|
||||
g_object_get (priv->element, "name", &name, NULL);
|
||||
gtk_list_store_remove (GTK_LIST_STORE (priv->completion_model), &iter);
|
||||
|
||||
sqlcmd = sqlite3_mprintf ("DELETE FROM forms WHERE field = '%q' AND value = '%q'",
|
||||
name, value);
|
||||
g_free (name);
|
||||
g_free (value);
|
||||
sqlite3_exec (priv->db, sqlcmd, NULL, NULL, &errmsg);
|
||||
sqlite3_free (sqlcmd);
|
||||
}
|
||||
|
||||
static void
|
||||
get_absolute_offset_for_element (WebKitDOMElement* element,
|
||||
WebKitDOMDocument* element_document,
|
||||
WebKitDOMNodeList* frames,
|
||||
glong* x,
|
||||
glong* y,
|
||||
gboolean ismainframe)
|
||||
{
|
||||
WebKitDOMElement* offset_parent;
|
||||
gint offset_top = 0, offset_left = 0;
|
||||
gulong i;
|
||||
|
||||
g_object_get (element, "offset-left", &offset_left,
|
||||
"offset-top", &offset_top,
|
||||
"offset-parent", &offset_parent,
|
||||
NULL);
|
||||
*x += offset_left;
|
||||
*y += offset_top;
|
||||
/* To avoid deadlock check only first element of the mainframe parent */
|
||||
if (ismainframe == TRUE)
|
||||
return;
|
||||
if (offset_parent)
|
||||
goto finish;
|
||||
|
||||
/* Element havent returned any parents. Thats mean or there is no parents or we are inside the frame
|
||||
Loop over all frames we have to find frame == element_document which is a root for our element
|
||||
and get its offsets */
|
||||
for (i = 0; i < webkit_dom_node_list_get_length (frames); i++)
|
||||
{
|
||||
WebKitDOMDocument *fdoc;
|
||||
WebKitDOMNode *frame = webkit_dom_node_list_item (frames, i);
|
||||
|
||||
if (WEBKIT_DOM_IS_HTML_IFRAME_ELEMENT (frame))
|
||||
fdoc = webkit_dom_html_iframe_element_get_content_document (WEBKIT_DOM_HTML_IFRAME_ELEMENT (frame));
|
||||
else
|
||||
fdoc = webkit_dom_html_frame_element_get_content_document (WEBKIT_DOM_HTML_FRAME_ELEMENT (frame));
|
||||
if (fdoc == element_document)
|
||||
{
|
||||
offset_parent = WEBKIT_DOM_ELEMENT (frame);
|
||||
ismainframe = TRUE;
|
||||
/* Add extra 4px to ~cover size of borders */
|
||||
*y += 4;
|
||||
break;
|
||||
}
|
||||
}
|
||||
finish:
|
||||
if (offset_parent)
|
||||
get_absolute_offset_for_element (offset_parent, element_document, frames, x, y, ismainframe);
|
||||
}
|
||||
|
||||
static void
|
||||
formhistory_reposition_popup (FormHistoryPriv* priv)
|
||||
{
|
||||
WebKitDOMDocument* element_document;
|
||||
WebKitDOMNodeList* frames;
|
||||
GtkWidget* view;
|
||||
GdkWindow* window;
|
||||
GtkWidget* toplevel;
|
||||
gint rx, ry;
|
||||
gint wx, wy;
|
||||
glong x = 0, y = 0;
|
||||
glong height;
|
||||
|
||||
view = g_object_get_data (G_OBJECT (priv->element), "webview");
|
||||
toplevel = gtk_widget_get_toplevel (view);
|
||||
/* Position of a root window */
|
||||
window = gtk_widget_get_window (toplevel);
|
||||
gdk_window_get_position (window, &rx, &ry);
|
||||
|
||||
/* Postion of webview in root window */
|
||||
window = gtk_widget_get_window (view);
|
||||
gdk_window_get_position (window, &wx, &wy);
|
||||
|
||||
/* Position of editbox on the webview */
|
||||
frames = g_object_get_data (G_OBJECT (priv->element), "framelist");
|
||||
element_document = g_object_get_data (G_OBJECT (priv->element), "doc");
|
||||
get_absolute_offset_for_element (priv->element, element_document, frames, &x, &y, FALSE);
|
||||
/* Add height as menu should start under editbox, now on top of it */
|
||||
g_object_get (priv->element, "client-height", &height, NULL);
|
||||
y += height + 1;
|
||||
gtk_window_move (GTK_WINDOW (priv->popup), rx + wx + x, ry +wy + y);
|
||||
|
||||
/* Window configuration */
|
||||
gtk_window_set_screen (GTK_WINDOW (priv->popup), gtk_widget_get_screen (view));
|
||||
gtk_window_set_transient_for (GTK_WINDOW (priv->popup), GTK_WINDOW (toplevel));
|
||||
gtk_tree_view_columns_autosize (GTK_TREE_VIEW (priv->treeview));
|
||||
/* FIXME: Adjust size according to treeview width and some reasonable height */
|
||||
gtk_window_resize (GTK_WINDOW (priv->popup), 50, 80);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
formhistory_suggestions_show (FormHistoryPriv* priv)
|
||||
{
|
||||
GtkListStore* store;
|
||||
static sqlite3_stmt* stmt;
|
||||
gchar* value, * name;
|
||||
const char* sqlcmd;
|
||||
gint result;
|
||||
gchar* likedvalue;
|
||||
int pos = 0;
|
||||
|
||||
g_return_val_if_fail (priv->element, FALSE);
|
||||
|
||||
g_object_get (priv->element,
|
||||
"name", &name,
|
||||
"value", &value,
|
||||
NULL);
|
||||
|
||||
katze_assign (priv->oldkeyword, g_strdup (value));
|
||||
if (!priv->popup)
|
||||
formhistory_construct_popup_gui (priv);
|
||||
|
||||
if (!stmt)
|
||||
{
|
||||
if (!priv->db)
|
||||
goto free_data;
|
||||
|
||||
sqlcmd = "SELECT DISTINCT value FROM forms WHERE field = ?1 and value like ?2";
|
||||
sqlite3_prepare_v2 (priv->db, sqlcmd, strlen (sqlcmd) + 1, &stmt, NULL);
|
||||
}
|
||||
|
||||
likedvalue = g_strdup_printf ("%s%%", value);
|
||||
sqlite3_bind_text (stmt, 1, name, -1, NULL);
|
||||
sqlite3_bind_text (stmt, 2, likedvalue, -1, g_free);
|
||||
result = sqlite3_step (stmt);
|
||||
|
||||
if (result != SQLITE_ROW)
|
||||
{
|
||||
if (result == SQLITE_ERROR)
|
||||
g_print (_("Failed to select suggestions\n"));
|
||||
sqlite3_reset (stmt);
|
||||
sqlite3_clear_bindings (stmt);
|
||||
formhistory_suggestions_hide_cb (NULL, NULL, priv);
|
||||
goto free_data;
|
||||
}
|
||||
|
||||
store = GTK_LIST_STORE (priv->completion_model);
|
||||
gtk_list_store_clear (store);
|
||||
|
||||
while (result == SQLITE_ROW)
|
||||
{
|
||||
const unsigned char* text = sqlite3_column_text (stmt, 0);
|
||||
pos++;
|
||||
gtk_list_store_insert_with_values (store, NULL, pos, 0, text, -1);
|
||||
result = sqlite3_step (stmt);
|
||||
}
|
||||
sqlite3_reset (stmt);
|
||||
sqlite3_clear_bindings (stmt);
|
||||
|
||||
if (!gtk_widget_get_visible (priv->popup))
|
||||
{
|
||||
formhistory_reposition_popup (priv);
|
||||
gtk_widget_show_all (priv->popup);
|
||||
}
|
||||
|
||||
free_data:
|
||||
g_free (name);
|
||||
g_free (value);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
formhistory_editbox_key_pressed_cb (WebKitDOMElement* element,
|
||||
WebKitDOMEvent* dom_event,
|
||||
FormHistoryPriv* priv)
|
||||
{
|
||||
glong key;
|
||||
GtkTreePath* path;
|
||||
gchar* keyword;
|
||||
gint matches;
|
||||
|
||||
/* FIXME: Priv is still set after module is disabled */
|
||||
g_return_if_fail (priv);
|
||||
g_return_if_fail (element);
|
||||
|
||||
if (priv->completion_timeout > 0)
|
||||
g_source_remove (priv->completion_timeout);
|
||||
|
||||
katze_object_assign (priv->element, g_object_ref (element));
|
||||
|
||||
key = webkit_dom_ui_event_get_key_code (WEBKIT_DOM_UI_EVENT (dom_event));
|
||||
switch (key)
|
||||
{
|
||||
/* ESC key*/
|
||||
case 27:
|
||||
case 35:
|
||||
case 36:
|
||||
/* Left key*/
|
||||
case 37:
|
||||
/* Right key*/
|
||||
case 39:
|
||||
/* Enter key*/
|
||||
case 13:
|
||||
if (key == 27)
|
||||
g_object_set (element, "value", priv->oldkeyword, NULL);
|
||||
formhistory_suggestions_hide_cb (element, dom_event, priv);
|
||||
return;
|
||||
break;
|
||||
/* Del key */
|
||||
case 46:
|
||||
/* Up key */
|
||||
case 38:
|
||||
/* Down key */
|
||||
case 40:
|
||||
|
||||
if (!gtk_widget_get_visible (priv->popup))
|
||||
{
|
||||
formhistory_suggestions_show (priv);
|
||||
return;
|
||||
}
|
||||
matches = gtk_tree_model_iter_n_children (priv->completion_model, NULL);
|
||||
if (key == 38)
|
||||
{
|
||||
if (priv->selection_index <= 0)
|
||||
priv->selection_index = matches - 1;
|
||||
else
|
||||
priv->selection_index = MAX (priv->selection_index - 1, 0);
|
||||
}
|
||||
else if (key == 40)
|
||||
{
|
||||
if (priv->selection_index == matches - 1)
|
||||
priv->selection_index = 0;
|
||||
else
|
||||
priv->selection_index = MIN (priv->selection_index + 1, matches -1);
|
||||
}
|
||||
if (priv->selection_index == -1)
|
||||
{
|
||||
/* No element is selected */
|
||||
return;
|
||||
}
|
||||
|
||||
path = gtk_tree_path_new_from_indices (priv->selection_index, -1);
|
||||
if (key == 46)
|
||||
{
|
||||
g_object_set (element, "value", priv->oldkeyword, NULL);
|
||||
formhistory_suggestion_remove (path, priv);
|
||||
matches--;
|
||||
}
|
||||
|
||||
if (matches == 0)
|
||||
formhistory_suggestions_hide_cb (element, dom_event, priv);
|
||||
else
|
||||
{
|
||||
gtk_tree_view_set_cursor (GTK_TREE_VIEW (priv->treeview), path, NULL, FALSE);
|
||||
formhistory_suggestion_set (path, priv);
|
||||
}
|
||||
gtk_tree_path_free (path);
|
||||
return;
|
||||
break;
|
||||
/* PgUp, PgDn, Ins */
|
||||
case 33:
|
||||
case 34:
|
||||
case 45:
|
||||
/* Shift, Ctrl, Alt, Tab, Caps Lock*/
|
||||
case 16:
|
||||
case 17:
|
||||
case 18:
|
||||
case 20:
|
||||
case 9:
|
||||
return;
|
||||
break;
|
||||
}
|
||||
|
||||
g_object_get (element, "value", &keyword, NULL);
|
||||
if (!(keyword && *keyword && *keyword != ' '))
|
||||
{
|
||||
formhistory_suggestions_hide_cb (element, dom_event, priv);
|
||||
goto free_data;
|
||||
}
|
||||
|
||||
/* If the same keyword is submitted there's no need to regenerate suggestions */
|
||||
if (gtk_widget_get_visible (priv->popup) &&
|
||||
!g_strcmp0 (keyword, priv->oldkeyword))
|
||||
goto free_data;
|
||||
priv->completion_timeout = g_timeout_add (COMPLETION_DELAY,
|
||||
(GSourceFunc)formhistory_suggestions_show, priv);
|
||||
free_data:
|
||||
g_free (keyword);
|
||||
}
|
||||
|
||||
static void
|
||||
formhistory_DOMContentLoaded_cb (WebKitDOMElement* window,
|
||||
WebKitDOMEvent* dom_event,
|
||||
FormHistoryPriv* priv)
|
||||
{
|
||||
gulong i;
|
||||
WebKitDOMDocument* doc;
|
||||
WebKitDOMNodeList* inputs;
|
||||
WebKitDOMNodeList* frames;
|
||||
GtkWidget* web_view;
|
||||
|
||||
if (WEBKIT_DOM_IS_DOCUMENT (window))
|
||||
doc = WEBKIT_DOM_DOCUMENT (window);
|
||||
else
|
||||
doc = webkit_dom_dom_window_get_document (WEBKIT_DOM_DOM_WINDOW (window));
|
||||
inputs = webkit_dom_document_query_selector_all (doc, "input[type='text']", NULL);
|
||||
frames = g_object_get_data (G_OBJECT (window), "framelist");
|
||||
web_view = g_object_get_data (G_OBJECT (window), "webview");
|
||||
|
||||
for (i = 0; i < webkit_dom_node_list_get_length (inputs); i++)
|
||||
{
|
||||
WebKitDOMNode* element = webkit_dom_node_list_item (inputs, i);
|
||||
#if WEBKIT_CHECK_VERSION (1, 6, 1)
|
||||
gchar* autocomplete = webkit_dom_html_input_element_get_autocomplete (
|
||||
WEBKIT_DOM_HTML_INPUT_ELEMENT (element));
|
||||
gboolean off = !g_strcmp0 (autocomplete, "off");
|
||||
g_free (autocomplete);
|
||||
if (off)
|
||||
continue;
|
||||
#endif
|
||||
|
||||
g_object_set_data (G_OBJECT (element), "doc", doc);
|
||||
g_object_set_data (G_OBJECT (element), "webview", web_view);
|
||||
g_object_set_data (G_OBJECT (element), "framelist", frames);
|
||||
/* Add dblclick? */
|
||||
webkit_dom_event_target_add_event_listener (
|
||||
WEBKIT_DOM_EVENT_TARGET (element), "keyup",
|
||||
G_CALLBACK (formhistory_editbox_key_pressed_cb), false,
|
||||
priv);
|
||||
webkit_dom_event_target_add_event_listener (
|
||||
WEBKIT_DOM_EVENT_TARGET (element), "blur",
|
||||
G_CALLBACK (formhistory_suggestions_hide_cb), false,
|
||||
priv);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
formhistory_setup_suggestions (WebKitWebView* web_view,
|
||||
JSContextRef js_context,
|
||||
MidoriExtension* extension)
|
||||
{
|
||||
WebKitDOMDocument* doc;
|
||||
WebKitDOMNodeList* frames;
|
||||
gulong i;
|
||||
|
||||
FormHistoryPriv* priv = g_object_get_data (G_OBJECT (extension), "priv");
|
||||
doc = webkit_web_view_get_dom_document (web_view);
|
||||
frames = webkit_dom_document_query_selector_all (doc, "iframe, frame", NULL);
|
||||
g_object_set_data (G_OBJECT (doc), "framelist", frames);
|
||||
g_object_set_data (G_OBJECT (doc), "webview", web_view);
|
||||
/* Connect to DOMContentLoaded of the main frame */
|
||||
webkit_dom_event_target_add_event_listener(
|
||||
WEBKIT_DOM_EVENT_TARGET (doc), "DOMContentLoaded",
|
||||
G_CALLBACK (formhistory_DOMContentLoaded_cb), false,
|
||||
priv);
|
||||
|
||||
/* Connect to DOMContentLoaded of frames */
|
||||
for (i = 0; i < webkit_dom_node_list_get_length (frames); i++)
|
||||
{
|
||||
WebKitDOMDOMWindow* framewin;
|
||||
|
||||
WebKitDOMNode* frame = webkit_dom_node_list_item (frames, i);
|
||||
if (WEBKIT_DOM_IS_HTML_IFRAME_ELEMENT (frame))
|
||||
framewin = webkit_dom_html_iframe_element_get_content_window (WEBKIT_DOM_HTML_IFRAME_ELEMENT (frame));
|
||||
else
|
||||
framewin = webkit_dom_html_frame_element_get_content_window (WEBKIT_DOM_HTML_FRAME_ELEMENT (frame));
|
||||
g_object_set_data (G_OBJECT (framewin), "framelist", frames);
|
||||
g_object_set_data (G_OBJECT (framewin), "webview", (GtkWidget*)web_view);
|
||||
webkit_dom_event_target_add_event_listener (
|
||||
WEBKIT_DOM_EVENT_TARGET (framewin), "DOMContentLoaded",
|
||||
G_CALLBACK (formhistory_DOMContentLoaded_cb), false,
|
||||
priv);
|
||||
}
|
||||
formhistory_suggestions_hide_cb (NULL, NULL, priv);
|
||||
}
|
||||
|
||||
void
|
||||
formhistory_private_destroy (FormHistoryPriv *priv)
|
||||
{
|
||||
if (priv->db)
|
||||
{
|
||||
sqlite3_close (priv->db);
|
||||
priv->db = NULL;
|
||||
}
|
||||
katze_assign (priv->oldkeyword, NULL);
|
||||
gtk_widget_destroy (priv->popup);
|
||||
priv->popup = NULL;
|
||||
katze_object_assign (priv->element, NULL);
|
||||
g_slice_free (FormHistoryPriv, priv);
|
||||
}
|
||||
|
||||
gboolean
|
||||
formhistory_construct_popup_gui (FormHistoryPriv* priv)
|
||||
{
|
||||
GtkTreeModel* model = NULL;
|
||||
GtkWidget* popup;
|
||||
GtkWidget* popup_frame;
|
||||
GtkWidget* scrolled;
|
||||
GtkWidget* treeview;
|
||||
GtkCellRenderer* renderer;
|
||||
GtkTreeViewColumn* column;
|
||||
|
||||
model = (GtkTreeModel*) gtk_list_store_new (1, G_TYPE_STRING);
|
||||
priv->completion_model = model;
|
||||
popup = gtk_window_new (GTK_WINDOW_POPUP);
|
||||
gtk_window_set_type_hint (GTK_WINDOW (popup), GDK_WINDOW_TYPE_HINT_COMBO);
|
||||
popup_frame = gtk_frame_new (NULL);
|
||||
gtk_frame_set_shadow_type (GTK_FRAME (popup_frame), GTK_SHADOW_ETCHED_IN);
|
||||
gtk_container_add (GTK_CONTAINER (popup), popup_frame);
|
||||
scrolled = g_object_new (GTK_TYPE_SCROLLED_WINDOW,
|
||||
"hscrollbar-policy", GTK_POLICY_NEVER,
|
||||
"vscrollbar-policy", GTK_POLICY_AUTOMATIC, NULL);
|
||||
gtk_container_add (GTK_CONTAINER (popup_frame), scrolled);
|
||||
treeview = gtk_tree_view_new_with_model (model);
|
||||
priv->treeview = treeview;
|
||||
gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (treeview), FALSE);
|
||||
gtk_tree_view_set_hover_selection (GTK_TREE_VIEW (treeview), TRUE);
|
||||
gtk_container_add (GTK_CONTAINER (scrolled), treeview);
|
||||
gtk_widget_set_size_request (gtk_scrolled_window_get_vscrollbar (
|
||||
GTK_SCROLLED_WINDOW (scrolled)), -1, 0);
|
||||
|
||||
renderer = gtk_cell_renderer_text_new ();
|
||||
column = gtk_tree_view_column_new_with_attributes ("suggestions", renderer, "text", 0, NULL);
|
||||
gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column);
|
||||
priv->popup = popup;
|
||||
|
||||
g_signal_connect (treeview, "button-press-event",
|
||||
G_CALLBACK (formhistory_suggestion_selected_cb), priv);
|
||||
return TRUE;
|
||||
}
|
||||
#endif
|
|
@ -1,143 +0,0 @@
|
|||
/*
|
||||
Copyright (C) 2009-2012 Alexander Butenko <a.butenka@gmail.com>
|
||||
Copyright (C) 2009-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.
|
||||
*/
|
||||
#include "formhistory-frontend.h"
|
||||
#ifdef FORMHISTORY_USE_JS
|
||||
|
||||
FormHistoryPriv*
|
||||
formhistory_private_new ()
|
||||
{
|
||||
FormHistoryPriv* priv;
|
||||
|
||||
priv = g_slice_new (FormHistoryPriv);
|
||||
return priv;
|
||||
}
|
||||
|
||||
gboolean
|
||||
formhistory_construct_popup_gui (FormHistoryPriv* priv)
|
||||
{
|
||||
gchar* autosuggest;
|
||||
gchar* style;
|
||||
guint i;
|
||||
gchar* file;
|
||||
|
||||
file = midori_app_find_res_filename ("autosuggestcontrol.js");
|
||||
if (!g_file_get_contents (file, &autosuggest, NULL, NULL))
|
||||
{
|
||||
g_free (file);
|
||||
return FALSE;
|
||||
}
|
||||
g_strchomp (autosuggest);
|
||||
|
||||
katze_assign (file, midori_app_find_res_filename ("autosuggestcontrol.css"));
|
||||
if (!g_file_get_contents (file, &style, NULL, NULL))
|
||||
{
|
||||
g_free (file);
|
||||
return FALSE;
|
||||
}
|
||||
g_strchomp (style);
|
||||
g_free (file);
|
||||
|
||||
i = 0;
|
||||
while (style[i])
|
||||
{
|
||||
if (style[i] == '\n')
|
||||
style[i] = ' ';
|
||||
i++;
|
||||
}
|
||||
|
||||
priv->jsforms = g_strdup_printf (
|
||||
"%s"
|
||||
"window.addEventListener ('DOMContentLoaded',"
|
||||
"function () {"
|
||||
" if (document.getElementById('formhistory'))"
|
||||
" return;"
|
||||
" if (!initSuggestions ())"
|
||||
" return;"
|
||||
" var mystyle = document.createElement('style');"
|
||||
" mystyle.setAttribute('type', 'text/css');"
|
||||
" mystyle.setAttribute('id', 'formhistory');"
|
||||
" mystyle.appendChild(document.createTextNode('%s'));"
|
||||
" var head = document.getElementsByTagName('head')[0];"
|
||||
" if (head) head.appendChild(mystyle);"
|
||||
"}, true);",
|
||||
autosuggest,
|
||||
style);
|
||||
g_strstrip (priv->jsforms);
|
||||
g_free (style);
|
||||
g_free (autosuggest);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
formhistory_setup_suggestions (WebKitWebView* web_view,
|
||||
JSContextRef js_context,
|
||||
MidoriExtension* extension)
|
||||
{
|
||||
GString* suggestions;
|
||||
FormHistoryPriv* priv;
|
||||
static sqlite3_stmt* stmt;
|
||||
const char* sqlcmd;
|
||||
const unsigned char* key;
|
||||
const unsigned char* value;
|
||||
|
||||
gint result, pos;
|
||||
|
||||
priv = g_object_get_data (G_OBJECT (extension), "priv");
|
||||
if (!priv->db)
|
||||
return;
|
||||
|
||||
if (!stmt)
|
||||
{
|
||||
sqlcmd = "SELECT DISTINCT group_concat(value,'\",\"'), field FROM forms \
|
||||
GROUP BY field ORDER BY field";
|
||||
sqlite3_prepare_v2 (priv->db, sqlcmd, strlen (sqlcmd) + 1, &stmt, NULL);
|
||||
}
|
||||
result = sqlite3_step (stmt);
|
||||
if (result != SQLITE_ROW)
|
||||
{
|
||||
if (result == SQLITE_ERROR)
|
||||
g_print (_("Failed to select suggestions\n"));
|
||||
sqlite3_reset (stmt);
|
||||
return;
|
||||
}
|
||||
suggestions = g_string_new (
|
||||
"function FormSuggestions(eid) { "
|
||||
"arr = new Array();");
|
||||
|
||||
while (result == SQLITE_ROW)
|
||||
{
|
||||
pos++;
|
||||
value = sqlite3_column_text (stmt, 0);
|
||||
key = sqlite3_column_text (stmt, 1);
|
||||
if (value)
|
||||
{
|
||||
g_string_append_printf (suggestions, " arr[\"%s\"] = [\"%s\"]; ",
|
||||
(gchar*)key, (gchar*)value);
|
||||
}
|
||||
result = sqlite3_step (stmt);
|
||||
}
|
||||
g_string_append (suggestions, "this.suggestions = arr[eid]; }");
|
||||
g_string_append (suggestions, priv->jsforms);
|
||||
sokoke_js_script_eval (js_context, suggestions->str, NULL);
|
||||
g_string_free (suggestions, TRUE);
|
||||
}
|
||||
|
||||
void
|
||||
formhistory_private_destroy (FormHistoryPriv *priv)
|
||||
{
|
||||
if (priv->db)
|
||||
{
|
||||
sqlite3_close (priv->db);
|
||||
priv->db = NULL;
|
||||
}
|
||||
katze_assign (priv->jsforms, NULL);
|
||||
g_slice_free (FormHistoryPriv, priv);
|
||||
}
|
||||
#endif
|
|
@ -1,681 +0,0 @@
|
|||
/*
|
||||
Copyright (C) 2009-2012 Alexander Butenko <a.butenka@gmail.com>
|
||||
Copyright (C) 2009-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.
|
||||
*/
|
||||
#define MAXCHARS 60
|
||||
#define MINCHARS 2
|
||||
#define GTK_RESPONSE_IGNORE 99
|
||||
#include "formhistory-frontend.h"
|
||||
|
||||
static void
|
||||
formhistory_toggle_state_cb (GtkAction* action,
|
||||
MidoriBrowser* browser);
|
||||
|
||||
static void
|
||||
formhistory_update_database (gpointer db,
|
||||
const gchar* host,
|
||||
const gchar* key,
|
||||
const gchar* value)
|
||||
{
|
||||
gchar* sqlcmd;
|
||||
gchar* errmsg;
|
||||
gint success;
|
||||
|
||||
if (!(value && *value))
|
||||
return;
|
||||
|
||||
sqlcmd = sqlite3_mprintf ("INSERT INTO forms VALUES"
|
||||
"('%q', '%q', '%q')",
|
||||
host, key, value);
|
||||
success = sqlite3_exec (db, sqlcmd, NULL, NULL, &errmsg);
|
||||
sqlite3_free (sqlcmd);
|
||||
if (success != SQLITE_OK)
|
||||
{
|
||||
g_printerr (_("Failed to add form value: %s\n"), errmsg);
|
||||
g_free (errmsg);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static gchar*
|
||||
formhistory_get_login_data (gpointer db,
|
||||
const gchar* domain)
|
||||
{
|
||||
static sqlite3_stmt* stmt;
|
||||
const char* sqlcmd;
|
||||
gint result;
|
||||
gchar* value = NULL;
|
||||
|
||||
if (!stmt)
|
||||
{
|
||||
sqlcmd = "SELECT value FROM forms WHERE domain = ?1 and field = 'MidoriPasswordManager' limit 1";
|
||||
sqlite3_prepare_v2 (db, sqlcmd, strlen (sqlcmd) + 1, &stmt, NULL);
|
||||
}
|
||||
sqlite3_bind_text (stmt, 1, domain, -1, NULL);
|
||||
result = sqlite3_step (stmt);
|
||||
if (result == SQLITE_ROW)
|
||||
value = g_strdup ((gchar*)sqlite3_column_text (stmt, 0));
|
||||
sqlite3_reset (stmt);
|
||||
sqlite3_clear_bindings (stmt);
|
||||
return value;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
formhistory_check_master_password (GtkWidget* parent,
|
||||
FormHistoryPriv* priv)
|
||||
{
|
||||
GtkWidget* dialog;
|
||||
GtkWidget* content_area;
|
||||
GtkWidget* hbox;
|
||||
GtkWidget* image;
|
||||
GtkWidget* label;
|
||||
GtkWidget* entry;
|
||||
const gchar* title;
|
||||
static int alive;
|
||||
gboolean ret = FALSE;
|
||||
|
||||
/* Password is set */
|
||||
if (priv->master_password && *priv->master_password)
|
||||
return TRUE;
|
||||
|
||||
/* Other prompt is active */
|
||||
if (alive == 1)
|
||||
return FALSE;
|
||||
|
||||
/* Prompt was cancelled */
|
||||
if (priv->master_password_canceled == 1)
|
||||
return FALSE;
|
||||
|
||||
alive = 1;
|
||||
title = _("Form history");
|
||||
dialog = gtk_dialog_new_with_buttons (title, GTK_WINDOW (parent),
|
||||
GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_NO_SEPARATOR,
|
||||
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
|
||||
GTK_STOCK_OK, GTK_RESPONSE_OK,
|
||||
NULL);
|
||||
content_area = gtk_dialog_get_content_area (GTK_DIALOG (dialog));
|
||||
gtk_window_set_icon_name (GTK_WINDOW (dialog), GTK_STOCK_DIALOG_AUTHENTICATION);
|
||||
gtk_container_set_border_width (GTK_CONTAINER (dialog), 5);
|
||||
gtk_container_set_border_width (GTK_CONTAINER (content_area), 5);
|
||||
|
||||
hbox = gtk_hbox_new (FALSE, 8);
|
||||
gtk_container_set_border_width (GTK_CONTAINER (hbox), 5);
|
||||
image = gtk_image_new_from_stock (GTK_STOCK_DIALOG_AUTHENTICATION,
|
||||
GTK_ICON_SIZE_DIALOG);
|
||||
gtk_box_pack_start (GTK_BOX (hbox), image, FALSE, FALSE, 0);
|
||||
|
||||
label = gtk_label_new (_("Master password required\n"
|
||||
"to open password database"));
|
||||
gtk_box_pack_start (GTK_BOX (hbox), label, TRUE, TRUE, 0);
|
||||
gtk_container_add (GTK_CONTAINER (content_area), hbox);
|
||||
|
||||
entry = gtk_entry_new ();
|
||||
g_object_set (entry, "truncate-multiline", TRUE, NULL);
|
||||
gtk_entry_set_visibility(GTK_ENTRY (entry),FALSE);
|
||||
gtk_entry_set_activates_default (GTK_ENTRY (entry), TRUE);
|
||||
gtk_container_add (GTK_CONTAINER (content_area), entry);
|
||||
|
||||
gtk_widget_show_all (entry);
|
||||
gtk_widget_show_all (hbox);
|
||||
gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
|
||||
|
||||
if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_OK)
|
||||
{
|
||||
/* FIXME: add password verification */
|
||||
katze_assign (priv->master_password,
|
||||
g_strdup (gtk_entry_get_text (GTK_ENTRY (entry))));
|
||||
ret = TRUE;
|
||||
}
|
||||
else
|
||||
priv->master_password_canceled = 1;
|
||||
|
||||
gtk_widget_destroy (dialog);
|
||||
alive = 0;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static gchar*
|
||||
formhistory_encrypt (const gchar* data,
|
||||
const gchar* password)
|
||||
{
|
||||
/* TODO: Implement persistent storage/ keyring support */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
formhistory_remember_password_response (GtkWidget* infobar,
|
||||
gint response_id,
|
||||
FormhistoryPasswordEntry* entry)
|
||||
{
|
||||
gchar* encrypted_form;
|
||||
|
||||
if (response_id == GTK_RESPONSE_IGNORE)
|
||||
goto cleanup;
|
||||
|
||||
if (formhistory_check_master_password (NULL, entry->priv))
|
||||
{
|
||||
if (response_id != GTK_RESPONSE_ACCEPT)
|
||||
katze_assign (entry->form_data, g_strdup ("never"));
|
||||
|
||||
if ((encrypted_form = formhistory_encrypt (entry->form_data,
|
||||
entry->priv->master_password)))
|
||||
formhistory_update_database (entry->priv->db, entry->domain, "MidoriPasswordManager", encrypted_form);
|
||||
g_free (encrypted_form);
|
||||
}
|
||||
|
||||
cleanup:
|
||||
g_free (entry->form_data);
|
||||
g_free (entry->domain);
|
||||
g_slice_free (FormhistoryPasswordEntry, entry);
|
||||
gtk_widget_destroy (infobar);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
formhistory_navigation_decision_cb (WebKitWebView* web_view,
|
||||
WebKitWebFrame* web_frame,
|
||||
WebKitNetworkRequest* request,
|
||||
WebKitWebNavigationAction* action,
|
||||
WebKitWebPolicyDecision* decision,
|
||||
MidoriExtension* extension)
|
||||
{
|
||||
FormHistoryPriv* priv;
|
||||
JSContextRef js_context;
|
||||
gchar* value;
|
||||
|
||||
/* The script returns form data in the form "field_name|,|value|,|field_type".
|
||||
We are handling only input fields with 'text' or 'password' type.
|
||||
The field separator is "|||" */
|
||||
const gchar* script = "function dumpForm (inputs) {"
|
||||
" var out = '';"
|
||||
" for (var i = 0; i < inputs.length; i++) {"
|
||||
" if (inputs[i].getAttribute('autocomplete') == 'off' && "
|
||||
" inputs[i].type == 'text')"
|
||||
" continue;"
|
||||
" if (inputs[i].value && (inputs[i].type == 'text' || inputs[i].type == 'password')) {"
|
||||
" var ename = inputs[i].getAttribute('name');"
|
||||
" var eid = inputs[i].getAttribute('id');"
|
||||
" if (!eid && ename)"
|
||||
" eid=ename;"
|
||||
" out += eid+'|,|'+inputs[i].value +'|,|'+inputs[i].type +'|||';"
|
||||
" }"
|
||||
" }"
|
||||
" return out;"
|
||||
"}"
|
||||
"dumpForm (document.getElementsByTagName('input'))";
|
||||
|
||||
if (webkit_web_navigation_action_get_reason (action) != WEBKIT_WEB_NAVIGATION_REASON_FORM_SUBMITTED)
|
||||
return FALSE;
|
||||
|
||||
priv = g_object_get_data (G_OBJECT (extension), "priv");
|
||||
js_context = webkit_web_frame_get_global_context (web_frame);
|
||||
value = sokoke_js_script_eval (js_context, script, NULL);
|
||||
|
||||
#ifdef FORMHISTORY_USE_GDOM
|
||||
formhistory_suggestions_hide_cb (NULL, NULL, priv);
|
||||
#endif
|
||||
if (value && *value)
|
||||
{
|
||||
gchar** inputs = g_strsplit (value, "|||", 0);
|
||||
guint i = 0;
|
||||
while (inputs[i] != NULL)
|
||||
{
|
||||
gchar** parts = g_strsplit (inputs[i], "|,|", 3);
|
||||
if (parts && parts[0] && parts[1] && parts[2])
|
||||
{
|
||||
if (strcmp (parts[2], "password"))
|
||||
formhistory_update_database (priv->db, NULL, parts[0], parts[1]);
|
||||
#if WEBKIT_CHECK_VERSION (1, 3, 8)
|
||||
else
|
||||
{
|
||||
gchar* data;
|
||||
gchar* domain;
|
||||
#if 0
|
||||
FormhistoryPasswordEntry* entry;
|
||||
#endif
|
||||
|
||||
domain = midori_uri_parse_hostname (webkit_web_frame_get_uri (web_frame), NULL);
|
||||
data = formhistory_get_login_data (priv->db, domain);
|
||||
if (data)
|
||||
{
|
||||
g_free (data);
|
||||
g_free (domain);
|
||||
break;
|
||||
}
|
||||
#if 0
|
||||
entry = g_slice_new (FormhistoryPasswordEntry);
|
||||
/* Domain and form data are freed from infopanel callback*/
|
||||
entry->form_data = g_strdup (value);
|
||||
entry->domain = domain;
|
||||
entry->priv = priv;
|
||||
g_object_set_data (G_OBJECT (web_view), "FormHistoryPasswordEntry", entry);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
}
|
||||
g_strfreev (parts);
|
||||
i++;
|
||||
}
|
||||
g_strfreev (inputs);
|
||||
g_free (value);
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
formhistory_window_object_cleared_cb (WebKitWebView* web_view,
|
||||
WebKitWebFrame* web_frame,
|
||||
JSContextRef js_context,
|
||||
JSObjectRef js_window,
|
||||
MidoriExtension* extension)
|
||||
{
|
||||
const gchar* page_uri;
|
||||
FormhistoryPasswordEntry* entry;
|
||||
GtkWidget* view;
|
||||
|
||||
page_uri = webkit_web_frame_get_uri (web_frame);
|
||||
if (!page_uri)
|
||||
return;
|
||||
|
||||
if (!midori_uri_is_http (page_uri) && !g_str_has_prefix (page_uri, "file"))
|
||||
return;
|
||||
|
||||
formhistory_setup_suggestions (web_view, js_context, extension);
|
||||
|
||||
#if WEBKIT_CHECK_VERSION (1, 3, 8)
|
||||
entry = g_object_get_data (G_OBJECT (web_view), "FormHistoryPasswordEntry");
|
||||
if (entry)
|
||||
{
|
||||
const gchar* message = _("Remember password on this page?");
|
||||
view = midori_browser_get_current_tab (midori_app_get_browser (
|
||||
midori_extension_get_app (extension)));
|
||||
midori_view_add_info_bar (MIDORI_VIEW (view), GTK_MESSAGE_QUESTION, message,
|
||||
G_CALLBACK (formhistory_remember_password_response), entry,
|
||||
_("Remember"), GTK_RESPONSE_ACCEPT,
|
||||
_("Not now"), GTK_RESPONSE_IGNORE,
|
||||
_("Never for this page"), GTK_RESPONSE_CANCEL, NULL);
|
||||
g_object_set_data (G_OBJECT (web_view), "FormHistoryPasswordEntry", NULL);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#if WEBKIT_CHECK_VERSION (1, 3, 8)
|
||||
static gchar*
|
||||
formhistory_decrypt (const gchar* data,
|
||||
const gchar* password)
|
||||
{
|
||||
/* TODO: Implement persistent storage/ keyring support */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
formhistory_fill_login_data (JSContextRef js_context,
|
||||
FormHistoryPriv* priv,
|
||||
const gchar* data)
|
||||
{
|
||||
gchar* decrypted_data = NULL;
|
||||
guint i = 0;
|
||||
GString *script;
|
||||
gchar** inputs;
|
||||
|
||||
/* Handle case that user dont want to store password */
|
||||
if (!strncmp (data, "never", 5))
|
||||
return;
|
||||
|
||||
#if 0
|
||||
if (!formhistory_check_master_password (NULL, priv))
|
||||
return;
|
||||
#endif
|
||||
|
||||
if (!(decrypted_data = formhistory_decrypt (data, priv->master_password)))
|
||||
return;
|
||||
|
||||
script = g_string_new ("");
|
||||
inputs = g_strsplit (decrypted_data, "|||", 0);
|
||||
while (inputs[i] != NULL)
|
||||
{
|
||||
gchar** parts = g_strsplit (inputs[i], "|,|", 3);
|
||||
if (parts && parts[0] && parts[1] && parts[2])
|
||||
{
|
||||
g_string_append_printf (script, "node = null;"
|
||||
"node = document.getElementById ('%s');"
|
||||
"if (!node) { node = document.getElementsByName ('%s')[0]; }"
|
||||
"if (node && node.type == '%s') { node.value = '%s'; }",
|
||||
parts[0], parts[0], parts[2], parts[1]);
|
||||
}
|
||||
g_strfreev (parts);
|
||||
i++;
|
||||
}
|
||||
g_free (decrypted_data);
|
||||
g_strfreev (inputs);
|
||||
g_free (sokoke_js_script_eval (js_context, script->str, NULL));
|
||||
g_string_free (script, TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
formhistory_frame_loaded_cb (WebKitWebView* web_view,
|
||||
WebKitWebFrame* web_frame,
|
||||
MidoriExtension* extension)
|
||||
{
|
||||
const gchar* page_uri;
|
||||
const gchar* count_request;
|
||||
FormHistoryPriv* priv;
|
||||
JSContextRef js_context;
|
||||
gchar* data;
|
||||
gchar* domain;
|
||||
gchar* count;
|
||||
|
||||
page_uri = webkit_web_frame_get_uri (web_frame);
|
||||
if (!page_uri)
|
||||
return;
|
||||
|
||||
count_request = "document.querySelectorAll('input[type=password]').length";
|
||||
js_context = webkit_web_frame_get_global_context (web_frame);
|
||||
count = sokoke_js_script_eval (js_context, count_request, NULL);
|
||||
if (count && count[0] == '0')
|
||||
{
|
||||
g_free (count);
|
||||
return;
|
||||
}
|
||||
g_free (count);
|
||||
|
||||
priv = g_object_get_data (G_OBJECT (extension), "priv");
|
||||
domain = midori_uri_parse_hostname (webkit_web_frame_get_uri (web_frame), NULL);
|
||||
data = formhistory_get_login_data (priv->db, domain);
|
||||
g_free (domain);
|
||||
|
||||
if (!data)
|
||||
return;
|
||||
formhistory_fill_login_data (js_context, priv, data);
|
||||
g_free (data);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
formhistory_deactivate_cb (MidoriExtension* extension,
|
||||
MidoriBrowser* browser);
|
||||
|
||||
static void
|
||||
formhistory_add_tab_cb (MidoriBrowser* browser,
|
||||
MidoriView* view,
|
||||
MidoriExtension* extension)
|
||||
{
|
||||
GtkWidget* web_view = midori_view_get_web_view (view);
|
||||
|
||||
g_signal_connect (web_view, "window-object-cleared",
|
||||
G_CALLBACK (formhistory_window_object_cleared_cb), extension);
|
||||
g_signal_connect (web_view, "navigation-policy-decision-requested",
|
||||
G_CALLBACK (formhistory_navigation_decision_cb), extension);
|
||||
|
||||
#if WEBKIT_CHECK_VERSION (1, 3, 8)
|
||||
g_signal_connect (web_view, "onload-event",
|
||||
G_CALLBACK (formhistory_frame_loaded_cb), extension);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
formhistory_add_tab_foreach_cb (MidoriView* view,
|
||||
MidoriExtension* extension)
|
||||
{
|
||||
formhistory_add_tab_cb (NULL, view, extension);
|
||||
}
|
||||
|
||||
static void
|
||||
formhistory_app_add_browser_cb (MidoriApp* app,
|
||||
MidoriBrowser* browser,
|
||||
MidoriExtension* extension)
|
||||
{
|
||||
|
||||
GtkAccelGroup* acg = gtk_accel_group_new ();
|
||||
GtkActionGroup* action_group = midori_browser_get_action_group (browser);
|
||||
GtkAction* action = gtk_action_new ("FormHistoryToggleState",
|
||||
_("Toggle form history state"),
|
||||
_("Activate or deactivate form history for the current tab."), NULL);
|
||||
gtk_window_add_accel_group (GTK_WINDOW (browser), acg);
|
||||
|
||||
g_object_set_data (G_OBJECT (browser), "FormHistoryExtension", extension);
|
||||
|
||||
g_signal_connect (action, "activate",
|
||||
G_CALLBACK (formhistory_toggle_state_cb), browser);
|
||||
|
||||
gtk_action_group_add_action_with_accel (action_group, action, "<Ctrl><Shift>F");
|
||||
gtk_action_set_accel_group (action, acg);
|
||||
gtk_action_connect_accelerator (action);
|
||||
|
||||
if (midori_extension_get_boolean (extension, "always-load"))
|
||||
{
|
||||
midori_browser_foreach (browser,
|
||||
(GtkCallback)formhistory_add_tab_foreach_cb, extension);
|
||||
g_signal_connect (browser, "add-tab",
|
||||
G_CALLBACK (formhistory_add_tab_cb), extension);
|
||||
}
|
||||
g_signal_connect (extension, "deactivate",
|
||||
G_CALLBACK (formhistory_deactivate_cb), browser);
|
||||
}
|
||||
|
||||
static void
|
||||
formhistory_deactivate_tab (MidoriView* view,
|
||||
MidoriExtension* extension)
|
||||
{
|
||||
GtkWidget* web_view = midori_view_get_web_view (view);
|
||||
|
||||
g_signal_handlers_disconnect_by_func (
|
||||
web_view, formhistory_window_object_cleared_cb, extension);
|
||||
g_signal_handlers_disconnect_by_func (
|
||||
web_view, formhistory_navigation_decision_cb, extension);
|
||||
#if WEBKIT_CHECK_VERSION (1, 3, 8)
|
||||
g_signal_handlers_disconnect_by_func (
|
||||
web_view, formhistory_frame_loaded_cb, extension);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
formhistory_deactivate_cb (MidoriExtension* extension,
|
||||
MidoriBrowser* browser)
|
||||
{
|
||||
MidoriApp* app = midori_extension_get_app (extension);
|
||||
FormHistoryPriv* priv = g_object_get_data (G_OBJECT (extension), "priv");
|
||||
|
||||
GtkActionGroup* action_group = midori_browser_get_action_group (browser);
|
||||
GtkAction* action;
|
||||
|
||||
g_signal_handlers_disconnect_by_func (
|
||||
browser, formhistory_add_tab_cb, extension);
|
||||
g_signal_handlers_disconnect_by_func (
|
||||
extension, formhistory_deactivate_cb, browser);
|
||||
g_signal_handlers_disconnect_by_func (
|
||||
app, formhistory_app_add_browser_cb, extension);
|
||||
midori_browser_foreach (browser,
|
||||
(GtkCallback)formhistory_deactivate_tab, extension);
|
||||
|
||||
g_object_set_data (G_OBJECT (browser), "FormHistoryExtension", NULL);
|
||||
action = gtk_action_group_get_action (action_group, "FormHistoryToggleState");
|
||||
if (action != NULL)
|
||||
{
|
||||
gtk_action_group_remove_action (action_group, action);
|
||||
g_object_unref (action);
|
||||
}
|
||||
|
||||
formhistory_private_destroy (priv);
|
||||
}
|
||||
|
||||
static void
|
||||
formhistory_activate_cb (MidoriExtension* extension,
|
||||
MidoriApp* app)
|
||||
{
|
||||
const gchar* config_dir;
|
||||
gchar* filename;
|
||||
sqlite3* db;
|
||||
char* errmsg = NULL, *errmsg2 = NULL;
|
||||
KatzeArray* browsers;
|
||||
MidoriBrowser* browser;
|
||||
FormHistoryPriv* priv;
|
||||
|
||||
priv = formhistory_private_new ();
|
||||
priv->master_password = NULL;
|
||||
priv->master_password_canceled = 0;
|
||||
formhistory_construct_popup_gui (priv);
|
||||
|
||||
config_dir = midori_extension_get_config_dir (extension);
|
||||
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 (config_dir != NULL)
|
||||
g_warning (_("Failed to open database: %s\n"), sqlite3_errmsg (db));
|
||||
sqlite3_close (db);
|
||||
}
|
||||
g_free (filename);
|
||||
if ((sqlite3_exec (db, "CREATE TABLE IF NOT EXISTS "
|
||||
"forms (domain text, field text, value text)",
|
||||
NULL, NULL, &errmsg) == SQLITE_OK))
|
||||
{
|
||||
sqlite3_exec (db,
|
||||
/* "PRAGMA synchronous = OFF; PRAGMA temp_store = MEMORY" */
|
||||
"PRAGMA count_changes = OFF; PRAGMA journal_mode = TRUNCATE;",
|
||||
NULL, NULL, &errmsg);
|
||||
priv->db = db;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (errmsg)
|
||||
{
|
||||
g_critical (_("Failed to execute database statement: %s\n"), errmsg);
|
||||
sqlite3_free (errmsg);
|
||||
if (errmsg2)
|
||||
{
|
||||
g_critical (_("Failed to execute database statement: %s\n"), errmsg2);
|
||||
sqlite3_free (errmsg2);
|
||||
}
|
||||
}
|
||||
sqlite3_close (db);
|
||||
}
|
||||
|
||||
g_object_set_data (G_OBJECT (extension), "priv", priv);
|
||||
browsers = katze_object_get_object (app, "browsers");
|
||||
KATZE_ARRAY_FOREACH_ITEM (browser, browsers)
|
||||
formhistory_app_add_browser_cb (app, browser, extension);
|
||||
g_signal_connect (app, "add-browser",
|
||||
G_CALLBACK (formhistory_app_add_browser_cb), extension);
|
||||
|
||||
g_object_unref (browsers);
|
||||
}
|
||||
|
||||
static void
|
||||
formhistory_preferences_response_cb (GtkWidget* dialog,
|
||||
gint response_id,
|
||||
MidoriExtension* extension)
|
||||
{
|
||||
GtkWidget* checkbox;
|
||||
gboolean old_state;
|
||||
gboolean new_state;
|
||||
MidoriApp* app;
|
||||
KatzeArray* browsers;
|
||||
MidoriBrowser* browser;
|
||||
|
||||
if (response_id == GTK_RESPONSE_APPLY)
|
||||
{
|
||||
checkbox = g_object_get_data (G_OBJECT (dialog), "always-load-checkbox");
|
||||
new_state = !gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (checkbox));
|
||||
old_state = midori_extension_get_boolean (extension, "always-load");
|
||||
|
||||
if (old_state != new_state)
|
||||
{
|
||||
midori_extension_set_boolean (extension, "always-load", new_state);
|
||||
|
||||
app = midori_extension_get_app (extension);
|
||||
browsers = katze_object_get_object (app, "browsers");
|
||||
KATZE_ARRAY_FOREACH_ITEM (browser, browsers)
|
||||
{
|
||||
midori_browser_foreach (browser,
|
||||
(GtkCallback)formhistory_deactivate_tab, extension);
|
||||
g_signal_handlers_disconnect_by_func (
|
||||
browser, formhistory_add_tab_cb, extension);
|
||||
|
||||
if (new_state)
|
||||
{
|
||||
midori_browser_foreach (browser,
|
||||
(GtkCallback)formhistory_add_tab_foreach_cb, extension);
|
||||
g_signal_connect (browser, "add-tab",
|
||||
G_CALLBACK (formhistory_add_tab_cb), extension);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
gtk_widget_destroy (dialog);
|
||||
}
|
||||
|
||||
static void
|
||||
formhistory_preferences_cb (MidoriExtension* extension)
|
||||
{
|
||||
GtkWidget* dialog;
|
||||
GtkWidget* content_area;
|
||||
GtkWidget* checkbox;
|
||||
|
||||
dialog = gtk_dialog_new ();
|
||||
|
||||
gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
|
||||
|
||||
gtk_dialog_add_button (GTK_DIALOG (dialog), GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL);
|
||||
gtk_dialog_add_button (GTK_DIALOG (dialog), GTK_STOCK_APPLY, GTK_RESPONSE_APPLY);
|
||||
|
||||
content_area = gtk_dialog_get_content_area (GTK_DIALOG (dialog));
|
||||
checkbox = gtk_check_button_new_with_label (_("Only activate form history via hotkey (Ctrl+Shift+F) per tab"));
|
||||
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (checkbox),
|
||||
!midori_extension_get_boolean (extension, "always-load"));
|
||||
g_object_set_data (G_OBJECT (dialog), "always-load-checkbox", checkbox);
|
||||
gtk_container_add (GTK_CONTAINER (content_area), checkbox);
|
||||
/* FIXME: Add pref to disable password manager */
|
||||
|
||||
g_signal_connect (dialog,
|
||||
"response",
|
||||
G_CALLBACK (formhistory_preferences_response_cb),
|
||||
extension);
|
||||
gtk_widget_show_all (dialog);
|
||||
}
|
||||
|
||||
static void
|
||||
formhistory_toggle_state_cb (GtkAction* action,
|
||||
MidoriBrowser* browser)
|
||||
{
|
||||
MidoriView* view = MIDORI_VIEW (midori_browser_get_current_tab (browser));
|
||||
MidoriExtension* extension = g_object_get_data (G_OBJECT (browser), "FormHistoryExtension");
|
||||
GtkWidget* web_view = midori_view_get_web_view (view);
|
||||
|
||||
if (g_signal_handler_find (web_view, G_SIGNAL_MATCH_FUNC,
|
||||
g_signal_lookup ("window-object-cleared", MIDORI_TYPE_VIEW), 0, NULL,
|
||||
formhistory_window_object_cleared_cb, extension))
|
||||
{
|
||||
formhistory_deactivate_tab (view, extension);
|
||||
}
|
||||
else
|
||||
formhistory_add_tab_cb (browser, view, extension);
|
||||
}
|
||||
|
||||
MidoriExtension*
|
||||
extension_init (void)
|
||||
{
|
||||
MidoriExtension* extension;
|
||||
|
||||
|
||||
extension = g_object_new (MIDORI_TYPE_EXTENSION,
|
||||
"name", _("Form history filler"),
|
||||
"description", _("Stores history of entered form data"),
|
||||
"version", "2.0" MIDORI_VERSION_SUFFIX,
|
||||
"authors", "Alexander V. Butenko <a.butenka@gmail.com>",
|
||||
NULL);
|
||||
|
||||
midori_extension_install_boolean (extension, "always-load", TRUE);
|
||||
g_signal_connect (extension, "activate",
|
||||
G_CALLBACK (formhistory_activate_cb), NULL);
|
||||
g_signal_connect (extension, "open-preferences",
|
||||
G_CALLBACK (formhistory_preferences_cb), NULL);
|
||||
|
||||
return extension;
|
||||
}
|
|
@ -462,7 +462,7 @@ namespace HistoryList {
|
|||
tab_added (browser, tab);
|
||||
browser.add_tab.connect (tab_added);
|
||||
browser.remove_tab.connect (tab_removed);
|
||||
browser.switch_tab.connect (this.tab_changed);
|
||||
browser.notify["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.switch_tab.disconnect (this.tab_changed);
|
||||
browser.notify["tab"].disconnect (this.tab_changed);
|
||||
}
|
||||
|
||||
void tab_added (Midori.Browser browser, Midori.View view) {
|
||||
|
@ -520,18 +520,21 @@ namespace HistoryList {
|
|||
}
|
||||
}
|
||||
|
||||
void tab_changed (Midori.View? old_view, Midori.View? new_view) {
|
||||
void tab_changed (GLib.Object window, GLib.ParamSpec pspec) {
|
||||
if(this.ignoreNextChange) {
|
||||
this.ignoreNextChange = false;
|
||||
} else {
|
||||
Midori.Browser? browser = Midori.Browser.get_for_widget (new_view);
|
||||
Midori.View? last_view
|
||||
= browser.get_data<Midori.View?> ("history-list-last-change");
|
||||
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");
|
||||
|
||||
if (last_view != null) {
|
||||
this.tab_list_resort (browser, last_view);
|
||||
}
|
||||
browser.set_data<Midori.View?> ("history-list-last-change", new_view);
|
||||
browser.set_data<Midori.View?> ("history-list-last-change", view);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -180,6 +180,8 @@ shortcuts_get_preferences_dialog (MidoriExtension* extension)
|
|||
GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE,
|
||||
#endif
|
||||
NULL);
|
||||
g_signal_connect (dialog, "destroy",
|
||||
G_CALLBACK (gtk_widget_destroyed), &dialog);
|
||||
gtk_window_set_icon_name (GTK_WINDOW (dialog), GTK_STOCK_PROPERTIES);
|
||||
sokoke_widget_get_text_size (dialog, "M", &width, &height);
|
||||
gtk_window_set_default_size (GTK_WINDOW (dialog), width * 52, height * 24);
|
||||
|
|
|
@ -66,14 +66,11 @@ statusbar_features_browser_notify_tab_cb (MidoriBrowser* browser,
|
|||
GtkWidget* combobox)
|
||||
{
|
||||
MidoriView* view = MIDORI_VIEW (midori_browser_get_current_tab (browser));
|
||||
gchar* text;
|
||||
|
||||
if (view == NULL)
|
||||
return;
|
||||
|
||||
text = g_strdup_printf ("%d%%", (gint)(midori_view_get_zoom_level (view) * 100));
|
||||
gtk_entry_set_text (GTK_ENTRY (gtk_bin_get_child (GTK_BIN (combobox))), text);
|
||||
g_free (text);
|
||||
gchar* zoom_level_text = g_strdup_printf ("%d%%",
|
||||
(gint)(midori_view_get_zoom_level (view) * 100));
|
||||
gtk_entry_set_text (GTK_ENTRY (gtk_bin_get_child (GTK_BIN (combobox))),
|
||||
zoom_level_text);
|
||||
g_free (zoom_level_text);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -107,81 +104,6 @@ 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,
|
||||
|
@ -192,8 +114,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. */
|
||||
|
@ -202,37 +124,48 @@ 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");
|
||||
|
||||
filters = midori_extension_get_string_list (extension, "items", NULL);
|
||||
if (filters && *filters)
|
||||
{
|
||||
i = 0;
|
||||
while (filters[i] != NULL)
|
||||
{
|
||||
button = statusbar_features_property_proxy (settings, filters[i], toolbar);
|
||||
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);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
button = statusbar_features_property_proxy (settings, "auto-load-images", toolbar);
|
||||
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);
|
||||
button = statusbar_features_property_proxy (settings, "enable-scripts", toolbar);
|
||||
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);
|
||||
button = statusbar_features_property_proxy (settings, "enable-plugins", toolbar);
|
||||
button = katze_property_proxy (settings, "identify-as", "custom-user-agent");
|
||||
gtk_box_pack_start (GTK_BOX (bbox), button, FALSE, FALSE, 2);
|
||||
button = statusbar_features_property_proxy (settings, "identify-as", toolbar);
|
||||
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);
|
||||
button = statusbar_features_property_proxy (settings, "zoom-level", toolbar);
|
||||
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);
|
||||
gtk_widget_show_all (bbox);
|
||||
gtk_box_pack_end (GTK_BOX (statusbar), bbox, FALSE, FALSE, 3);
|
||||
gtk_box_pack_start (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);
|
||||
}
|
||||
|
@ -261,7 +194,6 @@ 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);
|
||||
|
|
|
@ -143,6 +143,7 @@ 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,
|
||||
|
@ -170,6 +171,7 @@ tab_panel_treeview_query_tooltip_cb (GtkWidget* treeview,
|
|||
|
||||
return TRUE;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
midori_extension_row_activated_cb (GtkTreeView* treeview,
|
||||
|
@ -229,12 +231,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))
|
||||
midori_browser_remove_tab (browser, view);
|
||||
gtk_widget_destroy (view);
|
||||
else
|
||||
midori_browser_set_current_tab (browser, view);
|
||||
}
|
||||
else if (event->button == 2)
|
||||
midori_browser_remove_tab (midori_browser_get_for_widget (widget), view);
|
||||
gtk_widget_destroy (view);
|
||||
else
|
||||
tab_panel_popup (widget, event, view);
|
||||
|
||||
|
@ -417,7 +419,8 @@ tab_panel_browser_add_tab_cb (MidoriBrowser* browser,
|
|||
GtkWidget* view,
|
||||
MidoriExtension* extension)
|
||||
{
|
||||
gint page = midori_browser_page_num (browser, view);
|
||||
GtkWidget* notebook = katze_object_get_object (browser, "notebook");
|
||||
gint page = gtk_notebook_page_num (GTK_NOTEBOOK (notebook), view);
|
||||
MidoriWebSettings* settings = midori_browser_get_settings (browser);
|
||||
gboolean minimized = katze_object_get_boolean (view, "minimized");
|
||||
GdkPixbuf* icon = midori_view_get_icon (MIDORI_VIEW (view));
|
||||
|
@ -465,6 +468,8 @@ tab_panel_browser_add_tab_cb (MidoriBrowser* browser,
|
|||
g_signal_connect (view, "notify::title",
|
||||
G_CALLBACK (tab_panel_view_notify_title_cb), extension);
|
||||
}
|
||||
|
||||
g_object_unref (notebook);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -532,9 +537,11 @@ 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);
|
||||
|
|
|
@ -46,6 +46,8 @@ 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);
|
||||
|
||||
|
@ -56,6 +58,7 @@ 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);
|
||||
|
@ -104,12 +107,7 @@ 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++;
|
||||
}
|
||||
|
@ -396,7 +394,11 @@ static TBEditorWidget *tb_editor_create_dialog(MidoriBrowser *parent)
|
|||
GTK_WINDOW(parent),
|
||||
GTK_DIALOG_DESTROY_WITH_PARENT,
|
||||
GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE, NULL);
|
||||
vbox = gtk_dialog_get_content_area(GTK_DIALOG(dialog));
|
||||
#if !GTK_CHECK_VERSION(3,0,0)
|
||||
vbox = (GTK_DIALOG(dialog))->vbox;
|
||||
#else
|
||||
vbox = GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(dialog)));
|
||||
#endif
|
||||
gtk_box_set_spacing(GTK_BOX(vbox), 6);
|
||||
gtk_widget_set_name(dialog, "GeanyDialog");
|
||||
gtk_window_set_default_size(GTK_WINDOW(dialog), -1, 400);
|
||||
|
@ -408,7 +410,7 @@ static TBEditorWidget *tb_editor_create_dialog(MidoriBrowser *parent)
|
|||
G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING);
|
||||
|
||||
label = gtk_label_new(
|
||||
_("Select items to be displayed on the toolbar. Items can be reordered by drag and drop."));
|
||||
_("Select items to be displayed on the toolbar. Items can be reodered by drag and drop."));
|
||||
gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
|
||||
|
||||
tree_available = gtk_tree_view_new();
|
||||
|
@ -576,6 +578,17 @@ 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)
|
||||
{
|
||||
|
@ -585,7 +598,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 Toolbar…"));
|
||||
menuitem = gtk_menu_item_new_with_mnemonic (_("_Customize..."));
|
||||
g_signal_connect (menuitem, "activate",
|
||||
G_CALLBACK (tb_editor_menu_configure_toolbar_activate_cb), browser);
|
||||
gtk_widget_show (menuitem);
|
||||
|
@ -594,6 +607,7 @@ 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);
|
||||
}
|
||||
|
|
|
@ -28,7 +28,8 @@ web_cache_get_cache_dir (void)
|
|||
{
|
||||
static gchar* cache_dir = NULL;
|
||||
if (!cache_dir)
|
||||
cache_dir = g_build_filename (midori_paths_get_cache_dir (), "web", NULL);
|
||||
cache_dir = g_build_filename (g_get_user_cache_dir (),
|
||||
PACKAGE_NAME, "web", NULL);
|
||||
return cache_dir;
|
||||
}
|
||||
|
||||
|
|
|
@ -28,16 +28,13 @@ for extension in extensions:
|
|||
continue
|
||||
source = extension
|
||||
|
||||
if bld.env['platform'] == 'win32' and target in ['external-download-manager']:
|
||||
continue
|
||||
|
||||
obj = bld.new_task_gen ('cc', 'shlib')
|
||||
obj.target = target
|
||||
obj.includes = '.. ../katze ../midori'
|
||||
obj.includes = '..'
|
||||
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 midori-core katze'
|
||||
obj.vapi_dirs = '../midori'
|
||||
obj.packages = 'glib-2.0 gio-2.0 libsoup-2.4 midori'
|
||||
if bld.env['HAVE_GTK3']:
|
||||
obj.packages += ' gtk+-3.0 webkitgtk-3.0'
|
||||
else:
|
||||
|
|
Before Width: | Height: | Size: 832 B After Width: | Height: | Size: 832 B |
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
|
@ -41,4 +41,4 @@ def add_image (bld, category, name):
|
|||
|
||||
add_image (bld, 'categories', 'extension')
|
||||
add_image (bld, 'apps', 'midori')
|
||||
add_image (bld, 'status', 'internet-news-reader')
|
||||
add_image (bld, 'status', 'news-feed')
|
||||
|
|
|
@ -27,9 +27,9 @@ sokoke_on_entry_focus_in_event (GtkEntry* entry,
|
|||
g_object_get_data (G_OBJECT (entry), "sokoke_has_default"));
|
||||
if (has_default)
|
||||
{
|
||||
gtk_entry_set_text (entry, "");
|
||||
g_object_set_data (G_OBJECT (entry), "sokoke_has_default",
|
||||
GINT_TO_POINTER (0));
|
||||
gtk_entry_set_text (entry, "");
|
||||
sokoke_widget_set_pango_font_style (GTK_WIDGET (entry),
|
||||
PANGO_STYLE_NORMAL);
|
||||
}
|
||||
|
@ -46,9 +46,9 @@ sokoke_on_entry_focus_out_event (GtkEntry* entry,
|
|||
{
|
||||
const gchar* default_text = (const gchar*)g_object_get_data (
|
||||
G_OBJECT (entry), "sokoke_default_text");
|
||||
gtk_entry_set_text (entry, default_text);
|
||||
g_object_set_data (G_OBJECT (entry),
|
||||
"sokoke_has_default", GINT_TO_POINTER (1));
|
||||
gtk_entry_set_text (entry, default_text);
|
||||
sokoke_widget_set_pango_font_style (GTK_WIDGET (entry),
|
||||
PANGO_STYLE_ITALIC);
|
||||
}
|
||||
|
@ -71,15 +71,14 @@ 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);
|
||||
|
||||
if (default_text == NULL)
|
||||
g_object_set_data (G_OBJECT (entry), "sokoke_has_default", GINT_TO_POINTER (0));
|
||||
else if (!old_value)
|
||||
gchar* old_value = g_object_get_data (G_OBJECT (entry),
|
||||
"sokoke_default_text");
|
||||
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);
|
||||
|
@ -90,19 +89,55 @@ 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const gchar*
|
||||
gtk_entry_get_placeholder_text (GtkEntry* entry)
|
||||
{
|
||||
return g_object_get_data (G_OBJECT (entry), "sokoke_default_text");
|
||||
g_object_set_data (G_OBJECT (entry), "sokoke_default_text",
|
||||
(gpointer)default_text);
|
||||
}
|
||||
#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
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#if GTK_CHECK_VERSION (3, 2, 0) && defined (GTK_DISABLE_DEPRECATED)
|
||||
#if GTK_CHECK_VERSION (3, 2, 0)
|
||||
#define GTK_TYPE_VBOX GTK_TYPE_BOX
|
||||
#define GtkVBox GtkBox
|
||||
#define GtkVBoxClass GtkBoxClass
|
||||
|
@ -39,6 +39,25 @@ 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)
|
||||
|
@ -70,10 +89,24 @@ G_BEGIN_DECLS
|
|||
|
||||
#if !GTK_CHECK_VERSION (3, 2, 0) && defined (HAVE_HILDON_2_2)
|
||||
#define gtk_entry_set_placeholder_text hildon_gtk_entry_set_placeholder_text
|
||||
#define gtk_entry_get_placeholder_text hildon_gtk_entry_get_placeholder_text
|
||||
#elif !GTK_CHECK_VERSION (3, 2, 0)
|
||||
void gtk_entry_set_placeholder_text (GtkEntry* entry, const gchar* text);
|
||||
const gchar* gtk_entry_get_placeholder_text (GtkEntry* entry);
|
||||
#define gtk_entry_set_placeholder_text sokoke_entry_set_default_text
|
||||
#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)
|
||||
|
@ -116,10 +149,6 @@ G_BEGIN_DECLS
|
|||
#define GDK_KEY_Return GDK_Return
|
||||
#endif
|
||||
|
||||
#ifndef GDK_IS_X11_DISPLAY
|
||||
#define GDK_IS_X11_DISPLAY(display) TRUE
|
||||
#endif
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif
|
||||
|
|
|
@ -74,13 +74,6 @@ GList* kalistglobal;
|
|||
static void
|
||||
katze_array_finalize (GObject* object);
|
||||
|
||||
static void
|
||||
_katze_array_update (KatzeArray* array)
|
||||
{
|
||||
g_object_set_data (G_OBJECT (array), "last-update",
|
||||
GINT_TO_POINTER (time (NULL)));
|
||||
}
|
||||
|
||||
static void
|
||||
_katze_array_add_item (KatzeArray* array,
|
||||
gpointer item)
|
||||
|
@ -91,7 +84,6 @@ _katze_array_add_item (KatzeArray* array,
|
|||
katze_item_set_parent (item, array);
|
||||
|
||||
array->items = g_list_append (array->items, item);
|
||||
_katze_array_update (array);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -103,7 +95,6 @@ _katze_array_remove_item (KatzeArray* array,
|
|||
if (KATZE_IS_ITEM (item))
|
||||
katze_item_set_parent (item, NULL);
|
||||
g_object_unref (item);
|
||||
_katze_array_update (array);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -113,7 +104,6 @@ _katze_array_move_item (KatzeArray* array,
|
|||
{
|
||||
array->items = g_list_remove (array->items, item);
|
||||
array->items = g_list_insert (array->items, item, position);
|
||||
_katze_array_update (array);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -122,10 +112,9 @@ _katze_array_clear (KatzeArray* array)
|
|||
GObject* item;
|
||||
|
||||
while ((item = g_list_nth_data (array->items, 0)))
|
||||
g_signal_emit (array, signals[REMOVE_ITEM], 0, item);
|
||||
katze_array_remove_item (array, item);
|
||||
g_list_free (array->items);
|
||||
array->items = NULL;
|
||||
_katze_array_update (array);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -203,7 +192,7 @@ katze_array_class_init (KatzeArrayClass* class)
|
|||
"update",
|
||||
G_TYPE_FROM_CLASS (class),
|
||||
(GSignalFlags)(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION),
|
||||
G_STRUCT_OFFSET (KatzeArrayClass, update),
|
||||
0,
|
||||
0,
|
||||
NULL,
|
||||
g_cclosure_marshal_VOID__VOID,
|
||||
|
@ -216,7 +205,6 @@ katze_array_class_init (KatzeArrayClass* class)
|
|||
class->remove_item = _katze_array_remove_item;
|
||||
class->move_item = _katze_array_move_item;
|
||||
class->clear = _katze_array_clear;
|
||||
class->update = _katze_array_update;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -229,11 +217,14 @@ katze_array_init (KatzeArray* array)
|
|||
static void
|
||||
katze_array_finalize (GObject* object)
|
||||
{
|
||||
KatzeArray* array = KATZE_ARRAY (object);
|
||||
GList* items;
|
||||
KatzeArray* array;
|
||||
guint i;
|
||||
gpointer item;
|
||||
|
||||
for (items = array->items; items; items = g_list_next (items))
|
||||
g_object_unref (items->data);
|
||||
array = KATZE_ARRAY (object);
|
||||
i = 0;
|
||||
while ((item = g_list_nth_data (array->items, i++)))
|
||||
g_object_unref (item);
|
||||
g_list_free (array->items);
|
||||
|
||||
G_OBJECT_CLASS (katze_array_parent_class)->finalize (object);
|
||||
|
@ -373,44 +364,37 @@ katze_array_get_item_index (KatzeArray* array,
|
|||
/**
|
||||
* katze_array_find_token:
|
||||
* @array: a #KatzeArray
|
||||
* @token: a token string, or "token keywords" string
|
||||
* @token: a token string
|
||||
*
|
||||
* Looks up an item in the array which has the specified token.
|
||||
*
|
||||
* This function will fail if the type of the list
|
||||
* is not based on #KatzeItem children.
|
||||
* This function will silently fail if the type of the list
|
||||
* is not based on #GObject and only #KatzeItem children
|
||||
* are checked for their token, any other objects are skipped.
|
||||
*
|
||||
* Note that @token is by definition unique to one item.
|
||||
*
|
||||
* Since 0.4.4 @token can be a "token keywords" string.
|
||||
*
|
||||
* Return value: an item, or %NULL
|
||||
**/
|
||||
gpointer
|
||||
katze_array_find_token (KatzeArray* array,
|
||||
const gchar* token)
|
||||
{
|
||||
goffset token_length;
|
||||
GList* items;
|
||||
guint i;
|
||||
gpointer item;
|
||||
|
||||
g_return_val_if_fail (KATZE_IS_ARRAY (array), NULL);
|
||||
g_return_val_if_fail (katze_array_is_a (array, KATZE_TYPE_ITEM), NULL);
|
||||
g_return_val_if_fail (token != NULL, NULL);
|
||||
|
||||
token_length = strchr (token, ' ') - token;
|
||||
if (token_length < 1)
|
||||
token_length = strlen (token);
|
||||
|
||||
for (items = array->items; items; items = g_list_next (items))
|
||||
i = 0;
|
||||
while ((item = g_list_nth_data (array->items, i++)))
|
||||
{
|
||||
const gchar* found_token = ((KatzeItem*)items->data)->token;
|
||||
if (found_token != NULL)
|
||||
{
|
||||
guint bigger_item = strlen (found_token) > token_length ? strlen (found_token) : token_length;
|
||||
const gchar* found_token;
|
||||
|
||||
if (strncmp (token, found_token, bigger_item) == 0)
|
||||
return items->data;
|
||||
}
|
||||
if (!KATZE_IS_ITEM (item))
|
||||
continue;
|
||||
found_token = ((KatzeItem*)item)->token;
|
||||
if (!g_strcmp0 (found_token, token))
|
||||
return item;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
@ -422,8 +406,9 @@ katze_array_find_token (KatzeArray* array,
|
|||
*
|
||||
* Looks up an item in the array which has the specified URI.
|
||||
*
|
||||
* This function will fail if the type of the list
|
||||
* is not based on #KatzeItem children.
|
||||
* This function will silently fail if the type of the list
|
||||
* is not based on #GObject and only #KatzeItem children
|
||||
* are checked for their token, any other objects are skipped.
|
||||
*
|
||||
* Return value: an item, or %NULL
|
||||
*
|
||||
|
@ -433,17 +418,19 @@ gpointer
|
|||
katze_array_find_uri (KatzeArray* array,
|
||||
const gchar* uri)
|
||||
{
|
||||
GList* items;
|
||||
guint i;
|
||||
gpointer item;
|
||||
|
||||
g_return_val_if_fail (KATZE_IS_ARRAY (array), NULL);
|
||||
g_return_val_if_fail (katze_array_is_a (array, KATZE_TYPE_ITEM), NULL);
|
||||
g_return_val_if_fail (uri != NULL, NULL);
|
||||
|
||||
for (items = array->items; items; items = g_list_next (items))
|
||||
i = 0;
|
||||
while ((item = g_list_nth_data (array->items, i++)))
|
||||
{
|
||||
const gchar* found_uri = ((KatzeItem*)items->data)->uri;
|
||||
if (found_uri != NULL && !strcmp (found_uri, uri))
|
||||
return items->data;
|
||||
const gchar* found_uri;
|
||||
|
||||
if (!KATZE_IS_ITEM (item))
|
||||
continue;
|
||||
found_uri = ((KatzeItem*)item)->uri;
|
||||
if (!g_strcmp0 (found_uri, uri))
|
||||
return item;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
@ -355,16 +355,11 @@ katze_array_action_generate_menu (KatzeArrayAction* array_action,
|
|||
gint summand;
|
||||
KatzeItem* item;
|
||||
GtkWidget* menuitem;
|
||||
const gchar* icon_name;
|
||||
GdkPixbuf* icon;
|
||||
GtkWidget* image;
|
||||
GtkWidget* submenu;
|
||||
|
||||
g_return_if_fail (KATZE_IS_ARRAY_ACTION (array_action));
|
||||
g_return_if_fail (KATZE_IS_ITEM (array));
|
||||
g_return_if_fail (GTK_IS_MENU_SHELL (menu));
|
||||
g_return_if_fail (GTK_IS_TOOL_ITEM (proxy)
|
||||
|| GTK_IS_MENU_ITEM (proxy)
|
||||
|| GTK_IS_WINDOW (proxy));
|
||||
|
||||
if (!KATZE_IS_ARRAY (array))
|
||||
return;
|
||||
|
||||
|
@ -390,7 +385,18 @@ katze_array_action_generate_menu (KatzeArrayAction* array_action,
|
|||
}
|
||||
menuitem = katze_image_menu_item_new_ellipsized (
|
||||
katze_item_get_name (item));
|
||||
image = katze_item_get_image (item);
|
||||
if ((icon_name = katze_item_get_icon (item)) && *icon_name)
|
||||
image = gtk_image_new_from_icon_name (icon_name, GTK_ICON_SIZE_MENU);
|
||||
else
|
||||
{
|
||||
if (KATZE_ITEM_IS_FOLDER (item))
|
||||
icon = gtk_widget_render_icon (menuitem,
|
||||
GTK_STOCK_DIRECTORY, GTK_ICON_SIZE_MENU, NULL);
|
||||
else
|
||||
icon = katze_load_cached_icon (katze_item_get_uri (item), proxy);
|
||||
image = gtk_image_new_from_pixbuf (icon);
|
||||
g_object_unref (icon);
|
||||
}
|
||||
gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menuitem), image);
|
||||
gtk_image_menu_item_set_always_show_image (
|
||||
GTK_IMAGE_MENU_ITEM (menuitem), TRUE);
|
||||
|
@ -400,13 +406,8 @@ katze_array_action_generate_menu (KatzeArrayAction* array_action,
|
|||
{
|
||||
submenu = gtk_menu_new ();
|
||||
gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), submenu);
|
||||
/* Make sure menu appears to contain items */
|
||||
gtk_menu_shell_append (GTK_MENU_SHELL (submenu),
|
||||
gtk_separator_menu_item_new ());
|
||||
g_signal_connect (menuitem, "select",
|
||||
G_CALLBACK (katze_array_action_menu_item_select_cb), array_action);
|
||||
g_signal_connect (menuitem, "activate",
|
||||
G_CALLBACK (katze_array_action_menu_item_select_cb), array_action);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -420,39 +421,21 @@ katze_array_action_generate_menu (KatzeArrayAction* array_action,
|
|||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
katze_array_action_menu_item_need_update (KatzeArrayAction* array_action,
|
||||
GtkWidget* proxy)
|
||||
{
|
||||
GtkWidget* menu;
|
||||
KatzeArray* array;
|
||||
gint last_array_update, last_proxy_update;
|
||||
gboolean handled;
|
||||
|
||||
array = g_object_get_data (G_OBJECT (proxy), "KatzeItem");
|
||||
/* last-update is set on all arrays; consider public API */
|
||||
last_array_update = GPOINTER_TO_INT (
|
||||
g_object_get_data (G_OBJECT (array), "last-update"));
|
||||
last_proxy_update = GPOINTER_TO_INT (
|
||||
g_object_get_data (G_OBJECT (proxy), "last-update"));
|
||||
if (last_proxy_update > last_array_update)
|
||||
return FALSE;
|
||||
|
||||
menu = gtk_menu_item_get_submenu (GTK_MENU_ITEM (proxy));
|
||||
gtk_container_foreach (GTK_CONTAINER (menu),
|
||||
(GtkCallback)(gtk_widget_destroy), NULL);
|
||||
katze_array_action_generate_menu (array_action, array, GTK_MENU_SHELL (menu), proxy);
|
||||
g_signal_emit (array_action, signals[POPULATE_FOLDER], 0, menu, array, &handled);
|
||||
g_object_set_data (G_OBJECT (proxy), "last-update",
|
||||
GINT_TO_POINTER (time (NULL)));
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
katze_array_action_menu_item_select_cb (GtkWidget* proxy,
|
||||
KatzeArrayAction* array_action)
|
||||
{
|
||||
katze_array_action_menu_item_need_update (array_action, proxy);
|
||||
GtkWidget* menu;
|
||||
KatzeArray* array;
|
||||
gboolean handled;
|
||||
|
||||
menu = gtk_menu_item_get_submenu (GTK_MENU_ITEM (proxy));
|
||||
gtk_container_foreach (GTK_CONTAINER (menu),
|
||||
(GtkCallback)(gtk_widget_destroy), NULL);
|
||||
|
||||
array = g_object_get_data (G_OBJECT (proxy), "KatzeItem");
|
||||
katze_array_action_generate_menu (array_action, array, GTK_MENU_SHELL (menu), proxy);
|
||||
g_signal_emit (array_action, signals[POPULATE_FOLDER], 0, menu, array, &handled);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -475,21 +458,20 @@ katze_array_action_proxy_clicked_cb (GtkWidget* proxy,
|
|||
KatzeArray* array;
|
||||
gboolean handled = FALSE;
|
||||
|
||||
array = (KatzeArray*)g_object_get_data (G_OBJECT (proxy), "KatzeItem");
|
||||
if (GTK_IS_MENU_ITEM (proxy))
|
||||
{
|
||||
if (katze_array_action_menu_item_need_update (array_action, proxy))
|
||||
{
|
||||
g_object_set_data (G_OBJECT (proxy), "KatzeItem", array_action->array);
|
||||
katze_array_action_menu_item_select_cb (proxy, array_action);
|
||||
g_signal_emit (array_action, signals[POPULATE_FOLDER], 0,
|
||||
gtk_menu_item_get_submenu (GTK_MENU_ITEM (proxy)),
|
||||
array, &handled);
|
||||
array_action->array, &handled);
|
||||
if (!handled)
|
||||
g_signal_emit (array_action, signals[POPULATE_POPUP], 0,
|
||||
gtk_menu_item_get_submenu (GTK_MENU_ITEM (proxy)));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
array = (KatzeArray*)g_object_get_data (G_OBJECT (proxy), "KatzeArray");
|
||||
if (KATZE_IS_ITEM (array) && katze_item_get_uri ((KatzeItem*)array))
|
||||
{
|
||||
katze_array_action_activate_item (array_action, KATZE_ITEM (array), 1);
|
||||
|
@ -570,6 +552,7 @@ katze_array_action_item_notify_cb (KatzeItem* item,
|
|||
const gchar* property;
|
||||
const gchar* title;
|
||||
const gchar* desc;
|
||||
GdkPixbuf* icon;
|
||||
GtkWidget* image;
|
||||
|
||||
if (!G_IS_PARAM_SPEC_STRING (pspec))
|
||||
|
@ -596,13 +579,16 @@ katze_array_action_item_notify_cb (KatzeItem* item,
|
|||
}
|
||||
else if (KATZE_ITEM_IS_BOOKMARK (item) && !strcmp (property, "uri"))
|
||||
{
|
||||
image = katze_item_get_image (item);
|
||||
icon = katze_load_cached_icon (katze_item_get_uri (item), GTK_WIDGET (toolitem));
|
||||
image = gtk_image_new_from_pixbuf (icon);
|
||||
g_object_unref (icon);
|
||||
gtk_widget_show (image);
|
||||
gtk_tool_button_set_icon_widget (GTK_TOOL_BUTTON (toolitem), image);
|
||||
}
|
||||
else if (!strcmp (property, "icon"))
|
||||
{
|
||||
image = katze_item_get_image (item);
|
||||
image = gtk_image_new_from_icon_name (katze_item_get_icon (item),
|
||||
GTK_ICON_SIZE_MENU);
|
||||
gtk_widget_show (image);
|
||||
gtk_tool_button_set_icon_widget (GTK_TOOL_BUTTON (toolitem), image);
|
||||
}
|
||||
|
@ -614,12 +600,25 @@ katze_array_action_proxy_create_menu_proxy_cb (GtkWidget* proxy,
|
|||
{
|
||||
KatzeArrayAction* array_action;
|
||||
GtkWidget* menuitem;
|
||||
const gchar* icon_name;
|
||||
GtkWidget* image;
|
||||
GdkPixbuf* icon;
|
||||
|
||||
array_action = g_object_get_data (G_OBJECT (proxy), "KatzeArrayAction");
|
||||
menuitem = katze_image_menu_item_new_ellipsized (
|
||||
katze_item_get_name (item));
|
||||
image = katze_item_get_image (item);
|
||||
if ((icon_name = katze_item_get_icon (item)) && *icon_name)
|
||||
image = gtk_image_new_from_icon_name (icon_name, GTK_ICON_SIZE_MENU);
|
||||
else
|
||||
{
|
||||
if (KATZE_ITEM_IS_FOLDER (item))
|
||||
icon = gtk_widget_render_icon (menuitem,
|
||||
GTK_STOCK_DIRECTORY, GTK_ICON_SIZE_MENU, NULL);
|
||||
else
|
||||
icon = katze_load_cached_icon (katze_item_get_uri (item), proxy);
|
||||
image = gtk_image_new_from_pixbuf (icon);
|
||||
g_object_unref (icon);
|
||||
}
|
||||
gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menuitem), image);
|
||||
gtk_image_menu_item_set_always_show_image (
|
||||
GTK_IMAGE_MENU_ITEM (menuitem), TRUE);
|
||||
|
@ -675,6 +674,7 @@ katze_array_action_create_tool_item_for (KatzeArrayAction* array_action,
|
|||
const gchar* uri;
|
||||
const gchar* desc;
|
||||
GtkToolItem* toolitem;
|
||||
GdkPixbuf* icon;
|
||||
GtkWidget* image;
|
||||
GtkWidget* label;
|
||||
|
||||
|
@ -686,12 +686,20 @@ katze_array_action_create_tool_item_for (KatzeArrayAction* array_action,
|
|||
return gtk_separator_tool_item_new ();
|
||||
|
||||
if (KATZE_ITEM_IS_FOLDER (item))
|
||||
{
|
||||
toolitem = gtk_toggle_tool_button_new ();
|
||||
icon = gtk_widget_render_icon (GTK_WIDGET (toolitem),
|
||||
GTK_STOCK_DIRECTORY, GTK_ICON_SIZE_MENU, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
toolitem = gtk_tool_button_new (NULL, "");
|
||||
icon = katze_load_cached_icon (uri, GTK_WIDGET (toolitem));
|
||||
}
|
||||
g_signal_connect (toolitem, "create-menu-proxy",
|
||||
G_CALLBACK (katze_array_action_proxy_create_menu_proxy_cb), item);
|
||||
image = katze_item_get_image (item);
|
||||
image = gtk_image_new_from_pixbuf (icon);
|
||||
g_object_unref (icon);
|
||||
gtk_widget_show (image);
|
||||
gtk_tool_button_set_icon_widget (GTK_TOOL_BUTTON (toolitem), image);
|
||||
label = gtk_label_new (NULL);
|
||||
|
@ -731,9 +739,6 @@ static void
|
|||
katze_array_action_connect_proxy (GtkAction* action,
|
||||
GtkWidget* proxy)
|
||||
{
|
||||
KatzeArrayAction* array_action = KATZE_ARRAY_ACTION (action);
|
||||
g_object_set_data (G_OBJECT (proxy), "KatzeItem", array_action->array);
|
||||
|
||||
GTK_ACTION_CLASS (katze_array_action_parent_class)->connect_proxy (
|
||||
action, proxy);
|
||||
|
||||
|
@ -745,10 +750,9 @@ katze_array_action_connect_proxy (GtkAction* action,
|
|||
else if (GTK_IS_MENU_ITEM (proxy))
|
||||
{
|
||||
gtk_menu_item_set_submenu (GTK_MENU_ITEM (proxy), gtk_menu_new ());
|
||||
/* FIXME: 'select' doesn't cover all ways of selection */
|
||||
g_signal_connect (proxy, "select",
|
||||
G_CALLBACK (katze_array_action_proxy_clicked_cb), action);
|
||||
g_signal_connect (proxy, "activate",
|
||||
G_CALLBACK (katze_array_action_proxy_clicked_cb), action);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
#include <sqlite3.h>
|
||||
|
||||
#define QUERY_ALL "SELECT id, name, value, host, path, expiry, lastAccessed, isSecure, isHttpOnly FROM moz_cookies;"
|
||||
#define CREATE_TABLE "CREATE TABLE IF NOT EXISTS moz_cookies (id INTEGER PRIMARY KEY, name TEXT, value TEXT, host TEXT, path TEXT,expiry INTEGER, lastAccessed INTEGER, isSecure INTEGER, isHttpOnly INTEGER)"
|
||||
#define CREATE_TABLE "CREATE TABLE moz_cookies (id INTEGER PRIMARY KEY, name TEXT, value TEXT, host TEXT, path TEXT,expiry INTEGER, lastAccessed INTEGER, isSecure INTEGER, isHttpOnly INTEGER)"
|
||||
#define QUERY_INSERT "INSERT INTO moz_cookies VALUES(NULL, %Q, %Q, %Q, %Q, %d, NULL, %d, %d);"
|
||||
#define QUERY_DELETE "DELETE FROM moz_cookies WHERE name=%Q AND host=%Q;"
|
||||
|
||||
|
@ -71,6 +71,80 @@ G_DEFINE_TYPE_WITH_CODE (KatzeHttpCookiesSqlite, katze_http_cookies_sqlite, G_TY
|
|||
Copyright (C) 2009 Collabora Ltd.
|
||||
Mostly copied from libSoup 2.30, coding style retained */
|
||||
|
||||
static void
|
||||
try_create_table (sqlite3 *db)
|
||||
{
|
||||
char *error = NULL;
|
||||
|
||||
if (sqlite3_exec (db, CREATE_TABLE, NULL, NULL, &error)) {
|
||||
g_warning ("Failed to execute query: %s", error);
|
||||
sqlite3_free (error);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
exec_query_with_try_create_table (sqlite3* db,
|
||||
const char* sql,
|
||||
int (*callback)(void*,int,char**,char**),
|
||||
void *argument)
|
||||
{
|
||||
char *error = NULL;
|
||||
gboolean try_create = TRUE;
|
||||
|
||||
try_exec:
|
||||
if (sqlite3_exec (db, sql, callback, argument, &error)) {
|
||||
if (try_create) {
|
||||
try_create = FALSE;
|
||||
try_create_table (db);
|
||||
sqlite3_free (error);
|
||||
error = NULL;
|
||||
goto try_exec;
|
||||
} else {
|
||||
g_warning ("Failed to execute query: %s", error);
|
||||
sqlite3_free (error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
callback (void *data, int argc, char **argv, char **colname)
|
||||
{
|
||||
SoupCookie *cookie = NULL;
|
||||
SoupCookieJar *jar = SOUP_COOKIE_JAR (data);
|
||||
|
||||
char *name, *value, *host, *path;
|
||||
gint64 expire_time;
|
||||
time_t now;
|
||||
int max_age;
|
||||
gboolean http_only = FALSE, secure = FALSE;
|
||||
|
||||
now = time (NULL);
|
||||
|
||||
name = argv[COL_NAME];
|
||||
value = argv[COL_VALUE];
|
||||
host = argv[COL_HOST];
|
||||
path = argv[COL_PATH];
|
||||
expire_time = g_ascii_strtoull (argv[COL_EXPIRY], NULL, 10);
|
||||
|
||||
if (now >= expire_time)
|
||||
return 0;
|
||||
max_age = (expire_time - now <= G_MAXINT ? expire_time - now : G_MAXINT);
|
||||
|
||||
http_only = (g_strcmp0 (argv[COL_HTTP_ONLY], "1") == 0);
|
||||
secure = (g_strcmp0 (argv[COL_SECURE], "1") == 0);
|
||||
|
||||
cookie = soup_cookie_new (name, value, host, path, max_age);
|
||||
|
||||
if (secure)
|
||||
soup_cookie_set_secure (cookie, TRUE);
|
||||
if (http_only)
|
||||
soup_cookie_set_http_only (cookie, TRUE);
|
||||
|
||||
soup_cookie_jar_add_cookie (jar, cookie);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Follows sqlite3 convention; returns TRUE on error */
|
||||
static gboolean
|
||||
katze_http_cookies_sqlite_open_db (KatzeHttpCookiesSqlite* http_cookies)
|
||||
|
@ -83,91 +157,23 @@ katze_http_cookies_sqlite_open_db (KatzeHttpCookiesSqlite* http_cookies)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
if (sqlite3_exec (http_cookies->db, CREATE_TABLE, NULL, NULL, &error)) {
|
||||
if (sqlite3_exec (http_cookies->db, "PRAGMA synchronous = OFF; PRAGMA secure_delete = 1;", NULL, NULL, &error)) {
|
||||
g_warning ("Failed to execute query: %s", error);
|
||||
sqlite3_free (error);
|
||||
}
|
||||
|
||||
if (sqlite3_exec (http_cookies->db, "PRAGMA secure_delete = 1;",
|
||||
NULL, NULL, &error)) {
|
||||
g_warning ("Failed to execute query: %s", error);
|
||||
sqlite3_free (error);
|
||||
}
|
||||
|
||||
sqlite3_exec (http_cookies->db,
|
||||
/* Arguably cookies are like a cache, so performance over integrity */
|
||||
"PRAGMA synchronous = OFF; PRAGMA temp_store = MEMORY;"
|
||||
"PRAGMA count_changes = OFF; PRAGMA journal_mode = TRUNCATE;",
|
||||
NULL, NULL, &error);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
katze_http_cookies_sqlite_load (KatzeHttpCookiesSqlite* http_cookies)
|
||||
{
|
||||
const char *name, *value, *host, *path;
|
||||
sqlite3_stmt* stmt;
|
||||
SoupCookie *cookie = NULL;
|
||||
gint64 expire_time;
|
||||
time_t now;
|
||||
int max_age;
|
||||
gboolean http_only = FALSE, secure = FALSE;
|
||||
char *query;
|
||||
int result;
|
||||
|
||||
if (http_cookies->db == NULL) {
|
||||
if (katze_http_cookies_sqlite_open_db (http_cookies))
|
||||
return;
|
||||
}
|
||||
|
||||
sqlite3_prepare_v2 (http_cookies->db, QUERY_ALL, strlen (QUERY_ALL) + 1, &stmt, NULL);
|
||||
result = sqlite3_step (stmt);
|
||||
if (result != SQLITE_ROW)
|
||||
{
|
||||
if (result == SQLITE_ERROR)
|
||||
g_print (_("Failed to load cookies\n"));
|
||||
sqlite3_reset (stmt);
|
||||
return;
|
||||
}
|
||||
|
||||
while (result == SQLITE_ROW)
|
||||
{
|
||||
now = time (NULL);
|
||||
name = (const char*)sqlite3_column_text (stmt, COL_NAME);
|
||||
value = (const char*)sqlite3_column_text (stmt, COL_VALUE);
|
||||
host = (const char*)sqlite3_column_text (stmt, COL_HOST);
|
||||
path = (const char*)sqlite3_column_text (stmt, COL_PATH);
|
||||
expire_time = sqlite3_column_int64 (stmt,COL_EXPIRY);
|
||||
secure = sqlite3_column_int (stmt, COL_SECURE);
|
||||
http_only = sqlite3_column_int (stmt, COL_HTTP_ONLY);
|
||||
|
||||
if (now >= expire_time)
|
||||
{
|
||||
/* Cookie expired, remove it from database */
|
||||
query = sqlite3_mprintf (QUERY_DELETE, name, host);
|
||||
sqlite3_exec (http_cookies->db, QUERY_DELETE, NULL, NULL, NULL);
|
||||
sqlite3_free (query);
|
||||
result = sqlite3_step (stmt);
|
||||
continue;
|
||||
}
|
||||
max_age = (expire_time - now <= G_MAXINT ? expire_time - now : G_MAXINT);
|
||||
cookie = soup_cookie_new (name, value, host, path, max_age);
|
||||
|
||||
if (secure)
|
||||
soup_cookie_set_secure (cookie, TRUE);
|
||||
if (http_only)
|
||||
soup_cookie_set_http_only (cookie, TRUE);
|
||||
|
||||
soup_cookie_jar_add_cookie (http_cookies->jar, cookie);
|
||||
result = sqlite3_step (stmt);
|
||||
}
|
||||
|
||||
if (stmt)
|
||||
{
|
||||
sqlite3_reset (stmt);
|
||||
sqlite3_clear_bindings (stmt);
|
||||
}
|
||||
exec_query_with_try_create_table (http_cookies->db, QUERY_ALL, callback, http_cookies->jar);
|
||||
}
|
||||
static void
|
||||
katze_http_cookies_sqlite_jar_changed_cb (SoupCookieJar* jar,
|
||||
|
@ -207,14 +213,14 @@ katze_http_cookies_sqlite_jar_changed_cb (SoupCookieJar* jar,
|
|||
}
|
||||
}
|
||||
|
||||
if (!g_strcmp0 (g_getenv ("MIDORI_DEBUG"), "cookies"))
|
||||
if (g_getenv ("MIDORI_COOKIES_DEBUG") != NULL)
|
||||
http_cookies->counter++;
|
||||
|
||||
if (old_cookie) {
|
||||
query = sqlite3_mprintf (QUERY_DELETE,
|
||||
old_cookie->name,
|
||||
old_cookie->domain);
|
||||
sqlite3_exec (http_cookies->db, query, NULL, NULL, NULL);
|
||||
exec_query_with_try_create_table (http_cookies->db, query, NULL, NULL);
|
||||
sqlite3_free (query);
|
||||
}
|
||||
|
||||
|
@ -228,7 +234,7 @@ katze_http_cookies_sqlite_jar_changed_cb (SoupCookieJar* jar,
|
|||
expires,
|
||||
new_cookie->secure,
|
||||
new_cookie->http_only);
|
||||
sqlite3_exec (http_cookies->db, query, NULL, NULL, NULL);
|
||||
exec_query_with_try_create_table (http_cookies->db, query, NULL, NULL);
|
||||
sqlite3_free (query);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -211,7 +211,7 @@ katze_http_cookies_update_jar (KatzeHttpCookies* http_cookies)
|
|||
goto failed;
|
||||
g_free (temporary_filename);
|
||||
|
||||
if (!g_strcmp0 (g_getenv ("MIDORI_DEBUG"), "cookies"))
|
||||
if (g_getenv ("MIDORI_COOKIES_DEBUG") != NULL)
|
||||
{
|
||||
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_strcmp0 (g_getenv ("MIDORI_DEBUG"), "cookies"))
|
||||
if (g_getenv ("MIDORI_COOKIES_DEBUG") != NULL)
|
||||
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_strcmp0 (g_getenv ("MIDORI_DEBUG"), "cookies"))
|
||||
if (g_getenv ("MIDORI_COOKIES_DEBUG") != NULL)
|
||||
http_cookies->counter++;
|
||||
|
||||
if (!http_cookies->timeout && (old_cookie || new_cookie->expires))
|
||||
|
|
|
@ -15,8 +15,6 @@
|
|||
|
||||
#include <glib/gi18n.h>
|
||||
|
||||
#include <webkit/webkit.h>
|
||||
|
||||
/**
|
||||
* SECTION:katze-item
|
||||
* @short_description: A useful item
|
||||
|
@ -317,8 +315,6 @@ katze_item_set_name (KatzeItem* item,
|
|||
g_return_if_fail (KATZE_IS_ITEM (item));
|
||||
|
||||
katze_assign (item->name, g_strdup (name));
|
||||
if (item->parent)
|
||||
katze_array_update ((KatzeArray*)item->parent);
|
||||
g_object_notify (G_OBJECT (item), "name");
|
||||
}
|
||||
|
||||
|
@ -418,86 +414,9 @@ katze_item_set_icon (KatzeItem* item,
|
|||
g_return_if_fail (KATZE_IS_ITEM (item));
|
||||
|
||||
katze_item_set_meta_string (item, "icon", icon);
|
||||
if (item->parent)
|
||||
katze_array_update ((KatzeArray*)item->parent);
|
||||
g_object_notify (G_OBJECT (item), "icon");
|
||||
}
|
||||
|
||||
/**
|
||||
* katze_item_get_pixbuf:
|
||||
* @item: a #KatzeItem
|
||||
* @widget: a #GtkWidget, or %NULL
|
||||
*
|
||||
* Retrieves a #GdkPixbuf fit to display @item.
|
||||
*
|
||||
* Return value: the icon of the item
|
||||
*
|
||||
* Since: 0.4.6
|
||||
**/
|
||||
GdkPixbuf*
|
||||
katze_item_get_pixbuf (KatzeItem* item,
|
||||
GtkWidget* widget)
|
||||
{
|
||||
GdkPixbuf* pixbuf;
|
||||
|
||||
g_return_val_if_fail (KATZE_IS_ITEM (item), NULL);
|
||||
|
||||
if (item->uri == NULL)
|
||||
return NULL;
|
||||
|
||||
#if WEBKIT_CHECK_VERSION (1, 8, 0)
|
||||
/* FIXME: Don't hard-code icon size */
|
||||
if ((pixbuf = webkit_favicon_database_try_get_favicon_pixbuf (
|
||||
webkit_get_favicon_database (), item->uri, 16, 16)))
|
||||
return pixbuf;
|
||||
#else
|
||||
if ((pixbuf = g_object_get_data (G_OBJECT (item), "pixbuf")))
|
||||
return pixbuf;
|
||||
#endif
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* katze_item_get_image:
|
||||
* @item: a #KatzeItem
|
||||
*
|
||||
* Retrieves a #GtkImage fit to display @item.
|
||||
*
|
||||
* Return value: the icon of the item
|
||||
*
|
||||
* Since: 0.4.4
|
||||
**/
|
||||
GtkWidget*
|
||||
katze_item_get_image (KatzeItem* item)
|
||||
{
|
||||
GtkWidget* image;
|
||||
GdkPixbuf* pixbuf;
|
||||
const gchar* icon;
|
||||
|
||||
g_return_val_if_fail (KATZE_IS_ITEM (item), NULL);
|
||||
|
||||
if (KATZE_ITEM_IS_FOLDER (item))
|
||||
image = gtk_image_new_from_stock (GTK_STOCK_DIRECTORY, GTK_ICON_SIZE_MENU);
|
||||
/* FIXME: Pass widget for icon size */
|
||||
else if ((pixbuf = katze_item_get_pixbuf (item, NULL)))
|
||||
image = gtk_image_new_from_pixbuf (pixbuf);
|
||||
else if ((icon = katze_item_get_icon (item)) && !strchr (icon, '/'))
|
||||
image = gtk_image_new_from_icon_name (icon, GTK_ICON_SIZE_MENU);
|
||||
else
|
||||
{
|
||||
if (!(icon && (pixbuf = katze_load_cached_icon (icon, NULL))))
|
||||
pixbuf = katze_load_cached_icon (item->uri, NULL);
|
||||
if (pixbuf)
|
||||
{
|
||||
image = gtk_image_new_from_pixbuf (pixbuf);
|
||||
g_object_unref (pixbuf);
|
||||
}
|
||||
else
|
||||
image = gtk_image_new_from_stock (GTK_STOCK_FILE, GTK_ICON_SIZE_MENU);
|
||||
}
|
||||
return image;
|
||||
}
|
||||
|
||||
/**
|
||||
* katze_item_get_token:
|
||||
* @item: a #KatzeItem
|
||||
|
@ -608,22 +527,17 @@ katze_item_set_meta_data_value (KatzeItem* item,
|
|||
* Return value: a string, or %NULL
|
||||
*
|
||||
* Since: 0.1.8
|
||||
*
|
||||
* Since 0.4.4 "" is treated like %NULL.
|
||||
**/
|
||||
const gchar*
|
||||
katze_item_get_meta_string (KatzeItem* item,
|
||||
const gchar* key)
|
||||
{
|
||||
const gchar* value;
|
||||
|
||||
g_return_val_if_fail (KATZE_IS_ITEM (item), NULL);
|
||||
g_return_val_if_fail (key != NULL, NULL);
|
||||
|
||||
if (g_str_has_prefix (key, "midori:"))
|
||||
key = &key[7];
|
||||
value = g_hash_table_lookup (item->metadata, key);
|
||||
return value && *value ? value : NULL;
|
||||
return g_hash_table_lookup (item->metadata, key);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
#ifndef __KATZE_ITEM_H__
|
||||
#define __KATZE_ITEM_H__
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
#include <glib-object.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
|
@ -91,13 +91,6 @@ void
|
|||
katze_item_set_icon (KatzeItem* item,
|
||||
const gchar* icon);
|
||||
|
||||
GdkPixbuf*
|
||||
katze_item_get_pixbuf (KatzeItem* item,
|
||||
GtkWidget* widget);
|
||||
|
||||
GtkWidget*
|
||||
katze_item_get_image (KatzeItem* item);
|
||||
|
||||
const gchar*
|
||||
katze_item_get_token (KatzeItem* item);
|
||||
|
||||
|
|
|
@ -27,6 +27,9 @@
|
|||
struct _KatzeNet
|
||||
{
|
||||
GObject parent_instance;
|
||||
|
||||
gchar* cache_path;
|
||||
guint cache_size;
|
||||
};
|
||||
|
||||
struct _KatzeNetClass
|
||||
|
@ -51,14 +54,37 @@ 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;
|
||||
|
@ -83,28 +109,29 @@ 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);
|
||||
|
||||
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);
|
||||
if (subfolder)
|
||||
g_free (cache_path);
|
||||
return cached_path;
|
||||
}
|
||||
|
||||
|
|
|
@ -14,6 +14,8 @@
|
|||
|
||||
#include "katze-utils.h"
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define KATZE_TYPE_NET \
|
||||
|
|
|
@ -15,13 +15,6 @@
|
|||
#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>
|
||||
|
@ -110,8 +103,11 @@ katze_preferences_init (KatzePreferences* preferences)
|
|||
gtk_dialog_add_buttons (GTK_DIALOG (preferences),
|
||||
GTK_STOCK_HELP, GTK_RESPONSE_HELP,
|
||||
NULL);
|
||||
katze_widget_add_class (gtk_dialog_get_widget_for_response (
|
||||
GTK_DIALOG (preferences), GTK_RESPONSE_HELP), "help_button");
|
||||
#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
|
||||
|
||||
gtk_dialog_add_buttons (GTK_DIALOG (preferences),
|
||||
#if HAVE_HILDON
|
||||
|
@ -206,12 +202,7 @@ 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
|
||||
|
@ -305,14 +296,8 @@ 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 (
|
||||
|
|
|
@ -97,8 +97,8 @@ katze_throbber_realize (GtkWidget* widget);
|
|||
#if GTK_CHECK_VERSION (3, 0, 0)
|
||||
static void
|
||||
katze_throbber_get_preferred_height (GtkWidget *widget,
|
||||
gint *minimal_height,
|
||||
gint *natural_height);
|
||||
gint *minimal_width,
|
||||
gint *natural_width);
|
||||
static void
|
||||
katze_throbber_get_preferred_width (GtkWidget *widget,
|
||||
gint *minimal_width,
|
||||
|
@ -495,8 +495,8 @@ katze_throbber_set_animated (KatzeThrobber* throbber,
|
|||
(GSourceFunc)katze_throbber_timeout,
|
||||
throbber,
|
||||
(GDestroyNotify)katze_throbber_timeout_destroy);
|
||||
#endif
|
||||
gtk_widget_queue_draw (GTK_WIDGET (throbber));
|
||||
#endif
|
||||
|
||||
g_object_notify (G_OBJECT (throbber), "animated");
|
||||
}
|
||||
|
@ -857,14 +857,14 @@ katze_throbber_size_request (GtkWidget* widget,
|
|||
#if GTK_CHECK_VERSION (3, 0, 0)
|
||||
static void
|
||||
katze_throbber_get_preferred_height (GtkWidget *widget,
|
||||
gint *minimal_height,
|
||||
gint *natural_height)
|
||||
gint *minimal_width,
|
||||
gint *natural_width)
|
||||
{
|
||||
GtkRequisition requisition;
|
||||
|
||||
katze_throbber_size_request (widget, &requisition);
|
||||
|
||||
*minimal_height = *natural_height = requisition.height;
|
||||
*minimal_width = *natural_width = requisition.height;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -902,7 +902,6 @@ katze_throbber_aligned_coords (GtkWidget* widget,
|
|||
#endif
|
||||
|
||||
#if GTK_CHECK_VERSION (3, 0, 0)
|
||||
allocation.x = allocation.y = 0;
|
||||
allocation.width = gtk_widget_get_allocated_width (widget);
|
||||
allocation.height = gtk_widget_get_allocated_height (widget);
|
||||
gtk_widget_get_preferred_size (widget, &requisition, NULL);
|
||||
|
|
|
@ -277,6 +277,7 @@ 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
|
||||
|
@ -285,6 +286,7 @@ proxy_combo_box_changed_cb (GtkComboBox* button,
|
|||
gtk_widget_set_tooltip_text (GTK_WIDGET (button), custom_text);
|
||||
g_free (custom_text);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
@ -329,13 +331,7 @@ proxy_widget_string_destroy_cb (GtkWidget* proxy,
|
|||
static GList*
|
||||
katze_app_info_get_all_for_category (const gchar* category)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
/* FIXME: Real filtering by category would be better */
|
||||
const gchar* content_type = g_content_type_from_mime_type (category);
|
||||
GList* all_apps = g_app_info_get_all_for_type (content_type);
|
||||
#else
|
||||
GList* all_apps = g_app_info_get_all ();
|
||||
#endif
|
||||
GList* apps = NULL;
|
||||
guint i = 0;
|
||||
GAppInfo* info;
|
||||
|
@ -521,8 +517,14 @@ 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")))
|
||||
|
@ -810,10 +812,11 @@ 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);
|
||||
|
||||
|
@ -828,6 +831,10 @@ 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",
|
||||
|
@ -868,8 +875,16 @@ 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;
|
||||
|
@ -895,29 +910,21 @@ katze_widget_popup_position_menu (GtkMenu* menu,
|
|||
GtkRequisition widget_req;
|
||||
KatzePopupInfo* info = user_data;
|
||||
GtkWidget* widget = info->widget;
|
||||
GdkWindow* window = gtk_widget_get_window (widget);
|
||||
gint widget_height;
|
||||
|
||||
if (!window)
|
||||
return;
|
||||
|
||||
#if !GTK_CHECK_VERSION (3, 0, 0)
|
||||
if (GTK_IS_ENTRY (widget))
|
||||
window = gdk_window_get_parent (window);
|
||||
#endif
|
||||
gtk_widget_get_allocation (widget, &allocation);
|
||||
|
||||
/* Retrieve size and position of both widget and menu */
|
||||
gtk_widget_get_allocation (widget, &allocation);
|
||||
gdk_window_get_origin (window, &wx, &wy);
|
||||
if (!gtk_widget_get_has_window (widget))
|
||||
{
|
||||
gdk_window_get_position (gtk_widget_get_window (widget), &wx, &wy);
|
||||
wx += allocation.x;
|
||||
wy += allocation.y;
|
||||
#if GTK_CHECK_VERSION (3, 0, 0)
|
||||
gtk_widget_get_preferred_size (GTK_WIDGET (menu), &menu_req, NULL);
|
||||
gtk_widget_get_preferred_size (widget, &widget_req, NULL);
|
||||
#else
|
||||
}
|
||||
else
|
||||
gdk_window_get_origin (gtk_widget_get_window (widget), &wx, &wy);
|
||||
gtk_widget_size_request (GTK_WIDGET (menu), &menu_req);
|
||||
gtk_widget_size_request (widget, &widget_req);
|
||||
#endif
|
||||
menu_width = menu_req.width;
|
||||
widget_height = widget_req.height; /* Better than allocation.height */
|
||||
|
||||
|
@ -1183,16 +1190,6 @@ katze_strip_mnemonics (const gchar* original)
|
|||
return result;
|
||||
}
|
||||
|
||||
const gchar*
|
||||
katze_skip_whitespace (const gchar* str)
|
||||
{
|
||||
if (str == NULL)
|
||||
return NULL;
|
||||
while (*str == ' ' || *str == '\t' || *str == '\n')
|
||||
str++;
|
||||
return str;
|
||||
}
|
||||
|
||||
/**
|
||||
* katze_object_has_property:
|
||||
* @object: a #GObject
|
||||
|
@ -1502,7 +1499,8 @@ 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 (midori_paths_get_cache_dir (), "icons", filename, NULL);
|
||||
path = g_build_filename (g_get_user_cache_dir (), PACKAGE_NAME,
|
||||
"icons", filename, NULL);
|
||||
g_free (filename);
|
||||
if ((icon = gdk_pixbuf_new_from_file_at_size (path, 16, 16, NULL)))
|
||||
{
|
||||
|
@ -1522,15 +1520,6 @@ katze_uri_entry_changed_cb (GtkWidget* entry,
|
|||
{
|
||||
const gchar* uri = gtk_entry_get_text (GTK_ENTRY (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 };
|
||||
|
@ -1545,34 +1534,11 @@ 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
|
||||
|
@ -1590,28 +1556,11 @@ 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
|
||||
|
|
|
@ -58,20 +58,6 @@ G_BEGIN_DECLS
|
|||
**/
|
||||
#define katze_strv_assign(lvalue, rvalue) lvalue = (g_strfreev (lvalue), rvalue)
|
||||
|
||||
/**
|
||||
* katze_str_non_null:
|
||||
* @str: a string, or %NULL
|
||||
*
|
||||
* Returns "" if @str is %NULL.
|
||||
*
|
||||
* Since: 0.4.4
|
||||
**/
|
||||
static inline const gchar*
|
||||
katze_str_non_null (const gchar* str)
|
||||
{
|
||||
return str ? str : "";
|
||||
}
|
||||
|
||||
GtkWidget*
|
||||
katze_property_proxy (gpointer object,
|
||||
const gchar* property,
|
||||
|
@ -115,9 +101,6 @@ katze_bookmark_populate_tree_view (KatzeArray* array,
|
|||
gchar*
|
||||
katze_strip_mnemonics (const gchar* original);
|
||||
|
||||
const gchar*
|
||||
katze_skip_whitespace (const gchar* str);
|
||||
|
||||
gboolean
|
||||
katze_object_has_property (gpointer object,
|
||||
const gchar* property);
|
||||
|
@ -160,10 +143,6 @@ 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,
|
||||
|
|
|
@ -1,25 +0,0 @@
|
|||
/* Copyright (C) 2012 André Stösel <andre@stoesel.de>
|
||||
This file is licensed under the terms of the expat license, see the file EXPAT. */
|
||||
|
||||
[CCode (cprefix = "Katze", lower_case_cprefix = "katze_")]
|
||||
namespace Katze {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,143 +0,0 @@
|
|||
/*
|
||||
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 ());
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -1,244 +0,0 @@
|
|||
/*
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
|
@ -85,9 +85,6 @@ namespace Midori {
|
|||
if (uri == null)
|
||||
return keywords;
|
||||
string escaped = GLib.Uri.escape_string (keywords, ":/", true);
|
||||
/* Allow DuckDuckGo to distinguish Midori and in turn share revenue */
|
||||
if (uri == "https://duckduckgo.com/?q=%s")
|
||||
return "https://duckduckgo.com/?q=%s&t=midori".printf (escaped);
|
||||
if (uri.str ("%s") != null)
|
||||
return uri.printf (escaped);
|
||||
return uri + escaped;
|
||||
|
@ -114,69 +111,43 @@ 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
|
||||
hostname_is_ip_address () is not used because
|
||||
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] != '0' && uri[0].isdigit () && (uri.chr (4, '.') != null))
|
||||
return true;
|
||||
/* IPv6 */
|
||||
if (uri[0].isalnum () && uri[1].isalnum ()
|
||||
&& uri[2].isalnum () && uri[3].isalnum () && uri[4] == ':'
|
||||
&& (uri[5] == ':' || uri[5].isalnum ()))
|
||||
return true;
|
||||
return false;
|
||||
return uri != null && uri[0].isdigit ()
|
||||
&& (uri.chr (4, '.') != null || uri.chr (4, ':') != null);
|
||||
}
|
||||
public static bool is_valid (string? uri) {
|
||||
return uri != null
|
||||
&& 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) {
|
||||
display = _("MD5-Checksum:");
|
||||
type = GLib.ChecksumType.MD5;
|
||||
}
|
||||
|
||||
if (fragment == null) {
|
||||
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
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -26,6 +26,7 @@
|
|||
|
||||
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
|
||||
|
@ -41,9 +42,99 @@ 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
|
||||
|
||||
|
|
982
midori/main.c
982
midori/main.c
File diff suppressed because it is too large
Load diff
|
@ -6,7 +6,6 @@ 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
|
||||
|
|
|
@ -21,11 +21,9 @@
|
|||
|
||||
#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
|
||||
|
@ -70,6 +68,10 @@ struct _MidoriApp
|
|||
{
|
||||
GObject parent_instance;
|
||||
|
||||
MidoriBrowser* browser;
|
||||
GtkAccelGroup* accel_group;
|
||||
|
||||
gchar* name;
|
||||
MidoriWebSettings* settings;
|
||||
KatzeArray* bookmarks;
|
||||
KatzeArray* trash;
|
||||
|
@ -79,7 +81,6 @@ struct _MidoriApp
|
|||
KatzeArray* extensions;
|
||||
KatzeArray* browsers;
|
||||
|
||||
MidoriBrowser* browser;
|
||||
MidoriAppInstance instance;
|
||||
|
||||
#if !HAVE_HILDON || !HAVE_LIBNOTIFY
|
||||
|
@ -87,8 +88,6 @@ struct _MidoriApp
|
|||
#endif
|
||||
};
|
||||
|
||||
static gchar* app_name = NULL;
|
||||
|
||||
struct _MidoriAppClass
|
||||
{
|
||||
GObjectClass parent_class;
|
||||
|
@ -217,6 +216,7 @@ _midori_app_add_browser (MidoriApp* app,
|
|||
g_return_if_fail (MIDORI_IS_APP (app));
|
||||
g_return_if_fail (MIDORI_IS_BROWSER (browser));
|
||||
|
||||
gtk_window_add_accel_group (GTK_WINDOW (browser), app->accel_group);
|
||||
g_object_connect (browser,
|
||||
"signal::focus-in-event", midori_browser_focus_in_event_cb, app,
|
||||
"signal::new-window", midori_browser_new_window_cb, app,
|
||||
|
@ -229,32 +229,6 @@ _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
|
||||
|
@ -746,35 +720,25 @@ midori_app_create_instance (MidoriApp* app)
|
|||
GIOChannel* channel;
|
||||
#endif
|
||||
|
||||
if (!app->name)
|
||||
{
|
||||
const gchar* config = sokoke_set_config_dir (NULL);
|
||||
gchar* name_hash;
|
||||
name_hash = g_compute_checksum_for_string (G_CHECKSUM_MD5, config, -1);
|
||||
app->name = g_strconcat ("midori", "_", name_hash, NULL);
|
||||
g_free (name_hash);
|
||||
g_object_notify (G_OBJECT (app), "name");
|
||||
}
|
||||
|
||||
if (!(display = gdk_display_get_default ()))
|
||||
return MidoriAppInstanceNull;
|
||||
|
||||
{
|
||||
#if HAVE_UNIQUE
|
||||
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));
|
||||
g_free (name_hash);
|
||||
g_object_notify (G_OBJECT (app), "name");
|
||||
#else
|
||||
katze_assign (app_name, g_strdup (PACKAGE_NAME));
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef GDK_WINDOWING_X11
|
||||
/* On X11: :0 or :0.0 which is equivalent */
|
||||
display_name = g_strndup (gdk_display_get_name (display), 2);
|
||||
#else
|
||||
display_name = g_strdup (gdk_display_get_name (display));
|
||||
#endif
|
||||
n = strlen (display_name);
|
||||
for (i = 0; i < n; i++)
|
||||
if (strchr (":.\\/", display_name[i]))
|
||||
display_name[i] = '_';
|
||||
instance_name = g_strdup_printf ("de.twotoasts.%s_%s", app_name, display_name);
|
||||
g_free (display_name);
|
||||
katze_assign (app_name, instance_name);
|
||||
instance_name = g_strdup_printf ("de.twotoasts.%s_%s", app->name, display_name);
|
||||
|
||||
#if HAVE_UNIQUE
|
||||
instance = unique_app_new (instance_name, NULL);
|
||||
|
@ -782,7 +746,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, midori_paths_get_config_dir (), &exists);
|
||||
instance = socket_init (instance_name, sokoke_set_config_dir (NULL), &exists);
|
||||
g_object_set_data (G_OBJECT (app), "sock-exists",
|
||||
exists ? (gpointer)0xdeadbeef : NULL);
|
||||
if (instance != MidoriAppInstanceNull)
|
||||
|
@ -792,19 +756,19 @@ midori_app_create_instance (MidoriApp* app)
|
|||
(GIOFunc)midori_app_io_channel_watch_cb, app);
|
||||
}
|
||||
#endif
|
||||
|
||||
g_free (instance_name);
|
||||
g_free (display_name);
|
||||
|
||||
#endif
|
||||
return instance;
|
||||
}
|
||||
|
||||
const gchar*
|
||||
midori_app_get_name (MidoriApp* app)
|
||||
{
|
||||
return app_name;
|
||||
}
|
||||
|
||||
static void
|
||||
midori_app_init (MidoriApp* app)
|
||||
{
|
||||
app->accel_group = gtk_accel_group_new ();
|
||||
|
||||
app->settings = NULL;
|
||||
app->bookmarks = NULL;
|
||||
app->trash = NULL;
|
||||
|
@ -829,7 +793,9 @@ midori_app_finalize (GObject* object)
|
|||
{
|
||||
MidoriApp* app = MIDORI_APP (object);
|
||||
|
||||
katze_assign (app_name, NULL);
|
||||
g_object_unref (app->accel_group);
|
||||
|
||||
katze_assign (app->name, NULL);
|
||||
katze_object_assign (app->settings, NULL);
|
||||
katze_object_assign (app->bookmarks, NULL);
|
||||
katze_object_assign (app->trash, NULL);
|
||||
|
@ -869,7 +835,7 @@ midori_app_set_property (GObject* object,
|
|||
switch (prop_id)
|
||||
{
|
||||
case PROP_NAME:
|
||||
katze_assign (app_name, g_value_dup_string (value));
|
||||
katze_assign (app->name, g_value_dup_string (value));
|
||||
break;
|
||||
case PROP_SETTINGS:
|
||||
katze_object_assign (app->settings, g_value_dup_object (value));
|
||||
|
@ -909,7 +875,7 @@ midori_app_get_property (GObject* object,
|
|||
switch (prop_id)
|
||||
{
|
||||
case PROP_NAME:
|
||||
g_value_set_string (value, app_name);
|
||||
g_value_set_string (value, app->name);
|
||||
break;
|
||||
case PROP_SETTINGS:
|
||||
g_value_set_object (value, app->settings);
|
||||
|
@ -1145,19 +1111,7 @@ 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))
|
||||
{
|
||||
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
|
||||
if (!midori_app_instance_is_running (app))
|
||||
return midori_app_command_received (app, "command", command, NULL);
|
||||
|
||||
#if HAVE_HILDON
|
||||
|
@ -1350,39 +1304,144 @@ midori_app_send_notification (MidoriApp* app,
|
|||
*
|
||||
* Since: 0.4.2
|
||||
**/
|
||||
gboolean
|
||||
midori_app_setup (gint *argc,
|
||||
gchar** *argument_vector,
|
||||
const GOptionEntry *entries,
|
||||
GError* *error)
|
||||
void
|
||||
midori_app_setup (gchar** argument_vector)
|
||||
{
|
||||
GtkIconSource* icon_source;
|
||||
GtkIconSet* icon_set;
|
||||
GtkIconFactory* factory;
|
||||
gsize i;
|
||||
gboolean success;
|
||||
|
||||
static GtkStockItem items[] =
|
||||
typedef struct
|
||||
{
|
||||
{ STOCK_IMAGE },
|
||||
{ STOCK_WEB_BROWSER },
|
||||
{ STOCK_NEWS_FEED },
|
||||
{ STOCK_STYLE },
|
||||
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_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") },
|
||||
{ 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 },
|
||||
};
|
||||
|
||||
/* 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 (!g_thread_supported ()) g_thread_init (NULL);
|
||||
|
||||
#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
|
||||
|
@ -1405,90 +1464,5 @@ midori_app_setup (gint *argc,
|
|||
}
|
||||
}
|
||||
#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);
|
||||
}
|
||||
|
||||
|
|
|
@ -41,9 +41,6 @@ midori_app_get_type (void) G_GNUC_CONST;
|
|||
MidoriApp*
|
||||
midori_app_new (void);
|
||||
|
||||
const gchar*
|
||||
midori_app_get_name (MidoriApp* app);
|
||||
|
||||
gboolean
|
||||
midori_app_instance_is_running (MidoriApp* app);
|
||||
|
||||
|
@ -82,14 +79,8 @@ midori_app_send_notification (MidoriApp* app,
|
|||
const gchar* title,
|
||||
const gchar* message);
|
||||
|
||||
gboolean
|
||||
midori_app_setup (gint *argc,
|
||||
gchar** *argument_vector,
|
||||
const GOptionEntry *entries,
|
||||
GError* *error);
|
||||
|
||||
gboolean
|
||||
midori_debug (const gchar* token);
|
||||
void
|
||||
midori_app_setup (gchar** argument_vector);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
|
|
@ -982,26 +982,24 @@ 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, "id")
|
||||
|| g_str_equal (name, "parentid") || g_str_equal (name, "seq")
|
||||
|| g_str_equal (name, "pos_panel") || g_str_equal (name, "pos_bar"))
|
||||
|| g_str_equal (name, "toolbar"))
|
||||
{
|
||||
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 ();
|
||||
}
|
||||
|
@ -1068,74 +1066,6 @@ katze_array_from_sqlite (sqlite3* db,
|
|||
return katze_array_from_statement (stmt);
|
||||
}
|
||||
|
||||
/**
|
||||
* midori_array_query_recursive:
|
||||
* @array: the main bookmark array
|
||||
* @fields: comma separated list of fields
|
||||
* @condition: condition, like "folder = '%q'"
|
||||
* @value: a value to be inserted if @condition contains %q
|
||||
* @recursive: if %TRUE include children
|
||||
*
|
||||
* Stores the result in a #KatzeArray.
|
||||
*
|
||||
* Return value: a #KatzeArray on success, %NULL otherwise
|
||||
*
|
||||
* Since: 0.4.4
|
||||
**/
|
||||
KatzeArray*
|
||||
midori_array_query_recursive (KatzeArray* bookmarks,
|
||||
const gchar* fields,
|
||||
const gchar* condition,
|
||||
const gchar* value,
|
||||
gboolean recursive)
|
||||
{
|
||||
sqlite3* db;
|
||||
gchar* sqlcmd;
|
||||
char* sqlcmd_value;
|
||||
KatzeArray* array;
|
||||
KatzeItem* item;
|
||||
GList* list;
|
||||
|
||||
g_return_val_if_fail (KATZE_IS_ARRAY (bookmarks), NULL);
|
||||
g_return_val_if_fail (fields, NULL);
|
||||
g_return_val_if_fail (condition, NULL);
|
||||
db = g_object_get_data (G_OBJECT (bookmarks), "db");
|
||||
if (db == NULL)
|
||||
return NULL;
|
||||
|
||||
sqlcmd = g_strdup_printf ("SELECT %s FROM bookmarks WHERE %s "
|
||||
"ORDER BY (uri='') ASC, title DESC", fields, condition);
|
||||
if (strstr (condition, "%q"))
|
||||
{
|
||||
sqlcmd_value = sqlite3_mprintf (sqlcmd, value ? value : "");
|
||||
array = katze_array_from_sqlite (db, sqlcmd_value);
|
||||
sqlite3_free (sqlcmd_value);
|
||||
}
|
||||
else
|
||||
array = katze_array_from_sqlite (db, sqlcmd);
|
||||
g_free (sqlcmd);
|
||||
|
||||
if (!recursive)
|
||||
return array;
|
||||
|
||||
KATZE_ARRAY_FOREACH_ITEM_L (item, array, list)
|
||||
{
|
||||
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, "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);
|
||||
return array;
|
||||
}
|
||||
|
||||
/**
|
||||
* midori_array_query:
|
||||
* @array: the main bookmark array
|
||||
|
@ -1148,8 +1078,6 @@ midori_array_query_recursive (KatzeArray* bookmarks,
|
|||
* Return value: a #KatzeArray on success, %NULL otherwise
|
||||
*
|
||||
* Since: 0.4.3
|
||||
*
|
||||
* Deprecated: 0.4.4: Use midori_array_query_recursive() instead.
|
||||
**/
|
||||
KatzeArray*
|
||||
midori_array_query (KatzeArray* bookmarks,
|
||||
|
@ -1157,6 +1085,29 @@ midori_array_query (KatzeArray* bookmarks,
|
|||
const gchar* condition,
|
||||
const gchar* value)
|
||||
{
|
||||
return midori_array_query_recursive (bookmarks, fields, condition, value, FALSE);
|
||||
sqlite3* db;
|
||||
gchar* sqlcmd;
|
||||
char* sqlcmd_value;
|
||||
KatzeArray* array;
|
||||
|
||||
g_return_val_if_fail (KATZE_IS_ARRAY (bookmarks), NULL);
|
||||
g_return_val_if_fail (fields, NULL);
|
||||
g_return_val_if_fail (condition, NULL);
|
||||
db = g_object_get_data (G_OBJECT (bookmarks), "db");
|
||||
if (db == NULL)
|
||||
return NULL;
|
||||
|
||||
sqlcmd = g_strdup_printf ("SELECT %s FROM bookmarks WHERE %s "
|
||||
"ORDER BY title DESC", fields, condition);
|
||||
if (strstr (condition, "%q"))
|
||||
{
|
||||
sqlcmd_value = sqlite3_mprintf (sqlcmd, value ? value : "");
|
||||
array = katze_array_from_sqlite (db, sqlcmd_value);
|
||||
sqlite3_free (sqlcmd_value);
|
||||
}
|
||||
else
|
||||
array = katze_array_from_sqlite (db, sqlcmd);
|
||||
g_free (sqlcmd);
|
||||
return array;
|
||||
}
|
||||
|
||||
|
|
|
@ -36,13 +36,6 @@ midori_array_query (KatzeArray* array,
|
|||
const gchar* condition,
|
||||
const gchar* value);
|
||||
|
||||
KatzeArray*
|
||||
midori_array_query_recursive (KatzeArray* array,
|
||||
const gchar* fields,
|
||||
const gchar* condition,
|
||||
const gchar* value,
|
||||
gboolean recursive);
|
||||
|
||||
KatzeArray*
|
||||
katze_array_from_sqlite (sqlite3* db,
|
||||
const gchar* sqlcmd);
|
||||
|
|
|
@ -1,335 +0,0 @@
|
|||
/*
|
||||
Copyright (C) 2010 Christian Dywan <christian@twotoasts.de>
|
||||
Copyright (C) 2010 Alexander Butenko <a.butenka@gmail.com>
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
See the file COPYING for the full license text.
|
||||
*/
|
||||
|
||||
#include "midori-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)
|
||||
{
|
||||
g_printerr ("%s\n", query);
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
midori_bookmarks_add_item_cb (KatzeArray* array,
|
||||
KatzeItem* item,
|
||||
sqlite3* db)
|
||||
{
|
||||
midori_bookmarks_insert_item_db (db, item,
|
||||
katze_item_get_meta_integer (item, "parentid"));
|
||||
}
|
||||
|
||||
void
|
||||
midori_bookmarks_remove_item_cb (KatzeArray* array,
|
||||
KatzeItem* item,
|
||||
sqlite3* db)
|
||||
{
|
||||
gchar* sqlcmd;
|
||||
char* errmsg = NULL;
|
||||
|
||||
|
||||
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)
|
||||
{
|
||||
g_printerr (_("Failed to remove history item: %s\n"), errmsg);
|
||||
sqlite3_free (errmsg);
|
||||
}
|
||||
|
||||
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,
|
||||
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;
|
||||
|
||||
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 (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 (midori_debug ("bookmarks"))
|
||||
sqlite3_trace (db, midori_bookmarks_dbtracer, NULL);
|
||||
#endif
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
void
|
||||
midori_bookmarks_import (const gchar* filename,
|
||||
sqlite3* db)
|
||||
{
|
||||
KatzeArray* bookmarks;
|
||||
GError* error = NULL;
|
||||
|
||||
bookmarks = katze_array_new (KATZE_TYPE_ARRAY);
|
||||
|
||||
if (!midori_array_from_file (bookmarks, filename, "xbel", &error))
|
||||
{
|
||||
g_warning (_("The bookmarks couldn't be saved. %s"), error->message);
|
||||
g_error_free (error);
|
||||
return;
|
||||
}
|
||||
midori_bookmarks_import_array_db (db, bookmarks, 0);
|
||||
}
|
|
@ -1,32 +0,0 @@
|
|||
/*
|
||||
Copyright (C) 2010 Christian Dywan <christian@twotoasts.de>
|
||||
Copyright (C) 2010 Alexander Butenko <a.butenka@gmail.com>
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
See the file COPYING for the full license text.
|
||||
*/
|
||||
|
||||
#include <sqlite3.h>
|
||||
#include <katze/katze.h>
|
||||
|
||||
void
|
||||
midori_bookmarks_add_item_cb (KatzeArray* array,
|
||||
KatzeItem* item,
|
||||
sqlite3* db);
|
||||
|
||||
void
|
||||
midori_bookmarks_remove_item_cb (KatzeArray* array,
|
||||
KatzeItem* item,
|
||||
sqlite3* db);
|
||||
|
||||
sqlite3*
|
||||
midori_bookmarks_initialize (KatzeArray* array,
|
||||
char** errmsg);
|
||||
|
||||
void
|
||||
midori_bookmarks_import (const gchar* filename,
|
||||
sqlite3* db);
|
File diff suppressed because it is too large
Load diff
|
@ -152,16 +152,9 @@ GtkWidget*
|
|||
midori_browser_get_current_tab (MidoriBrowser* browser);
|
||||
#define midori_browser_get_tab midori_browser_get_current_tab
|
||||
|
||||
gint
|
||||
midori_browser_page_num (MidoriBrowser* browser,
|
||||
GtkWidget* view);
|
||||
|
||||
GList*
|
||||
midori_browser_get_tabs (MidoriBrowser* browser);
|
||||
|
||||
gint
|
||||
midori_browser_get_n_pages (MidoriBrowser* browser);
|
||||
|
||||
KatzeArray*
|
||||
midori_browser_get_proxy_items (MidoriBrowser* browser);
|
||||
|
||||
|
@ -180,11 +173,6 @@ 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__ */
|
||||
|
|
|
@ -1,320 +0,0 @@
|
|||
/*
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -14,7 +14,6 @@
|
|||
|
||||
#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);
|
||||
|
@ -26,7 +25,6 @@ struct _MidoriExtensionPrivate
|
|||
gchar* version;
|
||||
gchar* authors;
|
||||
gchar* website;
|
||||
gchar* key;
|
||||
|
||||
MidoriApp* app;
|
||||
gint active;
|
||||
|
@ -129,8 +127,7 @@ enum
|
|||
PROP_DESCRIPTION,
|
||||
PROP_VERSION,
|
||||
PROP_AUTHORS,
|
||||
PROP_WEBSITE,
|
||||
PROP_KEY
|
||||
PROP_WEBSITE
|
||||
};
|
||||
|
||||
enum {
|
||||
|
@ -263,23 +260,6 @@ midori_extension_class_init (MidoriExtensionClass* class)
|
|||
NULL,
|
||||
flags));
|
||||
|
||||
/**
|
||||
* MidoriExtension:key:
|
||||
*
|
||||
* The extension key.
|
||||
* Needed if there is more than one extension object in a single module.
|
||||
*
|
||||
* Since: 0.4.5
|
||||
*/
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_KEY,
|
||||
g_param_spec_string (
|
||||
"key",
|
||||
"Key",
|
||||
"The extension key",
|
||||
NULL,
|
||||
flags));
|
||||
|
||||
g_type_class_add_private (class, sizeof (MidoriExtensionPrivate));
|
||||
}
|
||||
|
||||
|
@ -318,10 +298,10 @@ midori_extension_activate_cb (MidoriExtension* extension,
|
|||
strlen (filename) - strlen ("." G_MODULE_SUFFIX));
|
||||
else
|
||||
filename = g_strdup (filename);
|
||||
folder = g_build_filename ("extensions", filename, NULL);
|
||||
folder = g_strconcat ("extensions/", filename, NULL);
|
||||
g_free (filename);
|
||||
katze_assign (config_file,
|
||||
midori_paths_get_preset_filename (folder, "config"));
|
||||
sokoke_find_config_filename (folder, "config"));
|
||||
g_free (folder);
|
||||
g_key_file_load_from_file (extension->priv->key_file, config_file,
|
||||
G_KEY_FILE_KEEP_COMMENTS, NULL);
|
||||
|
@ -341,32 +321,29 @@ midori_extension_activate_cb (MidoriExtension* extension,
|
|||
if (setting->type == G_TYPE_BOOLEAN)
|
||||
{
|
||||
MESettingBoolean* setting_ = (MESettingBoolean*)setting;
|
||||
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);
|
||||
if (extension->priv->key_file)
|
||||
setting_->value = sokoke_key_file_get_boolean_default (
|
||||
extension->priv->key_file,
|
||||
"settings", setting->name, setting_->default_value, NULL);
|
||||
else
|
||||
setting_->value = setting_->default_value;
|
||||
}
|
||||
else if (setting->type == G_TYPE_INT)
|
||||
{
|
||||
MESettingInteger* setting_ = (MESettingInteger*)setting;
|
||||
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);
|
||||
if (extension->priv->key_file)
|
||||
setting_->value = sokoke_key_file_get_integer_default (
|
||||
extension->priv->key_file,
|
||||
"settings", setting->name, setting_->default_value, NULL);
|
||||
else
|
||||
setting_->value = setting_->default_value;
|
||||
}
|
||||
else if (setting->type == G_TYPE_STRING)
|
||||
{
|
||||
if (extension->priv->key_file)
|
||||
{
|
||||
setting->value = g_key_file_get_string (
|
||||
extension->priv->key_file, "settings", setting->name, NULL);
|
||||
if (setting->value == NULL)
|
||||
setting->value = setting->default_value;
|
||||
}
|
||||
setting->value = sokoke_key_file_get_string_default (
|
||||
extension->priv->key_file,
|
||||
"settings", setting->name, setting->default_value, NULL);
|
||||
else
|
||||
setting->value = g_strdup (setting->default_value);
|
||||
}
|
||||
|
@ -375,10 +352,10 @@ midori_extension_activate_cb (MidoriExtension* extension,
|
|||
MESettingStringList* setting_ = (MESettingStringList*)setting;
|
||||
if (extension->priv->key_file)
|
||||
{
|
||||
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);
|
||||
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);
|
||||
}
|
||||
else
|
||||
setting_->value = g_strdupv (setting_->default_value);
|
||||
|
@ -423,7 +400,6 @@ midori_extension_finalize (GObject* object)
|
|||
katze_assign (extension->priv->version, NULL);
|
||||
katze_assign (extension->priv->authors, NULL);
|
||||
katze_assign (extension->priv->website, NULL);
|
||||
katze_assign (extension->priv->key, NULL);
|
||||
|
||||
katze_assign (extension->priv->config_dir, NULL);
|
||||
g_list_free (extension->priv->lsettings);
|
||||
|
@ -470,9 +446,6 @@ midori_extension_set_property (GObject* object,
|
|||
case PROP_WEBSITE:
|
||||
katze_assign (extension->priv->website, g_value_dup_string (value));
|
||||
break;
|
||||
case PROP_KEY:
|
||||
katze_assign (extension->priv->key, g_value_dup_string (value));
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
|
@ -504,9 +477,6 @@ midori_extension_get_property (GObject* object,
|
|||
case PROP_WEBSITE:
|
||||
g_value_set_string (value, extension->priv->website);
|
||||
break;
|
||||
case PROP_KEY:
|
||||
g_value_set_string (value, extension->priv->key);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
|
@ -649,11 +619,10 @@ midori_extension_get_config_dir (MidoriExtension* extension)
|
|||
if (!extension->priv->config_dir)
|
||||
{
|
||||
gchar* filename = g_object_get_data (G_OBJECT (extension), "filename");
|
||||
if (filename != NULL)
|
||||
if (!filename)
|
||||
return "/";
|
||||
extension->priv->config_dir = g_build_filename (
|
||||
midori_paths_get_config_dir (), "extensions", filename, NULL);
|
||||
else
|
||||
extension->priv->config_dir = NULL;
|
||||
sokoke_set_config_dir (NULL), "extensions", filename, NULL);
|
||||
}
|
||||
|
||||
return extension->priv->config_dir;
|
||||
|
|
File diff suppressed because it is too large
Load diff
227
midori/midori-panedaction.c
Normal file
227
midori/midori-panedaction.c
Normal file
|
@ -0,0 +1,227 @@
|
|||
/*
|
||||
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;
|
||||
}
|
70
midori/midori-panedaction.h
Normal file
70
midori/midori-panedaction.h
Normal file
|
@ -0,0 +1,70 @@
|
|||
/*
|
||||
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__
|
|
@ -1,79 +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.
|
||||
*/
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -253,6 +253,36 @@ 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)
|
||||
|
@ -262,6 +292,57 @@ 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)
|
||||
|
@ -300,7 +381,6 @@ 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);
|
||||
|
@ -346,7 +426,6 @@ 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);
|
||||
|
@ -491,15 +570,13 @@ midori_panel_set_right_aligned (MidoriPanel* panel,
|
|||
/* Private function, used by MidoriBrowser */
|
||||
/* static */ GtkWidget*
|
||||
midori_panel_construct_menu_item (MidoriPanel* panel,
|
||||
MidoriViewable* viewable,
|
||||
gboolean popup)
|
||||
MidoriViewable* viewable)
|
||||
{
|
||||
GtkAction* action;
|
||||
GtkWidget* menuitem;
|
||||
|
||||
action = g_object_get_data (G_OBJECT (viewable), "midori-panel-action");
|
||||
menuitem = popup ? sokoke_action_create_popup_menu_item (action)
|
||||
: gtk_action_create_menu_item (action);
|
||||
menuitem = gtk_action_create_menu_item (action);
|
||||
g_object_set_data (G_OBJECT (menuitem), "page", viewable);
|
||||
|
||||
if (gtk_widget_get_visible (GTK_WIDGET (viewable)))
|
||||
|
@ -561,9 +638,24 @@ 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));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -618,7 +710,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_NEVER,
|
||||
GTK_POLICY_AUTOMATIC,
|
||||
GTK_POLICY_AUTOMATIC);
|
||||
gtk_widget_set_can_focus (scrolled, TRUE);
|
||||
gtk_widget_show (scrolled);
|
||||
|
|
|
@ -12,7 +12,11 @@
|
|||
#ifndef __MIDORI_PANEL_H__
|
||||
#define __MIDORI_PANEL_H__
|
||||
|
||||
#include "midori-core.h"
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#include <katze/katze.h>
|
||||
|
||||
#include "midori-viewable.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
|
|
|
@ -33,11 +33,15 @@
|
|||
#endif
|
||||
|
||||
#define MIDORI_EVENT_NEW_TAB(evt) \
|
||||
(evt != NULL \
|
||||
&& ((((GdkEventButton*)evt)->button == 1 \
|
||||
((((GdkEventButton*)evt)->button == 1 \
|
||||
&& MIDORI_MOD_NEW_TAB(((GdkEventButton*)evt)->state)) \
|
||||
|| (((GdkEventButton*)evt)->button == 2)))
|
||||
|| (((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__ */
|
||||
|
|
|
@ -11,8 +11,6 @@
|
|||
|
||||
#include "midori-preferences.h"
|
||||
|
||||
#include "midori-app.h"
|
||||
#include "midori-core.h"
|
||||
#include "midori-platform.h"
|
||||
|
||||
#include <string.h>
|
||||
|
@ -294,7 +292,7 @@ midori_preferences_set_settings (MidoriPreferences* preferences,
|
|||
#define SPANNED_ADD(__widget) \
|
||||
katze_preferences_add_widget (_preferences, __widget, "spanned")
|
||||
/* Page "General" */
|
||||
if (!midori_paths_is_readonly ())
|
||||
if (!sokoke_is_app_or_private ())
|
||||
{
|
||||
PAGE_NEW (GTK_STOCK_HOME, _("Startup"));
|
||||
FRAME_NEW (NULL);
|
||||
|
@ -302,8 +300,7 @@ midori_preferences_set_settings (MidoriPreferences* preferences,
|
|||
INDENTED_ADD (label);
|
||||
button = katze_property_proxy (settings, "load-on-startup", NULL);
|
||||
SPANNED_ADD (button);
|
||||
label = gtk_label_new (_("Homepage:"));
|
||||
gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
|
||||
label = katze_property_label (settings, "homepage");
|
||||
INDENTED_ADD (label);
|
||||
entry = katze_property_proxy (settings, "homepage", "address");
|
||||
SPANNED_ADD (entry);
|
||||
|
@ -353,8 +350,7 @@ midori_preferences_set_settings (MidoriPreferences* preferences,
|
|||
button = katze_property_proxy (settings, "enforce-font-family", NULL);
|
||||
INDENTED_ADD (button);
|
||||
#endif
|
||||
label = gtk_label_new (_("Preferred Encoding"));
|
||||
gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
|
||||
label = katze_property_label (settings, "preferred-encoding");
|
||||
INDENTED_ADD (label);
|
||||
button = katze_property_proxy (settings, "preferred-encoding", "custom-default-encoding");
|
||||
SPANNED_ADD (button);
|
||||
|
@ -364,14 +360,12 @@ 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 = midori_paths_get_lib_path ("enchant");
|
||||
gchar* enchant_path = sokoke_find_lib_path ("enchant");
|
||||
if (enchant_path == NULL)
|
||||
{
|
||||
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), FALSE);
|
||||
|
@ -381,15 +375,11 @@ 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"));
|
||||
|
@ -397,42 +387,23 @@ 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);
|
||||
if (katze_object_has_property (settings, "enable-webgl"))
|
||||
{
|
||||
button = katze_property_proxy (settings, "enable-webgl", NULL);
|
||||
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
|
||||
|
||||
SPANNED_ADD (button);
|
||||
FRAME_NEW (NULL);
|
||||
button = gtk_label_new (_("Preferred languages"));
|
||||
gtk_misc_set_alignment (GTK_MISC (button), 0.0, 0.5);
|
||||
button = katze_property_label (settings, "preferred-languages");
|
||||
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);
|
||||
label = gtk_label_new (_("Save downloaded files to:"));
|
||||
gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
|
||||
#if !HAVE_HILDON
|
||||
label = katze_property_label (settings, "download-folder");
|
||||
INDENTED_ADD (label);
|
||||
button = katze_property_proxy (settings, "download-folder", "folder");
|
||||
SPANNED_ADD (button);
|
||||
#endif
|
||||
|
||||
/* Page "Interface" */
|
||||
PAGE_NEW (GTK_STOCK_CONVERT, _("Browsing"));
|
||||
|
@ -450,51 +421,45 @@ midori_preferences_set_settings (MidoriPreferences* preferences,
|
|||
INDENTED_ADD (label);
|
||||
button = katze_property_proxy (settings, "open-new-pages-in", NULL);
|
||||
SPANNED_ADD (button);
|
||||
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
|
||||
#if !HAVE_HILDON
|
||||
button = katze_property_proxy (settings, "always-show-tabbar", NULL);
|
||||
gtk_button_set_label (GTK_BUTTON (button), _("Always Show Tabbar"));
|
||||
INDENTED_ADD (button);
|
||||
button = katze_property_proxy (settings, "close-buttons-on-tabs", NULL);
|
||||
SPANNED_ADD (button);
|
||||
#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 = gtk_label_new (_("Text Editor"));
|
||||
gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
|
||||
label = katze_property_label (settings, "text-editor");
|
||||
INDENTED_ADD (label);
|
||||
entry = katze_property_proxy (settings, "text-editor", "application-text/plain");
|
||||
SPANNED_ADD (entry);
|
||||
label = gtk_label_new (_("News Aggregator"));
|
||||
gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
|
||||
label = katze_property_label (settings, "news-aggregator");
|
||||
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);
|
||||
label = gtk_label_new (_("Proxy server"));
|
||||
gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
|
||||
#if !HAVE_HILDON
|
||||
label = katze_property_label (settings, "proxy-type");
|
||||
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", "address");
|
||||
entry = katze_property_proxy (settings, "http-proxy", NULL);
|
||||
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 = gtk_label_new (_("Port"));
|
||||
label = katze_property_label (settings, "http-proxy-port");
|
||||
gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
|
||||
INDENTED_ADD (label);
|
||||
entry = katze_property_proxy (settings, "http-proxy-port", NULL);
|
||||
|
@ -502,14 +467,13 @@ 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 = gtk_label_new (_("Web Cache"));
|
||||
gtk_widget_set_tooltip_text (label, _("The maximum size of cached pages on disk"));
|
||||
label = katze_property_label (settings, "maximum-cache-size");
|
||||
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);
|
||||
|
|
|
@ -311,7 +311,7 @@ midori_search_action_create_tool_item (GtkAction* action)
|
|||
GtkWidget* alignment;
|
||||
|
||||
toolitem = GTK_WIDGET (gtk_tool_item_new ());
|
||||
entry = sokoke_search_entry_new (NULL);
|
||||
entry = gtk_icon_entry_new ();
|
||||
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);
|
||||
|
@ -432,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 = STOCK_EDIT_FIND;
|
||||
*icon_name = "edit-find";
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -876,189 +876,21 @@ midori_search_action_editor_name_changed_cb (GtkWidget* entry,
|
|||
GTK_RESPONSE_ACCEPT, text && *text);
|
||||
}
|
||||
|
||||
gchar*
|
||||
midori_search_action_token_for_uri (const gchar* uri)
|
||||
static inline const gchar*
|
||||
STR_NON_NULL (const gchar* string)
|
||||
{
|
||||
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);
|
||||
return string ? string : "";
|
||||
}
|
||||
|
||||
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
|
||||
static 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;
|
||||
|
@ -1067,6 +899,7 @@ 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);
|
||||
|
@ -1086,6 +919,7 @@ 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);
|
||||
}
|
||||
|
@ -1106,8 +940,9 @@ 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)));
|
||||
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);
|
||||
|
@ -1119,8 +954,9 @@ 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)
|
||||
, katze_str_non_null (katze_item_get_text (item)));
|
||||
, 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);
|
||||
gtk_widget_show_all (hbox);
|
||||
|
@ -1136,14 +972,28 @@ midori_search_action_get_editor (MidoriSearchAction* search_action,
|
|||
#else
|
||||
NULL);
|
||||
#endif
|
||||
g_object_set_data (G_OBJECT (entry_uri), "allow_%s", (void*)1);
|
||||
gtk_entry_set_activates_default (GTK_ENTRY (entry_uri), TRUE);
|
||||
gtk_entry_set_text (GTK_ENTRY (entry_uri),
|
||||
katze_str_non_null (katze_item_get_uri (item)));
|
||||
if (!new_engine)
|
||||
gtk_entry_set_text (GTK_ENTRY (entry_uri)
|
||||
, 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)
|
||||
, 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:"));
|
||||
|
@ -1151,8 +1001,9 @@ 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)
|
||||
, katze_str_non_null (katze_item_get_token (item)));
|
||||
, 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);
|
||||
gtk_widget_show_all (hbox);
|
||||
|
@ -1164,6 +1015,7 @@ 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);
|
||||
|
||||
|
@ -1188,7 +1040,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, NULL, FALSE);
|
||||
midori_search_action_get_editor (search_action, FALSE);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1196,7 +1048,7 @@ static void
|
|||
midori_search_action_dialog_add_cb (GtkWidget* widget,
|
||||
MidoriSearchAction* search_action)
|
||||
{
|
||||
midori_search_action_get_editor (search_action, katze_item_new (), TRUE);
|
||||
midori_search_action_get_editor (search_action, TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -1209,7 +1061,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, NULL, FALSE);
|
||||
midori_search_action_get_editor (search_action, FALSE);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -1457,8 +1309,6 @@ 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);
|
||||
|
@ -1493,11 +1343,6 @@ 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,
|
||||
|
@ -1508,6 +1353,11 @@ 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),
|
||||
|
|
|
@ -13,7 +13,6 @@
|
|||
#define __MIDORI_SEARCH_ACTION_H__
|
||||
|
||||
#include <katze/katze.h>
|
||||
#include <webkit/webkit.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
|
@ -73,15 +72,6 @@ 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__ */
|
||||
|
|
|
@ -1,109 +0,0 @@
|
|||
/*
|
||||
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");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,401 +0,0 @@
|
|||
/*
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -12,28 +12,42 @@
|
|||
#ifndef __MIDORI_STOCK_H__
|
||||
#define __MIDORI_STOCK_H__ 1
|
||||
|
||||
/* Stock items */
|
||||
/* Custom 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 "internet-news-reader"
|
||||
#define STOCK_STYLE "preferences-desktop-theme"
|
||||
#define STOCK_NEWS_FEED "news-feed"
|
||||
#define STOCK_STYLE "gnome-settings-theme"
|
||||
#define STOCK_TRANSFER "package"
|
||||
#define STOCK_PLUGINS "application-x-shockwave-flash"
|
||||
#define STOCK_TRANSFERS "package"
|
||||
#define STOCK_PLUGINS "gnome-mime-application-x-shockwave-flash"
|
||||
|
||||
#define STOCK_BOOKMARK_ADD "bookmark-new"
|
||||
#define STOCK_IMAGE "image-x-generic"
|
||||
#define STOCK_HOMEPAGE "go-home"
|
||||
#define STOCK_IMAGE "gnome-mime-image"
|
||||
#define STOCK_NETWORK_OFFLINE "network-offline"
|
||||
#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"
|
||||
#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
|
||||
|
||||
#endif /* !__MIDORI_STOCK_H__ */
|
||||
|
|
2196
midori/midori-view.c
2196
midori/midori-view.c
File diff suppressed because it is too large
Load diff
|
@ -16,10 +16,6 @@
|
|||
|
||||
#include <katze/katze.h>
|
||||
|
||||
#ifdef HAVE_GRANITE
|
||||
#include <granite/granite.h>
|
||||
#endif
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define MIDORI_LOAD_PROVISIONAL WEBKIT_LOAD_PROVISIONAL
|
||||
|
@ -57,15 +53,6 @@ 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) \
|
||||
|
@ -109,10 +96,6 @@ void
|
|||
midori_view_set_uri (MidoriView* view,
|
||||
const gchar* uri);
|
||||
|
||||
void
|
||||
midori_view_set_overlay_text (MidoriView* view,
|
||||
const gchar* text);
|
||||
|
||||
gboolean
|
||||
midori_view_is_blank (MidoriView* view);
|
||||
|
||||
|
@ -155,17 +138,8 @@ 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);
|
||||
|
@ -183,6 +157,9 @@ 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);
|
||||
|
@ -202,20 +179,15 @@ midori_view_can_go_forward (MidoriView* view);
|
|||
void
|
||||
midori_view_go_forward (MidoriView* view);
|
||||
|
||||
|
||||
void midori_view_go_back_or_forward (MidoriView* view,
|
||||
gint steps);
|
||||
|
||||
gboolean
|
||||
midori_view_can_go_back_or_forward (MidoriView* view,
|
||||
gint steps);
|
||||
|
||||
const gchar*
|
||||
midori_view_get_previous_page (MidoriView* view);
|
||||
|
||||
const gchar*
|
||||
midori_view_get_next_page (MidoriView* view);
|
||||
|
||||
gboolean
|
||||
midori_view_can_print (MidoriView* view);
|
||||
|
||||
void
|
||||
midori_view_print (MidoriView* view);
|
||||
|
||||
|
@ -225,10 +197,8 @@ midori_view_can_view_source (MidoriView* view);
|
|||
gboolean
|
||||
midori_view_can_save (MidoriView* view);
|
||||
|
||||
gchar*
|
||||
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);
|
||||
|
@ -261,9 +231,6 @@ midori_view_get_snapshot (MidoriView* view,
|
|||
GtkWidget*
|
||||
midori_view_get_web_view (MidoriView* view);
|
||||
|
||||
MidoriView*
|
||||
midori_view_get_for_widget (GtkWidget* web_view);
|
||||
|
||||
MidoriSecurity
|
||||
midori_view_get_security (MidoriView* view);
|
||||
|
||||
|
@ -281,9 +248,9 @@ midori_view_add_info_bar (MidoriView* view,
|
|||
const gchar* first_button_text,
|
||||
...);
|
||||
|
||||
const gchar*
|
||||
midori_view_fallback_extension (MidoriView* view,
|
||||
const gchar* extension);
|
||||
void
|
||||
midori_view_save_speed_dial_config (MidoriView* view,
|
||||
GKeyFile* key_file);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
|
163
midori/midori-viewable.c
Normal file
163
midori/midori-viewable.c
Normal file
|
@ -0,0 +1,163 @@
|
|||
/*
|
||||
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;
|
||||
}
|
61
midori/midori-viewable.h
Normal file
61
midori/midori-viewable.h
Normal file
|
@ -0,0 +1,61 @@
|
|||
/*
|
||||
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__ */
|
|
@ -1,23 +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.
|
||||
*/
|
||||
|
||||
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
|
@ -34,6 +34,8 @@ G_BEGIN_DECLS
|
|||
typedef struct _MidoriWebSettings MidoriWebSettings;
|
||||
typedef struct _MidoriWebSettingsClass MidoriWebSettingsClass;
|
||||
|
||||
#define MIDORI_PARAM_DELAY_SAVING (1 << 8)
|
||||
|
||||
enum
|
||||
{
|
||||
MIDORI_CLEAR_NONE = 0,
|
||||
|
@ -47,6 +49,20 @@ 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
|
||||
{
|
||||
|
@ -64,8 +80,7 @@ midori_startup_get_type (void) G_GNUC_CONST;
|
|||
|
||||
typedef enum
|
||||
{
|
||||
MIDORI_ENCODING_CHINESE /* Traditional */,
|
||||
MIDORI_ENCODING_CHINESE_SIMPLIFIED,
|
||||
MIDORI_ENCODING_CHINESE,
|
||||
MIDORI_ENCODING_JAPANESE,
|
||||
MIDORI_ENCODING_KOREAN,
|
||||
MIDORI_ENCODING_RUSSIAN,
|
||||
|
@ -126,7 +141,6 @@ typedef enum
|
|||
{
|
||||
MIDORI_IDENT_MIDORI /* Automatic */,
|
||||
MIDORI_IDENT_GENUINE /* Midori */,
|
||||
MIDORI_IDENT_CHROME,
|
||||
MIDORI_IDENT_SAFARI,
|
||||
MIDORI_IDENT_IPHONE,
|
||||
MIDORI_IDENT_FIREFOX,
|
||||
|
@ -159,24 +173,6 @@ const gchar*
|
|||
midori_web_settings_get_system_name (gchar** architecture,
|
||||
gchar** platform);
|
||||
|
||||
gboolean
|
||||
midori_web_settings_has_plugin_support (void);
|
||||
|
||||
typedef enum
|
||||
{
|
||||
MIDORI_SITE_DATA_UNDETERMINED,
|
||||
MIDORI_SITE_DATA_BLOCK,
|
||||
MIDORI_SITE_DATA_ACCEPT,
|
||||
MIDORI_SITE_DATA_PRESERVE,
|
||||
} MidoriSiteDataPolicy;
|
||||
|
||||
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__ */
|
||||
|
|
|
@ -14,7 +14,6 @@
|
|||
|
||||
#include "midori-app.h"
|
||||
#include "midori-array.h"
|
||||
#include "midori-bookmarks.h"
|
||||
#include "midori-browser.h"
|
||||
#include "midori-extension.h"
|
||||
#include "midori-locationaction.h"
|
||||
|
@ -22,6 +21,7 @@
|
|||
#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 */
|
||||
|
|
|
@ -14,19 +14,19 @@ namespace Midori {
|
|||
[NoAccessorMethod]
|
||||
public string name { get; set; }
|
||||
[NoAccessorMethod]
|
||||
public Midori.WebSettings settings { owned get; set; }
|
||||
public Midori.WebSettings settings { get; set; }
|
||||
[NoAccessorMethod]
|
||||
public Katze.Array bookmarks { get; set; }
|
||||
public GLib.Object bookmarks { get; set; }
|
||||
[NoAccessorMethod]
|
||||
public Katze.Array trash { get; set; }
|
||||
public GLib.Object trash { get; set; }
|
||||
[NoAccessorMethod]
|
||||
public Katze.Array search_engines { get; set; }
|
||||
public GLib.Object search_engines { get; set; }
|
||||
[NoAccessorMethod]
|
||||
public Katze.Array history { get; set; }
|
||||
public GLib.Object history { get; set; }
|
||||
[NoAccessorMethod]
|
||||
public Katze.Array extensions { get; set; }
|
||||
public GLib.Object extensions { get; set; }
|
||||
[NoAccessorMethod]
|
||||
public Katze.Array browsers { get; }
|
||||
public GLib.Object browsers { get; }
|
||||
public Browser? browser { get; }
|
||||
|
||||
[HasEmitter]
|
||||
|
@ -35,20 +35,18 @@ namespace Midori {
|
|||
[HasEmitter]
|
||||
public signal void quit ();
|
||||
}
|
||||
|
||||
[CCode (cheader_filename = "midori/midori.h")]
|
||||
public class Browser : Gtk.Window {
|
||||
public Browser ();
|
||||
public int add_item (Katze.Item item);
|
||||
public int add_item (GLib.Object 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 static unowned Browser get_for_widget (Gtk.Widget widget);
|
||||
public unowned Browser get_for_widget (Gtk.Widget widget);
|
||||
public unowned string[] get_toolbar_actions ();
|
||||
public unowned Katze.Array get_proxy_items ();
|
||||
public unowned GLib.Object get_proxy_items ();
|
||||
|
||||
[NoAccessorMethod]
|
||||
public Gtk.MenuBar menubar { owned get; }
|
||||
|
@ -69,13 +67,13 @@ namespace Midori {
|
|||
public string statusbar_text { owned get; set; }
|
||||
public Midori.WebSettings settings { get; set; }
|
||||
[NoAccessorMethod]
|
||||
public Katze.Array? bookmarks { owned get; set; }
|
||||
public GLib.Object bookmarks { owned get; set; }
|
||||
[NoAccessorMethod]
|
||||
public Katze.Array? trash { owned get; set; }
|
||||
public GLib.Object trash { owned get; set; }
|
||||
[NoAccessorMethod]
|
||||
public Katze.Array? search_engines { owned get; set; }
|
||||
public GLib.Object search_engines { owned get; set; }
|
||||
[NoAccessorMethod]
|
||||
public Katze.Array? history { owned get; set; }
|
||||
public GLib.Object history { owned get; set; }
|
||||
[NoAccessorMethod]
|
||||
public bool show_tabs { get; set; }
|
||||
|
||||
|
@ -84,10 +82,9 @@ 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 (WebKit.Download download);
|
||||
public signal void add_download (GLib.Object download);
|
||||
public signal void populate_tool_menu (Gtk.Menu menu);
|
||||
[HasEmitter]
|
||||
public signal void quit ();
|
||||
|
@ -118,17 +115,12 @@ namespace Midori {
|
|||
public string version { get; set; }
|
||||
[NoAccessorMethod]
|
||||
public string authors { get; set; }
|
||||
[NoAccessorMethod]
|
||||
public string website { get; set; }
|
||||
[NoAccessorMethod]
|
||||
public string key { get; set; }
|
||||
|
||||
public signal void activate (Midori.App app);
|
||||
public signal void deactivate ();
|
||||
public signal void open_preferences ();
|
||||
}
|
||||
|
||||
[CCode (cheader_filename = "midori/midori.h")]
|
||||
public class View : Gtk.VBox {
|
||||
[CCode (type = "GtkWidget*")]
|
||||
public View (GLib.Object net);
|
||||
|
@ -146,8 +138,9 @@ namespace Midori {
|
|||
public Gtk.Menu get_tab_menu ();
|
||||
public Pango.EllipsizeMode get_label_ellipsize ();
|
||||
public Gtk.Label get_proxy_tab_label ();
|
||||
public Katze.Item get_proxy_item ();
|
||||
public GLib.Object 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);
|
||||
|
@ -155,7 +148,6 @@ 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; }
|
||||
|
@ -166,42 +158,15 @@ namespace Midori {
|
|||
public double progress { get; set; }
|
||||
public bool minimized { get; }
|
||||
public float zoom_level { get; }
|
||||
public Katze.Array news_feeds { get; }
|
||||
public GLib.Object news_feeds { get; }
|
||||
public string statusbar_text { get; }
|
||||
public WebSettings settings { get; set; }
|
||||
public GLib.Object net { get; }
|
||||
|
||||
[HasEmitter]
|
||||
public signal bool download_requested (WebKit.Download download);
|
||||
|
||||
}
|
||||
|
||||
[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_")]
|
||||
|
|
223
midori/socket.c
223
midori/socket.c
|
@ -54,6 +54,9 @@
|
|||
#endif
|
||||
|
||||
#include "socket.h"
|
||||
#if USE_SSL
|
||||
# include <openssl/ssl.h>
|
||||
#endif
|
||||
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
# define debug_print g_debug
|
||||
|
@ -559,6 +562,10 @@ gboolean sock_has_read_data(SockInfo *sock)
|
|||
#ifdef G_OS_WIN32
|
||||
gulong val;
|
||||
|
||||
#if USE_SSL
|
||||
if (sock->ssl)
|
||||
return TRUE;
|
||||
#endif
|
||||
if (ioctlsocket(sock->sock, FIONREAD, &val) < 0) {
|
||||
g_warning("sock_has_read_data(): ioctlsocket() failed: %d\n",
|
||||
WSAGetLastError());
|
||||
|
@ -588,6 +595,22 @@ static gboolean sock_check(GSource *source)
|
|||
fd_set fds;
|
||||
GIOCondition condition = sock->condition;
|
||||
|
||||
#if USE_SSL
|
||||
if (sock->ssl) {
|
||||
if (condition & G_IO_IN) {
|
||||
if (SSL_pending(sock->ssl) > 0)
|
||||
return TRUE;
|
||||
if (SSL_want_write(sock->ssl))
|
||||
condition |= G_IO_OUT;
|
||||
}
|
||||
|
||||
if (condition & G_IO_OUT) {
|
||||
if (SSL_want_read(sock->ssl))
|
||||
condition |= G_IO_IN;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
FD_ZERO(&fds);
|
||||
FD_SET(sock->sock, &fds);
|
||||
|
||||
|
@ -624,6 +647,19 @@ guint sock_add_watch(SockInfo *sock, GIOCondition condition, SockFunc func,
|
|||
sock->callback = func;
|
||||
sock->condition = condition;
|
||||
sock->data = data;
|
||||
|
||||
#if USE_SSL
|
||||
if (sock->ssl) {
|
||||
GSource *source;
|
||||
|
||||
source = g_source_new(&sock_watch_funcs, sizeof(SockSource));
|
||||
((SockSource *)source)->sock = sock;
|
||||
g_source_set_priority(source, G_PRIORITY_DEFAULT);
|
||||
g_source_set_can_recurse(source, FALSE);
|
||||
return g_source_attach(source, NULL);
|
||||
}
|
||||
#endif
|
||||
|
||||
return g_io_add_watch(sock->sock_ch, condition, sock_watch_cb, sock);
|
||||
}
|
||||
|
||||
|
@ -1339,6 +1375,10 @@ gint sock_read(SockInfo *sock, gchar *buf, gint len)
|
|||
{
|
||||
g_return_val_if_fail(sock != NULL, -1);
|
||||
|
||||
#if USE_SSL
|
||||
if (sock->ssl)
|
||||
return ssl_read(sock->ssl, buf, len);
|
||||
#endif
|
||||
return fd_read(sock->sock, buf, len);
|
||||
}
|
||||
|
||||
|
@ -1354,10 +1394,44 @@ gint fd_read(gint fd, gchar *buf, gint len)
|
|||
#endif
|
||||
}
|
||||
|
||||
#if USE_SSL
|
||||
gint ssl_read(SSL *ssl, gchar *buf, gint len)
|
||||
{
|
||||
gint err, ret;
|
||||
|
||||
if (SSL_pending(ssl) == 0) {
|
||||
if (fd_check_io(SSL_get_rfd(ssl), G_IO_IN) < 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = SSL_read(ssl, buf, len);
|
||||
|
||||
switch ((err = SSL_get_error(ssl, ret))) {
|
||||
case SSL_ERROR_NONE:
|
||||
return ret;
|
||||
case SSL_ERROR_WANT_READ:
|
||||
case SSL_ERROR_WANT_WRITE:
|
||||
errno = EAGAIN;
|
||||
return -1;
|
||||
case SSL_ERROR_ZERO_RETURN:
|
||||
return 0;
|
||||
default:
|
||||
g_warning("SSL_read() returned error %d, ret = %d\n", err, ret);
|
||||
if (ret == 0)
|
||||
return 0;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
gint sock_write(SockInfo *sock, const gchar *buf, gint len)
|
||||
{
|
||||
g_return_val_if_fail(sock != NULL, -1);
|
||||
|
||||
#if USE_SSL
|
||||
if (sock->ssl)
|
||||
return ssl_write(sock->ssl, buf, len);
|
||||
#endif
|
||||
return fd_write(sock->sock, buf, len);
|
||||
}
|
||||
|
||||
|
@ -1385,10 +1459,34 @@ gint fd_write(gint fd, const gchar *buf, gint len)
|
|||
#endif
|
||||
}
|
||||
|
||||
#if USE_SSL
|
||||
gint ssl_write(SSL *ssl, const gchar *buf, gint len)
|
||||
{
|
||||
gint ret;
|
||||
|
||||
ret = SSL_write(ssl, buf, len);
|
||||
|
||||
switch (SSL_get_error(ssl, ret)) {
|
||||
case SSL_ERROR_NONE:
|
||||
return ret;
|
||||
case SSL_ERROR_WANT_READ:
|
||||
case SSL_ERROR_WANT_WRITE:
|
||||
errno = EAGAIN;
|
||||
return -1;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
gint sock_write_all(SockInfo *sock, const gchar *buf, gint len)
|
||||
{
|
||||
g_return_val_if_fail(sock != NULL, -1);
|
||||
|
||||
#if USE_SSL
|
||||
if (sock->ssl)
|
||||
return ssl_write_all(sock->ssl, buf, len);
|
||||
#endif
|
||||
return fd_write_all(sock->sock, buf, len);
|
||||
}
|
||||
|
||||
|
@ -1408,6 +1506,24 @@ gint fd_write_all(gint fd, const gchar *buf, gint len)
|
|||
return wrlen;
|
||||
}
|
||||
|
||||
#if USE_SSL
|
||||
gint ssl_write_all(SSL *ssl, const gchar *buf, gint len)
|
||||
{
|
||||
gint n, wrlen = 0;
|
||||
|
||||
while (len) {
|
||||
n = ssl_write(ssl, buf, len);
|
||||
if (n <= 0)
|
||||
return -1;
|
||||
len -= n;
|
||||
wrlen += n;
|
||||
buf += n;
|
||||
}
|
||||
|
||||
return wrlen;
|
||||
}
|
||||
#endif
|
||||
|
||||
gint fd_recv(gint fd, gchar *buf, gint len, gint flags)
|
||||
{
|
||||
#ifdef G_OS_WIN32
|
||||
|
@ -1454,10 +1570,38 @@ gint fd_gets(gint fd, gchar *buf, gint len)
|
|||
return bp - buf;
|
||||
}
|
||||
|
||||
#if USE_SSL
|
||||
gint ssl_gets(SSL *ssl, gchar *buf, gint len)
|
||||
{
|
||||
gchar *newline, *bp = buf;
|
||||
gint n;
|
||||
|
||||
if (--len < 1)
|
||||
return -1;
|
||||
do {
|
||||
if ((n = ssl_peek(ssl, bp, len)) <= 0)
|
||||
return -1;
|
||||
if ((newline = memchr(bp, '\n', n)) != NULL)
|
||||
n = newline - bp + 1;
|
||||
if ((n = ssl_read(ssl, bp, n)) < 0)
|
||||
return -1;
|
||||
bp += n;
|
||||
len -= n;
|
||||
} while (!newline && len);
|
||||
|
||||
*bp = '\0';
|
||||
return bp - buf;
|
||||
}
|
||||
#endif
|
||||
|
||||
gint sock_gets(SockInfo *sock, gchar *buf, gint len)
|
||||
{
|
||||
g_return_val_if_fail(sock != NULL, -1);
|
||||
|
||||
#if USE_SSL
|
||||
if (sock->ssl)
|
||||
return ssl_gets(sock->ssl, buf, len);
|
||||
#endif
|
||||
return fd_gets(sock->sock, buf, len);
|
||||
}
|
||||
|
||||
|
@ -1486,11 +1630,42 @@ gint fd_getline(gint fd, gchar **line)
|
|||
return (gint)size;
|
||||
}
|
||||
|
||||
#if USE_SSL
|
||||
gint ssl_getline(SSL *ssl, gchar **line)
|
||||
{
|
||||
gchar buf[BUFFSIZE];
|
||||
gchar *str = NULL;
|
||||
gint len;
|
||||
gulong size = 0;
|
||||
gulong cur_offset = 0;
|
||||
|
||||
while ((len = ssl_gets(ssl, buf, sizeof(buf))) > 0) {
|
||||
size += len;
|
||||
str = g_realloc(str, size + 1);
|
||||
memcpy(str + cur_offset, buf, len + 1);
|
||||
cur_offset += len;
|
||||
if (buf[len - 1] == '\n')
|
||||
break;
|
||||
}
|
||||
|
||||
*line = str;
|
||||
|
||||
if (!str)
|
||||
return -1;
|
||||
else
|
||||
return (gint)size;
|
||||
}
|
||||
#endif
|
||||
|
||||
gint sock_getline(SockInfo *sock, gchar **line)
|
||||
{
|
||||
g_return_val_if_fail(sock != NULL, -1);
|
||||
g_return_val_if_fail(line != NULL, -1);
|
||||
|
||||
#if USE_SSL
|
||||
if (sock->ssl)
|
||||
return ssl_getline(sock->ssl, line);
|
||||
#endif
|
||||
return fd_getline(sock->sock, line);
|
||||
}
|
||||
|
||||
|
@ -1504,10 +1679,44 @@ gint sock_puts(SockInfo *sock, const gchar *buf)
|
|||
}
|
||||
|
||||
/* peek at the socket data without actually reading it */
|
||||
#if USE_SSL
|
||||
gint ssl_peek(SSL *ssl, gchar *buf, gint len)
|
||||
{
|
||||
gint err, ret;
|
||||
|
||||
if (SSL_pending(ssl) == 0) {
|
||||
if (fd_check_io(SSL_get_rfd(ssl), G_IO_IN) < 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = SSL_peek(ssl, buf, len);
|
||||
|
||||
switch ((err = SSL_get_error(ssl, ret))) {
|
||||
case SSL_ERROR_NONE:
|
||||
return ret;
|
||||
case SSL_ERROR_WANT_READ:
|
||||
case SSL_ERROR_WANT_WRITE:
|
||||
errno = EAGAIN;
|
||||
return -1;
|
||||
case SSL_ERROR_ZERO_RETURN:
|
||||
return 0;
|
||||
default:
|
||||
g_warning("SSL_peek() returned error %d, ret = %d\n", err, ret);
|
||||
if (ret == 0)
|
||||
return 0;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
gint sock_peek(SockInfo *sock, gchar *buf, gint len)
|
||||
{
|
||||
g_return_val_if_fail(sock != NULL, -1);
|
||||
|
||||
#if USE_SSL
|
||||
if (sock->ssl)
|
||||
return ssl_peek(sock->ssl, buf, len);
|
||||
#endif
|
||||
return fd_recv(sock->sock, buf, len, MSG_PEEK);
|
||||
}
|
||||
|
||||
|
@ -1518,6 +1727,11 @@ gint sock_close(SockInfo *sock)
|
|||
if (!sock)
|
||||
return 0;
|
||||
|
||||
#if USE_SSL
|
||||
if (sock->ssl)
|
||||
ssl_done_socket(sock);
|
||||
#endif
|
||||
|
||||
if (sock->sock_ch) {
|
||||
g_io_channel_shutdown(sock->sock_ch, FALSE, NULL);
|
||||
g_io_channel_unref(sock->sock_ch);
|
||||
|
@ -1545,4 +1759,13 @@ gint fd_close(gint fd)
|
|||
#endif
|
||||
}
|
||||
|
||||
#if USE_SSL
|
||||
void ssl_done_socket(SockInfo *sockinfo)
|
||||
{
|
||||
if (sockinfo->ssl) {
|
||||
SSL_free(sockinfo->ssl);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
@ -20,6 +20,10 @@
|
|||
|
||||
typedef struct _SockInfo SockInfo;
|
||||
|
||||
#if USE_SSL
|
||||
# include <openssl/ssl.h>
|
||||
#endif
|
||||
|
||||
typedef enum
|
||||
{
|
||||
CONN_READY,
|
||||
|
@ -38,6 +42,11 @@ typedef gboolean (*SockFunc) (SockInfo *sock,
|
|||
struct _SockInfo
|
||||
{
|
||||
gint sock;
|
||||
#if USE_SSL
|
||||
SSL *ssl;
|
||||
#else
|
||||
gpointer ssl;
|
||||
#endif
|
||||
GIOChannel *sock_ch;
|
||||
|
||||
gchar *hostname;
|
||||
|
@ -102,4 +111,15 @@ gint fd_gets (gint sock, gchar *buf, gint len);
|
|||
gint fd_getline (gint sock, gchar **line);
|
||||
gint fd_close (gint sock);
|
||||
|
||||
/* Functions for SSL */
|
||||
#if USE_SSL
|
||||
gint ssl_read (SSL *ssl, gchar *buf, gint len);
|
||||
gint ssl_write (SSL *ssl, const gchar *buf, gint len);
|
||||
gint ssl_write_all (SSL *ssl, const gchar *buf, gint len);
|
||||
gint ssl_gets (SSL *ssl, gchar *buf, gint len);
|
||||
gint ssl_getline (SSL *ssl, gchar **line);
|
||||
gint ssl_peek (SSL *ssl, gchar *buf, gint len);
|
||||
void ssl_done_socket (SockInfo *sockinfo);
|
||||
#endif
|
||||
|
||||
#endif /* __SYLPH_SOCKET_H__ */
|
||||
|
|
849
midori/sokoke.c
849
midori/sokoke.c
File diff suppressed because it is too large
Load diff
|
@ -14,7 +14,6 @@
|
|||
#define __SOKOKE_H__ 1
|
||||
|
||||
#include <JavaScriptCore/JavaScript.h>
|
||||
#include <webkit/webkit.h>
|
||||
#include <midori/midori-websettings.h>
|
||||
#include <katze/gtk3-compat.h>
|
||||
|
||||
|
@ -42,17 +41,9 @@ 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,
|
||||
gboolean quote_command,
|
||||
const gchar* argument,
|
||||
gboolean quote_argument);
|
||||
const gchar* argument);
|
||||
|
||||
void
|
||||
sokoke_spawn_app (const gchar* uri,
|
||||
|
@ -72,6 +63,47 @@ 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,
|
||||
|
@ -89,10 +121,34 @@ sokoke_action_create_popup_menu_item (GtkAction* action);
|
|||
gint64
|
||||
sokoke_time_t_to_julian (const time_t* timestamp);
|
||||
|
||||
gint
|
||||
sokoke_days_between (const time_t* day1,
|
||||
const time_t* day2);
|
||||
|
||||
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, ...);
|
||||
|
@ -117,6 +173,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);
|
||||
|
@ -135,11 +194,12 @@ sokoke_register_privacy_item (const gchar* name,
|
|||
|
||||
void
|
||||
sokoke_widget_copy_clipboard (GtkWidget* widget,
|
||||
const gchar* text,
|
||||
GtkClipboardGetFunc get_cb,
|
||||
gpointer owner);
|
||||
const gchar* text);
|
||||
|
||||
GtkWidget*
|
||||
sokoke_search_entry_new (const gchar* placeholder_text);
|
||||
gchar*
|
||||
sokoke_build_thumbnail_path (const gchar* name);
|
||||
|
||||
gchar*
|
||||
midori_download_prepare_tooltip_text (WebKitDownload* download);
|
||||
|
||||
#endif /* !__SOKOKE_H__ */
|
||||
|
|
|
@ -7,10 +7,10 @@ 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 GCR GRANITE ZEITGEIST'
|
||||
'LIBNOTIFY WEBKIT JAVASCRIPTCOREGTK LIBXML X11 XSS WS2_32 OPENSSL HILDON' \
|
||||
'HILDON_FM'
|
||||
|
||||
if progressive:
|
||||
if progressive or Options.commands['check']:
|
||||
obj = bld.new_task_gen ('cc', 'staticlib')
|
||||
obj.target = 'midori-core'
|
||||
obj.includes = '.. ../katze . ../toolbars'
|
||||
|
@ -18,14 +18,10 @@ if progressive:
|
|||
obj.uselib = libs
|
||||
obj.add_marshal_file ('marshal.list', 'midori_cclosure_marshal')
|
||||
obj.install_path = None
|
||||
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'
|
||||
obj.packages = 'glib-2.0 gio-2.0 gtk+-2.0 libsoup-2.4 webkit-1.0'
|
||||
bld.add_group ()
|
||||
|
||||
if progressive:
|
||||
obj = bld.new_task_gen ('cc', 'program')
|
||||
obj.target = 'midori'
|
||||
obj.includes = '.. ../katze . ../panels'
|
||||
|
@ -34,3 +30,12 @@ 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'
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
#include "midori-browser.h"
|
||||
#include "midori-platform.h"
|
||||
#include "midori-view.h"
|
||||
#include "midori-core.h"
|
||||
#include "midori-viewable.h"
|
||||
|
||||
#include <glib/gi18n.h>
|
||||
#include <string.h>
|
||||
|
@ -29,8 +29,7 @@ gboolean
|
|||
midori_browser_edit_bookmark_dialog_new (MidoriBrowser* browser,
|
||||
KatzeItem* bookmark,
|
||||
gboolean new_bookmark,
|
||||
gboolean is_folder,
|
||||
GtkWidget* proxy);
|
||||
gboolean is_folder);
|
||||
|
||||
void
|
||||
midori_browser_open_bookmark (MidoriBrowser* browser,
|
||||
|
@ -120,87 +119,66 @@ midori_bookmarks_get_stock_id (MidoriViewable* viewable)
|
|||
return STOCK_BOOKMARKS;
|
||||
}
|
||||
|
||||
/* TODO: Function never used */
|
||||
void
|
||||
midori_bookmarks_export_array_db (sqlite3* db,
|
||||
KatzeArray* array,
|
||||
gint64 parentid)
|
||||
const gchar* folder)
|
||||
{
|
||||
KatzeArray* root_array;
|
||||
KatzeArray* subarray;
|
||||
KatzeItem* item;
|
||||
GList* list;
|
||||
gchar* parent_id;
|
||||
|
||||
parent_id = g_strdup_printf ("%" G_GINT64_FORMAT, parentid);
|
||||
if (!(root_array = midori_array_query (array, "*", "parentid = %q", parent_id)))
|
||||
{
|
||||
g_free (parent_id);
|
||||
if (!(root_array = midori_array_query (array, "*", "folder='%q'", folder)))
|
||||
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_meta_integer (item, "parentid"));
|
||||
midori_bookmarks_export_array_db (db, subarray, katze_item_get_name (item));
|
||||
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,
|
||||
gint64 parentid)
|
||||
const gchar* folder)
|
||||
{
|
||||
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), id);
|
||||
midori_bookmarks_import_array_db (db, KATZE_ARRAY (item), folder);
|
||||
midori_bookmarks_insert_item_db (db, item, folder);
|
||||
}
|
||||
g_list_free (list);
|
||||
}
|
||||
|
||||
static KatzeArray*
|
||||
midori_bookmarks_read_from_db (MidoriBookmarks* bookmarks,
|
||||
gint64 parentid,
|
||||
const gchar* folder,
|
||||
const gchar* keyword)
|
||||
{
|
||||
KatzeArray* array;
|
||||
|
||||
if (keyword && *keyword)
|
||||
array = midori_array_query (bookmarks->array,
|
||||
"id, parentid, title, uri, desc, app, toolbar, pos_panel, pos_bar", "title LIKE '%%%q%%'", keyword);
|
||||
else
|
||||
{
|
||||
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);
|
||||
}
|
||||
"uri, title, desc, app, toolbar, folder", "title LIKE '%%%q%%'", keyword);
|
||||
else
|
||||
array = midori_array_query (bookmarks->array,
|
||||
"id, parentid, title, uri, desc, app, toolbar, pos_panel, pos_bar", "parentid IS NULL", NULL);
|
||||
}
|
||||
"uri, title, desc, app, toolbar, folder", "folder = '%q'", folder);
|
||||
return array ? array : katze_array_new (KATZE_TYPE_ITEM);
|
||||
}
|
||||
|
||||
|
@ -208,7 +186,7 @@ static void
|
|||
midori_bookmarks_read_from_db_to_model (MidoriBookmarks* bookmarks,
|
||||
GtkTreeStore* model,
|
||||
GtkTreeIter* parent,
|
||||
gint64 parentid,
|
||||
const gchar* folder,
|
||||
const gchar* keyword)
|
||||
{
|
||||
KatzeArray* array;
|
||||
|
@ -216,7 +194,7 @@ midori_bookmarks_read_from_db_to_model (MidoriBookmarks* bookmarks,
|
|||
KatzeItem* item;
|
||||
GtkTreeIter child;
|
||||
|
||||
array = midori_bookmarks_read_from_db (bookmarks, parentid, keyword);
|
||||
array = midori_bookmarks_read_from_db (bookmarks, folder, 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);
|
||||
|
@ -230,30 +208,23 @@ midori_bookmarks_read_from_db_to_model (MidoriBookmarks* bookmarks,
|
|||
g_object_unref (item);
|
||||
}
|
||||
|
||||
gint64
|
||||
void
|
||||
midori_bookmarks_insert_item_db (sqlite3* db,
|
||||
KatzeItem* item,
|
||||
gint64 parentid)
|
||||
const gchar* folder)
|
||||
{
|
||||
gchar* sqlcmd;
|
||||
char* errmsg = NULL;
|
||||
KatzeItem* old_parent;
|
||||
gchar* new_parentid;
|
||||
gchar* id = NULL;
|
||||
const gchar* parent;
|
||||
const gchar* uri = NULL;
|
||||
const gchar* desc = NULL;
|
||||
gint64 seq = 0;
|
||||
|
||||
/* Bookmarks must have a name, import may produce invalid items */
|
||||
g_return_val_if_fail (katze_item_get_name (item), seq);
|
||||
g_return_if_fail (katze_item_get_name (item));
|
||||
|
||||
if (!db)
|
||||
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");
|
||||
return;
|
||||
|
||||
if (KATZE_ITEM_IS_BOOKMARK (item))
|
||||
uri = katze_item_get_uri (item);
|
||||
|
@ -263,57 +234,30 @@ midori_bookmarks_insert_item_db (sqlite3* db,
|
|||
|
||||
/* Use folder, otherwise fallback to parent folder */
|
||||
old_parent = katze_item_get_parent (item);
|
||||
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"));
|
||||
if (folder && *folder)
|
||||
parent = folder;
|
||||
else if (old_parent && katze_item_get_name (old_parent))
|
||||
parent = katze_item_get_name (old_parent);
|
||||
else
|
||||
new_parentid = g_strdup_printf ("NULL");
|
||||
parent = "";
|
||||
|
||||
sqlcmd = sqlite3_mprintf (
|
||||
"INSERT INTO bookmarks (id, parentid, title, uri, desc, toolbar, app) "
|
||||
"VALUES (%q, %q, '%q', '%q', '%q', %d, %d)",
|
||||
id,
|
||||
new_parentid,
|
||||
"INSERT into bookmarks (uri, title, desc, folder, toolbar, app) values"
|
||||
" ('%q', '%q', '%q', '%q', %d, %d)",
|
||||
uri ? uri : "",
|
||||
katze_item_get_name (item),
|
||||
katze_str_non_null (uri),
|
||||
katze_str_non_null (desc),
|
||||
desc ? desc : "",
|
||||
parent,
|
||||
katze_item_get_meta_boolean (item, "toolbar"),
|
||||
katze_item_get_meta_boolean (item, "app"));
|
||||
|
||||
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
|
||||
if (sqlite3_exec (db, sqlcmd, NULL, NULL, &errmsg) != SQLITE_OK)
|
||||
{
|
||||
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
|
||||
|
@ -323,9 +267,15 @@ 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, 0, bookmarks->filter);
|
||||
GTK_TREE_STORE (model), NULL, NULL, bookmarks->filter);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -336,7 +286,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, 0, bookmarks->filter);
|
||||
GTK_TREE_STORE (model), NULL, NULL, bookmarks->filter);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -346,7 +296,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, 0, bookmarks->filter);
|
||||
GTK_TREE_STORE (model), NULL, NULL, bookmarks->filter);
|
||||
}
|
||||
|
||||
|
||||
|
@ -359,7 +309,7 @@ midori_bookmarks_row_changed_cb (GtkTreeModel* model,
|
|||
KatzeItem* item;
|
||||
GtkTreeIter parent;
|
||||
KatzeItem* new_parent = NULL;
|
||||
gint64 parentid;
|
||||
const gchar* parent_name;
|
||||
|
||||
gtk_tree_model_get (model, iter, 0, &item, -1);
|
||||
|
||||
|
@ -369,15 +319,15 @@ midori_bookmarks_row_changed_cb (GtkTreeModel* model,
|
|||
|
||||
/* Bookmarks must not be moved into non-folder items */
|
||||
if (!KATZE_ITEM_IS_FOLDER (new_parent))
|
||||
parentid = 0;
|
||||
parent_name = "";
|
||||
else
|
||||
parentid = katze_item_get_meta_integer (new_parent, "id");
|
||||
parent_name = katze_item_get_name (new_parent);
|
||||
}
|
||||
else
|
||||
parentid = 0;
|
||||
parent_name = "";
|
||||
|
||||
katze_array_remove_item (bookmarks->array, item);
|
||||
katze_item_set_meta_integer (item, "parentid", parentid);
|
||||
katze_item_set_meta_string (item, "folder", parent_name);
|
||||
katze_array_add_item (bookmarks->array, item);
|
||||
|
||||
g_object_unref (item);
|
||||
|
@ -391,9 +341,9 @@ midori_bookmarks_add_clicked_cb (GtkWidget* toolitem)
|
|||
MidoriBrowser* browser = midori_browser_get_for_widget (toolitem);
|
||||
/* FIXME: Take selected folder into account */
|
||||
if (g_str_equal (gtk_widget_get_name (toolitem), "BookmarkFolderAdd"))
|
||||
midori_browser_edit_bookmark_dialog_new (browser, NULL, TRUE, TRUE, toolitem);
|
||||
midori_browser_edit_bookmark_dialog_new (browser, NULL, TRUE, TRUE);
|
||||
else
|
||||
midori_browser_edit_bookmark_dialog_new (browser, NULL, TRUE, FALSE, toolitem);
|
||||
midori_browser_edit_bookmark_dialog_new (browser, NULL, TRUE, FALSE);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -408,24 +358,14 @@ 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);
|
||||
}
|
||||
|
||||
browser, item, FALSE, KATZE_ITEM_IS_FOLDER (item));
|
||||
g_object_unref (item);
|
||||
}
|
||||
}
|
||||
|
@ -441,47 +381,6 @@ 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)
|
||||
|
@ -521,7 +420,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 (STOCK_BOOKMARK_ADD);
|
||||
toolitem = gtk_tool_button_new_from_stock (GTK_STOCK_ADD);
|
||||
gtk_widget_set_name (GTK_WIDGET (toolitem), "BookmarkAdd");
|
||||
gtk_widget_set_tooltip_text (GTK_WIDGET (toolitem),
|
||||
_("Add a new bookmark"));
|
||||
|
@ -552,7 +451,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 (STOCK_FOLDER_NEW);
|
||||
toolitem = gtk_tool_button_new_from_stock (GTK_STOCK_DIRECTORY);
|
||||
gtk_widget_set_name (GTK_WIDGET (toolitem), "BookmarkFolderAdd");
|
||||
gtk_widget_set_tooltip_text (GTK_WIDGET (toolitem),
|
||||
_("Add a new folder"));
|
||||
|
@ -596,8 +495,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, 0, NULL);
|
||||
g_signal_connect_after (bookmarks->array, "add-item",
|
||||
midori_bookmarks_read_from_db_to_model (bookmarks, GTK_TREE_STORE (model), NULL, "", NULL);
|
||||
g_signal_connect (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);
|
||||
|
@ -663,8 +562,6 @@ midori_bookmarks_treeview_render_icon_cb (GtkTreeViewColumn* column,
|
|||
if (KATZE_ITEM_IS_FOLDER (item))
|
||||
pixbuf = gtk_widget_render_icon (treeview, GTK_STOCK_DIRECTORY,
|
||||
GTK_ICON_SIZE_MENU, NULL);
|
||||
else if ((pixbuf = katze_item_get_pixbuf (item, treeview)))
|
||||
;
|
||||
else if (KATZE_ITEM_IS_BOOKMARK (item))
|
||||
pixbuf = katze_load_cached_icon (katze_item_get_uri (item), treeview);
|
||||
g_object_set (renderer, "pixbuf", pixbuf, NULL);
|
||||
|
@ -688,11 +585,8 @@ 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);
|
||||
|
||||
|
@ -790,9 +684,7 @@ midori_bookmarks_open_in_tab_activate_cb (GtkWidget* menuitem,
|
|||
KatzeItem* child;
|
||||
KatzeArray* array;
|
||||
|
||||
array = midori_bookmarks_read_from_db (bookmarks,
|
||||
katze_item_get_meta_integer (item, "parentid"), NULL);
|
||||
|
||||
array = midori_bookmarks_read_from_db (bookmarks, katze_item_get_name (item), NULL);
|
||||
g_return_if_fail (KATZE_IS_ARRAY (array));
|
||||
KATZE_ARRAY_FOREACH_ITEM (child, array)
|
||||
{
|
||||
|
@ -948,7 +840,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_meta_integer (item, "id"), NULL);
|
||||
iter, katze_item_get_name (item), NULL);
|
||||
g_object_unref (item);
|
||||
}
|
||||
|
||||
|
@ -990,7 +882,7 @@ midori_bookmarks_filter_timeout_cb (gpointer data)
|
|||
|
||||
gtk_tree_store_clear (treestore);
|
||||
midori_bookmarks_read_from_db_to_model (bookmarks,
|
||||
treestore, NULL, 0, bookmarks->filter);
|
||||
treestore, NULL, NULL, bookmarks->filter);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -1001,16 +893,21 @@ midori_bookmarks_filter_entry_changed_cb (GtkEntry* entry,
|
|||
{
|
||||
if (bookmarks->filter_timeout)
|
||||
g_source_remove (bookmarks->filter_timeout);
|
||||
|
||||
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)
|
||||
{
|
||||
|
@ -1024,8 +921,18 @@ midori_bookmarks_init (MidoriBookmarks* bookmarks)
|
|||
GtkTreeSelection* selection;
|
||||
|
||||
/* Create the filter entry */
|
||||
entry = sokoke_search_entry_new (_("Search Bookmarks"));
|
||||
g_signal_connect_after (entry, "changed",
|
||||
entry = gtk_icon_entry_new ();
|
||||
gtk_icon_entry_set_icon_from_stock (GTK_ICON_ENTRY (entry),
|
||||
GTK_ICON_ENTRY_PRIMARY,
|
||||
GTK_STOCK_FIND);
|
||||
gtk_icon_entry_set_icon_from_stock (GTK_ICON_ENTRY (entry),
|
||||
GTK_ICON_ENTRY_SECONDARY,
|
||||
GTK_STOCK_CLEAR);
|
||||
gtk_icon_entry_set_icon_highlight (GTK_ICON_ENTRY (entry),
|
||||
GTK_ICON_ENTRY_SECONDARY, TRUE);
|
||||
g_signal_connect (entry, "icon-release",
|
||||
G_CALLBACK (midori_bookmarks_filter_entry_clear_cb), bookmarks);
|
||||
g_signal_connect (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);
|
||||
|
@ -1038,14 +945,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_expand (column, TRUE);
|
||||
gtk_tree_view_column_set_sizing (column, GTK_TREE_VIEW_COLUMN_AUTOSIZE);
|
||||
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, TRUE);
|
||||
gtk_tree_view_column_pack_start (column, renderer_text, FALSE);
|
||||
gtk_tree_view_column_set_cell_data_func (column, renderer_text,
|
||||
(GtkTreeCellDataFunc)midori_bookmarks_treeview_render_text_cb,
|
||||
treeview, NULL);
|
||||
|
|
|
@ -40,19 +40,15 @@ midori_bookmarks_get_type (void);
|
|||
GtkWidget*
|
||||
midori_bookmarks_new (void);
|
||||
|
||||
gint64
|
||||
void
|
||||
midori_bookmarks_insert_item_db (sqlite3* db,
|
||||
KatzeItem* item,
|
||||
gint64 parentid);
|
||||
const gchar* folder);
|
||||
|
||||
void
|
||||
midori_bookmarks_import_array_db (sqlite3* db,
|
||||
KatzeArray* array,
|
||||
gint64 parentid);
|
||||
|
||||
gboolean
|
||||
midori_bookmarks_update_item_db (sqlite3* db,
|
||||
KatzeItem* item);
|
||||
const gchar* folder);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#include "midori-app.h"
|
||||
#include "midori-extension.h"
|
||||
#include "midori-platform.h"
|
||||
#include "midori-viewable.h"
|
||||
#include "midori-core.h"
|
||||
|
||||
#include <glib/gi18n.h>
|
||||
|
@ -93,7 +94,7 @@ midori_extensions_get_label (MidoriViewable* viewable)
|
|||
static const gchar*
|
||||
midori_extensions_get_stock_id (MidoriViewable* viewable)
|
||||
{
|
||||
return STOCK_EXTENSION;
|
||||
return STOCK_EXTENSIONS;
|
||||
}
|
||||
|
||||
static GtkWidget*
|
||||
|
@ -284,7 +285,6 @@ 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,17 +305,13 @@ 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);
|
||||
}
|
||||
}
|
||||
|
@ -332,17 +328,13 @@ 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);
|
||||
}
|
||||
}
|
||||
|
@ -462,9 +454,10 @@ 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_expand (column, TRUE);
|
||||
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, TRUE);
|
||||
gtk_tree_view_column_pack_start (column, renderer_text, FALSE);
|
||||
gtk_tree_view_column_set_expand (column, TRUE);
|
||||
gtk_tree_view_column_set_cell_data_func (column, renderer_text,
|
||||
(GtkTreeCellDataFunc)midori_extensions_treeview_render_text_cb,
|
||||
extensions->treeview, NULL);
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
#include "midori-browser.h"
|
||||
#include "midori-platform.h"
|
||||
#include "midori-view.h"
|
||||
#include "midori-core.h"
|
||||
#include "midori-viewable.h"
|
||||
|
||||
#include <glib/gi18n.h>
|
||||
#include <string.h>
|
||||
|
@ -28,8 +28,7 @@ void
|
|||
midori_browser_edit_bookmark_dialog_new (MidoriBrowser* browser,
|
||||
KatzeItem* bookmark,
|
||||
gboolean new_bookmark,
|
||||
gboolean is_folder,
|
||||
GtkWidget* proxy);
|
||||
gboolean is_folder);
|
||||
|
||||
|
||||
struct _MidoriHistory
|
||||
|
@ -117,59 +116,18 @@ midori_history_get_stock_id (MidoriViewable* viewable)
|
|||
return STOCK_HISTORY;
|
||||
}
|
||||
|
||||
#if !GLIB_CHECK_VERSION (2, 26, 0)
|
||||
static gint
|
||||
sokoke_days_between (const time_t* day1,
|
||||
const time_t* day2)
|
||||
{
|
||||
GDate* date1;
|
||||
GDate* date2;
|
||||
gint age;
|
||||
|
||||
date1 = g_date_new ();
|
||||
date2 = g_date_new ();
|
||||
|
||||
g_date_set_time_t (date1, *day1);
|
||||
g_date_set_time_t (date2, *day2);
|
||||
|
||||
age = g_date_days_between (date1, date2);
|
||||
|
||||
g_date_free (date1);
|
||||
g_date_free (date2);
|
||||
|
||||
return age;
|
||||
}
|
||||
#endif
|
||||
|
||||
static gchar*
|
||||
midori_history_format_date (KatzeItem *item)
|
||||
{
|
||||
gint64 day = katze_item_get_added (item);
|
||||
gchar* sdate;
|
||||
gint age;
|
||||
#if GLIB_CHECK_VERSION (2, 26, 0)
|
||||
GDateTime* now = g_date_time_new_now_local ();
|
||||
GDateTime* then = g_date_time_new_from_unix_local (day);
|
||||
age = g_date_time_get_day_of_year (now) - g_date_time_get_day_of_year (then);
|
||||
if (g_date_time_get_year (now) != g_date_time_get_year (then))
|
||||
age = 999;
|
||||
|
||||
if (age == 0)
|
||||
sdate = g_strdup (_("Today"));
|
||||
else if (age == 1)
|
||||
sdate = g_strdup (_("Yesterday"));
|
||||
else if (age < 7)
|
||||
sdate = g_strdup_printf (ngettext ("%d day ago",
|
||||
"%d days ago", (gint)age), (gint)age);
|
||||
else if (age == 7)
|
||||
sdate = g_strdup (_("A week ago"));
|
||||
else
|
||||
sdate = g_date_time_format (then, "%x");
|
||||
#else
|
||||
gint64 day;
|
||||
gchar token[50];
|
||||
gchar* sdate;
|
||||
time_t current_time;
|
||||
|
||||
current_time = time (NULL);
|
||||
day = katze_item_get_added (item);
|
||||
|
||||
age = sokoke_days_between ((time_t*)&day, ¤t_time);
|
||||
|
||||
/* A negative age is a date in the future, the clock is probably off */
|
||||
|
@ -189,7 +147,6 @@ midori_history_format_date (KatzeItem *item)
|
|||
sdate = g_strdup (_("Today"));
|
||||
else
|
||||
sdate = g_strdup (_("Yesterday"));
|
||||
#endif
|
||||
return sdate;
|
||||
}
|
||||
|
||||
|
@ -374,7 +331,6 @@ midori_history_bookmark_add_cb (GtkWidget* menuitem,
|
|||
GtkTreeIter iter;
|
||||
KatzeItem* item = NULL;
|
||||
|
||||
GtkWidget* proxy = GTK_IS_TOOL_ITEM (menuitem) ? menuitem : NULL;
|
||||
MidoriBrowser* browser = midori_browser_get_for_widget (GTK_WIDGET (history));
|
||||
if (katze_tree_view_get_selected_iter (GTK_TREE_VIEW (history->treeview),
|
||||
&model, &iter))
|
||||
|
@ -382,11 +338,11 @@ midori_history_bookmark_add_cb (GtkWidget* menuitem,
|
|||
|
||||
if (KATZE_IS_ITEM (item) && katze_item_get_uri (item))
|
||||
{
|
||||
midori_browser_edit_bookmark_dialog_new (browser, item, TRUE, FALSE, proxy);
|
||||
midori_browser_edit_bookmark_dialog_new (browser, item, TRUE, FALSE);
|
||||
g_object_unref (item);
|
||||
}
|
||||
else
|
||||
midori_browser_edit_bookmark_dialog_new (browser, NULL, TRUE, FALSE, proxy);
|
||||
midori_browser_edit_bookmark_dialog_new (browser, NULL, TRUE, FALSE);
|
||||
}
|
||||
|
||||
static GtkWidget*
|
||||
|
@ -456,8 +412,9 @@ midori_history_add_item_cb (KatzeArray* array,
|
|||
GtkTreeModel* model = gtk_tree_view_get_model (treeview);
|
||||
GtkTreeIter iter;
|
||||
KatzeItem* today;
|
||||
time_t current_time = time (NULL);
|
||||
time_t current_time;
|
||||
|
||||
current_time = time (NULL);
|
||||
if (gtk_tree_model_iter_children (model, &iter, NULL))
|
||||
{
|
||||
gint64 day;
|
||||
|
@ -466,18 +423,7 @@ midori_history_add_item_cb (KatzeArray* array,
|
|||
gtk_tree_model_get (model, &iter, 0, &today, -1);
|
||||
|
||||
day = katze_item_get_added (today);
|
||||
#if GLIB_CHECK_VERSION (2, 26, 0)
|
||||
has_today = g_date_time_get_day_of_month (
|
||||
g_date_time_new_from_unix_local (day))
|
||||
== g_date_time_get_day_of_month (
|
||||
g_date_time_new_from_unix_local (current_time))
|
||||
&& g_date_time_get_day_of_year (
|
||||
g_date_time_new_from_unix_local (day))
|
||||
== g_date_time_get_day_of_year (
|
||||
g_date_time_new_from_unix_local (current_time));
|
||||
#else
|
||||
has_today = sokoke_days_between ((time_t*)&day, ¤t_time) == 0;
|
||||
#endif
|
||||
g_object_unref (today);
|
||||
if (has_today)
|
||||
{
|
||||
|
@ -594,8 +540,6 @@ midori_history_treeview_render_icon_cb (GtkTreeViewColumn* column,
|
|||
|
||||
if (!item)
|
||||
pixbuf = NULL;
|
||||
else if ((pixbuf = katze_item_get_pixbuf (item, treeview)))
|
||||
;
|
||||
else if (katze_item_get_uri (item))
|
||||
pixbuf = katze_load_cached_icon (katze_item_get_uri (item), treeview);
|
||||
else
|
||||
|
@ -624,14 +568,11 @@ 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,
|
||||
"ellipsize", PANGO_ELLIPSIZE_END,
|
||||
NULL);
|
||||
g_object_set (renderer, "markup", NULL, "text", formatted, NULL);
|
||||
g_free (formatted);
|
||||
}
|
||||
else
|
||||
|
@ -967,11 +908,17 @@ 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);
|
||||
|
||||
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
|
||||
midori_history_filter_entry_clear_cb (GtkEntry* entry,
|
||||
gint icon_pos,
|
||||
gint button,
|
||||
MidoriHistory* history)
|
||||
{
|
||||
if (icon_pos == GTK_ICON_ENTRY_SECONDARY)
|
||||
gtk_entry_set_text (entry, "");
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -994,8 +941,19 @@ midori_history_init (MidoriHistory* history)
|
|||
GtkTreeSelection* selection;
|
||||
|
||||
/* Create the filter entry */
|
||||
entry = sokoke_search_entry_new (_("Search History"));
|
||||
g_signal_connect_after (entry, "changed",
|
||||
entry = gtk_icon_entry_new ();
|
||||
gtk_icon_entry_set_icon_from_stock (GTK_ICON_ENTRY (entry),
|
||||
GTK_ICON_ENTRY_PRIMARY,
|
||||
GTK_STOCK_FIND);
|
||||
gtk_icon_entry_set_icon_from_stock (GTK_ICON_ENTRY (entry),
|
||||
GTK_ICON_ENTRY_SECONDARY,
|
||||
GTK_STOCK_CLEAR);
|
||||
gtk_icon_entry_set_icon_highlight (GTK_ICON_ENTRY (entry),
|
||||
GTK_ICON_ENTRY_SECONDARY,
|
||||
TRUE);
|
||||
g_signal_connect (entry, "icon-release",
|
||||
G_CALLBACK (midori_history_filter_entry_clear_cb), history);
|
||||
g_signal_connect (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);
|
||||
|
@ -1008,14 +966,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_expand (column, TRUE);
|
||||
gtk_tree_view_column_set_sizing (column, GTK_TREE_VIEW_COLUMN_AUTOSIZE);
|
||||
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, TRUE);
|
||||
gtk_tree_view_column_pack_start (column, renderer_text, FALSE);
|
||||
gtk_tree_view_column_set_cell_data_func (column, renderer_text,
|
||||
(GtkTreeCellDataFunc)midori_history_treeview_render_text_cb,
|
||||
treeview, NULL);
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue