diff options
Diffstat (limited to 'src/csimport.vala')
-rw-r--r-- | src/csimport.vala | 187 |
1 files changed, 187 insertions, 0 deletions
diff --git a/src/csimport.vala b/src/csimport.vala new file mode 100644 index 0000000..5743db4 --- /dev/null +++ b/src/csimport.vala @@ -0,0 +1,187 @@ +using Gtk; + +namespace Emulation +{ + public void add_cs(string name, CS cs) + { + TreeIter iter; + GUI.main.cs_store.append(out iter); + GUI.main.cs_store.set(iter, 0, name, 1, cs, -1); + } +} + +namespace GUI +{ + class CSImport : Dialog + { + private Entry m_name_entry; + private Label m_status_label; + private ListStore m_dwords_store; + private Button m_okbtn; + private Array<uint32> m_dwords; + private bool m_validcs; + + private void dword_cellrenderer(TreeViewColumn tree_column, CellRenderer cell, TreeModel model, TreeIter iter) + { + uint32 id = 0; + model.get(iter, 0, &id, -1); + assert(id < m_dwords.length); + (cell as CellRendererText).text = m_dwords.index(id).to_string("0x%08X"); + } + + private inline void create_name_frame() + { + var namealign = new Alignment(1.0f, 0.5f, 1.0f, 1.0f); + namealign.left_padding = 12; + namealign.bottom_padding = 4; + namealign.add(m_name_entry = new Entry()); + + var nameframe = new Frame("<b>Name</b>"); + (nameframe.label_widget as Label).use_markup = true; + nameframe.shadow = ShadowType.NONE; + nameframe.add(namealign); + + this.vbox.pack_start(nameframe, false, true, 0); + } + + private inline void create_dwords_frame() + { + m_dwords_store = new ListStore(2, typeof(uint32), typeof(string)); + var dwords_list = new TreeView(); + dwords_list.insert_column_with_attributes(-1, "#", new CellRendererText(), "text", 0, null); + dwords_list.insert_column_with_data_func(-1, "Value", new CellRendererText(), dword_cellrenderer); + dwords_list.insert_column_with_attributes(-1, "Meta", new CellRendererText(), "text", 1, null); + dwords_list.border_width = 5; + dwords_list.set_model(m_dwords_store); + var sw = new ScrolledWindow(null, null); + sw.add(dwords_list); + sw.shadow_type = ShadowType.ETCHED_IN; + sw.hscrollbar_policy = PolicyType.AUTOMATIC; + sw.vscrollbar_policy = PolicyType.AUTOMATIC; + + Gdk.Color col = Gdk.Color(); + col.red = 0xFFFF; col.green = 0x0000; col.blue = 0x0000; + + m_status_label = new Label(null); + var loadbtn = new Button.with_label("Load"); + var loadalign = new Alignment(0.5f, 0.5f, 1.0f, 1.0f); + var loadbox = new HButtonBox(); + m_status_label.modify_fg(StateType.NORMAL, col); + loadbtn.image = new Image.from_stock("gtk-convert", IconSize.BUTTON); + loadbtn.clicked += load_cs; + loadbox.pack_end(loadbtn, false, true, 0); + loadalign.right_padding = 3; + loadalign.add(loadbox); + + var bbox = new HBox(false, 0); + bbox.pack_start(m_status_label, true, true, 0); + bbox.pack_start(loadalign, false, true, 0); + + var dbox = new VBox(false, 4); + dbox.pack_start(sw, true, true, 0); + dbox.pack_start(bbox, false, false, 0); + + var dwordsalign = new Alignment(1.0f, 0.5f, 1.0f, 1.0f); + dwordsalign.left_padding = 12; + dwordsalign.bottom_padding = 3; + dwordsalign.add(dbox); + + var dwordsframe = new Frame("<b>DWORDs</b>"); + (dwordsframe.label_widget as Label).use_markup = true; + dwordsframe.shadow = ShadowType.NONE; + dwordsframe.add(dwordsalign); + + vbox.pack_start(dwordsframe, true, true, 0); + set_transient_for(main); + } + + construct { + create_name_frame(); + create_dwords_frame(); + + add_button(STOCK_CLOSE, ResponseType.CLOSE); + m_okbtn = add_button(STOCK_OK, ResponseType.APPLY) as Button; + m_okbtn.sensitive = false; + + m_validcs = false; + m_dwords = new Array<uint32>(false, false, (uint)sizeof(uint32)); + m_name_entry.changed += update_okbtn; + + title = "Import CS"; + response.connect(on_response); + set_default_size(300, 400); + show_all(); + } + + private void on_response(Dialog source, int response_id) + { + switch (response_id) { + case ResponseType.APPLY: + Emulation.add_cs(m_name_entry.text, new Emulation.CS(&m_dwords.index(0), m_dwords.length)); + destroy(); + break; + + case ResponseType.CLOSE: + destroy(); + break; + } + } + + private void load_cs(Button source) + { + var fc = new FileChooserDialog("Open File", this, + FileChooserAction.OPEN, + STOCK_CANCEL, ResponseType.CANCEL, + STOCK_OPEN, ResponseType.ACCEPT, null); + + if (fc.run() == ResponseType.ACCEPT) { open_cs(fc.get_filename()); } + fc.destroy(); + } + + private void open_cs(string filename) + { + FileStream fs = FileStream.open(filename, "r"); + if (fs == null) { + var dlg = new MessageDialog(this, DialogFlags.MODAL, MessageType.ERROR, ButtonsType.OK, "Unable to open the selected file: " + filename); + dlg.run(); + dlg.destroy(); + return; + } + + m_dwords_store.clear(); + m_dwords.set_size(0); + TreeIter iter; + + uint32 dword; + uint dword_count = 0; + string pktname; + for (uint id = 0; fs.scanf("%x", out dword) == 1; id++) { + m_dwords_store.append(out iter); + pktname = null; + if (dword_count > 0) { + dword_count--; + } else { + Emulation.PacketBase p = Emulation.make_packet(dword); + dword_count = p.length; + pktname = "packet" + p.type_id.to_string(); + } + m_dwords_store.set(iter, 0, id, 1, pktname, -1); + m_dwords.append_val(dword); + } + + m_validcs = (dword_count == 0); + update_okbtn(); + } + + private void update_okbtn() + { + if (m_validcs) { + m_okbtn.sensitive = (m_name_entry.text_length > 0 && m_dwords.length > 0); + m_status_label.label = ""; + } else { + m_okbtn.sensitive = false; + m_status_label.label = "This CS is invalid!"; + } + } + } +} |