1 /*
2  * This file is part of gtkD.
3  *
4  * gtkD is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU Lesser General Public License
6  * as published by the Free Software Foundation; either version 3
7  * of the License, or (at your option) any later version, with
8  * some exceptions, please read the COPYING file.
9  *
10  * gtkD is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public License
16  * along with gtkD; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA
18  */
19 
20 // generated automatically - do not change
21 // find conversion definition on APILookup.txt
22 // implement new conversion functionalities on the wrap.utils pakage
23 
24 
25 module gtk.CssProvider;
26 
27 private import gio.FileIF;
28 private import glib.ConstructionException;
29 private import glib.ErrorG;
30 private import glib.GException;
31 private import glib.Str;
32 private import gobject.ObjectG;
33 private import gobject.Signals;
34 private import gtk.CssSection;
35 private import gtk.StyleProviderIF;
36 private import gtk.StyleProviderT;
37 private import gtkc.gtk;
38 public  import gtkc.gtktypes;
39 private import std.algorithm;
40 
41 
42 /**
43  * GtkCssProvider is an object implementing the #GtkStyleProvider interface.
44  * It is able to parse [CSS-like][css-overview] input in order to style widgets.
45  * 
46  * An application can make GTK+ parse a specific CSS style sheet by calling
47  * gtk_css_provider_load_from_file() or gtk_css_provider_load_from_resource()
48  * and adding the provider with gtk_style_context_add_provider() or
49  * gtk_style_context_add_provider_for_screen().
50  * 
51  * In addition, certain files will be read when GTK+ is initialized. First, the
52  * file `$XDG_CONFIG_HOME/gtk-3.0/gtk.css` is loaded if it exists. Then, GTK+
53  * loads the first existing file among
54  * `XDG_DATA_HOME/themes/theme-name/gtk-VERSION/gtk.css`,
55  * `$HOME/.themes/theme-name/gtk-VERSION/gtk.css`,
56  * `$XDG_DATA_DIRS/themes/theme-name/gtk-VERSION/gtk.css` and
57  * `DATADIR/share/themes/THEME/gtk-VERSION/gtk.css`, where `THEME` is the name of
58  * the current theme (see the #GtkSettings:gtk-theme-name setting), `DATADIR`
59  * is the prefix configured when GTK+ was compiled (unless overridden by the
60  * `GTK_DATA_PREFIX` environment variable), and `VERSION` is the GTK+ version number.
61  * If no file is found for the current version, GTK+ tries older versions all the
62  * way back to 3.0.
63  * 
64  * In the same way, GTK+ tries to load a gtk-keys.css file for the current
65  * key theme, as defined by #GtkSettings:gtk-key-theme-name.
66  */
67 public class CssProvider : ObjectG, StyleProviderIF
68 {
69 	/** the main Gtk struct */
70 	protected GtkCssProvider* gtkCssProvider;
71 
72 	/** Get the main Gtk struct */
73 	public GtkCssProvider* getCssProviderStruct(bool transferOwnership = false)
74 	{
75 		if (transferOwnership)
76 			ownedRef = false;
77 		return gtkCssProvider;
78 	}
79 
80 	/** the main Gtk struct as a void* */
81 	protected override void* getStruct()
82 	{
83 		return cast(void*)gtkCssProvider;
84 	}
85 
86 	protected override void setStruct(GObject* obj)
87 	{
88 		gtkCssProvider = cast(GtkCssProvider*)obj;
89 		super.setStruct(obj);
90 	}
91 
92 	/**
93 	 * Sets our main struct and passes it to the parent class.
94 	 */
95 	public this (GtkCssProvider* gtkCssProvider, bool ownedRef = false)
96 	{
97 		this.gtkCssProvider = gtkCssProvider;
98 		super(cast(GObject*)gtkCssProvider, ownedRef);
99 	}
100 
101 	// add the StyleProvider capabilities
102 	mixin StyleProviderT!(GtkCssProvider);
103 
104 
105 	/** */
106 	public static GType getType()
107 	{
108 		return gtk_css_provider_get_type();
109 	}
110 
111 	/**
112 	 * Returns a newly created #GtkCssProvider.
113 	 *
114 	 * Returns: A new #GtkCssProvider
115 	 *
116 	 * Throws: ConstructionException GTK+ fails to create the object.
117 	 */
118 	public this()
119 	{
120 		auto p = gtk_css_provider_new();
121 		
122 		if(p is null)
123 		{
124 			throw new ConstructionException("null returned by new");
125 		}
126 		
127 		this(cast(GtkCssProvider*) p, true);
128 	}
129 
130 	/**
131 	 * Returns the provider containing the style settings used as a
132 	 * fallback for all widgets.
133 	 *
134 	 * Returns: The provider used for fallback styling.
135 	 *     This memory is owned by GTK+, and you must not free it.
136 	 */
137 	public static CssProvider getDefault()
138 	{
139 		auto p = gtk_css_provider_get_default();
140 		
141 		if(p is null)
142 		{
143 			return null;
144 		}
145 		
146 		return ObjectG.getDObject!(CssProvider)(cast(GtkCssProvider*) p);
147 	}
148 
149 	/**
150 	 * Loads a theme from the usual theme paths
151 	 *
152 	 * Params:
153 	 *     name = A theme name
154 	 *     variant = variant to load, for example, "dark", or
155 	 *         %NULL for the default
156 	 *
157 	 * Returns: a #GtkCssProvider with the theme loaded.
158 	 *     This memory is owned by GTK+, and you must not free it.
159 	 */
160 	public static CssProvider getNamed(string name, string variant)
161 	{
162 		auto p = gtk_css_provider_get_named(Str.toStringz(name), Str.toStringz(variant));
163 		
164 		if(p is null)
165 		{
166 			return null;
167 		}
168 		
169 		return ObjectG.getDObject!(CssProvider)(cast(GtkCssProvider*) p);
170 	}
171 
172 	/**
173 	 * Loads @data into @css_provider, and by doing so clears any previously loaded
174 	 * information.
175 	 *
176 	 * Params:
177 	 *     data = CSS data loaded in memory
178 	 *     length = the length of @data in bytes, or -1 for NUL terminated strings. If
179 	 *         @length is not -1, the code will assume it is not NUL terminated and will
180 	 *         potentially do a copy.
181 	 *
182 	 * Returns: %TRUE. The return value is deprecated and %FALSE will only be
183 	 *     returned for backwards compatibility reasons if an @error is not
184 	 *     %NULL and a loading error occurred. To track errors while loading
185 	 *     CSS, connect to the #GtkCssProvider::parsing-error signal.
186 	 *
187 	 * Throws: GException on failure.
188 	 */
189 	public bool loadFromData(string data)
190 	{
191 		GError* err = null;
192 		
193 		auto p = gtk_css_provider_load_from_data(gtkCssProvider, Str.toStringz(data), cast(ptrdiff_t)data.length, &err) != 0;
194 		
195 		if (err !is null)
196 		{
197 			throw new GException( new ErrorG(err) );
198 		}
199 		
200 		return p;
201 	}
202 
203 	/**
204 	 * Loads the data contained in @file into @css_provider, making it
205 	 * clear any previously loaded information.
206 	 *
207 	 * Params:
208 	 *     file = #GFile pointing to a file to load
209 	 *
210 	 * Returns: %TRUE. The return value is deprecated and %FALSE will only be
211 	 *     returned for backwards compatibility reasons if an @error is not
212 	 *     %NULL and a loading error occurred. To track errors while loading
213 	 *     CSS, connect to the #GtkCssProvider::parsing-error signal.
214 	 *
215 	 * Throws: GException on failure.
216 	 */
217 	public bool loadFromFile(FileIF file)
218 	{
219 		GError* err = null;
220 		
221 		auto p = gtk_css_provider_load_from_file(gtkCssProvider, (file is null) ? null : file.getFileStruct(), &err) != 0;
222 		
223 		if (err !is null)
224 		{
225 			throw new GException( new ErrorG(err) );
226 		}
227 		
228 		return p;
229 	}
230 
231 	/**
232 	 * Loads the data contained in @path into @css_provider, making it clear
233 	 * any previously loaded information.
234 	 *
235 	 * Params:
236 	 *     path = the path of a filename to load, in the GLib filename encoding
237 	 *
238 	 * Returns: %TRUE. The return value is deprecated and %FALSE will only be
239 	 *     returned for backwards compatibility reasons if an @error is not
240 	 *     %NULL and a loading error occurred. To track errors while loading
241 	 *     CSS, connect to the #GtkCssProvider::parsing-error signal.
242 	 *
243 	 * Throws: GException on failure.
244 	 */
245 	public bool loadFromPath(string path)
246 	{
247 		GError* err = null;
248 		
249 		auto p = gtk_css_provider_load_from_path(gtkCssProvider, Str.toStringz(path), &err) != 0;
250 		
251 		if (err !is null)
252 		{
253 			throw new GException( new ErrorG(err) );
254 		}
255 		
256 		return p;
257 	}
258 
259 	/**
260 	 * Loads the data contained in the resource at @resource_path into
261 	 * the #GtkCssProvider, clearing any previously loaded information.
262 	 *
263 	 * To track errors while loading CSS, connect to the
264 	 * #GtkCssProvider::parsing-error signal.
265 	 *
266 	 * Params:
267 	 *     resourcePath = a #GResource resource path
268 	 *
269 	 * Since: 3.16
270 	 */
271 	public void loadFromResource(string resourcePath)
272 	{
273 		gtk_css_provider_load_from_resource(gtkCssProvider, Str.toStringz(resourcePath));
274 	}
275 
276 	/**
277 	 * Converts the @provider into a string representation in CSS
278 	 * format.
279 	 *
280 	 * Using gtk_css_provider_load_from_data() with the return value
281 	 * from this function on a new provider created with
282 	 * gtk_css_provider_new() will basically create a duplicate of
283 	 * this @provider.
284 	 *
285 	 * Returns: a new string representing the @provider.
286 	 *
287 	 * Since: 3.2
288 	 */
289 	public override string toString()
290 	{
291 		auto retStr = gtk_css_provider_to_string(gtkCssProvider);
292 		
293 		scope(exit) Str.freeString(retStr);
294 		return Str.toString(retStr);
295 	}
296 
297 	protected class OnParsingErrorDelegateWrapper
298 	{
299 		void delegate(CssSection, ErrorG, CssProvider) dlg;
300 		gulong handlerId;
301 		
302 		this(void delegate(CssSection, ErrorG, CssProvider) dlg)
303 		{
304 			this.dlg = dlg;
305 			onParsingErrorListeners ~= this;
306 		}
307 		
308 		void remove(OnParsingErrorDelegateWrapper source)
309 		{
310 			foreach(index, wrapper; onParsingErrorListeners)
311 			{
312 				if (wrapper.handlerId == source.handlerId)
313 				{
314 					onParsingErrorListeners[index] = null;
315 					onParsingErrorListeners = std.algorithm.remove(onParsingErrorListeners, index);
316 					break;
317 				}
318 			}
319 		}
320 	}
321 	OnParsingErrorDelegateWrapper[] onParsingErrorListeners;
322 
323 	/**
324 	 * Signals that a parsing error occurred. the @path, @line and @position
325 	 * describe the actual location of the error as accurately as possible.
326 	 *
327 	 * Parsing errors are never fatal, so the parsing will resume after
328 	 * the error. Errors may however cause parts of the given
329 	 * data or even all of it to not be parsed at all. So it is a useful idea
330 	 * to check that the parsing succeeds by connecting to this signal.
331 	 *
332 	 * Note that this signal may be emitted at any time as the css provider
333 	 * may opt to defer parsing parts or all of the input to a later time
334 	 * than when a loading function was called.
335 	 *
336 	 * Params:
337 	 *     section = section the error happened in
338 	 *     error = The parsing error
339 	 */
340 	gulong addOnParsingError(void delegate(CssSection, ErrorG, CssProvider) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
341 	{
342 		auto wrapper = new OnParsingErrorDelegateWrapper(dlg);
343 		wrapper.handlerId = Signals.connectData(
344 			this,
345 			"parsing-error",
346 			cast(GCallback)&callBackParsingError,
347 			cast(void*)wrapper,
348 			cast(GClosureNotify)&callBackParsingErrorDestroy,
349 			connectFlags);
350 		return wrapper.handlerId;
351 	}
352 	
353 	extern(C) static void callBackParsingError(GtkCssProvider* cssproviderStruct, GtkCssSection* section, GError* error, OnParsingErrorDelegateWrapper wrapper)
354 	{
355 		wrapper.dlg(ObjectG.getDObject!(CssSection)(section), new ErrorG(error), wrapper.outer);
356 	}
357 	
358 	extern(C) static void callBackParsingErrorDestroy(OnParsingErrorDelegateWrapper wrapper, GClosure* closure)
359 	{
360 		wrapper.remove(wrapper);
361 	}
362 }