From 3b364ddd42836d6475d863a47fcc189ffba4c4ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stephan=20A=C3=9Fmus?= Date: Mon, 4 Aug 2008 15:16:30 +0000 Subject: [PATCH] Intermediate commit, because I want to rename FolderIterator but it has changes. * Beginnings of node monitoring support. Currently disabled, but detects new, changed and removed files. Folders untested yet. There may also be a problem with the toplevel folders when a pose selection message is used. That's untested too as of yet. * Removed some superfluous whitespace. * Small refactoring in FolderIterator to access some stuff from the outside as well. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@26795 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/apps/text_search/FileIterator.h | 5 +- src/apps/text_search/FolderIterator.cpp | 53 +++++--- src/apps/text_search/FolderIterator.h | 12 +- src/apps/text_search/GrepWindow.cpp | 161 ++++++++++++++++++------ src/apps/text_search/GrepWindow.h | 8 +- src/apps/text_search/Jamfile | 2 + 6 files changed, 179 insertions(+), 62 deletions(-) diff --git a/src/apps/text_search/FileIterator.h b/src/apps/text_search/FileIterator.h index ebda8c48bf..c6cfa44304 100644 --- a/src/apps/text_search/FileIterator.h +++ b/src/apps/text_search/FileIterator.h @@ -36,7 +36,10 @@ public: // Returns the full path name of the next file. virtual bool GetNextName(char* buffer) = 0; - + + // Tells the Grepper whether the targets wants to know about negative hits. + virtual bool NotifyNegatives() const = 0; + protected: // Determines whether we can grep a file. bool _ExamineFile(BEntry& entry, char* buffer, diff --git a/src/apps/text_search/FolderIterator.cpp b/src/apps/text_search/FolderIterator.cpp index d29a0082b8..145fc7f366 100644 --- a/src/apps/text_search/FolderIterator.cpp +++ b/src/apps/text_search/FolderIterator.cpp @@ -109,21 +109,15 @@ FolderIterator::GetNextName(char* buffer) } -// #pragma mark - private - - bool -FolderIterator::_GetNextEntry(BEntry& entry) +FolderIterator::NotifyNegatives() const { - if (fDirectories.CountItems() == 1) - return _GetTopEntry(entry); - else - return _GetSubEntry(entry); + return false; } bool -FolderIterator::_GetTopEntry(BEntry& entry) +FolderIterator::GetTopEntry(BEntry& entry) { // If the user selected one or more files, we must look // at the "refs" inside the message that was passed into @@ -150,6 +144,37 @@ FolderIterator::_GetTopEntry(BEntry& entry) } +bool +FolderIterator::FollowSubdir(BEntry& entry) const +{ + if (!fRecurseDirs) + return false; + + if (fSkipDotDirs) { + char nameBuf[B_FILE_NAME_LENGTH]; + if (entry.GetName(nameBuf) == B_OK) { + if (*nameBuf == '.') + return false; + } + } + + return true; +} + + +// #pragma mark - private + + +bool +FolderIterator::_GetNextEntry(BEntry& entry) +{ + if (fDirectories.CountItems() == 1) + return GetTopEntry(entry); + else + return _GetSubEntry(entry); +} + + bool FolderIterator::_GetSubEntry(BEntry& entry) { @@ -173,17 +198,9 @@ FolderIterator::_GetSubEntry(BEntry& entry) void FolderIterator::_ExamineSubdir(BEntry& entry) { - if (!fRecurseDirs) + if (!FollowSubdir(entry)) return; - if (fSkipDotDirs) { - char nameBuf[B_FILE_NAME_LENGTH]; - if (entry.GetName(nameBuf) == B_OK) { - if (*nameBuf == '.') - return; - } - } - BDirectory* dir = new (nothrow) BDirectory(&entry); if (dir == NULL || dir->InitCheck() != B_OK || !fDirectories.AddItem(dir)) { // clean up diff --git a/src/apps/text_search/FolderIterator.h b/src/apps/text_search/FolderIterator.h index 82de89d767..d6fba5c88d 100644 --- a/src/apps/text_search/FolderIterator.h +++ b/src/apps/text_search/FolderIterator.h @@ -47,17 +47,19 @@ public: virtual ~FolderIterator(); virtual bool IsValid() const; - - // Returns the full path name of the next file. virtual bool GetNextName(char* buffer); + virtual bool NotifyNegatives() const; + + // Looks for the next entry in the top-level dir. + bool GetTopEntry(BEntry& entry); + + // Should this subfolder be followed? + bool FollowSubdir(BEntry& entry) const; private: // Looks for the next entry. bool _GetNextEntry(BEntry& entry); - // Looks for the next entry in the top-level dir. - bool _GetTopEntry(BEntry& entry); - // Looks for the next entry in a subdir. bool _GetSubEntry(BEntry& entry); diff --git a/src/apps/text_search/GrepWindow.cpp b/src/apps/text_search/GrepWindow.cpp index 1669e957e6..156d51cc70 100644 --- a/src/apps/text_search/GrepWindow.cpp +++ b/src/apps/text_search/GrepWindow.cpp @@ -34,6 +34,7 @@ #include #include #include +#include #include #include #include @@ -155,133 +156,137 @@ void GrepWindow::MessageReceived(BMessage *message) case B_ABOUT_REQUESTED: _OnAboutRequested(); break; - + case MSG_NEW_WINDOW: _OnNewWindow(); break; - + case B_SIMPLE_DATA: _OnFileDrop(message); break; - + case MSG_OPEN_PANEL: _OnOpenPanel(); break; - + case MSG_REFS_RECEIVED: _OnRefsReceived(message); break; - + case B_CANCEL: _OnOpenPanelCancel(); break; - + case MSG_RECURSE_LINKS: _OnRecurseLinks(); break; - + case MSG_RECURSE_DIRS: _OnRecurseDirs(); break; - + case MSG_SKIP_DOT_DIRS: _OnSkipDotDirs(); break; - + case MSG_CASE_SENSITIVE: _OnCaseSensitive(); break; - + case MSG_ESCAPE_TEXT: _OnEscapeText(); break; - + case MSG_TEXT_ONLY: _OnTextOnly(); break; - + case MSG_INVOKE_PE: _OnInvokePe(); break; - + case MSG_SEARCH_TEXT: _OnSearchText(); break; - + case MSG_SELECT_HISTORY: _OnHistoryItem(message); break; - + case MSG_START_CANCEL: _OnStartCancel(); break; - + case MSG_SEARCH_FINISHED: _OnSearchFinished(); break; - + + case B_PATH_MONITOR: + _OnNodeMonitorEvent(message); + break; + case MSG_REPORT_FILE_NAME: _OnReportFileName(message); break; - + case MSG_REPORT_RESULT: _OnReportResult(message); break; - + case MSG_REPORT_ERROR: _OnReportError(message); break; - + case MSG_SELECT_ALL: _OnSelectAll(message); break; - + case MSG_TRIM_SELECTION: _OnTrimSelection(); break; - + case MSG_COPY_TEXT: _OnCopyText(); break; - + case MSG_SELECT_IN_TRACKER: _OnSelectInTracker(); break; - + case MSG_MENU_SHOW_LINES: _OnMenuShowLines(); break; - + case MSG_CHECKBOX_SHOW_LINES: _OnCheckboxShowLines(); break; - + case MSG_OPEN_SELECTION: // fall through case MSG_INVOKE_ITEM: _OnInvokeItem(); break; - + case MSG_QUIT_NOW: _OnQuitNow(); break; - + case 'utf8': fModel->fEncoding = 0; break; - + case B_SJIS_CONVERSION: fModel->fEncoding = B_SJIS_CONVERSION; break; - + case B_EUC_CONVERSION: fModel->fEncoding = B_EUC_CONVERSION; break; - + case B_JIS_CONVERSION: fModel->fEncoding = B_JIS_CONVERSION; break; - + default: BWindow::MessageReceived(message); break; @@ -292,6 +297,7 @@ void GrepWindow::MessageReceived(BMessage *message) void GrepWindow::Quit() { + _StopNodeMonitoring(); _SavePrefs(); // TODO: stippi: Looks like this could be done @@ -663,12 +669,57 @@ GrepWindow::_SavePrefs() } +void +GrepWindow::_StartNodeMonitoring() +{ + BMessenger messenger(this); + uint32 fileFlags = B_WATCH_NAME | B_WATCH_STAT; + uint32 dirFlags = B_WATCH_DIRECTORY | B_WATCH_NAME; + + // watch the top level folder + BPath path(&fModel->fDirectory); + if (path.InitCheck() == B_OK) { +printf("start monitoring root folder: %s\n", path.Path()); + BPrivate::BPathMonitor::StartWatching(path.Path(), dirFlags, messenger); + } + + FolderIterator iterator(fModel); + + BEntry entry; + while (iterator.GetTopEntry(entry)) { + path.SetTo(&entry); + if (entry.IsDirectory()) { + // subfolder + if (iterator.FollowSubdir(entry)) { +printf("start monitoring folder: %s\n", path.Path()); + BPrivate::BPathMonitor::StartWatching(path.Path(), + dirFlags | B_WATCH_RECURSIVELY, messenger); + } + } else { + // regular file +printf("start monitoring file: %s\n", path.Path()); + BPrivate::BPathMonitor::StartWatching(path.Path(), fileFlags, + messenger); + } + } +} + + +void +GrepWindow::_StopNodeMonitoring() +{ + BPrivate::BPathMonitor::StopWatching(BMessenger(this)); +} + + // #pragma mark - events void GrepWindow::_OnStartCancel() { + _StopNodeMonitoring(); + if (fModel->fState == STATE_IDLE) { fModel->fState = STATE_SEARCH; @@ -714,8 +765,11 @@ GrepWindow::_OnStartCancel() // roll back in case of problems if (fGrepper == NULL) delete iterator; - delete fGrepper; - fGrepper = NULL; + else { + // Grepper owns iterator + delete fGrepper; + fGrepper = NULL; + } fModel->fState = STATE_CANCEL; // TODO: better notification to user fprintf(stderr, "Out of memory.\n"); @@ -732,6 +786,8 @@ GrepWindow::_OnSearchFinished() { fModel->fState = STATE_IDLE; +// _StartNodeMonitoring(); + delete fGrepper; fGrepper = NULL; @@ -740,11 +796,11 @@ GrepWindow::_OnSearchFinished() fPreferencesMenu->SetEnabled(true); fHistoryMenu->SetEnabled(true); fEncodingMenu->SetEnabled(true); - + fButton->SetLabel(_T("Search")); fButton->SetEnabled(true); fSearch->SetEnabled(true); - + fSearchText->SetEnabled(true); fSearchText->MakeFocus(true); fSearchText->SetText(fOldPattern.String()); @@ -753,6 +809,39 @@ GrepWindow::_OnSearchFinished() } +void +GrepWindow::_OnNodeMonitorEvent(BMessage* message) +{ + int32 opCode; + if (message->FindInt32("opcode", &opCode) != B_OK) + return; + + switch (opCode) { + case B_ENTRY_CREATED: +printf("B_ENTRY_CREATED\n"); + break; + case B_ENTRY_REMOVED: +printf("B_ENTRY_REMOVED\n"); + break; + case B_ENTRY_MOVED: +printf("B_ENTRY_MOVED\n"); + break; + case B_STAT_CHANGED: +printf("B_STAT_CHANGED\n"); + break; + case B_ATTR_CHANGED: +printf("B_ATTR_CHANGED\n"); + break; + + default: +printf("unkown opcode\n"); + break; + } + + message->PrintToStream(); +} + + void GrepWindow::_OnReportFileName(BMessage* message) { diff --git a/src/apps/text_search/GrepWindow.h b/src/apps/text_search/GrepWindow.h index 9381b508e7..ffebaf85f0 100644 --- a/src/apps/text_search/GrepWindow.h +++ b/src/apps/text_search/GrepWindow.h @@ -53,9 +53,13 @@ private: void _LoadPrefs(); void _SavePrefs(); - + + void _StartNodeMonitoring(); + void _StopNodeMonitoring(); + void _OnStartCancel(); void _OnSearchFinished(); + void _OnNodeMonitorEvent(BMessage* message); void _OnReportFileName(BMessage* message); void _OnReportResult(BMessage* message); void _OnReportError(BMessage* message); @@ -129,8 +133,8 @@ private: Grepper* fGrepper; BString fOldPattern; - Model* fModel; + bigtime_t fLastNodeMonitorEvent; BFilePanel* fFilePanel; }; diff --git a/src/apps/text_search/Jamfile b/src/apps/text_search/Jamfile index ab78d52797..865ef1db7a 100644 --- a/src/apps/text_search/Jamfile +++ b/src/apps/text_search/Jamfile @@ -2,6 +2,8 @@ SubDir HAIKU_TOP src apps text_search ; SetSubDirSupportedPlatformsBeOSCompatible ; +UsePrivateHeaders storage ; + Application TextSearch : FileIterator.cpp FolderIterator.cpp