diff --git a/uppsrc/ide/BaseDlg.cpp b/uppsrc/ide/BaseDlg.cpp index ef2dc45fb..44b82e065 100644 --- a/uppsrc/ide/BaseDlg.cpp +++ b/uppsrc/ide/BaseDlg.cpp @@ -215,18 +215,6 @@ BaseSetupDlg::BaseSetupDlg() DirSelect(upv, upv_sel); upv.NullText(GetHubDir()); output.NullText(GetDefaultUppOut()); - - source_masks.AddList("*.cpp *.h"); - source_masks.AddList("*.cpp *.h *.hpp *.c *.cxx *.cc *.m *.mm"); - source_masks.AddList("*.cpp *.h *.hpp *.c *.cxx *.cc *.m *.mm *.cs *.java *.js *.ts *.tsx *.jsx"); - - external << [=] { Sync(); }; - Sync(); -} - -void BaseSetupDlg::Sync() -{ - source_masks.Enable(external); } bool BaseSetupDlg::Run(String& vars) @@ -236,8 +224,6 @@ bool BaseSetupDlg::Run(String& vars) include <<= GetVar("INCLUDE"); upv <<= GetVar("UPPHUB"); all <<= GetVar("_all") == "1"; - external <<= GetVar("EXTERNAL") == "1"; - source_masks <<= GetVar("SOURCE_MASKS"); base <<= vars; new_base = IsNull(vars); @@ -262,8 +248,6 @@ bool BaseSetupDlg::Run(String& vars) SetVar("INCLUDE", ~include); SetVar("UPPHUB", ~upv); SetVar("_all", all ? "1" : "0"); - SetVar("EXTERNAL", external ? "1" : "0"); - SetVar("SOURCE_MASKS", ~source_masks); Vector paths = SplitDirs(upp.GetText().ToString()); for(int i = 0; i < paths.GetCount(); i++) RealizeDirectory(paths[i]); diff --git a/uppsrc/ide/Core/Assembly.cpp b/uppsrc/ide/Core/Assembly.cpp index a8f0af9d5..9204eef2a 100644 --- a/uppsrc/ide/Core/Assembly.cpp +++ b/uppsrc/ide/Core/Assembly.cpp @@ -131,8 +131,8 @@ void OverrideHubDir(const String& path) } bool IsExternalMode() -{ // use TheIDE as editor/analyser, packages are stored separately, no compilation - return GetVar("EXTERNAL") == "1"; +{ // Any folder can be package, .upp files are not stored in packages (but in cfg/external) + return GetVarsName() == "[external]"; } String GetHubDir() @@ -234,6 +234,8 @@ String Nest::PackageDirectory0(const String& name) String uppfile = NativePath(name); if(IsFullPath(uppfile)) return NormalizePath(uppfile); + if(IsExternalMode()) // name must be full directory path in external mode + return String(); String pname = GetFileName(uppfile); Vector d = GetUppDirs(); for(int i = 0; i < d.GetCount(); i++) { diff --git a/uppsrc/ide/Core/Core.h b/uppsrc/ide/Core/Core.h index eec364223..e244f5ca9 100644 --- a/uppsrc/ide/Core/Core.h +++ b/uppsrc/ide/Core/Core.h @@ -346,8 +346,10 @@ String GetAssemblyId(); void InvalidatePackageCache(); bool IsExternalMode(); - +String EncodePathAsFileName(const String& path); +String DecodePathFromFileName(const String& n); bool IsDirectoryExternalPackage(const String& dir); + bool IsDirectoryPackage(const String& path); String PackageFile(const String& name); String SourcePath(const String& package, const String& name); diff --git a/uppsrc/ide/Core/Workspace.cpp b/uppsrc/ide/Core/Workspace.cpp index 91c5bc617..819da64ae 100644 --- a/uppsrc/ide/Core/Workspace.cpp +++ b/uppsrc/ide/Core/Workspace.cpp @@ -12,6 +12,8 @@ String PackageDirectory(const String& name) String GetPackagePathNest(const String& path) { + if(IsExternalMode()) + return Null; String h = UnixPath(NormalizePath(path)); for(auto dir : GetUppDirs()) if(h.StartsWith(UnixPath(NormalizePath(dir)) + '/')) @@ -36,17 +38,30 @@ bool IsDirectoryExternalPackage(const String& dir) bool IsDirectoryPackage(const String& path) { if(IsExternalMode()) - return IsDirectoryExternalPackage(path); + return DirectoryExists(path); return FileExists(AppendFileName(path, GetFileTitle(path) + ".upp")); } +String EncodePathAsFileName(const String& path) +{ + String p = UnixPath(path); + p.Replace("/", "[sLash]"); + p.Replace(":", "[cOlon]"); + return p; +} + +String DecodePathFromFileName(const String& n) +{ + String p = n; + p.Replace("[sLash]", "/"); + p.Replace("[cOlon]", ":"); + return p; +} + String PackageFile(const String& package) { // in external mode we are storing packages into .config if(IsExternalMode()) { - String p = ConfigFile("external/" + GetVarsName()) + "/" + - Filter(package, [](int c) { - return findarg(c, '/', '\\', ':') >= 0 ? '%' : c; - }); + String p = ConfigFile("external") + "/" + EncodePathAsFileName(package); RealizePath(p); return p; } diff --git a/uppsrc/ide/SelectPkg.cpp b/uppsrc/ide/SelectPkg.cpp index 4dbc8dfae..9bf8264b7 100644 --- a/uppsrc/ide/SelectPkg.cpp +++ b/uppsrc/ide/SelectPkg.cpp @@ -292,6 +292,10 @@ SelectPackageDlg::SelectPackageDlg(const char *title, bool selectvars_, bool mai }; help << [&] { LaunchWebBrowser("https://www.ultimatepp.org/app$ide$PackagesAssembliesAndNests$en-us.html"); }; + + String exf = VarFilePath("[external]"); + if(!FileExists(exf)) + SaveFile(exf, "SOURCE_MASKS = \"*.cpp *.h *.hpp *.c *.cxx *.cc *.m *.mm *.cs *.java *.js *.ts *.tsx *.jsx\";"); } String SelectPackageDlg::LRUFilePath() @@ -483,6 +487,16 @@ void SelectPackageDlg::OnFilter() SyncList(Null); } +String SelectExternalPackage() +{ + FileSel fs; + fs.ActiveDir(GetHomeDirectory()); + LoadFromGlobal(fs, "PackageDirSelector"); + bool b = fs.ExecuteSelectDir("Select package directory"); + StoreToGlobal(fs, "PackageDirSelector"); + return b ? ~fs : String::GetVoid(); +} + void SelectPackageDlg::OnBase() { if(!finished && !canceled) { @@ -490,10 +504,26 @@ void SelectPackageDlg::OnBase() if(splitter.IsShown()) nest <<= nest.GetCount() ? 0 : ALL; Load(); + newu.SetLabel(IsExternalMode() ? "New project" : "New package"); } } void SelectPackageDlg::OnNew() { + if(IsExternalMode()) { + String n = SelectExternalPackage(); + if(IsNull(n)) + return; + String f = PackageFile(n); + if(!FileExists(f)) { + Package p; + p.config.Add(); + p.Save(f); + } + selected = n; + selected_nest.Clear(); + Break(IDYES); + return; + } TemplateDlg dlg; LoadFromGlobal(dlg, "NewPackage"); dlg.Load(GetUppDirsRaw(), ~kind == MAIN); @@ -590,6 +620,14 @@ void SelectPackageDlg::OnBaseEdit() { if(!base.IsCursor()) return; + if(IsExternalMode()) { + WithExtSetupLayout dlg; + CtrlLayoutOKCancel(dlg, "External mode settings"); + dlg.source_masks <<= GetVar("SOURCE_MASKS"); + if(dlg.ExecuteOK()) + SetVar("SOURCE_MASKS", ~dlg.source_masks); + return; + } String vars = base.Get(0), oldvars = vars; if(BaseSetup(vars)) { if(vars != oldvars) @@ -809,20 +847,35 @@ void SelectPackageDlg::Load(const String& find) LoadVars(assembly); if(GetVar("_all") == "1") nest <<= ALL; + else + nest <<= 0; SyncFilter(); } Vector upp = GetUppDirsRaw(); - bool external = IsExternalMode(); packages.Clear(); list.AddFrame(lists_status); loading = true; data.Clear(); Index dir_exists; String cache_path = CachePath(GetVarsName()); - LoadFromFile(data, cache_path); - data.SetCount(upp.GetCount()); - for(int i = 0; i < upp.GetCount(); i++) // Scan nest folders for subfolders (additional package candidates) - ScanFolder(upp[i], data[i], upp[i], dir_exists, Null); + if(IsExternalMode()) { + upp << ""; + for(FindFile ff(ConfigFile("external") + "/*.*"); ff; ff.Next()) + if(ff.IsFile()) { + String dir = DecodePathFromFileName(ff.GetName()); + if(DirectoryExists(dir)) { + PkData& d = data.At(0).GetAdd(dir); + d.package = dir; + d.ispackage = true; + } + } + } + else { + LoadFromFile(data, cache_path); + data.SetCount(upp.GetCount()); + for(int i = 0; i < upp.GetCount(); i++) // Scan nest folders for subfolders (additional package candidates) + ScanFolder(upp[i], data[i], upp[i], dir_exists, Null); + } int update = msecs(); for(int i = 0; i < data.GetCount() && loading; i++) { // Now investigate individual sub folders ArrayMap& nest = data[i]; @@ -839,8 +892,8 @@ void SelectPackageDlg::Load(const String& find) PkData& d = nest[i]; String path = nest.GetKey(i); - if(NormalizePath(path).StartsWith(nest_dir) && DirectoryExists(path)) { - String upp_path = AppendFileName(path, GetFileName(d.package) + ".upp"); + if((IsExternalMode() || NormalizePath(path).StartsWith(nest_dir)) && DirectoryExists(path)) { + String upp_path = PackageFile(d.package); LSLOW(); // this is used for testing only, normally it is NOP Time tm = FileGetTime(upp_path); if(IsNull(tm)) // .upp file does not exist - not a package @@ -860,9 +913,6 @@ void SelectPackageDlg::Load(const String& find) else d.ispackage = true; - if(external && !d.ispackage) // in external mode folders with sources are packages - d.ispackage = IsDirectoryExternalPackage(path); - if(d.ispackage) { String icon_path; if(IsUHDMode()) @@ -887,7 +937,8 @@ void SelectPackageDlg::Load(const String& find) nest.Sweep(); } - StoreToFile(data, cache_path); + if(!IsExternalMode()) + StoreToFile(data, cache_path); list.RemoveFrame(lists_status); while(IsSplashOpen()) ProcessEvents(); @@ -905,7 +956,8 @@ void SelectPackageDlg::SyncBase(String initvars) Vector varlist; for(FindFile ff(ConfigFile("*.var")); ff; ff.Next()) if(ff.IsFile()) { - varlist.Add(GetFileTitle(ff.GetName())); + String n = ff.GetName(); + varlist.Add(GetFileTitle(n)); } Sort(varlist, &PackageLess); diff --git a/uppsrc/ide/UppDlg.h b/uppsrc/ide/UppDlg.h index 2baa0444b..4f55bc88c 100644 --- a/uppsrc/ide/UppDlg.h +++ b/uppsrc/ide/UppDlg.h @@ -121,7 +121,6 @@ public: private: void OnUpp(); - void Sync(); private: bool new_base; @@ -488,3 +487,5 @@ struct PackageEditor : WorkspaceWork, WithUppLayout { }; void EditPackages(const char *main, const char *startwith, String& cfg); + +String SelectExternalPackage(); diff --git a/uppsrc/ide/UppWspc.cpp b/uppsrc/ide/UppWspc.cpp index c784f6f6e..22c55bcf8 100644 --- a/uppsrc/ide/UppWspc.cpp +++ b/uppsrc/ide/UppWspc.cpp @@ -1,5 +1,4 @@ #include "ide.h" -#include "ide.h" const char tempaux[] = ""; const char prjaux[] = ""; @@ -1041,7 +1040,7 @@ void WorkspaceWork::ToggleIncludeable() void WorkspaceWork::AddNormalUses() { - String p = SelectPackage("Select package"); + String p = IsExternalMode() ? SelectExternalPackage() : SelectPackage("Select package"); if(p.IsEmpty()) return; diff --git a/uppsrc/ide/ide.lay b/uppsrc/ide/ide.lay index f3d8ce65c..088af1c20 100644 --- a/uppsrc/ide/ide.lay +++ b/uppsrc/ide/ide.lay @@ -842,25 +842,29 @@ LAYOUT(GoToLineLayout, 260, 88) ITEM(Upp::Button, cancel, SetLabel(t_("Cancel")).RightPosZ(8, 64).BottomPosZ(8, 24)) END_LAYOUT -LAYOUT(BaseSetupLayout, 660, 220) +LAYOUT(BaseSetupLayout, 664, 176) ITEM(Upp::Label, dv___0, SetLabel(t_("Package nests")).LeftPosZ(4, 96).TopPosZ(4, 19)) - ITEM(Upp::EditString, upp, HSizePosZ(104, 28).TopPosZ(4, 19)) - ITEM(Upp::Button, setup_nest, SetLabel(t_("..")).RightPosZ(4, 20).TopPosZ(4, 19)) + ITEM(Upp::EditString, upp, HSizePosZ(104, 32).TopPosZ(4, 19)) + ITEM(Upp::Button, setup_nest, SetLabel(t_("..")).RightPosZ(8, 20).TopPosZ(4, 19)) ITEM(Upp::Label, dv___3, SetLabel(t_("Output directory")).LeftPosZ(4, 96).TopPosZ(28, 19)) - ITEM(Upp::EditString, output, HSizePosZ(104, 28).TopPosZ(28, 19)) - ITEM(Upp::Button, output_sel, RightPosZ(4, 20).TopPosZ(28, 19)) + ITEM(Upp::EditString, output, HSizePosZ(104, 32).TopPosZ(28, 19)) + ITEM(Upp::Button, output_sel, RightPosZ(8, 20).TopPosZ(28, 19)) ITEM(Upp::Label, dv___6, SetLabel(t_("Assembly name")).LeftPosZ(4, 96).TopPosZ(52, 19)) ITEM(Upp::EditString, base, NotNull(true).LeftPosZ(104, 140).TopPosZ(52, 19)) ITEM(Upp::Label, dv___8, SetLabel(t_("Additional includes")).LeftPosZ(4, 96).TopPosZ(76, 19)) - ITEM(Upp::EditString, include, HSizePosZ(104, 28).TopPosZ(76, 19)) - ITEM(Upp::Button, setup_includes, SetLabel(t_("..")).RightPosZ(4, 20).TopPosZ(76, 19)) - ITEM(Upp::Label, dv___11, SetLabel(t_("UppHub directory")).LeftPosZ(4, 96).BottomPosZ(101, 19)) - ITEM(Upp::EditString, upv, HSizePosZ(104, 28).BottomPosZ(101, 19)) - ITEM(Upp::Button, upv_sel, RightPosZ(4, 20).BottomPosZ(101, 19)) - ITEM(Upp::Label, dv___14, SetLabel(t_("Source masks")).LeftPosZ(4, 96).BottomPosZ(37, 19)) - ITEM(Upp::WithDropChoice, source_masks, HSizePosZ(104, 4).BottomPosZ(37, 19)) - ITEM(Upp::Option, all, SetLabel(t_("Preselect All instead of the first nest")).HSizePosZ(4, 140).BottomPosZ(80, 16)) - ITEM(Upp::Option, external, SetLabel(t_("External mode (advanced option - packages are folders with sources, package files are stored as theide config)")).HSizePosZ(4, 4).BottomPosZ(60, 16)) + ITEM(Upp::EditString, include, HSizePosZ(104, 32).TopPosZ(76, 19)) + ITEM(Upp::Button, setup_includes, SetLabel(t_("..")).RightPosZ(8, 20).TopPosZ(76, 19)) + ITEM(Upp::Label, dv___11, SetLabel(t_("UppHub directory")).LeftPosZ(4, 96).BottomPosZ(57, 19)) + ITEM(Upp::EditString, upv, HSizePosZ(104, 32).BottomPosZ(57, 19)) + ITEM(Upp::Button, upv_sel, RightPosZ(8, 20).BottomPosZ(57, 19)) + ITEM(Upp::Option, all, SetLabel(t_("Preselect All instead of the first nest")).HSizePosZ(4, 144).BottomPosZ(36, 16)) + ITEM(Upp::Button, ok, SetLabel(t_("OK")).RightPosZ(76, 64).BottomPosZ(8, 24)) + ITEM(Upp::Button, cancel, SetLabel(t_("Cancel")).RightPosZ(8, 64).BottomPosZ(8, 24)) +END_LAYOUT + +LAYOUT(ExtSetupLayout, 660, 64) + ITEM(Upp::Label, dv___0, SetLabel(t_("Source masks")).LeftPosZ(4, 96).BottomPosZ(37, 19)) + ITEM(Upp::EditString, source_masks, HSizePosZ(104, 4).BottomPosZ(37, 19)) ITEM(Upp::Button, ok, SetLabel(t_("OK")).RightPosZ(72, 64).BottomPosZ(8, 24)) ITEM(Upp::Button, cancel, SetLabel(t_("Cancel")).RightPosZ(4, 64).BottomPosZ(8, 24)) END_LAYOUT