Index: uppsrc/ide/BaseDlg.cpp =================================================================== --- uppsrc/ide/BaseDlg.cpp (revision 11990) +++ uppsrc/ide/BaseDlg.cpp (working copy) @@ -1,113 +1,253 @@ -#include "ide.h" - -static VectorMap sPi; - -void InvalidatePackageInfo(const String& name) -{ - int q = sPi.Find(name); - if(q >= 0) - sPi[q].path.Clear(); -} - -PackageInfo GetPackageInfo(const String& name) -{ - String path = PackagePath(name); - Time tm = FileGetTime(path); - int q = sPi.Find(name); - if(q >= 0) { - if(path == sPi[q].path && tm == sPi[q].stamp) - return sPi[q]; - } - else { - q = sPi.GetCount(); - sPi.Add(name); - } - PackageInfo& pi = sPi[q]; - pi.path = path; - pi.stamp = tm; - Package p; - p.Load(path); - pi.ink = p.ink; - pi.italic = p.italic; - pi.bold = p.bold; - return pi; -} - -bool BaseSetup(String& vars) { return BaseSetupDlg().Run(vars); } - -BaseSetupDlg::BaseSetupDlg() -: browse_out("Output & intermediate files") -{ - CtrlLayoutOKCancel(*this, "Assembly setup"); - browse_upp.SetImage(CtrlImg::right_arrow()); - browse_upp <<= THISBACK(OnBrowseUpp); - upp.AddFrame(browse_upp); - upp <<= THISBACK(OnUpp); - browse_out.Attach(output); -} - -bool BaseSetupDlg::Run(String& vars) -{ - upp <<= GetVar("UPP"); - output <<= GetVar("OUTPUT"); - base <<= vars; - new_base = IsNull(vars); - while(TopWindow::Run() == IDOK) - { - String varname = ~base; - String varfile = VarFilePath(varname); - if(varname != vars) - { - if(FileExists(varfile) && !PromptOKCancel(NFormat("Overwrite existing assembly [* \1%s\1]?", varfile))) - continue; - if(!SaveVars(varname)) - { - Exclamation(NFormat("Error writing assmbly [* \1%s\1].", VarFilePath(varname))); - continue; - } - } - SetVar("UPP", ~upp); - SetVar("OUTPUT", ~output); - Vector paths = SplitDirs(upp.GetText().ToString()); - for(int i = 0; i < paths.GetCount(); i++) - RealizeDirectory(paths[i]); - RealizeDirectory(~output); - vars = varname; - return true; - } - return false; -} - -void BaseSetupDlg::OnBrowseUpp() -{ - String s = ~upp; - int b, e; - if(upp.HasFocus()) - upp.GetSelection(b, e); - else - e = s.GetLength(); - b = e; - while(b > 0 && s[b - 1] != ';') - b--; - while(e < s.GetLength() && s[e] != ';') - e++; - FileSel fsel; - String pre = s.Left(b), post = s.Mid(e); - fsel.ActiveDir(s.Mid(b, e - b)); - if(fsel.ExecuteSelectDir()) { - String newdir = ~fsel; - upp <<= pre + newdir + Nvl(post, ";"); - upp.SetWantFocus(); - OnUpp(); - } -} - -void BaseSetupDlg::OnUpp() -{ - if(new_base) { - String s = ~upp; - int f = s.Find(';'); - if(f >= 0) s.Trim(f); - base <<= GetFileTitle(s); - } -} +#include "ide.h" + +static VectorMap sPi; + +void InvalidatePackageInfo(const String& name) +{ + int q = sPi.Find(name); + if(q >= 0) + sPi[q].path.Clear(); +} + +PackageInfo GetPackageInfo(const String& name) +{ + String path = PackagePath(name); + Time tm = FileGetTime(path); + int q = sPi.Find(name); + if(q >= 0) { + if(path == sPi[q].path && tm == sPi[q].stamp) + return sPi[q]; + } + else { + q = sPi.GetCount(); + sPi.Add(name); + } + PackageInfo& pi = sPi[q]; + pi.path = path; + pi.stamp = tm; + Package p; + p.Load(path); + pi.ink = p.ink; + pi.italic = p.italic; + pi.bold = p.bold; + return pi; +} + +void AddAssemblyPaths(FileSel& dir, const String& vars) +{ + // Adds the existing assemblies to the file selector. + int i = 0; + for(FindFile ff(ConfigFile("*.var")); ff; ff.Next()) { + auto fname = GetFileTitle(ff.GetName()); + if(ff.IsFile() && !fname.IsEqual(vars)) { + Nest n; + if(!n.Load(ff.GetPath())) + continue; + auto paths = Split(n.Get("UPP"), ';'); + if(paths.IsEmpty()) + continue; + const auto& path = paths[0]; + dir.AddPlace(path, IdeImg::Icon, fname); + i++; + } + } + if(i) + dir.AddPlaceSeparator(); +} + +NestEditorDlg::NestEditorDlg(const String& vars, const String& nest_paths) +{ + CtrlLayoutOKCancel(*this, "Package Nests Editor"); + Sizeable().Zoomable(); + + add.SetImage(CtrlImg::Add()).WhenAction = THISFN(AddRow); + modify.SetImage(IdeImg::work()).WhenAction = THISFN(EditRow); + remove.SetImage(IdeImg::closesplit()).WhenAction = THISFN(DeleteRow); + + nests.AutoHideSb() + .Inserting() + .Appending() + .Removing() + .Moving() + .MultiSelect() + .NoAppendLine() + .VertGrid(false) + .AddColumn("Paths").Edit(edit); + nests.SetData(nest_paths); + nests.WhenArrayAction = edit << THISFN(Modify); + nests.WhenStartEdit = THISFN(Sync); + nests.WhenAcceptEdit = THISFN(RemoveEmptyRows); + Add(nests.HSizePosZ(4, 4).VSizePosZ(32, 32)); + + edit_dir.Attach(edit); + edit_dir.AllFilesType(); + edit_dir.Title(String("Select nest path")); + + AddAssemblyPaths((FileSel&) edit_dir, vars); + Sync(); +} + +void NestEditorDlg::AddRow() +{ + if(nests.IsEdit()) + nests.AcceptEnter(); + nests.DoAppend(); + Sync(); +} + +void NestEditorDlg::EditRow() +{ + if(!nests.IsEdit()) + nests.DoEdit(); + Sync(); +} + +void NestEditorDlg::DeleteRow() +{ + auto b = IsRowEmpty(); + auto c = nests.IsEdit(); + if(c) + nests.AcceptEnter(); + if(!b && !nests.DoRemove() && c) + nests.DoEdit(); + Sync(); +} + +void NestEditorDlg::Modify() +{ + Update(); + Sync(); +} + +void NestEditorDlg::Sync() +{ + nests.Sync(); + bool b = nests.IsEdit(); + bool bb = nests.GetCount() > 0; + + modify.Enable(!b && bb); + remove.Enable(bb); + nests.SetCursor(nests.GetCursor()); +} + +void NestEditorDlg::RemoveEmptyRows() +{ + if(nests.IsCursor() && IsRowEmpty()) + nests.Remove(nests.GetCursor()); + Sync(); +} + +void NestEditorDlg::NestTable::SetData(const Value& data) +{ + Vector l = Split((String) data, ';'); + Clear(); + for(int i = 0; i < l.GetCount(); i++) + Add(l[i]); +} + +Value NestEditorDlg::NestTable::GetData() const +{ + String s; + for(int i = 0; i < GetCount(); i++) { + if(i) s << ';'; + s << (String) Get(i, 0); + } + return s; +} + + +bool BaseSetup(String& vars) { return BaseSetupDlg().Run(vars); } + +BaseSetupDlg::BaseSetupDlg() +: browse_out("Output & intermediate files") +{ + CtrlLayoutOKCancel(*this, "Assembly setup"); + browse_upp.SetImage(CtrlImg::right_arrow()).Tip("Select path"); + browse_upp <<= THISBACK(OnBrowseUpp); + setup_nest.SetImage(CtrlImg::down_arrow()).Tip("Open nest editor"); + setup_nest <<= THISBACK(OnSetupNests); + upp.AddFrame(setup_nest); + upp.AddFrame(browse_upp); + upp <<= THISBACK(OnUpp); + browse_out.Attach(output); +} + +bool BaseSetupDlg::Run(String& vars) +{ + upp <<= GetVar("UPP"); + output <<= GetVar("OUTPUT"); + base <<= vars; + new_base = IsNull(vars); + + while(TopWindow::Run() == IDOK) + { + String varname = ~base; + String varfile = VarFilePath(varname); + if(varname != vars) + { + if(FileExists(varfile) && !PromptOKCancel(NFormat("Overwrite existing assembly [* \1%s\1]?", varfile))) + continue; + if(!SaveVars(varname)) + { + Exclamation(NFormat("Error writing assmbly [* \1%s\1].", VarFilePath(varname))); + continue; + } + } + SetVar("UPP", ~upp); + SetVar("OUTPUT", ~output); + Vector paths = SplitDirs(upp.GetText().ToString()); + for(int i = 0; i < paths.GetCount(); i++) + RealizeDirectory(paths[i]); + RealizeDirectory(~output); + vars = varname; + return true; + } + return false; +} + +void BaseSetupDlg::OnSetupNests() +{ + NestEditorDlg ndlg(~base, ~upp); + if(!ndlg.ExecuteOK()) + return; + upp.SetData(~ndlg.nests); + OnUpp(); +} + + +void BaseSetupDlg::OnBrowseUpp() +{ + String s = ~upp; + int b, e; + if(upp.HasFocus()) + upp.GetSelection(b, e); + else + e = s.GetLength(); + b = e; + while(b > 0 && s[b - 1] != ';') + b--; + while(e < s.GetLength() && s[e] != ';') + e++; + SelectDirButton dirsel; + String pre = s.Left(b), post = s.Mid(e); + dirsel.ActiveDir(s.Mid(b, e - b)); + + AddAssemblyPaths((FileSel&) dirsel, ~base); + + if(dirsel.ExecuteSelectDir()) { + String newdir = ~dirsel; + upp <<= pre + newdir + Nvl(post, ";"); + upp.SetWantFocus(); + OnUpp(); + } +} + +void BaseSetupDlg::OnUpp() +{ + if(new_base) { + String s = ~upp; + int f = s.Find(';'); + if(f >= 0) s.Trim(f); + base <<= GetFileTitle(s); + } +} Index: uppsrc/ide/UppDlg.h =================================================================== --- uppsrc/ide/UppDlg.h (revision 11990) +++ uppsrc/ide/UppDlg.h (working copy) @@ -99,25 +99,51 @@ int FilterPackageName(int c); +class NestEditorDlg : public WithNestEditorLayout { +public: + typedef NestEditorDlg CLASSNAME; + NestEditorDlg(const String& vars, const String& nest_paths); + + struct NestTable : ArrayCtrl { + void SetData(const Value& data) override; + Value GetData() const override; + } nests; + +private: + void AddRow(); + void EditRow(); + void DeleteRow(); + void Sync(); + void Modify(); + void RemoveEmptyRows(); + bool IsRowEmpty() const { return IsNull(nests.Get(nests.GetCursor(), 0)); } + + EditString edit; + SelectDirButton edit_dir; +}; + class BaseSetupDlg : public WithBaseSetupLayout { public: - typedef BaseSetupDlg CLASSNAME; - BaseSetupDlg(); + typedef BaseSetupDlg CLASSNAME; + BaseSetupDlg(); - bool Run(String& vars); + bool Run(String& vars); private: - void OnUpp(); - void OnBrowseUpp(); + void OnUpp(); + void OnBrowseUpp(); + void OnSetupNests(); private: - FrameRight