1 module ui.file_chooser;
2 
3 import gtk.Main, gtk.Builder, gtk.Widget, gtk.Window, gdk.Event, gtk.Container;
4 import gtk.FileFilter, gtk.Expander, gtk.RadioButton, gtk.ToggleButton;
5 import gtk.Button;
6 
7 import std.conv;
8 
9 public import gtkc.gtktypes, gtk.FileChooserDialog;
10 import dcpu.ram_io;
11 
12 /**
13  * Custom FileChooserDialog that select a file for open or save data for FCPU-16
14  */
15 class FileOpener : FileChooserDialog {
16 private:
17   Builder builder;          /// Builder used to load from xml file the file options widget
18   Container foptions;
19   FileFilter[] filters;     /// File filters
20 
21   RadioButton rbut_hexdump; /// Radio button Hexdecimal Dump file
22   RadioButton rbut_dat;     /// Radio button Assembler DATs file
23   RadioButton rbut_base2;   /// Radio button for list of base 2 numbers
24   RadioButton rbut_raw;     /// Radio buttion Binary RAW file
25 
26   RadioButton rbut_big;     /// Radio button for RAW big endian file
27   RadioButton rbut_little;  /// Radio button for RAW little endian file
28 
29 public:
30 
31   TypeHexFile type = TypeHexFile.hexd;
32 
33   /**
34    * Params:
35    *  father  = Father Window
36    *  open    = TRUE if is choosing a file to open it. FALSE to save a file
37    */
38   this (Window father, bool open = true) {
39     if (open) {
40       super("Open file", father, FileChooserAction.OPEN, ["Open", "Cancel"], [ResponseType.ACCEPT, ResponseType.CANCEL]);
41     } else {
42       super("Save file", father, FileChooserAction.SAVE, ["Save", "Cancel"], [ResponseType.ACCEPT, ResponseType.CANCEL]);
43     }
44 
45     builder = new Builder ();
46     if (! builder.addFromString (import("file_chooser.ui"))) {
47       throw new Exception("Can't find file file_chooser.ui");
48     }
49 
50     // Create file filters
51     filters ~= new FileFilter();
52     filters[0].setName("Hexdump file (*.hex)");
53     filters[0].addPattern("*.hex");
54     filters ~= new FileFilter();
55     filters[1].setName("Assembler file (*.dasm|*.dasm16|*.asm)");
56     filters[1].addPattern("*.dasm");
57     filters[1].addPattern("*.dasm16");
58     filters[1].addPattern("*.asm");
59     filters ~= new FileFilter();
60     filters[2].setName("Base2 dump (*.txt)");
61     filters[2].addPattern("*.txt");
62     filters ~= new FileFilter();
63     filters[3].setName("Raw file (*.bin|*.raw)");
64     filters[3].addPattern("*.bin");
65     filters[3].addPattern("*.raw");
66     filters ~= new FileFilter();
67     filters[4].setName("All files");
68     filters[4].addPattern("*");
69 
70     foreach (ref f; filters) // And add it
71       this.addFilter(f);
72 
73     this.setCurrentFolderUri("/home/");
74 
75     // Get File options widget
76     foptions = cast(Container) builder.getObject ("file_options");
77     if (foptions is null) {
78       throw new Exception("Can't find file_options widget");
79     }
80 
81     foptions.reparent(this);
82     this.setExtraWidget(foptions);
83 
84     // Try to grab radiobuttons
85     rbut_hexdump = cast(RadioButton) builder.getObject ("rbut_hexdump");
86     if (rbut_hexdump is null) {
87       throw new Exception("Can't find rbut_hexdump widget");
88     }
89     rbut_dat = cast(RadioButton) builder.getObject ("rbut_dat");
90     if (rbut_dat is null) {
91       throw new Exception("Can't find rbut_dat widget");
92     }
93     rbut_base2 = cast(RadioButton) builder.getObject ("rbut_base2");
94     if (rbut_base2 is null) {
95       throw new Exception("Can't find rbut_base2 widget");
96     }
97     rbut_raw = cast(RadioButton) builder.getObject ("rbut_raw");
98     if (rbut_raw is null) {
99       throw new Exception("Can't find rbut_raw widget");
100     }
101 
102     // Big & little endian
103     rbut_big = cast(RadioButton) builder.getObject ("rbut_big");
104     if (rbut_big is null) {
105       throw new Exception("Can't find rbut_big widget");
106     }
107     rbut_little = cast(RadioButton) builder.getObject ("rbut_little");
108     if (rbut_little is null) {
109       throw new Exception("Can't find rbut_little widget");
110     }
111 
112     // Setup buttons and state
113     type = TypeHexFile.dat;
114     rbut_dat.setActive(true);
115 
116 
117     // Set what to do to the radio buttons
118     rbut_hexdump.addOnToggled( (ToggleButton rbut) {
119       if(rbut.getActive()) {
120         rbut_big.setSensitive(false);
121         rbut_little.setSensitive(false);
122         this.setFilter(filters[0]);
123         type = TypeHexFile.hexd;
124       }
125     });
126 
127     rbut_dat.addOnToggled( (ToggleButton rbut) {
128       if(rbut.getActive()) {
129         rbut_big.setSensitive(false);
130         rbut_little.setSensitive(false);
131         this.setFilter(filters[1]);
132         type = TypeHexFile.dat;
133       }
134     });
135 
136     rbut_raw.addOnToggled( (ToggleButton rbut) {
137       if(rbut.getActive()) {
138         rbut_big.setSensitive(true);
139         rbut_little.setSensitive(true);
140         rbut_big.setActive(false);
141         rbut_little.setActive(true);
142         this.setFilter(filters[3]);
143         type = TypeHexFile.lraw;
144       }
145     });
146 
147     rbut_base2.addOnToggled( (ToggleButton rbut) {
148       if(rbut.getActive()) {
149         rbut_big.setSensitive(false);
150         rbut_little.setSensitive(false);
151         this.setFilter(filters[2]);
152         type = TypeHexFile.b2;
153       }
154     });
155 
156     rbut_big.addOnToggled( (ToggleButton rbut) {
157       if(rbut.getActive()) {
158         type = TypeHexFile.braw;
159       }
160     });
161 
162     rbut_little.addOnToggled( (ToggleButton rbut) {
163       if(rbut.getActive()) {
164         type = TypeHexFile.lraw;
165       }
166     });
167 
168   }
169 
170 }