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