Пример #1
0
// factory function
CommandActuator*
CreateCommandActuator(const char* command)
{
	CommandActuator* act = NULL;
	int32 argc;
	char** argv = ParseArgvFromString(command, argc);
	if (command[0] == '*') {
		if (argc > 0) {
			char* c = argv[0] + 1;
			if (strcmp(c, "InsertString") == 0)
				act = new KeyStrokeSequenceCommandActuator(argc, argv);
			else if (strcmp(c, "MoveMouse") == 0)
				act = new MoveMouseByCommandActuator(argc, argv);
			else if (strcmp(c, "MoveMouseTo") == 0)
				act = new MoveMouseToCommandActuator(argc, argv);
			else if (strcmp(c, "MouseButton") == 0)
				act = new MouseButtonCommandActuator(argc, argv);
			else if (strcmp(c, "LaunchHandler") == 0)
				act = new MIMEHandlerCommandActuator(argc, argv);
			else if (strcmp(c, "Multi") == 0)
				act = new MultiCommandActuator(argc, argv);
			else if (strcmp(c, "MouseDown") == 0)
				act = new MouseDownCommandActuator(argc, argv);
			else if (strcmp(c, "MouseUp") == 0)
				act = new MouseUpCommandActuator(argc, argv);
			else if (strcmp(c, "SendMessage") == 0)
				act = new SendMessageCommandActuator(argc, argv);
			else
				act = new BeepCommandActuator(argc, argv);
		}
	} else
		act = new LaunchCommandActuator(argc, argv);

	FreeArgv(argv);
	return act;
}
bool
ShortcutsSpec::_AttemptTabCompletion()
{
	bool ret = false;

	int32 argc;
	char** argv = ParseArgvFromString(fCommand, argc);
	if (argc > 0) {
		// Try to complete the path partially expressed in the last argument!
		char* arg = argv[argc - 1];
		char* fileFragment = strrchr(arg, '/');
		if (fileFragment) {
			const char* directoryName = (fileFragment == arg) ? "/" : arg;
			*fileFragment = '\0';
			fileFragment++;
			int fragLen = strlen(fileFragment);

			BDirectory dir(directoryName);
			if (dir.InitCheck() == B_NO_ERROR) {
				BEntry nextEnt;
				BPath nextPath;
				BList matchList;
				int maxEntryLen = 0;

				// Read in all the files in the directory whose names start
				// with our fragment.
				while (dir.GetNextEntry(&nextEnt) == B_NO_ERROR) {
					if (nextEnt.GetPath(&nextPath) == B_NO_ERROR) {
						char* filePath = strrchr(nextPath.Path(), '/') + 1;
						if (strncmp(filePath, fileFragment, fragLen) == 0) {
							int len = strlen(filePath);
							if (len > maxEntryLen)
								maxEntryLen = len;
							char* newStr = new char[len + 1];
							strcpy(newStr, filePath);
							matchList.AddItem(newStr);
						}
					}
				}

				// Now slowly extend our keyword to its full length, counting
				// numbers of matches at each step. If the match list length
				// is 1, we can use that whole entry. If it's greater than one
				// , we can use just the match length.
				int matchLen = matchList.CountItems();
				if (matchLen > 0) {
					int i;
					BString result(fileFragment);
					for (i = fragLen; i < maxEntryLen; i++) {
						// See if all the matching entries have the same letter
						// in the next position... if so, we can go farther.
						char commonLetter = '\0';
						for (int j = 0; j < matchLen; j++) {
							char nextLetter = GetLetterAt(
								(char*)matchList.ItemAt(j), i);
							if (commonLetter == '\0')
								commonLetter = nextLetter;

							if ((commonLetter != '\0')
								&& (commonLetter != nextLetter)) {
								commonLetter = '\0';// failed;
								beep();
								break;
							}
						}
						if (commonLetter == '\0')
							break;
						else
							result.Append(commonLetter, 1);
					}

					// Free all the strings we allocated
					for (int k = 0; k < matchLen; k++)
						delete [] ((char*)matchList.ItemAt(k));

					DoStandardEscapes(result);

					BString wholeLine;
					for (int l = 0; l < argc - 1; l++) {
						wholeLine += argv[l];
						wholeLine += " ";
					}

					BString file(directoryName);
					DoStandardEscapes(file);

					if (directoryName[strlen(directoryName) - 1] != '/')
						file += "/";

					file += result;

					// Remove any trailing slash...
					const char* fileStr = file.String();
					if (fileStr[strlen(fileStr)-1] == '/')
						file.RemoveLast("/");

					// And re-append it iff the file is a dir.
					BDirectory testFileAsDir(file.String());
					if ((strcmp(file.String(), "/") != 0)
						&& (testFileAsDir.InitCheck() == B_NO_ERROR))
						file.Append("/");

					wholeLine += file;

					SetCommand(wholeLine.String());
					ret = true;
				}
			}
			*(fileFragment - 1) = '/';
		}
	}
	FreeArgv(argv);
	return ret;
}