Hi,

I've made 3 minor enhancements to Scintilla which I hope you will
consider incorporating into the proper version.

1) Horizontal scrollbar on long lines: I've added some code to the
Paint() method so it works out the longest line on screen while it is
painting and changes the size of the scrollbar if necessary. This should
work on Windows and GTK, but is only tested on Windows.

2) Find is very slow if the codepage isn't UTF8: This is because
MovePositionOutsideChar() is very slow when it thinks the codepage might
have multi-byte chars, which is whenever the codepage isn't UTF8. I've
created a change so that the codepage is queried (via Windows) for the
maximum char width. If this is 1 then there is nothing to do (CR/LF is
done separately). This should compile on Windows and GTK, but only
Windows queries the codepage (GTK continues to assumes 2 bytes).

3) Rectangular pasting:

a) If the clipboard contains a single line and there is a rectangular
selection (possibly zero-width), then the clipboard line will be copied
onto each of the selected lines.

b) If there is a rectangular selection then pasting will be rectangular
whether the clipboard content was copied rectangular or not; but only if
the number of lines selected matches the number in the clipboard
(excepting case (a) above).

c) If the clipboard contains a rectangular copy, then pasting is not
allowed if there is a stream-selection.

The rectangular changes should compile and work on Windows and compile
with no effect on GTK.

If you have any queries, or would like something done differently feel
free to ask.

-- 
Snow (aka Ross Newell)
diff -r -u scintilla/src/Editor.cxx scin1.67/src/Editor.cxx
--- scintilla/src/Editor.cxx    2005-12-10 09:22:10.000000000 +0000
+++ scin1.67/src/Editor.cxx     2006-03-04 18:18:56.000000000 +0000
@@ -2817,6 +2817,9 @@
                rcTextArea.left = vs.fixedColumnWidth;
                rcTextArea.right -= vs.rightMarginWidth;
                surfaceWindow->SetClip(rcTextArea);
+               
+               int textAreaWidth = rcTextArea.right - rcTextArea.left - 1;
+    int dispScrollWidth = textAreaWidth;
 
                // Loop on visible lines
                //double durLayout = 0.0;
@@ -2861,6 +2864,9 @@
                                        ll->selEnd = -1;
                                        ll->containsCaret = false;
                                }
+                               
+                               int lineLength = 
ll->positions[ll->numCharsInLine];
+        dispScrollWidth = lineLength > dispScrollWidth ? lineLength : 
dispScrollWidth;
 
                                GetHotSpotRange(ll->hsStart, ll->hsEnd);
 
@@ -3004,6 +3010,20 @@
                //if (durPaint < 0.00000001)
                //      durPaint = 0.00000001;
 
+               // If we are scrolled too far right for this page, 
+               // make the scrollbars bigger.
+               if (dispScrollWidth < xOffset + textAreaWidth) {
+                       dispScrollWidth = xOffset + textAreaWidth;
+               }
+
+       // If the needed width is bigger increase it, if the needed width is 
more than 50
+       // smaller and we have painted the whole screen decrease it.
+               if (dispScrollWidth > scrollWidth || 
+               (scrollWidth - dispScrollWidth > 50 && rcClient.Height() == 
rcArea.Height())) {
+                               scrollWidth = dispScrollWidth;
+                       SetScrollBars();
+               }
+
                // Right column limit indicator
                PRectangle rcBeyondEOF = rcClient;
                rcBeyondEOF.left = vs.fixedColumnWidth;
diff -r -u scintilla/win32/ScintillaWin.cxx scin1.67/win32/ScintillaWin.cxx
--- scintilla/win32/ScintillaWin.cxx    2005-11-30 09:42:42.000000000 +0000
+++ scin1.67/win32/ScintillaWin.cxx     2006-03-04 18:24:12.000000000 +0000
@@ -1107,13 +1107,14 @@
        if (!horizontalScrollBarVisible || (wrapState != eWrapNone))
                horizEndPreferred = 0;
        unsigned int pageWidth = rcText.Width();
-       sci.fMask = SIF_PAGE | SIF_RANGE;
        GetScrollInfo(SB_HORZ, &sci);
        if ((sci.nMin != 0) ||
                (sci.nMax != horizEndPreferred) ||
                (sci.nPage != pageWidth) ||
-               (sci.nPos != 0)) {
+                                       (sci.nPos != 0)) {
                sci.fMask = SIF_PAGE | SIF_RANGE;
+               if (horizEndPreferred != 0)
+                       sci.fMask |= SIF_DISABLENOSCROLL;
                sci.nMin = 0;
                sci.nMax = horizEndPreferred;
                sci.nPage = pageWidth;
@@ -1124,6 +1125,12 @@
                if (scrollWidth < static_cast<int>(pageWidth)) {
                        HorizontalScrollTo(0);
                }
+               else if (horizEndPreferred != 0) {
+                       // Sometime Windows won't display the horizontal 
scrollbar
+                       // This seems to persuade it most of the time.
+                       ShowScrollBar(MainHWND(), SB_HORZ, FALSE);              
+                       ShowScrollBar(MainHWND(), SB_HORZ, TRUE);               
+               }
        }
        return modified;
 }
diff -r -u scintilla/gtk/PlatGTK.cxx scin1.67/gtk/PlatGTK.cxx
--- scintilla/gtk/PlatGTK.cxx   2005-08-04 16:36:40.000000000 +0100
+++ scin1.67/gtk/PlatGTK.cxx    2006-03-04 18:36:26.000000000 +0000
@@ -2516,7 +2516,7 @@
 }
 #endif
 
-int Platform::DBCSCharMaxLength() {
+int Platform::DBCSCharMaxLength(int codePage) {
        return MB_CUR_MAX;
        //return 2;
 }
diff -r -u scintilla/include/Platform.h scin1.67/include/Platform.h
--- scintilla/include/Platform.h        2005-03-25 16:08:20.000000000 +0000
+++ scin1.67/include/Platform.h 2006-03-04 18:35:34.000000000 +0000
@@ -477,7 +477,7 @@
                WindowID w, unsigned int msg, unsigned long wParam=0, void 
*lParam=0);
        static bool IsDBCSLeadByte(int codePage, char ch);
        static int DBCSCharLength(int codePage, const char *s);
-       static int DBCSCharMaxLength();
+       static int DBCSCharMaxLength(int codePage);
 
        // These are utility functions not really tied to a platform
        static int Minimum(int a, int b);
diff -r -u scintilla/src/Document.cxx scin1.67/src/Document.cxx
--- scintilla/src/Document.cxx  2005-12-12 10:43:04.000000000 +0000
+++ scin1.67/src/Document.cxx   2006-03-04 18:40:50.000000000 +0000
@@ -271,7 +271,7 @@
        } else if (dbcsCodePage) {
                char mbstr[maxBytesInDBCSCharacter+1];
                int i;
-               for (i=0; i<Platform::DBCSCharMaxLength(); i++) {
+               for (i=0; i<Platform::DBCSCharMaxLength(dbcsCodePage); i++) {
                        mbstr[i] = cb.CharAt(pos+i);
                }
                mbstr[i] = '\0';
@@ -315,14 +315,14 @@
                                        pos--;
                                ch = static_cast<unsigned char>(cb.CharAt(pos));
                        }
-               } else {
+               } else if (Platform::DBCSCharMaxLength(dbcsCodePage) != 1) {
                        // Anchor DBCS calculations at start of line because 
start of line can
                        // not be a DBCS trail byte.
                        int posCheck = LineStart(LineFromPosition(pos));
                        while (posCheck < pos) {
                                char mbstr[maxBytesInDBCSCharacter+1];
                                int i;
-                               for(i=0;i<Platform::DBCSCharMaxLength();i++) {
+                               
for(i=0;i<Platform::DBCSCharMaxLength(dbcsCodePage);i++) {
                                        mbstr[i] = cb.CharAt(posCheck+i);
                                }
                                mbstr[i] = '\0';
diff -r -u scintilla/win32/PlatWin.cxx scin1.67/win32/PlatWin.cxx
--- scintilla/win32/PlatWin.cxx 2005-12-10 21:08:14.000000000 +0000
+++ scin1.67/win32/PlatWin.cxx  2006-03-04 18:33:54.000000000 +0000
@@ -1953,8 +1953,21 @@
        return (::IsDBCSLeadByteEx(codePage, s[0]) != 0) ? 2 : 1;
 }
 
-int Platform::DBCSCharMaxLength() {
-       return 2;
+int Platform::DBCSCharMaxLength(int codePage) {
+       static cachedCodePage;
+       static CPINFO cacheCPInfo;
+
+       if (codePage == 0) {
+               return 1;
+       }
+       if (cachedCodePage != codePage) {
+               if (!GetCPInfo(codePage, &cacheCPInfo)) {
+                       return 2;
+               }
+               cachedCodePage = codePage;
+       }
+
+       return cacheCPInfo.MaxCharSize;
 }
 
 // These are utility functions not really tied to a platform
diff -r -u scin1.67/gtk/ScintillaGTK.cxx scintilla/gtk/ScintillaGTK.cxx
--- scin1.67/gtk/ScintillaGTK.cxx       2005-11-15 23:24:02.000000000 +0000
+++ scintilla/gtk/ScintillaGTK.cxx      2006-03-04 19:26:18.000000000 +0000
@@ -1484,7 +1484,7 @@
                        int selStart = SelectionStart();
 
                        if (selText.rectangular) {
-                               PasteRectangular(selStart, selText.s, 
selText.len);
+                               PasteRectangular(selStart, selText.s, 
selText.len, 0);
                        } else {
                                pdoc->InsertString(currentPos, selText.s, 
selText.len);
                                SetEmptySelection(currentPos + selText.len);
diff -r -u scin1.67/src/Editor.cxx scintilla/src/Editor.cxx
--- scin1.67/src/Editor.cxx     2005-12-10 09:22:10.000000000 +0000
+++ scintilla/src/Editor.cxx    2006-03-04 19:39:06.000000000 +0000
@@ -3401,38 +3401,84 @@
        }
 }
 
-void Editor::PasteRectangular(int pos, const char *ptr, int len) {
+void Editor::PasteRectangular(int pos, const char *ptr, int len, int 
nrSelectedLines) {
        if (pdoc->IsReadOnly() || SelectionContainsProtected()) {
                return;
        }
-       currentPos = pos;
-       int xInsert = XFromPosition(currentPos);
-       int line = pdoc->LineFromPosition(currentPos);
+
+       // Count the nr of lines in the clipboard triming blank lines from 
start 
+       // and end.
+       while (len > 0 && IsEOLChar(ptr[len - 1]))
+               len--;
+       while (len > 0 && IsEOLChar(ptr[0])) {
+               ptr++;
+               len--;
+       }
        bool prevCr = false;
-       pdoc->BeginUndoAction();
+       int nrPastingLines = 1;
        for (int i = 0; i < len; i++) {
-               if (IsEOLChar(ptr[i])) {
-                       if ((ptr[i] == '\r') || (!prevCr))
-                               line++;
-                       if (line >= pdoc->LinesTotal()) {
-                               if (pdoc->eolMode != SC_EOL_LF)
-                                       pdoc->InsertChar(pdoc->Length(), '\r');
-                               if (pdoc->eolMode != SC_EOL_CR)
-                                       pdoc->InsertChar(pdoc->Length(), '\n');
+               if (IsEOLChar(ptr[i])) { 
+                       if (ptr[i] == '\r' || (!prevCr)) {
+                               nrPastingLines++;
                        }
-                       // Pad the end of lines with spaces if required
+                       prevCr = ptr[i] == '\r';
+               }       else {
+                       prevCr = false;
+               }
+       }
+               
+       if (nrPastingLines != 1 && nrSelectedLines > 0 &&        nrPastingLines 
!= nrSelectedLines) {
+               // Beep?
+               return;
+       }
+
+       // Only do this once we know we will proceed.
+       ClearSelection();
+
+       int xInsert = XFromPosition(currentPos);
+       int line = pdoc->LineFromPosition(currentPos);
+
+       pdoc->BeginUndoAction();
+               
+       if (nrPastingLines == 1 && nrSelectedLines > 0) {
+               // Paste the (only) clipboard line onto each selected line.
+               for (int i = 0; i < nrSelectedLines; i++) {
+                       // Pad the beginning of lines with spaces if required
                        currentPos = PositionFromLineX(line, xInsert);
-                       if ((XFromPosition(currentPos) < xInsert) && (i + 1 < 
len)) {
-                               for (int i = 0; i < xInsert - 
XFromPosition(currentPos); i++) {
-                                       pdoc->InsertChar(currentPos, ' ');
-                                       currentPos++;
+                       for (int j = 0; j < xInsert - 
XFromPosition(currentPos); j++) {
+                               pdoc->InsertChar(currentPos, ' ');
+                               currentPos++;
+                       }
+                       pdoc->InsertString(currentPos, ptr, len);
+                       line++;
+               }
+       }       else {
+               prevCr = false;
+               currentPos = pos;
+               for (int i = 0; i < len; i++) {
+                       if (IsEOLChar(ptr[i])) {
+                               if ((ptr[i] == '\r') || (!prevCr))
+                                       line++;
+                               if (line >= pdoc->LinesTotal()) {
+                                       if (pdoc->eolMode != SC_EOL_LF)
+                                               
pdoc->InsertChar(pdoc->Length(), '\r');
+                                       if (pdoc->eolMode != SC_EOL_CR)
+                                               
pdoc->InsertChar(pdoc->Length(), '\n');
                                }
+                               // Pad the beginning of lines with spaces if 
required
+                               currentPos = PositionFromLineX(line, xInsert);
+                               if ((XFromPosition(currentPos) < xInsert) && (i 
+ 1 < len)) {
+                                       for (int i = 0; i < xInsert - 
XFromPosition(currentPos); i++) {
+                                               pdoc->InsertChar(currentPos, ' 
');
+                                               currentPos++;
+                                       }
+                               }
+                               prevCr = ptr[i] == '\r';
+                       } else {
+                               pdoc->InsertString(currentPos, ptr + i, 1);
+                               currentPos++;
+                               prevCr = false;
                        }
-                       prevCr = ptr[i] == '\r';
-               } else {
-                       pdoc->InsertString(currentPos, ptr + i, 1);
-                       currentPos++;
-                       prevCr = false;
                }
        }
        pdoc->EndUndoAction();
@@ -4923,7 +4969,7 @@
                position = positionAfterDeletion;
 
                if (rectangular) {
-                       PasteRectangular(position, value, istrlen(value));
+                       PasteRectangular(position, value, istrlen(value), 0);
                        pdoc->EndUndoAction();
                        // Should try to select new rectangle but it may not be 
a rectangle now so just select the drop position
                        SetEmptySelection(position);
diff -r -u scin1.67/src/Editor.h scintilla/src/Editor.h
--- scin1.67/src/Editor.h       2005-12-10 09:22:10.000000000 +0000
+++ scintilla/src/Editor.h      2006-03-04 18:52:28.000000000 +0000
@@ -414,7 +414,7 @@
        void ClearAll();
        void ClearDocumentStyle();
        void Cut();
-       void PasteRectangular(int pos, const char *ptr, int len);
+       void PasteRectangular(int pos, const char *ptr, int len, int 
nrSelectedLines);
        virtual void Copy() = 0;
        virtual bool CanPaste();
        virtual void Paste() = 0;
diff -r -u scin1.67/win32/ScintillaWin.cxx scintilla/win32/ScintillaWin.cxx
--- scin1.67/win32/ScintillaWin.cxx     2005-11-30 09:42:42.000000000 +0000
+++ scintilla/win32/ScintillaWin.cxx    2006-03-04 18:58:20.000000000 +0000
@@ -222,7 +222,7 @@
        virtual bool GetScrollInfo(int nBar, LPSCROLLINFO lpsi);
        void ChangeScrollPos(int barType, int pos);
 
-       void InsertPasteText(const char *text, int len, int selStart, bool 
isRectangular);
+       void InsertPasteText(const char *text, int len, int selStart, int 
rectangularNrLines);
 
 public:
        // Public for benefit of Scintilla_DirectFunction
@@ -1237,10 +1237,11 @@
        }
 };
 
-void ScintillaWin::InsertPasteText(const char *text, int len, int selStart, 
bool isRectangular) {
-       if (isRectangular) {
-               PasteRectangular(selStart, text, len);
+void ScintillaWin::InsertPasteText(const char *text, int len, int selStart, 
int rectangularNrLines) {
+       if (rectangularNrLines != 0) {
+               PasteRectangular(selStart, text, len, rectangularNrLines);
        } else {
+               ClearSelection();
                if (convertPastes) {
                        // Convert line endings of the paste into our local 
line-endings mode
                        char *convertedString = 
Document::TransformLineEnds(&len, text, len, pdoc->eolMode);
@@ -1260,10 +1261,28 @@
        if (!::OpenClipboard(MainHWND()))
                return;
        pdoc->BeginUndoAction();
-       ClearSelection();
+       
        int selStart = SelectionStart();
-       bool isRectangular = ::IsClipboardFormatAvailable(cfColumnSelect) != 0;
+       int selEnd = SelectionEnd();
+       int rectangularNrLines = 0;
 
+       // If there is a rectangular selection count the nr lines selected.
+       bool isRectangular = selType == selRectangle;
+       if (isRectangular) {
+               int firstLine = pdoc->LineFromPosition(selStart);
+               int lastLine = pdoc->LineFromPosition(selEnd);
+               rectangularNrLines = lastLine - firstLine + 1;
+       }       
+       else if (::IsClipboardFormatAvailable(cfColumnSelect)) { 
+               if (selStart != selEnd) {
+                       return;
+               }
+               else {
+                       isRectangular = true;
+                       rectangularNrLines = -1;
+               }
+       }
+       
        // Always use CF_UNICODETEXT if available
        GlobalMemory memUSelection(::GetClipboardData(CF_UNICODETEXT));
        if (memUSelection) {
@@ -1294,7 +1313,7 @@
                        }
 
                        if (putf) {
-                               InsertPasteText(putf, len, selStart, 
isRectangular);
+                               InsertPasteText(putf, len, selStart, 
rectangularNrLines);
                                delete []putf;
                        }
                }
@@ -1329,11 +1348,11 @@
                                        delete []uptr;
 
                                        if (putf) {
-                                               InsertPasteText(putf, mlen, 
selStart, isRectangular);
+                                               InsertPasteText(putf, mlen, 
selStart, rectangularNrLines);
                                                delete []putf;
                                        }
                                } else {
-                                       InsertPasteText(ptr, len, selStart, 
isRectangular);
+                                       InsertPasteText(ptr, len, selStart, 
rectangularNrLines);
                                }
                        }
                        memSelection.Unlock();
_______________________________________________
Scintilla-interest mailing list
[email protected]
http://mailman.lyra.org/mailman/listinfo/scintilla-interest

Reply via email to