int EBuffer::KillChar() { int Y = VToR(CP.Row); if (CP.Col < LineLen()) { if (DelText(Y, CP.Col, 1)) return 1; } else if (LineJoin()) return 1; return 0; }
int EBuffer::KillLine() { int Y = VToR(CP.Row); if (Y == RCount - 1) { if (DelText(Y, 0, LineLen())) return 1; } else if (DelLine(Y)) return 1; return 0; }
int EBuffer::MoveRight() { if (CursorWithinEOL == 1 && CP.Col == LineLen()) { if (MoveDown()) return MoveLineStart(); else return 0; } SetPos(CP.Col + 1, CP.Row, tmRight); return 1; }
int EBuffer::KillWordPrev() { int Y = VToR(CP.Row); if (CP.Col == 0) { if (KillCharPrev() == 0) return 0; } else if (CP.Col > LineLen()) { if (SetPos(LineLen(), CP.Row) == 0) return 0; } else { PELine L = RLine(Y); int P = CharOffset(L, CP.Col); int C; int Class = ChClassK(L->Chars[P - 1]); while ((P > 0) && (ChClassK(L->Chars[P - 1]) == Class)) P--; C = ScreenPos(L, P); if (DelText(Y, C, CP.Col - C) == 0) return 0; if (SetPos(C, CP.Row) == 0) return 0; } return 1; }
int EBuffer::InsertString(const char *aStr, int aCount) { int P; int C, L; int Y = VToR(CP.Row); if (BFI(this, BFI_InsertKillBlock) == 1) if (CheckBlock() == 1) if (BlockKill() == 0) return 0; if (BFI(this, BFI_Insert) == 0) if (CP.Col < LineLen()) if (KillChar() == 0) return 0; if (InsText(Y, CP.Col, aCount, aStr) == 0) return 0; C = CP.Col; L = VToR(CP.Row); P = CharOffset(RLine(L), C); P += aCount; C = ScreenPos(RLine(L), P); if (SetPos(C, CP.Row) == 0) return 0; if (BFI(this, BFI_Trim) && *aStr != '\t') if (TrimLine(L) == 0) return 0; if (BFI(this, BFI_WordWrap) == 2) { if (DoWrap(0) == 0) return 0; } else if (BFI(this, BFI_WordWrap) == 1) { int P, C = CP.Col; PELine LP; int L; if (C > BFI(this, BFI_RightMargin)) { L = CP.Row; C = BFI(this, BFI_RightMargin); P = CharOffset(LP = RLine(L), C); while ((C > BFI(this, BFI_LeftMargin)) && ((LP->Chars[P] != ' ') && (LP->Chars[P] != 9))) C = ScreenPos(LP, --P); if (P <= BFI(this, BFI_LeftMargin)) { C = BFI(this, BFI_RightMargin); } else C = ScreenPos(LP, P); if (SplitLine(L, C) == 0) return 0; IndentLine(L + 1, BFI(this, BFI_LeftMargin)); if (SetPos(CP.Col - C - 1 + BFI(this, BFI_LeftMargin), CP.Row + 1) == 0) return 0; } } return 1; }
int EBuffer::MoveEndLinePageFile() { int L = GetVPort()->TP.Row + GetVPort()->Rows - 1; int Len = LineLen(); if (CP.Col == Len && CP.Row == L) return MoveFileEnd(); else if (CP.Col == Len) if (MovePageEnd() == 0) return 0; return MoveLineEnd(); }
int EBuffer::MoveLastNonWhite() { int C = LineLen(), P; PELine L = VLine(CP.Row); while (C > 0) { if (L->Chars[C - 1] == ' ' || L->Chars[C - 1] == 9) C--; else break; } P = ScreenPos(VLine(CP.Row), C); if (SetPos(P, CP.Row) == 0) return 0; return 1; }
int EBuffer::Delete() { int Y = VToR(CP.Row); if (CheckBlock() == 1 && BFI(this, BFI_DeleteKillBlock)) { if (BlockKill() == 0) return 0; } else if (CP.Col < LineLen()) { if (BFI(this, BFI_DeleteKillTab)) { int P; int C = CP.Col, C1; P = CharOffset(RLine(Y), C); C1 = ScreenPos(RLine(Y), P + 1); if (DelText(Y, C, C1 - C) == 0) return 0; } else { ELine *L = RLine(Y); int C = CharOffset(L, CP.Col); if (L->Count > 0 && L->Chars[C] == '\t') { /* We're on top of tab character. Skip over all spaces and tabs so that only the last space/tab gets deleted. */ while (C < L->Count && (L->Chars[C+1] == '\t' || L->Chars[C+1] == ' ')) C++; } if (DelText(Y, ScreenPos(L, C), 1) == 0) return 0; } } else if (LineJoin() == 0) return 0; if (BFI(this, BFI_WordWrap) == 2) { if (DoWrap(0) == 0) return 0; if (CP.Col >= LineLen(Y)) if (CP.Row < VCount - 1) { if (SetPos(BFI(this, BFI_LeftMargin), CP.Row + 1) == 0) return 0; } } if (BFI(this, BFI_Trim)) if (TrimLine(VToR(CP.Row)) == 0) return 0; return 1; }
int EBuffer::InsPrevLineChar() { int L = VToR(CP.Row); int C = CP.Col, P; if (L > 0) { L--; if (C < LineLen(L)) { P = CharOffset(RLine(L), C); return InsertChar(RLine(L)->Chars[P]); } } return 0; }
int EBuffer::BlockSelectLine() { int Y = VToR(CP.Row); if (BlockUnmark() == 0) return 0; BlockMode = bmStream; if (SetBB(EPoint(Y, 0)) == 0) return 0; if (Y == RCount - 1) { if (SetBE(EPoint(Y, LineLen(Y))) == 0) return 0; } else { if (SetBE(EPoint(Y + 1, 0)) == 0) return 0; } return 1; }
int EBuffer::LineCenter() { if (LineTrim() == 0) return 0; int ind = LineIndented(VToR(CP.Row)); int left = BFI(this, BFI_LeftMargin); int right = BFI(this, BFI_RightMargin); int len = LineLen(); //int chs = len - ind; int newind = left + ((right - left) - (len - ind)) / 2; if (newind < left) newind = left; return IndentLine(VToR(CP.Row), newind); }
int EBuffer::KillWord() { int Y = VToR(CP.Row); if (CP.Col >= LineLen()) { if (KillChar() == 0) return 0; } else { PELine L = RLine(Y); int P = CharOffset(L, CP.Col); int C; int Class = ChClassK(L->Chars[P]); while ((P < L->Count) && (ChClassK(L->Chars[P]) == Class)) P++; C = ScreenPos(L, P); if (DelText(Y, CP.Col, C - CP.Col) == 0) return 0; } return 1; }
int EBuffer::InsertSpacesToTab(int TSize) { int P = CP.Col, P1; if (BFI(this, BFI_InsertKillBlock) == 1) if (CheckBlock() == 1) if (BlockKill() == 0) return 0; if (TSize <= 0) TSize = BFI(this, BFI_TabSize); P1 = NextTab(P, TSize); if (BFI(this, BFI_Insert) == 0) { if (CP.Col < LineLen()) if (DelText(VToR(CP.Row), CP.Col, P1 - P) == 0) return 0; } if (InsText(VToR(CP.Row), CP.Col, P1 - P, 0) == 0) return 0; if (SetPos(P1, CP.Row) == 0) return 0; return 1; }
int EBuffer::KillWordOrCap() { int Y = VToR(CP.Row); if (CP.Col >= LineLen()) { if (KillChar() == 0) return 0; } else { PELine L = VLine(CP.Row); int P = CharOffset(L, CP.Col); int C; int Class = ChClassK(L->Chars[P]); if (Class == 1) { if (WGETBIT(Flags.CapitalChars, L->Chars[P]) == 1) while ((P < L->Count) && (WGETBIT(Flags.CapitalChars, L->Chars[P]) == 1)) P++; while ((P < L->Count) && (WGETBIT(Flags.WordChars, L->Chars[P]) == 1) && (WGETBIT(Flags.CapitalChars, L->Chars[P]) == 0)) P++; } else while ((P < L->Count) && (ChClassK(L->Chars[P]) == Class)) P++; C = ScreenPos(L, P); if (DelText(Y, CP.Col, C - CP.Col) == 0) return 0; } return 1; }
/****************************************************************************** CreateCellFrame: Create a Cell frame. *******************************************************************************/ CreateCellFrame(PTERWND w,int level,LPINT pFrameNo,int y,int ScrY, LPINT pFrameHt,LPINT pScrFrameHt, int CurColHeight,int ScrCurColHeight, LPINT pFirstCellFrame, LPINT pTableRowHeight, LPINT pScrTableRowHeight,LPINT pCellX,int TableRowIndent, int PageNo,int TopLeftMargin,int ColumnNo,int sect,int PrevCell, LPINT pCellFramed, long FrameFirstLine, long FrameLastLine, UINT PassFlags, BOOL RowBreak, LPINT pCellWidth, int TextWidth,int MaxColumns, int ColumnSpace, int PageWdth, int ColumnX,int ColumnWidth, int BoxFrame, int ParaFrameId) { int TblCellHeight,LeftWidth,RightWidth,TopWidth,BotWidth,SpaceTop,SpaceBot; int row,CellLeftMarg,CellRightMarg,CellMargin,FrameSpaceHt; BOOL IsFirstCellFrame=FALSE; UINT border; int ParentLeftMargin,ParentRightMargin; int pad,i,x,PrevRowId=cell[PrevCell].row; COLORREF BorderColor[4]; long l; //dm("CreateCellFrame"); // define the argument for easy reference #define FrameNo (*pFrameNo) #define FrameHt (*pFrameHt) #define ScrFrameHt (*pScrFrameHt) #define FirstCellFrame (*pFirstCellFrame) #define TableRowHeight (*pTableRowHeight) #define ScrTableRowHeight (*pScrTableRowHeight) #define CellX (*pCellX) #define CellFramed (*pCellFramed) #define CellWidth (*pCellWidth) // calcualte parent cell margin if (level>0) { int ParentCell=cell[PrevCell].ParentCell; ParentLeftMargin=TwipsToPrtX(CellLeftMargin(w,ParentCell)); ParentRightMargin=TwipsToPrtX(CellRightMargin(w,ParentCell)); } else ParentLeftMargin=ParentRightMargin=0; // adjust y from any frame space before the row row=cell[PrevCell].row; FrameSpaceHt=TableRow[row].FrmSpcBef; if (FrameSpaceHt>0) { y+=FrameSpaceHt; ScrY+=PrtToScrY(FrameSpaceHt); } // update table row height if (FirstCellFrame==-1) { int MinHeight; FirstCellFrame=FrameNo; // first frame for the row MinHeight=TableRow[PrevRowId].MinHeight; if (True(TableRow[PrevRowId].flags&ROWFLAG_SPLIT) /*&& TableAux[PrevRowId].FirstPage==PageNo */ && MinHeight>0) MinHeight=0; // 20051201 - min-height not supported at page-bot/top to keep the row height within the page-body area if (MinHeight<0) MinHeight=-MinHeight; // exact match if (TableRow[PrevRowId].MinPictHeight>MinHeight) MinHeight=TableRow[PrevRowId].MinPictHeight; // height of the picture frames TableRowHeight=TwipsToPrtY(MinHeight); ScrTableRowHeight=TwipsToScrY(MinHeight); IsFirstCellFrame=TRUE; } // set the border and space top/bottom border=GetCellFrameBorder(w,PrevCell,&LeftWidth,&RightWidth,&TopWidth,&BotWidth,PageNo,BorderColor); if (CellAux[PrevCell].flags&CAUX_SET_TOP_SPACE) SpaceTop=TwipsToPrtY(cell[PrevCell].margin); // use extra space else { pad=CellTopPad(w,PrevCell); SpaceTop=TwipsToPrtY(TopWidth+pad); // 20070430 } pad=CellBotPad(w,PrevCell); SpaceBot=TwipsToPrtY(BotWidth+pad); // adjust the frame height FrameHt+=(SpaceTop+SpaceBot); ScrFrameHt+=PrtToScrY(SpaceTop+SpaceBot); // keep track of max row height TblCellHeight=0; // height contribute by this cell toward the row if (IsLastSpannedCell(w,PrevCell)) TblCellHeight=GetLastSpannedCellHeight(w,PrevCell,NULL,PageNo); // height contrinution of this cell toward the row height else if ((cell[PrevCell].RowSpan==1 || IsPageLastRow(w,cell[PrevCell].row,PageNo)) && !(cell[PrevCell].flags&CFLAG_ROW_SPANNED)) { TblCellHeight=FrameHt; if (cell[PrevCell].TextAngle!=0) TblCellHeight=TwipsToPrtY(MIN_VTEXT_CELL_HEIGHT); // vertical text does not affect the row height if (cell[PrevCell].flags&CFLAG_VALIGN_BASE) TblCellHeight+=CellAux[PrevCell].SpaceBefore; // add base alignment adjustment } if (TableRow[PrevRowId].MinHeight>=0) { if (TblCellHeight>TableRowHeight) TableRowHeight=TblCellHeight; } ScrTableRowHeight=PrtToScrY(TableRowHeight); if (RowBreak) { // last cell of the table int row=cell[PrevCell].row; // 20070104: check for a hidden row for (i=FirstCellFrame;i<=FrameNo;i++) { int LastLine=frame[i].PageLastLine; int FirstLine=frame[i].PageFirstLine; if (frame[i].empty) continue; if (i==FrameNo) { // the frame for the last cell not yet built FirstLine=FrameFirstLine; LastLine=FrameLastLine; } for (l=FirstLine;l<=LastLine;l++) { int height=LineHt(l); if (height>0 && LineLen(l)==1 && LineInfo(w,l,INFO_CELL) && IsHiddenLine(w,l)) height=0; if (height!=0) break; } if (l<=LastLine) break; } if (i>FrameNo) ScrTableRowHeight=TableRowHeight=0; // all text in the row hidden - hide the row TableRow[row].height=TableRowHeight; // record the updated table row height for (i=FirstCellFrame;i<=FrameNo;i++) { if (frame[i].level!=level) continue; frame[i].height=TableRowHeight; frame[i].ScrHeight=ScrTableRowHeight; } FirstCellFrame=-1; // reset for the next row } // create the empty row indentation frame if (IsFirstCellFrame) { int row=cell[PrevCell].row; // create the empty frame to reserve any frame space if (TableRow[row].FrmSpcBef>0) { int SpcBef=TableRow[row].FrmSpcBef; frame[FrameNo].empty=TRUE; frame[FrameNo].PageNo=PageNo; // 20070511 frame[FrameNo].level=level; frame[FrameNo].sect=sect; // section to which the frame belongs frame[FrameNo].x=CellX; frame[FrameNo].y=y+CurColHeight-SpcBef; // relative to top margin frame[FrameNo].ScrY=ScrY+ScrCurColHeight-PrtToScrY(SpcBef); // relative to top margin frame[FrameNo].width=TextWidth; frame[FrameNo].BoxFrame=BoxFrame; frame[FrameNo].ParaFrameId=ParaFrameId; if (ParaFrameId>0) frame[FrameNo].ZOrder=ParaFrame[ParaFrameId].ZOrder; if (!BorderShowing && level==0) frame[FrameNo].flags|=FRAME_RIGHTMOST; frame[FrameNo].height=SpcBef; frame[FrameNo].ScrHeight=PrtToScrY(SpcBef); FrameNo++; // advance to the next frame if (!InitFrame(w,FrameNo)) AbortTer(w,"Ran Out of Text Frame Table (CreateFrames 1)",1); if (FirstCellFrame>=0) FirstCellFrame=FrameNo; // first frame for the row } TableRow[PrevRowId].FirstFrame=FrameNo; // first frame of the row frame[FrameNo].empty=TRUE; frame[FrameNo].PageNo=PageNo; // 20070511 frame[FrameNo].level=level; frame[FrameNo].sect=sect; // section to which the frame belongs frame[FrameNo].y=y+CurColHeight; // relative to top margin frame[FrameNo].ScrY=ScrY+ScrCurColHeight; // relative to top margin frame[FrameNo].BoxFrame=BoxFrame; frame[FrameNo].ParaFrameId=ParaFrameId; if (ParaFrameId>0) frame[FrameNo].ZOrder=ParaFrame[ParaFrameId].ZOrder; frame[FrameNo].CellId=PrevCell; frame[FrameNo].width=TableRow[PrevRowId].CurIndent; // TableRowIndent; frame[FrameNo].x=CellX; frame[FrameNo].border=0; frame[FrameNo].RowId=PrevRowId; frame[FrameNo].height=FrameHt=TableRowHeight; frame[FrameNo].ScrHeight=ScrFrameHt=ScrTableRowHeight; frame[FrameNo].flags|=FRAME_FIRST_ROW_FRAME; CellX=CellX+frame[FrameNo].width; FrameNo++; // advance to the next frame if (!InitFrame(w,FrameNo)) AbortTer(w,"Ran Out of Text Frame Table (CreateFrames 1)",1); } // create any intervening empty cell frames FrameEmptyCells(w,PrevRowId,&CellFramed,PrevCell,&CellX,y+CurColHeight,TableRowHeight,&FrameNo,sect,PageNo); // create the text frame CellMargin=TwipsToPrtX(cell[PrevCell].margin); CellLeftMarg=TwipsToPrtX(CellLeftMargin(w,PrevCell)); CellRightMarg=TwipsToPrtX(CellRightMargin(w,PrevCell)); CellWidth=TwipsToPrtX(cell[PrevCell].width); frame[FrameNo].empty=FALSE; frame[FrameNo].PageNo=PageNo; // 20070511 frame[FrameNo].level=level; frame[FrameNo].sect=sect; // section to which the frame belongs frame[FrameNo].PageFirstLine=FrameFirstLine; frame[FrameNo].PageLastLine=FrameLastLine; frame[FrameNo].y=y+CurColHeight; // relative to top margin frame[FrameNo].ScrY=ScrY+ScrCurColHeight; // relative to top margin frame[FrameNo].BoxFrame=BoxFrame; frame[FrameNo].ParaFrameId=ParaFrameId; if (ParaFrameId>0) frame[FrameNo].ZOrder=ParaFrame[ParaFrameId].ZOrder; frame[FrameNo].shading=cell[PrevCell].shading; // shading percentage frame[FrameNo].BackColor=cell[PrevCell].BackColor; // background color if (cell[PrevCell].BackColor==CLR_WHITE && cell[PrevCell].ParentCell>0 && False(cell[PrevCell].flags&CFLAG_FORCE_BKND_CLR)) { // check if parent cell is non-white int ParentCell=cell[PrevCell].ParentCell; while (ParentCell>0) { if (cell[ParentCell].BackColor!=CLR_WHITE || True(cell[ParentCell].flags&CFLAG_FORCE_BKND_CLR)) break; ParentCell=cell[ParentCell].ParentCell; } if (ParentCell>0) { frame[FrameNo].BackColor=cell[PrevCell].BackColor; // 20060313 frame[FrameNo].flags|=FRAME_FORCE_BKND_CLR; // to foce drawing of white color if any } } frame[FrameNo].flags|=PassFlags; // flags for the pass if (cell[PrevCell].flags&CFLAG_FORCE_BKND_CLR) frame[FrameNo].flags|=FRAME_FORCE_BKND_CLR; // enforce background color even for default color frame[FrameNo].x=CellX; frame[FrameNo].width=CellWidth; frame[FrameNo].SpaceLeft=CellLeftMarg; if (HtmlMode && IsFirstCellFrame && border&BORDER_LEFT) frame[FrameNo].SpaceLeft+=ScrToPrtX(3); // add width of the html table border frame[FrameNo].SpaceRight=CellRightMarg; // record the frame x space for the row if (IsFirstCellFrame) TableAux[PrevRowId].FrmBegX=frame[FrameNo].x; TableAux[PrevRowId].FrmEndX=frame[FrameNo].x+frame[FrameNo].width;; frame[FrameNo].border=border; frame[FrameNo].BorderWidth[BORDER_INDEX_LEFT]=LeftWidth; frame[FrameNo].BorderWidth[BORDER_INDEX_RIGHT]=RightWidth; frame[FrameNo].BorderWidth[BORDER_INDEX_TOP]=TopWidth; frame[FrameNo].BorderWidth[BORDER_INDEX_BOT]=BotWidth; // set border color for (i=0;i<4;i++) frame[FrameNo].BorderColor[i]=BorderColor[i]; frame[FrameNo].RowId=PrevRowId; if (cell[PrevCell].flags&CFLAG_ROW_SPANNED) // set height frame[FrameNo].TextHeight=frame[FrameNo].height=frame[FrameNo].ScrHeight=0; else { frame[FrameNo].TextHeight=ScrFrameHt-PrtToScrY(SpaceBot); frame[FrameNo].height=TableRowHeight; frame[FrameNo].ScrHeight=ScrTableRowHeight; } FrameHt=TableRowHeight; ScrFrameHt=ScrTableRowHeight; frame[FrameNo].SpaceTop=SpaceTop; frame[FrameNo].SpaceBot=SpaceBot; frame[FrameNo].CellId=PrevCell; CellFramed=PrevCell; FrameNo++; // advance to the next frame if (!InitFrame(w,FrameNo)) AbortTer(w,"Ran Out of Text Frame Table (CreateFrames 4)",1); // on row break create an empty frame on the right to cover any blank area x=frame[FrameNo-1].x+frame[FrameNo-1].width; // right edge of the right most frame if (RowBreak) { if (true || level==0) FrameEmptyCells(w,PrevRowId,&CellFramed,0,&x,frame[FrameNo-1].y,frame[FrameNo-1].height,&FrameNo,sect,PageNo); TableRow[PrevRowId].LastFrame=FrameNo; frame[FrameNo].empty=TRUE; frame[FrameNo].PageNo=PageNo; // 20070511 frame[FrameNo].level=level; frame[FrameNo].y=frame[FrameNo-1].y; frame[FrameNo].ScrY=frame[FrameNo-1].ScrY; frame[FrameNo].x=x; frame[FrameNo].BoxFrame=BoxFrame; frame[FrameNo].ParaFrameId=ParaFrameId; if (ParaFrameId>0) frame[FrameNo].ZOrder=ParaFrame[ParaFrameId].ZOrder; frame[FrameNo].width=ColumnX+ColumnWidth+ColumnSpace-x; if (level==0) { if (ParaFrameId>0) { int right=frame[BoxFrame].x+frame[BoxFrame].width-frame[BoxFrame].BorderWidth[BORDER_INDEX_RIGHT]; frame[FrameNo].width=right-frame[FrameNo].x; } else if (BorderShowing) { if (MaxColumns==1 || ((ColumnNo+1)==MaxColumns)) { int sect=frame[FrameNo-1].sect; frame[FrameNo].width=PageWdth-LeftBorderWidth-(int)(TerSect[sect].RightMargin*PrtResX)-x; } else frame[FrameNo].flags|=FRAME_LINE_BET_COL; // line between columns } else { frame[FrameNo].flags|=FRAME_RIGHTMOST; if ((ColumnNo+1)<MaxColumns) frame[FrameNo].flags|=FRAME_LINE_BET_COL; // line between columns } } if (frame[FrameNo].width<0) frame[FrameNo].width=0; frame[FrameNo].height=frame[FrameNo-1].height; frame[FrameNo].ScrHeight=frame[FrameNo-1].ScrHeight; frame[FrameNo].sect=frame[FrameNo-1].sect; frame[FrameNo].RowId=frame[FrameNo-1].RowId; frame[FrameNo].CellId=frame[FrameNo-1].CellId; // set cell id so that frame height is adjusted properly when this frame is after a spanning cell frame frame[FrameNo].flags|=(PassFlags|FRAME_LAST_ROW_FRAME); // last frame for the row CellFramed=0; // initialize for the next row FrameNo++; // advance to the next frame if (!InitFrame(w,FrameNo)) AbortTer(w,"Ran Out of Text Frame Table (CreateFrames 4)",1); } // adjust FrameHt to FrameSpace before FrameHt+=FrameSpaceHt; ScrFrameHt+=PrtToScrY(FrameSpaceHt); // undefine the arguments; #undef FrameNo #undef FrameHt #undef ScrFrameHt #undef FirstCellFrame #undef TableRowHeight #undef ScrTableRowHeight #undef CellX #undef CellFramed #undef CellWidth return TRUE; }
int EBuffer::Find(SearchReplaceOptions &opt) { int slen = strlen(opt.strSearch); int Options = opt.Options; int rlen = strlen(opt.strReplace); RxNode *R = NULL; opt.resCount = -1; opt.lastInsertLen = 0; if (slen == 0) return 0; if (Options & SEARCH_BLOCK) { if (CheckBlock() == 0) return 0; } if (Options & SEARCH_RE) { R = RxCompile(opt.strSearch); if (R == 0) { View->MView->Win->Choice(GPC_ERROR, "Find", 1, "O&K", "Invalid regular expression."); return 0; } } if (Options & SEARCH_GLOBAL) { if (Options & SEARCH_BLOCK) { if (Options & SEARCH_BACK) { if (SetPosR(BE.Col, BE.Row) == 0) goto error; } else { if (SetPosR(BB.Col, BB.Row) == 0) goto error; } } else { if (Options & SEARCH_BACK) { if (RCount < 1) goto error; if (SetPosR(LineLen(RCount - 1), RCount - 1) == 0) goto error; } else { if (SetPosR(0, 0) == 0) goto error; } } } opt.resCount = 0; while (1) { if (Options & SEARCH_RE) { if (FindRx(R, opt) == 0) goto end; } else { if (FindStr(opt.strSearch, slen, opt) == 0) goto end; } opt.resCount++; if (opt.Options & SEARCH_REPLACE) { char ask = 'A'; if (!(Options & SEARCH_NASK)) { char ch; while (1) { Draw(VToR(CP.Row), 1); Redraw(); switch (View->MView->Win->Choice(0, "Replace", 5, "&Yes", "&All", "&Once", "&Skip", "&Cancel", "Replace with %s?", opt.strReplace)) { case 0: ch = 'Y'; break; case 1: ch = 'A'; break; case 2: ch = 'O'; break; case 3: ch = 'N'; break; case 4: case -1: default: ch = 'Q'; break; } if (ch == 'Y') { ask = 'Y'; goto ok_rep; } if (ch == 'N') { ask = 'N'; goto ok_rep; } if (ch == 'Q') { ask = 'Q'; goto ok_rep; } if (ch == 'A') { ask = 'A'; goto ok_rep; } if (ch == 'O') { ask = 'O'; goto ok_rep; } } ok_rep: if (ask == 'N') goto try_join; if (ask == 'Q') goto end; if (ask == 'A') Options |= SEARCH_NASK; } if (Options & SEARCH_RE) { PELine L = RLine(Match.Row); int P, R; char *PR = 0; int LR = 0; R = Match.Row; P = Match.Col; P = CharOffset(L, P); if (0 == RxReplace(opt.strReplace, L->Chars, L->Count, MatchRes, &PR, &LR)) { if (DelText(R, Match.Col, MatchLen) == 0) goto error; if (PR && LR > 0) if (InsText(R, Match.Col, LR, PR) == 0) goto error; if (PR) free(PR); rlen = LR; } } else { if (DelText(Match.Row, Match.Col, MatchLen) == 0) goto error; if (InsText(Match.Row, Match.Col, rlen, opt.strReplace) == 0) goto error; // Cursor remains at start of inserted string. If there is recursive // replace pattern, fte can go it infinite loop. // Workaround: Move cursor to end of inserted string opt.lastInsertLen = strlen(opt.strReplace); } if (!(Options & SEARCH_BACK)) { MatchLen = rlen; MatchCount = rlen; } if (ask == 'O') goto end; } try_join: if (Options & SEARCH_JOIN) { char ask = 'A'; if (!(Options & SEARCH_NASK)) { char ch; while (1) { Draw(VToR(CP.Row), 1); Redraw(); switch (View->MView->Win->Choice(0, "Join Line", 5, "&Yes", "&All", "&Once", "&Skip", "&Cancel", "Join lines %d and %d?", 1 + VToR(CP.Row), 1 + VToR(CP.Row) + 1)) { case 0: ch = 'Y'; break; case 1: ch = 'A'; break; case 2: ch = 'O'; break; case 3: ch = 'N'; break; case 4: case -1: default: ch = 'Q'; break; } if (ch == 'Y') { ask = 'Y'; goto ok_join; } if (ch == 'N') { ask = 'N'; goto ok_join; } if (ch == 'Q') { ask = 'Q'; goto ok_join; } if (ch == 'A') { ask = 'A'; goto ok_join; } if (ch == 'O') { ask = 'O'; goto ok_join; } } ok_join: if (ask == 'N') goto try_split; if (ask == 'Q') goto end; if (ask == 'A') Options |= SEARCH_NASK; } if (JoinLine(Match.Row, Match.Col) == 0) goto error; if (ask == 'O') goto end; } try_split: if (Options & SEARCH_SPLIT) { char ask = 'A'; if (!(Options & SEARCH_NASK)) { char ch; while (1) { Draw(VToR(CP.Row), 1); Redraw(); switch(View->MView->Win->Choice(0, "Split Line", 5, "&Yes", "&All", "&Once", "&Skip", "&Cancel", "Split line %d?", VToR(CP.Row))) { case 0: ch = 'Y'; break; case 1: ch = 'A'; break; case 2: ch = 'O'; break; case 3: ch = 'S'; break; case 4: case -1: default: ch = 'Q'; break; } if (ch == 'Y') { ask = 'Y'; goto ok_split; } else if (ch == 'N') { ask = 'N'; goto ok_split; } else if (ch == 'Q') { ask = 'Q'; goto ok_split; } else if (ch == 'A') { ask = 'A'; goto ok_split; } else if (ch == 'O') { ask = 'O'; goto ok_split; } } ok_split: if (ask == 'N') goto try_delete; if (ask == 'Q') goto end; if (ask == 'A') Options |= SEARCH_NASK; } if (SplitLine(Match.Row, Match.Col + strlen(opt.strReplace)) == 0) goto error; if (ask == 'O') goto end; } try_delete: if (Options & SEARCH_DELETE) { char ask = 'A'; if (!(Options & SEARCH_NASK)) { char ch; while (1) { Draw(VToR(CP.Row), 1); Redraw(); switch (View->MView->Win->Choice(0, "Delete Line", 5, "&Yes", "&All", "&Once", "&Skip", "&Cancel", "Delete line %d?", VToR(CP.Row))) { case 0: ch = 'Y'; break; case 1: ch = 'A'; break; case 2: ch = 'O'; break; case 3: ch = 'N'; break; case 4: case -1: default: ch = 'Q'; break; } if (ch == 'Y') { ask = 'Y'; goto ok_delete; } if (ch == 'N') { ask = 'N'; goto ok_delete; } if (ch == 'Q') { ask = 'Q'; goto ok_delete; } if (ch == 'A') { ask = 'A'; goto ok_delete; } if (ch == 'O') { ask = 'O'; goto ok_delete; } } ok_delete: if (ask == 'N') goto next; if (ask == 'Q') goto end; if (ask == 'A') Options |= SEARCH_NASK; } if (Match.Row == RCount - 1) { if (DelText(Match.Row, 0, LineLen()) == 0) goto error; } else if (DelLine(Match.Row) == 0) goto error; if (ask == 'O') goto end; if (!(Options & SEARCH_ALL)) break; goto last; } next: if (!(Options & SEARCH_ALL)) break; Options |= SEARCH_NEXT; last: ; } end: // end of search if (R) RxFree(R); if (Options & SEARCH_ALL) Msg(S_INFO, "%d match(es) found.", opt.resCount); else { if (opt.resCount == 0) { Msg(S_INFO, "[%s] not found", opt.strSearch); return 0; } } return 1; error: if (R) { RxFree(R); } View->MView->Win->Choice(GPC_ERROR, "Find", 1, "O&K", "Error in search/replace."); return 0; }
int EBuffer::LineLen() { return LineLen(VToR(CP.Row)); }
int EBuffer::MoveNext() { if (CP.Col < LineLen()) if (MoveRight()) return 1; if (MoveDown() && MoveLineStart()) return 1; return 0; }
/****************************************************************************** AcceptChange: Accept the current changed text. ******************************************************************************/ BOOL AcceptChange(PTERWND w, long line, int col) { int i,font,CurCfmt,RevId; long l,BegLine,EndLine; int BegCol,EndCol,StartPos,EndPos; LPWORD fmt; CurCfmt=GetCurCfmt(w,line,col); if (!IsTrackChangeFont(w,CurCfmt)) return false; BegLine=EndLine=line; BegCol=EndCol=col; if (!GetChangeBeginPos(w,&BegLine, &BegCol)) return false; if (!TerLocateChangedChar2(hTerWnd,TerFont[CurCfmt].InsRev,TerFont[CurCfmt].DelRev,TerFont[CurCfmt].FmtRev,false,&EndLine,&EndCol,true)) return false; // 20080626 // ** Accept deletion ** if (TerFont[CurCfmt].DelRev>0) { BOOL SaveUnprotDel=True(TerFlags&TFLAG_UNPROTECTED_DEL); HilightBegRow=BegLine; HilightBegCol=BegCol; HilightEndRow=EndLine; HilightEndCol=EndCol; StretchHilight=false; HilightType=HILIGHT_CHAR; TerFlags|=TFLAG_UNPROTECTED_DEL; TerDeleteBlock(hTerWnd,false); if (!SaveUnprotDel) ResetUintFlag(TerFlags,TFLAG_UNPROTECTED_DEL); return true; } // ** Accept insertion ** // Save undo for insertion SaveUndo(w,BegLine,BegCol,EndLine,EndCol,'F'); // save font ids // Reset reviewer ids for (l=BegLine;l<=EndLine;l++) { StartPos=(l==BegLine)?BegCol:0; EndPos=(l==EndLine)?EndCol:LineLen(l); // exclusive // scan each character in the line to perform indicated delete operation (regular delete or track-delete) fmt=OpenCfmt(w,l); for (i=StartPos;i<EndPos;i++) { font=fmt[i]; RevId=TerFont[font].InsRev; font=SetTrackingFont(w,font,TRACK_NONE); if (reviewer[RevId].InsColor==TerFont[font].TextColor) { // reset color font=(int)GetNewColor(w,(WORD)font,(DWORD)CLR_AUTO,0L,l,i); } if (True(reviewer[RevId].InsStyle&TerFont[font].style)) { // reset style font=SetFontStyle(w,font,reviewer[RevId].InsStyle,false); // reset the reviewer style } fmt[i]=font; } CloseCfmt(w,l); } TerArg.modified++; return true; }
int EBuffer::BackSpace() { int Y = VToR(CP.Row); if (CheckBlock() == 1 && BFI(this, BFI_BackSpKillBlock)) { if (BlockKill() == 0) return 0; } else if (BFI(this, BFI_WordWrap) == 2 && CP.Row > 0 && !IsLineBlank(Y - 1) && CP.Col <= BFI(this, BFI_LeftMargin) && CP.Col <= LineIndented(Y)) { if (SetPos(LineLen(Y - 1), CP.Row - 1) == 0) return 0; } else if (CP.Col == 0) { if (CP.Row > 0) if (ExposeRow(VToR(CP.Row) - 1) == 0) return 0; if (MoveUp() == 0) return 0; if (MoveLineEnd() == 0) return 0; if (LineJoin() == 0) return 0; } else { if (BFI(this, BFI_BackSpUnindents) && (LineIndented(Y) == CP.Col)) { int C = CP.Col, C1 = 0; int L = VToR(CP.Row); C1 = C; while (L > 0 && (IsLineBlank(L - 1) || (C1 = LineIndented(L - 1)) >= C)) L--; if (L == 0) C1 = 0; if (C1 == C) C1--; if (C1 < 0) C1 = 0; if (C1 > C) C1 = C; if (SetPos(C1, CP.Row) == 0) return 0; if (C > LineIndented(Y)) return 0; if (DelText(Y, C1, C - C1) == 0) return 0; if (BFI(this, BFI_Insert) == 0) if (InsText(Y, C1, 1, " ") == 0) return 0; } else if (BFI(this, BFI_BackSpKillTab)) { int P; int C = CP.Col, C1; P = CharOffset(RLine(Y), C - 1); C1 = ScreenPos(RLine(Y), P); if (SetPos(C1, CP.Row) == 0) return 0; if (DelText(Y, C1, C - C1) == 0) return 0; if (BFI(this, BFI_Insert) == 0) if (InsText(Y, C1, 1, " ") == 0) return 0; } else { if (MovePrev() == 0) return 0; ELine *L = RLine(Y); int C = CharOffset(L, CP.Col); if (L->Count > 0 && L->Chars[C] == 9) { /* We're on top of tab character. Skip over all spaces and tabs so that only the last space/tab gets deleted. */ while (C < L->Count && (L->Chars[C+1] == 9 || L->Chars[C+1] == ' ')) C++; } if (DelText(Y, ScreenPos(L, C), 1) == 0) return 0; if (BFI(this, BFI_Insert) == 0) if (InsText(Y, ScreenPos(L, C), 1, " ") == 0) return 0; } } if (BFI(this, BFI_WordWrap) == 2) { if (DoWrap(0) == 0) return 0; } if (BFI(this, BFI_Trim)) { Y = VToR(CP.Row); if (TrimLine(Y) == 0) return 0; } return 1; }
int EBuffer::KillToLineEnd() { int Y = VToR(CP.Row); if (DelText(Y, CP.Col, LineLen() - CP.Col)) return 1; return 0; }
BOOL WINAPI _export TerLocateChangedChar2(HWND hWnd, int InsRev, int DelRev, int FmtRev,BOOL present, long far *StartLine, int far *StartCol, BOOL forward) { PTERWND w; long line; int i,col,CurCfmt,CurInsRev,CurDelRev,CurFmtRev; LPWORD fmt; if (NULL==(w=GetWindowPointer(hWnd))) return false; // get the pointer to window data // reset the checked flag for (i=0;i<TotalFonts;i++) ResetUintFlag(TerFont[i].flags,FFLAG_CHECKED); // scan each line in the forward direction if (forward) { for (line=(*StartLine);line<TotalLines;line++) { if (line==(*StartLine)) col=*StartCol; else col=0; if (col>=LineLen(line)) continue; // go to next line if (LineLen(line)==0) continue; if (cfmt(line).info.type==UNIFORM) { CurCfmt=cfmt(line).info.fmt; if (True(TerFont[CurCfmt].flags&FFLAG_CHECKED)) continue; // this font id already checked TerFont[CurCfmt].flags|=FFLAG_CHECKED; CurInsRev=TerFont[CurCfmt].InsRev; CurDelRev=TerFont[CurCfmt].DelRev; CurFmtRev=TerFont[CurCfmt].FmtRev; if (LocateRevMatched(w,present,InsRev,DelRev,FmtRev,CurInsRev,CurDelRev,CurFmtRev)) { *StartLine=line; *StartCol=col; return true; } else continue; // style not found } // open the line fmt=OpenCfmt(w,line); for (i=col;i<LineLen(line);i++) { CurCfmt=fmt[i]; if (True(TerFont[CurCfmt].flags&FFLAG_CHECKED)) continue; // this font id already checked TerFont[CurCfmt].flags|=FFLAG_CHECKED; CurInsRev=TerFont[CurCfmt].InsRev; CurDelRev=TerFont[CurCfmt].DelRev; CurFmtRev=TerFont[CurCfmt].FmtRev; if (LocateRevMatched(w,present,InsRev,DelRev,FmtRev,CurInsRev,CurDelRev,CurFmtRev)) { *StartLine=line; *StartCol=i; CloseCfmt(w,line); return true; } } CloseCfmt(w,line); if (line==(TotalLines-1)) { // 20080530: end of the file reached *StartLine=line; *StartCol=LineLen(line); return true; } } } else { // scan each line in the backward direction for (line=(*StartLine);line>=0;line--) { if (line==(*StartLine)) col=*StartCol; else col=LineLen(line)-1; if (col<0) continue; if (LineLen(line)==0) continue; if (cfmt(line).info.type==UNIFORM) { CurCfmt=cfmt(line).info.fmt; if (True(TerFont[CurCfmt].flags&FFLAG_CHECKED)) continue; // this font id already checked TerFont[CurCfmt].flags|=FFLAG_CHECKED; CurInsRev=TerFont[CurCfmt].InsRev; CurDelRev=TerFont[CurCfmt].DelRev; CurFmtRev=TerFont[CurCfmt].FmtRev; if (LocateRevMatched(w,present,InsRev,DelRev,FmtRev,CurInsRev,CurDelRev,CurFmtRev)) { *StartLine=line; *StartCol=col; return true; } else continue; // style not found } // open the line fmt=OpenCfmt(w,line); for (i=col;i>=0;i--) { CurCfmt=fmt[i]; if (True(TerFont[CurCfmt].flags&FFLAG_CHECKED)) continue; // this font id already checked TerFont[CurCfmt].flags|=FFLAG_CHECKED; CurInsRev=TerFont[CurCfmt].InsRev; CurDelRev=TerFont[CurCfmt].DelRev; CurFmtRev=TerFont[CurCfmt].FmtRev; if (LocateRevMatched(w,present,InsRev,DelRev,FmtRev,CurInsRev,CurDelRev,CurFmtRev)) { *StartLine=line; *StartCol=i; CloseCfmt(w,line); return true; } } CloseCfmt(w,line); } } return false; }
/****************************************************************************** RejectChange: Reject the current changed text. ******************************************************************************/ BOOL RejectChange(PTERWND w, long line, int col) { int i,font,CurCfmt,RevId; long l,BegLine,EndLine; int BegCol,EndCol,StartPos,EndPos; LPWORD fmt; CurCfmt=GetCurCfmt(w,line,col); if (!IsTrackChangeFont(w,CurCfmt)) return false; // ** reject deletion ** if (TerFont[CurCfmt].DelRev>0) { BegLine=EndLine=line; BegCol=EndCol=col; if (!GetDelBeginPos(w,&BegLine, &BegCol)) return false; // 20060929: since deletion happens after insertion, reject deletion including any previous insertion if (!TerLocateChangedChar(hTerWnd,-1,TerFont[CurCfmt].DelRev,false,&EndLine,&EndCol,true)) return false; // Save undo for insertion SaveUndo(w,BegLine,BegCol,EndLine,EndCol,'F'); // save font ids // Reset reviewer ids for (l=BegLine;l<=EndLine;l++) { StartPos=(l==BegLine)?BegCol:0; EndPos=(l==EndLine)?EndCol:LineLen(l); // exclusive // scan each character in the line to perform indicated delete operation (regular delete or track-delete) fmt=OpenCfmt(w,l); for (i=StartPos;i<EndPos;i++) { font=fmt[i]; RevId=TerFont[font].DelRev; font=SetTrackingFont(w,font,TRACK_NO_DEL); // 20060929: turn-off deletion if (false && reviewer[RevId].DelColor==TerFont[font].TextColor) { // 20060908: commented out - reset color font=(int)GetNewColor(w,(WORD)font,(DWORD)CLR_AUTO,0L,l,i); } if (True(reviewer[RevId].DelStyle&TerFont[font].style)) { // reset style font=SetFontStyle(w,font,reviewer[RevId].DelStyle,false); // reset the reviewer style } fmt[i]=font; } CloseCfmt(w,l); } TerArg.modified++; return true; } // ** reject font change, 20080626 if (TerFont[CurCfmt].FmtRev>0) { BegLine=EndLine=line; BegCol=EndCol=col; if (!GetChangeBeginPos(w,&BegLine, &BegCol)) return false; if (!TerLocateChangedChar2(hTerWnd,-1,-1,TerFont[CurCfmt].FmtRev,false,&EndLine,&EndCol,true)) return false; // Save undo for insertion SaveUndo(w,BegLine,BegCol,EndLine,EndCol,'F'); // save font ids // Reset to original font id for (l=BegLine;l<=EndLine;l++) { StartPos=(l==BegLine)?BegCol:0; EndPos=(l==EndLine)?EndCol:LineLen(l); // exclusive // scan each character in the line to perform indicated delete operation (regular delete or track-delete) fmt=OpenCfmt(w,l); for (i=StartPos;i<EndPos;i++) { font=fmt[i]; if (TerFont[font].FmtRev==0) continue; // this can happen when rejecting a formatted string within an inserted text font=TerFont[font].FmtOrigFont; // reset to original font RevId=TerFont[font].FmtRev; if (RevId>0) { // this should not happen since the orig-font would be a normal font font=SetTrackingFont(w,font,TRACK_NO_FMT); //inase the original font if (True(reviewer[RevId].FmtStyle&TerFont[font].style)) { // reset style font=SetFontStyle(w,font,reviewer[RevId].FmtStyle,false); // reset the reviewer style } } fmt[i]=font; } CloseCfmt(w,l); } TerArg.modified++; return true; } // ** Reject insertion ** if (TerFont[CurCfmt].InsRev>0) { BOOL SaveUnprotDel=True(TerFlags&TFLAG_UNPROTECTED_DEL); BegLine=EndLine=line; BegCol=EndCol=col; if (!GetChangeBeginPos(w,&BegLine, &BegCol)) return false; if (!TerLocateChangedChar(hTerWnd,TerFont[CurCfmt].InsRev,TerFont[CurCfmt].DelRev,false,&EndLine,&EndCol,true)) return false; HilightBegRow=BegLine; HilightBegCol=BegCol; HilightEndRow=EndLine; HilightEndCol=EndCol; StretchHilight=false; HilightType=HILIGHT_CHAR; TerFlags|=TFLAG_UNPROTECTED_DEL; TerDeleteBlock(hTerWnd,false); if (!SaveUnprotDel) ResetUintFlag(TerFlags,TFLAG_UNPROTECTED_DEL); return true; } return true; }
/****************************************************************************** TrackDelBlock: Delete the specified block of text in the tracking mode. The function returns TRUE if track-deletion is successful. ******************************************************************************/ BOOL TrackDelBlock(PTERWND w, long BegLine, int BegCol, long EndLine, int EndCol, BOOL ResetHilight, BOOL repaint) { long l; int i,StartPos,EndPos,font; LPWORD fmt; LPINT NewFont=NULL; BOOL TrackDelTextFound; // indicates the text that needs to be deleted using the tracking method (not by simply removing the character) BOOL IsTrackDelLine; BOOL RevInsertedLine; long DelCount=0,GroupUndoRef,EndAbsPos,NewFontMax; if (!TrackChanges) return false; // check if text the text to be deleted using tracking method exists in the block TrackDelTextFound=false; for (l=BegLine;l<=EndLine;l++) { if (False(LineFlags2(l)&LFLAG2_INS_REV)) { // no text in this line inserted by a reviewer TrackDelTextFound=true; // this line needs to be deleted using the tracking method break; } StartPos=(l==BegLine)?BegCol:0; EndPos=(l==EndLine)?EndCol:LineLen(l); // exclusive fmt=OpenCfmt(w,l); for (i=StartPos;i<EndPos;i++) { font=fmt[i]; if (TerFont[font].InsRev!=TrackRev) { TrackDelTextFound=true; // this text needs to be deleted using the tracking method break; } } CloseCfmt(w,l); if (TrackDelTextFound) break; } if (!TrackDelTextFound) return false; // normal deletion will do // undo consists of saving the original text, and marking the resultant text as inserted EndAbsPos=RowColToAbs(w,EndLine,EndCol); GroupUndoRef=UndoRef; SaveUndo(w,BegLine,BegCol,EndLine,EndCol-1,'D'); // save undo // use font cache to better efficiency: 20070927 NewFontMax=TotalFonts; NewFont=MemAlloc(sizeof(int)*(NewFontMax+1)); for (i=0;i<NewFontMax;i++) NewFont[i]=-1; // 20070927: temporary field to store new font id generated for an existing font id // scan the range of text and do deletion of both types (regular delete and track-delete) for (l=BegLine;l<=EndLine;l++) { StartPos=(l==BegLine)?BegCol:0; EndPos=(l==EndLine)?EndCol:LineLen(l); // exclusive IsTrackDelLine=(False(LineFlags2(l)&LFLAG2_INS_REV)); // no text in this line inserted by a reviewer if (IsTrackDelLine) { // do track delete of the text in this line fmt=OpenCfmt(w,l); for (i=StartPos;i<EndPos;i++) { font=fmt[i]; if (TerFont[font].DelRev!=TrackRev) { if (font<NewFontMax && NewFont[font]>=0) fmt[i]=(WORD)NewFont[font]; // 20070927: use previously created font id else { fmt[i]=SetTrackingFont(w,fmt[i],TRACK_DEL); if (font<NewFontMax) NewFont[font]=fmt[i]; // save for next lookup } } } CloseCfmt(w,l); continue; } // check if the entire line contains the text entered by the current reviewer (and not deleted by another reviewer) RevInsertedLine=true; fmt=OpenCfmt(w,l); for (i=StartPos;i<EndPos;i++) { font=fmt[i]; if (TerFont[font].InsRev!=TrackRev || True(TerFont[font].DelRev)) { RevInsertedLine=false; break; } } CloseCfmt(w,l); if (RevInsertedLine && StartPos==0 && EndPos==LineLen(l)) { // delete the whole line DelCount+=LineLen(l); // number of characters actually removed if (l<CurLine) CurLine--; // adjust current line if (l==CurLine) { CurLine--; CurCol=LineLen(CurLine)-1; } MoveLineArrays(w,l,1,'D'); EndLine--; continue; } // scan each character in the line to perform indicated delete operation (regular delete or track-delete) fmt=OpenCfmt(w,l); for (i=StartPos;i<EndPos;i++) { font=fmt[i]; if (True(TerFont[font].DelRev)) continue; // already track-delete if (TerFont[font].InsRev==TrackRev) { // text inserted by the current reviewer - do regular delete MoveLineData(w,l,i,1,'D'); fmt=OpenCfmt(w,l); // MoveLineData invalidates the fmt pointer i--; // don't let i advance because the character deleted at this position EndPos--; DelCount++; if (l==CurLine && i<CurCol) CurCol--; } else { // regular text or text inserted by another reviewer - track delete if (TerFont[font].DelRev!=TrackRev) fmt[i]=SetTrackingFont(w,fmt[i],TRACK_DEL); } } CloseCfmt(w,l); } if (NewFont!=NULL) MemFree(NewFont); // release font cache NewFont=NULL; // mark the resultant text as inserted UndoRef=GroupUndoRef; EndAbsPos-=DelCount; // new ending pos AbsToRowCol(w,EndAbsPos,&EndLine,&EndCol); SaveUndo(w,BegLine,BegCol,EndLine,EndCol-1,'I'); // save undo if (CurLine>=TotalLines) CurLine=TotalLines-1; if (CurCol>=LineLen(CurLine)) CurCol=LineLen(CurLine)-1; if (CurCol<0) CurCol=0; if (ResetHilight) HilightType=HILIGHT_OFF; if (repaint) PaintTer(w); return true; }
int EBuffer::DoWrap(int WrapAll) { int L, Len, C, P, Ind; PELine LP; int Left = BFI(this, BFI_LeftMargin), Right = BFI(this, BFI_RightMargin); int FirstParaLine; int NoChange = 0, NoChangeX = 0; if (Left >= Right) return 0; L = VToR(CP.Row); FirstParaLine = 0; if (L > 0) if (IsLineBlank(L - 1)) FirstParaLine = L; while (L < RCount) { NoChange = 1; if (VToR(CP.Row) != L || L != FirstParaLine) { if (VToR(CP.Row) == L) if (CP.Col <= LineIndented(L)) if (SetPos(Left, CP.Row) == 0) WFAIL(1); Ind = IndentLine(L, Left); if (VToR(CP.Row) == L) if (SetPos((CP.Col + Ind > 0) ? CP.Col + Ind : 0, CP.Row) == 0) WFAIL(2); NoChange = 0; } Len = LineLen(L); if (IsLineBlank(L)) break; if (Len < Right) { int firstwordbeg = -1; int firstwordend = -1; int X; PELine lp; if (L < RCount - 1) { IndentLine(L + 1, 0); if ((ScreenPos(RLine(L + 1), RLine(L + 1)->Count) == 0) || (RLine(L + 1)->Chars[0] == '>') || (RLine(L + 1)->Chars[0] == '<')) break; } else break; if (L + 1 >= RCount) break; lp = RLine(L + 1); for (X = 0; X < lp->Count; X++) { if (firstwordbeg == -1 && ((lp->Chars[X] != ' ') && (lp->Chars[X] != '\t'))) { firstwordbeg = X; } else if (firstwordend == -1 && ((lp->Chars[X] == ' ' || lp->Chars[X] == '\t'))) { firstwordend = X - 1; } } if (firstwordbeg != -1) if (firstwordend == -1) firstwordend = lp->Count; if (firstwordend == -1) break; if (Right - Len > firstwordend - firstwordbeg) { if (JoinLine(L, Len + 1) == 0) WFAIL(3); NoChange = 0; continue; } else IndentLine(L + 1, Left); } else if (Len > Right) { C = Right; P = CharOffset(LP = RLine(L), C); while ((C > Left) && ((LP->Chars[P] != ' ') && (LP->Chars[P] != 9))) C = ScreenPos(LP, --P); if (P <= Left) { L++; continue; } C = ScreenPos(LP, P); if (SplitLine(L, C) == 0) WFAIL(4); IndentLine(L + 1, Left); if (L < RCount - 2 && LineLen(L + 1) == Left) { if (!IsLineBlank(L + 2)) { if (JoinLine(L + 1, Left) == 0) WFAIL(5); } } if (L == VToR(CP.Row) && CP.Col > C) { if (SetPos(Left + CP.Col - C - 1, CP.Row + 1) == 0) WFAIL(6); } NoChange = 0; L++; continue; } if (WrapAll == 0) if (NoChangeX) { //printf("\n\nBreak OUT = %d\n\x7", L); break; } L++; NoChangeX = NoChange; } if (WrapAll == 1) if (SetPosR(Left, (L < RCount - 2) ? (L + 2) : (L < RCount - 1) ? (L + 1) : (RCount - 1)) == 0) WFAIL(7); return 1; }
int EBuffer::MoveLineEnd() { SetPos(LineLen(VToR(CP.Row)), CP.Row); return 1; }
int EBuffer::ShowPosition() { int CLine, NLines; int CAct, NAct; int CColumn, NColumns; int CCharPos, NChars; #ifdef HEAPWALK unsigned long MemUsed = 0, MemFree = 0, BlkUsed = 0, BlkFree = 0, BigFree = 0, BigUsed = 0; #endif if (!View) return 0; CLine = CP.Row + 1; NLines = VCount; CAct = VToR(CP.Row) + 1; NAct = RCount; CColumn = CP.Col + 1; NColumns = LineLen(CP.Row); CCharPos = CharOffset(VLine(CP.Row), CP.Col) + 1; NChars = VLine(CP.Row)->Count; #ifdef HEAPWALK if (_heapchk() != _HEAPOK) { MemUsed = -1; } else { _HEAPINFO hi; hi._pentry = NULL; while (_heapwalk(&hi) == _HEAPOK) { if (hi._useflag == _USEDENTRY) { BlkUsed++; MemUsed += hi._size; if (hi._size > BigUsed) BigUsed = hi._size; //fprintf(stderr, "USED %d\n", hi._size); } else { BlkFree++; MemFree += hi._size; if (hi._size > BigFree) BigFree = hi._size; //fprintf(stderr, "FREE %d\n", hi._size); } } } #endif int NN = -1; if (US.UndoPtr > 0) NN = US.Top[US.UndoPtr - 1]; Msg(S_INFO, #ifdef HEAPWALK "M%ld,%ld B%ld,%ld S%ld,%ld" #endif "L%d/%d G%d/%d/%d A%d/%d C%d/%d P%d/%d " "U%d/%d/%d " "H%d/%d/%d", #ifdef HEAPWALK MemUsed, MemFree, BlkUsed, BlkFree, BigUsed, BigFree, #endif CLine, NLines, RGap, RCount, RAllocated, CAct, NAct, CColumn, NColumns, CCharPos, NChars, US.UndoPtr, US.Num, NN, StartHilit, MinRedraw, MaxRedraw); return 1; }
int EBuffer::MoveFileEnd() { SetPos(LineLen(VToR(VCount - 1)), VCount - 1); return 1; }