/* * Copyright 2007 - 2009 Chris Roberts. All rights reserved. * Distributed under the terms of the MIT License. * * Authors: * Chris Roberts, cpr420@gmail.com */ #include #include #include #include #include const char* kTerminalSignature = "application/x-vnd.Haiku-Terminal"; const directory_which kAppsDirectory = B_SYSTEM_APPS_DIRECTORY; void launch_terminal(BEntry* targetEntry, BPath* terminalPath) { BPath targetPath; if (targetEntry->GetPath(&targetPath) != B_OK) return; // Escape paths which contain an apostraphe BString target(targetPath.Path()); target.ReplaceAll("'", "'\\''"); BString terminal(terminalPath->Path()); terminal.ReplaceAll("'", "'\\''"); // Build the command to "cd '/my/target/folder'; '/path/to/Terminal' &" BString command("cd '"); command << target << "'; '" << terminal << "' &"; // Launch the Terminal. system(command.String()); } void process_refs(entry_ref base_ref, BMessage* message, void* reserved) { BPath terminalPath; bool terminalFound = false; // Search for Terminal path by asking BRoster. entry_ref terminalRef; if (be_roster->FindApp(kTerminalSignature, &terminalRef) == B_OK) { if (terminalPath.SetTo(&terminalRef) == B_OK) terminalFound = true; } // Fall back to manually creating a path if BRoster didn't find it. if (!terminalFound) { if (find_directory(kAppsDirectory, &terminalPath) != B_OK) return; if (terminalPath.Append("Terminal") != B_OK) return; } BEntry entry; int32 i; entry_ref tracker_ref; std::vector entries; // Iterate through the refs that Tracker has sent us. for (i = 0; message->FindRef("refs", i, &tracker_ref) == B_OK; i++) { // Pass 'true' as the traverse argument below, so that if the ref // is a symbolic link we get the target of the link to ensure that // it actually exists. if (entry.SetTo(&tracker_ref, true) != B_OK) continue; // If the entry is a file then look for the parent directory. if (!entry.IsDirectory()) { if (entry.GetParent(&entry) != B_OK) continue; } bool duplicate = false; // Check for duplicates. for (uint x = 0; x < entries.size(); x++) { if (entries[x] == entry) { duplicate = true; break; } } // This is a duplicate. Continue to next ref. if (duplicate) continue; // Push entry onto the vector so we can check for duplicates later. entries.push_back(BEntry(entry)); launch_terminal(&entry, &terminalPath); } // If nothing was selected we'll use the base folder. if (i == 0) { if (entry.SetTo(&base_ref) == B_OK) launch_terminal(&entry, &terminalPath); } }