📄 mimerichtextedit.c
字号:
} // End CompactSelection/*--------------------------------------------------------------- * Handle general key press */voidMimeRichTextP::ActInsertSelf(Widget w, XKeyEvent *ev, String*, Cardinal*){ MimeRichTextC *This; XtVaGetValues(w, XmNuserData, &This, NULL);//// Translate event into characters// char buf[BUFSIZ]; KeySym keysym; Status status; int bufSize = XmImMbLookupString(w, ev, buf, BUFSIZ-1, &keysym, &status); if ( status == XBufferOverflow ) { char *altbuf = new char[bufSize+1]; bufSize = XmImMbLookupString(w, ev, buf, bufSize, &keysym, &status); } if ( status == XLookupNone ) return; if ( bufSize <= 0 ) return; buf[bufSize] = 0;//// If editable is False, TAB and NEWLINE will cause traversal.// if ( !This->priv->editable ) { if ( buf[0] == '\t' ) { if ( ev->state & ShiftMask ) XmProcessTraversal(This->priv->textDA, XmTRAVERSE_PREV_TAB_GROUP); else XmProcessTraversal(This->priv->textDA, XmTRAVERSE_NEXT_TAB_GROUP); } else if ( buf[0] == '\n' || buf[0] == '\r' ) XmProcessTraversal(This->priv->textDA, XmTRAVERSE_NEXT_TAB_GROUP); else XBell(halApp->display, 0); return; }//// If tabTraverses is True, TAB will cause traversal.// else if ( buf[0] == '\t' && This->priv->tabTraverses ) { if ( ev->state & ShiftMask ) XmProcessTraversal(This->priv->textDA, XmTRAVERSE_PREV_TAB_GROUP); else XmProcessTraversal(This->priv->textDA, XmTRAVERSE_NEXT_TAB_GROUP); return; }//// If singleLine is True, NEWLINE will cause traversal.// else if ( buf[0] == '\n' || buf[0] == '\r' && This->priv->singleLine ) { XmProcessTraversal(This->priv->textDA, XmTRAVERSE_NEXT_TAB_GROUP); return; }//// This will catch the escape key. I'm still not sure why we get an event// for this.// if ( keysym == XK_Escape ) return; This->priv->HideCursor();//// Delete the current selection// if ( This->priv->selectOn ) This->priv->DeleteSelection();//// Add a line record if necessary// TextLineC *tline = This->priv->cursorPos.textLine; if ( !tline ) { tline = new TextLineC; This->priv->cursorPos.Set(tline, 0, 0); }//// Point to the command under the cursor.// RichCmdC *curCmd = This->priv->cursorPos.Cmd(); TextPosC newPos;//// If this isn't a text command, insert one// if ( curCmd->IsGraphic() ) {//// See if the text should be inserted before or after the graphic// Boolean after = (This->priv->cursorPos.strPos>0); This->priv->InsertCommand(RC_TEXT, after, This->priv->cursorPos, &newPos); This->priv->cursorPos = newPos; curCmd = This->priv->cursorPos.Cmd(); } // End if cursor is not on a text command//// If this is a line break, split the line at the cursor position// TextLineC *newLine = NULL; if ( buf[0] == '\n' || buf[0] == '\r' ) { This->priv->InsertLineBreak(This->priv->cursorPos, &newPos); newLine = newPos.textLine;//// If the new line or the old line is blank, remove any excerpting// if ( newLine->IsBlank() ) newLine->RemoveExcerpt(); else if ( This->priv->cursorPos.textLine->IsBlank() ) This->priv->cursorPos.textLine->RemoveExcerpt(); } else {//// Insert new text into the current text segment// if ( This->priv->cursorPos.strPos < curCmd->LastPos() ) (*curCmd->text)(This->priv->cursorPos.strPos, 0) = buf; else *curCmd->text += buf; This->priv->cursorPos.strPos += bufSize; } This->priv->LinesChanged(tline, newLine ? newLine : tline, newLine != NULL);//// Keep the cursor in the window// This->priv->ScrollToCursor(); ScreenPosC spos = This->priv->cursorPos; This->priv->desiredCursorX = spos.x; This->priv->ShowCursor();} // End ActInsertSelf#if 0/*---------------------------------------------------------------------- * Action proc to insert cut buffer at cursor position */voidMimeRichTextP::ActPaste(Widget w, XButtonEvent*, String*, Cardinal*){ MimeRichTextC *This; XtVaGetValues(w, XmNuserData, &This, NULL); if ( !This->priv->editable ) { XBell(halApp->display, 0); return; } This->priv->InsertSavedLines(This->priv->cursorPos);} // End ActPaste#endif/*--------------------------------------------------------------- * Redraw the window */voidMimeRichTextP::ActRefresh(Widget w, XKeyEvent*, String*, Cardinal*){ MimeRichTextC *This; XtVaGetValues(w, XmNuserData, &This, NULL); RectC area(0, 0, This->priv->drawWd, This->priv->drawHt); This->priv->DrawScreen(area);} // End ActRefresh/*--------------------------------------------------------------- * Restore the last deletion */voidMimeRichTextP::ActUndo(Widget w, XKeyEvent*, String*, Cardinal*){ MimeRichTextC *This; XtVaGetValues(w, XmNuserData, &This, NULL); This->Undelete();}voidMimeRichTextC::Undelete(){ if ( !priv->editable ) { XBell(halApp->display, 0); return; } priv->InsertSavedLines(priv->lastDelPos);}/*--------------------------------------------------------------- * Insert the saved lines at the specified position */voidMimeRichTextP::InsertSavedLines(TextPosC insPos){ if ( !topSaveLine ) { XBell(halApp->display, 0); return; }#if 0 if ( debuglev > 2 ) { cout <<"Inserting saved lines at pos " <<insPos.cmdPos <<", " <<insPos.strPos <<" in line " <<insPos.textLine <<endl; if ( insPos.textLine ) cout <<" next line is " <<insPos.textLine->next <<endl; }#endif HideCursor();//// Clear the current selection// if ( selectOn ) DrawSelection();//// If there is more than one saved line, insert a line break at the insertion// position. If there is only one saved line, split the command at// the insertion position.// int dstCmdPos; TextPosC newPos; if ( topSaveLine != botSaveLine ) {// if ( debuglev > 2 ) cout <<" inserting line break" <<endl; InsertLineBreak(insPos, &newPos); dstCmdPos = insPos.cmdPos + 1; } else {// if ( debuglev > 2 ) cout <<" splitting command" <<endl; SplitCommand(insPos, &newPos); dstCmdPos = newPos.cmdPos; } cursorPos = newPos;//// For the first saved line, add the commands to the end of the line before// the break// TextLineC *dstLine = insPos.textLine; TextLineC *tline = topSaveLine; unsigned ccount = tline->cmdList.size(); RichCmdC *cmd; int c=0; for (c=0; c<ccount; c++) { cmd = tline->Cmd(c); if ( cmd->IsGraphic() ) cmd->graphic->Show();// if ( debuglev > 2 ) cout <<" adding command to first line" <<endl; dstLine->AddCommand(cmd, dstCmdPos); dstCmdPos++; } // End for each command//// Make the first line as efficient as possible.//// if ( debuglev > 2 ) cout <<" compacting first line" <<endl; CompactLine(dstLine); TextLineC *begLine = dstLine;//// For the in-between lines, just move the line to the line list.// RichCmdC *lastCmd; TextLineC *nline; tline = topSaveLine->next; while ( tline && tline != botSaveLine ) {//// Turn on graphics in line// ccount = tline->cmdList.size(); for (c=0; c<ccount; c++) { cmd = tline->Cmd(c); if ( cmd->IsGraphic() ) cmd->graphic->Show(); } nline = tline->next;// if ( debuglev > 2 ) cout <<" adding additional line" <<endl; AddLine(tline, dstLine); dstLine = tline; lastCmd = dstLine->Cmd(ccount-1); tline = nline; } // End for each intermediate line//// For the last line of several, we'll add the commands to the beginning// of the line after the break// if ( topSaveLine != botSaveLine ) { tline = botSaveLine/*->prev*/; dstLine = newPos.textLine; dstCmdPos = 0;//// Loop through the commands in this line// ccount = tline->cmdList.size(); for (c=0; c<ccount; c++) { cmd = tline->Cmd(c); if ( cmd->IsGraphic() ) cmd->graphic->Show();// if ( debuglev > 2 ) cout <<" adding command to last line" <<endl; dstLine->AddCommand(cmd, dstCmdPos); dstCmdPos++; } // End for each command//// Make the last line as efficient as possible.//// if ( debuglev > 2 ) cout <<" compacting last line" <<endl; CompactLine(dstLine); } // End if the last line needs processing TextLineC *endLine = dstLine; topSaveLine = botSaveLine = NULL; LinesChanged(begLine, endLine, True/*force layout*/);//// Keep the cursor visible// ScrollToCursor(); ScreenPosC spos = cursorPos; desiredCursorX = spos.x;//// Restore the current selection// if ( selectOn ) DrawSelection(); ShowCursor();} // End InsertSavedLines/*--------------------------------------------------------------- * Scroll the window up one line */voidMimeRichTextP::ActScrollUpLine(Widget w, XKeyEvent*, String*, Cardinal*){ MimeRichTextC *This; XtVaGetValues(w, XmNuserData, &This, NULL); This->ScrollUpLine();}voidMimeRichTextC::ScrollUpLine(){ if ( priv->textVSB ) { int val, ss, i, pi; XmScrollBarGetValues(priv->textVSB, &val, &ss, &i, &pi); if ( priv->vsbVal > 0 ) { val = priv->vsbVal - i; if ( val < 0 ) val = 0; XmScrollBarSetValues(priv->textVSB, val, ss, i, pi, True); } }#if 0 ScreenPosC spos = priv->cursorPos;//// Find the first non-visible line above this one// SoftLineC *line = spos.softLine; if ( !line ) return; line = line->prev; while ( line && priv->LineFullyVisible(line) ) line = line->prev; if ( !line ) return;//// Scroll to make the line visible// spos.Set(line, priv->desiredCursorX); priv->ScrollToPosition(spos);//// If the cursor went off the screen, move it up// spos = priv->cursorPos; line = spos.softLine; while ( line && !priv->LineFullyVisible(line) ) line = line->prev; if ( line && line != spos.softLine ) { spos.Set(line, priv->desiredCursorX); priv->HideCursor(); priv->cursorPos = spos; priv->ShowCursor(); }#endif} // End ScrollUpLine/*--------------------------------------------------------------- * Scroll the window up one page */voidMimeRichTextP::ActScrollUpPage(Widget w, XKeyEvent*, String*, Cardinal*){ MimeRichTextC *This; XtVaGetValues(w, XmNuserData, &This, NULL); This->ScrollUpPage();}voidMimeRichTextC::ScrollUpPage(){ if ( priv->textVSB ) { int val, ss, i, pi; XmScrollBarGetValues(priv->textVSB, &val, &ss, &i, &pi); if ( priv->vsbVal > 0 ) { val = priv->vsbVal - pi; if ( val < 0 ) val = 0; XmScrollBarSetValues(priv->textVSB, val, ss, i, pi, True); } }} // End ScrollUpPage/*--------------------------------------------------------------- * Scroll the window down one line */voidMimeRichTextP::ActScrollDownLine(Widget w, XKeyEvent*, String*, Cardinal*){ MimeRichTextC *This; XtVaGetValues(w, XmNuserData, &This, NULL); This->ScrollDownLine();}voidMimeRichTextC::ScrollDownLine(){ if ( priv->textVSB ) { int val, ss, i, pi; XmScrollBarGetValues(priv->textVSB, &val, &ss, &i, &pi); int max = priv->vsbMax - ss; if ( priv->vsbVal < max ) { val = priv->vsbVal + i; if ( val > max ) val = max; XmScrollBarSetValues(priv->textVSB, val, ss, i, pi, True); } }#if 0 ScreenPosC spos = priv->cursorPos;//// Find the first non-visible line below this one// SoftLineC *line = spos.softLine; if ( !line ) return; line = line->next; while ( line && priv->LineFullyVisible(line) ) line = line->next; if ( !line ) return;//// Scroll to make the line visible// spos.Set(line, priv->desiredCursorX); priv->ScrollToPosition(spos);//// If the cursor went off the screen, move it down// spos = priv->cursorPos; line = spos.softLine; while ( line && !priv->LineFullyVisible(line) ) line = line->next; if ( line && line != spos.softLine ) { spos.Set(line, priv->desiredCursorX); priv->HideCursor(); priv->cursorPos = spos; priv->ShowCursor(); }#endif} // End ScrollDownLine/*--------------------------------------------------------------- * Scroll the window down one page */voidMimeRichTextP::ActScrollDownPage(Widget w, XKeyEvent*, String*, Cardinal*){ MimeRichTextC *This; XtVaGetValues(w, XmNuserData, &This, NULL); This->ScrollDownPage();}voidMimeRichTextC::ScrollDownPage(){ if ( priv->textVSB ) { int val, ss, i, pi; XmScrollBarGetValues(priv->textVSB, &val, &ss, &i, &pi); int max = priv->vsbMax - ss; if ( priv->vsbVal < max ) { val = priv->vsbVal + pi; if ( val > max ) val = max; XmScrollBarSetValues(priv->textVSB, val, ss, i, pi, True); } }} // End ScrollDownPage/*--------------------------------------------------------------- * Scroll the window to the top */voidMimeRichTextP::ActScrollTop(Widget w, XKeyEvent*, String*, Cardinal*){ MimeRichTextC *This; XtVaGetValues(w, XmNuserData, &This, NULL); This->ScrollTop();}voidMimeRichTextC::ScrollTop(){ if ( priv->textVSB ) { int val, ss, i, pi; XmScrollBarGetValues(priv->textVSB, &val, &ss, &i, &pi); XmScrollBarSetValues(priv->textVSB, 0, ss, i, pi, True); }#if 0// if ( !priv->topSoftLine ) return;//// Make the top position visible// ScreenPosC spos(priv->topSoftLine, 0); priv->ScrollToPosition(spos);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -