#include "ide.h" class TextOption : public Option { public: virtual void SetData(const Value& data); virtual Value GetData() const; }; void TextOption::SetData(const Value& data) { String s = data; Set(!(IsNull(s) || s == "0")); } Value TextOption::GetData() const { return Get() ? "1" : "0"; } class TextSwitch : public Switch { public: virtual void SetData(const Value& data); virtual Value GetData() const; }; void TextSwitch::SetData(const Value& data) { String s = data; Switch::SetData(atoi((String)data)); } Value TextSwitch::GetData() const { return AsString(Switch::GetData()); } class DirTable : public ArrayCtrl { public: virtual void SetData(const Value& data); virtual Value GetData() const; protected: void Modify() { Update(); } EditString edit; SelectDirButton edit_dir; void Init(const char *name = NULL); public: DirTable(); DirTable(const char *name); }; void DirTable::SetData(const Value& data) { Vector l = Split((String)data, ';'); Clear(); for(int i = 0; i < l.GetCount(); i++) Add(l[i]); } Value DirTable::GetData() const { String s; for(int i = 0; i < GetCount(); i++) { if(i) s << ';'; s << (String)Get(i, 0); } return s; } void DirTable::Init(const char *name) { AutoHideSb(); AddColumn(name).Edit(edit); Appending().Removing().Moving(); edit_dir.Attach(edit); edit_dir.AllFilesType(); WhenArrayAction = edit <<= callback(this, &DirTable::Modify); } DirTable::DirTable() { Init(); NoHeader(); } DirTable::DirTable(const char *name) { Init(name); } class DirMap : public ArrayCtrl { public: virtual void SetData(const Value& data); virtual Value GetData() const; protected: void Modify() { Update(); } EditString localpath, remotepath; SelectDirButton edit_dir; public: DirMap(); }; void DirMap::SetData(const Value& data) { Vector l = Split((String)data, ';'); Clear(); for(int i = 0; i < l.GetCount(); i++) { String li = l[i]; int f = li.Find('>'); if(f >= 0) Add(li.Left(f), li.Mid(f + 1)); } } Value DirMap::GetData() const { String s; for(int i = 0; i < GetCount(); i++) { if(i) s << ';'; s << (String)Get(i, 0) << '>' << (String)Get(i, 1); } return s; } DirMap::DirMap() { AutoHideSb(); AddColumn("Map local path").Edit(localpath); AddColumn("To remote path").Edit(remotepath); Appending().Removing().Moving(); edit_dir.Attach(localpath); WhenArrayAction = localpath <<= remotepath <<= callback(this, &DirMap::Modify); } struct BuildMethods : public WithBuildMethodsLayout { TextOption debug_blitz; TextSwitch debug_linkmode; TextOption release_blitz; TextSwitch release_linkmode; TextOption linkmode_lock; DirTable path; DirTable include; DirTable lib; DirMap remote_path_map; OpenFileButton open_script; EditStringNotNull name; Index origfile; String default_method; void Load(); bool Save(); void NewBuilder(); void ShowDefault(); void SetDefault(); void ChangeMethod(); void Import(); void MethodMenu(Bar& bar); typedef BuildMethods CLASSNAME; BuildMethods(); }; int CharFilterFileName(int c) { return IsAlNum(c) || c == '_' ? c : 0; } BuildMethods::BuildMethods() { CtrlLayoutOKCancel(*this, "Build methods"); method.AddColumn("Method").Edit(name); name.SetFilter(CharFilterFileName); method.AddCtrl("BUILDER", builder); method.AddCtrl("COMPILER", compiler); method.AddCtrl("DEBUG_INFO", debug_info); method.AddCtrl("DEBUG_BLITZ", debug_blitz); method.AddCtrl("DEBUG_LINKMODE", debug_linkmode); method.AddCtrl("DEBUG_OPTIONS", debug_options); method.AddCtrl("DEBUG_FLAGS", debug_flags); method.AddCtrl("RELEASE_BLITZ", release_blitz); method.AddCtrl("RELEASE_LINKMODE", release_linkmode); method.AddCtrl("RELEASE_OPTIONS", speed_options); method.AddCtrl("RELEASE_SIZE_OPTIONS", size_options); method.AddCtrl("RELEASE_FLAGS", release_flags); method.AddCtrl("DEBUGGER", debugger); method.AddCtrl("PATH", path); method.AddCtrl("INCLUDE", include); method.AddCtrl("LIB", lib); method.AddCtrl("REMOTE_HOST", remote_host); method.AddCtrl("REMOTE_OS", remote_os); remote_os.Add("WIN32"); remote_os.Add("LINUX"); remote_os.Add("WINCE"); remote_os.Add("UNIX"); remote_os.Add("SOLARIS"); remote_os.Add("BSD"); method.AddCtrl("REMOTE_TRANSFER", remote_file_access); remote_file_access.Add("0", "direct (SAMBA)"); remote_file_access.Add("1", "indirect (transfer)"); method.AddCtrl("REMOTE_MAP", remote_path_map); method.AddCtrl("SCRIPT", scriptfile); method.AddCtrl("LINKMODE_LOCK", linkmode_lock); open_script.Attach(scriptfile); open_script.Type("Build scripts (*.bsc)", "*.bsc") .AllFilesType(); open_script.DefaultExt("bsc"); method.Appending().Removing().Duplicating(); method.WhenCursor = THISBACK(ChangeMethod); method.WhenBar = THISBACK(MethodMenu); paths.Add(path.SizePos(), "PATH - executable directories"); paths.Add(include.SizePos(), "INCLUDE directories"); paths.Add(lib.SizePos(), "LIB directories"); debug_info.Add("0", "None"); debug_info.Add("1", "Minimal"); debug_info.Add("2", "Full"); for(int i = 0; i < BuilderMap().GetCount(); i++) builder.Add(BuilderMap().GetKey(i)); builder <<= THISBACK(NewBuilder); setdefault <<= THISBACK(SetDefault); linkmode_lock.SetLabel("Lock link mode"); } void BuildMethods::MethodMenu(Bar& bar) { method.StdBar(bar); bar.Separator(); bar.Add("Import", THISBACK(Import)); } void BuildMethods::Import() { if(!Save()) return; FileSel fsel; fsel.Type("Build methods (*.bm)", "*.bm") .AllFilesType() .Multi() .DefaultExt("bm"); if(!fsel.ExecuteOpen()) return; for(int i = 0; i < fsel.GetCount(); i++) { String f = LoadFile(fsel[i]); if(f.IsVoid()) { if(!PromptOKCancel(NFormat("Failed to load [* \1%s\1]. Continue?", fsel[i]))) break; continue; } String nf = ConfigFile(GetFileNamePos(fsel[i])); if(FileExists(nf) && !PromptOKCancel(NFormat("File already exists: [* \1%s\1]. Overwrite?", nf))) continue; if(!SaveFile(nf, f)) if(!PromptOKCancel(NFormat("Failed to save [* \1%s\1]. Continue?", nf))) break; } Load(); } static int sCompare(const Value& v1, const Value& v2) { return (String)v1 < (String)v2; } static bool IsGccBuilder(String b) { return b == "GCC" || b == "GCC32" || b == "GCC_ARM"; } void BuildMethods::NewBuilder() { String b = ~builder; if(IsNull(speed_options)) { if(IsGccBuilder(b)) #ifdef PLATFORM_WIN32 speed_options <<= "-O3 -ffunction-sections"; #else speed_options <<= "-O3"; #endif else speed_options <<= "-O2"; } if(IsNull(size_options)) { if(IsGccBuilder(b)) #ifdef PLATFORM_WIN32 size_options <<= "-Os -finline-limit=20 -ffunction-sections"; #else size_options <<= "-Os -finline-limit=20"; #endif else size_options <<= "-O1"; } if(IsNull(debug_options)) { if(IsGccBuilder(b)) debug_options <<= "-O0"; else debug_options <<= "-Od"; } if(IsNull(debugger)) { if(IsGccBuilder(b)) debugger <<= "gdb"; else debugger <<= "msdev"; } ChangeMethod(); } void BuildMethods::ChangeMethod() { String b; if(method.IsCursor()) b = method.Get("BUILDER"); scriptfile.Enable(b == "SCRIPT"); } void BuildMethods::Load() { FindFile ff(ConfigFile("*.bm")); while(ff) { VectorMap map; String fn = ConfigFile(ff.GetName()); if(LoadVarFile(fn, map)) { origfile.Add(fn); method.Add(GetFileTitle(fn)); for(int j = 1; j < method.GetIndexCount(); j++) method.Set(method.GetCount() - 1, j, map.Get(method.GetId(j).ToString(), Null)); } ff.Next(); } method.Sort(0, sCompare); method.GoBegin(); NewBuilder(); } bool BuildMethods::Save() { int i; Index name; for(i = 0; i < method.GetCount(); i++) { String n = method.Get(i, 0); if(name.Find(n) >= 0) { Exclamation("Duplicate method [* " + DeQtf(n) + "] !"); return false; } name.Add(n); } Index saved; for(i = 0; i < method.GetCount(); i++) { VectorMap map; for(int j = 1; j < method.GetIndexCount(); j++) map.Add(method.GetId(j).ToString(), method.Get(i, j)); if(map.Get("BUILDER", "") != "SCRIPT") map.RemoveKey("SCRIPT"); String fn = ConfigFile(String(method.Get(i, 0)) + ".bm"); if(!SaveVarFile(fn, map)) { Exclamation("Error saving [* " + fn + "] !"); return false; } saved.Add(fn); } for(i = 0; i < origfile.GetCount(); i++) if(saved.Find(origfile[i]) < 0) DeleteFile(origfile[i]); return true; } struct BoldDisplay : Display { virtual void Paint(Draw& w, const Rect& r, const Value& q, Color ink, Color paper, dword style) const { w.DrawRect(r, paper); DrawSmartText(w, r.left, r.top, r.Width(), (String)q, StdFont().Bold(), ink); } }; void BuildMethods::ShowDefault() { String m = GetDefaultMethod(); for(int i = 0; i < method.GetCount(); i++) if((String)method.Get(i, 0) == m) method.SetDisplay(i, 0, Single()); else method.SetDisplay(i, 0, StdDisplay()); } void BuildMethods::SetDefault() { if(method.IsCursor()) { SaveFile(ConfigFile("default_method"), method.GetKey()); ShowDefault(); } } void Ide::SetupBuildMethods() { BuildMethods m; m.Load(); m.ShowDefault(); m.use_target = use_target; for(;;) { int c = m.Run(); if(c == IDCANCEL) break; if(c == IDOK && m.Save()) { use_target = m.use_target; break; } } SyncBuildMode(); SetBar(); }