File indexing completed on 2024-06-16 04:10:05
0001 0002 /* 0003 Copyright (c) 2003-2007 Clarence Dang <dang@kde.org> 0004 All rights reserved. 0005 0006 Redistribution and use in source and binary forms, with or without 0007 modification, are permitted provided that the following conditions 0008 are met: 0009 0010 1. Redistributions of source code must retain the above copyright 0011 notice, this list of conditions and the following disclaimer. 0012 2. Redistributions in binary form must reproduce the above copyright 0013 notice, this list of conditions and the following disclaimer in the 0014 documentation and/or other materials provided with the distribution. 0015 0016 THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 0017 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 0018 OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 0019 IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 0020 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 0021 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 0022 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 0023 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 0024 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 0025 THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 0026 */ 0027 0028 #define DEBUG_KP_TOOL_TEXT 0 0029 0030 0031 #include "tools/selection/text/kpToolText.h" 0032 #include "kpLogCategories.h" 0033 #include "document/kpDocument.h" 0034 #include "layers/selections/text/kpTextSelection.h" 0035 #include "commands/tools/selection/text/kpToolTextBackspaceCommand.h" 0036 #include "commands/tools/selection/text/kpToolTextChangeStyleCommand.h" 0037 #include "commands/tools/selection/kpToolSelectionCreateCommand.h" 0038 #include "environments/tools/selection/kpToolSelectionEnvironment.h" 0039 #include "commands/tools/selection/text/kpToolTextDeleteCommand.h" 0040 #include "commands/tools/selection/text/kpToolTextEnterCommand.h" 0041 #include "commands/tools/selection/text/kpToolTextInsertCommand.h" 0042 #include "widgets/toolbars/options/kpToolWidgetOpaqueOrTransparent.h" 0043 #include "views/kpView.h" 0044 #include "views/manager/kpViewManager.h" 0045 0046 #include <QList> 0047 0048 #include <KLocalizedString> 0049 0050 // protected static 0051 bool kpToolText::CursorIsOnWordChar (const QList <QString> &textLines, 0052 int cursorRow, int cursorCol) 0053 { 0054 return (cursorRow >= 0 && cursorRow < textLines.size () && 0055 cursorCol >= 0 && cursorCol < textLines [cursorRow].length () && 0056 !textLines [cursorRow][cursorCol].isSpace ()); 0057 } 0058 0059 0060 // protected static 0061 bool kpToolText::CursorIsAtStart (const QList <QString> &, 0062 int cursorRow, int cursorCol) 0063 { 0064 return (cursorRow == 0 && cursorCol == 0); 0065 } 0066 0067 // protected static 0068 bool kpToolText::CursorIsAtEnd (const QList <QString> &textLines, 0069 int cursorRow, int cursorCol) 0070 { 0071 if (textLines.isEmpty ()) { 0072 return (cursorRow == 0 && cursorCol == 0); 0073 } 0074 0075 return (cursorRow == textLines.size () - 1 && 0076 cursorCol == textLines [cursorRow].length ()); 0077 } 0078 0079 0080 // protected static 0081 void kpToolText::MoveCursorLeft (const QList <QString> &textLines, 0082 int *cursorRow, int *cursorCol) 0083 { 0084 if (textLines.isEmpty ()) { 0085 return; 0086 } 0087 0088 (*cursorCol)--; 0089 0090 if (*cursorCol < 0) 0091 { 0092 (*cursorRow)--; 0093 if (*cursorRow < 0) 0094 { 0095 *cursorRow = 0; 0096 *cursorCol = 0; 0097 } 0098 else { 0099 *cursorCol = textLines [*cursorRow].length (); 0100 } 0101 } 0102 } 0103 0104 // protected static 0105 void kpToolText::MoveCursorRight (const QList <QString> &textLines, 0106 int *cursorRow, int *cursorCol) 0107 { 0108 if (textLines.isEmpty ()) { 0109 return; 0110 } 0111 0112 (*cursorCol)++; 0113 0114 if (*cursorCol > textLines [*cursorRow].length ()) 0115 { 0116 (*cursorRow)++; 0117 if (*cursorRow > textLines.size () - 1) 0118 { 0119 *cursorRow = textLines.size () - 1; 0120 *cursorCol = textLines [*cursorRow].length (); 0121 } 0122 else { 0123 *cursorCol = 0; 0124 } 0125 } 0126 } 0127 0128 0129 #define IS_ON_SPACE_OR_EOL() !CursorIsOnWordChar (textLines, *cursorRow, *cursorCol) 0130 0131 // protected static 0132 int kpToolText::MoveCursorToWordStart (const QList <QString> &textLines, 0133 int *cursorRow, int *cursorCol) 0134 { 0135 if (textLines.isEmpty ()) { 0136 return 0; 0137 } 0138 0139 int numMoves = 0; 0140 0141 #define IS_ON_ANCHOR() \ 0142 (CursorIsOnWordChar (textLines, *cursorRow, *cursorCol) && \ 0143 (cursorCol == nullptr || \ 0144 !CursorIsOnWordChar (textLines, *cursorRow, *cursorCol - 1))) 0145 #define MOVE_CURSOR_LEFT() \ 0146 (MoveCursorLeft (textLines, cursorRow, cursorCol), ++numMoves) 0147 0148 0149 // (these comments will exclude the row=0,col=0 boundary case) 0150 0151 if (IS_ON_ANCHOR ()) { 0152 MOVE_CURSOR_LEFT (); 0153 } 0154 0155 // --- now we're not on an anchor point (start of word) --- 0156 0157 // End up on a letter... 0158 while (!(*cursorRow == 0 && *cursorCol == 0) && 0159 (IS_ON_SPACE_OR_EOL ())) 0160 { 0161 MOVE_CURSOR_LEFT (); 0162 } 0163 0164 // --- now we're on a letter --- 0165 0166 // Find anchor point 0167 while (!(*cursorRow == 0 && *cursorCol == 0) && !IS_ON_ANCHOR ()) 0168 { 0169 MOVE_CURSOR_LEFT (); 0170 } 0171 0172 0173 #undef IS_ON_ANCHOR 0174 #undef MOVE_CURSOR_LEFT 0175 0176 return numMoves; 0177 } 0178 0179 // protected static 0180 int kpToolText::MoveCursorToNextWordStart (const QList <QString> &textLines, 0181 int *cursorRow, int *cursorCol) 0182 { 0183 if (textLines.isEmpty ()) { 0184 return 0; 0185 } 0186 0187 int numMoves = 0; 0188 0189 #define IS_AT_END() CursorIsAtEnd (textLines, *cursorRow, *cursorCol) 0190 #define MOVE_CURSOR_RIGHT() \ 0191 (MoveCursorRight (textLines, cursorRow, cursorCol), ++numMoves) 0192 0193 0194 // (these comments will exclude the last row,end col boundary case) 0195 0196 // Find space 0197 while (!IS_AT_END () && !IS_ON_SPACE_OR_EOL ()) 0198 { 0199 MOVE_CURSOR_RIGHT (); 0200 } 0201 0202 // --- now we're on a space --- 0203 0204 // Find letter 0205 while (!IS_AT_END () && IS_ON_SPACE_OR_EOL ()) 0206 { 0207 MOVE_CURSOR_RIGHT (); 0208 } 0209 0210 // --- now we're on a letter --- 0211 0212 0213 #undef IS_AT_END 0214 #undef MOVE_CURSOR_RIGHT 0215 0216 return numMoves; 0217 } 0218 0219 #undef IS_ON_SPACE_OR_EOL 0220