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.ComboBoxText;
26 
27 private import glib.ConstructionException;
28 private import glib.Str;
29 private import gobject.Signals;
30 private import gtk.ComboBox;
31 private import gtk.TreeIter;
32 private import gtk.TreeModelIF;
33 public  import gtkc.gdktypes;
34 private import gtkc.gtk;
35 public  import gtkc.gtktypes;
36 private import std.algorithm;
37 
38 
39 /**
40  * A GtkComboBoxText is a simple variant of #GtkComboBox that hides
41  * the model-view complexity for simple text-only use cases.
42  * 
43  * To create a GtkComboBoxText, use gtk_combo_box_text_new() or
44  * gtk_combo_box_text_new_with_entry().
45  * 
46  * You can add items to a GtkComboBoxText with
47  * gtk_combo_box_text_append_text(), gtk_combo_box_text_insert_text()
48  * or gtk_combo_box_text_prepend_text() and remove options with
49  * gtk_combo_box_text_remove().
50  * 
51  * If the GtkComboBoxText contains an entry (via the “has-entry” property),
52  * its contents can be retrieved using gtk_combo_box_text_get_active_text().
53  * The entry itself can be accessed by calling gtk_bin_get_child() on the
54  * combo box.
55  * 
56  * You should not call gtk_combo_box_set_model() or attempt to pack more cells
57  * into this combo box via its GtkCellLayout interface.
58  * 
59  * # GtkComboBoxText as GtkBuildable
60  * 
61  * The GtkComboBoxText implementation of the GtkBuildable interface supports
62  * adding items directly using the <items> element and specifying <item>
63  * elements for each item. Each <item> element can specify the “id”
64  * corresponding to the appended text and also supports the regular
65  * translation attributes “translatable”, “context” and “comments”.
66  * 
67  * Here is a UI definition fragment specifying GtkComboBoxText items:
68  * |[
69  * <object class="GtkComboBoxText">
70  * <items>
71  * <item translatable="yes" id="factory">Factory</item>
72  * <item translatable="yes" id="home">Home</item>
73  * <item translatable="yes" id="subway">Subway</item>
74  * </items>
75  * </object>
76  * ]|
77  * 
78  * # CSS nodes
79  * 
80  * |[<!-- language="plain" -->
81  * combobox
82  * ╰── box.linked
83  * ├── entry.combo
84  * ├── button.combo
85  * ╰── window.popup
86  * ]|
87  * 
88  * GtkComboBoxText has a single CSS node with name combobox. It adds
89  * the style class .combo to the main CSS nodes of its entry and button
90  * children, and the .linked class to the node of its internal box.
91  */
92 public class ComboBoxText : ComboBox
93 {
94 	/** the main Gtk struct */
95 	protected GtkComboBoxText* gtkComboBoxText;
96 
97 	/** Get the main Gtk struct */
98 	public GtkComboBoxText* getComboBoxTextStruct(bool transferOwnership = false)
99 	{
100 		if (transferOwnership)
101 			ownedRef = false;
102 		return gtkComboBoxText;
103 	}
104 
105 	/** the main Gtk struct as a void* */
106 	protected override void* getStruct()
107 	{
108 		return cast(void*)gtkComboBoxText;
109 	}
110 
111 	protected override void setStruct(GObject* obj)
112 	{
113 		gtkComboBoxText = cast(GtkComboBoxText*)obj;
114 		super.setStruct(obj);
115 	}
116 
117 	/**
118 	 * Sets our main struct and passes it to the parent class.
119 	 */
120 	public this (GtkComboBoxText* gtkComboBoxText, bool ownedRef = false)
121 	{
122 		this.gtkComboBoxText = gtkComboBoxText;
123 		super(cast(GtkComboBox*)gtkComboBoxText, ownedRef);
124 	}
125 
126 	/**
127 	 * Creates a new ComboBoxText, which is a ComboBox just displaying strings.
128 	 * Params:
129 	 *   entry = If true, create an ComboBox with an entry.
130 	 * Throws: ConstructionException GTK+ fails to create the object.
131 	 */
132 	public this (bool entry=true)
133 	{
134 		GtkComboBoxText* p;
135 		if ( entry )
136 		{
137 			// GtkWidget* gtk_combo_box_text_new_with_entry (void);
138 			p = cast(GtkComboBoxText*)gtk_combo_box_text_new_with_entry();
139 		}
140 		else
141 		{
142 			// GtkWidget* gtk_combo_box_text_new (void);
143 			p = cast(GtkComboBoxText*)gtk_combo_box_text_new();
144 		}
145 		
146 		if(p is null)
147 		{
148 			throw new ConstructionException("null returned by gtk_combo_box_new");
149 		}
150 		
151 		this(p);
152 	}
153 	
154 	/** */
155 	public void setActiveText(string text, bool insert=false)
156 	{
157 		int active = 0;
158 		setActive(0);
159 		while ( getActive() >= 0 ) // returns -1 if end of list if reached
160 		{
161 			if( text == getActiveText() ) return;
162 			++active;
163 			setActive(active);
164 		}
165 		// was not found, the combo has now nothing selected
166 		if ( insert )
167 		{
168 			append("", text);
169 			setActive(active);
170 		}
171 	}
172 	
173 	/** */
174 	int getIndex(string text)
175 	{
176 		TreeIter iter;
177 		TreeModelIF model = getModel();
178 		int index = 0;
179 		bool found = false;
180 		bool end = false;
181 		if ( model.getIterFirst(iter) )
182 		{
183 			iter.setModel(model);
184 			while ( !end && iter !is  null && !found )
185 			{
186 				found = iter.getValueString(0) == text;
187 				if ( !found )
188 				{
189 					end = !model.iterNext(iter);
190 					++index;
191 				}
192 			}
193 		}
194 		else
195 		{
196 			end = true;
197 		}
198 		return end ? -1 : index;
199 	}
200 	
201 	/** */
202 	void prependOrReplaceText(string text)
203 	{
204 		int index = getIndex(text);
205 		if ( index > 0 )
206 		{
207 			remove(index);
208 			prepend("", text);
209 		}
210 		else if ( index == -1 )
211 		{
212 			prepend("", text);
213 		}
214 	}
215 	
216 	protected class OnChangedDelegateWrapper
217 	{
218 		void delegate(ComboBoxText) dlg;
219 		gulong handlerId;
220 		
221 		this(void delegate(ComboBoxText) dlg)
222 		{
223 			this.dlg = dlg;
224 			onChangedListeners ~= this;
225 		}
226 		
227 		void remove(OnChangedDelegateWrapper source)
228 		{
229 			foreach(index, wrapper; onChangedListeners)
230 			{
231 				if (wrapper.handlerId == source.handlerId)
232 				{
233 					onChangedListeners[index] = null;
234 					onChangedListeners = std.algorithm.remove(onChangedListeners, index);
235 					break;
236 				}
237 			}
238 		}
239 	}
240 	OnChangedDelegateWrapper[] onChangedListeners;
241 	
242 	/**
243 	 * The changed signal is emitted when the active
244 	 * item is changed. The can be due to the user selecting
245 	 * a different item from the list, or due to a
246 	 * call to gtk_combo_box_set_active_iter().
247 	 * It will also be emitted while typing into the entry of a combo box
248 	 * with an entry.
249 	 *
250 	 * Since: 2.4
251 	 */
252 	gulong addOnChanged(void delegate(ComboBoxText) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
253 	{
254 		auto wrapper = new OnChangedDelegateWrapper(dlg);
255 		wrapper.handlerId = Signals.connectData(
256 			this,
257 			"changed",
258 			cast(GCallback)&callBackChanged,
259 			cast(void*)wrapper,
260 			cast(GClosureNotify)&callBackChangedDestroy,
261 			connectFlags);
262 		return wrapper.handlerId;
263 	}
264 	
265 	extern(C) static void callBackChanged(GtkComboBoxText* comboboxTextStruct, OnChangedDelegateWrapper wrapper)
266 	{
267 		wrapper.dlg(wrapper.outer);
268 	}
269 	
270 	extern(C) static void callBackChangedDestroy(OnChangedDelegateWrapper wrapper, GClosure* closure)
271 	{
272 		wrapper.remove(wrapper);
273 	}
274 	
275 	protected class OnFormatEntryTextDelegateWrapper
276 	{
277 		string delegate(string, ComboBoxText) dlg;
278 		gulong handlerId;
279 		
280 		this(string delegate(string, ComboBoxText) dlg)
281 		{
282 			this.dlg = dlg;
283 			onFormatEntryTextListeners ~= this;
284 		}
285 		
286 		void remove(OnFormatEntryTextDelegateWrapper source)
287 		{
288 			foreach(index, wrapper; onFormatEntryTextListeners)
289 			{
290 				if (wrapper.handlerId == source.handlerId)
291 				{
292 					onFormatEntryTextListeners[index] = null;
293 					onFormatEntryTextListeners = std.algorithm.remove(onFormatEntryTextListeners, index);
294 					break;
295 				}
296 			}
297 		}
298 	}
299 	OnFormatEntryTextDelegateWrapper[] onFormatEntryTextListeners;
300 	
301 	/**
302 	 * For combo boxes that are created with an entry (See GtkComboBox:has-entry).
303 	 *
304 	 * A signal which allows you to change how the text displayed in a combo box's
305 	 * entry is displayed.
306 	 *
307 	 * Connect a signal handler which returns an allocated string representing
308 	 * @path. That string will then be used to set the text in the combo box's entry.
309 	 * The default signal handler uses the text from the GtkComboBox::entry-text-column
310 	 * model column.
311 	 *
312 	 * Here's an example signal handler which fetches data from the model and
313 	 * displays it in the entry.
314 	 * |[<!-- language="C" -->
315 	 * static gchar*
316 	 * format_entry_text_callback (GtkComboBox *combo,
317 	 * const gchar *path,
318 	 * gpointer     user_data)
319 	 * {
320 	 * GtkTreeIter iter;
321 	 * GtkTreeModel model;
322 	 * gdouble      value;
323 	 *
324 	 * model = gtk_combo_box_get_model (combo);
325 	 *
326 	 * gtk_tree_model_get_iter_from_string (model, &iter, path);
327 	 * gtk_tree_model_get (model, &iter,
328 	 * THE_DOUBLE_VALUE_COLUMN, &value,
329 	 * -1);
330 	 *
331 	 * return g_strdup_printf ("%g", value);
332 	 * }
333 	 * ]|
334 	 *
335 	 * Params:
336 	 *     path = the GtkTreePath string from the combo box's current model to format text for
337 	 *
338 	 * Return: a newly allocated string representing @path
339 	 *     for the current GtkComboBox model.
340 	 *
341 	 * Since: 3.4
342 	 */
343 	gulong addOnFormatEntryText(string delegate(string, ComboBoxText) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
344 	{
345 		auto wrapper = new OnFormatEntryTextDelegateWrapper(dlg);
346 		wrapper.handlerId = Signals.connectData(
347 			this,
348 			"format-entry-text",
349 			cast(GCallback)&callBackFormatEntryText,
350 			cast(void*)wrapper,
351 			cast(GClosureNotify)&callBackFormatEntryTextDestroy,
352 			connectFlags);
353 		return wrapper.handlerId;
354 	}
355 	
356 	extern(C) static string callBackFormatEntryText(GtkComboBoxText* comboboxStructText, char* path,OnFormatEntryTextDelegateWrapper wrapper)
357 	{
358 		return wrapper.dlg(Str.toString(path), wrapper.outer);
359 	}
360 	
361 	extern(C) static void callBackFormatEntryTextDestroy(OnFormatEntryTextDelegateWrapper wrapper, GClosure* closure)
362 	{
363 		wrapper.remove(wrapper);
364 	}
365 	
366 	protected class OnMoveActiveDelegateWrapper
367 	{
368 		void delegate(GtkScrollType, ComboBoxText) dlg;
369 		gulong handlerId;
370 		
371 		this(void delegate(GtkScrollType, ComboBoxText) dlg)
372 		{
373 			this.dlg = dlg;
374 			onMoveActiveListeners ~= this;
375 		}
376 		
377 		void remove(OnMoveActiveDelegateWrapper source)
378 		{
379 			foreach(index, wrapper; onMoveActiveListeners)
380 			{
381 				if (wrapper.handlerId == source.handlerId)
382 				{
383 					onMoveActiveListeners[index] = null;
384 					onMoveActiveListeners = std.algorithm.remove(onMoveActiveListeners, index);
385 					break;
386 				}
387 			}
388 		}
389 	}
390 	OnMoveActiveDelegateWrapper[] onMoveActiveListeners;
391 	
392 	/**
393 	 * The ::move-active signal is a
394 	 * [keybinding signal][GtkBindingSignal]
395 	 * which gets emitted to move the active selection.
396 	 *
397 	 * Params:
398 	 *     scrollType = a #GtkScrollType
399 	 *
400 	 * Since: 2.12
401 	 */
402 	gulong addOnMoveActive(void delegate(GtkScrollType, ComboBoxText) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
403 	{
404 		auto wrapper = new OnMoveActiveDelegateWrapper(dlg);
405 		wrapper.handlerId = Signals.connectData(
406 			this,
407 			"move-active",
408 			cast(GCallback)&callBackMoveActive,
409 			cast(void*)wrapper,
410 			cast(GClosureNotify)&callBackMoveActiveDestroy,
411 			connectFlags);
412 		return wrapper.handlerId;
413 	}
414 	
415 	extern(C) static void callBackMoveActive(GtkComboBoxText* comboboxTextStruct, GtkScrollType scrollType,OnMoveActiveDelegateWrapper wrapper)
416 	{
417 		wrapper.dlg(scrollType, wrapper.outer);
418 	}
419 	
420 	extern(C) static void callBackMoveActiveDestroy(OnMoveActiveDelegateWrapper wrapper, GClosure* closure)
421 	{
422 		wrapper.remove(wrapper);
423 	}
424 	
425 	protected class OnPopdownDelegateWrapper
426 	{
427 		bool delegate(ComboBoxText) dlg;
428 		gulong handlerId;
429 		
430 		this(bool delegate(ComboBoxText) dlg)
431 		{
432 			this.dlg = dlg;
433 			onPopdownListeners ~= this;
434 		}
435 		
436 		void remove(OnPopdownDelegateWrapper source)
437 		{
438 			foreach(index, wrapper; onPopdownListeners)
439 			{
440 				if (wrapper.handlerId == source.handlerId)
441 				{
442 					onPopdownListeners[index] = null;
443 					onPopdownListeners = std.algorithm.remove(onPopdownListeners, index);
444 					break;
445 				}
446 			}
447 		}
448 	}
449 	OnPopdownDelegateWrapper[] onPopdownListeners;
450 	
451 	/**
452 	 * The ::popdown signal is a
453 	 * [keybinding signal][GtkBindingSignal]
454 	 * which gets emitted to popdown the combo box list.
455 	 *
456 	 * The default bindings for this signal are Alt+Up and Escape.
457 	 *
458 	 * Since: 2.12
459 	 */
460 	gulong addOnPopdown(bool delegate(ComboBoxText) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
461 	{
462 		auto wrapper = new OnPopdownDelegateWrapper(dlg);
463 		wrapper.handlerId = Signals.connectData(
464 			this,
465 			"popdown",
466 			cast(GCallback)&callBackPopdown,
467 			cast(void*)wrapper,
468 			cast(GClosureNotify)&callBackPopdownDestroy,
469 			connectFlags);
470 		return wrapper.handlerId;
471 	}
472 	
473 	extern(C) static int callBackPopdown(GtkComboBoxText* comboboxTextStruct,OnPopdownDelegateWrapper wrapper)
474 	{
475 		return wrapper.dlg(wrapper.outer);
476 	}
477 	
478 	extern(C) static void callBackPopdownDestroy(OnPopdownDelegateWrapper wrapper, GClosure* closure)
479 	{
480 		wrapper.remove(wrapper);
481 	}
482 	
483 	protected class OnPopupDelegateWrapper
484 	{
485 		void delegate(ComboBoxText) dlg;
486 		gulong handlerId;
487 		
488 		this(void delegate(ComboBoxText) dlg)
489 		{
490 			this.dlg = dlg;
491 			onPopupListeners ~= this;
492 		}
493 		
494 		void remove(OnPopupDelegateWrapper source)
495 		{
496 			foreach(index, wrapper; onPopupListeners)
497 			{
498 				if (wrapper.handlerId == source.handlerId)
499 				{
500 					onPopupListeners[index] = null;
501 					onPopupListeners = std.algorithm.remove(onPopupListeners, index);
502 					break;
503 				}
504 			}
505 		}
506 	}
507 	OnPopupDelegateWrapper[] onPopupListeners;
508 	
509 	/**
510 	 * The ::popup signal is a
511 	 * [keybinding signal][GtkBindingSignal]
512 	 * which gets emitted to popup the combo box list.
513 	 *
514 	 * The default binding for this signal is Alt+Down.
515 	 *
516 	 * Since: 2.12
517 	 */
518 	gulong addOnPopup(void delegate(ComboBoxText) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
519 	{
520 		auto wrapper = new OnPopupDelegateWrapper(dlg);
521 		wrapper.handlerId = Signals.connectData(
522 			this,
523 			"popup",
524 			cast(GCallback)&callBackPopup,
525 			cast(void*)wrapper,
526 			cast(GClosureNotify)&callBackPopupDestroy,
527 			connectFlags);
528 		return wrapper.handlerId;
529 	}
530 	
531 	extern(C) static void callBackPopup(GtkComboBoxText* comboboxTextStruct,OnPopupDelegateWrapper wrapper)
532 	{
533 		wrapper.dlg(wrapper.outer);
534 	}
535 	
536 	extern(C) static void callBackPopupDestroy(OnPopupDelegateWrapper wrapper, GClosure* closure)
537 	{
538 		wrapper.remove(wrapper);
539 	}
540 
541 	/**
542 	 */
543 
544 	/** */
545 	public static GType getType()
546 	{
547 		return gtk_combo_box_text_get_type();
548 	}
549 
550 	/**
551 	 * Appends @text to the list of strings stored in @combo_box.
552 	 * If @id is non-%NULL then it is used as the ID of the row.
553 	 *
554 	 * This is the same as calling gtk_combo_box_text_insert() with a
555 	 * position of -1.
556 	 *
557 	 * Params:
558 	 *     id = a string ID for this value, or %NULL
559 	 *     text = A string
560 	 *
561 	 * Since: 2.24
562 	 */
563 	public void append(string id, string text)
564 	{
565 		gtk_combo_box_text_append(gtkComboBoxText, Str.toStringz(id), Str.toStringz(text));
566 	}
567 
568 	/**
569 	 * Appends @text to the list of strings stored in @combo_box.
570 	 *
571 	 * This is the same as calling gtk_combo_box_text_insert_text() with a
572 	 * position of -1.
573 	 *
574 	 * Params:
575 	 *     text = A string
576 	 *
577 	 * Since: 2.24
578 	 */
579 	public void appendText(string text)
580 	{
581 		gtk_combo_box_text_append_text(gtkComboBoxText, Str.toStringz(text));
582 	}
583 
584 	/**
585 	 * Returns the currently active string in @combo_box, or %NULL
586 	 * if none is selected. If @combo_box contains an entry, this
587 	 * function will return its contents (which will not necessarily
588 	 * be an item from the list).
589 	 *
590 	 * Returns: a newly allocated string containing the
591 	 *     currently active text. Must be freed with g_free().
592 	 *
593 	 * Since: 2.24
594 	 */
595 	public string getActiveText()
596 	{
597 		auto retStr = gtk_combo_box_text_get_active_text(gtkComboBoxText);
598 		
599 		scope(exit) Str.freeString(retStr);
600 		return Str.toString(retStr);
601 	}
602 
603 	/**
604 	 * Inserts @text at @position in the list of strings stored in @combo_box.
605 	 * If @id is non-%NULL then it is used as the ID of the row.  See
606 	 * #GtkComboBox:id-column.
607 	 *
608 	 * If @position is negative then @text is appended.
609 	 *
610 	 * Params:
611 	 *     position = An index to insert @text
612 	 *     id = a string ID for this value, or %NULL
613 	 *     text = A string to display
614 	 *
615 	 * Since: 3.0
616 	 */
617 	public void insert(int position, string id, string text)
618 	{
619 		gtk_combo_box_text_insert(gtkComboBoxText, position, Str.toStringz(id), Str.toStringz(text));
620 	}
621 
622 	/**
623 	 * Inserts @text at @position in the list of strings stored in @combo_box.
624 	 *
625 	 * If @position is negative then @text is appended.
626 	 *
627 	 * This is the same as calling gtk_combo_box_text_insert() with a %NULL
628 	 * ID string.
629 	 *
630 	 * Params:
631 	 *     position = An index to insert @text
632 	 *     text = A string
633 	 *
634 	 * Since: 2.24
635 	 */
636 	public void insertText(int position, string text)
637 	{
638 		gtk_combo_box_text_insert_text(gtkComboBoxText, position, Str.toStringz(text));
639 	}
640 
641 	/**
642 	 * Prepends @text to the list of strings stored in @combo_box.
643 	 * If @id is non-%NULL then it is used as the ID of the row.
644 	 *
645 	 * This is the same as calling gtk_combo_box_text_insert() with a
646 	 * position of 0.
647 	 *
648 	 * Params:
649 	 *     id = a string ID for this value, or %NULL
650 	 *     text = a string
651 	 *
652 	 * Since: 2.24
653 	 */
654 	public void prepend(string id, string text)
655 	{
656 		gtk_combo_box_text_prepend(gtkComboBoxText, Str.toStringz(id), Str.toStringz(text));
657 	}
658 
659 	/**
660 	 * Prepends @text to the list of strings stored in @combo_box.
661 	 *
662 	 * This is the same as calling gtk_combo_box_text_insert_text() with a
663 	 * position of 0.
664 	 *
665 	 * Params:
666 	 *     text = A string
667 	 *
668 	 * Since: 2.24
669 	 */
670 	public void prependText(string text)
671 	{
672 		gtk_combo_box_text_prepend_text(gtkComboBoxText, Str.toStringz(text));
673 	}
674 
675 	/**
676 	 * Removes the string at @position from @combo_box.
677 	 *
678 	 * Params:
679 	 *     position = Index of the item to remove
680 	 *
681 	 * Since: 2.24
682 	 */
683 	public void remove(int position)
684 	{
685 		gtk_combo_box_text_remove(gtkComboBoxText, position);
686 	}
687 
688 	/**
689 	 * Removes all the text entries from the combo box.
690 	 *
691 	 * Since: 3.0
692 	 */
693 	public override void removeAll()
694 	{
695 		gtk_combo_box_text_remove_all(gtkComboBoxText);
696 	}
697 }