Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members | Related Pages

pgrichedit.cpp

Go to the documentation of this file.
00001 /*
00002    ParaGUI - crossplatform widgetset
00003    Copyright (C) 2000,2001,2002  Alexander Pipelka
00004  
00005    This library is free software; you can redistribute it and/or
00006    modify it under the terms of the GNU Library General Public
00007    License as published by the Free Software Foundation; either
00008    version 2 of the License, or (at your option) any later version.
00009  
00010    This library is distributed in the hope that it will be useful,
00011    but WITHOUT ANY WARRANTY; without even the implied warranty of
00012    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013    Library General Public License for more details.
00014  
00015    You should have received a copy of the GNU Library General Public
00016    License along with this library; if not, write to the Free
00017    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00018  
00019    Alexander Pipelka
00020    pipelka@teleweb.at
00021  
00022    Last Update:      $Author: mbickel $
00023    Update Date:      $Date: 2007-04-13 16:16:04 $
00024    Source File:      $Source: /home/cvspsrv/cvsroot/games/asc/source/libs/paragui/src/widgets/pgrichedit.cpp,v $
00025    CVS/RCS Revision: $Revision: 1.2 $
00026    Status:           $State: Exp $
00027 */
00028 
00029 
00030 #include "pgapplication.h"
00031 #include "pgrichedit.h"
00032 #include "pgscrollarea.h"
00033 #include "pglog.h"
00034 
00035 const Uint32 PG_RichEdit::my_Marks[PG_RichEdit::MARKS_COUNT] = { ' ', 0x01, '\n', '\t', 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0xF
00036                                                                };
00037 const Uint32 PG_RichEdit::my_FontBeginMark = 010;
00038 
00039 
00040 PG_RichEdit::PG_RichEdit(PG_Widget* parent, const PG_Rect& r, bool autoResize, Uint32 linewidth, Uint32 tabSize, Uint32 childsborderwidth, const std::string& style) :
00041 PG_ScrollWidget(parent, r, style) {
00042 
00043         EnableScrollBar(true, PG_ScrollBar::HORIZONTAL);
00044 
00045         my_LineWidth = (linewidth != 0) ? linewidth : r.my_width;
00046         my_scrollarea->SetAreaWidth(my_LineWidth);
00047         my_ChildsBorderWidth = childsborderwidth;
00048 
00049         //TO-DO : Value 5 is font size, witch is currently unknown ...
00050         my_objHorizontalScrollbar->SetLineSize(5);
00051         my_TabSize = tabSize;
00052         my_Align = my_Marks[PG_RichEdit::PG_TEXT_LEFT];
00053         my_AutoVerticalResize = autoResize;
00054         my_AutoHorizontalResize = autoResize;
00055 
00056         my_objVerticalScrollbar->sigScrollTrack.connect(slot(*this, &PG_RichEdit::handleScrollTrack));
00057         my_objVerticalScrollbar->sigScrollPos.connect(slot(*this, &PG_RichEdit::handleScrollTrack));
00058         my_objHorizontalScrollbar->sigScrollTrack.connect(slot(*this, &PG_RichEdit::handleScrollTrack));
00059         my_objHorizontalScrollbar->sigScrollPos.connect(slot(*this, &PG_RichEdit::handleScrollTrack));
00060 }
00061 
00062 void PG_RichEdit::SetAlignment(Uint8 align) {
00063         my_Align = my_Marks[align];
00064 }
00065 
00066 void PG_RichEdit::SetAutoResize(bool bHorizontal, bool bVertical) {
00067         my_AutoHorizontalResize = bHorizontal;
00068         my_AutoVerticalResize = bVertical;
00069 }
00070 
00071 /*void PG_RichEdit::UpdateScrollBarsPos() {
00072         //PG_WidgetList::UpdateScrollBarsPos();
00073  
00074         //TO-DO : Value 5 is font size, witch is currently unknown ...
00075         my_objVerticalScrollbar->SetLineSize(5);
00076         my_objHorizontalScrollbar->SetLineSize(5);
00077 }*/
00078 
00079 void PG_RichEdit::eventBlit(SDL_Surface* srf, const PG_Rect& src, const PG_Rect& dst) {
00080 
00081         PG_ScrollWidget::eventBlit(srf, src, dst);
00082 
00083         RichLineArray::iterator line;
00084         int deltax = (my_objHorizontalScrollbar->IsVisible()) ? my_scrollarea->GetScrollPosX() : 0;
00085         int deltay = (my_objVerticalScrollbar->IsVisible()) ? my_scrollarea->GetScrollPosY() : 0;
00086 
00087         for (line = my_RichText.begin(); line != my_RichText.end(); line++) {
00088                 if ((Sint32)(line->my_BaseLine - deltay) < 0) {
00089                         continue;
00090                 }
00091 
00092                 RichLinePartArray::iterator linePart;
00093 
00094                 for (linePart = line->my_LineParts.begin(); linePart != line->my_LineParts.end(); linePart++) {
00095                         Size_tArray::iterator word;
00096                         Uint32 width = 0;
00097 
00098                         for (word = linePart->my_WordIndexes.begin(); word != linePart->my_WordIndexes.end(); word++) {
00099                                 PG_FontEngine::RenderText(PG_Application::GetScreen(), dst, my_xpos - deltax + width + linePart->my_Left,  my_ypos + line->my_BaseLine - deltay, my_ParsedWords[*word].my_Word, GetFont());
00100                                 width += my_ParsedWords[*word].my_WidthAfterFormating;
00101                         }
00102                 }
00103 
00104                 if ((Sint32)(line->my_BaseLine - deltay - line->my_LineSpace) >= Height()) {
00105                         break;
00106                 }
00107         }
00108 }
00109 
00110 void PG_RichEdit::AddChild(PG_Widget* child) {
00111         PG_ScrollWidget::AddChild(child);
00112         CompleteLines();
00113 }
00114 
00115 bool PG_RichEdit::RemoveChild(PG_Widget* child) {
00116         bool result = PG_ScrollWidget::RemoveChild(child);
00117         CompleteLines();
00118         return result;
00119 }
00120 
00121 void PG_RichEdit::SetText(const std::string& text) {
00122         my_scrollarea->SetAreaWidth(my_LineWidth);
00123         my_scrollarea->SetAreaHeight(0);
00124 
00125         my_text = text;
00126 
00127         // trim the string
00128         bool bStop = false;
00129         char c;
00130 
00131         while(!my_text.empty() && !bStop) {
00132                 c = my_text[my_text.size()-1];
00133                 bStop = true;
00134                 switch(c) {
00135                         case '\n':
00136                         case '\r':
00137                         case '\t':
00138                         case ' ':
00139                                 my_text = my_text.substr(0, my_text.size()-1);
00140                                 bStop = false;
00141                 }
00142         }
00143 
00144         ParseWords();
00145         CompleteLines();
00146 }
00147 
00148 void PG_RichEdit::ParseWords() {
00149         size_t searchFrom = 0;
00150         static PG_String blank = " ";
00151 
00152         my_ParsedWords.clear();
00153 
00154         Uint16 my_sw = 0;
00155         PG_FontEngine::GetTextSize(blank, GetFont(), &my_sw);
00156 
00157         RichWordDescription wordDescr;
00158         PG_String word;
00159 
00160         Uint16 w, h, sw = 0;
00161         int bl, ls;
00162         bool space = false;
00163         int length = 0;
00164 
00165         do {
00166                 sw = 0;
00167                 space = false;
00168 
00169                 searchFrom = GetWord(searchFrom, &word, &wordDescr.my_EndMark);
00170 
00171                 length = word.length();
00172                 if (length > 0) {
00173                         if (word[length - 1] == ' ') {
00174                                 space = true;
00175                                 word.erase(length-1, 1);
00176                         }
00177                 }
00178                 PG_FontEngine::GetTextSize(word, GetFont(), &w, &h, &bl, &ls);
00179                 wordDescr.my_Width = w;
00180                 if (space) {
00181                         word += ' ';
00182                         sw = my_sw;
00183                 }
00184                 wordDescr.my_Word = word;
00185                 wordDescr.my_EndSpaceWidth = sw;
00186                 wordDescr.my_WidthAfterFormating = w + sw;
00187                 wordDescr.my_Height = h;
00188                 wordDescr.my_BaseLine = bl;
00189                 wordDescr.my_LineSkip = ls;
00190 
00191                 my_ParsedWords.push_back(wordDescr);
00192 
00193                 if ((searchFrom != std::string::npos) && (searchFrom < my_text.length()))
00194                         searchFrom++;
00195                 else
00196                         break;
00197         } while (true);
00198 }
00199 
00200 size_t PG_RichEdit::GetWord(size_t searchFrom, PG_String *word, Uint32 *endMark) {
00201         size_t ik, length = my_text.length(), result = PG_String::npos;
00202 
00203         *endMark = my_Marks[MARK_SPACE];
00204 
00205         if (searchFrom >= my_text.length()) {
00206                 return std::string::npos;
00207         }
00208 
00209         for (ik = searchFrom; ik < length; ik++) {
00210                 for (Uint32 jk = 0; jk < MARKS_COUNT; jk++) {
00211                         if ((Uint32)my_text[ik] == my_Marks[jk]) {
00212                                 *endMark = my_Marks[jk];
00213                                 result = ik;
00214                                 jk = MARKS_COUNT;
00215                                 ik = length;
00216                                 break;
00217                         }
00218                 }
00219         }
00220 
00221         if (result != std::string::npos) {
00222                 size_t increment = 1;
00223 
00224                 if ((Uint32)my_text[result] != my_Marks[MARK_SPACE]) {
00225                         increment = 0;
00226                 }
00227                 *word = my_text.substr(searchFrom, result - searchFrom + increment);
00228 
00229                 // Candid - cut too long words, if wanted
00230                 if (!my_AutoHorizontalResize) {
00231                         Uint16 width, i = word->size() - 1, w;
00232                         PG_FontEngine::GetTextSize(*word, GetFont(), &width);
00233 
00234                         if (width > my_width) {
00235                                 for (; width > my_width && i > 0; --i) {
00236                                         PG_FontEngine::GetTextSize(word->substr(i, 1), GetFont(), &w);
00237                                         width -= w;
00238                                 }
00239                                 result -= word->size() - i + 1;
00240                                 *word = word->substr(0, i);
00241                         }
00242                 }
00243 
00244                 if ((Uint32)my_text[result] == my_Marks[MARK_NONBREAKABLE_SPACE]) {
00245                         PG_String newword;
00246 
00247                         *word += " ";
00248                         result = GetWord(result + 1, &newword, endMark);
00249                         *word += newword;
00250                 }
00251         } else {
00252                 *word = my_text.substr(searchFrom);
00253                 // Candid - cut too long words, if wanted
00254                 if (!my_AutoHorizontalResize) {
00255                         Uint16 width, i = word->size() - 1, w;
00256                         PG_FontEngine::GetTextSize(*word, GetFont(), &width);
00257 
00258                         if (width > my_width) {
00259                                 for (; width > my_width && i > 0; --i) {
00260                                         PG_FontEngine::GetTextSize(word->substr(i, 1), GetFont(), &w);
00261                                         width -= w;
00262                                 }
00263                                 *word = word->substr(0, i);
00264                         }
00265                 }
00266         }
00267 
00268         return result;
00269 }
00270 
00271 Sint32 PG_RichEdit::CompleteLines() {
00272         my_RichText.clear();
00273 
00274         if (my_text.length() == 0)
00275                 return 0;
00276 
00277         Uint32 lineSpace = 0;
00278         Sint32 top = 0;
00279         size_t searchFrom = 0;
00280         bool changeAlign = false;
00281 
00282         do {
00283                 Uint32 lineAscent = 0;
00284                 Uint32 lineSpaceOld = lineSpace;
00285                 size_t searchFromOld = searchFrom;
00286 
00287                 RichLineArray::iterator actualLine = my_RichText.insert(my_RichText.end(), RichLine(top));
00288 
00289                 searchFrom = CompleteLine(actualLine, top, searchFrom, lineSpace, lineAscent, changeAlign);
00290 
00291                 if (lineSpace != lineSpaceOld) {
00292                         my_RichText.erase(actualLine);
00293                         searchFrom = searchFromOld;
00294                         changeAlign = true;
00295                 } else {
00296                         actualLine->my_BaseLine += lineAscent;
00297 
00298                         actualLine->my_LineSpace = lineSpace;
00299                         top += lineSpace;
00300                         lineSpace = 0;
00301                         changeAlign = false;
00302                 }
00303 
00304         } while(searchFrom < my_ParsedWords.size());
00305 
00306         if (top > my_scrollarea->GetAreaHeight()) {
00307                 my_scrollarea->SetAreaHeight(top);
00308                 if( my_scrollarea->GetAreaWidth() != my_width - my_objVerticalScrollbar->my_width) { // my_objVerticalScrollbar->IsVisible() &&
00309                         SetLineWidth(my_width - my_objVerticalScrollbar->my_width);
00310                 }
00311         }
00312 
00313         if(my_AutoVerticalResize || my_AutoHorizontalResize) {
00314                 Uint16 w = my_width, h = my_height;
00315                 if (my_AutoVerticalResize) {
00316                         h = GetListHeight();
00317                 }
00318                 if(my_AutoHorizontalResize) {
00319                         w = GetListWidth();
00320                 }
00321                 SizeWidget(w, h, false);
00322         } else {
00323                 CheckScrollBars();
00324         }
00325 
00326         Update();
00327 
00328         return top;
00329 }
00330 
00331 size_t PG_RichEdit::CompleteLine(RichLineArray::iterator actualLine, Sint32 &lineTop, size_t searchFrom, Uint32 &lineSpace, Uint32 &lineAscent, bool changeAlign) {
00332         bool breakLine = false;
00333 
00334         Sint32 linePartLeft = 0;
00335         Sint32 linePartWidthMax = my_scrollarea->GetAreaWidth();
00336         WidgetMap widgetsOnLine;
00337 
00338         Uint32 align = my_Align;
00339 
00340         GetWidgetsOnLine(lineTop, lineSpace, widgetsOnLine, true);
00341 
00342         WidgetMap::iterator childOnLine = widgetsOnLine.begin();
00343 
00344         if ((align == my_Marks[MARK_ALL_LEFT]) || (align == my_Marks[MARK_ALL_CENTER]) || (align == my_Marks[MARK_ALL_RIGHT])) {
00345                 size_t size;
00346                 Uint32 maxHeight = lineSpace;
00347 
00348                 do {
00349                         WidgetMap::iterator widget;
00350 
00351                         for (widget = widgetsOnLine.begin(); widget != widgetsOnLine.end(); widget++) {
00352                                 PG_Point coord = ScreenToClient(widget->second->my_xpos, widget->second->my_ypos);
00353                                 if (widget->second->my_height > maxHeight)
00354                                         maxHeight = widget->second->my_height;
00355                                 //align widgets to line top
00356                                 widget->second->MoveWidget(coord.x, lineTop);
00357                         }
00358                         for (widget = widgetsOnLine.begin(); widget != widgetsOnLine.end(); widget++) {
00359                                 //align widgets to line bottom
00360                                 PG_Point coord = ScreenToClient(widget->second->my_xpos, widget->second->my_ypos);
00361                                 widget->second->MoveWidget(coord.x, coord.y + maxHeight - widget->second->my_height);
00362                                 coord = ScreenToClient(widget->second->my_xpos, widget->second->my_ypos);
00363                                 lineTop = (coord.y + widget->second->my_height) - lineSpace;
00364                         }
00365                         size = widgetsOnLine.size();
00366                         GetWidgetsOnLine(lineTop, maxHeight, widgetsOnLine, false);
00367                 } while (size != widgetsOnLine.size());
00368 
00369                 actualLine->my_BaseLine = lineTop;
00370 
00371                 childOnLine = widgetsOnLine.begin();
00372         }
00373 
00374         do {
00375                 // !!!
00376                 if (my_objVerticalScrollbar->IsVisible())
00377                         linePartWidthMax = my_scrollarea->GetAreaWidth() - linePartLeft - my_objVerticalScrollbar->my_width;
00378                 else
00379                         linePartWidthMax = my_scrollarea->GetAreaWidth() - linePartLeft;
00380                 if (childOnLine != widgetsOnLine.end())
00381                         linePartWidthMax = childOnLine->first - linePartLeft;
00382                 RichLinePartArray::iterator actualLinePart = actualLine->my_LineParts.insert(actualLine->my_LineParts.end(), RichLinePart(linePartLeft, linePartWidthMax));
00383 
00384                 searchFrom = CompleteLinePart(searchFrom, lineTop, lineSpace, actualLine, actualLinePart, breakLine, lineAscent, changeAlign);
00385                 if (childOnLine == widgetsOnLine.end())
00386                         break;
00387 
00388                 if ((align == my_Marks[MARK_TEXT_LEFT]) || (align == my_Marks[MARK_TEXT_CENTER]) || (align == my_Marks[MARK_TEXT_RIGHT]) || (align == my_Marks[MARK_TEXT_BLOCK])) {
00389                         PG_Point coord = ScreenToClient(childOnLine->second->my_xpos, childOnLine->second->my_ypos);
00390 
00391                         if (coord.y >= lineTop) {
00392                                 childOnLine->second->MoveWidget(coord.x, lineTop);
00393                         }
00394                 }
00395 
00396                 linePartLeft = childOnLine->first + childOnLine->second->my_width + (2 * my_ChildsBorderWidth);
00397                 childOnLine++;
00398         } while ((searchFrom < my_ParsedWords.size()) && (breakLine == false));
00399 
00400         AlignLine(actualLine, widgetsOnLine, align);
00401 
00402 
00403         return searchFrom;
00404 }
00405 
00406 void PG_RichEdit::AlignLine(RichLineArray::iterator actualLine, WidgetMap &widgetsOnLine, Uint32 align) {
00407         if ((align == my_Marks[MARK_ALL_LEFT]) || (align == my_Marks[MARK_ALL_CENTER]) || (align == my_Marks[MARK_ALL_RIGHT])) {
00408                 WidgetMap::iterator widget;
00409                 RichLinePartArray::iterator linePart;
00410                 Sint32 lineWidth = 0, delta = 0;
00411 
00412                 for (linePart = actualLine->my_LineParts.begin(); linePart < actualLine->my_LineParts.end(); linePart++) {
00413                         Sint32 width = linePart->Width(my_ParsedWords);
00414 
00415                         if (((Sint32)linePart->my_Left + width) > lineWidth)
00416                                 lineWidth = linePart->my_Left + width;
00417                 }
00418                 for (widget = widgetsOnLine.begin(); widget != widgetsOnLine.end(); widget++) {
00419                         PG_Point coord = ScreenToClient(widget->second->my_xpos, widget->second->my_ypos);
00420 
00421                         if ((coord.x + widget->second->my_width) > lineWidth)
00422                                 lineWidth = coord.x + widget->second->my_width;
00423                 }
00424 
00425                 if (align == my_Marks[MARK_ALL_CENTER])
00426                         delta = (my_scrollarea->GetAreaWidth() / 2) - (lineWidth / 2);
00427                 else if (align == my_Marks[MARK_ALL_RIGHT])
00428                         delta = my_scrollarea->GetAreaWidth() - lineWidth;
00429 
00430                 if (align != my_Marks[MARK_ALL_LEFT]) {
00431                         for (linePart = actualLine->my_LineParts.begin(); linePart < actualLine->my_LineParts.end(); linePart++) {
00432                                 linePart->my_Left += delta;
00433                         }
00434                         for (widget = widgetsOnLine.begin(); widget != widgetsOnLine.end(); widget++) {
00435                                 PG_Point coord = ScreenToClient(widget->second->my_xpos, widget->second->my_ypos);
00436 
00437                                 widget->second->MoveWidget(coord.x + delta, coord.y);
00438                         }
00439                 }
00440         }
00441 }
00442 
00443 Sint32 PG_RichEdit::CompleteLinePart(size_t searchFrom, Sint32 lineTop, Uint32 &lineSpace, RichLineArray::iterator actualLine, RichLinePartArray::iterator actualLinePart, bool &breakLine, Uint32 &lineAscent, bool changeAlign) {
00444         breakLine = false;
00445 
00446         Sint32 w = 0, h = 0, ls = 0, lb = 0;
00447         Sint32 lineWidth = 0;
00448 
00449         int align = my_Align;
00450 
00451         bool linePartEnd = false;
00452 
00453         while ((!linePartEnd) && (!breakLine)) {
00454                 Uint32          oldFind = searchFrom, tabSize = 0;
00455 
00456                 w = my_ParsedWords[searchFrom].my_Width + my_ParsedWords[searchFrom].my_EndSpaceWidth;
00457                 h = my_ParsedWords[searchFrom].my_Height;
00458                 lb = my_ParsedWords[searchFrom].my_BaseLine;
00459                 ls = my_ParsedWords[searchFrom].my_LineSkip;
00460 
00461                 if (my_ParsedWords[searchFrom].my_EndMark == my_Marks[MARK_ENTER]) {
00462                         breakLine = true;
00463                 } else if (my_ParsedWords[searchFrom].my_EndMark == my_Marks[MARK_TAB]) {
00464                         if (my_TabSize > 0) {
00465                                 tabSize = my_TabSize - ((actualLinePart->my_Left + lineWidth + w) % my_TabSize);
00466                                 w += tabSize;
00467                         }
00468                 } else if ((my_ParsedWords[searchFrom].my_EndMark == my_Marks[MARK_TEXT_LEFT]   ||
00469                             my_ParsedWords[searchFrom].my_EndMark == my_Marks[MARK_TEXT_CENTER] ||
00470                             my_ParsedWords[searchFrom].my_EndMark == my_Marks[MARK_TEXT_RIGHT]  ||
00471                             my_ParsedWords[searchFrom].my_EndMark == my_Marks[MARK_TEXT_BLOCK]) &&
00472                            (my_ParsedWords[searchFrom].my_EndMark != my_Align)) {
00473                         if (changeAlign) {
00474                                 my_Align = my_ParsedWords[searchFrom].my_EndMark;
00475                                 if ((lineWidth + w) > 0)    //if align change mark is not first character on the line part
00476                                 {
00477                                         linePartEnd = true;
00478                                 } else {
00479                                         align = my_Align;
00480                                 }
00481                         }
00482                 } else if ((my_ParsedWords[searchFrom].my_EndMark == my_Marks[MARK_ALL_LEFT]   ||
00483                             my_ParsedWords[searchFrom].my_EndMark == my_Marks[MARK_ALL_CENTER] ||
00484                             my_ParsedWords[searchFrom].my_EndMark == my_Marks[MARK_ALL_RIGHT]) &&
00485                            (my_ParsedWords[searchFrom].my_EndMark != my_Align)) {
00486                         if (changeAlign) {
00487                                 my_Align = my_ParsedWords[searchFrom].my_EndMark;
00488                                 breakLine = true;
00489                         }
00490                 }
00491 
00492                 if ((lineWidth + w) > actualLinePart->my_WidthMax) {
00493                         if (my_ParsedWords[searchFrom].my_EndSpaceWidth > 0) {
00494                                 w = my_ParsedWords[searchFrom].my_Width;
00495                         } else if (my_ParsedWords[searchFrom].my_EndMark == my_Marks[MARK_TAB]) {
00496                                 w -= tabSize;
00497                         }
00498                         linePartEnd = true;
00499                 }
00500 
00501                 lineWidth += w;
00502 
00503                 if (lineWidth > actualLinePart->my_WidthMax) {
00504                         my_Align = align;
00505                         breakLine = false;
00506                         searchFrom = oldFind - 1;
00507 
00508                         if (w > actualLinePart->my_WidthMax) {
00509                                 if(my_AutoHorizontalResize) {
00510                                         searchFrom--;
00511                                         linePartEnd = false;
00512                                         my_scrollarea->SetAreaWidth(lineWidth);
00513                                 }
00514                         } else if (actualLinePart->my_WordIndexes.size() == 0) {
00515                                 //searchFrom++;
00516                                 lineSpace = my_ParsedWords[searchFrom + 1].my_LineSkip;
00517                         }
00518                         //linePartEnd = true;
00519                 } else {
00520                         if ((my_ParsedWords[searchFrom].my_Word.length() > 0) || (tabSize > 0)) {
00521                                 if ((Uint32)ls > lineSpace)
00522                                         lineSpace = ls;
00523                                 if ((Uint32)lb > lineAscent)
00524                                         lineAscent = lb;
00525 
00526                                 actualLinePart->my_WordIndexes.push_back(searchFrom);
00527                                 my_ParsedWords[searchFrom].my_WidthAfterFormating = w;
00528                         }
00529                 }
00530                 if (++searchFrom >= my_ParsedWords.size())
00531                         linePartEnd = true;
00532         }
00533 
00534         //remove last space character in last word
00535         Sint32 nwords = actualLinePart->my_WordIndexes.size();
00536 
00537         if (nwords > 0)
00538                 my_ParsedWords[actualLinePart->my_WordIndexes[nwords - 1]].my_WidthAfterFormating = my_ParsedWords[actualLinePart->my_WordIndexes[nwords - 1]].my_Width;
00539 
00540         AlignLinePart(actualLinePart, align, breakLine);
00541         return searchFrom;
00542 }
00543 
00544 void PG_RichEdit::AlignLinePart(RichLinePartArray::iterator actualLinePart, Uint32 align, bool breakLine) {
00545         Uint32 width = 0;
00546 
00547         if ((align == my_Marks[PG_TEXT_CENTER]) || (align == my_Marks[PG_TEXT_RIGHT]) || (align == my_Marks[PG_TEXT_BLOCK])) {
00548                 width = actualLinePart->Width(my_ParsedWords);
00549 
00550                 if (align == my_Marks[PG_TEXT_CENTER])
00551                         actualLinePart->my_Left += (actualLinePart->my_WidthMax / 2) - (width / 2);
00552                 else if (align == my_Marks[PG_TEXT_RIGHT])
00553                         actualLinePart->my_Left += actualLinePart->my_WidthMax - width;
00554                 else if (align == my_Marks[PG_TEXT_BLOCK]) {
00555                         if (!breakLine) {
00556                                 Sint32 nwords = actualLinePart->my_WordIndexes.size();
00557 
00558                                 if (nwords > 1) {
00559                                         Uint32 addToSpace = (actualLinePart->my_WidthMax - width) / (nwords - 1);
00560                                         Sint32 rest = (actualLinePart->my_WidthMax - width) % (nwords - 1);
00561 
00562                                         for (Sint32 ik = 0, jk = 0; ik < (nwords - 1); ik++) {
00563                                                 my_ParsedWords[actualLinePart->my_WordIndexes[ik]].my_WidthAfterFormating += (addToSpace + (jk++ < rest));
00564                                         }
00565                                 }
00566                         }
00567                 }
00568         }
00569 }
00570 
00571 void PG_RichEdit::GetWidgetsOnLine(Sint32 lineTop, Uint32 lineHeight, WidgetMap &widgetsOnLine, bool clear) {
00572         PG_Widget* child;
00573 
00574         if (clear)
00575                 widgetsOnLine.clear();
00576 
00577         PG_RectList* list = my_scrollarea->GetChildList();
00578         if(list == NULL) {
00579                 return;
00580         }
00581 
00582         for (child = list->first(); child != NULL; child = child->next()) {
00583                 PG_Point coord = ScreenToClient(child->my_xpos, child->my_ypos);
00584 
00585                 if ((lineTop < (coord.y + child->my_height)) && ((lineTop + (Sint32)lineHeight) >= coord.y)) {
00586                         bool insert = true;
00587 
00588                         if (!clear) {
00589                                 WidgetMap::iterator header;
00590 
00591                                 for (header = widgetsOnLine.begin(); header != widgetsOnLine.end(); header++) {
00592                                         if (child == header->second) {
00593                                                 insert = false;
00594                                                 break;
00595                                         }
00596                                 }
00597                         }
00598                         if (insert) {
00599                                 widgetsOnLine.insert(WidgetMap::value_type(coord.x - my_ChildsBorderWidth, child));
00600                         }
00601                 }
00602         }
00603 }
00604 
00605 bool PG_RichEdit::ProcessLongLine(PG_String &word, size_t &searchFrom, Uint32 oldFind, Sint32 lineTop, Uint32 &lineSpace, bool normalLine, RichLineArray::iterator actualLine, RichLinePartArray::iterator actualLinePart, Uint32 &lineAscent) {
00606         /*Sint32          w = 0, h = 0, ls = 0, la = 0;
00607         PG_FontParam    newFont; 
00608         PG_FontParam    CurFont = my_font;
00609 
00610         WidgetMap widgetsOnLine;
00611            
00612         for (size_t ik = 0; ik < word.length(); ik++) 
00613         {                            
00614             if (word[ik] == my_FontBeginMark)        
00615             {
00616             ik += CurFont.FormatTagProc(&word[ik], 0);
00617             }
00618             
00619             string newword = word.substr(0, ((ik == string::npos) ? ik : ik + 1));           
00620             PG_FontEngine::GetTextSize(newword.c_str(), GetFont(), &w, &h, &la, &ls, NULL, NULL, NULL);
00621 
00622             if (w > (Sint32)my_listwidth)
00623             {                                                                                                         
00624                 if (normalLine) 
00625                 {                                        
00626                     GetWidgetsOnLine(lineTop + lineSpace, lineSpace, widgetsOnLine, true);
00627                     
00628                     if (widgetsOnLine.size() > 0)
00629                     {
00630                         searchFrom = oldFind - 1;                                                                 
00631                         return false;
00632                     }
00633                 }
00634                 else my_RichText.erase(actualLine);
00635                 newword = word.substr(0, ik);                        
00636                 PG_FontEngine::GetTextSize(newword.c_str(), GetFont(), &w, &h, &la, &ls, NULL, NULL, NULL);
00637                 actualLine = my_RichText.insert(my_RichText.end(), RichLine(lineTop));            
00638                 actualLinePart = actualLine->my_LineParts.insert(actualLine->my_LineParts.end(), RichLinePart(0, my_listwidth));
00639                 actualLinePart->my_Left = 0;                    
00640                 actualLinePart->my_Words.push_back(RichWordDescription(newword, (Uint32)w));               
00641                 *defaultFont = newFont;            
00642                             
00643                 if ((Uint32)ls > lineSpace) lineSpace = ls;
00644                 if ((Uint32)la > lineAscent) lineAscent = la;
00645 
00646                 if (searchFrom == my_text.npos) searchFrom = my_text.length() - 1;                                                        
00647                 searchFrom -= (word.length() - ik);  
00648                 break;            
00649             }  
00650         }    */
00651         return true;
00652 }
00653 
00654 bool PG_RichEdit::LoadText(const std::string& textfile) {
00655         PG_DataContainer* text = PG_FileArchive::ReadFile(textfile);
00656 
00657         if(text == NULL) {
00658                 return false;
00659         }
00660 
00661         // Hmm,...
00662         // size() returns the number of loaded bytes. We have to terminate the text with 0.
00663         // Last character will be truncated by this (i love valgrind).
00664         text->data()[text->size()-1] = 0;
00665         SetText(text->data());
00666 
00667         delete text;
00668         return true;
00669 }
00670 
00671 void PG_RichEdit::SetTabSize(Uint16 tabSize) {
00672         my_TabSize = tabSize;
00673 }
00674 
00675 bool PG_RichEdit::handleScrollTrack() {
00676         my_scrollarea->Update();
00677         return true;
00678 }
00679 
00680 void PG_RichEdit::SetLineWidth(Uint16 lineWidth) {
00681         my_LineWidth = lineWidth;
00682         SetText(GetText());
00683 }
00684 
00685 void PG_RichEdit::eventSizeWidget(Uint16 w, Uint16 h) {
00686         PG_ScrollWidget::eventSizeWidget(w, h);
00687         SetLineWidth(w);
00688 }

Generated on Tue Jun 24 01:27:49 2008 for Advanced Strategic Command by  doxygen 1.4.2