xref: /haiku/src/apps/stylededit/StyledEditView.cpp (revision 60c26cd332a044bb9003091b9196cc404ebe5482)
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, 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 
42 StyledEditView::~StyledEditView()
43 {
44 	delete fMessenger;
45 }
46 
47 
48 void
49 StyledEditView::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 
57 void
58 StyledEditView::Reset()
59 {
60 	fSuppressChanges = true;
61 	SetText("");
62 	fEncoding = "";
63 	fSuppressChanges = false;
64 }
65 
66 
67 void
68 StyledEditView::SetSuppressChanges(bool suppressChanges)
69 {
70 	fSuppressChanges = suppressChanges;
71 }
72 
73 
74 status_t
75 StyledEditView::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 
134 status_t
135 StyledEditView::WriteStyledEditFile(BFile* file)
136 {
137 	return BTranslationUtils::WriteStyledEditFile(this, file,
138 		fEncoding.String());
139 }
140 
141 
142 void
143 StyledEditView::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 
157 uint32
158 StyledEditView::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 
172 void
173 StyledEditView::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 
183 void
184 StyledEditView::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 
195 void
196 StyledEditView::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