StyledEditView.cpp revision e7d3e55ad60a62998aa0fbb10ac2bc93b2be1033
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 *		Axel D��rfler, axeld@pinc-software.de
9 */
10
11
12#include "Constants.h"
13#include "StyledEditView.h"
14
15#include <CharacterSet.h>
16#include <CharacterSetRoster.h>
17#include <DataIO.h>
18#include <File.h>
19#include <Message.h>
20#include <Messenger.h>
21#include <Node.h>
22#include <Rect.h>
23#include <TranslationUtils.h>
24#include <UTF8.h>
25
26#include <stdio.h>
27#include <stdlib.h>
28
29
30using namespace BPrivate;
31
32
33StyledEditView::StyledEditView(BRect viewFrame, BRect textBounds, BHandler *handler)
34	: BTextView(viewFrame, "textview", textBounds,
35		B_FOLLOW_ALL, B_FRAME_EVENTS | B_WILL_DRAW)
36{
37	fMessenger = new BMessenger(handler);
38	fSuppressChanges = false;
39}
40
41
42StyledEditView::~StyledEditView()
43{
44	delete fMessenger;
45}
46
47
48void
49StyledEditView::Select(int32 start, int32 finish)
50{
51	fMessenger->SendMessage(start == finish ? DISABLE_ITEMS : ENABLE_ITEMS);
52	fMessenger->SendMessage(UPDATE_LINE);
53	BTextView::Select(start, finish);
54}
55
56
57void
58StyledEditView::Reset()
59{
60	fSuppressChanges = true;
61	SetText("");
62	fEncoding = "";
63	fSuppressChanges = false;
64}
65
66
67void
68StyledEditView::SetSuppressChanges(bool suppressChanges)
69{
70	fSuppressChanges = suppressChanges;
71}
72
73
74status_t
75StyledEditView::GetStyledText(BPositionIO* stream)
76{
77	fSuppressChanges = true;
78	status_t result = BTranslationUtils::GetStyledText(stream, this,
79		fEncoding.String());
80	fSuppressChanges = false;
81
82	if (result != B_OK)
83		return result;
84
85	BNode* node = dynamic_cast<BNode*>(stream);
86	if (node != NULL) {
87		// get encoding
88		if (node->ReadAttrString("be:encoding", &fEncoding) != B_OK) {
89			// try to read as "int32"
90			int32 encoding;
91			ssize_t bytesRead = node->ReadAttr("be:encoding", B_INT32_TYPE, 0,
92				&encoding, sizeof(encoding));
93			if (bytesRead == (ssize_t)sizeof(encoding)) {
94				if (encoding == 65535) {
95					fEncoding = "UTF-8";
96				} else {
97					const BCharacterSet* characterSet
98						= BCharacterSetRoster::GetCharacterSetByConversionID(encoding);
99					if (characterSet != NULL)
100						fEncoding = characterSet->GetName();
101				}
102			}
103		}
104
105		// TODO: move those into BTranslationUtils::GetStyledText() as well?
106
107		// restore alignment
108		int32 align;
109		ssize_t bytesRead = node->ReadAttr("alignment", 0, 0, &align, sizeof(align));
110		if (bytesRead == (ssize_t)sizeof(align))
111			SetAlignment((alignment)align);
112
113		// restore wrapping
114		bool wrap;
115		bytesRead = node->ReadAttr("wrap", 0, 0, &wrap, sizeof(wrap));
116		if (bytesRead == (ssize_t)sizeof(wrap)) {
117			SetWordWrap(wrap);
118			if (wrap == false) {
119				BRect textRect;
120				textRect = Bounds();
121				textRect.OffsetTo(B_ORIGIN);
122				textRect.InsetBy(TEXT_INSET, TEXT_INSET);
123					// the width comes from stylededit R5. TODO: find a better way
124				textRect.SetRightBottom(BPoint(1500.0, textRect.RightBottom().y));
125				SetTextRect(textRect);
126			}
127		}
128	}
129
130	return result;
131}
132
133
134status_t
135StyledEditView::WriteStyledEditFile(BFile* file)
136{
137	return BTranslationUtils::WriteStyledEditFile(this, file,
138		fEncoding.String());
139}
140
141
142void
143StyledEditView::SetEncoding(uint32 encoding)
144{
145	fEncoding = "";
146	if (encoding == 0)
147		return;
148
149	const BCharacterSet* set
150		= BCharacterSetRoster::GetCharacterSetByFontID(encoding);
151
152	if (set != NULL)
153		fEncoding = set->GetName();
154}
155
156
157uint32
158StyledEditView::GetEncoding() const
159{
160	if (fEncoding == "")
161		return 0;
162
163	const BCharacterSet* set =
164		BCharacterSetRoster::FindCharacterSetByName(fEncoding.String());
165	if(set != NULL)
166		return set->GetFontID();
167
168	return 0;
169}
170
171
172void
173StyledEditView::DeleteText(int32 start, int32 finish)
174{
175	if (!fSuppressChanges)
176		fMessenger-> SendMessage(TEXT_CHANGED);
177
178	BTextView::DeleteText(start, finish);
179	fMessenger->SendMessage(UPDATE_LINE);
180}
181
182
183void
184StyledEditView::InsertText(const char *text, int32 length, int32 offset,
185	const text_run_array *runs)
186{
187	if (!fSuppressChanges)
188		fMessenger->SendMessage(TEXT_CHANGED);
189
190	BTextView::InsertText(text, length, offset, runs);
191	fMessenger->SendMessage(UPDATE_LINE);
192}
193
194
195void
196StyledEditView::FrameResized(float width, float height)
197{
198	BTextView::FrameResized(width, height);
199
200	if (DoesWordWrap()) {
201		BRect textRect;
202		textRect = Bounds();
203		textRect.OffsetTo(B_ORIGIN);
204		textRect.InsetBy(TEXT_INSET, TEXT_INSET);
205		SetTextRect(textRect);
206	}
207}
208
209