1 #include "ide.h"
2 
3 struct Custom : public WithCustomLayout<TopWindow> {
4 	LineEdit   output;
5 	LineEdit   command;
6 
7 	DropList   package;
8 	EditString when;
9 	EditString extension;
10 
11 	void InsertCmd(String s);
12 	void InsertOut(String s);
13 	void DoMenu(Button& b, Callback1<String> cb, bool cmd);
14 	void OutMenu();
15 	void CmdMenu();
16 
17 	void Perform(const char *main);
18 
19 	Custom();
20 
21 	typedef Custom CLASSNAME;
22 };
23 
InsertCmd(String s)24 void Custom::InsertCmd(String s) {
25 	command.Paste(s.ToWString());
26 	command.SetFocus();
27 }
28 
InsertOut(String s)29 void Custom::InsertOut(String s) {
30 	output.Paste(s.ToWString());
31 	output.SetFocus();
32 }
33 
DoMenu(Button & b,Callback1<String> cb,bool cmd)34 void Custom::DoMenu(Button& b, Callback1<String> cb, bool cmd) {
35 	if(!list.IsCursor()) return;
36 	MenuBar menu;
37 //	Event<> Arg<String> set;
38 //	set <<= cb;
39 	String pk = list.Get(0);
40 	String ext = (String)list.Get(2);
41 	if(ext[0] != '.')
42 		ext = '.' + ext;
43 	String samplefile = "foo/" + ForceExt("sample", ext);
44 	String sample = SourcePath(pk, samplefile);
45 	menu.Add("Input file path (like '" + UnixPath(sample) + "')", callback1(cb, "$(PATH)"));
46 	menu.Add("Input file package-relative path (like '" + samplefile + "')", callback1(cb, "$(RELPATH)"));
47 	menu.Add("Input file directory (like '" + samplefile + "')", callback1(cb, "$(FILEDIR)"));
48 	menu.Add("Package directory (like '" + UnixPath(GetFileFolder(sample)) + "')", callback1(cb, "$(DIR)"));
49 	menu.Add("Input file name (like '" + GetFileName(sample) + "')", callback1(cb, "$(FILE)"));
50 	menu.Add("Input file title (like '" + GetFileTitle(sample) + "')", callback1(cb, "$(TITLE)"));
51 	menu.Add("Input file package (like '" + pk + "')", callback1(cb, "$(PACKAGE)"));
52 	Vector<String> ss = SplitFlags0((String)list.Get(1));
53 	String opath = "f:/out/mypackage/WIN32-ST/somefile.ext";
54 	menu.Add("Package output directory (like '" + opath + "')", callback1(cb, "$(OUTDIR)"));
55 	opath = "f:/out/WIN32-ST/myapp.exe";
56 	menu.Add("Executable path (like '" + UnixPath(opath) + "')", callback1(cb, "$(EXEPATH)"));
57 	menu.Add("Executable directory (like '" + UnixPath(GetFileFolder(opath)) + "')", callback1(cb, "$(EXEDIR)"));
58 	menu.Add("Executable filename (like '" + UnixPath(GetFileName(opath)) + "')", callback1(cb, "$(EXEFILE)"));
59 	menu.Add("Executable title (like '" + UnixPath(GetFileTitle(opath)) + "')", callback1(cb, "$(EXETITLE)"));
60 	menu.Add("Semicolon separated include dirs (like '/bin/include;/cpp/inc')", callback1(cb, "$(INCLUDE)"));
61 	menu.Add("Prefixed include dirs (like '-inc/include -inc/cpp/inc' for '$(!-inc)')",
62 		     callback1(cb, "$(!)"));
63 	menu.Add("$ character", callback1(cb, "$$"));
64 	if(cmd) {
65 		menu.Separator();
66 		menu.Add("copy command", callback1(cb, "cp "));
67 		menu.Add("chdir command", callback1(cb, "cd "));
68 	}
69 	menu.Execute(b.GetScreenRect().BottomLeft());
70 }
71 
OutMenu()72 void Custom::OutMenu() {
73 	DoMenu(outputmenu, THISBACK(InsertOut), false);
74 }
75 
CmdMenu()76 void Custom::CmdMenu() {
77 	DoMenu(commandmenu, THISBACK(InsertCmd), true);
78 }
79 
Custom()80 Custom::Custom() {
81 	CtrlLayoutExit(*this, "Custom build steps");
82 	Sizeable().MaximizeBox();
83 	list.AutoHideSb();
84 	list.Appending().Removing();
85 	list.AddColumn("Host package", 85).Edit(package);
86 	list.AddColumn("When", 416).Edit(when);
87 	when.SetFilter(CondFilter);
88 	list.AddColumn(".extension", 74).Edit(extension);
89 	list.AddCtrl(command);
90 	list.AddCtrl(output);
91 	outputmenu.SetFrame(InsetFrame());
92 	outputmenu.SetImage(CtrlImg::smalldown()).NoWantFocus();
93 	outputmenu <<= THISBACK(OutMenu);
94 	commandmenu.SetFrame(InsetFrame());
95 	commandmenu.SetImage(CtrlImg::smalldown()).NoWantFocus();
96 	commandmenu <<= THISBACK(CmdMenu);
97 }
98 
99 class CustomOrder : public ArrayCtrl::Order {
100 public:
operator ()(const Vector<Value> & row1,const Vector<Value> & row2) const101 	virtual bool operator()(const Vector<Value>& row1, const Vector<Value>& row2) const {
102 		for(int i = 0; i < 3; i++)
103 			if(String(row1[i]) != String(row2[i]))
104 				return String(row1[i]) < String(row2[i]);
105 		return false;
106 	}
107 };
108 
Perform(const char * main)109 void Custom::Perform(const char *main) {
110 	Workspace wspc;
111 	wspc.Scan(main);
112 	list.Clear();
113 	int i;
114 	for(i = 0; i < wspc.GetCount(); i++) {
115 		package.Add(wspc[i]);
116 		if(i == 0)
117 			list.IndexInfo(0).InsertValue(wspc[i]);
118 		Array<CustomStep>& m = wspc.GetPackage(i).custom;
119 		for(int j = 0; j < m.GetCount(); j++)
120 			list.Add(wspc[i], m[j].when, m[j].ext, m[j].command, m[j].output);
121 	}
122 	list.Sort(Single<CustomOrder>());
123 	list.SetCursor(0);
124 	Run();
125 	for(i = 0; i < wspc.GetCount(); i++)
126 		wspc.GetPackage(i).custom.Clear();
127 	for(i = 0; i < list.GetCount(); i++) {
128 		String pk = list.Get(i, 0);
129 		for(int k = 0; k < wspc.GetCount(); k++)
130 			if(wspc[k] == pk) {
131 				CustomStep& m = wspc.GetPackage(k).custom.Add();
132 				m.when = list.Get(i, 1);
133 				m.ext = list.Get(i, 2);
134 				m.command = list.Get(i, 3);
135 				m.output = list.Get(i, 4);
136 				break;
137 			}
138 	}
139 	for(i = 0; i < wspc.GetCount(); i++) {
140 		String pp = PackagePath(wspc[i]);
141 		RealizePath(pp);
142 		wspc.GetPackage(i).Save(pp);
143 	}
144 }
145 
CustomSteps()146 void Ide::CustomSteps() {
147 	Custom dlg;
148 	dlg.Perform(main);
149 	ScanWorkspace();
150 }
151