1 /* 2 * Copyright 2007 - 2009 Chris Roberts. All rights reserved. 3 * Distributed under the terms of the MIT License. 4 * 5 * Authors: 6 * Chris Roberts, cpr420@gmail.com 7 */ 8 9 #include <StorageKit.h> 10 #include <SupportKit.h> 11 #include <AppKit.h> 12 13 #include <vector> 14 15 #include <add-ons/tracker/TrackerAddOn.h> 16 17 const char* kTerminalSignature = "application/x-vnd.Haiku-Terminal"; 18 const directory_which kAppsDirectory = B_SYSTEM_APPS_DIRECTORY; 19 20 void 21 launch_terminal(BEntry* targetEntry, BPath* terminalPath) { 22 23 BPath targetPath; 24 25 if (targetEntry->GetPath(&targetPath) != B_OK) 26 return; 27 28 // Escape paths which contain an apostraphe 29 BString target(targetPath.Path()); 30 target.ReplaceAll("'", "'\\''"); 31 32 BString terminal(terminalPath->Path()); 33 terminal.ReplaceAll("'", "'\\''"); 34 35 // Build the command to "cd '/my/target/folder'; '/path/to/Terminal' &" 36 BString command("cd '"); 37 command << target << "'; '" << terminal << "' &"; 38 39 // Launch the Terminal. 40 system(command.String()); 41 } 42 43 44 void 45 process_refs(entry_ref base_ref, BMessage* message, void* reserved) 46 { 47 BPath terminalPath; 48 49 bool terminalFound = false; 50 51 // Search for Terminal path by asking BRoster. 52 entry_ref terminalRef; 53 if (be_roster->FindApp(kTerminalSignature, &terminalRef) == B_OK) { 54 if (terminalPath.SetTo(&terminalRef) == B_OK) 55 terminalFound = true; 56 } 57 58 // Fall back to manually creating a path if BRoster didn't find it. 59 if (!terminalFound) { 60 if (find_directory(kAppsDirectory, &terminalPath) != B_OK) 61 return; 62 63 if (terminalPath.Append("Terminal") != B_OK) 64 return; 65 } 66 67 BEntry entry; 68 int32 i; 69 entry_ref tracker_ref; 70 std::vector<BEntry> entries; 71 72 // Iterate through the refs that Tracker has sent us. 73 for (i = 0; message->FindRef("refs", i, &tracker_ref) == B_OK; i++) { 74 75 // Pass 'true' as the traverse argument below, so that if the ref 76 // is a symbolic link we get the target of the link to ensure that 77 // it actually exists. 78 if (entry.SetTo(&tracker_ref, true) != B_OK) 79 continue; 80 81 // If the entry is a file then look for the parent directory. 82 if (!entry.IsDirectory()) { 83 if (entry.GetParent(&entry) != B_OK) 84 continue; 85 } 86 87 bool duplicate = false; 88 89 // Check for duplicates. 90 for (uint x = 0; x < entries.size(); x++) { 91 if (entries[x] == entry) { 92 duplicate = true; 93 break; 94 } 95 } 96 97 // This is a duplicate. Continue to next ref. 98 if (duplicate) 99 continue; 100 101 // Push entry onto the vector so we can check for duplicates later. 102 entries.push_back(BEntry(entry)); 103 104 launch_terminal(&entry, &terminalPath); 105 106 } 107 108 // If nothing was selected we'll use the base folder. 109 if (i == 0) { 110 if (entry.SetTo(&base_ref) == B_OK) 111 launch_terminal(&entry, &terminalPath); 112 } 113 } 114