libroot/posix/stdio: Remove unused portions.
[haiku.git] / src / apps / stylededit / StyledEditApp.cpp
blob7e3ecdc08d2f54ccbaf677f37f5da2dd87fa9aab
1 /*
2 * Copyright 2002-2016, Haiku, Inc. All Rights Reserved.
3 * Distributed under the terms of the MIT License.
5 * Authors:
6 * Mattias Sundblad
7 * Andrew Bachmann
8 * Jonas Sundström
9 */
12 #include "Constants.h"
13 #include "StyledEditApp.h"
14 #include "StyledEditWindow.h"
16 #include <Alert.h>
17 #include <Autolock.h>
18 #include <Catalog.h>
19 #include <Locale.h>
20 #include <MenuBar.h>
21 #include <CharacterSet.h>
22 #include <CharacterSetRoster.h>
23 #include <FilePanel.h>
24 #include <MenuItem.h>
25 #include <Message.h>
26 #include <Path.h>
27 #include <Screen.h>
29 #include <stdio.h>
32 using namespace BPrivate;
35 static BRect sWindowRect(7, 26, 507, 426);
36 static float sCascadeOffset = 15;
37 static BPoint sTopLeft = BPoint(7, 26);
40 namespace
42 void
43 cascade()
45 BScreen screen;
46 BRect screenBorder = screen.Frame();
47 float left = sWindowRect.left + sCascadeOffset;
48 if (left + sWindowRect.Width() > screenBorder.right)
49 left = sTopLeft.x;
51 float top = sWindowRect.top + sCascadeOffset;
52 if (top + sWindowRect.Height() > screenBorder.bottom)
53 top = sTopLeft.y;
55 sWindowRect.OffsetTo(BPoint(left, top));
59 void
60 uncascade()
62 BScreen screen;
63 BRect screenBorder = screen.Frame();
65 float left = sWindowRect.left - sCascadeOffset;
66 if (left < sTopLeft.x) {
67 left = screenBorder.right - sWindowRect.Width() - sTopLeft.x;
68 left = left - ((int)left % (int)sCascadeOffset) + sTopLeft.x;
71 float top = sWindowRect.top - sCascadeOffset;
72 if (top < sTopLeft.y) {
73 top = screenBorder.bottom - sWindowRect.Height() - sTopLeft.y;
74 top = top - ((int)left % (int)sCascadeOffset) + sTopLeft.y;
77 sWindowRect.OffsetTo(BPoint(left, top));
82 // #pragma mark -
85 #undef B_TRANSLATION_CONTEXT
86 #define B_TRANSLATION_CONTEXT "Open_and_SaveAsPanel"
89 StyledEditApp::StyledEditApp()
91 BApplication(APP_SIGNATURE),
92 fOpenPanel(NULL)
94 B_TRANSLATE_MARK_SYSTEM_NAME_VOID("StyledEdit");
96 fOpenPanel = new BFilePanel();
97 fOpenAsEncoding = 0;
99 BMenuBar* menuBar
100 = dynamic_cast<BMenuBar*>(fOpenPanel->Window()->FindView("MenuBar"));
101 if (menuBar != NULL) {
102 fOpenPanelEncodingMenu = new BMenu(B_TRANSLATE("Encoding"));
103 fOpenPanelEncodingMenu->SetRadioMode(true);
105 menuBar->AddItem(fOpenPanelEncodingMenu);
107 BCharacterSetRoster roster;
108 BCharacterSet charset;
109 while (roster.GetNextCharacterSet(&charset) == B_NO_ERROR) {
110 BString name;
111 if (charset.GetFontID() == B_UNICODE_UTF8)
112 name = B_TRANSLATE("Default");
113 else
114 name = charset.GetPrintName();
116 const char* mime = charset.GetMIMEName();
117 if (mime != NULL) {
118 name.Append(" (");
119 name.Append(mime);
120 name.Append(")");
122 BMenuItem* item
123 = new BMenuItem(name.String(), new BMessage(OPEN_AS_ENCODING));
124 item->SetTarget(this);
125 fOpenPanelEncodingMenu->AddItem(item);
126 if (charset.GetFontID() == fOpenAsEncoding)
127 item->SetMarked(true);
129 } else
130 fOpenPanelEncodingMenu = NULL;
132 fWindowCount = 0;
133 fNextUntitledWindow = 1;
134 fBadArguments = false;
136 float factor = be_plain_font->Size() / 12.0f;
137 sCascadeOffset *= factor;
138 sTopLeft.x *= factor;
139 sTopLeft.y *= factor;
140 sWindowRect.left *= factor;
141 sWindowRect.top *= factor;
142 sWindowRect.right *= factor;
143 sWindowRect.bottom *= factor;
147 StyledEditApp::~StyledEditApp()
149 delete fOpenPanel;
153 void
154 StyledEditApp::MessageReceived(BMessage* message)
156 switch (message->what) {
157 case MENU_NEW:
158 OpenDocument();
159 break;
160 case MENU_OPEN:
161 fOpenPanel->Show();
162 break;
163 case B_SILENT_RELAUNCH:
164 OpenDocument();
165 break;
166 case OPEN_AS_ENCODING:
167 void* ptr;
168 if (message->FindPointer("source", &ptr) == B_OK
169 && fOpenPanelEncodingMenu != NULL) {
170 fOpenAsEncoding = (uint32)fOpenPanelEncodingMenu->IndexOf(
171 (BMenuItem*)ptr);
173 break;
175 default:
176 BApplication::MessageReceived(message);
177 break;
182 void
183 StyledEditApp::OpenDocument()
185 new StyledEditWindow(sWindowRect, fNextUntitledWindow++, fOpenAsEncoding);
186 cascade();
187 fWindowCount++;
191 status_t
192 StyledEditApp::OpenDocument(entry_ref* ref, BMessage* message)
194 // traverse eventual symlink
195 BEntry entry(ref, true);
196 entry.GetRef(ref);
198 if (entry.IsDirectory()) {
199 BPath path(&entry);
200 fprintf(stderr,
201 "Can't open directory \"%s\" for editing.\n",
202 path.Path());
203 return B_ERROR;
206 BEntry parent;
207 entry.GetParent(&parent);
209 if (!entry.Exists() && !parent.Exists()) {
210 fprintf(stderr,
211 "Can't create file. Missing parent directory.\n");
212 return B_ERROR;
215 BWindow* window = NULL;
216 StyledEditWindow* document = NULL;
218 for (int32 index = 0; ; index++) {
219 window = WindowAt(index);
220 if (window == NULL)
221 break;
223 document = dynamic_cast<StyledEditWindow*>(window);
224 if (document == NULL)
225 continue;
227 if (document->IsDocumentEntryRef(ref)) {
228 if (document->Lock()) {
229 document->Activate();
230 document->Unlock();
231 if (message != NULL)
232 document->PostMessage(message);
233 return B_OK;
238 document = new StyledEditWindow(sWindowRect, ref, fOpenAsEncoding);
239 cascade();
241 if (message != NULL)
242 document->PostMessage(message);
244 fWindowCount++;
246 return B_OK;
250 void
251 StyledEditApp::CloseDocument()
253 uncascade();
254 fWindowCount--;
255 if (fWindowCount == 0) {
256 BAutolock lock(this);
257 Quit();
262 void
263 StyledEditApp::RefsReceived(BMessage* message)
265 int32 index = 0;
266 entry_ref ref;
268 while (message->FindRef("refs", index, &ref) == B_OK) {
269 int32 line;
270 if (message->FindInt32("be:line", index, &line) != B_OK)
271 line = -1;
272 int32 start, length;
273 if (message->FindInt32("be:selection_length", index, &length) != B_OK
274 || message->FindInt32("be:selection_offset", index, &start) != B_OK)
276 start = -1;
277 length = -1;
280 BMessage* selection = NULL;
281 if (line >= 0 || (start >= 0 && length >= 0)) {
282 selection = new BMessage(UPDATE_LINE_SELECTION);
283 if (line >= 0)
284 selection->AddInt32("be:line", line);
285 if (start >= 0) {
286 selection->AddInt32("be:selection_offset", start);
287 selection->AddInt32("be:selection_length", max_c(0, length));
291 OpenDocument(&ref, selection);
292 index++;
297 void
298 StyledEditApp::ArgvReceived(int32 argc, char* argv[])
300 // If StyledEdit is already running and gets invoked again
301 // we need to account for a possible mismatch in current
302 // working directory. The paths of the new arguments are
303 // relative to the cwd of the invocation, if they are not
304 // absolute. This cwd we find as a string named "cwd" in
305 // the BLooper's current message.
307 const char* cwd = "";
308 BMessage* message = CurrentMessage();
310 if (message != NULL) {
311 if (message->FindString("cwd", &cwd) != B_OK)
312 cwd = "";
315 for (int i = 1 ; (i < argc) ; i++) {
316 BPath path;
317 if (argv[i][0] == '/') {
318 path.SetTo(argv[i]);
319 } else {
320 path.SetTo(cwd, argv[i]);
321 // patch relative paths only
324 entry_ref ref;
325 get_ref_for_path(path.Path(), &ref);
327 status_t status;
328 status = OpenDocument(&ref);
330 if (status != B_OK && IsLaunching())
331 fBadArguments = true;
336 void
337 StyledEditApp::ReadyToRun()
339 if (fWindowCount > 0)
340 return;
342 if (fBadArguments)
343 Quit();
344 else
345 OpenDocument();
349 int32
350 StyledEditApp::NumberOfWindows()
352 return fWindowCount;
356 // #pragma mark -
360 main(int argc, char** argv)
362 StyledEditApp styledEdit;
363 styledEdit.Run();
364 return 0;