xref: /haiku/src/bin/alert.cpp (revision 1d9d47fc72028bb71b5f232a877231e59cfe2438)
1 /*********************************************************************
2 ** Alert Applet
3 **********************************************************************
4 ** 2002-04-28  Mathew Hounsell  Created.
5 */
6 
7 #include <Application.h>
8 #include <Alert.h>
9 
10 #include <cstdio>
11 #include <cstring>
12 #include <cstdlib>
13 #include <cassert>
14 
15 /*********************************************************************
16 */
17 
18 // #define SIGNATURE "application/x-vnd.Be-cmd-alert"
19 #define SIGNATURE "application/x-vnd.OBOS.cmd-alert"
20 #define APP_NAME "alert"
21 
22 #define BUTTON_DEFAULT "OK"
23 
24 #define ERR_INIT_FAIL  127
25 #define ERR_ARGS_FAIL  126
26 #define ERR_NONE       0
27 
28 /*********************************************************************
29 */
30 class Arguments {
31 	bool ok, recved, modal;
32 	alert_type icon;
33 	char *arg_text, *arg_but0, *arg_but1, *arg_but2;
34 	char *choice_text;
35 	int32 choice;
36 public:
37 	Arguments( void ) {
38 		ok = recved = modal = false;
39 		icon = B_INFO_ALERT;
40 		arg_text = arg_but0 = arg_but1 = arg_but2 = 0;
41 		choice = 0;
42 	}
43 	~Arguments( void ) {
44 		std::free( arg_text );
45 		std::free( arg_but0 );
46 		std::free( arg_but1 );
47 		std::free( arg_but2 );
48 	}
49 
50 	inline bool Good( void ) const { return ok; }
51 	inline bool Bad( void ) const { return ! ok; }
52 
53 	void ArgvReceived( int32 argc, char **argv )
54 	{
55 		recved = true;
56 
57 		if( argc < 2 ) return;
58 
59 		int32 start = 1;
60 		bool flag_icon = false;
61 
62 		// Look for '--' options'
63 		for( int32 i = 1; i < argc; ++i, ++start ) {
64 			if( '-' == argv[i][0] && '-' == argv[i][1] ) {
65 				if( 0 == strcmp( argv[i] + 2, "modal" ) ) {
66 					modal = true;
67 //				} else if( 0 == strcmp( argv[i] + 2, "empty" )
68 //				       ||  0 == strcmp( argv[i] + 2, "none" ) ) {
69 				} else if( 0 == strcmp( argv[i] + 2, "empty" ) ) {
70 					if( flag_icon ) return;
71 					icon = B_EMPTY_ALERT;
72 					flag_icon = true;
73 				} else if( 0 == strcmp( argv[i] + 2, "info" ) ) {
74 					if( flag_icon ) return;
75 					icon = B_INFO_ALERT;
76 					flag_icon = true;
77 				} else if( 0 == strcmp( argv[i] + 2, "idea" ) ) {
78 					if( flag_icon ) return;
79 					icon = B_IDEA_ALERT;
80 					flag_icon = true;
81 //				} else if( 0 == strcmp( argv[i] + 2, "warning" )
82 //				       ||  0 == strcmp( argv[i] + 2, "warn" ) ) {
83 				} else if( 0 == strcmp( argv[i] + 2, "warning" ) ) {
84 					if( flag_icon ) return;
85 					icon = B_WARNING_ALERT;
86 					flag_icon = true;
87 				} else if( 0 == strcmp( argv[i] + 2, "stop" ) ) {
88 					if( flag_icon ) return;
89 					icon = B_STOP_ALERT;
90 					flag_icon = true;
91 				} else {
92 					return;
93 				}
94 			} else break;
95 		}
96 
97 		if( start >= argc ) { // Nothing but --modal
98 			return;
99 		}
100 
101 		arg_text = strdup( argv[start++] );
102 		if( start < argc ) arg_but0 = strdup( argv[start++] );
103 		else arg_but0 = strdup( BUTTON_DEFAULT );
104 		if( start < argc ) arg_but1 = strdup( argv[start++] );
105 		if( start < argc ) arg_but2 = strdup( argv[start++] );
106 
107 		ok = true;
108 	}
109 
110 	inline char const * Title( void ) const { return APP_NAME; }
111 
112 	inline char const * Text( void ) const { return arg_text; }
113 	inline char const * ButtonZero( void ) const { return arg_but0; }
114 	inline char const * ButtonOne( void ) const { return arg_but1; }
115 	inline char const * ButtonTwo( void ) const { return arg_but2; }
116 
117 	inline alert_type Type( void ) const { return icon; }
118 
119 	inline bool IsModal( void ) const { return modal; }
120 
121 	inline bool Received( void ) const { return recved; }
122 
123 	inline int32 ChoiceNumber( void ) const { return choice; }
124 	inline char const * ChoiceText( void ) const { return choice_text; }
125 
126 	void SetChoice( int32 but )
127 	{
128 		assert( but >= 0 && but <= 2 );
129 
130 		choice = but;
131 		switch( choice ) {
132 			case 0: choice_text = arg_but0; break;
133 			case 1: choice_text = arg_but1; break;
134 			case 2: choice_text = arg_but2; break;
135 		}
136 	}
137 
138 	void Usage( void )
139 	{
140 		fprintf(
141 		    stderr,
142 			"usage: " APP_NAME " <type> ] [ --modal ] [ --help ] text [ button1 [ button2 [ button3 ]]]\n"
143 			  "<type> is --empty | --info | --idea | --warning | --stop\n"
144 			  "--modal makes the alert system modal and shows it in all workspaces.\n"
145 			  "If any button argument is given, exit status is button number (starting with 0)\n"
146 			  " and '" APP_NAME "' will print the title of the button pressed to stdout.\n"
147 		);
148 	}
149 
150 } arguments;
151 
152 /*********************************************************************
153 */
154 class AlertApplication : public BApplication {
155 	typedef BApplication super;
156 
157 public:
158 	AlertApplication( void ) : super( SIGNATURE ) { }
159 	// No destructor as it crashes app.
160 
161 	virtual void ArgvReceived( int32 argc, char **argv )
162 	{
163 		if( ! arguments.Received() ) {
164 			arguments.ArgvReceived( argc, argv );
165 		}
166 	}
167 
168 	// Prepare to Run
169 	virtual void ReadyToRun(void) {
170 
171 		if( arguments.Good() ) {
172 			BAlert * alert_p
173 				= new BAlert(
174 						arguments.Title(),
175 						arguments.Text(),
176 						arguments.ButtonZero(),
177 						arguments.ButtonOne(),
178 						arguments.ButtonTwo(),
179 						B_WIDTH_AS_USUAL,
180 						arguments.Type()
181 					);
182 
183 			if( arguments.IsModal() ) {
184 				alert_p->SetFeel( B_MODAL_ALL_WINDOW_FEEL );
185 			}
186 
187 			arguments.SetChoice( alert_p->Go() );
188 		}
189 
190 		Quit();
191 	}
192 };
193 
194 /*********************************************************************
195 ** Acording to the BeBook youm should use the message handling in
196 ** BApplication for arguments. However that requires the app to
197 ** be created.
198 */
199 int main( int argc, char ** argv )
200 {
201 	arguments.ArgvReceived( int32(argc), argv );
202 	if( ! arguments.Good() ) {
203 		arguments.Usage();
204 		return ERR_ARGS_FAIL;
205 	}
206 
207 	int errorlevel = ERR_NONE;
208 
209 	// App is Automatically assigned to be_app
210 	new AlertApplication();
211 
212 	if( B_OK != be_app->InitCheck() ) {
213 		// Cast for the right version.
214 		errorlevel = ERR_INIT_FAIL;
215 	} else {
216 		// Run
217 		be_app->Run();
218 		if( ! arguments.Good() ) { // In case of Roster start.
219 			arguments.Usage();
220 			errorlevel = ERR_ARGS_FAIL;
221 		} else {
222 			fprintf( stdout, "%s\n", arguments.ChoiceText() );
223 			errorlevel = arguments.ChoiceNumber();
224 		}
225 	}
226 
227 	return errorlevel;
228 }
229