// // Copyright (C) 1996 Ben Ross // // You may distribute under the terms of the GNU General Public // License as specified in the COPYING file. // // $Id: XeTextKeys.C,v 1.7 2000/10/12 10:51:06 brian Exp $ #include #include #include XeTextKeys::KeyOpMap XeTextKeys::_mappings[] = { { "up", (KeyFunc)up, XK_Up, 0 }, { "down", (KeyFunc)down, XK_Down, 0 }, { "left", (KeyFunc)left, XK_Left, 0 }, { "right", (KeyFunc)right, XK_Right, 0 }, { "extend_up", (KeyFunc)extend_up, XK_Up, ShiftMask }, { "extend_down", (KeyFunc)extend_down, XK_Down, ShiftMask }, { "extend_left", (KeyFunc)extend_left, XK_Left, ShiftMask }, { "extend_right", (KeyFunc)extend_right, XK_Right, ShiftMask }, { "prev_word", (KeyFunc)prev_word, XK_Left, Mod1Mask }, { "next_word", (KeyFunc)next_word, XK_Right, Mod1Mask }, { "extend_prev_word", (KeyFunc)extend_prev_word, XK_Left, Mod1Mask|ShiftMask }, { "extend_next_word", (KeyFunc)extend_next_word, XK_Right, Mod1Mask|ShiftMask }, { "start_line", (KeyFunc)start_line, XK_Left, ControlMask }, { "end_line", (KeyFunc)end_line, XK_Right, ControlMask }, { "extend_start_line", (KeyFunc)extend_start_line, XK_Left, ControlMask|ShiftMask }, { "extend_end_line", (KeyFunc)extend_end_line, XK_Right, ControlMask|ShiftMask }, { "page_up", (KeyFunc)page_up, XK_Page_Up, 0 }, { "page_down", (KeyFunc)page_down, XK_Page_Down, 0 }, { "home", (KeyFunc)home, XK_Home, 0 }, { "end", (KeyFunc)end, XK_End, 0 }, // { "delete_right", (KeyFunc)delete_right, XK_Delete, 0 }, }; int XeTextKeys::getNumOps(void) { return (sizeof(_mappings) / sizeof(KeyOpMap)); } void XeTextKeys::up(XeText* text) { if (text->_sel.lineStart == 0) { if (text->selLength()) text->setSelection(0, 0, 0); } else { text->setSelection(text->_sel.lineStart - 1, text->_caretPos); } } void XeTextKeys::down(XeText* text) { if ((ulong)text->_sel.lineEnd >= text->_lineStarts->getSize() - 1) { text->setSelection(text->_text->getSize(), text->_text->getSize(), text->_lineStarts->getSize() - 1); } else { text->setSelection(text->_sel.lineEnd + 1, text->_caretPos); } } void XeTextKeys::left(XeText* text) { SelStruct& sel = text->_sel; if (sel.selStart == 0) { if (text->selLength()) text->setSelection(0, 0, 0); return; } if (text->selLength()) text->setSelection(sel.selStart, sel.selStart, sel.lineStart); else { if (sel.posStart == 0) text->setSelection(sel.selStart-1, sel.selStart-1, sel.lineStart-1); else text->setSelection(sel.selStart-1, sel.selStart-1, sel.lineStart); } text->_caretPos = sel.posStart; } void XeTextKeys::right(XeText* text) { SelStruct& sel = text->_sel; if((ulong)text->_sel.selEnd >= text->_text->getSize()) { if (text->selLength()) text->setSelection(text->_text->getSize(), text->_text->getSize(), text->_lineStarts->getSize() - 1); return; } if (text->selLength()) text->setSelection(sel.selEnd, sel.selEnd, sel.lineEnd); else { if ((*text->_text)[sel.selEnd] == '\n') text->setSelection(sel.selEnd+1, sel.selEnd+1, sel.lineEnd+1); else text->setSelection(sel.selEnd+1, sel.selEnd+1, sel.lineEnd); } text->_caretPos = sel.posStart; } void XeTextKeys::extend_up(XeText* text) { if (text->_anchor.lineStart == 0) return; text->extendSelection(text->_anchor.lineStart - 1, text->_caretPos); } void XeTextKeys::extend_down(XeText* text) { if ((ulong)text->_anchor.lineStart >= text->_lineStarts->getSize() - 1) text->extendSelection(text->_anchor.lineStart, text->getPhysicalLength(text->_anchor.lineStart)); else text->extendSelection(text->_anchor.lineStart + 1, text->_caretPos); } void XeTextKeys::extend_left(XeText* text) { if (text->_anchor.selStart == 0) return; if (text->_anchor.posStart == 0) text->stretchSelection(-1, -1); else text->stretchSelection(-1, 0); text->_caretPos = text->_anchor.posStart; } void XeTextKeys::extend_right(XeText* text) { if((ulong)text->_anchor.selStart >= text->_text->getSize()) return; if ((*text->_text)[text->_anchor.selStart] == '\n') text->stretchSelection(1, 1); else text->stretchSelection(1, 0); text->_caretPos = text->_anchor.posStart; } void XeTextKeys::prev_word(XeText* text) { SelStruct sel = text->_sel; if (sel.selStart == 0) return; if (sel.posStart == 0) sel.lineStart--; sel.selStart--; text->getNextPos(TRUE, &sel); text->setSelection(sel.selStart, sel.selStart, sel.lineStart); } void XeTextKeys::next_word(XeText* text) { SelStruct sel = text->_sel; if((ulong)sel.selEnd >= text->_text->getSize()) return; text->swapSel(sel); text->getNextPos(FALSE, &sel); text->setSelection(sel.selStart, sel.selStart, sel.lineStart); } void XeTextKeys::extend_prev_word(XeText* text) { SelStruct sel = text->_anchor; if (sel.selStart == 0) return; if (sel.posStart == 0) sel.lineStart--; sel.selStart--; sel.posStart = text->getPhysicalLength(sel.lineStart, sel.selStart); text->getNextPos(TRUE, &sel); // $$$ not the most efficient way to do the selection since we know // the value of sel.selStart in this case.. what may be needed is // a function XeTextBase::extendSelection(selStart, lineStart, posStart) text->extendSelection(sel.lineStart, sel.posStart); text->_caretPos = text->_anchor.posStart; } void XeTextKeys::extend_next_word(XeText* text) { SelStruct sel = text->_anchor; if((ulong)sel.selStart >= text->_text->getSize()) return; text->getNextPos(FALSE, &sel); text->extendSelection(sel.lineStart, sel.posStart); text->_caretPos = text->_anchor.posStart; } void XeTextKeys::start_line(XeText* text) { SelStruct& sel = text->_sel; if (sel.selStart == 0) return; if (sel.posStart == 0) text->setSelection(sel.selStart-1, sel.selStart-1, sel.lineStart-1); else text->setSelection(sel.lineStart, 0); text->_caretPos = sel.posStart; } void XeTextKeys::end_line(XeText* text) { SelStruct& sel = text->_sel; ulong textSize = text->_text->getSize(); if((ulong)text->_sel.selEnd >= textSize) return; if ((*text->_text)[sel.selEnd] == '\n') text->setSelection(sel.selEnd+1, sel.selEnd+1, sel.lineEnd+1); else { if ((ulong)sel.lineEnd == text->_lineStarts->getSize() - 1) text->setSelection(textSize, textSize, sel.lineEnd); else { long index = text->lineIndex(sel.lineEnd + 1); text->setSelection(index - 1, index - 1, sel.lineEnd); } } text->_caretPos = sel.posStart; } void XeTextKeys::extend_start_line(XeText* text) { SelStruct& anchor = text->_anchor; if (anchor.selStart == 0) return; if (anchor.posStart == 0) text->stretchSelection(-1, -1); else text->extendSelection(anchor.lineStart, 0); text->_caretPos = anchor.posStart; } void XeTextKeys::extend_end_line(XeText* text) { SelStruct& anchor = text->_anchor; if((ulong)anchor.selStart >= text->_text->getSize()) return; if ((*text->_text)[text->_anchor.selStart] == '\n') text->stretchSelection(1, 1); else text->extendSelection(anchor.lineStart, text->getPhysicalLength(anchor.lineStart)); text->_caretPos = text->_anchor.posStart; } void XeTextKeys::page_up(XeText* text) { text->setSelection(text->_anchor.lineStart - text->_visLines, text->_caretPos); text->autoScroll(); } void XeTextKeys::page_down(XeText* text) { text->setSelection(text->_anchor.lineStart + text->_visLines, text->_caretPos); text->autoScroll(); } void XeTextKeys::home(XeText* text) { text->setSelection(0, text->_caretPos); text->autoScroll(); } void XeTextKeys::end(XeText* text) { text->setSelection(text->numLines(), text->_caretPos); text->autoScroll(); } void XeTextKeys::delete_right(XeText* text) { if (text->selLength()) { // do a normal backspace (delete the selection) char c = '\b'; text->replaceSelection(&c, 0); return; } if((ulong)text->_anchor.selStart >= text->_text->getSize()) return; if ((*text->_text)[text->_anchor.selStart] == '\n') text->stretchSelection(1, 1, XeTextBase::SelChar, FALSE); else text->stretchSelection(1, 0, XeTextBase::SelChar, FALSE); text->replaceSelection("", 0, FALSE); }