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