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