1 /* 2 * Copyright 2002-2007, Haiku, Inc. All Rights Reserved. 3 * Distributed under the terms of the MIT License. 4 * 5 * Authors: 6 * Mattias Sundblad 7 * Andrew Bachmann 8 */ 9 10 11 #include "Constants.h" 12 #include "StyledEditApp.h" 13 #include "StyledEditWindow.h" 14 15 #include <Alert.h> 16 #include <Autolock.h> 17 #include <MenuBar.h> 18 #include <CharacterSet.h> 19 #include <CharacterSetRoster.h> 20 #include <FilePanel.h> 21 #include <MenuItem.h> 22 #include <Message.h> 23 #include <Path.h> 24 #include <Screen.h> 25 26 #include <stdio.h> 27 28 29 using namespace BPrivate; 30 31 32 StyledEditApp * styled_edit_app; 33 BRect gWindowRect(7-15, 26-15, 507, 426); 34 35 36 namespace 37 { 38 void 39 cascade() 40 { 41 BScreen screen(NULL); 42 BRect screenBorder = screen.Frame(); 43 float left = gWindowRect.left + 15; 44 if (left + gWindowRect.Width() > screenBorder.right) 45 left = 7; 46 47 float top = gWindowRect.top + 15; 48 if (top + gWindowRect.Height() > screenBorder.bottom) 49 top = 26; 50 51 gWindowRect.OffsetTo(BPoint(left,top)); 52 } 53 54 55 void 56 uncascade() 57 { 58 BScreen screen(NULL); 59 BRect screenBorder = screen.Frame(); 60 61 float left = gWindowRect.left - 15; 62 if (left < 7) { 63 left = screenBorder.right - gWindowRect.Width() - 7; 64 left = left - ((int)left % 15) + 7; 65 } 66 67 float top = gWindowRect.top - 15; 68 if (top < 26) { 69 top = screenBorder.bottom - gWindowRect.Height() - 26; 70 top = top - ((int)left % 15) + 26; 71 } 72 73 gWindowRect.OffsetTo(BPoint(left,top)); 74 } 75 } 76 77 78 // #pragma mark - 79 80 81 StyledEditApp::StyledEditApp() 82 : BApplication(APP_SIGNATURE), 83 fOpenPanel(NULL) 84 { 85 fOpenPanel = new BFilePanel(); 86 BMenuBar *menuBar = 87 dynamic_cast<BMenuBar*>(fOpenPanel->Window()->FindView("MenuBar")); 88 89 fOpenAsEncoding = 0; 90 fOpenPanelEncodingMenu= new BMenu("Encoding"); 91 menuBar->AddItem(fOpenPanelEncodingMenu); 92 fOpenPanelEncodingMenu->SetRadioMode(true); 93 94 BCharacterSetRoster roster; 95 BCharacterSet charset; 96 while (roster.GetNextCharacterSet(&charset) == B_NO_ERROR) { 97 BString name; 98 if (charset.GetFontID() == B_UNICODE_UTF8) 99 name = "Default"; 100 else 101 name = charset.GetPrintName(); 102 103 const char* mime = charset.GetMIMEName(); 104 if (mime) { 105 name.Append(" ("); 106 name.Append(mime); 107 name.Append(")"); 108 } 109 BMenuItem* item = new BMenuItem(name.String(), new BMessage(OPEN_AS_ENCODING)); 110 item->SetTarget(this); 111 fOpenPanelEncodingMenu->AddItem(item); 112 if (charset.GetFontID() == fOpenAsEncoding) 113 item->SetMarked(true); 114 } 115 116 fWindowCount = 0; 117 fNextUntitledWindow = 1; 118 119 styled_edit_app = this; 120 } 121 122 123 StyledEditApp::~StyledEditApp() 124 { 125 delete fOpenPanel; 126 } 127 128 129 void 130 StyledEditApp::DispatchMessage(BMessage *msg, BHandler *handler) 131 { 132 if (msg->what == B_ARGV_RECEIVED) { 133 int32 argc; 134 if (msg->FindInt32("argc", &argc) != B_OK) 135 argc = 0; 136 137 const char** argv = new const char*[argc]; 138 for (int arg = 0; arg < argc; arg++) { 139 if (msg->FindString("argv", arg, &argv[arg]) != B_OK) { 140 argv[arg] = ""; 141 } 142 } 143 const char* cwd; 144 if (msg->FindString("cwd", &cwd) != B_OK) 145 cwd = ""; 146 147 ArgvReceivedEx(argc, argv, cwd); 148 delete[] argv; 149 } else 150 BApplication::DispatchMessage(msg, handler); 151 } 152 153 154 void 155 StyledEditApp::MessageReceived(BMessage *message) 156 { 157 switch (message->what) { 158 case MENU_NEW: 159 OpenDocument(); 160 break; 161 case MENU_OPEN: 162 fOpenPanel->Show(); 163 break; 164 case B_SILENT_RELAUNCH: 165 OpenDocument(); 166 break; 167 case OPEN_AS_ENCODING: 168 void* ptr; 169 if (message->FindPointer("source", &ptr) == B_OK 170 && fOpenPanelEncodingMenu != 0) { 171 fOpenAsEncoding = (uint32)fOpenPanelEncodingMenu->IndexOf((BMenuItem*)ptr); 172 } 173 break; 174 175 default: 176 BApplication::MessageReceived(message); 177 break; 178 } 179 } 180 181 182 void 183 StyledEditApp::OpenDocument() 184 { 185 cascade(); 186 new StyledEditWindow(gWindowRect, fNextUntitledWindow++, fOpenAsEncoding); 187 fWindowCount++; 188 } 189 190 191 void 192 StyledEditApp::OpenDocument(entry_ref* ref) 193 { 194 cascade(); 195 new StyledEditWindow(gWindowRect, ref, fOpenAsEncoding); 196 fWindowCount++; 197 } 198 199 200 void 201 StyledEditApp::CloseDocument() 202 { 203 uncascade(); 204 fWindowCount--; 205 if (fWindowCount == 0) { 206 BAutolock lock(this); 207 Quit(); 208 } 209 } 210 211 212 void 213 StyledEditApp::RefsReceived(BMessage *message) 214 { 215 int32 index = 0; 216 entry_ref ref; 217 218 while (message->FindRef("refs", index++, &ref) == B_OK) { 219 OpenDocument(&ref); 220 } 221 } 222 223 224 void 225 StyledEditApp::ArgvReceivedEx(int32 argc, const char* argv[], const char* cwd) 226 { 227 for (int i = 1 ; (i < argc) ; i++) { 228 BPath path; 229 if (argv[i][0] == '/') 230 path.SetTo(argv[i]); 231 else 232 path.SetTo(cwd, argv[i]); 233 234 if (path.InitCheck() != B_OK) { 235 fprintf(stderr, "Setting path failed: \""); 236 if (argv[i][0] == '/') 237 fprintf(stderr, "%s\".\n", argv[i]); 238 else 239 fprintf(stderr, "%s/%s\".\n", cwd, argv[i]); 240 continue; 241 } 242 243 entry_ref ref; 244 status_t status = get_ref_for_path(path.Path(), &ref); 245 if (status != B_OK) { 246 fprintf(stderr, "Could not open \"%s\": %s.\n", path.Path(), strerror(status)); 247 continue; 248 } 249 250 OpenDocument(&ref); 251 } 252 } 253 254 255 void 256 StyledEditApp::ReadyToRun() 257 { 258 if (fWindowCount == 0) 259 OpenDocument(); 260 } 261 262 263 int32 264 StyledEditApp::NumberOfWindows() 265 { 266 return fWindowCount; 267 } 268 269 270 // #pragma mark - 271 272 273 int 274 main(int argc, char** argv) 275 { 276 StyledEditApp styledEdit; 277 styledEdit.Run(); 278 return 0; 279 } 280 281