StyledEditWindow.cpp revision a723b3d4
131139022SAxel Dörfler/*
2a723b3d4SAxel Dörfler * Copyright 2002-2010, Haiku, Inc. All Rights Reserved.
331139022SAxel Dörfler * Distributed under the terms of the MIT License.
431139022SAxel Dörfler *
531139022SAxel Dörfler * Authors:
631139022SAxel Dörfler *		Mattias Sundblad
731139022SAxel Dörfler *		Andrew Bachmann
812483e3cSPhilippe Saint-Pierre *		Philippe Saint-Pierre
913e9a630SJonas Sundström *		Jonas Sundstr��m
1031139022SAxel Dörfler */
1131139022SAxel Dörfler
12a723b3d4SAxel Dörfler
1331139022SAxel Dörfler#include "Constants.h"
1431139022SAxel Dörfler#include "ColorMenuItem.h"
1531139022SAxel Dörfler#include "FindWindow.h"
1631139022SAxel Dörfler#include "ReplaceWindow.h"
1731139022SAxel Dörfler#include "StyledEditApp.h"
1831139022SAxel Dörfler#include "StyledEditView.h"
1931139022SAxel Dörfler#include "StyledEditWindow.h"
20f7afd44bSPhil Greenway
21f7afd44bSPhil Greenway#include <Alert.h>
22ed48868fSshatty#include <Autolock.h>
23f0da038eSAdrien Destugues#include <Catalog.h>
24f303cd6cSRyan Leavengood#include <CharacterSet.h>
25f303cd6cSRyan Leavengood#include <CharacterSetRoster.h>
26f7afd44bSPhil Greenway#include <Clipboard.h>
27f303cd6cSRyan Leavengood#include <Debug.h>
28f7afd44bSPhil Greenway#include <File.h>
29f303cd6cSRyan Leavengood#include <FilePanel.h>
30a723b3d4SAxel Dörfler#include <fs_attr.h>
31f0da038eSAdrien Destugues#include <Locale.h>
32f7afd44bSPhil Greenway#include <Menu.h>
33f303cd6cSRyan Leavengood#include <MenuBar.h>
34f7afd44bSPhil Greenway#include <MenuItem.h>
3513e9a630SJonas Sundström#include <Path.h>
36f7afd44bSPhil Greenway#include <PrintJob.h>
37f303cd6cSRyan Leavengood#include <Rect.h>
38b40c9906SRyan Leavengood#include <Roster.h>
39f7afd44bSPhil Greenway#include <ScrollView.h>
40844ea151Sshatty#include <TextControl.h>
41f303cd6cSRyan Leavengood#include <TextView.h>
42f7afd44bSPhil Greenway#include <TranslationUtils.h>
43f7afd44bSPhil Greenway
4446555d8fSshattyusing namespace BPrivate;
4546555d8fSshatty
46ff99f481SAxel Dörfler
478e26769cSRene Gollentconst float kLineViewWidth = 30.0;
4831139022SAxel Dörfler
49a723b3d4SAxel Dörfler#define ATTRNAME_SE_INFO "se-info"
50a723b3d4SAxel Dörfler
51f0da038eSAdrien Destugues#undef TR_CONTEXT
52f0da038eSAdrien Destugues#define TR_CONTEXT "StyledEditWindow"
53ff99f481SAxel Dörfler
54a723b3d4SAxel Dörfler
55670567f9SshattyStyledEditWindow::StyledEditWindow(BRect frame, int32 id, uint32 encoding)
5656a7c23dSAxel Dörfler	: BWindow(frame, "untitled", B_DOCUMENT_WINDOW, B_ASYNCHRONOUS_CONTROLS)
57ed48868fSshatty{
58670567f9Sshatty	InitWindow(encoding);
59f0da038eSAdrien Destugues	BString unTitled(TR("Untitled "));
60ed48868fSshatty	unTitled << id;
61ed48868fSshatty	SetTitle(unTitled.String());
6231139022SAxel Dörfler	fSaveItem->SetEnabled(true);
6331139022SAxel Dörfler		// allow saving empty files
64ed48868fSshatty	Show();
6531139022SAxel Dörfler}
6631139022SAxel Dörfler
67f7afd44bSPhil Greenway
68f0da038eSAdrien DestuguesStyledEditWindow::StyledEditWindow(BRect frame, entry_ref* ref, uint32 encoding)
6956a7c23dSAxel Dörfler	: BWindow(frame, "untitled", B_DOCUMENT_WINDOW, B_ASYNCHRONOUS_CONTROLS)
70ed48868fSshatty{
71670567f9Sshatty	InitWindow(encoding);
72ed48868fSshatty	OpenFile(ref);
73ed48868fSshatty	Show();
7431139022SAxel Dörfler}
7531139022SAxel Dörfler
7631139022SAxel Dörfler
77ed48868fSshattyStyledEditWindow::~StyledEditWindow()
78ed48868fSshatty{
79d727a85bSshatty	delete fSaveMessage;
80d727a85bSshatty	delete fPrintSettings;
81f7afd44bSPhil Greenway	delete fSavePanel;
8231139022SAxel Dörfler}
8331139022SAxel Dörfler
8431139022SAxel Dörfler
85f0da038eSAdrien Destugues#undef TR_CONTEXT
86f0da038eSAdrien Destugues#define TR_CONTEXT "Menus"
87f0da038eSAdrien Destugues
88a723b3d4SAxel Dörfler
89ed48868fSshattyvoid
90670567f9SshattyStyledEditWindow::InitWindow(uint32 encoding)
91ed48868fSshatty{
9231139022SAxel Dörfler	fPrintSettings = NULL;
9331139022SAxel Dörfler	fSaveMessage = NULL;
9431139022SAxel Dörfler
95ed48868fSshatty	// undo modes
96ed48868fSshatty	fUndoFlag = false;
97ed48868fSshatty	fCanUndo = false;
98ed48868fSshatty	fRedoFlag = false;
99ed48868fSshatty	fCanRedo = false;
10031139022SAxel Dörfler
101ed48868fSshatty	// clean modes
102ed48868fSshatty	fUndoCleans = false;
103ed48868fSshatty	fRedoCleans = false;
104ed48868fSshatty	fClean = true;
10531139022SAxel Dörfler
10631139022SAxel Dörfler	// search- state
10731139022SAxel Dörfler	fReplaceString = "";
10831139022SAxel Dörfler	fStringToFind = "";
10931139022SAxel Dörfler	fCaseSens = false;
11031139022SAxel Dörfler	fWrapAround = false;
11131139022SAxel Dörfler	fBackSearch = false;
11231139022SAxel Dörfler
11331139022SAxel Dörfler	// add menubar
11431139022SAxel Dörfler	fMenuBar = new BMenuBar(BRect(0, 0, 0, 0), "menubar");
115f7afd44bSPhil Greenway	AddChild(fMenuBar);
116f7afd44bSPhil Greenway
11731139022SAxel Dörfler	// add textview and scrollview
11831139022SAxel Dörfler
11931139022SAxel Dörfler	BRect viewFrame = Bounds();
12031139022SAxel Dörfler	viewFrame.top = fMenuBar->Bounds().Height() + 1;
121f7afd44bSPhil Greenway	viewFrame.right -=  B_V_SCROLL_BAR_WIDTH;
12231139022SAxel Dörfler	viewFrame.left = 0;
12314ea5e5eSKarsten Heimrich	viewFrame.bottom -= B_H_SCROLL_BAR_HEIGHT;
12414ea5e5eSKarsten Heimrich
12531139022SAxel Dörfler	BRect textBounds = viewFrame;
126f7afd44bSPhil Greenway	textBounds.OffsetTo(B_ORIGIN);
127f7afd44bSPhil Greenway	textBounds.InsetBy(TEXT_INSET, TEXT_INSET);
12831139022SAxel Dörfler
129f7afd44bSPhil Greenway	fTextView= new StyledEditView(viewFrame, textBounds, this);
130ed48868fSshatty	fTextView->SetDoesUndo(true);
131ed48868fSshatty	fTextView->SetStylable(true);
132670567f9Sshatty	fTextView->SetEncoding(encoding);
13331139022SAxel Dörfler
13431139022SAxel Dörfler	fScrollView = new BScrollView("scrollview", fTextView, B_FOLLOW_ALL, 0,
13531139022SAxel Dörfler		true, true, B_PLAIN_BORDER);
136f7afd44bSPhil Greenway	AddChild(fScrollView);
137ed48868fSshatty	fTextView->MakeFocus(true);
138a723b3d4SAxel Dörfler
13931139022SAxel Dörfler	// Add "File"-menu:
140f0da038eSAdrien Destugues	BMenu* menu = new BMenu(TR("File"));
141ed48868fSshatty	fMenuBar->AddItem(menu);
14231139022SAxel Dörfler
14331139022SAxel Dörfler	BMenuItem* menuItem;
144f0da038eSAdrien Destugues	menu->AddItem(menuItem = new BMenuItem(TR("New"),
145f0da038eSAdrien Destugues		new BMessage(MENU_NEW), 'N'));
146ed48868fSshatty	menuItem->SetTarget(be_app);
14714ea5e5eSKarsten Heimrich
148f0da038eSAdrien Destugues	menu->AddItem(menuItem = new BMenuItem(fRecentMenu =
149f0da038eSAdrien Destugues		new BMenu(TR("Open" B_UTF8_ELLIPSIS)), new BMessage(MENU_OPEN)));
15031139022SAxel Dörfler	menuItem->SetShortcut('O', 0);
151f7afd44bSPhil Greenway	menuItem->SetTarget(be_app);
15231139022SAxel Dörfler	menu->AddSeparatorItem();
15331139022SAxel Dörfler
154f0da038eSAdrien Destugues	menu->AddItem(fSaveItem = new BMenuItem(TR("Save"),
155f0da038eSAdrien Destugues		new BMessage(MENU_SAVE), 'S'));
15614ea5e5eSKarsten Heimrich	fSaveItem->SetEnabled(false);
157f0da038eSAdrien Destugues	menu->AddItem(menuItem = new BMenuItem(TR("Save as" B_UTF8_ELLIPSIS),
158f0da038eSAdrien Destugues		new BMessage(MENU_SAVEAS)));
159f0da038eSAdrien Destugues	menuItem->SetShortcut('S', B_SHIFT_KEY);
16031139022SAxel Dörfler	menuItem->SetEnabled(true);
16131139022SAxel Dörfler
162f0da038eSAdrien Destugues	menu->AddItem(fRevertItem =
163f0da038eSAdrien Destugues		new BMenuItem(TR("Revert to saved" B_UTF8_ELLIPSIS),
16414ea5e5eSKarsten Heimrich		new BMessage(MENU_REVERT)));
16531139022SAxel Dörfler	fRevertItem->SetEnabled(false);
166f0da038eSAdrien Destugues	menu->AddItem(menuItem = new BMenuItem(TR("Close"),
167f0da038eSAdrien Destugues		new BMessage(MENU_CLOSE), 'W'));
16831139022SAxel Dörfler
169ed48868fSshatty	menu->AddSeparatorItem();
170f0da038eSAdrien Destugues	menu->AddItem(menuItem = new BMenuItem(TR("Page setup" B_UTF8_ELLIPSIS),
171f0da038eSAdrien Destugues		new BMessage(MENU_PAGESETUP)));
172f0da038eSAdrien Destugues	menu->AddItem(menuItem = new BMenuItem(TR("Print" B_UTF8_ELLIPSIS),
173f0da038eSAdrien Destugues		new BMessage(MENU_PRINT), 'P'));
17431139022SAxel Dörfler
175ed48868fSshatty	menu->AddSeparatorItem();
176f0da038eSAdrien Destugues	menu->AddItem(menuItem = new BMenuItem(TR("Quit"),
177f0da038eSAdrien Destugues		new BMessage(MENU_QUIT), 'Q'));
17831139022SAxel Dörfler
17931139022SAxel Dörfler	// Add the "Edit"-menu:
180f0da038eSAdrien Destugues	menu = new BMenu(TR("Edit"));
181ed48868fSshatty	fMenuBar->AddItem(menu);
18231139022SAxel Dörfler
183f0da038eSAdrien Destugues	menu->AddItem(fUndoItem = new BMenuItem(TR("Can't undo"),
184f0da038eSAdrien Destugues		new BMessage(B_UNDO), 'Z'));
185ed48868fSshatty	fUndoItem->SetEnabled(false);
18631139022SAxel Dörfler
187ed48868fSshatty	menu->AddSeparatorItem();
188f0da038eSAdrien Destugues	menu->AddItem(fCutItem = new BMenuItem(TR("Cut"), new BMessage(B_CUT), 'X'));
189f7afd44bSPhil Greenway	fCutItem->SetEnabled(false);
190ed48868fSshatty	fCutItem->SetTarget(fTextView);
191f7afd44bSPhil Greenway
192f0da038eSAdrien Destugues	menu->AddItem(fCopyItem = new BMenuItem(TR("Copy"),
193f0da038eSAdrien Destugues		new BMessage(B_COPY), 'C'));
194ed48868fSshatty	fCopyItem->SetEnabled(false);
195ed48868fSshatty	fCopyItem->SetTarget(fTextView);
196f7afd44bSPhil Greenway
197f0da038eSAdrien Destugues	menu->AddItem(menuItem = new BMenuItem(TR("Paste"),
198f0da038eSAdrien Destugues		new BMessage(B_PASTE), 'V'));
199ed48868fSshatty	menuItem->SetTarget(fTextView);
200f0da038eSAdrien Destugues	menu->AddItem(fClearItem = new BMenuItem(TR("Clear"),
201f0da038eSAdrien Destugues		new BMessage(MENU_CLEAR)));
20214ea5e5eSKarsten Heimrich	fClearItem->SetEnabled(false);
203ed48868fSshatty	fClearItem->SetTarget(fTextView);
20431139022SAxel Dörfler
205ed48868fSshatty	menu->AddSeparatorItem();
206f0da038eSAdrien Destugues	menu->AddItem(menuItem = new BMenuItem(TR("Select all"),
207f0da038eSAdrien Destugues		new BMessage(B_SELECT_ALL), 'A'));
208ed48868fSshatty	menuItem->SetTarget(fTextView);
20931139022SAxel Dörfler
210ed48868fSshatty	menu->AddSeparatorItem();
211f0da038eSAdrien Destugues	menu->AddItem(menuItem = new BMenuItem(TR("Find" B_UTF8_ELLIPSIS),
212f0da038eSAdrien Destugues		new BMessage(MENU_FIND), 'F'));
213f0da038eSAdrien Destugues	menu->AddItem(fFindAgainItem= new BMenuItem(TR("Find again"),
214f0da038eSAdrien Destugues		new BMessage(MENU_FIND_AGAIN), 'G'));
215aa9dc9eaSshatty	fFindAgainItem->SetEnabled(false);
21631139022SAxel Dörfler
217f0da038eSAdrien Destugues	menu->AddItem(menuItem = new BMenuItem(TR("Find selection"),
218f0da038eSAdrien Destugues		new BMessage(MENU_FIND_SELECTION), 'H'));
219f0da038eSAdrien Destugues	menu->AddItem(menuItem = new BMenuItem(TR("Replace" B_UTF8_ELLIPSIS),
220f0da038eSAdrien Destugues		new BMessage(MENU_REPLACE), 'R'));
221f0da038eSAdrien Destugues	menu->AddItem(fReplaceSameItem = new BMenuItem(TR("Replace same"),
222f0da038eSAdrien Destugues		new BMessage(MENU_REPLACE_SAME), 'T'));
223aa9dc9eaSshatty	fReplaceSameItem->SetEnabled(false);
22431139022SAxel Dörfler
22531139022SAxel Dörfler	// Add the "Font"-menu:
226f0da038eSAdrien Destugues	fFontMenu = new BMenu(TR("Font"));
22787765587Sshatty	fMenuBar->AddItem(fFontMenu);
22831139022SAxel Dörfler
229f7afd44bSPhil Greenway	//"Size"-subMenu
230f0da038eSAdrien Destugues	fFontSizeMenu = new BMenu(TR("Size"));
23187765587Sshatty	fFontSizeMenu->SetRadioMode(true);
23287765587Sshatty	fFontMenu->AddItem(fFontSizeMenu);
23331139022SAxel Dörfler
23431139022SAxel Dörfler	const int32 fontSizes[] = {9, 10, 11, 12, 14, 18, 24, 36, 48, 72};
23531139022SAxel Dörfler	for (uint32 i = 0; i < sizeof(fontSizes) / sizeof(fontSizes[0]); i++) {
23631139022SAxel Dörfler		BMessage* fontMessage = new BMessage(FONT_SIZE);
23731139022SAxel Dörfler		fontMessage->AddFloat("size", fontSizes[i]);
23814ea5e5eSKarsten Heimrich
23931139022SAxel Dörfler		char label[64];
24031139022SAxel Dörfler		snprintf(label, sizeof(label), "%ld", fontSizes[i]);
24131139022SAxel Dörfler		fFontSizeMenu->AddItem(menuItem = new BMenuItem(label, fontMessage));
24231139022SAxel Dörfler
24331139022SAxel Dörfler		if (fontSizes[i] == (int32)be_plain_font->Size())
24431139022SAxel Dörfler			menuItem->SetMarked(true);
24531139022SAxel Dörfler	}
24614ea5e5eSKarsten Heimrich
24731139022SAxel Dörfler	// "Color"-subMenu
248f0da038eSAdrien Destugues	fFontColorMenu = new BMenu(TR("Color"));
24987765587Sshatty	fFontColorMenu->SetRadioMode(true);
25087765587Sshatty	fFontMenu->AddItem(fFontColorMenu);
25114ea5e5eSKarsten Heimrich
252f0da038eSAdrien Destugues	fFontColorMenu->AddItem(fBlackItem = new BMenuItem(TR("Black"),
253f0da038eSAdrien Destugues		new BMessage(FONT_COLOR)));
25414ea5e5eSKarsten Heimrich	fBlackItem->SetMarked(true);
255f0da038eSAdrien Destugues	fFontColorMenu->AddItem(fRedItem = new ColorMenuItem(TR("Red"), RED,
256f0da038eSAdrien Destugues		new BMessage(FONT_COLOR)));
257f0da038eSAdrien Destugues	fFontColorMenu->AddItem(fGreenItem = new ColorMenuItem(TR("Green"), GREEN,
258f0da038eSAdrien Destugues		new BMessage(FONT_COLOR)));
259f0da038eSAdrien Destugues	fFontColorMenu->AddItem(fBlueItem = new ColorMenuItem(TR("Blue"), BLUE,
260f0da038eSAdrien Destugues		new BMessage(FONT_COLOR)));
261f0da038eSAdrien Destugues	fFontColorMenu->AddItem(fCyanItem = new ColorMenuItem(TR("Cyan"), CYAN,
262f0da038eSAdrien Destugues		new BMessage(FONT_COLOR)));
263f0da038eSAdrien Destugues	fFontColorMenu->AddItem(fMagentaItem = new ColorMenuItem(TR("Magenta"), MAGENTA,
264f0da038eSAdrien Destugues		new BMessage(FONT_COLOR)));
265f0da038eSAdrien Destugues	fFontColorMenu->AddItem(fYellowItem = new ColorMenuItem(TR("Yellow"), YELLOW,
266f0da038eSAdrien Destugues		new BMessage(FONT_COLOR)));
26787765587Sshatty	fFontMenu->AddSeparatorItem();
268f7afd44bSPhil Greenway
26912483e3cSPhilippe Saint-Pierre	// Available fonts
27031139022SAxel Dörfler
271d470934cSshatty	fCurrentFontItem = 0;
27212483e3cSPhilippe Saint-Pierre	fCurrentStyleItem = 0;
273f7afd44bSPhil Greenway
27431139022SAxel Dörfler	BMenu* subMenu;
275f7afd44bSPhil Greenway	int32 numFamilies = count_font_families();
27631139022SAxel Dörfler	for (int32 i = 0; i < numFamilies; i++) {
27731139022SAxel Dörfler		font_family family;
27831139022SAxel Dörfler		if (get_font_family(i, &family) == B_OK) {
27931139022SAxel Dörfler			subMenu = new BMenu(family);
280ed48868fSshatty			subMenu->SetRadioMode(true);
281a723b3d4SAxel Dörfler			fFontMenu->AddItem(menuItem = new BMenuItem(subMenu,
28212483e3cSPhilippe Saint-Pierre				new BMessage(FONT_FAMILY)));
28331139022SAxel Dörfler
28431139022SAxel Dörfler			int32 numStyles = count_font_styles(family);
28531139022SAxel Dörfler			for (int32 j = 0; j < numStyles; j++) {
286f7afd44bSPhil Greenway				font_style style;
287f7afd44bSPhil Greenway				uint32 flags;
28831139022SAxel Dörfler				if (get_font_style(family, j, &style, &flags) == B_OK) {
28931139022SAxel Dörfler					subMenu->AddItem(menuItem = new BMenuItem(style,
29031139022SAxel Dörfler						new BMessage(FONT_STYLE)));
291f7afd44bSPhil Greenway				}
292f7afd44bSPhil Greenway			}
293f7afd44bSPhil Greenway		}
29431139022SAxel Dörfler	}
29531139022SAxel Dörfler
29631139022SAxel Dörfler	// Add the "Document"-menu:
297f0da038eSAdrien Destugues	menu = new BMenu(TR("Document"));
298ed48868fSshatty	fMenuBar->AddItem(menu);
29931139022SAxel Dörfler
30031139022SAxel Dörfler	// "Align"-subMenu:
301f0da038eSAdrien Destugues	subMenu = new BMenu(TR("Align"));
30214ea5e5eSKarsten Heimrich	subMenu->SetRadioMode(true);
3030b46ec98Sshatty
304f0da038eSAdrien Destugues	subMenu->AddItem(fAlignLeft = new BMenuItem(TR("Left"),
305f0da038eSAdrien Destugues		new BMessage(ALIGN_LEFT)));
30612483e3cSPhilippe Saint-Pierre	fAlignLeft->SetMarked(true);
30731139022SAxel Dörfler
308f0da038eSAdrien Destugues	subMenu->AddItem(fAlignCenter = new BMenuItem(TR("Center"),
309f0da038eSAdrien Destugues		new BMessage(ALIGN_CENTER)));
310f0da038eSAdrien Destugues	subMenu->AddItem(fAlignRight = new BMenuItem(TR("Right"),
311f0da038eSAdrien Destugues		new BMessage(ALIGN_RIGHT)));
312ed48868fSshatty	menu->AddItem(subMenu);
313f0da038eSAdrien Destugues	menu->AddItem(fWrapItem = new BMenuItem(TR("Wrap lines"),
314f0da038eSAdrien Destugues		new BMessage(WRAP_LINES)));
315ed48868fSshatty	fWrapItem->SetMarked(true);
31631139022SAxel Dörfler
31731139022SAxel Dörfler	fSavePanel = NULL;
31831139022SAxel Dörfler	fSavePanelEncodingMenu = NULL;
31931139022SAxel Dörfler		// build lazily
32031139022SAxel Dörfler}
32131139022SAxel Dörfler
3228f63353bSshatty
323a723b3d4SAxel Dörflervoid
324a723b3d4SAxel DörflerStyledEditWindow::LoadAttrs()
325a723b3d4SAxel Dörfler{
326a723b3d4SAxel Dörfler	if (!fSaveMessage)
327a723b3d4SAxel Dörfler		return;
328a723b3d4SAxel Dörfler
329a723b3d4SAxel Dörfler	entry_ref dir;
330a723b3d4SAxel Dörfler	const char* name;
331a723b3d4SAxel Dörfler	if (fSaveMessage->FindRef("directory", &dir) != B_OK
332a723b3d4SAxel Dörfler		|| fSaveMessage->FindString("name", &name) != B_OK)
333a723b3d4SAxel Dörfler		return;
334a723b3d4SAxel Dörfler
335a723b3d4SAxel Dörfler	BPath documentPath(&dir);
336a723b3d4SAxel Dörfler	documentPath.Append(name);
337a723b3d4SAxel Dörfler
338a723b3d4SAxel Dörfler	BNode documentNode(documentPath.Path());
339a723b3d4SAxel Dörfler	if (documentNode.InitCheck() != B_OK)
340a723b3d4SAxel Dörfler		return;
341a723b3d4SAxel Dörfler
342a723b3d4SAxel Dörfler	BRect newFrame(Frame());
343a723b3d4SAxel Dörfler	ssize_t bytesRead = documentNode.ReadAttr(ATTRNAME_SE_INFO, B_RECT_TYPE,
344a723b3d4SAxel Dörfler		0, &newFrame, sizeof(BRect));
345a723b3d4SAxel Dörfler	if (bytesRead < 0)
346a723b3d4SAxel Dörfler		return;
347a723b3d4SAxel Dörfler
348a723b3d4SAxel Dörfler	MoveTo(newFrame.left, newFrame.top);
349a723b3d4SAxel Dörfler	ResizeTo(newFrame.Width(), newFrame.Height());
350a723b3d4SAxel Dörfler}
351a723b3d4SAxel Dörfler
352a723b3d4SAxel Dörfler
353a723b3d4SAxel Dörflervoid
354a723b3d4SAxel DörflerStyledEditWindow::SaveAttrs()
355a723b3d4SAxel Dörfler{
356a723b3d4SAxel Dörfler	if (!fSaveMessage)
357a723b3d4SAxel Dörfler		return;
358a723b3d4SAxel Dörfler
359a723b3d4SAxel Dörfler	entry_ref dir;
360a723b3d4SAxel Dörfler	const char* name;
361a723b3d4SAxel Dörfler	if (fSaveMessage->FindRef("directory", &dir) != B_OK
362a723b3d4SAxel Dörfler		|| fSaveMessage->FindString("name", &name) != B_OK)
363a723b3d4SAxel Dörfler		return;
364a723b3d4SAxel Dörfler
365a723b3d4SAxel Dörfler	BPath documentPath(&dir);
366a723b3d4SAxel Dörfler	documentPath.Append(name);
367a723b3d4SAxel Dörfler
368a723b3d4SAxel Dörfler	BNode documentNode(documentPath.Path());
369a723b3d4SAxel Dörfler	if (documentNode.InitCheck() != B_OK)
370a723b3d4SAxel Dörfler		return;
371a723b3d4SAxel Dörfler
372a723b3d4SAxel Dörfler	BRect frame(Frame());
373a723b3d4SAxel Dörfler	documentNode.WriteAttr(ATTRNAME_SE_INFO, B_RECT_TYPE, 0, &frame,
374a723b3d4SAxel Dörfler		sizeof(BRect));
375a723b3d4SAxel Dörfler}
376a723b3d4SAxel Dörfler
377a723b3d4SAxel Dörfler
378ed48868fSshattyvoid
379f0da038eSAdrien DestuguesStyledEditWindow::MessageReceived(BMessage* message)
380ed48868fSshatty{
38131139022SAxel Dörfler	if (message->WasDropped()) {
3826e6e1d64SDarkWyrm		entry_ref ref;
38331139022SAxel Dörfler		if (message->FindRef("refs", 0, &ref)==B_OK) {
38431139022SAxel Dörfler			message->what = B_REFS_RECEIVED;
3856e6e1d64SDarkWyrm			be_app->PostMessage(message);
3866e6e1d64SDarkWyrm		}
3876e6e1d64SDarkWyrm	}
38831139022SAxel Dörfler
38931139022SAxel Dörfler	switch (message->what) {
39031139022SAxel Dörfler		// File menu
39131139022SAxel Dörfler		case MENU_SAVE:
39231139022SAxel Dörfler			if (!fSaveMessage)
393a445cd42Sshatty				SaveAs();
394ed48868fSshatty			else
395ed48868fSshatty				Save(fSaveMessage);
39631139022SAxel Dörfler			break;
39731139022SAxel Dörfler
398ed48868fSshatty		case MENU_SAVEAS:
399a445cd42Sshatty			SaveAs();
40031139022SAxel Dörfler			break;
40131139022SAxel Dörfler
402ed48868fSshatty		case B_SAVE_REQUESTED:
403ed48868fSshatty			Save(message);
40431139022SAxel Dörfler			break;
40531139022SAxel Dörfler
406bed4e0fbSshatty		case SAVE_THEN_QUIT:
40731139022SAxel Dörfler			if (Save(message) == B_OK)
408bed4e0fbSshatty				Quit();
40931139022SAxel Dörfler			break;
41031139022SAxel Dörfler
411ed48868fSshatty		case MENU_REVERT:
412ed48868fSshatty			RevertToSaved();
41331139022SAxel Dörfler			break;
41431139022SAxel Dörfler
41531139022SAxel Dörfler		case MENU_CLOSE:
41631139022SAxel Dörfler			if (QuitRequested())
417ed48868fSshatty				Quit();
41831139022SAxel Dörfler			break;
41931139022SAxel Dörfler
420ed48868fSshatty		case MENU_PAGESETUP:
421ed48868fSshatty			PageSetup(fTextView->Window()->Title());
42231139022SAxel Dörfler			break;
423ed48868fSshatty		case MENU_PRINT:
424ed48868fSshatty			Print(fTextView->Window()->Title());
42531139022SAxel Dörfler			break;
426ed48868fSshatty		case MENU_QUIT:
427ed48868fSshatty			be_app->PostMessage(B_QUIT_REQUESTED);
42831139022SAxel Dörfler			break;
42931139022SAxel Dörfler
43031139022SAxel Dörfler		// Edit menu
43131139022SAxel Dörfler
432ed48868fSshatty		case B_UNDO:
433ed48868fSshatty			ASSERT(fCanUndo || fCanRedo);
434ed48868fSshatty			ASSERT(!(fCanUndo && fCanRedo));
43531139022SAxel Dörfler			if (fCanUndo)
436ed48868fSshatty				fUndoFlag = true;
43731139022SAxel Dörfler			if (fCanRedo)
438ed48868fSshatty				fRedoFlag = true;
43931139022SAxel Dörfler
440ed48868fSshatty			fTextView->Undo(be_clipboard);
44131139022SAxel Dörfler			break;
44214ea5e5eSKarsten Heimrich		case B_CUT:
443ed48868fSshatty			fTextView->Cut(be_clipboard);
44431139022SAxel Dörfler			break;
445ed48868fSshatty		case B_COPY:
446ed48868fSshatty			fTextView->Copy(be_clipboard);
44731139022SAxel Dörfler			break;
448ed48868fSshatty		case B_PASTE:
449ed48868fSshatty			fTextView->Paste(be_clipboard);
45031139022SAxel Dörfler			break;
45114ea5e5eSKarsten Heimrich		case MENU_CLEAR:
452ed48868fSshatty			fTextView->Clear();
45331139022SAxel Dörfler			break;
454ed48868fSshatty		case MENU_FIND:
45531139022SAxel Dörfler		{
45631139022SAxel Dörfler			BRect findWindowFrame(100, 100, 400, 235);
45731139022SAxel Dörfler			BWindow* window = new FindWindow(findWindowFrame, this,
458f303cd6cSRyan Leavengood				&fStringToFind, fCaseSens, fWrapAround, fBackSearch);
45931139022SAxel Dörfler			window->Show();
46031139022SAxel Dörfler			break;
46131139022SAxel Dörfler		}
462ed48868fSshatty		case MSG_SEARCH:
463ed48868fSshatty			message->FindString("findtext", &fStringToFind);
464aa9dc9eaSshatty			fFindAgainItem->SetEnabled(true);
465ed48868fSshatty			message->FindBool("casesens", &fCaseSens);
466ed48868fSshatty			message->FindBool("wrap", &fWrapAround);
467ed48868fSshatty			message->FindBool("backsearch", &fBackSearch);
46831139022SAxel Dörfler
469ed48868fSshatty			Search(fStringToFind, fCaseSens, fWrapAround, fBackSearch);
470f7afd44bSPhil Greenway			break;
471ed48868fSshatty		case MENU_FIND_AGAIN:
472ed48868fSshatty			Search(fStringToFind, fCaseSens, fWrapAround, fBackSearch);
47331139022SAxel Dörfler			break;
474ed48868fSshatty		case MENU_FIND_SELECTION:
475ed48868fSshatty			FindSelection();
47631139022SAxel Dörfler			break;
477ed48868fSshatty		case MENU_REPLACE:
47831139022SAxel Dörfler		{
47931139022SAxel Dörfler			BRect replaceWindowFrame(100, 100, 400, 284);
48031139022SAxel Dörfler			BWindow* window = new ReplaceWindow(replaceWindowFrame, this,
481f303cd6cSRyan Leavengood				&fStringToFind, &fReplaceString, fCaseSens, fWrapAround, fBackSearch);
48231139022SAxel Dörfler			window->Show();
48331139022SAxel Dörfler			break;
48431139022SAxel Dörfler		}
485ed48868fSshatty		case MSG_REPLACE:
486ed48868fSshatty		{
487f303cd6cSRyan Leavengood			message->FindBool("casesens", &fCaseSens);
488f303cd6cSRyan Leavengood			message->FindBool("wrap", &fWrapAround);
489f303cd6cSRyan Leavengood			message->FindBool("backsearch", &fBackSearch);
49031139022SAxel Dörfler
491f303cd6cSRyan Leavengood			message->FindString("FindText", &fStringToFind);
492f303cd6cSRyan Leavengood			message->FindString("ReplaceText", &fReplaceString);
49331139022SAxel Dörfler
494aa9dc9eaSshatty			fFindAgainItem->SetEnabled(true);
495aa9dc9eaSshatty			fReplaceSameItem->SetEnabled(true);
49631139022SAxel Dörfler
497f303cd6cSRyan Leavengood			Replace(fStringToFind, fReplaceString, fCaseSens, fWrapAround, fBackSearch);
49831139022SAxel Dörfler			break;
499ed48868fSshatty		}
500aa9dc9eaSshatty		case MENU_REPLACE_SAME:
501f303cd6cSRyan Leavengood			Replace(fStringToFind, fReplaceString, fCaseSens, fWrapAround, fBackSearch);
50231139022SAxel Dörfler			break;
50331139022SAxel Dörfler
504ed48868fSshatty		case MSG_REPLACE_ALL:
505ed48868fSshatty		{
506f303cd6cSRyan Leavengood			message->FindBool("casesens", &fCaseSens);
507f303cd6cSRyan Leavengood			message->FindString("FindText",&fStringToFind);
50814ea5e5eSKarsten Heimrich			message->FindString("ReplaceText",&fReplaceString);
50931139022SAxel Dörfler
510f303cd6cSRyan Leavengood			bool allWindows;
511ed48868fSshatty			message->FindBool("allwindows", &allWindows);
51231139022SAxel Dörfler
513aa9dc9eaSshatty			fFindAgainItem->SetEnabled(true);
514aa9dc9eaSshatty			fReplaceSameItem->SetEnabled(true);
51531139022SAxel Dörfler
51631139022SAxel Dörfler			if (allWindows)
517f303cd6cSRyan Leavengood				SearchAllWindows(fStringToFind, fReplaceString, fCaseSens);
51814ea5e5eSKarsten Heimrich			else
519f303cd6cSRyan Leavengood				ReplaceAll(fStringToFind, fReplaceString, fCaseSens);
52014ea5e5eSKarsten Heimrich			break;
52131139022SAxel Dörfler		}
52231139022SAxel Dörfler
52331139022SAxel Dörfler		// Font menu
52431139022SAxel Dörfler
525ed48868fSshatty		case FONT_SIZE:
526ed48868fSshatty		{
527ed48868fSshatty			float fontSize;
52831139022SAxel Dörfler			if (message->FindFloat("size", &fontSize) == B_OK)
52931139022SAxel Dörfler				SetFontSize(fontSize);
53031139022SAxel Dörfler			break;
531ed48868fSshatty		}
5328f63353bSshatty		case FONT_FAMILY:
53331139022SAxel Dörfler		{
53431139022SAxel Dörfler			const char* fontFamily = NULL;
53531139022SAxel Dörfler			const char* fontStyle = NULL;
53631139022SAxel Dörfler			void* ptr;
53731139022SAxel Dörfler			if (message->FindPointer("source", &ptr) == B_OK) {
53812483e3cSPhilippe Saint-Pierre				BMenuItem* item = static_cast<BMenuItem*>(ptr);
53912483e3cSPhilippe Saint-Pierre				fontFamily = item->Label();
5408f63353bSshatty			}
5418f63353bSshatty			SetFontStyle(fontFamily, fontStyle);
54231139022SAxel Dörfler			break;
54331139022SAxel Dörfler		}
544ed48868fSshatty		case FONT_STYLE:
54531139022SAxel Dörfler		{
54631139022SAxel Dörfler			const char* fontFamily = NULL;
54731139022SAxel Dörfler			const char* fontStyle = NULL;
54831139022SAxel Dörfler			void* ptr;
54931139022SAxel Dörfler			if (message->FindPointer("source", &ptr) == B_OK) {
55031139022SAxel Dörfler				BMenuItem* item = static_cast<BMenuItem*>(ptr);
5518f63353bSshatty				fontStyle = item->Label();
55231139022SAxel Dörfler				BMenu* menu = item->Menu();
55331139022SAxel Dörfler				if (menu != NULL) {
55412483e3cSPhilippe Saint-Pierre					BMenuItem* super_item = menu->Superitem();
55512483e3cSPhilippe Saint-Pierre					if (super_item != NULL)
55612483e3cSPhilippe Saint-Pierre						fontFamily = super_item->Label();
5578f63353bSshatty				}
5588f63353bSshatty			}
559ed48868fSshatty			SetFontStyle(fontFamily, fontStyle);
56031139022SAxel Dörfler			break;
56131139022SAxel Dörfler		}
562ed48868fSshatty		case FONT_COLOR:
563ed48868fSshatty		{
56431139022SAxel Dörfler			void* ptr;
56531139022SAxel Dörfler			if (message->FindPointer("source", &ptr) == B_OK) {
56631139022SAxel Dörfler				if (ptr == fBlackItem)
56787765587Sshatty					SetFontColor(&BLACK);
56831139022SAxel Dörfler				else if (ptr == fRedItem)
56987765587Sshatty					SetFontColor(&RED);
57031139022SAxel Dörfler				else if (ptr == fGreenItem)
57187765587Sshatty					SetFontColor(&GREEN);
57231139022SAxel Dörfler				else if (ptr == fBlueItem)
57387765587Sshatty					SetFontColor(&BLUE);
57431139022SAxel Dörfler				else if (ptr == fCyanItem)
57587765587Sshatty					SetFontColor(&CYAN);
57631139022SAxel Dörfler				else if (ptr == fMagentaItem)
57787765587Sshatty					SetFontColor(&MAGENTA);
57831139022SAxel Dörfler				else if (ptr == fYellowItem)
57987765587Sshatty					SetFontColor(&YELLOW);
58087765587Sshatty			}
58131139022SAxel Dörfler			break;
582ed48868fSshatty		}
58331139022SAxel Dörfler
58431139022SAxel Dörfler		// Document menu
58531139022SAxel Dörfler
586ed48868fSshatty		case ALIGN_LEFT:
5870b46ec98Sshatty			fTextView->SetAlignment(B_ALIGN_LEFT);
588f303cd6cSRyan Leavengood			_UpdateCleanUndoRedoSaveRevert();
58931139022SAxel Dörfler			break;
590ed48868fSshatty		case ALIGN_CENTER:
5910b46ec98Sshatty			fTextView->SetAlignment(B_ALIGN_CENTER);
592f303cd6cSRyan Leavengood			_UpdateCleanUndoRedoSaveRevert();
59331139022SAxel Dörfler			break;
594ed48868fSshatty		case ALIGN_RIGHT:
5950b46ec98Sshatty			fTextView->SetAlignment(B_ALIGN_RIGHT);
596f303cd6cSRyan Leavengood			_UpdateCleanUndoRedoSaveRevert();
59731139022SAxel Dörfler			break;
598ed48868fSshatty		case WRAP_LINES:
599f303cd6cSRyan Leavengood		{
600f303cd6cSRyan Leavengood			BRect textRect(fTextView->Bounds());
601f303cd6cSRyan Leavengood			textRect.OffsetTo(B_ORIGIN);
602f0da038eSAdrien Destugues			textRect.InsetBy(TEXT_INSET, TEXT_INSET);
6030b46ec98Sshatty			if (fTextView->DoesWordWrap()) {
604ed48868fSshatty				fTextView->SetWordWrap(false);
605ed48868fSshatty				fWrapItem->SetMarked(false);
6068f63353bSshatty				// the width comes from stylededit R5. TODO: find a better way
607f303cd6cSRyan Leavengood				textRect.SetRightBottom(BPoint(1500.0, textRect.RightBottom().y));
6080b46ec98Sshatty			} else {
609ed48868fSshatty				fTextView->SetWordWrap(true);
610ed48868fSshatty				fWrapItem->SetMarked(true);
611f303cd6cSRyan Leavengood			}
612f303cd6cSRyan Leavengood			fTextView->SetTextRect(textRect);
613f303cd6cSRyan Leavengood
614f303cd6cSRyan Leavengood			_UpdateCleanUndoRedoSaveRevert();
61531139022SAxel Dörfler			break;
616f303cd6cSRyan Leavengood		}
61731139022SAxel Dörfler		case ENABLE_ITEMS:
618ed48868fSshatty			fCutItem->SetEnabled(true);
619ed48868fSshatty			fCopyItem->SetEnabled(true);
620ed48868fSshatty			fClearItem->SetEnabled(true);
62131139022SAxel Dörfler			break;
62231139022SAxel Dörfler		case DISABLE_ITEMS:
623ed48868fSshatty			fCutItem->SetEnabled(false);
624ed48868fSshatty			fCopyItem->SetEnabled(false);
625ed48868fSshatty			fClearItem->SetEnabled(false);
62631139022SAxel Dörfler			break;
62731139022SAxel Dörfler		case TEXT_CHANGED:
6280b46ec98Sshatty			if (fUndoFlag) {
6290b46ec98Sshatty				if (fUndoCleans) {
6300b46ec98Sshatty					// we cleaned!
6310b46ec98Sshatty					fClean = true;
6320b46ec98Sshatty					fUndoCleans = false;
63314ea5e5eSKarsten Heimrich				} else if (fClean) {
634f0da038eSAdrien Destugues					// if we were clean
635f0da038eSAdrien Destugues					// then a redo will make us clean again
636f0da038eSAdrien Destugues					fRedoCleans = true;
637f0da038eSAdrien Destugues					fClean = false;
63814ea5e5eSKarsten Heimrich				}
6390b46ec98Sshatty				// set mode
6400b46ec98Sshatty				fCanUndo = false;
6410b46ec98Sshatty				fCanRedo = true;
642f0da038eSAdrien Destugues				fUndoItem->SetLabel(TR("Redo typing"));
6430b46ec98Sshatty				fUndoItem->SetEnabled(true);
6440b46ec98Sshatty				fUndoFlag = false;
6450b46ec98Sshatty			} else {
6460b46ec98Sshatty				if (fRedoFlag && fRedoCleans) {
6470b46ec98Sshatty					// we cleaned!
6480b46ec98Sshatty					fClean = true;
6490b46ec98Sshatty					fRedoCleans = false;
6500b46ec98Sshatty				} else if (fClean) {
6510b46ec98Sshatty					// if we were clean
6520b46ec98Sshatty					// then an undo will make us clean again
6530b46ec98Sshatty					fUndoCleans = true;
6540b46ec98Sshatty					fClean = false;
655ed48868fSshatty				} else {
6560b46ec98Sshatty					// no more cleaning from undo now...
6570b46ec98Sshatty					fUndoCleans = false;
658f7afd44bSPhil Greenway				}
6590b46ec98Sshatty				// set mode
6600b46ec98Sshatty				fCanUndo = true;
6610b46ec98Sshatty				fCanRedo = false;
662f0da038eSAdrien Destugues				fUndoItem->SetLabel(TR("Undo typing"));
6630b46ec98Sshatty				fUndoItem->SetEnabled(true);
6640b46ec98Sshatty				fRedoFlag = false;
665ed48868fSshatty			}
6660b46ec98Sshatty			if (fClean) {
6670b46ec98Sshatty				fRevertItem->SetEnabled(false);
66814ea5e5eSKarsten Heimrich				fSaveItem->SetEnabled(fSaveMessage == NULL);
6690b46ec98Sshatty			} else {
6700b46ec98Sshatty				fRevertItem->SetEnabled(fSaveMessage != NULL);
6710b46ec98Sshatty				fSaveItem->SetEnabled(true);
67231139022SAxel Dörfler			}
67331139022SAxel Dörfler			break;
67431139022SAxel Dörfler
6750b2e176dSshatty		case SAVE_AS_ENCODING:
67631139022SAxel Dörfler			void* ptr;
67731139022SAxel Dörfler			if (message->FindPointer("source", &ptr) == B_OK
67831139022SAxel Dörfler				&& fSavePanelEncodingMenu != NULL) {
679f0da038eSAdrien Destugues				fTextView->SetEncoding(
680f0da038eSAdrien Destugues					(uint32)fSavePanelEncodingMenu->IndexOf((BMenuItem*)ptr));
6810b2e176dSshatty			}
68231139022SAxel Dörfler			break;
68331139022SAxel Dörfler
684ed48868fSshatty		default:
68531139022SAxel Dörfler			BWindow::MessageReceived(message);
68631139022SAxel Dörfler			break;
687ed48868fSshatty	}
68831139022SAxel Dörfler}
68931139022SAxel Dörfler
690ed48868fSshatty
691a445cd42Sshattyvoid
692a445cd42SshattyStyledEditWindow::MenusBeginning()
693a445cd42Sshatty{
69487765587Sshatty	// set up the recent documents menu
695a445cd42Sshatty	BMessage documents;
69631139022SAxel Dörfler	be_roster->GetRecentDocuments(&documents, 9, NULL, APP_SIGNATURE);
69731139022SAxel Dörfler
69814ea5e5eSKarsten Heimrich	// delete old items..
699a445cd42Sshatty	//    shatty: it would be preferable to keep the old
700a445cd42Sshatty	//            menu around instead of continuously thrashing
701a445cd42Sshatty	//            the menu, but unfortunately there does not
702a445cd42Sshatty	//            seem to be a straightforward way to update it
703a445cd42Sshatty	// going backwards may simplify memory management
70431139022SAxel Dörfler	for (int i = fRecentMenu->CountItems(); i-- > 0;) {
705a445cd42Sshatty		delete fRecentMenu->RemoveItem(i);
706a445cd42Sshatty	}
70731139022SAxel Dörfler
708a445cd42Sshatty	// add new items
709a445cd42Sshatty	int count = 0;
710a445cd42Sshatty	entry_ref ref;
71131139022SAxel Dörfler	while (documents.FindRef("refs", count++, &ref) == B_OK) {
71231139022SAxel Dörfler		if (ref.device != -1 && ref.directory != -1) {
7134fd52066Sshatty			// sanity check passed
71431139022SAxel Dörfler			BMessage* openRecent = new BMessage(B_REFS_RECEIVED);
71531139022SAxel Dörfler			openRecent->AddRef("refs", &ref);
71631139022SAxel Dörfler			BMenuItem* item = new BMenuItem(ref.name, openRecent);
7174fd52066Sshatty			item->SetTarget(be_app);
7184fd52066Sshatty			fRecentMenu->AddItem(item);
7194fd52066Sshatty		}
720a445cd42Sshatty	}
72131139022SAxel Dörfler
72231139022SAxel Dörfler	// update the font menu
72387765587Sshatty	// unselect the old values
72412483e3cSPhilippe Saint-Pierre	if (fCurrentFontItem != NULL) {
725d470934cSshatty		fCurrentFontItem->SetMarked(false);
72612483e3cSPhilippe Saint-Pierre		BMenu* menu = fCurrentFontItem->Submenu();
72712483e3cSPhilippe Saint-Pierre		if (menu != NULL) {
72812483e3cSPhilippe Saint-Pierre			BMenuItem* item = menu->FindMarked();
72912483e3cSPhilippe Saint-Pierre			if (item != NULL) {
73012483e3cSPhilippe Saint-Pierre				item->SetMarked(false);
73112483e3cSPhilippe Saint-Pierre			}
73212483e3cSPhilippe Saint-Pierre		}
73312483e3cSPhilippe Saint-Pierre	}
73412483e3cSPhilippe Saint-Pierre
73512483e3cSPhilippe Saint-Pierre	if (fCurrentStyleItem != NULL) {
73612483e3cSPhilippe Saint-Pierre		fCurrentStyleItem->SetMarked(false);
73712483e3cSPhilippe Saint-Pierre	}
73831139022SAxel Dörfler
73931139022SAxel Dörfler	BMenuItem* oldColorItem = fFontColorMenu->FindMarked();
74031139022SAxel Dörfler	if (oldColorItem != NULL)
74187765587Sshatty		oldColorItem->SetMarked(false);
74231139022SAxel Dörfler
74331139022SAxel Dörfler	BMenuItem* oldSizeItem = fFontSizeMenu->FindMarked();
74431139022SAxel Dörfler	if (oldSizeItem != NULL)
74587765587Sshatty		oldSizeItem->SetMarked(false);
74631139022SAxel Dörfler
74714ea5e5eSKarsten Heimrich	// find the current font, color, size
74887765587Sshatty	BFont font;
74987765587Sshatty	uint32 sameProperties;
75087765587Sshatty	rgb_color color = BLACK;
75187765587Sshatty	bool sameColor;
75231139022SAxel Dörfler	fTextView->GetFontAndColor(&font, &sameProperties, &color, &sameColor);
75331139022SAxel Dörfler
75431139022SAxel Dörfler	if (sameColor && color.alpha == 255) {
755d470934cSshatty		// select the current color
75687765587Sshatty		if (color.red == 0) {
75787765587Sshatty			if (color.green == 0) {
75887765587Sshatty				if (color.blue == 0) {
75987765587Sshatty					fBlackItem->SetMarked(true);
76087765587Sshatty				} else if (color.blue == 255) {
76187765587Sshatty					fBlueItem->SetMarked(true);
76287765587Sshatty				}
76387765587Sshatty			} else if (color.green == 255) {
76487765587Sshatty				if (color.blue == 0) {
76587765587Sshatty					fGreenItem->SetMarked(true);
76687765587Sshatty				} else if (color.blue == 255) {
76787765587Sshatty					fCyanItem->SetMarked(true);
76887765587Sshatty				}
76987765587Sshatty			}
77087765587Sshatty		} else if (color.red == 255) {
77187765587Sshatty			if (color.green == 0) {
77287765587Sshatty				if (color.blue == 0) {
77387765587Sshatty					fRedItem->SetMarked(true);
77487765587Sshatty				} else if (color.blue == 255) {
77587765587Sshatty					fMagentaItem->SetMarked(true);
77687765587Sshatty				}
77787765587Sshatty			} else if (color.green == 255) {
77887765587Sshatty				if (color.blue == 0) {
77987765587Sshatty					fYellowItem->SetMarked(true);
78087765587Sshatty				}
78187765587Sshatty			}
78214ea5e5eSKarsten Heimrich		}
78387765587Sshatty	}
78431139022SAxel Dörfler
785d470934cSshatty	if (sameProperties & B_FONT_SIZE) {
786d470934cSshatty		if ((int)font.Size() == font.Size()) {
787d470934cSshatty			// select the current font size
788d470934cSshatty			char fontSizeStr[16];
78931139022SAxel Dörfler			snprintf(fontSizeStr, 15, "%i", (int)font.Size());
79031139022SAxel Dörfler			BMenuItem* item = fFontSizeMenu->FindItem(fontSizeStr);
79131139022SAxel Dörfler			if (item != NULL)
792d470934cSshatty				item->SetMarked(true);
793d470934cSshatty		}
794d470934cSshatty	}
79531139022SAxel Dörfler
79612483e3cSPhilippe Saint-Pierre	font_family family;
79712483e3cSPhilippe Saint-Pierre	font_style style;
79812483e3cSPhilippe Saint-Pierre	font.GetFamilyAndStyle(&family, &style);
79912483e3cSPhilippe Saint-Pierre
80012483e3cSPhilippe Saint-Pierre	fCurrentFontItem = fFontMenu->FindItem(family);
80112483e3cSPhilippe Saint-Pierre
80212483e3cSPhilippe Saint-Pierre	if (fCurrentFontItem != NULL) {
80312483e3cSPhilippe Saint-Pierre		fCurrentFontItem->SetMarked(true);
80412483e3cSPhilippe Saint-Pierre		BMenu* menu = fCurrentFontItem->Submenu();
80512483e3cSPhilippe Saint-Pierre		if (menu != NULL) {
80612483e3cSPhilippe Saint-Pierre			BMenuItem* item = menu->FindItem(style);
80712483e3cSPhilippe Saint-Pierre			fCurrentStyleItem = item;
80812483e3cSPhilippe Saint-Pierre			if (fCurrentStyleItem != NULL) {
80912483e3cSPhilippe Saint-Pierre				item->SetMarked(true);
810d470934cSshatty			}
811d470934cSshatty		}
812d470934cSshatty	}
81331139022SAxel Dörfler
8149e159bcfSshatty	switch (fTextView->Alignment()) {
81531139022SAxel Dörfler		case B_ALIGN_LEFT:
81631139022SAxel Dörfler		default:
81731139022SAxel Dörfler			fAlignLeft->SetMarked(true);
81831139022SAxel Dörfler			break;
81931139022SAxel Dörfler		case B_ALIGN_CENTER:
82031139022SAxel Dörfler			fAlignCenter->SetMarked(true);
82131139022SAxel Dörfler			break;
82231139022SAxel Dörfler		case B_ALIGN_RIGHT:
82331139022SAxel Dörfler			fAlignRight->SetMarked(true);
82431139022SAxel Dörfler			break;
8259e159bcfSshatty	}
826a445cd42Sshatty}
827ed48868fSshatty
82831139022SAxel Dörfler
829ed48868fSshattyvoid
830ed48868fSshattyStyledEditWindow::Quit()
831ed48868fSshatty{
832a723b3d4SAxel Dörfler	SaveAttrs();
83314ea5e5eSKarsten Heimrich	styled_edit_app->CloseDocument();
834ed48868fSshatty	BWindow::Quit();
835ed48868fSshatty}
83631139022SAxel Dörfler
83731139022SAxel Dörfler
838f0da038eSAdrien Destugues// This is temporary solution for building BString with printf like format.
839f0da038eSAdrien Destugues// will be removed in the future.
840f0da038eSAdrien Destuguesstatic void
841f0da038eSAdrien Destuguesbs_printf(BString* string, const char* format, ...)
842f0da038eSAdrien Destugues{
843f0da038eSAdrien Destugues	va_list 	ap;
844f0da038eSAdrien Destugues	va_start(ap, format);
845f0da038eSAdrien Destugues	char*	buf;
846f0da038eSAdrien Destugues	vasprintf(&buf, format, ap);
847f0da038eSAdrien Destugues	string->SetTo(buf);
848f0da038eSAdrien Destugues	free(buf);
849f0da038eSAdrien Destugues	va_end(ap);
850f0da038eSAdrien Destugues}
851f0da038eSAdrien Destugues
852f0da038eSAdrien Destugues
853f0da038eSAdrien Destugues#undef TR_CONTEXT
854f0da038eSAdrien Destugues#define TR_CONTEXT "QuitAlert"
855f0da038eSAdrien Destugues
856a723b3d4SAxel Dörfler
857ed48868fSshattybool
858ed48868fSshattyStyledEditWindow::QuitRequested()
859ed48868fSshatty{
86031139022SAxel Dörfler	if (fClean)
86131139022SAxel Dörfler		return true;
862ed48868fSshatty
863f0da038eSAdrien Destugues	BString alertText;
864f0da038eSAdrien Destugues	bs_printf(&alertText, TR("Save changes to the document \"%s\"? "), Title());
865a723b3d4SAxel Dörfler
866f0da038eSAdrien Destugues	int32 index = _ShowAlert(alertText, TR("Cancel"), TR("Don't save"), TR("Save"),
86710c45684SKarsten Heimrich		B_WARNING_ALERT);
86810c45684SKarsten Heimrich
86910c45684SKarsten Heimrich	if (index == 0)
87010c45684SKarsten Heimrich		return false;	// "cancel": dont save, dont close the window
871f5c4a083SAxel Dörfler
87210c45684SKarsten Heimrich	if (index == 1)
87310c45684SKarsten Heimrich		return true;	// "don't save": just close the window
874f5c4a083SAxel Dörfler
87510c45684SKarsten Heimrich	if (!fSaveMessage) {
87610c45684SKarsten Heimrich		SaveAs(new BMessage(SAVE_THEN_QUIT));
877bed4e0fbSshatty		return false;
878ed48868fSshatty	}
87931139022SAxel Dörfler
88031139022SAxel Dörfler	return Save() == B_OK;
88131139022SAxel Dörfler}
88231139022SAxel Dörfler
88331139022SAxel Dörfler
884f0da038eSAdrien Destugues#undef TR_CONTEXT
885f0da038eSAdrien Destugues#define TR_CONTEXT "SaveAlert"
886f0da038eSAdrien Destugues
887a723b3d4SAxel Dörfler
888ed48868fSshattystatus_t
889f0da038eSAdrien DestuguesStyledEditWindow::Save(BMessage* message)
890ed48868fSshatty{
89110c45684SKarsten Heimrich	if (!message)
89231139022SAxel Dörfler		message = fSaveMessage;
893f5c4a083SAxel Dörfler
89410c45684SKarsten Heimrich	if (!message)
89510c45684SKarsten Heimrich		return B_ERROR;
89631139022SAxel Dörfler
89731139022SAxel Dörfler	entry_ref dirRef;
89831139022SAxel Dörfler	const char* name;
89910c45684SKarsten Heimrich	if (message->FindRef("directory", &dirRef) != B_OK
90010c45684SKarsten Heimrich		|| message->FindString("name", &name) != B_OK)
90110c45684SKarsten Heimrich		return B_BAD_VALUE;
90231139022SAxel Dörfler
90331139022SAxel Dörfler	BDirectory dir(&dirRef);
904a445cd42Sshatty	BEntry entry(&dir, name);
905f5c4a083SAxel Dörfler
90610c45684SKarsten Heimrich	status_t status = B_ERROR;
90710c45684SKarsten Heimrich	if (dir.InitCheck() == B_OK && entry.InitCheck() == B_OK) {
90877b20801SJérôme Duval		struct stat st;
90910c45684SKarsten Heimrich		BFile file(&entry, B_READ_WRITE | B_CREATE_FILE);
91077b20801SJérôme Duval		if (file.InitCheck() == B_OK
91177b20801SJérôme Duval			&& (status = file.GetStat(&st)) == B_OK) {
91277b20801SJérôme Duval			// check the file permissions
91377b20801SJérôme Duval			if (!((getuid() == st.st_uid && (S_IWUSR & st.st_mode))
91477b20801SJérôme Duval				|| (getgid() == st.st_gid && (S_IWGRP & st.st_mode))
91577b20801SJérôme Duval				|| (S_IWOTH & st.st_mode))) {
91677b20801SJérôme Duval				BString alertText;
91777b20801SJérôme Duval				bs_printf(&alertText, TR("This file is marked Read-Only. "
91877b20801SJérôme Duval					"Save changes to the document \"%s\"? "), name);
91977b20801SJérôme Duval				switch (_ShowAlert(alertText, TR("Cancel"), TR("Don't save"),
92077b20801SJérôme Duval					TR("Save"), B_WARNING_ALERT)) {
92177b20801SJérôme Duval					case 0:
92277b20801SJérôme Duval						return B_CANCELED;
92377b20801SJérôme Duval					case 1:
92477b20801SJérôme Duval						return B_OK;
92577b20801SJérôme Duval					default:
92677b20801SJérôme Duval						break;