xref: /haiku/src/bin/filepanel.cpp (revision 9760dcae2038d47442f4658c2575844c6cf92c40)
1 /*
2  * filepanel.cpp - a command line tool to open a BFilePanel and get the result
3  * copyright 2003, Francois Revol, revol@free.fr
4  * LDFLAGS="-lbe -ltracker" make filepanel
5  * return:
6  * 0: the user has selected something,
7  * 1: the user canceled/closed the panel,
8  * 2: an error occured.
9  */
10 
11 //#define USE_FNMATCH
12 
13 #ifdef USE_FNMATCH
14 #include <fnmatch.h>
15 #endif
16 #include <stdio.h>
17 #include <stdlib.h>
18 #include <strings.h>
19 #include <Application.h>
20 #include <Messenger.h>
21 #include <Window.h>
22 #include <storage/Entry.h>
23 #include <storage/FilePanel.h>
24 #include <storage/Path.h>
25 
26 #define APP_SIG "application/x-vnd.mmu_man.filepanel"
27 
28 volatile int return_code = 0;
29 
30 class FilePanelApp : public BApplication
31 {
32 public:
33 	FilePanelApp();
34 
35 	virtual void MessageReceived(BMessage *message);
36 	virtual void RefsReceived(BMessage *message);
37 };
38 
39 FilePanelApp::FilePanelApp()
40 	:BApplication(APP_SIG)
41 {
42 }
43 
44 void
45 FilePanelApp::MessageReceived(BMessage *message)
46 {
47 	entry_ref e;
48 	const char *name;
49 	BEntry entry;
50 	BPath p;
51 
52 	//message->PrintToStream();
53 	switch (message->what) {
54 	case B_SAVE_REQUESTED:
55 		message->FindRef("directory", &e);
56 		message->FindString("name", &name);
57 		entry.SetTo(&e);
58 		entry.GetPath(&p);
59 		printf("%s/%s\n", p.Path(), name);
60 		be_app_messenger.SendMessage(B_QUIT_REQUESTED);
61 		break;
62 	case B_CANCEL:
63 		return_code = 1;
64 		be_app_messenger.SendMessage(B_QUIT_REQUESTED);
65 		break;
66 	default:
67 		BApplication::MessageReceived(message);
68 	}
69 }
70 
71 void
72 FilePanelApp::RefsReceived(BMessage *message)
73 {
74 	entry_ref e;
75 	BEntry entry;
76 	int i;
77 	BPath p;
78 //	message->PrintToStream();
79 	for (i = 0; message->FindRef("refs", i, &e) == B_OK; i++) {
80 		entry.SetTo(&e);
81 		entry.GetPath(&p);
82 		puts(p.Path());
83 	}
84 	be_app_messenger.SendMessage(B_QUIT_REQUESTED);
85 }
86 
87 int
88 usage(char *pname, int error)
89 {
90 	fprintf(stderr, "display a load/save file panel\n");
91 	fprintf(stderr, "usage: %s [--help] [--directory folder] [--load|--save] [--title ttl] [--single] [--modal] [--allow pattern] [--forbid pattern]\n", pname);
92 	fprintf(stderr, "usage: %s [-h]     [-d folder]              [-l|-s]     [-t ttl]      [-1]       [-m]      [-a pattern]      [-f pattern]\n", pname);
93 	fprintf(stderr, "options:\n");
94 	fprintf(stderr, "short\tlong\tdescription\n");
95 	fprintf(stderr, "-h\t--help\tdisplay usage\n");
96 	fprintf(stderr, "-d\t--directory\topen at <folder>\n");
97 	fprintf(stderr, "-l\t--load\tuse a load FilePanel (default)\n");
98 	fprintf(stderr, "-s\t--save\tuse a save FilePanel\n");
99 	fprintf(stderr, "-n\t--name\tset the default name for saving\n");
100 	fprintf(stderr, "-k\t--kind\tkind of entries that can be opened (flavour): any combination of f, d, s (file (default), directory, symlink)\n");
101 	fprintf(stderr, "-t\t--title\tset the FilePanel window title\n");
102 	fprintf(stderr, "-1\t--single\tallow only 1 file to be selected\n");
103 	fprintf(stderr, "-m\t--modal\tmakes the FilePanel modal\n");
104 #ifndef USE_FNMATCH
105 	fprintf(stderr, "-a\t--allow\tunimplemented\n");
106 	fprintf(stderr, "-f\t--forbid\tunimplemented\n");
107 #else
108 	fprintf(stderr, "-a\t--allow\tunimplemented\n");
109 	fprintf(stderr, "-f\t--forbid\tunimplemented\n");
110 #endif
111 	return error;
112 }
113 
114 int
115 main(int argc, char **argv)
116 {
117 	int i;
118 	file_panel_mode fpMode = B_OPEN_PANEL;
119 	uint32 nodeFlavour = 0;
120 	char *openAt = NULL;
121 	char *windowTitle = NULL;
122 	bool allowMultiSelect = true;
123 	bool makeModal = false;
124 	const char *defaultName = NULL;
125 
126 	for (i = 1; i < argc; i++) {
127 		if (strncmp(argv[i], "--", 2) && ((*(argv[i]) == '-' && strlen(argv[i]) != 2) || *(argv[i]) != '-')) {
128 			fprintf(stderr, "%s not a valid option\n", argv[i]);
129 			return usage(argv[0], 2);
130 		}
131 		if (!strcmp(argv[i], "--help") || !strcmp(argv[i], "-h")) {
132 			return usage(argv[0], 0);
133 		} else if (!strcmp(argv[i], "--directory") || !strcmp(argv[i], "-d")) {
134 			if (++i >= argc) {
135 				fprintf(stderr, "%s: this option requires a parameter\n", argv[i-1]);
136 				return usage(argv[0], 2);
137 			}
138 			openAt = argv[i];
139 		} else if (!strcmp(argv[i], "--load") || !strcmp(argv[i], "-l")) {
140 			fpMode = B_OPEN_PANEL;
141 		} else if (!strcmp(argv[i], "--save") || !strcmp(argv[i], "-s")) {
142 			fpMode = B_SAVE_PANEL;
143 		} else if (!strcmp(argv[i], "--name") || !strcmp(argv[i], "-n")) {
144 			if (++i >= argc) {
145 				fprintf(stderr, "%s: this option requires a parameter\n", argv[i-1]);
146 				return usage(argv[0], 2);
147 			}
148 			defaultName = (const char *)argv[i];
149 		} else if (!strcmp(argv[i], "--kind") || !strcmp(argv[i], "-k")) {
150 			if (++i >= argc) {
151 				fprintf(stderr, "%s: this option requires a parameter\n", argv[i-1]);
152 				return usage(argv[0], 2);
153 			}
154 			if (strchr(argv[i], 'f')) nodeFlavour |= B_FILE_NODE;
155 			if (strchr(argv[i], 'd')) nodeFlavour |= B_DIRECTORY_NODE;
156 			if (strchr(argv[i], 's')) nodeFlavour |= B_SYMLINK_NODE;
157 		} else if (!strcmp(argv[i], "--title") || !strcmp(argv[i], "-t")) {
158 			if (++i >= argc) {
159 				fprintf(stderr, "%s: this option requires a parameter\n", argv[i-1]);
160 				return usage(argv[0], 2);
161 			}
162 			windowTitle = argv[i];
163 		} else if (!strcmp(argv[i], "--single") || !strcmp(argv[i], "-1")) {
164 			allowMultiSelect = false;
165 		} else if (!strcmp(argv[i], "--modal") || !strcmp(argv[i], "-m")) {
166 			makeModal = true;
167 		} else if (!strcmp(argv[i], "--allow") || !strcmp(argv[i], "-a")) {
168 			if (++i >= argc) {
169 				fprintf(stderr, "%s: this option requires a parameter\n", argv[i-1]);
170 				return usage(argv[0], 2);
171 			}
172 			fprintf(stderr, "%s: UNIMPLEMENTED\n", argv[i-1]);
173 		} else if (!strcmp(argv[i], "--forbid") || !strcmp(argv[i], "-f")) {
174 			if (++i >= argc) {
175 				fprintf(stderr, "%s: this option requires a parameter\n", argv[i-1]);
176 				return usage(argv[0], 2);
177 			}
178 			fprintf(stderr, "%s: UNIMPLEMENTED\n", argv[i-1]);
179 		} else {
180 			fprintf(stderr, "%s not a valid option\n", argv[i]);
181 			return usage(argv[0], 2);
182 		}
183 	}
184 	new FilePanelApp;
185 	entry_ref panelDir;
186 // THIS LINE makes main() return always 0 no matter which value on return of exit() ???
187 	BFilePanel *fPanel = new BFilePanel(fpMode, NULL, NULL, nodeFlavour, allowMultiSelect, NULL, NULL, makeModal);
188 /**/
189 	if (openAt)
190 		fPanel->SetPanelDirectory(openAt);
191 	if (windowTitle)
192 		fPanel->Window()->SetTitle(windowTitle);
193 	if (fpMode == B_SAVE_PANEL && defaultName)
194 		fPanel->SetSaveText(defaultName);
195 
196 	fPanel->Show();
197 /**/
198 	be_app->Run();
199 	delete be_app;
200 //	printf("rc = %d\n", return_code);
201 // WTF ??
202 //return 2;
203 //	exit(2);
204 	exit(return_code);
205 	return return_code;
206 }
207 
208