X-Git-Url: http://ecere.com/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=ide%2Fsrc%2Fdialogs%2FFindInFilesDialog.ec;h=335dbbecd18c4440dfb3b1de31947c6b3b42cfb1;hb=582660009592c95f083df207f0a5964c033a76a9;hp=07bfd11a2a247eb71c73b52323eaa144d4f934cf;hpb=877038b7b4357f609cea602d9f7b3513de397971;p=sdk diff --git a/ide/src/dialogs/FindInFilesDialog.ec b/ide/src/dialogs/FindInFilesDialog.ec index 07bfd11..335dbbe 100644 --- a/ide/src/dialogs/FindInFilesDialog.ec +++ b/ide/src/dialogs/FindInFilesDialog.ec @@ -14,13 +14,12 @@ class FindInFilesDialog : Window tabCycle = true; size = { 440, 208 }; autoCreate = false; - stayOnTop = true; - + public: - property char * searchString { set { findContent.contents = value; } get { return findContent.contents; } }; + property const char * searchString { set { findContent.contents = value; } get { return findContent.contents; } }; property bool contentWholeWord { set { contentWholeWord.checked = value; } get { return contentWholeWord.checked; } }; property bool contentMatchCase { set { contentMatchCase.checked = value; } get { return contentMatchCase.checked; } }; - property char * currentDirectory + property const char * currentDirectory { set { @@ -143,7 +142,7 @@ public: DataRow row; sprintf(label, $"%s Project", project.name); row = findIn.AddString(label); - row.tag = (uint)project; + row.tag = (int64)(intptr)project; } } @@ -154,7 +153,7 @@ public: { for(row = inWorkspaceRow.next; row; row = row.next) { - if((Project)row.tag == project) + if((Project)(intptr)row.tag == project) { findIn.DeleteRow(row); break; @@ -166,7 +165,7 @@ public: void Show() { if(!created) - Create(); + Modal(); else Activate(); } @@ -180,9 +179,10 @@ private: DataRow inDirectoryRow; DataRow inWorkspaceRow; FindInFilesMode lastSelectionMode; - Project lastSelectionProject; - ProjectNode lastSelectionProjectNode; + String lastSelectionProject; + String lastSelectionProjectNode; bool replaceMode; + SelectorButton starDir; FindInFilesDialog() { @@ -195,6 +195,8 @@ private: ~FindInFilesDialog() { SearchStop(); + delete lastSelectionProject; + delete lastSelectionProjectNode; } LayoutPage layout @@ -250,19 +252,26 @@ private: { Project prj; lastSelectionMode = mode; - lastSelectionProject = prj = lastSelectionMode == project ? (Project)row.tag : null; + prj = lastSelectionMode == project ? (Project)(intptr)row.tag : null; + delete lastSelectionProject; if(prj) { DataRow r = null; ProjectNode node = prj.topNode; + char filePath[MAX_LOCATION]; + prj.topNode.GetFullFilePath(filePath, true); + lastSelectionProject = CopyString(filePath); findWherePrjNode.Clear(); ListProjectNodeFolders(node, null); - if(lastSelectionProjectNode && lastSelectionProjectNode.project == prj) - node = lastSelectionProjectNode; + if(lastSelectionProjectNode && !(node = prj.topNode.FindByFullPath(lastSelectionProjectNode, false))) + { + node = prj.topNode; + delete lastSelectionProjectNode; + } for(r = findWherePrjNode.firstRow; r; r = r.next) - if((ProjectNode)r.tag == node) + if((ProjectNode)(intptr)r.tag == node) break; if(r) findWherePrjNode.SelectRow(r); @@ -279,7 +288,7 @@ private: row = findWherePrjNode/*parentRow*/.AddRow(); else row = findWherePrjNode.AddRow(); - row.tag = (int)node; + row.tag = (int64)(intptr)node; row.SetData(null, node); if(node.files) { @@ -303,7 +312,16 @@ private: bool NotifySelect(DropBox control, DataRow row, Modifiers mods) { if(row) - lastSelectionProjectNode = (ProjectNode)row.tag; + { + ProjectNode node = (ProjectNode)(intptr)row.tag; + delete lastSelectionProjectNode; + if(node) + { + char filePath[MAX_LOCATION]; + node.GetFullFilePath(filePath, true); + lastSelectionProjectNode = CopyString(filePath); + } + } return true; } }; @@ -322,7 +340,7 @@ private: bool NotifySelect(DropBox control, DataRow row, Modifiers mods) { - fileFilter = row ? row.tag : 0; + fileFilter = (int)(row ? row.tag : 0); //ListFiles(); return true; } @@ -377,14 +395,14 @@ private: bool NotifyClicked(Button control, int x, int y, Modifiers mods) { - String findPath = findWhere.path; + const String findPath = findWhere.path; if(findIn.currentRow == inDirectoryRow && !findPath[0]) { findWhere.Activate(); MessageBox { type = ok, master = parent, text = text, contents = $"You must specify a search location." }.Modal(); } - else if(!FileExists(findPath)) + else if(findIn.currentRow == inDirectoryRow && !FileExists(findPath)) { findWhere.Activate(); MessageBox { type = ok, master = parent, @@ -417,7 +435,7 @@ private: return true; } }; - + SearchThread searchThread { findDialog = this }; FileDialog fileDialog { master = this, type = selectDir, text = $"Select Search Location..." }; @@ -430,8 +448,7 @@ private: bool OnPostCreate() { - bool disabled; - bool withWorkspace = (bool)ide.workspace; + bool withWorkspace = ide.workspace != null; DataRow row; if(!inDirectoryRow) inDirectoryRow = findIn.AddString($"Directory"); @@ -444,12 +461,20 @@ private: if(lastSelectionProject) { for(row = findIn.firstRow; row; row = row.next) - if((Project)row.tag == lastSelectionProject) - break; + { + char filePath[MAX_LOCATION]; + Project p = (Project)(intptr)row.tag; + if(p) + { + p.topNode.GetFullFilePath(filePath, true); + if(!fstrcmp(filePath, lastSelectionProject)) + break; + } + } if(row) findIn.SelectRow(row); else - lastSelectionProject = null; + delete lastSelectionProject; } if(!lastSelectionProject) { @@ -457,7 +482,7 @@ private: { Project prj = ide.workspace.projects.firstIterator.data; for(row = findIn.firstRow; row; row = row.next) - if((Project)row.tag == prj) + if((Project)(intptr)row.tag == prj) break; if(row) findIn.SelectRow(row); @@ -476,15 +501,13 @@ private: findWhere.disabled = disabled; subDirs.disabled = disabled;*/ - + findContent.Activate(); return true; } void SearchStart() { - char text[2048]; - searchThread.active = true; searchThread.project = null; searchThread.projectNode = null; @@ -493,7 +516,7 @@ private: if(findIn.currentRow == inDirectoryRow) { searchThread.mode = directory; - strcpy(searchThread.dir, findWhere.slashPath); + strcpy(searchThread.dir, findWhere.path); } else if(findIn.currentRow == inWorkspaceRow) { @@ -503,14 +526,14 @@ private: else { searchThread.mode = project; - searchThread.project = (Project)findIn.currentRow.tag; - searchThread.projectNode = (ProjectNode)(findWherePrjNode.currentRow ? findWherePrjNode.currentRow.tag : null); + searchThread.project = (Project)(intptr)findIn.currentRow.tag; + searchThread.projectNode = (ProjectNode)(findWherePrjNode.currentRow ? (void *)(intptr)findWherePrjNode.currentRow.tag : null); } //searchThread.nameMatchCase = nameMatchCase.checked; //searchThread.nameWholeWord = nameWholeWord.checked; searchThread.contentMatchCase = contentMatchCase.checked; searchThread.contentWholeWord = contentWholeWord.checked; - + searchThread.filter = filters[fileFilter]; strcpy(searchThread.nameCriteria, fileName.contents); @@ -520,11 +543,11 @@ private: searchThread.replaceMode = replaceMode; //cancel.text = "Stop"; - + ide.outputView.ShowClearSelectTab(find); Destroy(0); - + searchThread.Create(); } @@ -570,7 +593,7 @@ private: bool OnKeyHit(Key key, unichar ch) { - if(ch) + if(ch && !key.alt && !key.ctrl && !key.shift && (contentMatchCase.active || contentWholeWord.active)) { findContent.Activate(); return findContent.OnKeyHit(key, ch); @@ -579,6 +602,8 @@ private: } } +static define stackSize = 1024; + class SearchThread : Thread { public: @@ -623,12 +648,11 @@ private: unsigned int Main() { - int frame, treeTop = 0; - int globalFindCount = 0, filesSearchedCount = 0, filesMatchedCount = 0; + int frame; + int globalFindCount = 0, filesSearchedCount = 0, filesMatchedCount = 0, dirsMatchedCount = 0; //double lastTime = GetTime(); - SearchStackFrame stack[1024]; FindInFilesMode mode = this.mode; - + EditBox replaceEdit = null; abort = false; @@ -637,66 +661,83 @@ private: app.Lock(); { char substring[512]; + char containing[512]; + const char * and; + const char * filterName; + if(!strcmp(filter.name, "All files")) + filterName = "files"; + else + filterName = filter.name; if(nameCriteria[0]) sprintf(substring, $" with file name matching \"%s\"", nameCriteria); else substring[0] = '\0'; + if(contentCriteria && contentCriteria[0]) + sprintf(containing, $" containing \"%s\"", contentCriteria); + else + containing[0] = '\0'; + if(substring[0] && containing[0]) + and = " and"; + else + and = ""; if(mode == directory) { char * s; ide.outputView.findBox.Logf( - $"Searching \"%s\"%s for %s%s%s containing \"%s\"\n\n", + $"Searching \"%s\"%s for %s%s%s%s\n\n", (s = CopySystemPath(dir)), subDirs ? $" and its sub directories" : "", - filter.name, substring, substring[0] ? $" and" : "", contentCriteria); + filterName, substring, and, containing); delete s; } else if(mode == workspace) ide.outputView.findBox.Logf( - $"Searching workspace files for files%s%s containing \"%s\"\n\n", - substring, substring[0] ? $" and" : "", contentCriteria); + $"Searching workspace files for %s%s%s%s\n\n", + filterName, substring, and, containing); else if(mode == project) ide.outputView.findBox.Logf( - $"Searching project %s files for files%s%s containing \"%s\"\n\n", - project.name, substring, substring[0] ? $" and" : "", contentCriteria); + $"Searching project %s files for %s%s%s%s\n\n", + project.name, filterName, substring, and, containing); } app.Unlock(); - - if(replaceMode && contentReplace[0]) + + if(replaceMode) { replaceEdit = EditBox { - multiLine = true,textHorzScroll = true,textVertScroll = true, - text = $"Replacing Editbox", size = Size { 640,480 },maxLineSize = 65536 + multiLine = true,textHorzScroll = true,textVertScroll = true, + text = $"Replacing Editbox", size = Size { 640,480 }/*,maxLineSize = 65536*/ }; } if(mode == directory) { + SearchStackFrame * stack = new0 SearchStackFrame[stackSize]; + strcpy(stack[0].path, dir); - stack[0].fileList = FileListing { dir, extensions = filter.extensions }; // there should be a sorted = true/false + stack[0].fileList = FileListing { dir, extensions = filter.extensions }; // there should be a sorted = true/false - for(frame = 0; frame >= 0 && !abort; ) + for(frame = 0; frame >= 0 && frame < stackSize && !abort; ) { if(stack[frame].fileList.Find()) { + bool match = true; + if(nameCriteria[0]) + { + char name[MAX_LOCATION]; + GetLastDirectory(stack[frame].fileList.path, name); + if(SearchString(name, 0, nameCriteria, false, false) == null) + match = false; + } if(!stack[frame].fileList.stats.attribs.isDirectory) { bool relative = false; - bool match = true; char fileRelative[MAX_LOCATION]; if(filter.ValidateFileName(stack[frame].fileList.name)) { MakePathRelative(stack[frame].fileList.path, dir, fileRelative); relative = true; - + filesSearchedCount++; - if(nameCriteria[0]) - { - char name[MAX_LOCATION]; - GetLastDirectory(stack[frame].fileList.path, name); - if(!(bool)SearchString(name, 0, nameCriteria, false, false)) - match = false; - } if(match && contentCriteria[0]) { int ret; @@ -706,7 +747,7 @@ private: $"Searching %s for %s", relative ? fileRelative : stack[frame].fileList.path, contentCriteria); app.Unlock(); - if(replaceMode && contentReplace[0]) + if(replaceMode) ret = SearchFileContentAndReplace(stack[frame].fileList.path, relative, fileRelative, replaceEdit); else ret = SearchFileContent(stack[frame].fileList.path, relative, fileRelative); @@ -721,7 +762,7 @@ private: filesMatchedCount++; app.Lock(); ide.outputView.findBox.Logf( - $"%s matches the file name criteria\n", + "%s\n", relative ? fileRelative : stack[frame].fileList.path); app.Unlock(); } @@ -734,12 +775,19 @@ private: MakePathRelative(stack[frame].fileList.path, dir, fileRelative); relative = true; app.Lock(); + if(match && nameCriteria[0]) + { + dirsMatchedCount++; + ide.outputView.findBox.Logf( + "%s\n", + relative ? fileRelative : stack[frame].fileList.path); + } ide.outputView.findBox.Tellf( $"Searching %s", relative ? fileRelative : stack[frame].fileList.path); app.Unlock(); } - if(subDirs && stack[frame].fileList.stats.attribs.isDirectory) + if(subDirs && stack[frame].fileList.stats.attribs.isDirectory && strcmp(stack[frame].fileList.name, ".git")) { int lastFrame = frame; /*double thisTime = GetTime(); @@ -750,9 +798,21 @@ private: lastTime = thisTime; } app.Unlock();*/ - frame++; - strcpy(stack[frame].path, stack[lastFrame].fileList.path); - stack[frame].fileList = FileListing { stack[frame].path, extensions = stack[lastFrame].fileList.extensions }; + if(frame < stackSize-1) + { + frame++; + strcpy(stack[frame].path, stack[lastFrame].fileList.path); + stack[frame].fileList = FileListing { stack[frame].path, extensions = stack[lastFrame].fileList.extensions }; + } + else + { + abort = true; + for( ; frame >= 0 ; frame--) + stack[frame].fileList.Stop(); + app.Lock(); + ide.outputView.findBox.Logf($"Error: aborting search!\n"); + app.Unlock(); + } } } else @@ -762,15 +822,15 @@ private: } if(abort) for( ; frame >= 0 ; frame--) - stack[frame].fileList.Stop(); + if(frame < stackSize) + stack[frame].fileList.Stop(); + delete stack; } else if(mode == workspace || mode == project) { - int len; - char path[MAX_LOCATION]; - bool firtIteration = true; + bool firstIteration = true; Project prj = project; - ProjectNode stack[1024]; + ProjectNode * stack = new0 ProjectNode[stackSize]; Iterator it { ide.workspace.projects }; while(true) @@ -782,28 +842,30 @@ private: } stack[1] = projectNode ? projectNode : prj.topNode; - for(frame = 1; frame && !abort;) + for(frame = 1; frame && !abort && frame < stackSize-1;) { switch(stack[frame].type) { case project: - if((subDirs || firtIteration) && stack[frame].files && stack[frame].files.count) + if((subDirs || firstIteration) && stack[frame].files && stack[frame].files.count) { int lastFrame = frame; frame++; stack[frame] = stack[lastFrame].files.first; - firtIteration = false; + firstIteration = false; } break; case file: - { + { bool relative = true; char fileRelative[MAX_LOCATION]; char filePath[MAX_LOCATION]; - strcpy(filePath, prj.topNode.path); + filePath[0] = '\0'; + PathCat(filePath, prj.topNode.path); PathCat(filePath, stack[frame].path); PathCat(filePath, stack[frame].name); - strcpy(fileRelative, stack[frame].path); + fileRelative[0] = '\0'; + PathCat(fileRelative, stack[frame].path); PathCat(fileRelative, stack[frame].name); if(relative && mode == workspace && prj != ide.project) { @@ -814,7 +876,7 @@ private: if(filter.ValidateFileName(stack[frame].name)) { filesSearchedCount++; - if(!nameCriteria[0] || (bool)SearchString(stack[frame].name, 0, nameCriteria, false, false)) + if(!nameCriteria[0] || SearchString(stack[frame].name, 0, nameCriteria, false, false) != null) { if(contentCriteria[0]) { @@ -826,7 +888,7 @@ private: contentCriteria); app.Unlock(); - if(replaceMode && contentReplace[0]) + if(replaceMode) ret = SearchFileContentAndReplace(filePath, relative, fileRelative, replaceEdit); else ret = SearchFileContent(filePath, relative, fileRelative); @@ -842,7 +904,6 @@ private: app.Lock(); ide.outputView.findBox.Logf( "%s\n", relative ? fileRelative : filePath); - /*" matches the file name criteria"*/ app.Unlock(); } } @@ -851,16 +912,40 @@ private: break; } case folder: - if((subDirs || firtIteration) && stack[frame].files && stack[frame].files.count) + { + bool relative = true; + char fileRelative[MAX_LOCATION]; + char filePath[MAX_LOCATION]; + filePath[0] = '\0'; + PathCat(filePath, prj.topNode.path); + PathCat(filePath, stack[frame].path); + fileRelative[0] = '\0'; + PathCat(fileRelative, stack[frame].path); + if(relative && mode == workspace && prj != ide.project) + { + char special[MAX_LOCATION]; + sprintf(special, "(%s)%s", prj.name, fileRelative); + strcpy(fileRelative, special); + } + if(nameCriteria[0] && SearchString(stack[frame].name, 0, nameCriteria, false, false) != null) + { + dirsMatchedCount++; + app.Lock(); + ide.outputView.findBox.Logf( + "%s\n", relative ? fileRelative : filePath); + app.Unlock(); + } + if((subDirs || firstIteration) && stack[frame].files && stack[frame].files.count) { int lastFrame = frame; frame++; stack[frame] = stack[lastFrame].files.first; - firtIteration = false; + firstIteration = false; } else stack[frame] = stack[frame].next; break; + } case resources: stack[frame] = stack[frame].next; break; @@ -878,9 +963,11 @@ private: } if(abort) { - for( ; frame ; frame--) - stack[frame] = null; + for( ; frame >= 0; frame--) + if(frame < stackSize) + stack[frame] = null; } + delete stack; } delete replaceEdit; @@ -889,6 +976,8 @@ private: app.Lock(); if(filesSearchedCount) { + if(!contentCriteria[0] && (filesMatchedCount || dirsMatchedCount)) + ide.outputView.findBox.Logf("\n"); if(globalFindCount) ide.outputView.findBox.Logf( $"%s search %s a total of %d match%s in %d out of the %d file%s searched\n", @@ -912,7 +1001,7 @@ private: return 0; } - int SearchFileContent(char *filePath, bool relative, char *fileRelative) + int SearchFileContent(const char *filePath, bool relative, const char *fileRelative) { int findCount = -1; File f = FileOpen(filePath, read); @@ -937,8 +1026,8 @@ private: } if(inLineFindCount && !abortNow) { - char s1[6] = " "; - char s2[4] = " "; + char s1[7] = " "; + char s2[5] = " "; int len = strlen(line); s1[6 - HowManyDigits(lineNum)] = '\0'; s2[4 - HowManyDigits(col)] = '\0'; @@ -962,6 +1051,14 @@ private: f.Seek(-strlen(contentCriteria), current);*/ } delete f; + if(findCount) + { + app.Lock(); + ide.outputView.findBox.Logf( + $"Found %d match%s in \"%s\"%s\n\n", findCount, (findCount > 1) ? "es" : "", + relative ? fileRelative : filePath, abortNow ? $" before search was aborted" : ""); + app.Unlock(); + } } else { @@ -969,18 +1066,10 @@ private: ide.outputView.findBox.Logf($"Unable to open file %s\n\n", filePath); app.Unlock(); } - if(findCount) - { - app.Lock(); - ide.outputView.findBox.Logf( - $"Found %d match%s in \"%s\"%s\n\n", findCount, (findCount > 1) ? "es" : "", - relative ? fileRelative : filePath, abortNow ? $" before search was aborted" : ""); - app.Unlock(); - } return findCount; } - int SearchFileContentAndReplace(char *filePath, bool relative, char *fileRelative, EditBox edit) + int SearchFileContentAndReplace(const char *filePath, bool relative, const char *fileRelative, EditBox edit) { int replaceCount = -1; File f = FileOpen(filePath, read); @@ -991,8 +1080,6 @@ private: while(f.GetLine(line, 65536/* should there be a - 1 here? */) && !abortNow) { int col = 0; - char * find = null; - int inLineFindCount = 0; if(SearchString(line, 0, contentCriteria, contentMatchCase, contentWholeWord) && !abortNow) { int lastLineNum = 0; @@ -1045,9 +1132,17 @@ private: // todo /*else f.Seek(-strlen(contentCriteria), current);*/ - + } delete f; + if(replaceCount) + { + app.Lock(); + ide.outputView.findBox.Logf( + $"Replaced %d match%s in \"%s\"%s\n\n", replaceCount, (replaceCount > 1) ? $"es" : "", + relative ? fileRelative : filePath, abortNow ? $" before search was aborted" : ""); + app.Unlock(); + } } else { @@ -1055,14 +1150,6 @@ private: ide.outputView.findBox.Logf($"Unable to open file %s\n\n", filePath); app.Unlock(); } - if(replaceCount) - { - app.Lock(); - ide.outputView.findBox.Logf( - $"Replaced %d match%s in \"%s\"%s\n\n", replaceCount, (replaceCount > 1) ? $"es" : "", - relative ? fileRelative : filePath, abortNow ? $" before search was aborted" : ""); - app.Unlock(); - } return replaceCount; } } @@ -1073,4 +1160,3 @@ static struct SearchStackFrame char path[MAX_LOCATION]; FileListing fileList; }; -