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