1 module easyd.gtk.dialogs; 2 3 // (C) 2014-2019 by Matthias Rossmy 4 // This file is distributed under the "Fair Use License v2" 5 6 import easyd.string; 7 import easyd.gtk.base; 8 import easyd.gtk.widgets; 9 import std.string; 10 11 import gtk.Dialog; 12 import gtk.Window; 13 import gtk.Label; 14 import gtk.CheckButton; 15 import gtk.ToggleButton; 16 import gtk.FileChooserDialog; 17 import gtk.FileFilter; 18 19 struct Dialog 20 { 21 BindingSet bindings; 22 gtk.Dialog.Dialog gtkDlg; 23 GridLayout layout; 24 int row = 0; 25 26 this(Window parent, string title="", string[] buttonsText = ["OK"/*.tr*/,"Cancel"/*.tr*/], int[] responses = [1,2]) 27 { 28 gtkDlg = new gtk.Dialog.Dialog(title, parent, DialogFlags.MODAL | DialogFlags.DESTROY_WITH_PARENT, buttonsText, cast(GtkResponseType[]) responses); 29 layout = new GridLayout; 30 layout.margin = 5; 31 layout.spacing=5; 32 gtkDlg.getContentArea.packEnd(layout,true,true,0); 33 } 34 35 ~this() 36 { 37 if(gtkDlg !is null) gtkDlg.destroy(); 38 } 39 40 T add(T)(T widget) 41 { 42 widget.setHexpand(1); 43 layout.attach(widget,0,row++,2,1); 44 return widget; 45 } 46 47 void add(string label) 48 { 49 auto l = new Label(label); 50 l.setAlignment(0,0.5); 51 layout.attach(l,0,row++,2,1); 52 } 53 54 T add(T)(string label, T widget) 55 { 56 auto l = new Label(label); 57 l.setAlignment(0,0.5); 58 layout.attach(l,0,row++,1,1); 59 return layout.addRightOf(l,widget,1,1,true); 60 } 61 62 void add(T,TData)(ref TData data, string label, T widget) 63 { 64 bindings.add(data,add(label,widget)); 65 } 66 67 int runAndGetButtonID(int okId=1) 68 { 69 bindings.load; 70 gtkDlg.showAll; 71 int result = cast(int)(gtkDlg.run); 72 gtkDlg.hide; 73 if(result==okId) bindings.apply; 74 return result; 75 } 76 77 bool run(int okId=1) 78 { 79 return runAndGetButtonID(okId)==okId; 80 } 81 82 void return1() 83 { 84 gtkDlg.response(cast(GtkResponseType)1); 85 } 86 } 87 88 void showMessage(Window parent, string s, MessageType t = MessageType.INFO) 89 { 90 showMessage(parent,"",s,t); 91 } 92 93 void showMessage(Window parent, string title, string s, MessageType t = MessageType.INFO) 94 { 95 auto d = Dialog(parent,title,[t==MessageType.ERROR? "Close"/*.tr*/ : "OK"/*.tr*/],[1]); 96 d.add(s); 97 if(title.length>0) d.gtkDlg.setDefaultSize(200,1); 98 d.run; 99 } 100 101 bool confirm(Window parent, string question) 102 { 103 return confirm(parent,"",question); 104 } 105 106 bool confirm(Window parent, string title, string question) 107 { 108 auto d = Dialog(parent,title,["Yes"/*.tr*/,"No"/*.tr*/],[1,2]); 109 d.add(question); 110 return d.run==1; 111 } 112 113 bool stringDlg(Window parent, out string result, string title="", string text="", bool password=false) 114 { 115 auto d = new Dialog(parent,title); 116 117 if(text.length>0) d.add(text); 118 119 auto l = new LineEdit; 120 l.onPressEnter ~= &d.return1; 121 d.add(l); 122 123 if(password) 124 { 125 l.setVisibility(false); 126 struct StringDlgController 127 { 128 CheckButton cb; 129 this(LineEdit l) 130 { 131 cb = new CheckButton("Show password"/*.tr*/); 132 cb.addOnToggled(&cbClick); 133 } 134 void cbClick(ToggleButton t) 135 { 136 l.setVisibility(cb.getActive); 137 } 138 } 139 auto c=StringDlgController(l); 140 d.add(c.cb); 141 } 142 143 if(d.run==1) 144 { 145 result = l.getText; 146 return true; 147 } 148 else 149 { 150 return false; 151 } 152 } 153 154 bool fileDlg(Window parent, ref string result, string filters="*", FileChooserAction action=FileChooserAction.OPEN) 155 { 156 auto fc= new FileChooserDialog("", parent, action); 157 158 auto fl = filters.split; 159 if(action==FileChooserAction.OPEN) 160 { 161 auto ff = new FileFilter; 162 ff.setName(filters); 163 foreach(f;fl) 164 { 165 ff.addPattern(f); 166 } 167 fc.addFilter(ff); 168 } 169 else 170 { 171 foreach(f;fl) 172 { 173 auto ff = new FileFilter; 174 ff.setName(f); 175 ff.addPattern(f); 176 fc.addFilter(ff); 177 } 178 } 179 180 fc.selectFilename(result); 181 182 bool ok = fc.run() == ResponseType.OK; 183 if (ok) 184 { 185 result = fc.getFilename; 186 string f = fc.getFilter.getName; 187 if(f.startsWith("*") && f.countChar('*')==1 && !result.endsWith(f.subStr(1))) result ~= f.subStr(1); 188 } 189 fc.destroy(); 190 return ok; 191 }