From 9cdba41addb4087592fe682fdd4b6900ab9b29e9 Mon Sep 17 00:00:00 2001 From: John Scipione Date: Tue, 3 Mar 2015 18:40:55 -0500 Subject: [PATCH] Tracker and Open Target Folder: Select result Implement the todo in Open Target Folder to select the result by sending Tracker a message with the refs to select. Add a new kSelect message constant to tracker_private.h to hook into. Tracker reads in the message and finds the window that the refs are located in, activates it, then selects the corresponding poses scrolling the pose view if necessary. Bump version of Open Target Folder to 1.0.2 --- headers/private/tracker/tracker_private.h | 3 ++ .../opentargetfolder/opentargetfolder.cpp | 24 ++++++++- .../opentargetfolder/opentargetfolder.rdef | 2 +- src/kits/tracker/Tracker.cpp | 51 +++++++++++++++++++ src/kits/tracker/Tracker.h | 1 + 5 files changed, 78 insertions(+), 3 deletions(-) diff --git a/headers/private/tracker/tracker_private.h b/headers/private/tracker/tracker_private.h index ec5500970b..557caa8111 100644 --- a/headers/private/tracker/tracker_private.h +++ b/headers/private/tracker/tracker_private.h @@ -68,6 +68,9 @@ const uint32 kFSClipboardChanges = 'TCch'; const uint32 kMoveToTrash = 'Ttrs'; // Used by ShowImage to delete images +const uint32 kSelect = 'Tsel'; + // Used by Open Target Folder tracker add-on to select files + } // namespace BPrivate diff --git a/src/add-ons/tracker/opentargetfolder/opentargetfolder.cpp b/src/add-ons/tracker/opentargetfolder/opentargetfolder.cpp index 73e5ef05ec..47109f4701 100644 --- a/src/add-ons/tracker/opentargetfolder/opentargetfolder.cpp +++ b/src/add-ons/tracker/opentargetfolder/opentargetfolder.cpp @@ -24,10 +24,19 @@ #include +using namespace BPrivate; + extern "C" void process_refs(entry_ref directoryRef, BMessage* message, void*) { entry_ref ref; + uint32 selectCount = 0; + + // create Tracker messenger... + BMessenger messenger(kTrackerSignature); + + // create select message... + BMessage selectMessage(kSelect); for (int32 i = 0; message->FindRef("refs", i, &ref) == B_OK; i++) { BSymLink link(&ref); @@ -76,11 +85,22 @@ process_refs(entry_ref directoryRef, BMessage* message, void*) trackerMessage.AddRef("refs", &parent); // ...and send it - BMessenger messenger(kTrackerSignature); messenger.SendMessage(&trackerMessage); - // TODO: select entry via scripting? + entry_ref target; + if (targetEntry.GetRef(&target) != B_OK) { + // don't alert, selection is not critical + break; + } + + // add ref to selection message + selectMessage.AddRef("refs", &target); + selectCount++; } + + // ...and send it + if (selectCount > 0) + messenger.SendMessage(&selectMessage); } diff --git a/src/add-ons/tracker/opentargetfolder/opentargetfolder.rdef b/src/add-ons/tracker/opentargetfolder/opentargetfolder.rdef index 3bf227b785..6f31c2ec25 100644 --- a/src/add-ons/tracker/opentargetfolder/opentargetfolder.rdef +++ b/src/add-ons/tracker/opentargetfolder/opentargetfolder.rdef @@ -5,7 +5,7 @@ resource app_flags B_SINGLE_LAUNCH; resource app_version { major = 1, middle = 0, - minor = 1, + minor = 2, variety = B_APPV_FINAL, internal = 1, diff --git a/src/kits/tracker/Tracker.cpp b/src/kits/tracker/Tracker.cpp index 234301e99d..1fae98a835 100644 --- a/src/kits/tracker/Tracker.cpp +++ b/src/kits/tracker/Tracker.cpp @@ -82,6 +82,7 @@ All rights reserved. #include "Thread.h" #include "TrackerSettings.h" #include "TrackerSettingsWindow.h" +#include "TrackerString.h" #include "TrashWatcher.h" #include "VirtualDirectoryWindow.h" @@ -485,6 +486,10 @@ TTracker::MessageReceived(BMessage* message) MoveRefsToTrash(message); break; + case kSelect: + SelectRefs(message); + break; + case kCloseWindowAndChildren: { const node_ref* itemNode; @@ -699,6 +704,52 @@ TTracker::MoveRefsToTrash(const BMessage* message) } +void +TTracker::SelectRefs(const BMessage* message) +{ + uint32 type = 0; + int32 count = 0; + message->GetInfo("refs", &type, &count); + + for (int32 index = 0; index < count; index++) { + entry_ref ref; + message->FindRef("refs", index, &ref); + BEntry entry(&ref, true); + if (entry.InitCheck() != B_OK || !entry.Exists()) + continue; + + AutoLock lock(&fWindowList); + BContainerWindow* window = FindParentContainerWindow(&ref); + if (window == NULL) + continue; + + char name[B_FILE_NAME_LENGTH]; + if (entry.GetName(name) != B_OK) + continue; + + BString expression; + expression << "^"; + expression << name; + expression << "$"; + + BMessage* selectMessage = new BMessage(kSelectMatchingEntries); + selectMessage->AddInt32("ExpressionType", kRegexpMatch); + selectMessage->AddString("Expression", expression); + selectMessage->AddBool("InvertSelection", false); + selectMessage->AddBool("IgnoreCase", false); + + window->Activate(); + // must be activated to populate the pose list + + snooze(100000); + // wait a bit for the pose list to be populated + // ToDo: figure out why this is necessary + + window->PostMessage(selectMessage); + } +} + + template class EntryAndNodeDoSoonWithMessageFunctor : public FunctionObjectWithResult { diff --git a/src/kits/tracker/Tracker.h b/src/kits/tracker/Tracker.h index 8cb4b84d28..efda7aef37 100644 --- a/src/kits/tracker/Tracker.h +++ b/src/kits/tracker/Tracker.h @@ -201,6 +201,7 @@ private: void CloseAllInWorkspace(); void OpenInfoWindows(BMessage*); void MoveRefsToTrash(const BMessage*); + void SelectRefs(const BMessage*); void OpenContainerWindow(Model*, BMessage* refsList = NULL, OpenSelector openSelector = kOpen, uint32 openFlags = 0, bool checkAlreadyOpen = true,