// Entryの実体 // Entryインターフェースからプロパティ実体を持つEntryBaseを作り // 各操作の実体を持つGroup,Itemに派生する。 import entry_interface; private import inifile; private import std.file; private import std.string; // プロパティ実体 class EntryBase : Entry { protected: Entry parent; char[] name, execfile, execpath, execparams, iconfile; uint iconindex; bool removed = false; public: // properties Entry Parent() { assert(parent); return parent; } void Parent(Entry entry) { assert(entry); this.parent = entry; } char[] Name() { assert(this.name.length != 0); return name; } void Name(char[] name) { assert(name.length != 0); this.name = name.dup; } char[] ExecFile() { assert(execfile.length != 0); return execfile; } void ExecFile(char[] file) { assert(file.length != 0); this.execfile = file.dup; } char[] ExecPath() { // assert(execpath.length != 0); return execpath; } void ExecPath(char[] path) { // assert(path.length != 0); this.execpath = path.dup; } char[] ExecParams() { // assert(execparams.length != 0); return execparams; } void ExecParams(char[] params) { // assert(params.length != 0); this.execparams = params.dup; } char[] IconFile() { // assert(iconfile.length != 0); return iconfile; } void IconFile(char[] file) { // assert(file.length != 0); this.iconfile = file.dup; } uint IconIndex() { return iconindex; } void IconIndex(uint index) { this.iconindex = index; } bool Removed() { return removed; } // operations abstract ENTRY_TYPE Type(); abstract void Add(Entry entry); abstract void Remove(bool notify); abstract Entries GetChildren(); } // グループ操作実体 class Group : EntryBase { private: Entries entries; public: this() { entries = new Entries; } // common operations ENTRY_TYPE Type() { return ENTRY_TYPE.ENTRY_TYPE_GROUP; } void Add(Entry entry) { assert(entry); entries.add(entry); } void Remove(bool notify) { // 子エントリーすべてを削除 for (int i = 0; i < entries.size(); i++) { entries[i].Remove(false); } Update(); if (notify) { assert(parent.Type() == ENTRY_TYPE.ENTRY_TYPE_GROUP); (cast(Group)parent).Update(); } } Entries GetChildren() { return entries; } // original operation void Update() { // エントリーを整理し、新しい子エントリー配列を作る Entries new_entries = new Entries; for (int i = 0; i < entries.size(); i++) { if (!entries[i].Removed) { new_entries.add(entries[i]); } } entries = new_entries; } } // アイテム操作実体 class Item : EntryBase { // common operations ENTRY_TYPE Type() { return ENTRY_TYPE.ENTRY_TYPE_ITEM; } void Add(Entry entry) { // アイテムにエントリーは追加できないので呼び出される事はないはず assert(0); } void Remove(bool notify) { // 削除フラグを立て、必要があれば親エントリー(Groupのハズ)を更新 removed = true; if (notify) { assert(parent.Type == ENTRY_TYPE.ENTRY_TYPE_GROUP); (cast(Group)parent).Update(); } } Entries GetChildren() { // アイテムは子エントリーを持たないので呼び出されることはないはず assert(0); } } // ------------------------------------------------------------------ // ファイルからエントリー情報を取得 Entry LoadEntry(char[] filename) { Entry root = new Group; Entry leaf; IniFile ini = new IniFile(filename); char[][] sections = ini.GetSectionNames(); for (int i = 0; i < sections.length; i++) { if (ini.GetInteger(sections[i], "Type", 1) == 0) { leaf = LoadEntry(ini.GetString(sections[i], "ExecFile", "")); } else { leaf = new Item; } leaf.Name = ini.GetString(sections[i], "Name", ""); leaf.ExecFile = ini.GetString(sections[i], "ExecFile", ""); leaf.ExecPath = ini.GetString(sections[i], "ExecPath", ""); leaf.ExecParams = ini.GetString(sections[i], "ExecParams", ""); leaf.IconFile = ini.GetString(sections[i], "IconFile", ""); leaf.IconIndex = ini.GetInteger(sections[i], "IconIndex", -1); root.Add(leaf); } return root; } // ファイルにエントリー情報を保存 void SaveEntry(char[] filename, Entry entry, bool remove) { if (remove == true && exists(filename)) { std.file.remove(filename); } IniFile ini = new IniFile(filename); for (int i = 0; i < entry.GetChildren().size(); i++) { Entry leaf = entry.GetChildren()[i]; char[] section = "Item" ~ std.string.toString(i); ini.WriteInteger(section, "Type", leaf.Type); ini.WriteString(section, "Name", leaf.Name); ini.WriteString(section, "ExecFile", leaf.ExecFile); ini.WriteString(section, "ExecPath", leaf.ExecPath); ini.WriteString(section, "ExecParams", leaf.ExecParams); ini.WriteString(section, "IconFile", leaf.IconFile); ini.WriteInteger(section, "IconIndex", leaf.IconIndex); } }