1 #include "MacroManager.h"
2 
3 #include <ide/Common/Common.h>
4 
5 #define IMAGECLASS MacroManagerImg
6 #define IMAGEFILE  <ide/MacroManager/MacroManager.iml>
7 #include <Draw/iml_source.h>
8 
9 #define METHOD_NAME "MacroManagerWindow::" << UPP_FUNCTION_NAME << "(): "
10 
11 namespace Upp {
12 
MacroManagerWindow(const Workspace & wspc,const String & hlStyles)13 MacroManagerWindow::MacroManagerWindow(const Workspace& wspc, const String& hlStyles)
14 	: wspc(wspc)
15 	, globalMacrosChanged(false)
16 {
17 	CtrlLayout(*this, t_("Macro Manager"));
18 	Zoomable().Sizeable().MinimizeBox(false);
19 	globalTree.NoRoot();
20 	localTree.NoRoot();
21 
22 	parent.Add(editor.SizePos());
23 	parent.AddFrame(splitter.Left(tab, 330));
24 	tab.Add(globalTree.SizePos(), t_("Global macros"));
25 
26 	editor.Highlight("usc");
27 	editor.SetReadOnly();
28 
29 	LoadMacros();
30 
31 	editor.Hide();
32 	editor.LoadHlStyles(hlStyles);
33 
34 	InitButtons();
35 	InitEvents();
36 	InitToolBar();
37 }
38 
InitToolBar()39 void MacroManagerWindow::InitToolBar()
40 {
41 	InitToolButton(editLabel, t_("Edit"), MacroManagerImg::PluginEdit());
42 	InitToolButton(exportLabel, t_("Export current"), MacroManagerImg::PluginGo());
43 	tool.Separator();
44 	InitToolButton(newGlobalLabel, t_("New global"), IdeCommonImg::PageAdd());
45 	InitToolButton(importGlobalsLabel, t_("Import globals"), MacroManagerImg::PluginAdd());
46 	InitToolButton(exportGlobalsLabel, t_("Export globals"), MacroManagerImg::ArrowRight());
47 
48 	newGlobalLabel.Enable();
49 	importGlobalsLabel.Enable();
50 	exportGlobalsLabel.Enable(globalTree.GetChildCount(0));
51 }
52 
InitToolButton(ToolButton & toolButton,const String & label,const Image & image)53 void MacroManagerWindow::InitToolButton(
54 	ToolButton& toolButton, const String& label, const Image& image)
55 {
56 	tool.Add(toolButton.Label(label));
57 	toolButton.Image(image);
58 	toolButton.SizePos();
59 	toolButton.Disable();
60 }
61 
InitButtons()62 void MacroManagerWindow::InitButtons()
63 {
64 	closeButton.Close();
65 
66 	closeButton        << [=] { Break(); };
67 	editLabel          << [=] { OnEditFile(); };
68 	exportLabel        << [=] { OnExport(globalTree.GetCursor()); };
69 	newGlobalLabel     << [=] { OnNewMacroFile(); };
70 	importGlobalsLabel << [=] { OnImport(); };
71 	exportGlobalsLabel << [=] { OnExport(0); };
72 
73 	editLabel.Tip(t_("Edit currently selected macro inside TheIde.."));
74 	exportLabel.Tip(t_("Export selected macro file.."));
75 	newGlobalLabel.Tip(t_("Create new file that stores global macros.."));
76 	importGlobalsLabel.Tip(t_("Install file/files containing macros.."));
77 	exportGlobalsLabel.Tip(t_("Export all global macros files.."));
78 }
79 
InitEvents()80 void MacroManagerWindow::InitEvents()
81 {
82 	globalTree.WhenSel = [=]           { OnTreeSel(); };
83 	localTree.WhenSel  = [=]           { OnTreeSel(); };
84 
85 	globalTree.WhenBar = [=](Bar& bar) { OnMacroBar(bar); };
86 	localTree.WhenBar  = [=](Bar& bar) { OnMacroBar(bar); };
87 
88 	tab.WhenSet        = [=]           { OnTabSet(); };
89 }
90 
OnMacroBar(Bar & bar)91 void MacroManagerWindow::OnMacroBar(Bar& bar)
92 {
93 	if(IsGlobalTab()) {
94 		bool partOfFile = IsGlobalFile();
95 
96 		bar.Add(t_("New.."),    [=] { OnNewMacroFile(); });
97 		bar.Add(t_("Import.."), [=] { OnImport(); });
98 		bar.Add(t_("Delete"),   [=] { OnDeleteMacroFile(); })
99 		    .Enable(partOfFile);
100 		bar.Add(t_("Export.."), [=] { OnExport(globalTree.GetCursor()); })
101 		    .Enable(partOfFile);
102 		bar.Separator();
103 	}
104 	bar.Add(t_("Edit"), [=] { OnEditFile();})
105 	    .Enable(IsEditPossible());
106 }
107 
Layout()108 void MacroManagerWindow::Layout()
109 {
110 	OnTreeSel();
111 }
112 
OnTreeSel()113 void MacroManagerWindow::OnTreeSel()
114 {
115 	const TreeCtrl& tree = GetCurrentTree();
116 	bool hasCursor = tree.IsCursor();
117 	exportLabel.Enable(IsGlobalTab() && IsGlobalFile());
118 
119 	editLabel.Enable(hasCursor && IsEditPossible());
120 
121 	editor.Show(editLabel.IsEnabled());
122 
123 	if(IsFile())
124 		editor.Set(LoadFile(static_cast<String>(tree.Get())));
125 	else if(IsMacro())
126 		editor.Set(ValueTo<MacroElement>(tree.Get()).GetContent());
127 }
128 
OnTabSet()129 void MacroManagerWindow::OnTabSet()
130 {
131 	exportLabel.Enable(tab.Get() == 0);
132 	editor.Hide();
133 
134 	OnTreeSel();
135 }
136 
OnImport()137 void MacroManagerWindow::OnImport()
138 {
139 	auto filePath = SelectFileOpen("*.usc");
140 	if(IsNull(filePath))
141 		return;
142 
143 	if(!UscFileParser(filePath).IsValid()) {
144 		ErrorOK(DeQtf(String(t_("Import failed! Following file")) << " \"" << filePath << "\" " << t_("is not a valid macro file!")));
145 		return;
146 	}
147 
148 	auto localDir = GetLocalDir();
149 	if(!DirectoryExists(localDir) && !RealizeDirectory(localDir)) {
150 		ErrorOK(DeQtf(String(t_("Realizing directory")) << " \"" << localDir << "\" " << t_("failed.")));
151 		return;
152 	}
153 
154 	auto newFileName = GetFileName(filePath);
155 	auto newFilePath = LocalPath(newFileName);
156 	if(FileExists(newFilePath) && !PromptYesNo(DeQtf(GenFileOverrideMessage(newFileName))))
157 		return;
158 
159 	FileCopy(filePath, newFilePath);
160 	ReloadGlobalMacros();
161 	OnTreeSel();
162 
163 	OnGlobalMacrosChanged();
164 }
165 
ExportFiles(Index<String> & files,const String & dir)166 void MacroManagerWindow::ExportFiles(Index<String>& files, const String& dir)
167 {
168 	for(const auto& file : files) {
169 		auto fileName = GetFileName(file);
170 		auto filePath = AppendFileName(dir, GetFileName(file));
171 
172 		if(FileExists(filePath) && !PromptYesNo(DeQtf(GenFileOverrideMessage(fileName))))
173 			continue;
174 
175 		FileCopy(file, filePath);
176 	}
177 }
178 
FindNodeFiles(int id,Index<String> & list)179 void MacroManagerWindow::FindNodeFiles(int id, Index<String>& list)
180 {
181 	if(IsFile(id)) {
182 		list.FindAdd((String)globalTree.Get(id));
183 		return;
184 	}
185 
186 	for(int i = 0; i < globalTree.GetChildCount(id); i++) {
187 		int node = globalTree.GetChild(id, i);
188 		FindNodeFiles(node, list);
189 	}
190 }
191 
OnExport(int id)192 void MacroManagerWindow::OnExport(int id)
193 {
194 	if(id == 0 || IsGlobalFile()) {
195 		auto dir = SelectDirectory();
196 		if(dir.IsEmpty())
197 			return;
198 
199 		Index<String> list;
200 		FindNodeFiles(id, list);
201 		ExportFiles(list, dir);
202 	}
203 }
204 
OnEditFile()205 void MacroManagerWindow::OnEditFile()
206 {
207 	const TreeCtrl& tree = GetCurrentTree();
208 	if(!tree.IsCursor())
209 		return;
210 
211 	if(IsMacro()) {
212 		MacroElement element = ValueTo<MacroElement>(tree.Get());
213 		WhenEdit(element.fileName, element.line - 1);
214 		Break();
215 	}
216 	else if(IsFile()) {
217 		WhenEdit(tree.Get(), 1);
218 		Break();
219 	}
220 }
221 
OnNewMacroFile()222 void MacroManagerWindow::OnNewMacroFile()
223 {
224 	String fileName;
225 	if(!EditTextNotNull(fileName, t_("New global macro file"), t_("Macro file name:")))
226 		return;
227 
228 	if(!fileName.EndsWith(".usc"))
229 		fileName << ".usc";
230 
231 	String fullPath = AppendFileName(GetLocalDir(), fileName);
232 	RealizeDirectory(GetLocalDir());
233 	if(FileExists(fullPath)) {
234 		PromptOK(String() << t_("file") << " \"" << fileName << "\" " << t_("already exists!"));
235 		return;
236 	}
237 
238 	if(!SaveFile(fullPath, "macro \"" + GetFileTitle(fileName) + "\" {}")) {
239 		PromptOK(String() << t_("Error occured while saving file") << " \"" << fileName << "\"");
240 		return;
241 	}
242 
243 	int fileNode = globalTree.Add(0, Image(), fullPath, fileName);
244 	auto list = UscFileParser(fullPath).Parse();
245 	for(const auto& element : list) {
246 		globalTree.Add(fileNode, element.GetImage(), RawToValue(element), element.name);
247 	}
248 
249 	globalTree.OpenDeep(fileNode);
250 	globalTree.FindSetCursor(fullPath);
251 
252 	OnGlobalMacrosChanged();
253 }
254 
OnDeleteMacroFile()255 void MacroManagerWindow::OnDeleteMacroFile()
256 {
257 	auto fileName = static_cast<String>(globalTree.GetValue());
258 	if(!PromptOKCancel(t_("Are you sure you want to remove following macro file \"" + fileName + "\"?")))
259 		return;
260 
261 	FileDelete(AppendFileName(GetLocalDir(), fileName));
262 	globalTree.Remove(globalTree.GetCursor());
263 	OnTreeSel();
264 
265 	OnGlobalMacrosChanged();
266 }
267 
OnGlobalMacrosChanged()268 void MacroManagerWindow::OnGlobalMacrosChanged()
269 {
270 	exportGlobalsLabel.Enable(globalTree.GetChildCount(0));
271 	globalMacrosChanged = true;
272 }
273 
GenFileOverrideMessage(const String & fileName)274 String MacroManagerWindow::GenFileOverrideMessage(const String& fileName)
275 {
276 	return String(t_("Target file")) << " \"" << fileName << "\" " << t_("already exists! Do you want to overwrite it?");
277 }
278 
LoadUscDir(const String & dir)279 void MacroManagerWindow::LoadUscDir(const String& dir)
280 {
281 	for(FindFile ff(AppendFileName(dir, "*.usc")); ff; ff.Next()) {
282 		String fileTitle = ff.GetName();
283 		if(!ff.GetPath().EndsWith(String() << "UppLocal" << DIR_SEPS << ff.GetName()))
284 			fileTitle = "../" + fileTitle;
285 
286 		int fileNode = globalTree.Add(0, Image(), ff.GetPath(), fileTitle);
287 
288 		auto list = UscFileParser(ff.GetPath()).Parse();
289 		for(const auto& element : list)
290 			globalTree.Add(fileNode, element.GetImage(), RawToValue(element), element.name);
291 	}
292 }
293 
LoadMacros()294 void MacroManagerWindow::LoadMacros()
295 {
296 	ReloadGlobalMacros();
297 	ReloadLocalMacros();
298 }
299 
ReloadGlobalMacros()300 void MacroManagerWindow::ReloadGlobalMacros()
301 {
302 	globalTree.Clear();
303 
304 	LoadUscDir(GetLocalDir());
305 	LoadUscDir(GetFileFolder(ConfigFile("x")));
306 
307 	globalTree.OpenDeep(0);
308 }
309 
ReloadLocalMacros()310 void MacroManagerWindow::ReloadLocalMacros()
311 {
312 	for(int i = 0; i < wspc.GetCount(); i++) {
313 		const auto& package = wspc.GetPackage(i);
314 		int packageNode = -1;
315 		for (const auto& file : package.file) {
316 			auto filePath = SourcePath(wspc[i], file);
317 
318 			if (ToLower(GetFileExt(filePath)) != ".usc")
319 				continue;
320 
321 			auto list = UscFileParser(filePath).Parse();
322 			if (list.GetCount() == 0)
323 				continue;
324 
325 			if(tab.GetCount() == 1)
326 				tab.Add(localTree.SizePos(), t_("Local macros (Read only)"));
327 
328 			if(packageNode == -1)
329 				packageNode = localTree.Add(0, Image(), 0, wspc[i]);
330 
331 			int fileNode = localTree.Add(packageNode, Image(), filePath, file);
332 			for(int j = 0; j < list.GetCount(); j++) {
333 				auto& macroElement = list[j];
334 				localTree.Add(fileNode, macroElement.GetImage(), RawToValue(macroElement), macroElement.name);
335 			}
336 		}
337 	}
338 
339 	localTree.OpenDeep(0);
340 }
341 
342 }
343