xref: /haiku/src/bin/alert.cpp (revision 8195a5a835117ab2da405e0d477153570b75d921)
1 /*
2  * Copyright 2002-2006, Haiku Inc. All Rights Reserved.
3  * Distributed under the terms of the MIT License.
4  *
5  * Authors:
6  *		Mathew Hounsell
7  *		Vasilis Kaoutsis, kaoutsis@sch.gr
8  */
9 
10 
11 #include <Alert.h>
12 #include <Application.h>
13 
14 #include <stdio.h>
15 #include <string.h>
16 
17 
18 const char* kSignature = "application/x-vnd.Haiku.cmd-alert";
19 
20 const char* kButtonDefault = "OK";
21 
22 const int32 kErrorInitFail = 127;
23 const int32 kErrorArgumentsFail = 126;
24 
25 
26 class AlertApplication : public BApplication {
27 	public:
28 		AlertApplication();
29 		virtual ~AlertApplication() { }
30 
31 		virtual void ReadyToRun();
32 		virtual void ArgvReceived(int32 argc, char** argv);
33 
34 		bool GoodArguments() const { return fOk; }
35 		int32 ChoiceNumber() const { return fChoiceNumber; }
36 		char const* ChoiceText() const { return fChoiceText; }
37 
38 	private:
39 		void _SetChoice(int32 buttonIndex);
40 		void _Usage() const;
41 
42 	private:
43 		bool fOk;
44 		bool fModal;
45 		alert_type fIcon;
46 		char* fArgumentText;
47 		char* fArgumentButton0;
48 		char* fArgumentButton1;
49 		char* fArgumentButton2;
50 		char* fChoiceText;
51 		int32 fChoiceNumber;
52 };
53 
54 
55 AlertApplication::AlertApplication()
56 	: BApplication(kSignature),
57 	fOk(false),
58 	fModal(false),
59 	fIcon(B_INFO_ALERT),
60 	fArgumentText(NULL),
61 	fArgumentButton0(NULL),
62 	fArgumentButton1(NULL),
63 	fArgumentButton2(NULL),
64 	fChoiceText(NULL),
65 	fChoiceNumber(0)
66 {
67 }
68 
69 
70 /*!
71 	Invoked when the application receives a B_ARGV_RECEIVED message.
72 	The message is sent when command line arguments are used in launching the
73 	app from the shell. The function isn't called if there were no command
74 	line arguments.
75 */
76 void
77 AlertApplication::ArgvReceived(int32 argc, char** argv)
78 {
79 	// Now there is at least one
80 	// command line argument option.
81 
82 	const uint32 kArgCount = argc - 1;
83 	uint32 index = 1;
84 	bool iconFlag = false;
85 
86 	// Look for valid '--' options.
87 	for (; index <= kArgCount; ++index) {
88 		if (argv[index][0] == '-' && argv[index][1] == '-') {
89 			const char* option = argv[index] + 2;
90 
91 			if (!strcmp(option, "modal"))
92 				fModal = true;
93 			else if (!strcmp(option, "empty") && !iconFlag) {
94 				fIcon = B_EMPTY_ALERT;
95 				iconFlag = true;
96 			} else if (!strcmp(option, "info") && !iconFlag) {
97 				fIcon = B_INFO_ALERT;
98 				iconFlag = true;
99 			} else if (!strcmp(option, "idea") && !iconFlag) {
100 				fIcon = B_IDEA_ALERT;
101 				iconFlag = true;
102 			} else if (!strcmp(option, "warning") && !iconFlag) {
103 				fIcon = B_WARNING_ALERT;
104 				iconFlag = true;
105 			} else if (!strcmp(option, "stop") && !iconFlag) {
106 				fIcon = B_STOP_ALERT;
107 				iconFlag = true;
108 			} else {
109 				// Unrecognized '--' opition.
110 				fprintf(stdout, "Unrecognized option %s\n", argv[index]);
111 				return;
112 			}
113 		} else {
114 			// Option doesn't start with '--'
115 			break;
116 		}
117 
118 		if (index == kArgCount) {
119 			// User provides arguments that all begins with '--',
120 			// so none can be considered as text argument.
121 			fprintf(stdout, "Missing the text argument!\n");
122 			return;
123 		}
124 	}
125 
126 	fArgumentText = strdup(argv[index]);
127 		// First argument that start without --,
128 		// so grub it as the text argument.
129 
130 	if (index == kArgCount) {
131 		// No more text argument. Give Button0
132 		// the default label.
133 		fArgumentButton0 = strdup(kButtonDefault);
134 		fOk = true;
135 		return;
136 	}
137 
138 	if (index < kArgCount) {
139 		// There is another argument,
140 		// so let that be the Button0 label.
141 		fArgumentButton0 = strdup(argv[++index]);
142 	}
143 
144 	if (index < kArgCount) {
145 		// There is another argument,
146 		// so let that be the Button1 label.
147 		fArgumentButton1 = strdup(argv[++index]);
148 	}
149 
150 	if (index < kArgCount) {
151 		// There is another argument,
152 		// so let that be the Button2 label.
153 		fArgumentButton2 = strdup(argv[++index]);
154 	}
155 
156 	// Ignore all other arguments if they exist,
157 	// since they are useless.
158 
159 	fOk = true;
160 }
161 
162 
163 void
164 AlertApplication::_SetChoice(int32 buttonIndex)
165 {
166 	fChoiceNumber = buttonIndex;
167 	switch (fChoiceNumber) {
168 		case 0:
169 			fChoiceText = fArgumentButton0;
170 			break;
171 
172 		case 1:
173 			fChoiceText = fArgumentButton1;
174 			break;
175 
176 		case 2:
177 			fChoiceText = fArgumentButton2;
178 			break;
179 	}
180 }
181 
182 
183 void
184 AlertApplication::_Usage() const
185 {
186 	fprintf(stderr,
187 		"usage: alert [ <type> ] [ --modal ] [ --help ] text [ button1 [ button2 [ button3 ]]]\n"
188 		"<type> is --empty | --info | --idea | --warning | --stop\n"
189 		"--modal makes the alert system modal and shows it in all workspaces.\n"
190 		"If any button argument is given, exit status is button number (starting with 0)\n"
191 		"and 'alert' will print the title of the button pressed to stdout.\n");
192 }
193 
194 
195 /*!
196 	Is called when the app receives a B_READY_TO_RUN message. The message
197 	is sent automatically during the Run() function, and is sent after the
198 	initial B_REFS_RECEIVED and B_ARGV_RECEIVED messages (if any) have been
199 	handled.
200 */
201 void
202 AlertApplication::ReadyToRun()
203 {
204 	if (GoodArguments()) {
205 		BAlert* alert = new BAlert("alert", fArgumentText,
206 			fArgumentButton0, fArgumentButton1, fArgumentButton2,
207 			B_WIDTH_AS_USUAL, fIcon);
208 
209 		if (fModal)
210 			alert->SetFeel(B_MODAL_ALL_WINDOW_FEEL);
211 
212 		_SetChoice(alert->Go());
213 	} else
214 		_Usage();
215 
216 	Quit();
217 }
218 
219 
220 //	#pragma mark -
221 
222 
223 int
224 main(int argc, char** argv)
225 {
226 	AlertApplication app;
227 	if (app.InitCheck() != B_OK)
228 		return kErrorInitFail;
229 
230 	app.Run();
231 	if (!app.GoodArguments())
232 		return kErrorArgumentsFail;
233 
234 	fprintf(stdout, "%s\n", app.ChoiceText());
235 	return app.ChoiceNumber();
236 }
237