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(),®ion); 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