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