StyledEditView.cpp revision 670567f9
1#include <Message.h>
2#include <Messenger.h>
3#include <Rect.h>
4#include <Region.h>
5#include <TranslationUtils.h>
6#include <Node.h>
7#include <stdio.h>
8
9#include "StyledEditView.h"
10#include "Constants.h"
11#include "CharacterSet.h"
12#include "UTF8.h"
13
14StyledEditView::StyledEditView(BRect viewFrame, BRect textBounds, BHandler *handler)
15	: BTextView(viewFrame, "textview", textBounds,
16			    B_FOLLOW_ALL, B_FRAME_EVENTS|B_WILL_DRAW)
17{
18	fHandler= handler;
19	fMessenger= new BMessenger(handler);
20	fSuppressChanges = false;
21	fEncoding = 0;
22}/***StyledEditView()***/
23
24StyledEditView::~StyledEditView(){
25
26}/***~StyledEditView***/
27
28void
29StyledEditView::FrameResized(float width, float height)
30{
31	BTextView::FrameResized(width, height);
32
33	if (DoesWordWrap()) {
34		BRect textRect;
35		textRect = Bounds();
36		textRect.OffsetTo(B_ORIGIN);
37		textRect.InsetBy(TEXT_INSET,TEXT_INSET);
38		SetTextRect(textRect);
39	}
40/*	// I tried to do some sort of intelligent resize thing but it just doesn't work
41	// so we revert to the R5 stylededit yucky practice of setting the text rect to
42	// some crazy large number when word wrap is turned off :-(
43	 else if (textRect.Width() > TextRect().Width()) {
44		SetTextRect(textRect);
45	}
46
47	BRegion region;
48	GetTextRegion(0,TextLength(),&region);
49	float textWidth = region.Frame().Width();
50	if (textWidth < textRect.Width()) {
51		BRect textRect(B_ORIGIN,BPoint(textWidth+TEXT_INSET*2,Bounds().Height()));
52		textRect.InsetBy(TEXT_INSET,TEXT_INSET);
53		SetTextRect(textRect);
54	}
55	*/
56}
57
58status_t
59StyledEditView::GetStyledText(BPositionIO * stream)
60{
61	status_t result = B_OK;
62	fSuppressChanges = true;
63	result = BTranslationUtils::GetStyledText(stream, this, NULL);
64
65	BNode * node = dynamic_cast<BNode*>(stream);
66	if (node != 0) {
67		ssize_t bytesRead;
68		// decode encoding
69		int32 encoding;
70		bytesRead = node->ReadAttr("be:encoding",0,0,&encoding,sizeof(encoding));
71		if (bytesRead > 0) {
72			CharacterSetRoster * roster = CharacterSetRoster::Roster(&result);
73			if (result != B_OK) {
74				return result;
75			}
76			if (encoding == 65535) {
77				fEncoding = 0;
78			} else {
79				const CharacterSet * cs = roster->FindCharacterSetByConversionID(encoding);
80				if (cs != 0) {
81					fEncoding = cs->GetFontID();
82				}
83			}
84		}
85
86		// restore alignment
87		alignment align;
88		bytesRead = node->ReadAttr("alignment",0,0,&align,sizeof(align));
89		if (bytesRead > 0) {
90			SetAlignment(align);
91		}
92		// restore wrapping
93		bool wrap;
94		bytesRead = node->ReadAttr("wrap",0,0,&wrap,sizeof(wrap));
95		if (bytesRead > 0) {
96			SetWordWrap(wrap);
97		}
98		if (wrap == false) {
99			BRect textRect;
100			textRect = Bounds();
101			textRect.OffsetTo(B_ORIGIN);
102			textRect.InsetBy(TEXT_INSET,TEXT_INSET);
103				// the width comes from stylededit R5. TODO: find a better way
104			textRect.SetRightBottom(BPoint(1500.0,textRect.RightBottom().y));
105			SetTextRect(textRect);
106		}
107	}
108	fSuppressChanges = false;
109	return result;
110}
111
112status_t
113StyledEditView::WriteStyledEditFile(BFile * file)
114{
115	status_t result = B_OK;
116	result = BTranslationUtils::WriteStyledEditFile(this,file);
117	if (result != B_OK) {
118		return result;
119	}
120	if (fEncoding == 0) {
121		int32 encoding = 65535;
122		file->WriteAttr("be:encoding",B_INT32_TYPE,0,&encoding,sizeof(encoding));
123	} else {
124		result = file->SetSize(0);
125		if (result != B_OK) {
126			return result;
127		}
128		result = file->Seek(0,SEEK_SET);
129		if (result != B_OK) {
130			return result;
131		}
132		CharacterSetRoster * roster = CharacterSetRoster::Roster(&result);
133		if (result != B_OK) {
134			return result;
135		}
136		uint32 id = roster->FindCharacterSetByFontID(fEncoding)->GetConversionID();
137		const char * outText = Text();
138		int32 sourceLength = TextLength();
139		int32 state = 0;
140		char buffer[256];
141		while (sourceLength > 0) {
142			int32 length = sourceLength;
143			int32 written = 256;
144			result = convert_from_utf8(id,outText,&length,buffer,&written,&state);
145			if (result != B_OK) {
146				return result;
147			}
148			file->Write(buffer,written);
149			sourceLength -= length;
150			outText += length;
151		}
152		file->WriteAttr("be:encoding",B_INT32_TYPE,0,&id,sizeof(id));
153	}
154
155	alignment align = Alignment();
156	file->WriteAttr("alignment",B_INT32_TYPE,0,&align,sizeof(align));
157	bool wrap = DoesWordWrap();
158	file->WriteAttr("wrap",B_BOOL_TYPE,0,&wrap,sizeof(wrap));
159	return result;
160}
161
162void
163StyledEditView::Reset()
164{
165	fSuppressChanges = true;
166	SetText("");
167	fSuppressChanges = false;
168}
169
170void
171StyledEditView::Select(int32 start, int32 finish)
172{
173	if(start==finish)
174		fChangeMessage= new BMessage(DISABLE_ITEMS);
175	else
176		fChangeMessage= new BMessage(ENABLE_ITEMS);
177
178	fMessenger->SendMessage(fChangeMessage);
179
180	BTextView::Select(start, finish);
181}
182
183void
184StyledEditView::SetEncoding(uint32 encoding)
185{
186	fEncoding = encoding;
187}
188
189uint32
190StyledEditView::GetEncoding() const
191{
192	return fEncoding;
193}
194
195void
196StyledEditView::InsertText(const char *text, int32 length, int32 offset, const text_run_array *runs)
197{
198	if (!fSuppressChanges)
199		fMessenger-> SendMessage(new BMessage(TEXT_CHANGED));
200
201	BTextView::InsertText(text, length, offset, runs);
202
203}/****StyledEditView::InsertText()***/
204
205void
206StyledEditView::DeleteText(int32 start, int32 finish)
207{
208	if (!fSuppressChanges)
209		fMessenger-> SendMessage(new BMessage(TEXT_CHANGED));
210
211	BTextView::DeleteText(start, finish);
212
213}/***StyledEditView::DeleteText***/
214