📄 mimerichtextselect.c
字号:
RichCmdC *cmd = newPos->Cmd(); Boolean found = False; Boolean gotText = False; while ( !found && cmdPos < cmdCount ) {//// Look forward through the characters// unsigned strSize = cmd->LastPos(); while ( !found && strPos < strSize ) { if ( cmd->IsText() ) { gotText = True; char c = (*cmd->text)[strPos]; if ( needWhite ) { if ( isspace(c) ) needWhite = False; } else if ( needNonWhite ) { if ( !isspace(c) ) found = True; } }//// If we found any characters, we can stop here// else { if ( gotText ) found = True; else needWhite = False; } if ( !found ) strPos++; } // End for each character//// Move to next command// if ( !found ) { cmdPos++; if ( cmdPos < cmdCount ) { cmd = newPos->textLine->Cmd(cmdPos); strPos = 0; } } } // End for each data block//// If we're at the end of the line, move to the beginning of the next// if ( !found && cmdPos == cmdCount && strPos == cmd->LastPos() ) { TextLineC *nextLine = newPos->textLine->next; if ( nextLine ) {//// Move to the next line// newPos->textLine = nextLine; newPos->cmdPos = 0; newPos->strPos = 0; } else {//// Move to the end of this line// newPos->cmdPos = cmdCount - 1; newPos->strPos = cmd->LastPos(); } } // End if at end of line else { newPos->cmdPos = cmdPos; newPos->strPos = strPos; }//// Make sure we're not pointing to a clipped position// ScreenPosC spos = *newPos; while ( !spos.softLine && newPos->strPos < cmd->LastPos() ) { newPos->strPos++; spos = *newPos; } if ( spos.softLine ) return True; else return False;} // End FindPosNextWord/*----------------------------------------------------------------------- * Find the end of the current word. This means find the next white * character. */BooleanMimeRichTextP::FindPosEndWord(TextPosC& curPos, TextPosC *newPos){ *newPos = curPos; if ( !newPos->textLine ) return False;//// Look forward through data// unsigned cmdCount = newPos->textLine->cmdList.size(); int strPos = newPos->strPos; int cmdPos = newPos->cmdPos; RichCmdC *cmd = newPos->Cmd(); Boolean found = False; while ( !found && cmdPos < cmdCount ) {//// Look forward through the characters// unsigned strSize = cmd->LastPos(); while ( !found && strPos < strSize ) { if ( cmd->IsText() ) { char c = (*cmd->text)[strPos]; if ( isspace(c) ) found = True; } else found = True; if ( !found ) strPos++; } // End for each character//// Move to next command// if ( !found ) { cmdPos++; if ( cmdPos < cmdCount ) { cmd = newPos->textLine->Cmd(cmdPos); strPos = 0; } } } // End for each data block if ( !found ) {//// Move to the end of this line// newPos->cmdPos = cmdCount - 1; newPos->strPos = cmd->LastPos(); } // End if at end of line else { newPos->cmdPos = cmdPos; newPos->strPos = strPos; }//// Make sure we're not pointing to a clipped position// ScreenPosC spos = *newPos; while ( !spos.softLine && newPos->strPos < cmd->LastPos() ) { newPos->strPos++; spos = *newPos; } if ( spos.softLine ) return True; else return False;} // End FindPosEndWord/*--------------------------------------------------------------- * Method to find the draw data containing the specified x position */RichDrawDataC*SoftLineC::PickData(int x){ RichDrawDataC *pickData = NULL; RichDrawDataC *dd = drawData; while ( !pickData && dd ) {//// Loop until we hit the correct data block// if ( (dd->x + dd->width) > x ) {//// Back up if we've gone past.// if ( dd->x > x && dd->prev ) dd = dd->prev;//// This should be the one// pickData = dd; } dd = dd->next; } // End for each data block if ( !pickData && drawData ) { if ( x <= bounds.xmin ) pickData = FirstData(); else pickData = LastData(); } return pickData;} // End PickData/*--------------------------------------------------------------- * Change the selection range */voidMimeRichTextP::UpdateSelection(TextPosC& begPos, TextPosC& endPos){ if ( begPos == selectBegPos && endPos == selectEndPos ) return;//// If the positions are the same, turn off the selection// if ( begPos == endPos ) { if ( selectOn ) DrawSelection(); // To turn it off selectOn = False; selectBegPos = begPos; selectEndPos = endPos; return; }//// If there is no current selection, just use the specified positions// if ( !selectOn ) { selectBegPos = begPos; selectEndPos = endPos; DrawSelection(); selectOn = True; return; }//// If the beginning position has changed, draw to the new position// if ( begPos < selectBegPos ) { DrawSelectionRange(&begPos, &selectBegPos); // Draw section } else if ( begPos > selectBegPos ) { DrawSelectionRange(&selectBegPos, &begPos); // Clear section }//// If the end position has changed, draw to the new position// if ( endPos < selectEndPos ) { DrawSelectionRange(&endPos, &selectEndPos); // Clear section } else if ( endPos > selectEndPos ) { DrawSelectionRange(&selectEndPos, &endPos); // Draw section } selectBegPos = begPos; selectEndPos = endPos; //CompactSelection();} // End UpdateSelection/*--------------------------------------------------------------- * Handle start of the a selection */voidMimeRichTextP::ActSelectBegin(Widget w, XButtonEvent *ev, String*, Cardinal*){ //if ( debuglev > 1 ) cout <<"Button down" <<endl; MimeRichTextC *This; XtVaGetValues(w, XmNuserData, &This, NULL);//// Remove any existing click timer// if ( This->priv->clickTimer ) { XtRemoveTimeOut(This->priv->clickTimer); This->priv->clickTimer = (XtIntervalId)NULL; } This->priv->okToEndSelection = False; XmProcessTraversal(This->priv->textDA, XmTRAVERSE_CURRENT);//// Count multi-clicks ourself if a timer can't be used// if ( !This->priv->timerOk ) { u_long diff = ev->time - This->priv->selectTime; if ( diff > (u_long)XtGetMultiClickTime(halApp->display) ) This->priv->clickCount = 0; } This->priv->clickCount++; This->priv->selectTime = ev->time;//// See if this click is in a graphic// RichGraphicC *graphic = NULL; if ( This->priv->clickCount <= 2 ) graphic = This->priv->PickGraphic(ev->x, ev->y); TextPosC newBegPos, newEndPos; switch ( This->priv->clickCount ) { case 1: if ( graphic ) { if ( debuglev > 1 ) cout <<"Single click in graphic" <<endl; graphic->SingleClick(ev); This->MoveCursor(graphic, 1); } else { if ( debuglev > 1 ) cout <<"Single click" <<endl; This->MoveCursor(w, ev->x, ev->y); } newBegPos = This->priv->cursorPos; newEndPos = This->priv->cursorPos; This->priv->selectType = SELECT_CHAR; break; case 2: // Select word if ( graphic ) { if ( debuglev > 1 ) cout <<"Double click in graphic" <<endl; graphic->DoubleClick(ev); This->MoveCursor(graphic, 1); newBegPos = This->priv->cursorPos; newEndPos = This->priv->cursorPos; } else { if ( debuglev > 1 ) cout <<"Double click" <<endl; This->priv->FindPosBegClass(This->priv->cursorPos, &newBegPos); This->priv->FindPosEndClass(This->priv->cursorPos, &newEndPos); } This->priv->selectType = SELECT_WORD; break; case 3: // Select line { if ( debuglev > 1 ) cout <<"Got triple click" <<endl; ScreenPosC begPos(This->priv->cursorPos); ScreenPosC endPos(This->priv->cursorPos); begPos.Set(begPos.softLine, begPos.softLine->bounds.xmin); endPos.Set(endPos.softLine, endPos.softLine->bounds.xmax); newBegPos = begPos; newEndPos = endPos; This->priv->selectType = SELECT_LINE; } break; case 4: // Select page { if ( debuglev > 1 ) cout <<"Got quadruple click" <<endl; if ( This->priv->botTextLine ) { TextLineC *tline = This->priv->botTextLine; unsigned cmdCount = tline->cmdList.size(); RichCmdC *cmd = tline->Cmd(cmdCount-1); newBegPos.Set(This->priv->topTextLine, 0, 0); newEndPos.Set(tline, cmdCount-1, cmd->LastPos()); This->priv->selectType = SELECT_PAGE; } This->priv->clickCount = 0; } break; }//// Keep the beginning position to the left of the end position// if ( newBegPos <= newEndPos ) This->priv->UpdateSelection(newBegPos, newEndPos); else This->priv->UpdateSelection(newEndPos, newBegPos); This->priv->baseSelectBegPos = This->priv->selectBegPos; This->priv->baseSelectEndPos = This->priv->selectEndPos; if ( This->priv->selectOn ) {//// Move the cursor to the nearest end of the selection// This->priv->HideCursor(); ScreenPosC cpos = This->priv->cursorPos; ScreenPosC bpos = This->priv->selectBegPos; ScreenPosC epos = This->priv->selectEndPos; int begDist = This->priv->Distance(cpos, bpos); int endDist = This->priv->Distance(cpos, epos); if ( begDist < endDist ) This->priv->cursorPos = This->priv->selectBegPos; else This->priv->cursorPos = This->priv->selectEndPos; This->priv->ShowCursor(); }//// Add a timer to look for multi-clicks// This->priv->clickWidget = w; This->priv->clickEvent = *ev; if ( This->priv->timerOk ) This->priv->clickTimer = XtAppAddTimeOut(halApp->context, XtGetMultiClickTime(halApp->display), (XtTimerCallbackProc)ClickReset, (XtPointer)This->priv);} // End ActSelectBegin/*--------------------------------------------------------------- * Handle extend of the selection */voidMimeRichTextP::ActSelectMotion(Widget w, XMotionEvent *ev, String*,Cardinal*){ MimeRichTextC *This; XtVaGetValues(w, XmNuserData, &This, NULL); This->priv->selectTime = ev->time; if ( !This->priv->baseSelectBegPos.textLine ) return;//// Find the position of the pointer in both da and form coords// int dx = ev->x; int dy = ev->y;//// See if the pointer is inside or outside the window// Dimension winWd, winHt; XtVaGetValues(This->priv->textDA, XmNwidth, &winWd, XmNheight, &winHt, 0); Boolean scrollU = (This->priv->vsbOn && This->priv->vsbVal > 0 && dy <= (int)0); Boolean scrollD = (This->priv->vsbOn && This->priv->vsbVal < This->priv->vsbMax && dy >= (int)winHt); Boolean scrollL = (This->priv->hsbOn && This->priv->hsbVal > 0 && dx <= (int)0); Boolean scrollR = (This->priv->hsbOn && This->priv->hsbVal < This->priv->hsbMax && dx >= (int)winWd); Boolean offScreen = (scrollU || scrollD || scrollL || scrollR); if ( offScreen ) { This->priv->scrollEvent = *ev; This->priv->scrollEvent.x = dx; This->priv->scrollEvent.y = dy; This->priv->vScrollAction = (char *) (scrollU ? "IncrementUpOrLeft" : scrollD ? "IncrementDownOrRight" : NULL); This->priv->hScrollAction = (char *) (scrollL ? "IncrementUpOrLeft" : scrollR ? "IncrementDownOrRight" : NULL);#if 0// if ( debuglev > 1 ) { cout <<"Event off-screen, scrolling "; if ( scrollU ) cout <<"up "; else if ( scrollD ) cout <<"down "; else cout <<"none "; cout <<"and "; if ( scrollL ) cout <<"left."; else if ( scrollR ) cout <<"right."; else cout <<"none."; cout <<endl;// }#endif }//// If there is a scroll timer running, see if we moved back on the screen// if ( This->priv->scrollTimer && !offScreen ) {// cout <<"Stopping auto-scroll timer." <<endl; XtRemoveTimeOut(This->priv->scrollTimer); This->priv->scrollTimer = (XtIntervalId)NULL; } // End if there is a scroll timer//// If there's no scroll timer, see if we need one// else if ( This->priv->timerOk && !This->priv->scrollTimer && offScreen ) {// if ( debuglev > 1 )// cout <<"Starting auto-scroll timer" <<endl; This->priv->scrollTimer = XtAppAddTimeOut(halApp->context, This->priv->autoScrollInterval, (XtTimerCallbackProc)HandleAutoScroll, (XtPointer)This->priv); } // End if there is no scroll timer//// If we're on the screen, process this event// if ( !offScreen ) This->priv->UpdateMotionSelection(dx + This->priv->hsbVal, dy + This->priv->vsbVal, True/*scroll*/);} // End ActSelectMotion/*--------------------------------------------------------------- * Update the selection after a motion event */voidMimeRichTextP::UpdateMotionSelection(int x, int y, Boolean scroll){//// Find the position of the cursor// SoftLineC *pline = PickLine(y); if ( !pline ) { pline = botSoftLine; if ( pline ) x = pline->bounds.xmax; } ScreenPosC spos(pline, x); TextPosC newPos = spos; HideCursor();//// See if we're selecting a word at a time// if ( selectType == SELECT_WORD ) {//// If the new position is to the left of the base beginning position, select// to the beginning of the word under the cursor.// if ( newPos < baseSelectBegPos ) { TextPosC wordPos; if ( FindPosBegClass(newPos, &wordPos) ) UpdateSelection(wordPos, baseSelectEndPos); }//// If the new position is to the right of the base ending p
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -