|
1 |
#include "ide.h"
|
|
2 |
|
|
3 |
class CategoryFile : public Moveable<CategoryFile> {
|
|
4 |
public:
|
|
5 |
CategoryFile(const String& description, const String& extension)
|
|
6 |
: description(description)
|
|
7 |
, extension(extension)
|
|
8 |
{}
|
|
9 |
|
|
10 |
const String& GetDescription() const { return description; }
|
|
11 |
const String& GetExtension() const { return extension; }
|
|
12 |
|
|
13 |
private:
|
|
14 |
String description;
|
|
15 |
String extension;
|
|
16 |
};
|
|
17 |
|
|
18 |
class NewFileBasicInformationsWindow : public WithNewFileBasicInformationsLayout<TopWindow> {
|
|
19 |
public:
|
|
20 |
NewFileBasicInformationsWindow(const Workspace& wspc, const String& activePackage, Button* parentNext);
|
|
21 |
|
|
22 |
String GetPackage() const;
|
|
23 |
String GetFileExt() const;
|
|
24 |
|
|
25 |
bool IsTypeChoosen() const;
|
|
26 |
|
|
27 |
private:
|
|
28 |
void InitCategories();
|
|
29 |
void InitCategoriesArray();
|
|
30 |
|
|
31 |
void OnCategorySelection();
|
|
32 |
void OnTypeDeclarationChange();
|
|
33 |
void OnFileTypeChange();
|
|
34 |
|
|
35 |
private:
|
|
36 |
VectorMap<String, Vector<CategoryFile>> categoriesFiles;
|
|
37 |
|
|
38 |
Button* parentNext;
|
|
39 |
};
|
|
40 |
|
|
41 |
NewFileBasicInformationsWindow::NewFileBasicInformationsWindow(
|
|
42 |
const Workspace& wspc,
|
|
43 |
const String& activePackage,
|
|
44 |
Button* parentNext)
|
|
45 |
: parentNext(parentNext)
|
|
46 |
{
|
|
47 |
CtrlLayout(*this);
|
|
48 |
Zoomable();
|
|
49 |
|
|
50 |
for(int i = 0; i < wspc.GetCount(); i++)
|
|
51 |
package.Add(wspc[i]);
|
|
52 |
if (package.GetCount()) {
|
|
53 |
int activeIdx = package.Find(activePackage);
|
|
54 |
package.SetIndex(activeIdx >= 0 ? activeIdx : 0);
|
|
55 |
}
|
|
56 |
|
|
57 |
InitCategories();
|
|
58 |
InitCategoriesArray();
|
|
59 |
}
|
|
60 |
|
|
61 |
String NewFileBasicInformationsWindow::GetPackage() const
|
|
62 |
{
|
|
63 |
return package.Get();
|
|
64 |
}
|
|
65 |
|
|
66 |
String NewFileBasicInformationsWindow::GetFileExt() const
|
|
67 |
{
|
|
68 |
int cursor = files.GetCursor();
|
|
69 |
if (cursor < 0)
|
|
70 |
return "";
|
|
71 |
|
|
72 |
return files.Get(cursor, 1);
|
|
73 |
}
|
|
74 |
|
|
75 |
bool NewFileBasicInformationsWindow::IsTypeChoosen() const
|
|
76 |
{
|
|
77 |
return typeDeclaration.Get() == 0;
|
|
78 |
}
|
|
79 |
|
|
80 |
void NewFileBasicInformationsWindow::InitCategories()
|
|
81 |
{
|
|
82 |
// TODO: Maybe we should have separate file for this?
|
|
83 |
|
|
84 |
Vector<CategoryFile> cppFiles;
|
|
85 |
cppFiles.Add(CategoryFile("C source file (.c)", "c"));
|
|
86 |
cppFiles.Add(CategoryFile("C header (.h)", "h"));
|
|
87 |
cppFiles.Add(CategoryFile("C++ source file (.cpp)", "cpp"));
|
|
88 |
cppFiles.Add(CategoryFile("C++ header file (.hpp)", "hpp"));
|
|
89 |
categoriesFiles.Add("C/C++ source files", cppFiles);
|
|
90 |
|
|
91 |
Vector<CategoryFile> javaFiles;
|
|
92 |
javaFiles.Add(CategoryFile("Java source file (.java)", "java"));
|
|
93 |
categoriesFiles.Add("Java source files", javaFiles);
|
|
94 |
|
|
95 |
Vector<CategoryFile> uppFiles;
|
|
96 |
uppFiles.Add(CategoryFile("Layout file (.lay)", "lay"));
|
|
97 |
uppFiles.Add(CategoryFile("Image file (.iml)", "iml"));
|
|
98 |
uppFiles.Add(CategoryFile("Escape script file (.usc)", "usc"));
|
|
99 |
categoriesFiles.Add("Upp files", uppFiles);
|
|
100 |
|
|
101 |
Vector<CategoryFile> webFiles;
|
|
102 |
webFiles.Add(CategoryFile("JavaScript source file (.js)", "js"));
|
|
103 |
webFiles.Add(CategoryFile("Skylark template file (.witz)", "witz"));
|
|
104 |
categoriesFiles.Add("Web", webFiles);
|
|
105 |
|
|
106 |
Vector<CategoryFile> otherFiles;
|
|
107 |
otherFiles.Add(CategoryFile("Text file (.txt)", "txt"));
|
|
108 |
categoriesFiles.Add("Other", otherFiles);
|
|
109 |
}
|
|
110 |
|
|
111 |
void NewFileBasicInformationsWindow::InitCategoriesArray()
|
|
112 |
{
|
|
113 |
categories.AddColumn();
|
|
114 |
files.AddColumn();
|
|
115 |
files.AddColumn();
|
|
116 |
files.ColumnWidths("100 0");
|
|
117 |
for (int i = 0; i < categoriesFiles.GetCount(); i++)
|
|
118 |
categories.Add(categoriesFiles.GetKey(i));
|
|
119 |
|
|
120 |
categories << [&] { OnCategorySelection(); };
|
|
121 |
files << [&] { OnFileTypeChange(); };
|
|
122 |
typeDeclaration << [&] { OnTypeDeclarationChange(); };
|
|
123 |
}
|
|
124 |
|
|
125 |
void NewFileBasicInformationsWindow::OnCategorySelection()
|
|
126 |
{
|
|
127 |
int cursor = categories.GetCursor();
|
|
128 |
if (cursor < 0)
|
|
129 |
return;
|
|
130 |
|
|
131 |
String key = categories.Get(cursor, 0);
|
|
132 |
int idx = categoriesFiles.Find(key);
|
|
133 |
if (idx < 0)
|
|
134 |
return;
|
|
135 |
|
|
136 |
files.Clear();
|
|
137 |
for (const CategoryFile& cf : categoriesFiles[idx])
|
|
138 |
files.Add(cf.GetDescription(), cf.GetExtension());
|
|
139 |
|
|
140 |
parentNext->Disable();
|
|
141 |
}
|
|
142 |
|
|
143 |
void NewFileBasicInformationsWindow::OnTypeDeclarationChange()
|
|
144 |
{
|
|
145 |
if (typeDeclaration.Get() == 1) {
|
|
146 |
categories.Disable();
|
|
147 |
files.Disable();
|
|
148 |
|
|
149 |
parentNext->Enable();
|
|
150 |
}
|
|
151 |
else {
|
|
152 |
categories.Enable();
|
|
153 |
files.Enable();
|
|
154 |
}
|
|
155 |
}
|
|
156 |
|
|
157 |
void NewFileBasicInformationsWindow::OnFileTypeChange()
|
|
158 |
{
|
|
159 |
parentNext->Enable(files.GetCursor() >= 0);
|
|
160 |
}
|
|
161 |
|
|
162 |
class NewFileSummaryWindow : public WithNewFileSummaryLayout<TopWindow> {
|
|
163 |
typedef NewFileSummaryWindow CLASSNAME;
|
|
164 |
|
|
165 |
public:
|
|
166 |
NewFileSummaryWindow(Button* newFileWindowOK);
|
|
167 |
|
|
168 |
String GetAbsoluteFilePath();
|
|
169 |
String GetFilePathInPackage();
|
|
170 |
void SetPackage(const String& newPackage);
|
|
171 |
void SetExtension(const String& newExtension);
|
|
172 |
|
|
173 |
void UpdateFields();
|
|
174 |
|
|
175 |
private:
|
|
176 |
void CheckPaths(const String& file, const String& absoluteFile);
|
|
177 |
void OnTypeDeclarationChange();
|
|
178 |
|
|
179 |
private:
|
|
180 |
String package;
|
|
181 |
String extension;
|
|
182 |
|
|
183 |
Button* parentOK;
|
|
184 |
};
|
|
185 |
|
|
186 |
NewFileSummaryWindow::NewFileSummaryWindow(Button* okButton)
|
|
187 |
: parentOK(okButton)
|
|
188 |
{
|
|
189 |
CtrlLayout(*this);
|
|
190 |
|
|
191 |
fileName <<= THISBACK(UpdateFields);
|
|
192 |
/*
|
|
193 |
fileName <<= [&] {
|
|
194 |
UpdateFields();
|
|
195 |
};
|
|
196 |
*/
|
|
197 |
|
|
198 |
Zoomable();
|
|
199 |
}
|
|
200 |
|
|
201 |
String NewFileSummaryWindow::GetAbsoluteFilePath()
|
|
202 |
{
|
|
203 |
return absoluteFilePath.GetData();
|
|
204 |
}
|
|
205 |
|
|
206 |
String NewFileSummaryWindow::GetFilePathInPackage()
|
|
207 |
{
|
|
208 |
return filePathInPackage.GetData();
|
|
209 |
}
|
|
210 |
|
|
211 |
void NewFileSummaryWindow::SetPackage(const String& newPackage)
|
|
212 |
{
|
|
213 |
package = newPackage;
|
|
214 |
}
|
|
215 |
|
|
216 |
void NewFileSummaryWindow::SetExtension(const String& newExtension)
|
|
217 |
{
|
|
218 |
extension = newExtension;
|
|
219 |
}
|
|
220 |
|
|
221 |
void NewFileSummaryWindow::UpdateFields()
|
|
222 |
{
|
|
223 |
String file = fileName.GetData();
|
|
224 |
file.IsEmpty() ? parentOK->Disable() : parentOK->Enable();
|
|
225 |
|
|
226 |
String packageFile = file;
|
|
227 |
if (!extension.IsEmpty())
|
|
228 |
packageFile += "." + extension;
|
|
229 |
String absoluteFile = GetFileFolder(PackagePath(package)) + DIR_SEP + packageFile;
|
|
230 |
|
|
231 |
filePathInPackage.SetData(packageFile);
|
|
232 |
absoluteFilePath.SetData(absoluteFile);
|
|
233 |
|
|
234 |
CheckPaths(file, absoluteFilePath);
|
|
235 |
}
|
|
236 |
|
|
237 |
void NewFileSummaryWindow::CheckPaths(const String& file, const String& absoluteFile)
|
|
238 |
{
|
|
239 |
if (file.IsEmpty()) {
|
|
240 |
parentOK->Disable();
|
|
241 |
}
|
|
242 |
else
|
|
243 |
if (FileExists(absoluteFile)) {
|
|
244 |
info.SetData("[ [ [@(170.42.0) Error: file already exists.]]]");
|
|
245 |
parentOK->Disable();
|
|
246 |
}
|
|
247 |
else {
|
|
248 |
info.Clear();
|
|
249 |
parentOK->Enable();
|
|
250 |
}
|
|
251 |
}
|
|
252 |
|
|
253 |
class NewFileWindow : public WithNewFileLayout<TopWindow> {
|
|
254 |
enum class State;
|
|
255 |
|
|
256 |
public:
|
|
257 |
NewFileWindow(const Workspace& wspc, const String& activePackage);
|
|
258 |
|
|
259 |
String GetAbsoluteFilePath();
|
|
260 |
String GetFilePathInPackage();
|
|
261 |
|
|
262 |
private:
|
|
263 |
void SetState(State newState);
|
|
264 |
void ResetStateComponents();
|
|
265 |
|
|
266 |
void OnNext();
|
|
267 |
void OnBack();
|
|
268 |
|
|
269 |
private:
|
|
270 |
enum class State {
|
|
271 |
BasicInformations,
|
|
272 |
Summary,
|
|
273 |
Unknown
|
|
274 |
};
|
|
275 |
|
|
276 |
State state;
|
|
277 |
|
|
278 |
NewFileBasicInformationsWindow basicInformations;
|
|
279 |
NewFileSummaryWindow summary;
|
|
280 |
};
|
|
281 |
|
|
282 |
NewFileWindow::NewFileWindow(const Workspace& wspc, const String& activePackage)
|
|
283 |
: state(State::Unknown)
|
|
284 |
, basicInformations(wspc, activePackage, &next)
|
|
285 |
, summary(&ok)
|
|
286 |
{
|
|
287 |
CtrlLayoutOKCancel(*this, "New file");
|
|
288 |
Zoomable();
|
|
289 |
|
|
290 |
parent.Add(basicInformations.SizePos());
|
|
291 |
parent.Add(summary.SizePos());
|
|
292 |
|
|
293 |
next << [&] { OnNext(); };
|
|
294 |
back << [&] { OnBack(); };
|
|
295 |
|
|
296 |
SetState(State::BasicInformations);
|
|
297 |
}
|
|
298 |
|
|
299 |
String NewFileWindow::GetAbsoluteFilePath()
|
|
300 |
{
|
|
301 |
return summary.GetAbsoluteFilePath();
|
|
302 |
}
|
|
303 |
|
|
304 |
String NewFileWindow::GetFilePathInPackage()
|
|
305 |
{
|
|
306 |
return summary.GetFilePathInPackage();
|
|
307 |
}
|
|
308 |
|
|
309 |
void NewFileWindow::SetState(State newState)
|
|
310 |
{
|
|
311 |
if(state == newState)
|
|
312 |
return;
|
|
313 |
|
|
314 |
ResetStateComponents();
|
|
315 |
|
|
316 |
switch (newState) {
|
|
317 |
case State::BasicInformations:
|
|
318 |
basicInformations.Show();
|
|
319 |
if (state == State::Summary)
|
|
320 |
next.Enable();
|
|
321 |
break;
|
|
322 |
case State::Summary:
|
|
323 |
summary.SetPackage(basicInformations.GetPackage());
|
|
324 |
summary.SetExtension(basicInformations.IsTypeChoosen() ? basicInformations.GetFileExt() : "");
|
|
325 |
summary.fileName.Clear();
|
|
326 |
summary.UpdateFields();
|
|
327 |
summary.Show();
|
|
328 |
summary.fileName.SetFocus();
|
|
329 |
back.Enable();
|
|
330 |
break;
|
|
331 |
default:
|
|
332 |
ASSERT(0);
|
|
333 |
}
|
|
334 |
|
|
335 |
state = newState;
|
|
336 |
}
|
|
337 |
|
|
338 |
void NewFileWindow::ResetStateComponents()
|
|
339 |
{
|
|
340 |
basicInformations.Hide();
|
|
341 |
summary.Hide();
|
|
342 |
|
|
343 |
ok.Disable();
|
|
344 |
|
|
345 |
next.Disable();
|
|
346 |
back.Disable();
|
|
347 |
}
|
|
348 |
|
|
349 |
void NewFileWindow::OnNext()
|
|
350 |
{
|
|
351 |
SetState(State::Summary);
|
|
352 |
}
|
|
353 |
|
|
354 |
void NewFileWindow::OnBack()
|
|
355 |
{
|
|
356 |
SetState(State::BasicInformations);
|
|
357 |
}
|
|
358 |
|
|
359 |
void Ide::NewFile()
|
|
360 |
{
|
|
361 |
Vector<String> packages;
|
|
362 |
|
|
363 |
String activePackage = GetActivePackage();
|
|
364 |
NewFileWindow newFileWindow(IdeWorkspace(), activePackage);
|
|
365 |
if (!newFileWindow.ExecuteOK())
|
|
366 |
return;
|
|
367 |
|
|
368 |
Package pkg;
|
|
369 |
String uppManifestPath = PackagePath(activePackage);
|
|
370 |
pkg.Load(uppManifestPath);
|
|
371 |
Package::File& packageFile = pkg.file.Add();
|
|
372 |
packageFile = newFileWindow.GetFilePathInPackage();
|
|
373 |
pkg.Save(uppManifestPath);
|
|
374 |
|
|
375 |
// TODO: Bad solution <- We should open this file in TheIDE like in workspace.
|
|
376 |
SaveFile(absolutePath);
|
|
377 |
}
|