StyledEditWindow.cpp revision e62d9cf8
131139022SAxel Dörfler/*
20cc8d8abSSiarzhuk Zharski * Copyright 2002-2012, 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
105d67e2baSRyan Leavengood *		Ryan Leavengood
110cc8d8abSSiarzhuk Zharski *		Vlad Slepukhin
120cc8d8abSSiarzhuk Zharski *		Sarzhuk Zharski
1331139022SAxel Dörfler */
1431139022SAxel Dörfler
15a723b3d4SAxel Dörfler
1631139022SAxel Dörfler#include "ColorMenuItem.h"
170f4985d8SVlad Slepukhin#include "Constants.h"
1831139022SAxel Dörfler#include "FindWindow.h"
1931139022SAxel Dörfler#include "ReplaceWindow.h"
200f4985d8SVlad Slepukhin#include "StatusView.h"
2131139022SAxel Dörfler#include "StyledEditApp.h"
2231139022SAxel Dörfler#include "StyledEditView.h"
2331139022SAxel Dörfler#include "StyledEditWindow.h"
24f7afd44bSPhil Greenway
25f7afd44bSPhil Greenway#include <Alert.h>
26ed48868fSshatty#include <Autolock.h>
27f0da038eSAdrien Destugues#include <Catalog.h>
28f303cd6cSRyan Leavengood#include <CharacterSet.h>
29f303cd6cSRyan Leavengood#include <CharacterSetRoster.h>
30f7afd44bSPhil Greenway#include <Clipboard.h>
31f303cd6cSRyan Leavengood#include <Debug.h>
32f7afd44bSPhil Greenway#include <File.h>
33f303cd6cSRyan Leavengood#include <FilePanel.h>
34a723b3d4SAxel Dörfler#include <fs_attr.h>
35f0da038eSAdrien Destugues#include <Locale.h>
36f7afd44bSPhil Greenway#include <Menu.h>
37f303cd6cSRyan Leavengood#include <MenuBar.h>
38f7afd44bSPhil Greenway#include <MenuItem.h>
390cc8d8abSSiarzhuk Zharski#include <NodeMonitor.h>
4013e9a630SJonas Sundström#include <Path.h>
41f7afd44bSPhil Greenway#include <PrintJob.h>
42e056d320SFreeman Lou#include <RecentItems.h>
43f303cd6cSRyan Leavengood#include <Rect.h>
44b40c9906SRyan Leavengood#include <Roster.h>
459bf722bdSAxel Dörfler#include <Screen.h>
46f7afd44bSPhil Greenway#include <ScrollView.h>
47844ea151Sshatty#include <TextControl.h>
48f303cd6cSRyan Leavengood#include <TextView.h>
49f7afd44bSPhil Greenway#include <TranslationUtils.h>
5015d26d2cSAxel Dörfler#include <UnicodeChar.h>
51f8668ab4SSiarzhuk Zharski#include <UTF8.h>
5242cb481fSSiarzhuk Zharski#include <Volume.h>
53f7afd44bSPhil Greenway
549bf722bdSAxel Dörfler
5546555d8fSshattyusing namespace BPrivate;
5646555d8fSshatty
57ff99f481SAxel Dörfler
588e26769cSRene Gollentconst float kLineViewWidth = 30.0;
59c92efcc0SAxel Dörflerconst char* kInfoAttributeName = "StyledEdit-info";
6031139022SAxel Dörfler
61a723b3d4SAxel Dörfler
62546208a5SOliver Tappe#undef B_TRANSLATION_CONTEXT
63546208a5SOliver Tappe#define B_TRANSLATION_CONTEXT "StyledEditWindow"
64ff99f481SAxel Dörfler
65a723b3d4SAxel Dörfler
669bf722bdSAxel Dörfler// This is a temporary solution for building BString with printf like format.
679bf722bdSAxel Dörfler// will be removed in the future.
689bf722bdSAxel Dörflerstatic void
699bf722bdSAxel Dörflerbs_printf(BString* string, const char* format, ...)
709bf722bdSAxel Dörfler{
719bf722bdSAxel Dörfler	va_list ap;
729bf722bdSAxel Dörfler	va_start(ap, format);
739bf722bdSAxel Dörfler	char* buf;
749bf722bdSAxel Dörfler	vasprintf(&buf, format, ap);
759bf722bdSAxel Dörfler	string->SetTo(buf);
769bf722bdSAxel Dörfler	free(buf);
779bf722bdSAxel Dörfler	va_end(ap);
789bf722bdSAxel Dörfler}
799bf722bdSAxel Dörfler
809bf722bdSAxel Dörfler
819bf722bdSAxel Dörfler// #pragma mark -
829bf722bdSAxel Dörfler
839bf722bdSAxel Dörfler
84670567f9SshattyStyledEditWindow::StyledEditWindow(BRect frame, int32 id, uint32 encoding)
85e62d9cf8SPhilippe Saint-Pierre	:
86e62d9cf8SPhilippe Saint-Pierre	BWindow(frame, "untitled", B_DOCUMENT_WINDOW, B_ASYNCHRONOUS_CONTROLS),
87e62d9cf8SPhilippe Saint-Pierre	fFindWindow(NULL),
88e62d9cf8SPhilippe Saint-Pierre	fReplaceWindow(NULL)
89ed48868fSshatty{
905188c282SAxel Dörfler	_InitWindow(encoding);
91906db303SMatt Madia	BString unTitled(B_TRANSLATE("Untitled "));
92ed48868fSshatty	unTitled << id;
93ed48868fSshatty	SetTitle(unTitled.String());
9431139022SAxel Dörfler	fSaveItem->SetEnabled(true);
9531139022SAxel Dörfler		// allow saving empty files
96ed48868fSshatty	Show();
9731139022SAxel Dörfler}
9831139022SAxel Dörfler
99f7afd44bSPhil Greenway
100f0da038eSAdrien DestuguesStyledEditWindow::StyledEditWindow(BRect frame, entry_ref* ref, uint32 encoding)
101e62d9cf8SPhilippe Saint-Pierre	:
102e62d9cf8SPhilippe Saint-Pierre	BWindow(frame, "untitled", B_DOCUMENT_WINDOW, B_ASYNCHRONOUS_CONTROLS),
103e62d9cf8SPhilippe Saint-Pierre	fFindWindow(NULL),
104e62d9cf8SPhilippe Saint-Pierre	fReplaceWindow(NULL)
105ed48868fSshatty{
1065188c282SAxel Dörfler	_InitWindow(encoding);
107ed48868fSshatty	OpenFile(ref);
108ed48868fSshatty	Show();
10931139022SAxel Dörfler}
11031139022SAxel Dörfler
11131139022SAxel Dörfler
112ed48868fSshattyStyledEditWindow::~StyledEditWindow()
113ed48868fSshatty{
114d727a85bSshatty	delete fSaveMessage;
115d727a85bSshatty	delete fPrintSettings;
116f7afd44bSPhil Greenway	delete fSavePanel;
11731139022SAxel Dörfler}
11831139022SAxel Dörfler
11931139022SAxel Dörfler
1205188c282SAxel Dörflervoid
1215188c282SAxel DörflerStyledEditWindow::Quit()
1225188c282SAxel Dörfler{
1230cc8d8abSSiarzhuk Zharski	_SwitchNodeMonitor(false);
1240cc8d8abSSiarzhuk Zharski
1255188c282SAxel Dörfler	_SaveAttrs();
1265188c282SAxel Dörfler	if (StyledEditApp* app = dynamic_cast<StyledEditApp*>(be_app))
1275188c282SAxel Dörfler		app->CloseDocument();
1285188c282SAxel Dörfler	BWindow::Quit();
1295188c282SAxel Dörfler}
1305188c282SAxel Dörfler
1315188c282SAxel Dörfler
132546208a5SOliver Tappe#undef B_TRANSLATION_CONTEXT
133546208a5SOliver Tappe#define B_TRANSLATION_CONTEXT "QuitAlert"
134f0da038eSAdrien Destugues
135a723b3d4SAxel Dörfler
1365188c282SAxel Dörflerbool
1375188c282SAxel DörflerStyledEditWindow::QuitRequested()
138ed48868fSshatty{
1395188c282SAxel Dörfler	if (fClean)
1405188c282SAxel Dörfler		return true;
14131139022SAxel Dörfler
1420cc8d8abSSiarzhuk Zharski	if (fTextView->TextLength() == 0 && fSaveMessage == NULL)
1430cc8d8abSSiarzhuk Zharski		return true;
1440cc8d8abSSiarzhuk Zharski
1455188c282SAxel Dörfler	BString alertText;
1465188c282SAxel Dörfler	bs_printf(&alertText,
1475188c282SAxel Dörfler		B_TRANSLATE("Save changes to the document \"%s\"? "), Title());
14831139022SAxel Dörfler
1495188c282SAxel Dörfler	int32 index = _ShowAlert(alertText, B_TRANSLATE("Cancel"),
1505188c282SAxel Dörfler		B_TRANSLATE("Don't save"), B_TRANSLATE("Save"),	B_WARNING_ALERT);
15131139022SAxel Dörfler
1525188c282SAxel Dörfler	if (index == 0)
1535188c282SAxel Dörfler		return false;	// "cancel": dont save, dont close the window
15431139022SAxel Dörfler
1555188c282SAxel Dörfler	if (index == 1)
1565188c282SAxel Dörfler		return true;	// "don't save": just close the window
157f7afd44bSPhil Greenway
1585188c282SAxel Dörfler	if (!fSaveMessage) {
1595188c282SAxel Dörfler		SaveAs(new BMessage(SAVE_THEN_QUIT));
1605188c282SAxel Dörfler		return false;
1615188c282SAxel Dörfler	}
16231139022SAxel Dörfler
1635188c282SAxel Dörfler	return Save() == B_OK;
1645188c282SAxel Dörfler}
16514ea5e5eSKarsten Heimrich
16631139022SAxel Dörfler
1675188c282SAxel Dörflervoid
1685188c282SAxel DörflerStyledEditWindow::MessageReceived(BMessage* message)
1695188c282SAxel Dörfler{
1705188c282SAxel Dörfler	if (message->WasDropped()) {
1715188c282SAxel Dörfler		entry_ref ref;
1725188c282SAxel Dörfler		if (message->FindRef("refs", 0, &ref)==B_OK) {
1735188c282SAxel Dörfler			message->what = B_REFS_RECEIVED;
1745188c282SAxel Dörfler			be_app->PostMessage(message);
1755188c282SAxel Dörfler		}
1765188c282SAxel Dörfler	}
17731139022SAxel Dörfler
1785188c282SAxel Dörfler	switch (message->what) {
1795188c282SAxel Dörfler		// File menu
1805188c282SAxel Dörfler		case MENU_SAVE:
1815188c282SAxel Dörfler			if (!fSaveMessage)
1825188c282SAxel Dörfler				SaveAs();
1835188c282SAxel Dörfler			else
1845188c282SAxel Dörfler				Save(fSaveMessage);
1855188c282SAxel Dörfler			break;
186a723b3d4SAxel Dörfler
1875188c282SAxel Dörfler		case MENU_SAVEAS:
1885188c282SAxel Dörfler			SaveAs();
1895188c282SAxel Dörfler			break;
19031139022SAxel Dörfler
1915188c282SAxel Dörfler		case B_SAVE_REQUESTED:
1925188c282SAxel Dörfler			Save(message);
1935188c282SAxel Dörfler			break;
19414ea5e5eSKarsten Heimrich
1955188c282SAxel Dörfler		case SAVE_THEN_QUIT:
1965188c282SAxel Dörfler			if (Save(message) == B_OK)
1975188c282SAxel Dörfler				Quit();
1985188c282SAxel Dörfler			break;
19931139022SAxel Dörfler
2000cc8d8abSSiarzhuk Zharski		case MENU_RELOAD:
2010cc8d8abSSiarzhuk Zharski			_ReloadDocument(message);
2025188c282SAxel Dörfler			break;
20331139022SAxel Dörfler
2045188c282SAxel Dörfler		case MENU_CLOSE:
2055188c282SAxel Dörfler			if (QuitRequested())
2065188c282SAxel Dörfler				Quit();
2075188c282SAxel Dörfler			break;
20831139022SAxel Dörfler
2095188c282SAxel Dörfler		case MENU_PAGESETUP:
2105188c282SAxel Dörfler			PageSetup(fTextView->Window()->Title());
2115188c282SAxel Dörfler			break;
2125188c282SAxel Dörfler		case MENU_PRINT:
2135188c282SAxel Dörfler			Print(fTextView->Window()->Title());
2145188c282SAxel Dörfler			break;
2155188c282SAxel Dörfler		case MENU_QUIT:
2165188c282SAxel Dörfler			be_app->PostMessage(B_QUIT_REQUESTED);
2175188c282SAxel Dörfler			break;
21831139022SAxel Dörfler
2195188c282SAxel Dörfler		// Edit menu
22031139022SAxel Dörfler
2215188c282SAxel Dörfler		case B_UNDO:
2225188c282SAxel Dörfler			ASSERT(fCanUndo || fCanRedo);
2235188c282SAxel Dörfler			ASSERT(!(fCanUndo && fCanRedo));
2245188c282SAxel Dörfler			if (fCanUndo)
2255188c282SAxel Dörfler				fUndoFlag = true;
2265188c282SAxel Dörfler			if (fCanRedo)
2275188c282SAxel Dörfler				fRedoFlag = true;
22831139022SAxel Dörfler
2295188c282SAxel Dörfler			fTextView->Undo(be_clipboard);
2305188c282SAxel Dörfler			break;
2315188c282SAxel Dörfler		case B_CUT:
2325188c282SAxel Dörfler			fTextView->Cut(be_clipboard);
2335188c282SAxel Dörfler			break;
2345188c282SAxel Dörfler		case B_COPY:
2355188c282SAxel Dörfler			fTextView->Copy(be_clipboard);
2365188c282SAxel Dörfler			break;
2375188c282SAxel Dörfler		case B_PASTE:
2385188c282SAxel Dörfler			fTextView->Paste(be_clipboard);
2395188c282SAxel Dörfler			break;
2405188c282SAxel Dörfler		case MENU_CLEAR:
2415188c282SAxel Dörfler			fTextView->Clear();
2425188c282SAxel Dörfler			break;
2435188c282SAxel Dörfler		case MENU_FIND:
2445188c282SAxel Dörfler		{
245579c4d6eSEzo			if (fFindWindow == NULL) {
246579c4d6eSEzo				BRect findWindowFrame(Frame());
247579c4d6eSEzo				findWindowFrame.InsetBy(
248579c4d6eSEzo					(findWindowFrame.Width() - 400) / 2,
249579c4d6eSEzo					(findWindowFrame.Height() - 235) / 2);
250579c4d6eSEzo
251579c4d6eSEzo				fFindWindow = new FindWindow(findWindowFrame, this,
252579c4d6eSEzo					&fStringToFind, fCaseSensitive, fWrapAround, fBackSearch);
253579c4d6eSEzo				fFindWindow->Show();
254579c4d6eSEzo
255579c4d6eSEzo			} else if (fFindWindow->IsHidden())
256579c4d6eSEzo				fFindWindow->Show();
257579c4d6eSEzo			else
258579c4d6eSEzo				fFindWindow->Activate();
2595188c282SAxel Dörfler			break;
2605188c282SAxel Dörfler		}
26185ce1385SRene Gollent		case MSG_FIND_WINDOW_QUIT:
26285ce1385SRene Gollent		{
26385ce1385SRene Gollent			fFindWindow = NULL;
26485ce1385SRene Gollent			break;
26585ce1385SRene Gollent		}
2665188c282SAxel Dörfler		case MSG_SEARCH:
2675188c282SAxel Dörfler			message->FindString("findtext", &fStringToFind);
2685188c282SAxel Dörfler			fFindAgainItem->SetEnabled(true);
2695188c282SAxel Dörfler			message->FindBool("casesens", &fCaseSensitive);
2705188c282SAxel Dörfler			message->FindBool("wrap", &fWrapAround);
2715188c282SAxel Dörfler			message->FindBool("backsearch", &fBackSearch);
27231139022SAxel Dörfler
2735188c282SAxel Dörfler			_Search(fStringToFind, fCaseSensitive, fWrapAround, fBackSearch);
2745188c282SAxel Dörfler			break;
2755188c282SAxel Dörfler		case MENU_FIND_AGAIN:
2765188c282SAxel Dörfler			_Search(fStringToFind, fCaseSensitive, fWrapAround, fBackSearch);
2775188c282SAxel Dörfler			break;
2785188c282SAxel Dörfler		case MENU_FIND_SELECTION:
2795188c282SAxel Dörfler			_FindSelection();
2805188c282SAxel Dörfler			break;
2815188c282SAxel Dörfler		case MENU_REPLACE:
2825188c282SAxel Dörfler		{
283579c4d6eSEzo			if (fReplaceWindow == NULL) {
284579c4d6eSEzo				BRect replaceWindowFrame(Frame());
285579c4d6eSEzo				replaceWindowFrame.InsetBy(
286579c4d6eSEzo					(replaceWindowFrame.Width() - 400) / 2,
287579c4d6eSEzo					(replaceWindowFrame.Height() - 284) / 2);
288579c4d6eSEzo
289579c4d6eSEzo				fReplaceWindow = new ReplaceWindow(replaceWindowFrame, this,
290579c4d6eSEzo					&fStringToFind, &fReplaceString, fCaseSensitive,
291579c4d6eSEzo					fWrapAround, fBackSearch);
292579c4d6eSEzo				fReplaceWindow->Show();
293579c4d6eSEzo
294579c4d6eSEzo			} else if (fReplaceWindow->IsHidden())
295579c4d6eSEzo				fReplaceWindow->Show();
296579c4d6eSEzo			else
297579c4d6eSEzo				fReplaceWindow->Activate();
2985188c282SAxel Dörfler			break;
2995188c282SAxel Dörfler		}
3005188c282SAxel Dörfler		case MSG_REPLACE:
3015188c282SAxel Dörfler		{
3025188c282SAxel Dörfler			message->FindBool("casesens", &fCaseSensitive);
3035188c282SAxel Dörfler			message->FindBool("wrap", &fWrapAround);
3045188c282SAxel Dörfler			message->FindBool("backsearch", &fBackSearch);
305f7afd44bSPhil Greenway
3065188c282SAxel Dörfler			message->FindString("FindText", &fStringToFind);
3075188c282SAxel Dörfler			message->FindString("ReplaceText", &fReplaceString);
308f7afd44bSPhil Greenway
3095188c282SAxel Dörfler			fFindAgainItem->SetEnabled(true);
3105188c282SAxel Dörfler			fReplaceSameItem->SetEnabled(true);
31131139022SAxel Dörfler
3125188c282SAxel Dörfler			_Replace(fStringToFind, fReplaceString, fCaseSensitive, fWrapAround,
3135188c282SAxel Dörfler				fBackSearch);
3145188c282SAxel Dörfler			break;
3155188c282SAxel Dörfler		}
3165188c282SAxel Dörfler		case MENU_REPLACE_SAME:
3175188c282SAxel Dörfler			_Replace(fStringToFind, fReplaceString, fCaseSensitive, fWrapAround,
3185188c282SAxel Dörfler				fBackSearch);
3195188c282SAxel Dörfler			break;
32031139022SAxel Dörfler
3215188c282SAxel Dörfler		case MSG_REPLACE_ALL:
3225188c282SAxel Dörfler		{
3235188c282SAxel Dörfler			message->FindBool("casesens", &fCaseSensitive);
3248a85cd4cSSiarzhuk Zharski			message->FindString("FindText", &fStringToFind);
3258a85cd4cSSiarzhuk Zharski			message->FindString("ReplaceText", &fReplaceString);
32631139022SAxel Dörfler
3275188c282SAxel Dörfler			bool allWindows;
3285188c282SAxel Dörfler			message->FindBool("allwindows", &allWindows);
32931139022SAxel Dörfler
3305188c282SAxel Dörfler			fFindAgainItem->SetEnabled(true);
3315188c282SAxel Dörfler			fReplaceSameItem->SetEnabled(true);
33231139022SAxel Dörfler
3335188c282SAxel Dörfler			if (allWindows)
3345188c282SAxel Dörfler				SearchAllWindows(fStringToFind, fReplaceString, fCaseSensitive);
3355188c282SAxel Dörfler			else
3365188c282SAxel Dörfler				_ReplaceAll(fStringToFind, fReplaceString, fCaseSensitive);
3375188c282SAxel Dörfler			break;
3385188c282SAxel Dörfler		}
33931139022SAxel Dörfler
3400cc8d8abSSiarzhuk Zharski		case B_NODE_MONITOR:
3410cc8d8abSSiarzhuk Zharski			_HandleNodeMonitorEvent(message);
3420cc8d8abSSiarzhuk Zharski			break;
3430cc8d8abSSiarzhuk Zharski
3445188c282SAxel Dörfler		// Font menu
34514ea5e5eSKarsten Heimrich
3465188c282SAxel Dörfler		case FONT_SIZE:
3475188c282SAxel Dörfler		{
3485188c282SAxel Dörfler			float fontSize;
3495188c282SAxel Dörfler			if (message->FindFloat("size", &fontSize) == B_OK)
3505188c282SAxel Dörfler				_SetFontSize(fontSize);
3515188c282SAxel Dörfler			break;
3525188c282SAxel Dörfler		}
3535188c282SAxel Dörfler		case FONT_FAMILY:
3545188c282SAxel Dörfler		{
3555188c282SAxel Dörfler			const char* fontFamily = NULL;
3565188c282SAxel Dörfler			const char* fontStyle = NULL;
3575188c282SAxel Dörfler			void* ptr;
3585188c282SAxel Dörfler			if (message->FindPointer("source", &ptr) == B_OK) {
3595188c282SAxel Dörfler				BMenuItem* item = static_cast<BMenuItem*>(ptr);
3605188c282SAxel Dörfler				fontFamily = item->Label();
3615188c282SAxel Dörfler			}
362d2ff9616SAxel Dörfler
363d2ff9616SAxel Dörfler			BFont font;
364d2ff9616SAxel Dörfler			font.SetFamilyAndStyle(fontFamily, fontStyle);
365d2ff9616SAxel Dörfler			fItalicItem->SetMarked((font.Face() & B_ITALIC_FACE) != 0);
366d2ff9616SAxel Dörfler			fBoldItem->SetMarked((font.Face() & B_BOLD_FACE) != 0);
367d2ff9616SAxel Dörfler
3685188c282SAxel Dörfler			_SetFontStyle(fontFamily, fontStyle);
3695188c282SAxel Dörfler			break;
3705188c282SAxel Dörfler		}
3715188c282SAxel Dörfler		case FONT_STYLE:
3725188c282SAxel Dörfler		{
3735188c282SAxel Dörfler			const char* fontFamily = NULL;
3745188c282SAxel Dörfler			const char* fontStyle = NULL;
3755188c282SAxel Dörfler			void* ptr;
3765188c282SAxel Dörfler			if (message->FindPointer("source", &ptr) == B_OK) {
3775188c282SAxel Dörfler				BMenuItem* item = static_cast<BMenuItem*>(ptr);
3785188c282SAxel Dörfler				fontStyle = item->Label();
3795188c282SAxel Dörfler				BMenu* menu = item->Menu();
3805188c282SAxel Dörfler				if (menu != NULL) {
3815188c282SAxel Dörfler					BMenuItem* super_item = menu->Superitem();
3825188c282SAxel Dörfler					if (super_item != NULL)
3835188c282SAxel Dörfler						fontFamily = super_item->Label();
3845188c282SAxel Dörfler				}
3855188c282SAxel Dörfler			}
386d2ff9616SAxel Dörfler
387d2ff9616SAxel Dörfler			BFont font;
388d2ff9616SAxel Dörfler			font.SetFamilyAndStyle(fontFamily, fontStyle);
389d2ff9616SAxel Dörfler			fItalicItem->SetMarked((font.Face() & B_ITALIC_FACE) != 0);
390d2ff9616SAxel Dörfler			fBoldItem->SetMarked((font.Face() & B_BOLD_FACE) != 0);
391d2ff9616SAxel Dörfler
3925188c282SAxel Dörfler			_SetFontStyle(fontFamily, fontStyle);
3935188c282SAxel Dörfler			break;
3945188c282SAxel Dörfler		}
395d2ff9616SAxel Dörfler		case kMsgSetItalic:
396d2ff9616SAxel Dörfler		{
397d2ff9616SAxel Dörfler			uint32 sameProperties;
398d2ff9616SAxel Dörfler			BFont font;
399d2ff9616SAxel Dörfler			fTextView->GetFontAndColor(&font, &sameProperties);
400d2ff9616SAxel Dörfler
401d2ff9616SAxel Dörfler			if (fItalicItem->IsMarked())
402d2ff9616SAxel Dörfler				font.SetFace(B_REGULAR_FACE);
403d2ff9616SAxel Dörfler			fItalicItem->SetMarked(!fItalicItem->IsMarked());
404d2ff9616SAxel Dörfler
405d2ff9616SAxel Dörfler			font_family family;
406d2ff9616SAxel Dörfler			font_style style;
407d2ff9616SAxel Dörfler			font.GetFamilyAndStyle(&family, &style);
408d2ff9616SAxel Dörfler
409d2ff9616SAxel Dörfler			_SetFontStyle(family, style);
410d2ff9616SAxel Dörfler			break;
411d2ff9616SAxel Dörfler		}
412d2ff9616SAxel Dörfler		case kMsgSetBold:
413d2ff9616SAxel Dörfler		{
414d2ff9616SAxel Dörfler			uint32 sameProperties;
415d2ff9616SAxel Dörfler			BFont font;
416d2ff9616SAxel Dörfler			fTextView->GetFontAndColor(&font, &sameProperties);
417d2ff9616SAxel Dörfler
418d2ff9616SAxel Dörfler			if (fBoldItem->IsMarked())
419d2ff9616SAxel Dörfler				font.SetFace(B_REGULAR_FACE);
420d2ff9616SAxel Dörfler			fBoldItem->SetMarked(!fBoldItem->IsMarked());
421d2ff9616SAxel Dörfler
422d2ff9616SAxel Dörfler			font_family family;
423d2ff9616SAxel Dörfler			font_style style;
424d2ff9616SAxel Dörfler			font.GetFamilyAndStyle(&family, &style);
425d2ff9616SAxel Dörfler
426d2ff9616SAxel Dörfler			_SetFontStyle(family, style);
427d2ff9616SAxel Dörfler			break;
428d2ff9616SAxel Dörfler		}
4295188c282SAxel Dörfler		case FONT_COLOR:
4305188c282SAxel Dörfler		{
431e62d9cf8SPhilippe Saint-Pierre			ssize_t colorLength;
432e62d9cf8SPhilippe Saint-Pierre			rgb_color* color;
433e62d9cf8SPhilippe Saint-Pierre			if (message->FindData("color", B_RGB_COLOR_TYPE,
434e62d9cf8SPhilippe Saint-Pierre					(const void**)&color, &colorLength) == B_OK
435e62d9cf8SPhilippe Saint-Pierre				&& colorLength == sizeof(rgb_color)) {
436e62d9cf8SPhilippe Saint-Pierre				/*
437e62d9cf8SPhilippe Saint-Pierre				 * TODO: Ideally, when selecting the default color,
438e62d9cf8SPhilippe Saint-Pierre				 * you wouldn't naively apply it; it shouldn't lose its nature.
439e62d9cf8SPhilippe Saint-Pierre				 * When reloaded with a different default color, it should
440e62d9cf8SPhilippe Saint-Pierre				 * reflect that different choice.
441e62d9cf8SPhilippe Saint-Pierre				 */
442e62d9cf8SPhilippe Saint-Pierre				_SetFontColor(color);
4435188c282SAxel Dörfler			}
4445188c282SAxel Dörfler			break;
4455188c282SAxel Dörfler		}
44631139022SAxel Dörfler
4475188c282SAxel Dörfler		// Document menu
4485188c282SAxel Dörfler
4495188c282SAxel Dörfler		case ALIGN_LEFT:
4505188c282SAxel Dörfler			fTextView->SetAlignment(B_ALIGN_LEFT);
4515188c282SAxel Dörfler			_UpdateCleanUndoRedoSaveRevert();
4525188c282SAxel Dörfler			break;
4535188c282SAxel Dörfler		case ALIGN_CENTER:
4545188c282SAxel Dörfler			fTextView->SetAlignment(B_ALIGN_CENTER);
4555188c282SAxel Dörfler			_UpdateCleanUndoRedoSaveRevert();
4565188c282SAxel Dörfler			break;
4575188c282SAxel Dörfler		case ALIGN_RIGHT:
4585188c282SAxel Dörfler			fTextView->SetAlignment(B_ALIGN_RIGHT);
4595188c282SAxel Dörfler			_UpdateCleanUndoRedoSaveRevert();
4605188c282SAxel Dörfler			break;
4615188c282SAxel Dörfler		case WRAP_LINES:
4625188c282SAxel Dörfler		{
4635188c282SAxel Dörfler			BRect textRect(fTextView->Bounds());
4645188c282SAxel Dörfler			textRect.OffsetTo(B_ORIGIN);
4655188c282SAxel Dörfler			textRect.InsetBy(TEXT_INSET, TEXT_INSET);
4665188c282SAxel Dörfler			if (fTextView->DoesWordWrap()) {
4675188c282SAxel Dörfler				fTextView->SetWordWrap(false);
4685188c282SAxel Dörfler				fWrapItem->SetMarked(false);
4695188c282SAxel Dörfler				// the width comes from stylededit R5. TODO: find a better way
4705188c282SAxel Dörfler				textRect.SetRightBottom(BPoint(1500.0, textRect.RightBottom().y));
4715188c282SAxel Dörfler			} else {
4725188c282SAxel Dörfler				fTextView->SetWordWrap(true);
4735188c282SAxel Dörfler				fWrapItem->SetMarked(true);
4745188c282SAxel Dörfler			}
4755188c282SAxel Dörfler			fTextView->SetTextRect(textRect);
4765188c282SAxel Dörfler
4775188c282SAxel Dörfler			_UpdateCleanUndoRedoSaveRevert();
4785188c282SAxel Dörfler			break;
4795188c282SAxel Dörfler		}
4805188c282SAxel Dörfler		case SHOW_STATISTICS:
4815188c282SAxel Dörfler			_ShowStatistics();
4825188c282SAxel Dörfler			break;
4835188c282SAxel Dörfler		case ENABLE_ITEMS:
4845188c282SAxel Dörfler			fCutItem->SetEnabled(true);
4855188c282SAxel Dörfler			fCopyItem->SetEnabled(true);
4865188c282SAxel Dörfler			break;
4875188c282SAxel Dörfler		case DISABLE_ITEMS:
4885188c282SAxel Dörfler			fCutItem->SetEnabled(false);
4895188c282SAxel Dörfler			fCopyItem->SetEnabled(false);
4905188c282SAxel Dörfler			break;
4915188c282SAxel Dörfler		case TEXT_CHANGED:
4925188c282SAxel Dörfler			if (fUndoFlag) {
4935188c282SAxel Dörfler				if (fUndoCleans) {
4945188c282SAxel Dörfler					// we cleaned!
4955188c282SAxel Dörfler					fClean = true;
4965188c282SAxel Dörfler					fUndoCleans = false;
4975188c282SAxel Dörfler				} else if (fClean) {
4985188c282SAxel Dörfler					// if we were clean
4995188c282SAxel Dörfler					// then a redo will make us clean again
5005188c282SAxel Dörfler					fRedoCleans = true;
5015188c282SAxel Dörfler					fClean = false;
5025188c282SAxel Dörfler				}
5035188c282SAxel Dörfler				// set mode
5045188c282SAxel Dörfler				fCanUndo = false;
5055188c282SAxel Dörfler				fCanRedo = true;
5065188c282SAxel Dörfler				fUndoItem->SetLabel(B_TRANSLATE("Redo typing"));
5075188c282SAxel Dörfler				fUndoItem->SetEnabled(true);
5085188c282SAxel Dörfler				fUndoFlag = false;
5095188c282SAxel Dörfler			} else {
5105188c282SAxel Dörfler				if (fRedoFlag && fRedoCleans) {
5115188c282SAxel Dörfler					// we cleaned!
5125188c282SAxel Dörfler					fClean = true;
5135188c282SAxel Dörfler					fRedoCleans = false;
5145188c282SAxel Dörfler				} else if (fClean) {
5155188c282SAxel Dörfler					// if we were clean
5165188c282SAxel Dörfler					// then an undo will make us clean again
5175188c282SAxel Dörfler					fUndoCleans = true;
5185188c282SAxel Dörfler					fClean = false;
5195188c282SAxel Dörfler				} else {
5205188c282SAxel Dörfler					// no more cleaning from undo now...
5215188c282SAxel Dörfler					fUndoCleans = false;
5225188c282SAxel Dörfler				}
5235188c282SAxel Dörfler				// set mode
5245188c282SAxel Dörfler				fCanUndo = true;
5255188c282SAxel Dörfler				fCanRedo = false;
5265188c282SAxel Dörfler				fUndoItem->SetLabel(B_TRANSLATE("Undo typing"));
5275188c282SAxel Dörfler				fUndoItem->SetEnabled(true);
5285188c282SAxel Dörfler				fRedoFlag = false;
5295188c282SAxel Dörfler			}
5305188c282SAxel Dörfler			if (fClean) {
5315188c282SAxel Dörfler				fSaveItem->SetEnabled(fSaveMessage == NULL);
5325188c282SAxel Dörfler			} else {
5335188c282SAxel Dörfler				fSaveItem->SetEnabled(true);
5345188c282SAxel Dörfler			}
5350cc8d8abSSiarzhuk Zharski			fReloadItem->SetEnabled(fSaveMessage != NULL);
5360cc8d8abSSiarzhuk Zharski			fEncodingItem->SetEnabled(fSaveMessage != NULL);
5375188c282SAxel Dörfler			break;
5385188c282SAxel Dörfler
5395188c282SAxel Dörfler		case SAVE_AS_ENCODING:
5405188c282SAxel Dörfler			void* ptr;
5415188c282SAxel Dörfler			if (message->FindPointer("source", &ptr) == B_OK
5425188c282SAxel Dörfler				&& fSavePanelEncodingMenu != NULL) {
5435188c282SAxel Dörfler				fTextView->SetEncoding(
5445188c282SAxel Dörfler					(uint32)fSavePanelEncodingMenu->IndexOf((BMenuItem*)ptr));
5455188c282SAxel Dörfler			}
5465188c282SAxel Dörfler			break;
5475188c282SAxel Dörfler
5480f4985d8SVlad Slepukhin		case UPDATE_STATUS:
54942cb481fSSiarzhuk Zharski		{
5500f4985d8SVlad Slepukhin			message->AddBool("modified", !fClean);
55142cb481fSSiarzhuk Zharski			bool readOnly = !fTextView->IsEditable();
55242cb481fSSiarzhuk Zharski			message->AddBool("readOnly", readOnly);
55342cb481fSSiarzhuk Zharski			if (readOnly) {
55442cb481fSSiarzhuk Zharski				BVolume volume(fNodeRef.device);
55542cb481fSSiarzhuk Zharski				message->AddBool("canUnlock", !volume.IsReadOnly());
55642cb481fSSiarzhuk Zharski			}
5570f4985d8SVlad Slepukhin			fStatusView->SetStatus(message);
5580f4985d8SVlad Slepukhin			break;
55942cb481fSSiarzhuk Zharski		}
5600f4985d8SVlad Slepukhin
5618914c88dSJanus		case UPDATE_STATUS_REF:
5628914c88dSJanus		{
5638914c88dSJanus			entry_ref ref;
5648914c88dSJanus			const char* name;
5658914c88dSJanus
5668914c88dSJanus			if (fSaveMessage != NULL
5678914c88dSJanus				&& fSaveMessage->FindRef("directory", &ref) == B_OK
5688914c88dSJanus				&& fSaveMessage->FindString("name", &name) == B_OK) {
5698914c88dSJanus
5708914c88dSJanus				BDirectory dir(&ref);
5718914c88dSJanus				status_t status = dir.InitCheck();
5728914c88dSJanus				BEntry entry;
5738914c88dSJanus				if (status == B_OK)
5748914c88dSJanus					status = entry.SetTo(&dir, name);
5758914c88dSJanus				if (status == B_OK)
5768914c88dSJanus					status = entry.GetRef(&ref);
5778914c88dSJanus			}
5788914c88dSJanus			fStatusView->SetRef(ref);
5798914c88dSJanus			break;
5808914c88dSJanus		}
5818914c88dSJanus
5820f4985d8SVlad Slepukhin		case UNLOCK_FILE:
5830f4985d8SVlad Slepukhin		{
5840f4985d8SVlad Slepukhin			status_t status = _UnlockFile();
5850f4985d8SVlad Slepukhin			if (status != B_OK) {
5860f4985d8SVlad Slepukhin				BString text;
5870f4985d8SVlad Slepukhin				bs_printf(&text,
5880f4985d8SVlad Slepukhin					B_TRANSLATE("Unable to unlock file\n\t%s"),
5890f4985d8SVlad Slepukhin					strerror(status));
5900f4985d8SVlad Slepukhin				_ShowAlert(text, B_TRANSLATE("OK"), "", "", B_STOP_ALERT);
5910f4985d8SVlad Slepukhin			}
5920f4985d8SVlad Slepukhin			PostMessage(UPDATE_STATUS);
5930f4985d8SVlad Slepukhin			break;
5940f4985d8SVlad Slepukhin		}
5950f4985d8SVlad Slepukhin
596c7087c91SSiarzhuk Zharski		case UPDATE_LINE_SELECTION:
59746f1daffSVlad Slepukhin		{
59846f1daffSVlad Slepukhin			int32 line;
59946f1daffSVlad Slepukhin			if (message->FindInt32("be:line", &line) == B_OK) {
60046f1daffSVlad Slepukhin				fTextView->GoToLine(line);
60146f1daffSVlad Slepukhin				fTextView->ScrollToSelection();
60246f1daffSVlad Slepukhin			}
60346f1daffSVlad Slepukhin
60446f1daffSVlad Slepukhin			int32 start, length;
60546f1daffSVlad Slepukhin			if (message->FindInt32("be:selection_offset", &start) == B_OK) {
60646f1daffSVlad Slepukhin				if (message->FindInt32("be:selection_length", &length) != B_OK)
60746f1daffSVlad Slepukhin					length = 0;
60846f1daffSVlad Slepukhin
60946f1daffSVlad Slepukhin				fTextView->Select(start, start + length);
61046f1daffSVlad Slepukhin				fTextView->ScrollToOffset(start);
61146f1daffSVlad Slepukhin			}
61246f1daffSVlad Slepukhin			break;
61346f1daffSVlad Slepukhin		}
6145188c282SAxel Dörfler		default:
6155188c282SAxel Dörfler			BWindow::MessageReceived(message);
6165188c282SAxel Dörfler			break;
61731139022SAxel Dörfler	}
6185188c282SAxel Dörfler}
61914ea5e5eSKarsten Heimrich
62014ea5e5eSKarsten Heimrich
6215188c282SAxel Dörflervoid
6225188c282SAxel DörflerStyledEditWindow::MenusBeginning()
6235188c282SAxel Dörfler{
6245188c282SAxel Dörfler	// update the font menu
6255188c282SAxel Dörfler	// unselect the old values
6265188c282SAxel Dörfler	if (fCurrentFontItem != NULL) {
6275188c282SAxel Dörfler		fCurrentFontItem->SetMarked(false);
6285188c282SAxel Dörfler		BMenu* menu = fCurrentFontItem->Submenu();
6295188c282SAxel Dörfler		if (menu != NULL) {
6305188c282SAxel Dörfler			BMenuItem* item = menu->FindMarked();
6312cfeb3caSJohn Scipione			if (item != NULL)
6325188c282SAxel Dörfler				item->SetMarked(false);
6335188c282SAxel Dörfler		}
6345188c282SAxel Dörfler	}
63531139022SAxel Dörfler
6365188c282SAxel Dörfler	if (fCurrentStyleItem != NULL) {
6375188c282SAxel Dörfler		fCurrentStyleItem->SetMarked(false);
6385188c282SAxel Dörfler	}
6395188c282SAxel Dörfler
6405188c282SAxel Dörfler	BMenuItem* oldColorItem = fFontColorMenu->FindMarked();
6415188c282SAxel Dörfler	if (oldColorItem != NULL)
6425188c282SAxel Dörfler		oldColorItem->SetMarked(false);
6435188c282SAxel Dörfler
6445188c282SAxel Dörfler	BMenuItem* oldSizeItem = fFontSizeMenu->FindMarked();
6455188c282SAxel Dörfler	if (oldSizeItem != NULL)
6465188c282SAxel Dörfler		oldSizeItem->SetMarked(false);
6475188c282SAxel Dörfler
6485188c282SAxel Dörfler	// find the current font, color, size
6495188c282SAxel Dörfler	BFont font;
6505188c282SAxel Dörfler	uint32 sameProperties;
651e62d9cf8SPhilippe Saint-Pierre	rgb_color color = ui_color(B_DOCUMENT_TEXT_COLOR);
6525188c282SAxel Dörfler	bool sameColor;
6535188c282SAxel Dörfler	fTextView->GetFontAndColor(&font, &sameProperties, &color, &sameColor);
6542cfeb3caSJohn Scipione	color.alpha = 255;
6555188c282SAxel Dörfler
6562cfeb3caSJohn Scipione	if (sameColor) {
657e62d9cf8SPhilippe Saint-Pierre		if (fDefaultFontColorItem->Color() == color)
658e62d9cf8SPhilippe Saint-Pierre			fDefaultFontColorItem->SetMarked(true);
659e62d9cf8SPhilippe Saint-Pierre		else {
660e62d9cf8SPhilippe Saint-Pierre			for (int i = 0; i < fFontColorMenu->CountItems(); i++) {
661e62d9cf8SPhilippe Saint-Pierre				ColorMenuItem* item = dynamic_cast<ColorMenuItem*>
662e62d9cf8SPhilippe Saint-Pierre					(fFontColorMenu->ItemAt(i));
663e62d9cf8SPhilippe Saint-Pierre				if (item != NULL && item->Color() == color) {
664e62d9cf8SPhilippe Saint-Pierre					item->SetMarked(true);
665e62d9cf8SPhilippe Saint-Pierre					break;
666f7afd44bSPhil Greenway				}
667f7afd44bSPhil Greenway			}
668f7afd44bSPhil Greenway		}
66931139022SAxel Dörfler	}
67031139022SAxel Dörfler
6715188c282SAxel Dörfler	if (sameProperties & B_FONT_SIZE) {
6725188c282SAxel Dörfler		if ((int)font.Size() == font.Size()) {
6735188c282SAxel Dörfler			// select the current font size
6745188c282SAxel Dörfler			char fontSizeStr[16];
6755188c282SAxel Dörfler			snprintf(fontSizeStr, 15, "%i", (int)font.Size());
6765188c282SAxel Dörfler			BMenuItem* item = fFontSizeMenu->FindItem(fontSizeStr);
6775188c282SAxel Dörfler			if (item != NULL)
6785188c282SAxel Dörfler				item->SetMarked(true);
6795188c282SAxel Dörfler		}
6805188c282SAxel Dörfler	}
6815188c282SAxel Dörfler
6825188c282SAxel Dörfler	font_family family;
6835188c282SAxel Dörfler	font_style style;
6845188c282SAxel Dörfler	font.GetFamilyAndStyle(&family, &style);
6855188c282SAxel Dörfler
6865188c282SAxel Dörfler	fCurrentFontItem = fFontMenu->FindItem(family);
6875188c282SAxel Dörfler
6885188c282SAxel Dörfler	if (fCurrentFontItem != NULL) {
6895188c282SAxel Dörfler		fCurrentFontItem->SetMarked(true);
6905188c282SAxel Dörfler		BMenu* menu = fCurrentFontItem->Submenu();
6915188c282SAxel Dörfler		if (menu != NULL) {
6925188c282SAxel Dörfler			BMenuItem* item = menu->FindItem(style);
6935188c282SAxel Dörfler			fCurrentStyleItem = item;
694d2ff9616SAxel Dörfler			if (fCurrentStyleItem != NULL)
6955188c282SAxel Dörfler				item->SetMarked(true);
6965188c282SAxel Dörfler		}
6975188c282SAxel Dörfler	}
6985188c282SAxel Dörfler
699d2ff9616SAxel Dörfler	fBoldItem->SetMarked((font.Face() & B_BOLD_FACE) != 0);
700d2ff9616SAxel Dörfler	fItalicItem->SetMarked((font.Face() & B_ITALIC_FACE) != 0);
701d2ff9616SAxel Dörfler
7025188c282SAxel Dörfler	switch (fTextView->Alignment()) {
7035188c282SAxel Dörfler		case B_ALIGN_LEFT:
7045188c282SAxel Dörfler		default:
7055188c282SAxel Dörfler			fAlignLeft->SetMarked(true);
7065188c282SAxel Dörfler			break;
7075188c282SAxel Dörfler		case B_ALIGN_CENTER:
7085188c282SAxel Dörfler			fAlignCenter->SetMarked(true);
7095188c282SAxel Dörfler			break;
7105188c282SAxel Dörfler		case B_ALIGN_RIGHT:
7115188c282SAxel Dörfler			fAlignRight->SetMarked(true);
7125188c282SAxel Dörfler			break;
7135188c282SAxel Dörfler	}
7140cc8d8abSSiarzhuk Zharski
7150cc8d8abSSiarzhuk Zharski	// text encoding
7160cc8d8abSSiarzhuk Zharski	const BCharacterSet* charset
7170cc8d8abSSiarzhuk Zharski		= BCharacterSetRoster::GetCharacterSetByFontID(fTextView->GetEncoding());
7180cc8d8abSSiarzhuk Zharski	BMenu* encodingMenu = fEncodingItem->Submenu();
7190cc8d8abSSiarzhuk Zharski	if (charset != NULL && encodingMenu != NULL) {
7200cc8d8abSSiarzhuk Zharski		const char* mime = charset->GetMIMEName();
7210cc8d8abSSiarzhuk Zharski		BString name(charset->GetPrintName());
7220cc8d8abSSiarzhuk Zharski		if (mime)
7230cc8d8abSSiarzhuk Zharski			name << " (" << mime << ")";
7240cc8d8abSSiarzhuk Zharski
7250cc8d8abSSiarzhuk Zharski		BMenuItem* item = encodingMenu->FindItem(name);
7260cc8d8abSSiarzhuk Zharski		if (item != NULL)
7270cc8d8abSSiarzhuk Zharski			item->SetMarked(true);
7280cc8d8abSSiarzhuk Zharski	}
7295188c282SAxel Dörfler}
7305188c282SAxel Dörfler
7315188c282SAxel Dörfler
732546208a5SOliver Tappe#undef B_TRANSLATION_CONTEXT
733546208a5SOliver Tappe#define B_TRANSLATION_CONTEXT "SaveAlert"
7345188c282SAxel Dörfler
7355188c282SAxel Dörfler
7365188c282SAxel Dörflerstatus_t
7375188c282SAxel DörflerStyledEditWindow::Save(BMessage* message)
7385188c282SAxel Dörfler{
7390cc8d8abSSiarzhuk Zharski	_NodeMonitorSuspender nodeMonitorSuspender(this);
7400cc8d8abSSiarzhuk Zharski
7415188c282SAxel Dörfler	if (!message)
7425188c282SAxel Dörfler		message = fSaveMessage;
7435188c282SAxel Dörfler
7445188c282SAxel Dörfler	if (!message)
7455188c282SAxel Dörfler		return B_ERROR;
7465188c282SAxel Dörfler
7475188c282SAxel Dörfler	entry_ref dirRef;
7485188c282SAxel Dörfler	const char* name;
7495188c282SAxel Dörfler	if (message->FindRef("directory", &dirRef) != B_OK
7505188c282SAxel Dörfler		|| message->FindString("name", &name) != B_OK)
7515188c282SAxel Dörfler		return B_BAD_VALUE;
7525188c282SAxel Dörfler
7535188c282SAxel Dörfler	BDirectory dir(&dirRef);
7545188c282SAxel Dörfler	BEntry entry(&dir, name);
7555188c282SAxel Dörfler
7565188c282SAxel Dörfler	status_t status = B_ERROR;
7575188c282SAxel Dörfler	if (dir.InitCheck() == B_OK && entry.InitCheck() == B_OK) {
7585188c282SAxel Dörfler		struct stat st;
7595188c282SAxel Dörfler		BFile file(&entry, B_READ_WRITE | B_CREATE_FILE);
7605188c282SAxel Dörfler		if (file.InitCheck() == B_OK
7615188c282SAxel Dörfler			&& (status = file.GetStat(&st)) == B_OK) {
7625188c282SAxel Dörfler			// check the file permissions
7635188c282SAxel Dörfler			if (!((getuid() == st.st_uid && (S_IWUSR & st.st_mode))
7645188c282SAxel Dörfler				|| (getgid() == st.st_gid && (S_IWGRP & st.st_mode))
7655188c282SAxel Dörfler				|| (S_IWOTH & st.st_mode))) {
7665188c282SAxel Dörfler				BString alertText;
7675188c282SAxel Dörfler				bs_printf(&alertText, B_TRANSLATE("This file is marked "
768776c58b2SHumdinger					"read-only. Save changes to the document \"%s\"? "), name);
7695188c282SAxel Dörfler				switch (_ShowAlert(alertText, B_TRANSLATE("Cancel"),
7705188c282SAxel Dörfler						B_TRANSLATE("Don't save"),
7715188c282SAxel Dörfler						B_TRANSLATE("Save"), B_WARNING_ALERT)) {
7725188c282SAxel Dörfler					case 0:
7735188c282SAxel Dörfler						return B_CANCELED;
7745188c282SAxel Dörfler					case 1:
7755188c282SAxel Dörfler						return B_OK;
7765188c282SAxel Dörfler					default:
7775188c282SAxel Dörfler						break;
7785188c282SAxel Dörfler				}
7795188c282SAxel Dörfler			}
7805188c282SAxel Dörfler
7815188c282SAxel Dörfler			status = fTextView->WriteStyledEditFile(&file);
7825188c282SAxel Dörfler		}
7835188c282SAxel Dörfler	}
7845188c282SAxel Dörfler
7855188c282SAxel Dörfler	if (status != B_OK) {
7865188c282SAxel Dörfler		BString alertText;
7875188c282SAxel Dörfler		bs_printf(&alertText, B_TRANSLATE("Error saving \"%s\":\n%s"), name,
7885188c282SAxel Dörfler			strerror(status));
78931139022SAxel Dörfler
7905188c282SAxel Dörfler		_ShowAlert(alertText, B_TRANSLATE("OK"), "", "", B_STOP_ALERT);
7915188c282SAxel Dörfler		return status;
7925188c282SAxel Dörfler	}
7930b46ec98Sshatty
7945188c282SAxel Dörfler	SetTitle(name);
795