@@ -996,162 +996,98 @@ int Editor::contextHelp()
996996 return 1 ;
997997}
998998
999- void Editor::highlightBlock (QTextCursor *cur)
1000- {
1001- // anchor and position vary depending on select up or down
1002- int beg = cur->position ();
1003- int end = cur->anchor ();
1004-
1005- // swap begin and end?
1006- if (beg > end) {
1007- beg = cur->anchor ();
1008- end = cur->position ();
1009- }
1010-
1011- // find new begin and end
1012- cur->setPosition (beg, QTextCursor::MoveAnchor);
1013- cur->movePosition (QTextCursor::StartOfLine, QTextCursor::MoveAnchor);
1014- beg = cur->anchor ();
1015- cur->setPosition (end, QTextCursor::MoveAnchor);
1016- cur->movePosition (QTextCursor::EndOfLine, QTextCursor::MoveAnchor);
1017- end = cur->anchor ();
1018-
1019- // set new cursor positions
1020- cur->setPosition (beg, QTextCursor::MoveAnchor);
1021- cur->setPosition (end, QTextCursor::KeepAnchor);
1022- }
1023-
1024999int Editor::tabBlockShift ()
10251000{
1001+ /* make tabs based on user preference - set by mainwindow */
10261002 int tabSpaces = propDialog->getTabSpaces ();
1003+ QString tab (tabSpaces, ' ' );
10271004
10281005 QTextCursor cur = this ->textCursor ();
1029- int curbeg = cur.selectionStart ();
10301006
10311007 /* do we have shift ? */
1032- bool shift = false ;
1033- if ((QApplication::keyboardModifiers () & Qt::SHIFT))
1034- shift = true ;
1035-
1036- /* make tabs based on user preference - set by mainwindow */
1037- QString tab = " " ;
1038- for (int n = tabSpaces; n > 0 ; n--) tab+=" " ;
1039-
1040- QString text = cur.selectedText ();
1041-
1042- /* if a block is selected */
1043- if (cur.selectedText ().length () > 0 && cur.selectedText ().contains (QChar::ParagraphSeparator) == true ) {
1044-
1045- highlightBlock (&cur);
1046- curbeg = cur.selectionStart ();
1047-
1048- QStringList mylist;
1049-
1050- /* highlight block from beginning of the first line to the last line */
1051- int column = cur.columnNumber ();
1052- #if 0
1053- // I found this method had some troubles.
1054- // Using highlightBlock() instead.
1055- if(column > 0) {
1056- cur.setPosition(curbeg-column,QTextCursor::MoveAnchor);
1057- cur.movePosition(QTextCursor::Right,QTextCursor::KeepAnchor, text.length()+column);
1058- text = cur.selectedText();
1059- }
1060- #endif
1061- text = cur.selectedText ();
1062- if (text.length () == 0 )
1063- return 0 ;
1008+ bool shiftTab = QApplication::keyboardModifiers () & Qt::SHIFT;
10641009
1065- /* get a list of the selected block. keep empty lines */
1066- mylist = text.split (QChar::ParagraphSeparator);
1010+ /* block is selected */
1011+ if (cur.hasSelection () && cur.selectedText ().contains (QChar::ParagraphSeparator)) {
1012+ /* determine current selection */
1013+ int curbeg = cur.selectionStart ();
1014+ int curend = cur.selectionEnd ();
10671015
1068- /* start a single undo/redo operation */
1069- cur.beginEditBlock ();
1016+ /* create workable selection */
1017+ cur.setPosition (curbeg, QTextCursor::MoveAnchor);
1018+ cur.movePosition (QTextCursor::StartOfLine, QTextCursor::MoveAnchor);
1019+ cur.setPosition (curend, QTextCursor::KeepAnchor);
10701020
1071- /* get rid of old block */
1072- cur.removeSelectedText ( );
1021+ /* get a list of lines in the selected block. keep empty lines */
1022+ QStringList mylist = cur.selectedText (). split (QChar::ParagraphSeparator );
10731023
10741024 /* indent list */
1075- text = " " ;
1076- for (int n = 0 ; n < mylist.length (); n++) {
1077- QString s = mylist.at (n);
1078- if (s.length () == 0 && n+1 == mylist.length ())
1079- break ;
1080-
1081- if (shift == false ) {
1082- for (int n = tabSpaces; n > 0 ; n--) s = " " + s;
1083- }
1084- else {
1085- if (s.indexOf (tab) == 0 || (n == 0 && column >= tabSpaces && s.at (0 ) == ' ' )) {
1086- s = s.mid (tabSpaces);
1087- }
1088- /* Sometimes code isn't aligned according to tabSpaces. Fix it.
1089- * This means that some indented lines can get unindented though.
1090- */
1091- else {
1092- for (int j = tabSpaces; s.length () > 0 && j > 0 ; j--) {
1093- if (s.at (0 ) == ' ' ) {
1094- s = s.mid (1 );
1095- }
1096- }
1097- }
1025+ QString text;
1026+
1027+ for (int n = 1 ; n <= mylist.length (); n++) {
1028+ QString s = mylist[n-1 ];
1029+ int size = s.length ();
1030+
1031+ /* ignore empty last line */
1032+ if (size == 0 && n == mylist.length ()) break ;
1033+
1034+ if (!shiftTab) s.insert (0 , tab); // increase line indent
1035+ else if (s.startsWith (tab)) s.remove (0 , tabSpaces); // decrease line indent
1036+ else s.replace (QRegExp (" ^ *" ), " " ); // remove leading spaces
1037+
1038+ /* adjust selection */
1039+ if (n == 1 ) {
1040+ curbeg -= size - s.length (); // only first line
1041+ curbeg = std::max (curbeg, cur.selectionStart ()); // avoid underflow
10981042 }
1043+ curend -= size - s.length (); // all but an empty last line
1044+
1045+ /* rebuild block */
10991046 text += s;
1100- if (n+1 < mylist.length ())
1101- text += " \n " ;
1047+ if (n < mylist.length ()) text += QChar::ParagraphSeparator;
11021048 }
11031049 /* insert new block */
1104- cur.insertText (text);
1105-
1106- cur.setPosition (curbeg,QTextCursor::MoveAnchor);
1107- cur.movePosition (QTextCursor::Right,QTextCursor::MoveAnchor, text.length ());
1108- cur.movePosition (QTextCursor::Left,QTextCursor::KeepAnchor, text.length ());
1109- this ->setTextCursor (cur);
1110-
1111- /* end single undo/redo operation */
1112- cur.endEditBlock ();
1113- }
1114- /* a single-line selection */
1115- else {
1116- int selectStart = cur.selectionStart (); /* for resetting selection when done */
1117- int selectEnd = cur.selectionEnd ();
1118- int selectLength = selectEnd - selectStart;
1119- cur.setPosition (selectStart,QTextCursor::MoveAnchor); /* reset cursor to start of selection */
1120- int column = cur.columnNumber (); /* column to start insertion */
1121- int cursorPos = cur.position (); /* cursor position within text */
1122-
1123- if (cursorPos > -1 ) {
1124- if (shift == false ) {
1125- for (int n = column % tabSpaces; n < tabSpaces; n++) {
1126- cur.insertText (" " );
1127- cursorPos++;
1128- }
1129- cur.setPosition (cursorPos,QTextCursor::MoveAnchor); /* reset selection */
1130- cur.movePosition (QTextCursor::Right,QTextCursor::MoveAnchor, selectLength);
1131- cur.movePosition (QTextCursor::Left,QTextCursor::KeepAnchor, selectLength);
1132- this ->setTextCursor (cur);
1133- }
1134- else if (cur.columnNumber () != 0 ) {
1135- QString st;
1136- for (int n = column % tabSpaces; n < tabSpaces; n++) {
1137- cur.movePosition (QTextCursor::Left,QTextCursor::KeepAnchor);
1138- st = cur.selectedText ();
1139- if (st.length () == 1 && st.at (0 ) == ' ' ) {
1140- cur.removeSelectedText ();
1141- if (cur.columnNumber () % tabSpaces == 0 )
1142- break ;
1143- }
1144- if (st.at (0 ) != ' ' )
1145- cur.movePosition (QTextCursor::Right,QTextCursor::MoveAnchor);
1146- }
1147- /* reset selection */
1148- cur.movePosition (QTextCursor::Right,QTextCursor::MoveAnchor, selectLength);
1149- cur.movePosition (QTextCursor::Left,QTextCursor::KeepAnchor, selectLength);
1150- this ->setTextCursor (cur);
1151- }
1152- }
1153- this ->setTextCursor (cur);
1050+ if (cur.selectedText ().length () != text.length ()) // avoid empty undo actions
1051+ cur.insertText (text);
1052+
1053+ /* update selection */
1054+ cur.setPosition (curbeg, QTextCursor::MoveAnchor);
1055+ cur.setPosition (curend, QTextCursor::KeepAnchor);
1056+
1057+ } else if (!shiftTab) {
1058+ int column = cur.columnNumber () + (cur.selectionStart () - cur.position ());
1059+ cur.insertText (QString (tabSpaces - column % tabSpaces, ' ' ));
1060+ } else {
1061+ /* determine current selection */
1062+ int curbeg = cur.selectionStart ();
1063+ int curend = cur.selectionEnd ();
1064+
1065+ /* create workable selection */
1066+ cur.setPosition (curbeg, QTextCursor::MoveAnchor);
1067+ cur.movePosition (QTextCursor::StartOfLine, QTextCursor::MoveAnchor);
1068+ cur.movePosition (QTextCursor::EndOfLine, QTextCursor::KeepAnchor);
1069+
1070+ /* indent line */
1071+ QString line = cur.selectedText ();
1072+ int size = line.length ();
1073+
1074+ if (line.startsWith (tab)) line.remove (0 , tabSpaces); // decrease line indent
1075+ else line.replace (QRegExp (" ^ *" ), " " ); // remove leading spaces
1076+
1077+ /* adjust selection */
1078+ curbeg = std::max (curbeg - size + line.length (), cur.selectionStart ());
1079+ curend = std::max (curend - size + line.length (), cur.selectionStart ());
1080+
1081+ /* insert new line */
1082+ if (cur.selectedText ().length () != line.length ()) // avoid empty undo actions
1083+ cur.insertText (line);
1084+
1085+ /* update selection */
1086+ cur.setPosition (curbeg, QTextCursor::MoveAnchor);
1087+ cur.setPosition (curend, QTextCursor::KeepAnchor);
11541088 }
1089+ this ->setTextCursor (cur);
1090+
11551091 return 1 ;
11561092}
11571093
0 commit comments