From e99c6b480cdc824035e5d875278b13d01533a175 Mon Sep 17 00:00:00 2001 From: cxl Date: Sun, 16 Apr 2017 17:52:22 +0000 Subject: [PATCH] TextDiffCtrl: Directory comparison now can show/filter new/modified/removed files git-svn-id: svn://ultimatepp.org/upp/trunk@11011 f0d560ea-af0d-0410-9eb7-867de7ffcac7 --- uppsrc/TextDiffCtrl.h | 263 +++++++++++++++++++++++++++++ uppsrc/TextDiffCtrl/DirDiff.cpp | 52 +++++- uppsrc/TextDiffCtrl/TextDiffCtrl.h | 5 + uppsrc/ide/Core/Logger.cpp | 25 +-- uppsrc/ide/Core/Logger.h | 5 +- 5 files changed, 320 insertions(+), 30 deletions(-) create mode 100644 uppsrc/TextDiffCtrl.h diff --git a/uppsrc/TextDiffCtrl.h b/uppsrc/TextDiffCtrl.h new file mode 100644 index 000000000..77da6f228 --- /dev/null +++ b/uppsrc/TextDiffCtrl.h @@ -0,0 +1,263 @@ +#ifndef _TextDiffCtrl_TextDiffCtrl_h +#define _TextDiffCtrl_TextDiffCtrl_h + +#include + +namespace Upp { + +#define IMAGECLASS DiffImg +#define IMAGEFILE +#include + +class TextSection +{ +public: + TextSection(int start1, int count1, int start2, int count2, bool same) + : start1(start1), count1(count1), start2(start2), count2(count2), same(same) {} + +public: + int start1; + int count1; + int start2; + int count2 : 31; + unsigned same : 1; +}; + +Array CompareLineMaps(const Vector& l1, const Vector& l2); +Vector GetLineMap(Stream& stream); +Vector GetFileLineMap(const String& path); +Vector GetStringLineMap(const String &s); + +class TextCompareCtrl : public Ctrl { +public: + virtual void Paint(Draw& draw); + virtual void Layout(); + virtual void MouseWheel(Point pt, int zdelta, dword keyflags); + virtual void MouseMove(Point pt, dword keyflags); + virtual void LeftDown(Point pt, dword keyflags); + virtual void LeftDouble(Point pt, dword keyflags); + virtual void LeftUp(Point pt, dword keyflags); + virtual void RightDown(Point p, dword keyflags); + virtual bool Key(dword key, int repcnt); + +private: + void SelfScroll(); + void PairScroll(TextCompareCtrl *ctrl); + void UpdateWidth(); + WString ExpandTabs(const wchar *line) const; + int MeasureLength(const wchar *line) const; + bool GetSelection(int& l, int& h); + void DoSelection(int y, bool shift); + void Copy(); + int GetLineNo(int y, int& yy); + +private: + struct Line { + Line() : number(Null), level(0) {} + int number; + bool diff; + String text; + int level; + String text_diff; + int number_diff; + bool left; + }; + Array lines; + int maxwidth; + ScrollBars scroll; + Font font; + Font number_font; + Color number_bg; + Color gutter_fg; + Color gutter_bg; + Size letter; + int tabsize; + int number_width; + int number_yshift; + int gutter_width; + int cursor; + int anchor; + bool gutter_capture; + bool show_line_number; + bool show_white_space; + bool show_diff_highlight; + bool change_paper_color; + + typedef TextCompareCtrl CLASSNAME; + +public: + Event<> WhenScroll; + Callback2 WhenLeftDouble; + Event&, const WString&> WhenHighlight; + + void SetCount(int c); + void AddCount(int c); + int GetCount() const { return lines.GetCount(); } + + void SetFont(Font f, Font nf); + void SetFont(Font f); + Font GetFont() const { return font; } + Font GetNumberFont() const { return number_font; } + + void NumberBgColor(Color bg) { number_bg = bg; Refresh(); } + Color GetNumberBgColor() const { return number_bg; } + + void AutoHideSb(bool ssb=true){ scroll.AutoHide(ssb); } + void ShowSb(bool ssb) { scroll.ShowY(ssb); } + void HideSb() { ShowSb(false); } + + void Gutter(int size) { gutter_width = size; Refresh(); } + void NoGutter() { gutter_width = 0; Refresh(); } + + void TabSize(int t); + int GetTabSize() const { return tabsize; } + + void Set(int line, String text, bool diff, int number, int level, String text_diff, int number_diff, bool left); + String GetText(int line) const { return lines[line].text; } + bool GetDiff(int line) const { return lines[line].diff; } + int GetNumber(int line) const { return lines[line].number; } + int GetNumberDiff(int line) const { return lines[line].number_diff; } + + Point GetPos() const; + void SetPos(Point pos); + + int GetSb() const { return scroll.Get().y; } + void SetSb(int y) { scroll.Set(0, y); } + + void ClearSelection() { cursor = Null; Refresh(); } + void SetSelection(int l, int h) { cursor = l; anchor = h; } + + void ShowLineNumber(bool sln) { show_line_number = sln; Refresh(); } + void HideLineNumber() { ShowLineNumber(false); } + + void ShowWhiteSpace(bool sws) { show_white_space = sws; Refresh(); } + void HideWhiteSpace() { ShowWhiteSpace(false); } + + void DiffHighlight(bool dh) { show_diff_highlight = dh; Refresh(); } + void NoDiffHighlight() { DiffHighlight(false); } + + void ChangePaperColor(bool cpc) { change_paper_color = cpc; Refresh(); } + void NoChangePaperColor() { ChangePaperColor(false); } + + Event<> ScrollWhen(TextCompareCtrl& pair) { return THISBACK1(PairScroll, &pair); } + + TextCompareCtrl(); +}; + +struct TextDiffCtrl : public Splitter { + TextCompareCtrl left; + TextCompareCtrl right; + + typedef TextDiffCtrl CLASSNAME; + + void Set(Stream& l, Stream& r); + void Set(const String& l, const String& r); + void InsertFrameLeft(CtrlFrame& f) { left.InsertFrame(0, f); } + void InsertFrameRight(CtrlFrame& f) { right.InsertFrame(0, f); } + void AddFrameLeft(CtrlFrame& f) { left.AddFrame(f); } + void AddFrameRight(CtrlFrame& f) { right.AddFrame(f); } + void SetFont(Font f, Font nf) { left.SetFont(f, nf); right.SetFont(f, nf); } + void SetFont(Font f) { left.SetFont(f); right.SetFont(f); } + + void GetLeftLine(int number, int line); + void GetRightLine(int number, int line); + + Callback1 WhenLeftLine; + Callback1 WhenRightLine; + + TextDiffCtrl(); +}; + +struct DiffDlg : public TopWindow { + TextDiffCtrl diff; + FrameTop p; + DataPusher l; + Button write; + String editfile; + String extfile; + + typedef DiffDlg CLASSNAME; + + void Write(); + void Execute(const String& f); + + static Event&, const WString&> WhenHighlight; + + DiffDlg(); +}; + +FileSel& DiffFs(); + +struct FileDiff : DiffDlg { + FrameTop r; + + virtual void Open(); + void Execute(const String& f); + + typedef FileDiff CLASSNAME; + + String GetExtPath() const { return ~r; } + + FileDiff(FileSel& fs); + + FileSel& fs; +}; + +struct PatchDiff : FileDiff { + PatchDiff(FileSel& fs) : FileDiff(fs) {} + + virtual void Open(); + + void Copy(FileIn& in, FileIn& oin, int& l, int ln, int n); + void LoadDiff(const char *fn); +}; + +class DirDiffDlg : public TopWindow { + Splitter files_diff; + ParentCtrl files_pane; + FileList files; + + SelectDirButton seldir1; + WithDropChoice dir1; + SelectDirButton seldir2; + WithDropChoice dir2; + Option hidden; + Button compare; + Label info; + + Option removed, added, modified; + + FrameTop left, right; + EditString lfile, rfile; + Button copyleft, copyright; + + Array> list; + + void GatherFilesDeep(Index& files, const String& base, const String& path); + void Compare(); + void ShowResult(); + void ClearFiles(); + void File(); + void Copy(bool left); + +public: + TextDiffCtrl diff; + + typedef DirDiffDlg CLASSNAME; + + void SetFont(Font fnt) { diff.SetFont(fnt); } + void Dir1(const String& dir) { dir1 <<= dir; } + void Dir2(const String& dir) { dir2 <<= dir; } + void Dir1AddList(const String& dir) { dir1.AddList(dir); } + void Dir2AddList(const String& dir) { dir2.AddList(dir); } + + String GetLeftFile() const { return ~lfile; } + String GetRightFile() const { return ~rfile; } + + DirDiffDlg(); +}; + + +}; + +#endif diff --git a/uppsrc/TextDiffCtrl/DirDiff.cpp b/uppsrc/TextDiffCtrl/DirDiff.cpp index 19579be2a..35b714a1d 100644 --- a/uppsrc/TextDiffCtrl/DirDiff.cpp +++ b/uppsrc/TextDiffCtrl/DirDiff.cpp @@ -18,7 +18,7 @@ void DirDiffDlg::GatherFilesDeep(Index& files, const String& base, const } } -bool FileEqual(const String& f1, const String& f2) +bool FileEqual(const String& f1, const String& f2, int& n) { FileIn in1(f1); FileIn in2(f2); @@ -31,6 +31,11 @@ bool FileEqual(const String& f1, const String& f2) } return true; } + else + { + n = (in1 ? 1 : 2); + } + return false; } @@ -48,15 +53,32 @@ void DirDiffDlg::Compare() Sort(f); Progress pi(t_("Comparing..")); pi.SetTotal(f.GetCount()); + + list.Clear(); for(int i = 0; i < f.GetCount(); i++) { if(pi.StepCanceled()) break; String p1 = AppendFileName(~dir1, f[i]); String p2 = AppendFileName(~dir2, f[i]); - if(!FileEqual(p1, p2)) - files.Add(f[i], NativePathIcon(FileExists(p1) ? p1 : p2)); - info = AsString(files.GetCount()) + " files"; + int n = 0; + if(!FileEqual(p1, p2, n)) + list.Add(MakeTuple(f[i], p1, p2, n)); } + + ShowResult(); +} + +void DirDiffDlg::ShowResult() +{ + static Color cs[] = {SColorText(), Red, Green()}; + files.Clear(); + for(int i = 0; i < list.GetCount(); i++) + { + int n = list[i].d; + if( (n==0 && modified) || (n==1 && removed) || (n==2 && added)) + files.Add(list[i].a, NativePathIcon(FileExists(list[i].b) ? list[i].b : list[i].c), StdFont(),cs[list[i].d]); + } + info = AsString(files.GetCount()) + " files"; } void DirDiffDlg::ClearFiles() @@ -101,15 +123,29 @@ DirDiffDlg::DirDiffDlg() int bcx = GetTextSize(t_("Compare"), StdFont()).cx * 12 / 10 + 2 * div; hidden.SetLabel(t_("Hidden")); + + added.SetLabel(t_("New")); + modified.SetLabel(t_("Modified")); + removed.SetLabel(t_("Removed")); + compare.SetLabel(t_("Compare")); int bcy = compare.GetStdSize().cy; files_pane.Add(dir1.TopPos(0, cy).HSizePos()); files_pane.Add(dir2.TopPos(cy + div, cy).HSizePos()); files_pane.Add(hidden.TopPos(2 * cy + 2 * div, bcy).LeftPos(0, bcx)); - files_pane.Add(info.TopPos(2 * cy + 2 * div, bcy).HSizePos(bcx + 2 * div, bcx + div)); + + files_pane.Add( added.TopPos(3 * cy + 3 * div, bcy).LeftPosZ(2, 60)); + files_pane.Add(modified.TopPos(3 * cy + 3 * div, bcy).LeftPosZ(52, 70)); + files_pane.Add( removed.TopPos(3 * cy + 3 * div, bcy).LeftPosZ(132, 80)); + + removed = 1; + added = 1; + modified = 1; + + files_pane.Add(info.SetAlign(ALIGN_RIGHT).TopPos(3 * cy + 3 * div, bcy).RightPos(1, 70)); files_pane.Add(compare.TopPos(2 * cy + 2 * div, bcy).RightPos(0, bcx)); - files_pane.Add(files.VSizePos(2 * cy + bcy + 3 * div, 0).HSizePos()); + files_pane.Add(files.VSizePos(3 * cy + bcy + 4 * div, 0).HSizePos()); Add(files_diff.SizePos()); files_diff.Set(files_pane, diff); @@ -124,6 +160,10 @@ DirDiffDlg::DirDiffDlg() dir1 <<= THISBACK(ClearFiles); dir2 <<= THISBACK(ClearFiles); + modified << [=]() {ShowResult();}; + removed << [=]() {ShowResult();}; + added << [=]() {ShowResult();}; + files.WhenSel = THISBACK(File); diff.InsertFrameLeft(left); diff --git a/uppsrc/TextDiffCtrl/TextDiffCtrl.h b/uppsrc/TextDiffCtrl/TextDiffCtrl.h index 834211a67..5663c0f6e 100644 --- a/uppsrc/TextDiffCtrl/TextDiffCtrl.h +++ b/uppsrc/TextDiffCtrl/TextDiffCtrl.h @@ -224,13 +224,18 @@ class DirDiffDlg : public TopWindow { Option hidden; Button compare; Label info; + + Option removed, added, modified; FrameTop left, right; EditString lfile, rfile; Button copyleft, copyright; + + Array> list; void GatherFilesDeep(Index& files, const String& base, const String& path); void Compare(); + void ShowResult(); void ClearFiles(); void File(); void Copy(bool left); diff --git a/uppsrc/ide/Core/Logger.cpp b/uppsrc/ide/Core/Logger.cpp index 9854d9d50..ed0210324 100644 --- a/uppsrc/ide/Core/Logger.cpp +++ b/uppsrc/ide/Core/Logger.cpp @@ -34,26 +34,8 @@ void Logger::Log() String Logger::GetCurrentTime() { - // TODO: Add support for ms somehow... - - time_t currentTime = time(nullptr); - tm* timeInfo = localtime(¤tTime); - - StringStream ss; - ss << AlignTime(timeInfo->tm_hour) << ":" - << AlignTime(timeInfo->tm_min) << ":" - << AlignTime(timeInfo->tm_sec); - - return ss.GetResult(); -} - -String Logger::AlignTime(int timeValue, int level) -{ - String alignedTime = IntStr(timeValue); - for (int i = 0; i < level - alignedTime.GetLength(); i++) { - alignedTime = "0" + alignedTime; - } - return alignedTime; + Time tm = GetSysTime(); + return Format("%02d:%02d:%02d", (int)tm.hour, (int)tm.minute, (int)tm.second); } Stream& Upp::operator<<(Stream& s, Logger::LoggingLevel level) @@ -66,9 +48,10 @@ Stream& Upp::operator<<(Stream& s, Logger::LoggingLevel level) return s << "INFO "; case (Logger::LoggingLevel::WARN): return s << "WARN "; - case (Logger::LoggingLevel::ERROR): + case (Logger::LoggingLevel::ERROR_LEVEL): return s << "ERROR"; case (Logger::LoggingLevel::NONE): return s << "NONE "; } + return s; } diff --git a/uppsrc/ide/Core/Logger.h b/uppsrc/ide/Core/Logger.h index 8859ec386..39f8b8726 100644 --- a/uppsrc/ide/Core/Logger.h +++ b/uppsrc/ide/Core/Logger.h @@ -15,7 +15,7 @@ public: DEBUG, INFO, WARN, - ERROR, + ERROR_LEVEL, NONE }; @@ -32,7 +32,6 @@ private: void Log(); String GetCurrentTime(); - String AlignTime(int timeValue, int level = 2); private: StringStream outputStream; @@ -54,7 +53,7 @@ public: \ LOGGER(Logd, Logger::LoggingLevel::DEBUG) LOGGER(Logi, Logger::LoggingLevel::INFO) LOGGER(Logw, Logger::LoggingLevel::WARN) -LOGGER(Loge, Logger::LoggingLevel::ERROR) +LOGGER(Loge, Logger::LoggingLevel::ERROR_LEVEL) #undef LOGGER