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