diff --git a/uppsrc/Core/JSON.cpp b/uppsrc/Core/JSON.cpp index 577de40c5..cba60945a 100644 --- a/uppsrc/Core/JSON.cpp +++ b/uppsrc/Core/JSON.cpp @@ -229,6 +229,9 @@ template<> void Jsonize(JsonIO& io, String& var) { if(io.IsLoading()) { const Value& v = io.Get(); + if(IsNull(v)) + var = Null; + else if(IsString(v)) var = v; else @@ -242,6 +245,9 @@ template<> void Jsonize(JsonIO& io, WString& var) { if(io.IsLoading()) { const Value& v = io.Get(); + if(IsNull(v)) + var = Null; + else if(IsString(v)) var = v; else diff --git a/uppsrc/Core/Xmlize.h b/uppsrc/Core/Xmlize.h index c6c7ddf50..a04e6c00b 100644 --- a/uppsrc/Core/Xmlize.h +++ b/uppsrc/Core/Xmlize.h @@ -345,6 +345,12 @@ void XmlizeByJsonize(XmlIO& xio, T& x) { if(xio.IsStoring()) StoreJsonValue(xio, StoreAsJsonValue(x)); - else - LoadFromJsonValue(x, LoadJsonValue(xio.Node())); + else { + try { + LoadFromJsonValue(x, LoadJsonValue(xio.Node())); + } + catch(JsonizeError e) { + throw XmlError("xmlize by jsonize error: " + e); + } + } } diff --git a/uppsrc/Core/src.tpp/DateFmt$en-us.tpp b/uppsrc/Core/src.tpp/DateFmt$en-us.tpp index b916f5755..b91ffcbfd 100644 --- a/uppsrc/Core/src.tpp/DateFmt$en-us.tpp +++ b/uppsrc/Core/src.tpp/DateFmt$en-us.tpp @@ -42,40 +42,6 @@ function.&] [s7; [*/ Return value]-|Filtered character.&] [s3; &] [s4;%- &] -[s5;:DayOfWeek`(Date`):%- [@(0.0.255) int]_[* DayOfWeek]([_^Date^ Date]_[*@3 date])&] -[s2; Day [%-*@3 date] number of day of week, beginning from 0.&] -[s3; &] -[s4;%- &] -[s5;:LastDayOfMonth`(Date`):%- [_^Date^ Date]_[* LastDayOfMonth]([_^Date^ Date]_[*@3 d])&] -[s2; Returns day [%-*@3 d] last day of the month.&] -[s0;l288; Example:&] -[s0;l288; [*C@3 ][*C LastDayOfMonth(Date(2011, 9, 23)) `= `"30/9/2011`"]&] -[s3; &] -[s4;%- &] -[s5;:FirstDayOfMonth`(Date`):%- [_^Date^ Date]_[* FirstDayOfMonth]([_^Date^ Date]_[*@3 d])&] -[s2; Returns day [%-*@3 d] first day of the month.&] -[s0;l288; Example:&] -[s0;l288; [*C@3 ][*C LastDayOfYear(Date(2011, 9, 23)) `= `"1/9/2011`"]&] -[s3; &] -[s4;%- &] -[s5;:LastDayOfYear`(Date`):%- [_^Date^ Date]_[* LastDayOfYear]([_^Date^ Date]_[*@3 d])&] -[s2; Returns day [%-*@3 d] last day of the year.&] -[s0;l288; Example:&] -[s0;l288; [*C@3 ][*C LastDayOfYear(Date(2011, 9, 23)) `= `"31/12/2011`"]&] -[s3; &] -[s4;%- &] -[s5;:FirstDayOfYear`(Date`):%- [_^Date^ Date]_[* FirstDayOfYear]([_^Date^ Date]_[*@3 d])&] -[s2; Returns day [%-*@3 d ]first day of the year.&] -[s0;l288; Example:&] -[s0;l288; [*C@3 ][*C FirstDayOfYear(Date(2011, 9, 23)) `= `"1/1/2011`"]&] -[s3; &] -[s4;%- &] -[s5;:DayOfYear`(Date`):%- [@(0.0.255) int]_[* DayOfYear]([_^Date^ Date]_[*@3 d])&] -[s2; Returns day [%-*@3 d ]number of day of year, beginning from 1.&] -[s0;l288; Example:&] -[s0;l288; [*C@3 ][*C DayOfYear(Date(2011, 1, 2)) `= 2]&] -[s3; &] -[s4;%- &] [s5;:SetDateFormat`(const char`*`):%- [@(0.0.255) void]_[* SetDateFormat]([@(0.0.255) const ]_[@(0.0.255) char]_`*[*@3 fmt])&] [s2; Sets formating string for dates. When used for formatting, there diff --git a/uppsrc/Core/src.tpp/DateTime$en-us.tpp b/uppsrc/Core/src.tpp/DateTime$en-us.tpp index 76e484478..8a028dea9 100644 --- a/uppsrc/Core/src.tpp/DateTime$en-us.tpp +++ b/uppsrc/Core/src.tpp/DateTime$en-us.tpp @@ -87,6 +87,66 @@ onst]&] [s3; &] [s0; &] [s0; &] +[ {{10000@(113.42.0) [s0;%% [*@7;4 Date functions]]}}&] +[s0; &] +[s3;%% &] +[s4; &] +[s5;:DayOfWeek`(Date`): [@(0.0.255) int]_[* DayOfWeek]([_^Date^ Date]_[*@3 date])&] +[s2;%% Day [%-*@3 date] number of day of week, beginning from 0.&] +[s3;%% &] +[s4; &] +[s5;:IsLeapYear`(int`): [@(0.0.255) bool]_[* IsLeapYear]([@(0.0.255) int]_[*@3 year])&] +[s2;%% Returns true if [%-*@3 year] is leap (there is 29 days in February +in that year).&] +[s3;%% &] +[s4; &] +[s5;:GetDaysOfMonth`(int`,int`): [@(0.0.255) int]_[* GetDaysOfMonth]([@(0.0.255) int]_[*@3 mo +nth], [@(0.0.255) int]_[*@3 year])&] +[s2;%% Returns a number of days in [%-*@3 month] of [%-*@3 year].&] +[s3;%% &] +[s4; &] +[s5;:LastDayOfMonth`(Date`): [_^Date^ Date]_[* LastDayOfMonth]([_^Date^ Date]_[*@3 d])&] +[s2;%% Returns day [%-*@3 d] last day of the month.&] +[s0;l288;%% Example:&] +[s0;l288;%% [*C@3 ][*C LastDayOfMonth(Date(2011, 9, 23)) `= `"30/9/2011`"]&] +[s3;%% &] +[s4; &] +[s5;:FirstDayOfMonth`(Date`): [_^Date^ Date]_[* FirstDayOfMonth]([_^Date^ Date]_[*@3 d])&] +[s2;%% Returns day [%-*@3 d] first day of the month.&] +[s0;l288;%% Example:&] +[s0;l288;%% [*C@3 ][*C LastDayOfYear(Date(2011, 9, 23)) `= `"1/9/2011`"]&] +[s3;%% &] +[s4; &] +[s5;:LastDayOfYear`(Date`): [_^Date^ Date]_[* LastDayOfYear]([_^Date^ Date]_[*@3 d])&] +[s2;%% Returns day [%-*@3 d] last day of the year.&] +[s0;l288;%% Example:&] +[s0;l288;%% [*C@3 ][*C LastDayOfYear(Date(2011, 9, 23)) `= `"31/12/2011`"]&] +[s3;%% &] +[s4; &] +[s5;:FirstDayOfYear`(Date`): [_^Date^ Date]_[* FirstDayOfYear]([_^Date^ Date]_[*@3 d])&] +[s2;%% Returns day [%-*@3 d ]first day of the year.&] +[s0;l288;%% Example:&] +[s0;l288;%% [*C@3 ][*C FirstDayOfYear(Date(2011, 9, 23)) `= `"1/1/2011`"]&] +[s3;%% &] +[s4; &] +[s5;:DayOfYear`(Date`): [@(0.0.255) int]_[* DayOfYear]([_^Date^ Date]_[*@3 d])&] +[s2;%% Returns day [%-*@3 d ]number of day of year, beginning from +1.&] +[s0;l288;%% Example:&] +[s0;l288;%% [*C@3 ][*C DayOfYear(Date(2011, 1, 2)) `= 2]&] +[s3;%% &] +[s4; &] +[s5;:AddMonths`(Date`,int`): [_^Date^ Date]_[* AddMonths]([_^Date^ Date]_[*@3 date], +[@(0.0.255) int]_[*@3 months])&] +[s2;%% Adds [%-*@3 months] to [%-*@3 date] and returns the result.&] +[s3;%% &] +[s4; &] +[s5;:AddYears`(Date`,int`): [_^Date^ Date]_[* AddYears]([_^Date^ Date]_[*@3 date], +[@(0.0.255) int]_[*@3 years])&] +[s2;%% Adds [%-*@3 years] to [%-*@3 date] and returns the result. Note +that this is not as simple as adding year attribute of Date because +of leap years.&] +[s0; &] [s0; &] [ {{10000@(113.42.0) [s0;%% [*@7;4 Time]]}}&] [s3; &] @@ -152,4 +212,4 @@ _>_]&] ]&] [s2;%% Converst the time into a system specific value.&] [s3; &] -[s0; ] \ No newline at end of file +[s0; ]] \ No newline at end of file diff --git a/uppsrc/ide/Browser/TopicBase.cpp b/uppsrc/ide/Browser/TopicBase.cpp index c4f7581f3..ccc42e899 100644 --- a/uppsrc/ide/Browser/TopicBase.cpp +++ b/uppsrc/ide/Browser/TopicBase.cpp @@ -1,6 +1,6 @@ #include "Browser.h" -#define LLOG(x) // DLOG(x) +#define LLOG(x) // DLOG(x) Index& ref_link() { diff --git a/uppsrc/ide/Common/Common.h b/uppsrc/ide/Common/Common.h index d16c1d256..fec8ae1b6 100644 --- a/uppsrc/ide/Common/Common.h +++ b/uppsrc/ide/Common/Common.h @@ -32,6 +32,9 @@ void ShellOpenFolder(const String& dir); Image IdeFileImage(const String& filename, bool fast = false, bool include_path = false); bool FinishSave(String tmpfile, String outfile); +void DeactivationSave(bool b); +bool IsDeactivationSave(); + bool FinishSave(String outfile); bool SaveFileFinish(const String& filename, const String& data); bool SaveChangedFileFinish(const String& filename, const String& data); diff --git a/uppsrc/ide/Common/Util.cpp b/uppsrc/ide/Common/Util.cpp index 835dcac15..adae17a35 100644 --- a/uppsrc/ide/Common/Util.cpp +++ b/uppsrc/ide/Common/Util.cpp @@ -1,195 +1,213 @@ -#include "Common.h" - -bool Debugger::Tip(const String&, CodeEditor::MouseTip&) -{ - return false; -} - -bool FinishSave(String tmpfile, String outfile) -{ - Progress progress; - int time = GetTickCount(); - for(;;) { - progress.SetTotal(10000); - progress.SetText("Saving '" + GetFileName(outfile) + "'"); - if(!FileExists(tmpfile)) - return false; - FileDelete(outfile); - if(FileMove(tmpfile, outfile)) - return true; - IdeConsoleFlush(); - Sleep(200); - if(progress.SetPosCanceled((GetTickCount() - time) % progress.GetTotal())) { - int art = Prompt(Ctrl::GetAppName(), CtrlImg::exclamation(), - "Unable to save current file.&" - "Retry save, ignore it or save file to another location?", - "Save as...", "Retry", "Ignore"); - if(art < 0) - return false; - if(art && AnySourceFs().ExecuteSaveAs()) - outfile = AnySourceFs(); - progress.SetPos(0); - } - } -} - -bool FinishSave(String outfile) -{ - return FinishSave(outfile + ".$tmp", outfile); -} - -bool SaveFileFinish(const String& filename, const String& data) -{ - if(!SaveFile(filename + ".$tmp", data)) { - Exclamation("Error creating temporary file " + filename); - return false; - } - return FinishSave(filename); -} - -bool SaveChangedFileFinish(const String& filename, const String& data) -{ - if(data == LoadFile(filename)) - return true; - return SaveFileFinish(filename, data); -} - -typedef VectorMap sStringMap; - -GLOBAL_VAR(sStringMap, sWorkspaceCfg) -GLOBAL_VAR(Vector, sWorkspaceCfgFlush) - -void RegisterWorkspaceConfig(const char *name) -{ - ASSERT(sWorkspaceCfg().Find(name) < 0); - sWorkspaceCfg().Add(name); -} - -void RegisterWorkspaceConfig(const char *name, Callback WhenFlush) -{ - RegisterWorkspaceConfig(name); - sWorkspaceCfgFlush().Add(WhenFlush); -} - - -String& WorkspaceConfigData(const char *name) -{ - return sWorkspaceCfg().GetAdd(name); -} - -void SerializeWorkspaceConfigs(Stream& s) -{ - int i; - for(i = 0; i < sWorkspaceCfgFlush().GetCount(); i++) - sWorkspaceCfgFlush()[i](); - VectorMap& cfg = sWorkspaceCfg(); - int version = 0; - s / version; - int count = cfg.GetCount(); - s / count; - for(i = 0; i < count; i++) { - String name; - if(s.IsStoring()) - name = cfg.GetKey(i); - s % name; - int q = cfg.Find(name); - if(q >= 0) - s % cfg[q]; - else - { - String dummy; - s % dummy; - } - } - s.Magic(); -} - -bool GuiPackageResolver(const String& error, const String& path, int line) -{ -prompt: - switch(Prompt(Ctrl::GetAppName(), CtrlImg::exclamation(), - error + "&while parsing package " + DeQtf(path), - "Edit \\& Retry", "Ignore", "Stop")) { - case 0: - if(!PromptYesNo("Ignoring will damage package. Everything past the " - "point of error will be lost.&Do you want to continue ?")) - goto prompt; - return false; - case 1: { - TopWindow win; - LineEdit edit; - edit.Set(LoadFile(path)); - edit.SetCursor(edit.GetPos(line)); - win.Title(path); - win.Add(edit.SizePos()); - win.Run(); - SaveFile(path, edit.Get()); - } - return true;; - case -1: - exit(1); - } - return false; -} - -void CleanModules() -{ - for(int i = 0; i < GetIdeModuleCount(); i++) - GetIdeModule(i).CleanUsc(); -} - -bool IdeModuleUsc(CParser& p) -{ - for(int i = 0; i < GetIdeModuleCount(); i++) - if(GetIdeModule(i).ParseUsc(p)) - return true; - return false; -} - -static void ReadMacro(CParser& p) -{ - IdeMacro macro; - if(p.IsString()) { - macro.menu = p.ReadString(); - if(p.Char(':')) - macro.submenu = p.ReadString(); - } - if(!p.IsChar('{')) - macro.hotkey = ParseKeyDesc(p); - EscLambda& l = macro.code.CreateLambda(); - const char *t = p.GetPtr(); - l.filename = p.GetFileName(); - l.line = p.GetLine(); - if(!p.Char('{')) - p.ThrowError("missing '{'"); - SkipBlock(p); - l.code = String(t, p.GetPtr()); - Array& mlist = UscMacros(); - if(macro.hotkey) { - int f = FindFieldIndex(mlist, &IdeMacro::hotkey, macro.hotkey); - if(f >= 0) { - PutConsole(NFormat("%s(%d): duplicate macro hotkey %s\n", l.filename, l.line, GetKeyDesc(macro.hotkey))); - const EscLambda& lambda = UscMacros()[f].code.GetLambda(); - PutConsole(NFormat("%s(%d): previously defined here\n", lambda.filename, lambda.line)); - } - } - if(!IsNull(macro.menu)) { - for(int i = 0; i < mlist.GetCount(); i++) - if(mlist[i].menu == macro.menu && mlist[i].submenu == macro.submenu) { - PutConsole(NFormat("%s(%d): duplicate macro menu item (%s:%s)\n", - l.filename, l.line, macro.menu, macro.submenu)); - const EscLambda& lambda = UscMacros()[i].code.GetLambda(); - PutConsole(NFormat("%s(%d): previously defined here\n", lambda.filename, lambda.line)); - break; - } - } - mlist.Add(macro); -} - -INITBLOCK { - Package::SetPackageResolver(GuiPackageResolver); - UscSetCleanModules(CleanModules); - SetIdeModuleUsc(IdeModuleUsc); - UscSetReadMacro(ReadMacro); -} - +#include "Common.h" + +bool Debugger::Tip(const String&, CodeEditor::MouseTip&) +{ + return false; +} + +bool deactivation_save; + +void DeactivationSave(bool b) // On deactivation, make no prompts, ignore save errors +{ + deactivation_save = b; +} + +bool IsDeactivationSave() +{ + return deactivation_save; +} + +bool FinishSave(String tmpfile, String outfile) +{ + if(IsDeactivationSave()) { + FileMove(tmpfile, outfile); + return true; + } + Progress progress; + int time = GetTickCount(); + for(;;) { + progress.SetTotal(10000); + progress.SetText("Saving '" + GetFileName(outfile) + "'"); + if(!FileExists(tmpfile)) + return false; + FileDelete(outfile); + if(FileMove(tmpfile, outfile)) + return true; + IdeConsoleFlush(); + Sleep(200); + if(progress.SetPosCanceled((GetTickCount() - time) % progress.GetTotal())) { + int art = Prompt(Ctrl::GetAppName(), CtrlImg::exclamation(), + "Unable to save current file.&" + "Retry save, ignore it or save file to another location?", + "Save as...", "Retry", "Ignore"); + if(art < 0) + return false; + if(art && AnySourceFs().ExecuteSaveAs()) + outfile = AnySourceFs(); + progress.SetPos(0); + } + } +} + +bool FinishSave(String outfile) +{ + return FinishSave(outfile + ".$tmp", outfile); +} + +bool SaveFileFinish(const String& filename, const String& data) +{ + if(!SaveFile(filename + ".$tmp", data)) { + if(IsDeactivationSave()) + return true; + Exclamation("Error creating temporary file " + filename); + return false; + } + return FinishSave(filename); +} + +bool SaveChangedFileFinish(const String& filename, const String& data) +{ + if(data == LoadFile(filename)) + return true; + return SaveFileFinish(filename, data); +} + +typedef VectorMap sStringMap; + +GLOBAL_VAR(sStringMap, sWorkspaceCfg) +GLOBAL_VAR(Vector, sWorkspaceCfgFlush) + +void RegisterWorkspaceConfig(const char *name) +{ + ASSERT(sWorkspaceCfg().Find(name) < 0); + sWorkspaceCfg().Add(name); +} + +void RegisterWorkspaceConfig(const char *name, Callback WhenFlush) +{ + RegisterWorkspaceConfig(name); + sWorkspaceCfgFlush().Add(WhenFlush); +} + + +String& WorkspaceConfigData(const char *name) +{ + return sWorkspaceCfg().GetAdd(name); +} + +void SerializeWorkspaceConfigs(Stream& s) +{ + int i; + for(i = 0; i < sWorkspaceCfgFlush().GetCount(); i++) + sWorkspaceCfgFlush()[i](); + VectorMap& cfg = sWorkspaceCfg(); + int version = 0; + s / version; + int count = cfg.GetCount(); + s / count; + for(i = 0; i < count; i++) { + String name; + if(s.IsStoring()) + name = cfg.GetKey(i); + s % name; + int q = cfg.Find(name); + if(q >= 0) + s % cfg[q]; + else + { + String dummy; + s % dummy; + } + } + s.Magic(); +} + +bool GuiPackageResolver(const String& error, const String& path, int line) +{ +prompt: + switch(Prompt(Ctrl::GetAppName(), CtrlImg::exclamation(), + error + "&while parsing package " + DeQtf(path), + "Edit \\& Retry", "Ignore", "Stop")) { + case 0: + if(!PromptYesNo("Ignoring will damage package. Everything past the " + "point of error will be lost.&Do you want to continue ?")) + goto prompt; + return false; + case 1: { + TopWindow win; + LineEdit edit; + edit.Set(LoadFile(path)); + edit.SetCursor(edit.GetPos(line)); + win.Title(path); + win.Add(edit.SizePos()); + win.Run(); + SaveFile(path, edit.Get()); + } + return true;; + case -1: + exit(1); + } + return false; +} + +void CleanModules() +{ + for(int i = 0; i < GetIdeModuleCount(); i++) + GetIdeModule(i).CleanUsc(); +} + +bool IdeModuleUsc(CParser& p) +{ + for(int i = 0; i < GetIdeModuleCount(); i++) + if(GetIdeModule(i).ParseUsc(p)) + return true; + return false; +} + +static void ReadMacro(CParser& p) +{ + IdeMacro macro; + if(p.IsString()) { + macro.menu = p.ReadString(); + if(p.Char(':')) + macro.submenu = p.ReadString(); + } + if(!p.IsChar('{')) + macro.hotkey = ParseKeyDesc(p); + EscLambda& l = macro.code.CreateLambda(); + const char *t = p.GetPtr(); + l.filename = p.GetFileName(); + l.line = p.GetLine(); + if(!p.Char('{')) + p.ThrowError("missing '{'"); + SkipBlock(p); + l.code = String(t, p.GetPtr()); + Array& mlist = UscMacros(); + if(macro.hotkey) { + int f = FindFieldIndex(mlist, &IdeMacro::hotkey, macro.hotkey); + if(f >= 0) { + PutConsole(NFormat("%s(%d): duplicate macro hotkey %s\n", l.filename, l.line, GetKeyDesc(macro.hotkey))); + const EscLambda& lambda = UscMacros()[f].code.GetLambda(); + PutConsole(NFormat("%s(%d): previously defined here\n", lambda.filename, lambda.line)); + } + } + if(!IsNull(macro.menu)) { + for(int i = 0; i < mlist.GetCount(); i++) + if(mlist[i].menu == macro.menu && mlist[i].submenu == macro.submenu) { + PutConsole(NFormat("%s(%d): duplicate macro menu item (%s:%s)\n", + l.filename, l.line, macro.menu, macro.submenu)); + const EscLambda& lambda = UscMacros()[i].code.GetLambda(); + PutConsole(NFormat("%s(%d): previously defined here\n", lambda.filename, lambda.line)); + break; + } + } + mlist.Add(macro); +} + +INITBLOCK { + Package::SetPackageResolver(GuiPackageResolver); + UscSetCleanModules(CleanModules); + SetIdeModuleUsc(IdeModuleUsc); + UscSetReadMacro(ReadMacro); +} + diff --git a/uppsrc/ide/ide.cpp b/uppsrc/ide/ide.cpp index dd33cb680..fb89175df 100644 --- a/uppsrc/ide/ide.cpp +++ b/uppsrc/ide/ide.cpp @@ -565,8 +565,11 @@ void Ide::CycleFiles() void Ide::Deactivate() { - if(deactivate_save) + if(deactivate_save) { + DeactivationSave(true); SaveFile(); + DeactivationSave(false); + } } bool Ide::Key(dword key, int count) {