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