Initial version of wxStyledTextCtrl, a Scintilla wrapper. There is
still LOTS and LOTS to be done, but this is already very functional. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@6555 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
585
contrib/src/stc/PlatWX.cpp
Normal file
585
contrib/src/stc/PlatWX.cpp
Normal file
@@ -0,0 +1,585 @@
|
||||
// Scintilla source code edit control
|
||||
// PlatWX.cxx - implementation of platform facilities on wxWindows
|
||||
// Copyright 1998-1999 by Neil Hodgson <neilh@scintilla.org>
|
||||
// Robin Dunn <robin@aldunn.com>
|
||||
// The License.txt file describes the conditions under which this software may be distributed.
|
||||
|
||||
|
||||
#include "Platform.h"
|
||||
#include "wx/stc/stc.h"
|
||||
|
||||
Point Point::FromLong(long lpoint) {
|
||||
return Point(lpoint & 0xFFFF, lpoint >> 32);
|
||||
}
|
||||
|
||||
wxRect wxRectFromPRectangle(PRectangle prc) {
|
||||
wxRect rc(prc.left, prc.top,
|
||||
prc.right-prc.left+1, prc.bottom-prc.top+1);
|
||||
return rc;
|
||||
}
|
||||
|
||||
PRectangle PRectangleFromwxRect(wxRect rc) {
|
||||
return PRectangle(rc.GetLeft(), rc.GetTop(), rc.GetRight(), rc.GetBottom());
|
||||
}
|
||||
|
||||
Colour::Colour(long lcol) {
|
||||
co.Set(lcol & 0xff, (lcol >> 8) & 0xff, (lcol >> 16) & 0xff);
|
||||
}
|
||||
|
||||
Colour::Colour(unsigned int red, unsigned int green, unsigned int blue) {
|
||||
co.Set(red, green, blue);
|
||||
}
|
||||
|
||||
bool Colour::operator==(const Colour &other) const {
|
||||
return co == other.co;
|
||||
}
|
||||
|
||||
long Colour::AsLong() const {
|
||||
return (((long)co.Blue() << 16) |
|
||||
((long)co.Green() << 8) |
|
||||
((long)co.Red()));
|
||||
}
|
||||
|
||||
unsigned int Colour::GetRed() {
|
||||
return co.Red();
|
||||
}
|
||||
|
||||
unsigned int Colour::GetGreen() {
|
||||
return co.Green();
|
||||
}
|
||||
|
||||
unsigned int Colour::GetBlue() {
|
||||
return co.Blue();
|
||||
}
|
||||
|
||||
Palette::Palette() {
|
||||
used = 0;
|
||||
allowRealization = false;
|
||||
}
|
||||
|
||||
Palette::~Palette() {
|
||||
Release();
|
||||
}
|
||||
|
||||
void Palette::Release() {
|
||||
used = 0;
|
||||
}
|
||||
|
||||
// This method either adds a colour to the list of wanted colours (want==true)
|
||||
// or retrieves the allocated colour back to the ColourPair.
|
||||
// This is one method to make it easier to keep the code for wanting and retrieving in sync.
|
||||
void Palette::WantFind(ColourPair &cp, bool want) {
|
||||
if (want) {
|
||||
for (int i=0; i < used; i++) {
|
||||
if (entries[i].desired == cp.desired)
|
||||
return;
|
||||
}
|
||||
|
||||
if (used < numEntries) {
|
||||
entries[used].desired = cp.desired;
|
||||
entries[used].allocated = cp.desired;
|
||||
used++;
|
||||
}
|
||||
} else {
|
||||
for (int i=0; i < used; i++) {
|
||||
if (entries[i].desired == cp.desired) {
|
||||
cp.allocated = entries[i].allocated;
|
||||
return;
|
||||
}
|
||||
}
|
||||
cp.allocated = cp.desired;
|
||||
}
|
||||
}
|
||||
|
||||
void Palette::Allocate(Window &) {
|
||||
if (allowRealization) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Font::Font() {
|
||||
id = 0;
|
||||
ascent = 0;
|
||||
}
|
||||
|
||||
Font::~Font() {
|
||||
}
|
||||
|
||||
void Font::Create(const char *faceName, int size, bool bold, bool italic) {
|
||||
Release();
|
||||
id = new wxFont(size,
|
||||
wxDEFAULT,
|
||||
italic ? wxITALIC : wxNORMAL,
|
||||
bold ? wxBOLD : wxNORMAL,
|
||||
false,
|
||||
faceName);
|
||||
}
|
||||
|
||||
|
||||
void Font::Release() {
|
||||
if (id)
|
||||
delete id;
|
||||
id = 0;
|
||||
}
|
||||
|
||||
|
||||
Surface::Surface() :
|
||||
hdc(0), hdcOwned(0), bitmap(0),
|
||||
x(0), y(0) {
|
||||
}
|
||||
|
||||
Surface::~Surface() {
|
||||
Release();
|
||||
}
|
||||
|
||||
void Surface::Release() {
|
||||
if (bitmap) {
|
||||
((wxMemoryDC*)hdc)->SelectObject(wxNullBitmap);
|
||||
delete bitmap;
|
||||
bitmap = 0;
|
||||
}
|
||||
if (hdcOwned) {
|
||||
delete hdc;
|
||||
hdc = 0;
|
||||
hdcOwned = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool Surface::Initialised() {
|
||||
return hdc != 0;
|
||||
}
|
||||
|
||||
void Surface::Init() {
|
||||
Release();
|
||||
hdc = new wxMemoryDC();
|
||||
hdcOwned = true;
|
||||
// **** ::SetTextAlign(hdc, TA_BASELINE);
|
||||
}
|
||||
|
||||
void Surface::Init(SurfaceID hdc_) {
|
||||
Release();
|
||||
hdc = hdc_;
|
||||
// **** ::SetTextAlign(hdc, TA_BASELINE);
|
||||
}
|
||||
|
||||
void Surface::InitPixMap(int width, int height, Surface *surface_) {
|
||||
Release();
|
||||
hdc = new wxMemoryDC(surface_->hdc);
|
||||
hdcOwned = true;
|
||||
bitmap = new wxBitmap(width, height);
|
||||
((wxMemoryDC*)hdc)->SelectObject(*bitmap);
|
||||
// **** ::SetTextAlign(hdc, TA_BASELINE);
|
||||
}
|
||||
|
||||
void Surface::PenColour(Colour fore) {
|
||||
hdc->SetPen(wxPen(fore.co, 1, wxSOLID));
|
||||
}
|
||||
|
||||
void Surface::BrushColor(Colour back) {
|
||||
hdc->SetBrush(wxBrush(back.co, wxSOLID));
|
||||
}
|
||||
|
||||
void Surface::SetFont(Font &font_) {
|
||||
hdc->SetFont(*font_.GetID());
|
||||
}
|
||||
|
||||
int Surface::LogPixelsY() {
|
||||
return hdc->GetPPI().y;
|
||||
}
|
||||
|
||||
void Surface::MoveTo(int x_, int y_) {
|
||||
x = x_;
|
||||
y = y_;
|
||||
}
|
||||
|
||||
void Surface::LineTo(int x_, int y_) {
|
||||
hdc->DrawLine(x,y, x_,y_);
|
||||
x = x_;
|
||||
y = y_;
|
||||
}
|
||||
|
||||
void Surface::Polygon(Point *pts, int npts, Colour fore,
|
||||
Colour back) {
|
||||
PenColour(fore);
|
||||
BrushColor(back);
|
||||
hdc->DrawPolygon(npts, (wxPoint*)pts);
|
||||
}
|
||||
|
||||
void Surface::RectangleDraw(PRectangle rc, Colour fore, Colour back) {
|
||||
PenColour(fore);
|
||||
BrushColor(back);
|
||||
hdc->DrawRectangle(wxRectFromPRectangle(rc));
|
||||
}
|
||||
|
||||
void Surface::FillRectangle(PRectangle rc, Colour back) {
|
||||
BrushColor(back);
|
||||
hdc->SetPen(*wxTRANSPARENT_PEN);
|
||||
hdc->DrawRectangle(wxRectFromPRectangle(rc));
|
||||
}
|
||||
|
||||
void Surface::FillRectangle(PRectangle rc, Surface &surfacePattern) {
|
||||
wxBrush br;
|
||||
if (surfacePattern.bitmap)
|
||||
br = wxBrush(*surfacePattern.bitmap);
|
||||
else // Something is wrong so display in red
|
||||
br = wxBrush(*wxRED, wxSOLID);
|
||||
hdc->SetPen(*wxTRANSPARENT_PEN);
|
||||
hdc->SetBrush(br);
|
||||
hdc->DrawRectangle(wxRectFromPRectangle(rc));
|
||||
}
|
||||
|
||||
void Surface::RoundedRectangle(PRectangle rc, Colour fore, Colour back) {
|
||||
PenColour(fore);
|
||||
BrushColor(back);
|
||||
hdc->DrawRoundedRectangle(wxRectFromPRectangle(rc), 8);
|
||||
}
|
||||
|
||||
void Surface::Ellipse(PRectangle rc, Colour fore, Colour back) {
|
||||
PenColour(fore);
|
||||
BrushColor(back);
|
||||
hdc->DrawEllipse(wxRectFromPRectangle(rc));
|
||||
}
|
||||
|
||||
void Surface::Copy(PRectangle rc, Point from, Surface &surfaceSource) {
|
||||
hdc->Blit(rc.left, rc.top, rc.Width(), rc.Height(),
|
||||
surfaceSource.hdc, from.x, from.y, wxCOPY);
|
||||
}
|
||||
|
||||
void Surface::DrawText(PRectangle rc, Font &font, int ybase,
|
||||
const char *s, int len, Colour fore, Colour back) {
|
||||
SetFont(font);
|
||||
hdc->SetTextForeground(fore.co);
|
||||
hdc->SetTextBackground(back.co);
|
||||
FillRectangle(rc, back);
|
||||
|
||||
// ybase is where the baseline should be, but wxWin uses the upper left
|
||||
// corner, so I need to calculate the real position for the text...
|
||||
hdc->DrawText(wxString(s, len), rc.left, ybase - font.ascent);
|
||||
}
|
||||
|
||||
void Surface::DrawTextClipped(PRectangle rc, Font &font, int ybase, const char *s, int len, Colour fore, Colour back) {
|
||||
SetFont(font);
|
||||
hdc->SetTextForeground(fore.co);
|
||||
hdc->SetTextBackground(back.co);
|
||||
FillRectangle(rc, back);
|
||||
hdc->SetClippingRegion(wxRectFromPRectangle(rc));
|
||||
|
||||
// see comments above
|
||||
hdc->DrawText(wxString(s, len), rc.left, ybase - font.ascent);
|
||||
hdc->DestroyClippingRegion();
|
||||
}
|
||||
|
||||
int Surface::WidthText(Font &font, const char *s, int len) {
|
||||
SetFont(font);
|
||||
int w;
|
||||
int h;
|
||||
hdc->GetTextExtent(wxString(s, len), &w, &h);
|
||||
return w;
|
||||
}
|
||||
|
||||
void Surface::MeasureWidths(Font &font, const char *s, int len, int *positions) {
|
||||
SetFont(font);
|
||||
int totalWidth = 0;
|
||||
for (int i=0; i<len; i++) {
|
||||
int w;
|
||||
int h;
|
||||
hdc->GetTextExtent(s[i], &w, &h);
|
||||
totalWidth += w;
|
||||
positions[i] = totalWidth;
|
||||
}
|
||||
}
|
||||
|
||||
int Surface::WidthChar(Font &font, char ch) {
|
||||
SetFont(font);
|
||||
int w;
|
||||
int h;
|
||||
hdc->GetTextExtent(ch, &w, &h);
|
||||
return w;
|
||||
}
|
||||
|
||||
#define EXTENT_TEST " `~!@#$%^&*()-_=+\\|[]{};:\"\'<,>.?/1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||
|
||||
int Surface::Ascent(Font &font) {
|
||||
SetFont(font);
|
||||
int w, h, d, e;
|
||||
hdc->GetTextExtent(EXTENT_TEST, &w, &h, &d, &e);
|
||||
font.ascent = h - d;
|
||||
return font.ascent;
|
||||
}
|
||||
|
||||
int Surface::Descent(Font &font) {
|
||||
SetFont(font);
|
||||
int w, h, d, e;
|
||||
hdc->GetTextExtent(EXTENT_TEST, &w, &h, &d, &e);
|
||||
return d;
|
||||
}
|
||||
|
||||
int Surface::InternalLeading(Font &font) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Surface::ExternalLeading(Font &font) {
|
||||
SetFont(font);
|
||||
int w, h, d, e;
|
||||
hdc->GetTextExtent(EXTENT_TEST, &w, &h, &d, &e);
|
||||
return e;
|
||||
}
|
||||
|
||||
int Surface::Height(Font &font) {
|
||||
SetFont(font);
|
||||
return hdc->GetCharHeight();
|
||||
}
|
||||
|
||||
int Surface::AverageCharWidth(Font &font) {
|
||||
SetFont(font);
|
||||
return hdc->GetCharWidth();
|
||||
}
|
||||
|
||||
int Surface::SetPalette(Palette *pal, bool inBackGround) {
|
||||
return 0; // **** figure out what to do with palettes...
|
||||
}
|
||||
|
||||
void Surface::SetClip(PRectangle rc) {
|
||||
hdc->SetClippingRegion(wxRectFromPRectangle(rc));
|
||||
}
|
||||
|
||||
|
||||
|
||||
Window::~Window() {
|
||||
}
|
||||
|
||||
void Window::Destroy() {
|
||||
if (id)
|
||||
id->Destroy();
|
||||
id = 0;
|
||||
}
|
||||
|
||||
bool Window::HasFocus() {
|
||||
return wxWindow::FindFocus() == id;
|
||||
}
|
||||
|
||||
PRectangle Window::GetPosition() {
|
||||
wxRect rc(id->GetPosition(), id->GetSize());
|
||||
return PRectangleFromwxRect(rc);
|
||||
}
|
||||
|
||||
void Window::SetPosition(PRectangle rc) {
|
||||
id->SetSize(rc.left, rc.top, rc.Width(), rc.Height());
|
||||
}
|
||||
|
||||
void Window::SetPositionRelative(PRectangle rc, Window) {
|
||||
SetPosition(rc); // ????
|
||||
}
|
||||
|
||||
PRectangle Window::GetClientPosition() {
|
||||
wxSize sz = id->GetClientSize();
|
||||
return PRectangle(0, 0, sz.x - 1, sz.y - 1);
|
||||
}
|
||||
|
||||
void Window::Show(bool show) {
|
||||
id->Show(show);
|
||||
}
|
||||
|
||||
void Window::InvalidateAll() {
|
||||
id->Refresh(false);
|
||||
}
|
||||
|
||||
void Window::InvalidateRectangle(PRectangle rc) {
|
||||
id->Refresh(false, &wxRectFromPRectangle(rc));
|
||||
}
|
||||
|
||||
void Window::SetFont(Font &font) {
|
||||
id->SetFont(*font.GetID());
|
||||
}
|
||||
|
||||
void Window::SetCursor(Cursor curs) {
|
||||
int cursorId;
|
||||
|
||||
switch (curs) {
|
||||
case cursorText:
|
||||
cursorId = wxCURSOR_IBEAM;
|
||||
break;
|
||||
case cursorArrow:
|
||||
cursorId = wxCURSOR_ARROW;
|
||||
break;
|
||||
case cursorUp:
|
||||
cursorId = wxCURSOR_ARROW; // ** no up arrow... wxCURSOR_UPARROW;
|
||||
break;
|
||||
case cursorWait:
|
||||
cursorId = wxCURSOR_WAIT;
|
||||
break;
|
||||
case cursorHoriz:
|
||||
cursorId = wxCURSOR_SIZEWE;
|
||||
break;
|
||||
case cursorVert:
|
||||
cursorId = wxCURSOR_SIZENS;
|
||||
break;
|
||||
case cursorReverseArrow:
|
||||
cursorId = wxCURSOR_POINT_RIGHT;
|
||||
break;
|
||||
default:
|
||||
cursorId = wxCURSOR_ARROW;
|
||||
break;
|
||||
}
|
||||
|
||||
id->SetCursor(wxCursor(cursorId));
|
||||
}
|
||||
|
||||
|
||||
void Window::SetTitle(const char *s) {
|
||||
id->SetTitle(s);
|
||||
}
|
||||
|
||||
|
||||
|
||||
ListBox::ListBox() {
|
||||
}
|
||||
|
||||
ListBox::~ListBox() {
|
||||
}
|
||||
|
||||
void ListBox::Create(Window &parent, int ctrlID) {
|
||||
id = new wxListBox(parent.id, ctrlID, wxDefaultPosition, wxDefaultSize,
|
||||
0, NULL, wxLB_SINGLE | wxLB_SORT);
|
||||
}
|
||||
|
||||
void ListBox::Clear() {
|
||||
((wxListBox*)id)->Clear();
|
||||
}
|
||||
|
||||
void ListBox::Append(char *s) {
|
||||
((wxListBox*)id)->Append(s);
|
||||
}
|
||||
|
||||
int ListBox::Length() {
|
||||
return ((wxListBox*)id)->Number();
|
||||
}
|
||||
|
||||
void ListBox::Select(int n) {
|
||||
((wxListBox*)id)->SetSelection(n);
|
||||
}
|
||||
|
||||
int ListBox::GetSelection() {
|
||||
return ((wxListBox*)id)->GetSelection();
|
||||
}
|
||||
|
||||
int ListBox::Find(const char *prefix) {
|
||||
return ((wxListBox*)id)->FindString(prefix);
|
||||
}
|
||||
|
||||
void ListBox::GetValue(int n, char *value, int len) {
|
||||
wxString text = ((wxListBox*)id)->GetString(n);
|
||||
strncpy(value, text.c_str(), len);
|
||||
value[len-1] = '\0';
|
||||
}
|
||||
|
||||
void ListBox::Sort() {
|
||||
// wxWindows keeps sorted so no need to sort
|
||||
}
|
||||
|
||||
|
||||
Menu::Menu() : id(0) {
|
||||
}
|
||||
|
||||
void Menu::CreatePopUp() {
|
||||
Destroy();
|
||||
id = new wxMenu();
|
||||
}
|
||||
|
||||
void Menu::Destroy() {
|
||||
if (id)
|
||||
delete id;
|
||||
id = 0;
|
||||
}
|
||||
|
||||
void Menu::Show(Point pt, Window &w) {
|
||||
w.GetID()->PopupMenu(id, pt.x - 4, pt.y);
|
||||
Destroy();
|
||||
}
|
||||
|
||||
|
||||
Colour Platform::Chrome() {
|
||||
wxColour c;
|
||||
c = wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DFACE);
|
||||
return Colour(c.Red(), c.Green(), c.Blue());
|
||||
}
|
||||
|
||||
Colour Platform::ChromeHighlight() {
|
||||
wxColour c;
|
||||
c = wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DHIGHLIGHT);
|
||||
return Colour(c.Red(), c.Green(), c.Blue());
|
||||
}
|
||||
|
||||
const char *Platform::DefaultFont() {
|
||||
return wxNORMAL_FONT->GetFaceName();
|
||||
}
|
||||
|
||||
int Platform::DefaultFontSize() {
|
||||
return 8;
|
||||
}
|
||||
|
||||
unsigned int Platform::DoubleClickTime() {
|
||||
return 500; // **** ::GetDoubleClickTime();
|
||||
}
|
||||
|
||||
void Platform::DebugDisplay(const char *s) {
|
||||
wxLogDebug(s);
|
||||
}
|
||||
|
||||
bool Platform::IsKeyDown(int key) {
|
||||
return false; // I don't think we'll need this.
|
||||
}
|
||||
|
||||
long Platform::SendScintilla(WindowID w,
|
||||
unsigned int msg,
|
||||
unsigned long wParam,
|
||||
long lParam) {
|
||||
|
||||
wxStyledTextCtrl* stc = (wxStyledTextCtrl*)w;
|
||||
return stc->SendMsg(msg, wParam, lParam);
|
||||
}
|
||||
|
||||
|
||||
// These are utility functions not really tied to a platform
|
||||
|
||||
int Platform::Minimum(int a, int b) {
|
||||
if (a < b)
|
||||
return a;
|
||||
else
|
||||
return b;
|
||||
}
|
||||
|
||||
int Platform::Maximum(int a, int b) {
|
||||
if (a > b)
|
||||
return a;
|
||||
else
|
||||
return b;
|
||||
}
|
||||
|
||||
#define TRACE
|
||||
|
||||
void Platform::DebugPrintf(const char *format, ...) {
|
||||
#ifdef TRACE
|
||||
char buffer[2000];
|
||||
va_list pArguments;
|
||||
va_start(pArguments, format);
|
||||
vsprintf(buffer,format,pArguments);
|
||||
va_end(pArguments);
|
||||
Platform::DebugDisplay(buffer);
|
||||
#endif
|
||||
}
|
||||
|
||||
int Platform::Clamp(int val, int minVal, int maxVal) {
|
||||
if (val > maxVal)
|
||||
val = maxVal;
|
||||
if (val < minVal)
|
||||
val = minVal;
|
||||
return val;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
47
contrib/src/stc/README.txt
Normal file
47
contrib/src/stc/README.txt
Normal file
@@ -0,0 +1,47 @@
|
||||
This contrib is the wxStyledTextCtrl, which is a wrapper around the
|
||||
Scintilla edit control. (See www.scintilla.org)
|
||||
|
||||
There is still VERY MUCH to be done, most notable of which is a more
|
||||
advanced sample that exercises more of the code. (I havn't tested
|
||||
AutoComplete or CallTips, or most of the event types at all yet.) And
|
||||
also documentation, adding wrappers for some new scintilla
|
||||
functionality, building and testing on wxGTK, etc. Be patient, it all
|
||||
will get there soon.
|
||||
|
||||
|
||||
|
||||
Let me describe a bit about the architecture I am implementing...
|
||||
Obviously there is the Platform layer which implements the varioius
|
||||
platform classes by using wxWindows classes and filling in where
|
||||
needed. Then there is a ScintillaWX class that is derived from
|
||||
ScintillaBase and implements the necessary virtual methods that
|
||||
Scintilla needs to fully funciton. This class however is not meant to
|
||||
ever be used directly by wx programmers. I call it one end of the
|
||||
bridge between the wx and Scintilla worlds. The other end of the
|
||||
bridge is a class called wxStyledTextCtrl that looks, feels and acts
|
||||
like other classes in wxWindows. Here is a diagram:
|
||||
|
||||
|
||||
+------------------+ +-------------------+
|
||||
| wxStyledTextCtrl |--bridge--| ScintillaWX |
|
||||
+------------------+ +-------------------+
|
||||
| ScintillaBase |
|
||||
+-------------------+
|
||||
| Editor |
|
||||
+-------------------+
|
||||
| PlatWX |
|
||||
+-------------------+
|
||||
|
||||
|
||||
wxStyledTextCtrl derives from wxControl so it has a window that can be
|
||||
drawn upon. When a wxStyledTextCtrl is constructed it constructs a
|
||||
ScintillaWX for itself and passes itself to the scintilla object to be
|
||||
set as the wMain and wDraw attributes. All method calls on the STC
|
||||
are sent over the bridge in the form of calls to ScintiallWX::WndProc.
|
||||
All notifications are sent back over the bridge and turned into
|
||||
wxEvents.
|
||||
|
||||
|
||||
Robin
|
||||
|
||||
|
457
contrib/src/stc/ScintillaWX.cpp
Normal file
457
contrib/src/stc/ScintillaWX.cpp
Normal file
@@ -0,0 +1,457 @@
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Name: ScintillaWX.cxx
|
||||
// Purpose: A wxWindows implementation of Scintilla. A class derived
|
||||
// from ScintillaBase that uses the "wx platform" defined in
|
||||
// PlatformWX.cxx This class is one end of a bridge between
|
||||
// the wx world and the Scintilla world. It needs a peer
|
||||
// object of type wxStyledTextCtrl to function.
|
||||
//
|
||||
// Author: Robin Dunn
|
||||
//
|
||||
// Created: 13-Jan-2000
|
||||
// RCS-ID: $Id$
|
||||
// Copyright: (c) 2000 by Total Control Software
|
||||
// Licence: wxWindows license
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "ScintillaWX.h"
|
||||
#include "wx/stc/stc.h"
|
||||
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
const int H_SCROLL_MAX = 2000;
|
||||
const int H_SCROLL_STEP = 20;
|
||||
const int H_SCROLL_PAGE = 200;
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// Helper classes
|
||||
|
||||
class wxSTCTimer : public wxTimer {
|
||||
public:
|
||||
wxSTCTimer(ScintillaWX* swx) {
|
||||
this->swx = swx;
|
||||
}
|
||||
|
||||
void Notify() {
|
||||
swx->DoTick();
|
||||
}
|
||||
|
||||
private:
|
||||
ScintillaWX* swx;
|
||||
};
|
||||
|
||||
|
||||
|
||||
bool wxSTCDropTarget::OnDropText(wxCoord x, wxCoord y, const wxString& data) {
|
||||
return swx->DoDropText(x, y, data);
|
||||
}
|
||||
|
||||
wxDragResult wxSTCDropTarget::OnEnter(wxCoord x, wxCoord y, wxDragResult def) {
|
||||
return swx->DoDragEnter(x, y, def);
|
||||
}
|
||||
|
||||
wxDragResult wxSTCDropTarget::OnDragOver(wxCoord x, wxCoord y, wxDragResult def) {
|
||||
return swx->DoDragOver(x, y, def);
|
||||
}
|
||||
|
||||
void wxSTCDropTarget::OnLeave() {
|
||||
swx->DoDragLeave();
|
||||
}
|
||||
|
||||
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// Constructor/Destructor
|
||||
|
||||
|
||||
ScintillaWX::ScintillaWX(wxStyledTextCtrl* win) {
|
||||
capturedMouse = false;
|
||||
wMain = win;
|
||||
wDraw = win;
|
||||
stc = win;
|
||||
Initialise();
|
||||
}
|
||||
|
||||
|
||||
ScintillaWX::~ScintillaWX() {
|
||||
SetTicking(false);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// base class virtuals
|
||||
|
||||
|
||||
void ScintillaWX::Initialise() {
|
||||
//ScintillaBase::Initialise();
|
||||
dropTarget.SetScintilla(this);
|
||||
stc->SetDropTarget(&dropTarget);
|
||||
}
|
||||
|
||||
|
||||
void ScintillaWX::Finalise() {
|
||||
ScintillaBase::Finalise();
|
||||
}
|
||||
|
||||
|
||||
void ScintillaWX::StartDrag() {
|
||||
wxDropSource source;
|
||||
wxTextDataObject data(dragChars);
|
||||
wxDragResult result;
|
||||
|
||||
source.SetData(data);
|
||||
result = source.DoDragDrop(TRUE);
|
||||
if (result == wxDragMove && dropWentOutside)
|
||||
ClearSelection();
|
||||
inDragDrop = FALSE;
|
||||
SetDragPosition(invalidPosition);
|
||||
}
|
||||
|
||||
|
||||
void ScintillaWX::SetTicking(bool on) {
|
||||
wxSTCTimer* steTimer;
|
||||
if (timer.ticking != on) {
|
||||
timer.ticking = on;
|
||||
if (timer.ticking) {
|
||||
steTimer = new wxSTCTimer(this);
|
||||
steTimer->Start(timer.tickSize);
|
||||
timer.tickerID = (int)steTimer;
|
||||
} else {
|
||||
steTimer = (wxSTCTimer*)timer.tickerID;
|
||||
steTimer->Stop();
|
||||
delete steTimer;
|
||||
timer.tickerID = 0;
|
||||
}
|
||||
}
|
||||
timer.ticksToWait = caret.period;
|
||||
}
|
||||
|
||||
|
||||
void ScintillaWX::SetMouseCapture(bool on) {
|
||||
if (on)
|
||||
wMain.GetID()->CaptureMouse();
|
||||
else
|
||||
wMain.GetID()->ReleaseMouse();
|
||||
capturedMouse = on;
|
||||
}
|
||||
|
||||
|
||||
bool ScintillaWX::HaveMouseCapture() {
|
||||
return capturedMouse;
|
||||
}
|
||||
|
||||
|
||||
void ScintillaWX::ScrollText(int linesToMove) {
|
||||
int dy = vs.lineHeight * (linesToMove);
|
||||
// TODO: calculate the rectangle to refreshed...
|
||||
wMain.GetID()->ScrollWindow(0, dy);
|
||||
}
|
||||
|
||||
void ScintillaWX::SetVerticalScrollPos() {
|
||||
wMain.GetID()->SetScrollPos(wxVERTICAL, topLine);
|
||||
}
|
||||
|
||||
void ScintillaWX::SetHorizontalScrollPos() {
|
||||
wMain.GetID()->SetScrollPos(wxHORIZONTAL, xOffset);
|
||||
}
|
||||
|
||||
|
||||
bool ScintillaWX::ModifyScrollBars(int nMax, int nPage) {
|
||||
bool modified = false;
|
||||
int sbMax = wMain.GetID()->GetScrollRange(wxVERTICAL);
|
||||
int sbThumb = wMain.GetID()->GetScrollThumb(wxVERTICAL);
|
||||
int sbPos = wMain.GetID()->GetScrollPos(wxVERTICAL);
|
||||
|
||||
|
||||
if (sbMax != nMax || sbThumb != nPage) {
|
||||
wMain.GetID()->SetScrollbar(wxVERTICAL, sbPos, nPage, nMax);
|
||||
modified = true;
|
||||
}
|
||||
|
||||
sbMax = wMain.GetID()->GetScrollRange(wxHORIZONTAL);
|
||||
sbThumb = wMain.GetID()->GetScrollThumb(wxHORIZONTAL);
|
||||
if ((sbMax != H_SCROLL_MAX) || (sbThumb != H_SCROLL_STEP)) {
|
||||
wMain.GetID()->SetScrollbar(wxHORIZONTAL, 0, H_SCROLL_STEP, H_SCROLL_MAX);
|
||||
modified = true;
|
||||
}
|
||||
return modified;
|
||||
}
|
||||
|
||||
|
||||
void ScintillaWX::NotifyChange() {
|
||||
stc->NotifyChange();
|
||||
}
|
||||
|
||||
|
||||
void ScintillaWX::NotifyParent(SCNotification scn) {
|
||||
stc->NotifyParent(&scn);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void ScintillaWX::Copy() {
|
||||
if (currentPos != anchor) {
|
||||
char* text = CopySelectionRange();
|
||||
textDO.SetText(text);
|
||||
wxTheClipboard->Open();
|
||||
wxTheClipboard->SetData(&textDO);
|
||||
wxTheClipboard->Close();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ScintillaWX::Paste() {
|
||||
pdoc->BeginUndoAction();
|
||||
ClearSelection();
|
||||
|
||||
wxTextDataObject data;
|
||||
bool canPaste;
|
||||
|
||||
wxTheClipboard->Open();
|
||||
canPaste = wxTheClipboard->GetData(data);
|
||||
wxTheClipboard->Close();
|
||||
if (canPaste) {
|
||||
wxString str = data.GetText();
|
||||
int len = str.Length();
|
||||
pdoc->InsertString(currentPos, str.c_str(), len);
|
||||
SetEmptySelection(currentPos + len);
|
||||
}
|
||||
|
||||
pdoc->EndUndoAction();
|
||||
NotifyChange();
|
||||
Redraw();
|
||||
}
|
||||
|
||||
|
||||
bool ScintillaWX::CanPaste() {
|
||||
wxTextDataObject data;
|
||||
bool canPaste;
|
||||
|
||||
wxTheClipboard->Open();
|
||||
canPaste = wxTheClipboard->GetData(data);
|
||||
wxTheClipboard->Close();
|
||||
|
||||
return canPaste;
|
||||
}
|
||||
|
||||
void ScintillaWX::CreateCallTipWindow(PRectangle) {
|
||||
ct.wCallTip = new wxWindow(wDraw.GetID(), -1);
|
||||
ct.wDraw = ct.wCallTip;
|
||||
}
|
||||
|
||||
|
||||
void ScintillaWX::AddToPopUp(const char *label, int cmd, bool enabled) {
|
||||
if (!label[0])
|
||||
popup.GetID()->AppendSeparator();
|
||||
else
|
||||
popup.GetID()->Append(cmd, label);
|
||||
|
||||
if (!enabled)
|
||||
popup.GetID()->Enable(cmd, enabled);
|
||||
|
||||
// TODO: need to create event handler mappings for the cmd ID
|
||||
}
|
||||
|
||||
|
||||
void ScintillaWX::ClaimSelection() {
|
||||
|
||||
}
|
||||
|
||||
|
||||
LRESULT ScintillaWX::DefWndProc(UINT /*iMessage*/, WPARAM /*wParam*/, LPARAM /*lParam*/) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
LRESULT ScintillaWX::WndProc(UINT iMessage, WPARAM wParam, LPARAM lParam) {
|
||||
switch (iMessage) {
|
||||
case EM_CANPASTE:
|
||||
return CanPaste();
|
||||
default:
|
||||
return ScintillaBase::WndProc(iMessage, wParam, lParam);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// Event delegates
|
||||
|
||||
void ScintillaWX::DoPaint(wxDC* dc, wxRect rect) {
|
||||
|
||||
paintState = painting;
|
||||
Surface surfaceWindow;
|
||||
surfaceWindow.Init(dc);
|
||||
PRectangle rcPaint = PRectangleFromwxRect(rect);
|
||||
dc->BeginDrawing();
|
||||
Paint(&surfaceWindow, rcPaint);
|
||||
dc->EndDrawing();
|
||||
surfaceWindow.Release();
|
||||
if (paintState == paintAbandoned) {
|
||||
// Painting area was insufficient to cover new styling or brace highlight positions
|
||||
FullPaint();
|
||||
}
|
||||
paintState = notPainting;
|
||||
}
|
||||
|
||||
|
||||
void ScintillaWX::DoHScroll(int type, int pos) {
|
||||
int xPos = xOffset;
|
||||
switch (type) {
|
||||
case wxEVT_SCROLLWIN_LINEUP:
|
||||
xPos -= H_SCROLL_STEP;
|
||||
break;
|
||||
case wxEVT_SCROLLWIN_LINEDOWN:
|
||||
xPos += H_SCROLL_STEP;
|
||||
break;
|
||||
case wxEVT_SCROLLWIN_PAGEUP:
|
||||
xPos -= H_SCROLL_PAGE;
|
||||
break;
|
||||
case wxEVT_SCROLLWIN_PAGEDOWN:
|
||||
xPos += H_SCROLL_PAGE;
|
||||
break;
|
||||
case wxEVT_SCROLLWIN_TOP:
|
||||
xPos = 0;
|
||||
break;
|
||||
case wxEVT_SCROLLWIN_BOTTOM:
|
||||
xPos = H_SCROLL_MAX;
|
||||
break;
|
||||
case wxEVT_SCROLLWIN_THUMBTRACK:
|
||||
xPos = pos;
|
||||
break;
|
||||
}
|
||||
HorizontalScrollTo(xPos);
|
||||
}
|
||||
|
||||
void ScintillaWX::DoVScroll(int type, int pos) {
|
||||
int topLineNew = topLine;
|
||||
switch (type) {
|
||||
case wxEVT_SCROLLWIN_LINEUP:
|
||||
topLineNew -= 1;
|
||||
break;
|
||||
case wxEVT_SCROLLWIN_LINEDOWN:
|
||||
topLineNew += 1;
|
||||
break;
|
||||
case wxEVT_SCROLLWIN_PAGEUP:
|
||||
topLineNew -= LinesToScroll();
|
||||
break;
|
||||
case wxEVT_SCROLLWIN_PAGEDOWN:
|
||||
topLineNew += LinesToScroll();
|
||||
break;
|
||||
case wxEVT_SCROLLWIN_TOP:
|
||||
topLineNew = 0;
|
||||
break;
|
||||
case wxEVT_SCROLLWIN_BOTTOM:
|
||||
topLineNew = MaxScrollPos();
|
||||
break;
|
||||
case wxEVT_SCROLLWIN_THUMBTRACK:
|
||||
topLineNew = pos;
|
||||
break;
|
||||
}
|
||||
ScrollTo(topLineNew);
|
||||
}
|
||||
|
||||
void ScintillaWX::DoSize(int width, int height) {
|
||||
PRectangle rcClient(0,0,width,height);
|
||||
SetScrollBarsTo(rcClient);
|
||||
DropGraphics();
|
||||
}
|
||||
|
||||
void ScintillaWX::DoLoseFocus(){
|
||||
DropCaret();
|
||||
}
|
||||
|
||||
void ScintillaWX::DoGainFocus(){
|
||||
ShowCaretAtCurrentPosition();
|
||||
}
|
||||
|
||||
void ScintillaWX::DoSysColourChange() {
|
||||
InvalidateStyleData();
|
||||
}
|
||||
|
||||
void ScintillaWX::DoButtonDown(Point pt, unsigned int curTime, bool shift, bool ctrl, bool alt) {
|
||||
ButtonDown(pt, curTime, shift, ctrl, alt);
|
||||
}
|
||||
|
||||
void ScintillaWX::DoButtonUp(Point pt, unsigned int curTime, bool ctrl) {
|
||||
ButtonUp(pt, curTime, ctrl);
|
||||
}
|
||||
|
||||
void ScintillaWX::DoButtonMove(Point pt) {
|
||||
ButtonMove(pt);
|
||||
}
|
||||
|
||||
|
||||
void ScintillaWX::DoAddChar(char ch) {
|
||||
AddChar(ch);
|
||||
}
|
||||
|
||||
int ScintillaWX::DoKeyDown(int key, bool shift, bool ctrl, bool alt) {
|
||||
return KeyDown(key, shift, ctrl, alt);
|
||||
}
|
||||
|
||||
|
||||
void ScintillaWX::DoCommand(int ID) {
|
||||
Command(ID);
|
||||
}
|
||||
|
||||
|
||||
void ScintillaWX::DoContextMenu(Point pt) {
|
||||
ContextMenu(pt);
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
bool ScintillaWX::DoDropText(long x, long y, const wxString& data) {
|
||||
SetDragPosition(invalidPosition);
|
||||
int movePos = PositionFromLocation(Point(x,y));
|
||||
DropAt(movePos, data, dragResult == wxDragMove, FALSE); // TODO: rectangular?
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
wxDragResult ScintillaWX::DoDragEnter(wxCoord x, wxCoord y, wxDragResult def) {
|
||||
return def;
|
||||
}
|
||||
|
||||
|
||||
wxDragResult ScintillaWX::DoDragOver(wxCoord x, wxCoord y, wxDragResult def) {
|
||||
SetDragPosition(PositionFromLocation(Point(x, y)));
|
||||
dragResult = def;
|
||||
return def;
|
||||
}
|
||||
|
||||
|
||||
void ScintillaWX::DoDragLeave() {
|
||||
SetDragPosition(invalidPosition);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
// Redraw all of text area. This paint will not be abandoned.
|
||||
void ScintillaWX::FullPaint() {
|
||||
paintState = painting;
|
||||
rcPaint = GetTextRectangle();
|
||||
wxClientDC dc(wMain.GetID());
|
||||
Surface surfaceWindow;
|
||||
surfaceWindow.Init(&dc);
|
||||
Paint(&surfaceWindow, rcPaint);
|
||||
surfaceWindow.Release();
|
||||
paintState = notPainting;
|
||||
}
|
||||
|
||||
|
||||
void ScintillaWX::DoScrollToLine(int line) {
|
||||
ScrollTo(line);
|
||||
}
|
||||
|
||||
|
||||
void ScintillaWX::DoScrollToColumn(int column) {
|
||||
HorizontalScrollTo(column * vs.spaceWidth);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------
|
148
contrib/src/stc/ScintillaWX.h
Normal file
148
contrib/src/stc/ScintillaWX.h
Normal file
@@ -0,0 +1,148 @@
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Name: ScintillaWX.h
|
||||
// Purpose: A wxWindows implementation of Scintilla. A class derived
|
||||
// from ScintillaBase that uses the "wx platform" defined in
|
||||
// PlatWX.cpp. This class is one end of a bridge between
|
||||
// the wx world and the Scintilla world. It needs a peer
|
||||
// object of type wxStyledTextCtrl to function.
|
||||
//
|
||||
// Author: Robin Dunn
|
||||
//
|
||||
// Created: 13-Jan-2000
|
||||
// RCS-ID: $Id$
|
||||
// Copyright: (c) 2000 by Total Control Software
|
||||
// Licence: wxWindows license
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef __ScintillaWX_h__
|
||||
#define __ScintillaWX_h__
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
#include "Platform.h"
|
||||
|
||||
#include "Scintilla.h"
|
||||
#ifdef SCI_LEXER
|
||||
#include "SciLexer.h"
|
||||
#include "PropSet.h"
|
||||
#include "Accessor.h"
|
||||
#include "KeyWords.h"
|
||||
#endif
|
||||
#include "ContractionState.h"
|
||||
#include "SVector.h"
|
||||
#include "CellBuffer.h"
|
||||
#include "CallTip.h"
|
||||
#include "KeyMap.h"
|
||||
#include "Indicator.h"
|
||||
#include "LineMarker.h"
|
||||
#include "Style.h"
|
||||
#include "ViewStyle.h"
|
||||
#include "AutoComplete.h"
|
||||
#include "Document.h"
|
||||
#include "Editor.h"
|
||||
#include "ScintillaBase.h"
|
||||
|
||||
#include <wx/wx.h>
|
||||
#include <wx/dataobj.h>
|
||||
#include <wx/clipbrd.h>
|
||||
#include <wx/dnd.h>
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
class wxStyledTextCtrl; // forward
|
||||
class ScintillaWX;
|
||||
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// Helper classes
|
||||
|
||||
class wxSTCDropTarget : public wxTextDropTarget {
|
||||
public:
|
||||
void SetScintilla(ScintillaWX* swx) {
|
||||
this->swx = swx;
|
||||
}
|
||||
|
||||
bool OnDropText(wxCoord x, wxCoord y, const wxString& data);
|
||||
wxDragResult OnEnter(wxCoord x, wxCoord y, wxDragResult def);
|
||||
wxDragResult OnDragOver(wxCoord x, wxCoord y, wxDragResult def);
|
||||
void OnLeave();
|
||||
|
||||
private:
|
||||
ScintillaWX* swx;
|
||||
};
|
||||
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
class ScintillaWX : public ScintillaBase {
|
||||
public:
|
||||
|
||||
ScintillaWX(wxStyledTextCtrl* win);
|
||||
~ScintillaWX();
|
||||
|
||||
// base class virtuals
|
||||
virtual void Initialise();
|
||||
virtual void Finalise();
|
||||
virtual void StartDrag();
|
||||
virtual void SetTicking(bool on);
|
||||
virtual void SetMouseCapture(bool on);
|
||||
virtual bool HaveMouseCapture();
|
||||
virtual void ScrollText(int linesToMove);
|
||||
virtual void SetVerticalScrollPos();
|
||||
virtual void SetHorizontalScrollPos();
|
||||
virtual bool ModifyScrollBars(int nMax, int nPage);
|
||||
virtual void Copy();
|
||||
virtual void Paste();
|
||||
virtual void CreateCallTipWindow(PRectangle rc);
|
||||
virtual void AddToPopUp(const char *label, int cmd = 0, bool enabled = true);
|
||||
virtual void ClaimSelection();
|
||||
|
||||
virtual LRESULT DefWndProc(UINT iMessage, WPARAM wParam, LPARAM lParam);
|
||||
virtual LRESULT WndProc(UINT iMessage, WPARAM wParam, LPARAM lParam);
|
||||
|
||||
virtual void NotifyChange();
|
||||
virtual void NotifyParent(SCNotification scn);
|
||||
|
||||
|
||||
// Event delegates
|
||||
void DoPaint(wxDC* dc, wxRect rect);
|
||||
void DoHScroll(int type, int pos);
|
||||
void DoVScroll(int type, int pos);
|
||||
void DoSize(int width, int height);
|
||||
void DoLoseFocus();
|
||||
void DoGainFocus();
|
||||
void DoSysColourChange();
|
||||
void DoButtonDown(Point pt, unsigned int curTime, bool shift, bool ctrl, bool alt);
|
||||
void DoButtonUp(Point pt, unsigned int curTime, bool ctrl);
|
||||
void DoButtonMove(Point pt);
|
||||
void DoAddChar(char ch);
|
||||
int DoKeyDown(int key, bool shift, bool ctrl, bool alt);
|
||||
void DoTick() { Tick(); }
|
||||
|
||||
bool DoDropText(long x, long y, const wxString& data);
|
||||
wxDragResult DoDragEnter(wxCoord x, wxCoord y, wxDragResult def);
|
||||
wxDragResult DoDragOver(wxCoord x, wxCoord y, wxDragResult def);
|
||||
void DoDragLeave();
|
||||
|
||||
void DoCommand(int ID);
|
||||
void DoContextMenu(Point pt);
|
||||
|
||||
|
||||
// helpers
|
||||
void FullPaint();
|
||||
bool CanPaste();
|
||||
bool GetHideSelection() { return hideSelection; }
|
||||
void DoScrollToLine(int line);
|
||||
void DoScrollToColumn(int column);
|
||||
|
||||
private:
|
||||
bool capturedMouse;
|
||||
wxStyledTextCtrl* stc;
|
||||
|
||||
wxTextDataObject textDO;
|
||||
wxSTCDropTarget dropTarget;
|
||||
wxDragResult dragResult;
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
#endif
|
106
contrib/src/stc/makefile.vc
Normal file
106
contrib/src/stc/makefile.vc
Normal file
@@ -0,0 +1,106 @@
|
||||
# File: makefile.vc For stectrl
|
||||
# Author: Robin Dunn
|
||||
# Created: 1-Feb-2000
|
||||
# Updated:
|
||||
|
||||
|
||||
|
||||
# Set WXDIR for your system
|
||||
WXDIR = $(WXWIN)
|
||||
SCINTILLA=.\scintilla
|
||||
S=$(SCINTILLA)\src
|
||||
EXTRAINC=-D__WX__ -DSCI_LEXER -I$(SCINTILLA)/include -I$(S) -I. -I$(WXDIR)\contrib\include
|
||||
NOPCH=1
|
||||
|
||||
!include $(WXDIR)\src\makevc.env
|
||||
|
||||
OBJECTS = \
|
||||
$(D)\Accessor.obj \
|
||||
$(D)\AutoComplete.obj \
|
||||
$(D)\CallTip.obj \
|
||||
$(D)\CellBuffer.obj \
|
||||
$(D)\ContractionState.obj\
|
||||
$(D)\Document.obj \
|
||||
$(D)\Editor.obj \
|
||||
$(D)\Indicator.obj \
|
||||
$(D)\KeyMap.obj \
|
||||
$(D)\KeyWords.obj \
|
||||
$(D)\LineMarker.obj \
|
||||
$(D)\PropSet.obj \
|
||||
$(D)\ScintillaBase.obj \
|
||||
$(D)\Style.obj \
|
||||
$(D)\ViewStyle.obj \
|
||||
\
|
||||
$(D)\PlatWX.obj \
|
||||
$(D)\ScintillaWX.obj \
|
||||
$(D)\stc.obj \
|
||||
|
||||
|
||||
|
||||
|
||||
LIBTARGET = $(WXDIR)\contrib\lib\stc$(LIBEXT).lib
|
||||
|
||||
all: $(D) $(LIBTARGET)
|
||||
|
||||
$(D) :
|
||||
mkdir $(D)
|
||||
|
||||
wx:
|
||||
cd $(WXDIR)\src\msw
|
||||
nmake -f makefile.vc FINAL=$(FINAL)
|
||||
cd $(THISDIR)
|
||||
|
||||
wxclean:
|
||||
cd $(WXDIR)\src\msw
|
||||
nmake -f makefile.vc clean
|
||||
cd $(THISDIR)
|
||||
|
||||
|
||||
|
||||
|
||||
$(LIBTARGET): $(OBJECTS)
|
||||
-erase $(LIBTARGET)
|
||||
$(implib) @<<
|
||||
-out:$(LIBTARGET)
|
||||
-machine:$(CPU)
|
||||
$(OBJECTS)
|
||||
<<
|
||||
|
||||
|
||||
$(PROGRAM).exe: $(D)\$(PROGRAM).obj $(DUMMYOBJ) $(WXLIB) $(LIBTARGET) $(PROGRAM).res
|
||||
$(link) @<<
|
||||
-out:$(PROGRAM).exe
|
||||
$(LINKFLAGS)
|
||||
$(DUMMYOBJ) $(D)\$(PROGRAM).obj $(LIBTARGET) $(PROGRAM).res
|
||||
$(LIBS)
|
||||
<<
|
||||
|
||||
$(PROGRAM).res : $(PROGRAM).rc $(WXDIR)\include\wx\msw\wx.rc
|
||||
$(rc) -r /i$(WXDIR)\include -fo$@ $(PROGRAM).rc
|
||||
|
||||
|
||||
|
||||
{$(S)}.cxx{$(D)}.obj:
|
||||
$(cc) @<<
|
||||
$(CPPFLAGS) /c /Fo$@ /Tp $<
|
||||
<<
|
||||
|
||||
{}.cpp{$(D)}.obj:
|
||||
$(cc) @<<
|
||||
$(CPPFLAGS) /c /Fo$@ /Tp $<
|
||||
<<
|
||||
|
||||
|
||||
show:
|
||||
@echo $(CPPFLAGS)
|
||||
|
||||
|
||||
clean:
|
||||
-erase $(D)\*.obj
|
||||
-erase *.sbr
|
||||
-erase *.exe
|
||||
-erase *.res
|
||||
-erase *.map
|
||||
-erase *.pdb
|
||||
-erase $(LIBTARGET)
|
||||
|
7
contrib/src/stc/scintilla/README.txt
Normal file
7
contrib/src/stc/scintilla/README.txt
Normal file
@@ -0,0 +1,7 @@
|
||||
This directory contains copies of the scintilla/src and
|
||||
scintilla/include directories from the Scintilla/SCiTE source
|
||||
distribution. All other code needed to implement Scintilla on top of
|
||||
wxWindows is located in the directory above this one.
|
||||
|
||||
The current version of the Scintilla code is somewhere between 1.22
|
||||
and 1.23, (from their CVS.)
|
76
contrib/src/stc/scintilla/include/Accessor.h
Normal file
76
contrib/src/stc/scintilla/include/Accessor.h
Normal file
@@ -0,0 +1,76 @@
|
||||
// SciTE - Scintilla based Text Editor
|
||||
// Accessor.h - rapid easy access to contents of a Scintilla
|
||||
// Copyright 1998-2000 by Neil Hodgson <neilh@scintilla.org>
|
||||
// The License.txt file describes the conditions under which this software may be distributed.
|
||||
|
||||
class Accessor {
|
||||
protected:
|
||||
// bufferSize is a trade off between time taken to copy the characters and SendMessage overhead
|
||||
// slopSize positions the buffer before the desired position in case there is some backtracking
|
||||
enum {bufferSize=4000, slopSize=bufferSize/8};
|
||||
char buf[bufferSize+1];
|
||||
WindowID id;
|
||||
PropSet &props;
|
||||
int startPos;
|
||||
int endPos;
|
||||
int lenDoc;
|
||||
int offset; // Optional but including an offset makes GCC generate better code
|
||||
void Fill(int position);
|
||||
public:
|
||||
Accessor(WindowID id_, PropSet &props_, int offset_=0) :
|
||||
id(id_), props(props_), startPos(0x7FFFFFFF), endPos(0),
|
||||
lenDoc(-1), offset(offset_) {
|
||||
}
|
||||
char operator[](int position) {
|
||||
position += offset;
|
||||
if (position < startPos || position >= endPos) {
|
||||
Fill(position);
|
||||
}
|
||||
return buf[position - startPos];
|
||||
}
|
||||
char SafeGetCharAt(int position, char chDefault=' ') {
|
||||
// Safe version of operator[], returning a defined value for invalid position
|
||||
position += offset;
|
||||
if (position < startPos || position >= endPos) {
|
||||
Fill(position);
|
||||
if (position < startPos || position >= endPos) {
|
||||
// Position is outside range of document
|
||||
return chDefault;
|
||||
}
|
||||
}
|
||||
return buf[position - startPos];
|
||||
}
|
||||
char StyleAt(int position);
|
||||
int GetLine(int position);
|
||||
int LineStart(int line);
|
||||
int LevelAt(int line);
|
||||
int Length();
|
||||
void Flush() {
|
||||
startPos = 0x7FFFFFFF;
|
||||
lenDoc = -1;
|
||||
}
|
||||
int GetLineState(int line);
|
||||
int SetLineState(int line, int state);
|
||||
PropSet &GetPropSet() { return props; }
|
||||
};
|
||||
|
||||
class StylingContext : public Accessor {
|
||||
char styleBuf[bufferSize];
|
||||
int validLen;
|
||||
char chFlags;
|
||||
char chWhile;
|
||||
unsigned int startSeg;
|
||||
public:
|
||||
StylingContext(WindowID id_, PropSet &props_, int offset_=0) :
|
||||
Accessor(id_,props_,offset_), validLen(0), chFlags(0) {}
|
||||
void StartAt(unsigned int start, char chMask=31);
|
||||
void SetFlags(char chFlags_, char chWhile_) {chFlags = chFlags_; chWhile = chWhile_; };
|
||||
void ColourSegment(unsigned int start, unsigned int end, int chAttr);
|
||||
unsigned int GetStartSegment() { return startSeg; }
|
||||
void StartSegment(unsigned int pos);
|
||||
void ColourTo(unsigned int pos, int chAttr);
|
||||
int GetLine(int position);
|
||||
void SetLevel(int line, int level);
|
||||
void Flush();
|
||||
};
|
||||
|
8
contrib/src/stc/scintilla/include/KeyWords.h
Normal file
8
contrib/src/stc/scintilla/include/KeyWords.h
Normal file
@@ -0,0 +1,8 @@
|
||||
// SciTE - Scintilla based Text Editor
|
||||
// KeyWords.h - colourise for particular languages
|
||||
// Copyright 1998-2000 by Neil Hodgson <neilh@scintilla.org>
|
||||
// The License.txt file describes the conditions under which this software may be distributed.
|
||||
|
||||
void ColouriseDoc(int codePage, int startPos, int lengthDoc, int initStyle,
|
||||
int language, WordList *keywordlists[], StylingContext &styler);
|
||||
|
392
contrib/src/stc/scintilla/include/Platform.h
Normal file
392
contrib/src/stc/scintilla/include/Platform.h
Normal file
@@ -0,0 +1,392 @@
|
||||
// Scintilla source code edit control
|
||||
// Platform.h - interface to platform facilities
|
||||
// Also includes some basic utilities
|
||||
// Implemented in PlatGTK.cxx for GTK+/Linux, PlatWin.cxx for Windows, and PlatWX.cxx for wxWindows
|
||||
// Copyright 1998-2000 by Neil Hodgson <neilh@scintilla.org>
|
||||
// The License.txt file describes the conditions under which this software may be distributed.
|
||||
|
||||
#ifndef PLATFORM_H
|
||||
#define PLATFORM_H
|
||||
|
||||
// PLAT_GTK = GTK+ on Linux, PLAT_WIN = Win32 API on Win32 OS
|
||||
// PLAT_WX is wxWindows on any supported platform
|
||||
// Could also have PLAT_GTKWIN = GTK+ on Win32 OS in future
|
||||
|
||||
#define PLAT_GTK 0
|
||||
#define PLAT_WIN 0
|
||||
#define PLAT_WX 0
|
||||
|
||||
#if defined(__WX__)
|
||||
#undef PLAT_WX
|
||||
#define PLAT_WX 1
|
||||
|
||||
#elif defined(GTK)
|
||||
#undef PLAT_GTK
|
||||
#define PLAT_GTK 1
|
||||
|
||||
#else
|
||||
#undef PLAT_WIN
|
||||
#define PLAT_WIN 1
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
// Include the main header for each platform
|
||||
|
||||
#if PLAT_GTK
|
||||
#include <gtk/gtk.h>
|
||||
#include <gdk/gdkkeysyms.h>
|
||||
#endif
|
||||
|
||||
#if PLAT_WIN
|
||||
#define _WIN32_WINNT 0x0400 // Otherwise some required stuff gets ifdef'd out
|
||||
// Vassili Bourdo: shut up annoying Visual C++ warnings:
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(disable: 4800 4244 4309)
|
||||
#endif
|
||||
#include <windows.h>
|
||||
#include <richedit.h>
|
||||
#endif
|
||||
|
||||
#if PLAT_WX
|
||||
#include <wx/wx.h>
|
||||
#endif
|
||||
|
||||
// Underlying the implementation of the platform classes are platform specific types.
|
||||
// Sometimes these need to be passed around by client code so they are defined here
|
||||
|
||||
#if PLAT_GTK
|
||||
typedef GdkColor ColourID;
|
||||
typedef GdkFont* FontID;
|
||||
typedef GdkDrawable* SurfaceID;
|
||||
typedef GtkWidget* WindowID;
|
||||
typedef GtkItemFactory* MenuID;
|
||||
#endif
|
||||
|
||||
#if PLAT_WIN
|
||||
typedef COLORREF ColourID;
|
||||
typedef HFONT FontID;
|
||||
typedef HDC SurfaceID;
|
||||
typedef HWND WindowID;
|
||||
typedef HMENU MenuID;
|
||||
#endif
|
||||
|
||||
#if PLAT_WX
|
||||
typedef wxColour ColourID;
|
||||
typedef wxFont* FontID;
|
||||
typedef wxDC* SurfaceID;
|
||||
typedef wxWindow* WindowID;
|
||||
typedef wxMenu* MenuID;
|
||||
#endif
|
||||
|
||||
#if PLAT_GTK || PLAT_WX
|
||||
#define SHIFT_PRESSED 1
|
||||
#define LEFT_CTRL_PRESSED 2
|
||||
#define LEFT_ALT_PRESSED 4
|
||||
#endif
|
||||
|
||||
// Point is exactly the same as the Win32 POINT and GTK+ GdkPoint so can be used interchangeably
|
||||
|
||||
class Point {
|
||||
public:
|
||||
int x;
|
||||
int y;
|
||||
|
||||
Point(int x_=0, int y_=0) : x(x_), y(y_) {
|
||||
}
|
||||
|
||||
// Other automatically defined methods (assignment, copy constructor, destructor) are fine
|
||||
|
||||
static Point FromLong(long lpoint);
|
||||
};
|
||||
|
||||
// PRectangle is exactly the same as the Win32 RECT so can be used interchangeably
|
||||
// PRectangles contain their top and left sides, but not their right and bottom sides
|
||||
class PRectangle {
|
||||
public:
|
||||
int left;
|
||||
int top;
|
||||
int right;
|
||||
int bottom;
|
||||
|
||||
PRectangle(int left_=0, int top_=0, int right_=0, int bottom_ = 0) :
|
||||
left(left_), top(top_), right(right_), bottom(bottom_) {
|
||||
}
|
||||
|
||||
// Other automatically defined methods (assignment, copy constructor, destructor) are fine
|
||||
|
||||
bool Contains(Point pt) {
|
||||
return (pt.x >= left) && (pt.x <= right) &&
|
||||
(pt.y >= top) && (pt.y <= bottom);
|
||||
}
|
||||
bool Contains(PRectangle rc) {
|
||||
return (rc.left >= left) && (rc.right <= right) &&
|
||||
(rc.top >= top) && (rc.bottom <= bottom);
|
||||
}
|
||||
bool Intersects(PRectangle other) {
|
||||
return (right >= other.left) && (left <= other.right) &&
|
||||
(bottom >= other.top) && (top <= other.bottom);
|
||||
}
|
||||
int Width() { return right - left; }
|
||||
int Height() { return bottom - top; }
|
||||
};
|
||||
|
||||
#if PLAT_WX
|
||||
wxRect wxRectFromPRectangle(PRectangle prc);
|
||||
PRectangle PRectangleFromwxRect(wxRect rc);
|
||||
#endif
|
||||
|
||||
class Colour {
|
||||
ColourID co;
|
||||
public:
|
||||
Colour(long lcol=0);
|
||||
Colour(unsigned int red, unsigned int green, unsigned int blue);
|
||||
bool operator==(const Colour &other) const;
|
||||
long AsLong() const;
|
||||
unsigned int GetRed();
|
||||
unsigned int GetGreen();
|
||||
unsigned int GetBlue();
|
||||
|
||||
friend class Surface;
|
||||
friend class Palette;
|
||||
};
|
||||
|
||||
// Colour pairs hold a desired colour and the colour that the graphics engine
|
||||
// allocates to approximate the desired colour.
|
||||
// To make palette management more automatic, ColourPairs could register at
|
||||
// construction time with a palette management object.
|
||||
struct ColourPair {
|
||||
Colour desired;
|
||||
Colour allocated;
|
||||
|
||||
ColourPair(Colour desired_=Colour(0,0,0)) {
|
||||
desired = desired_;
|
||||
allocated = desired;
|
||||
}
|
||||
};
|
||||
|
||||
class Window; // Forward declaration for Palette
|
||||
|
||||
class Palette {
|
||||
int used;
|
||||
enum {numEntries = 100};
|
||||
ColourPair entries[numEntries];
|
||||
#if PLAT_GTK
|
||||
GdkColor *allocatedPalette;
|
||||
int allocatedLen;
|
||||
#elif PLAT_WIN
|
||||
HPALETTE hpal;
|
||||
#elif PLAT_WX
|
||||
// wxPalette* pal; // **** Is this needed?
|
||||
#endif
|
||||
public:
|
||||
bool allowRealization;
|
||||
|
||||
Palette();
|
||||
~Palette();
|
||||
|
||||
void Release();
|
||||
|
||||
// This method either adds a colour to the list of wanted colours (want==true)
|
||||
// or retrieves the allocated colour back to the ColourPair.
|
||||
// This is one method to make it easier to keep the code for wanting and retrieving in sync.
|
||||
void WantFind(ColourPair &cp, bool want);
|
||||
|
||||
void Allocate(Window &w);
|
||||
|
||||
friend class Surface;
|
||||
};
|
||||
|
||||
class Font {
|
||||
FontID id;
|
||||
#if PLAT_WX
|
||||
int ascent;
|
||||
#endif
|
||||
// Private so Font objects can not be copied
|
||||
Font(const Font &) {}
|
||||
Font &operator=(const Font &) { id=0; return *this; }
|
||||
public:
|
||||
Font();
|
||||
~Font();
|
||||
|
||||
void Create(const char *faceName, int size, bool bold=false, bool italic=false);
|
||||
void Release();
|
||||
|
||||
FontID GetID() { return id; }
|
||||
friend class Surface;
|
||||
};
|
||||
|
||||
// A surface abstracts a place to draw
|
||||
class Surface {
|
||||
private:
|
||||
#if PLAT_GTK
|
||||
GdkDrawable *drawable;
|
||||
GdkGC *gc;
|
||||
GdkPixmap *ppixmap;
|
||||
int x;
|
||||
int y;
|
||||
bool inited;
|
||||
bool createdGC;
|
||||
#elif PLAT_WIN
|
||||
HDC hdc;
|
||||
bool hdcOwned;
|
||||
HPEN pen;
|
||||
HPEN penOld;
|
||||
HBRUSH brush;
|
||||
HBRUSH brushOld;
|
||||
HFONT font;
|
||||
HFONT fontOld;
|
||||
HBITMAP bitmap;
|
||||
HBITMAP bitmapOld;
|
||||
HPALETTE paletteOld;
|
||||
#elif PLAT_WX
|
||||
wxDC* hdc;
|
||||
bool hdcOwned;
|
||||
wxBitmap* bitmap;
|
||||
int x;
|
||||
int y;
|
||||
#endif
|
||||
|
||||
// Private so Surface objects can not be copied
|
||||
Surface(const Surface &) {}
|
||||
Surface &operator=(const Surface &) { return *this; }
|
||||
#if PLAT_WIN || PLAT_WX
|
||||
void BrushColor(Colour back);
|
||||
void SetFont(Font &font_);
|
||||
#endif
|
||||
public:
|
||||
Surface();
|
||||
~Surface();
|
||||
|
||||
void Init();
|
||||
void Init(SurfaceID hdc_);
|
||||
void InitPixMap(int width, int height, Surface *surface_);
|
||||
|
||||
void Release();
|
||||
bool Initialised();
|
||||
void PenColour(Colour fore);
|
||||
int LogPixelsY();
|
||||
void MoveTo(int x_, int y_);
|
||||
void LineTo(int x_, int y_);
|
||||
void Polygon(Point *pts, int npts, Colour fore, Colour back);
|
||||
void RectangleDraw(PRectangle rc, Colour fore, Colour back);
|
||||
void FillRectangle(PRectangle rc, Colour back);
|
||||
void FillRectangle(PRectangle rc, Surface &surfacePattern);
|
||||
void RoundedRectangle(PRectangle rc, Colour fore, Colour back);
|
||||
void Ellipse(PRectangle rc, Colour fore, Colour back);
|
||||
void Copy(PRectangle rc, Point from, Surface &surfaceSource);
|
||||
|
||||
void DrawText(PRectangle rc, Font &font_, int ybase, const char *s, int len, Colour fore, Colour back);
|
||||
void DrawTextClipped(PRectangle rc, Font &font_, int ybase, const char *s, int len, Colour fore, Colour back);
|
||||
void MeasureWidths(Font &font_, const char *s, int len, int *positions);
|
||||
int WidthText(Font &font_, const char *s, int len);
|
||||
int WidthChar(Font &font_, char ch);
|
||||
int Ascent(Font &font_);
|
||||
int Descent(Font &font_);
|
||||
int InternalLeading(Font &font_);
|
||||
int ExternalLeading(Font &font_);
|
||||
int Height(Font &font_);
|
||||
int AverageCharWidth(Font &font_);
|
||||
|
||||
int SetPalette(Palette *pal, bool inBackGround);
|
||||
void SetClip(PRectangle rc);
|
||||
};
|
||||
|
||||
// Class to hide the details of window manipulation
|
||||
// Does not own the window which will normally have a longer life than this object
|
||||
class Window {
|
||||
friend class ListBox;
|
||||
protected:
|
||||
WindowID id;
|
||||
public:
|
||||
Window() : id(0) {}
|
||||
virtual ~Window();
|
||||
Window &operator=(WindowID id_) {
|
||||
id = id_;
|
||||
return *this;
|
||||
}
|
||||
WindowID GetID() { return id; }
|
||||
bool Created() { return id != 0; }
|
||||
void Destroy();
|
||||
bool HasFocus();
|
||||
PRectangle GetPosition();
|
||||
void SetPosition(PRectangle rc);
|
||||
void SetPositionRelative(PRectangle rc, Window relativeTo);
|
||||
PRectangle GetClientPosition();
|
||||
void Show(bool show=true);
|
||||
void InvalidateAll();
|
||||
void InvalidateRectangle(PRectangle rc);
|
||||
void SetFont(Font &font);
|
||||
enum Cursor { cursorText, cursorArrow, cursorUp, cursorWait, cursorHoriz, cursorVert, cursorReverseArrow };
|
||||
void SetCursor(Cursor curs);
|
||||
void SetTitle(const char *s);
|
||||
#if PLAT_WIN
|
||||
LRESULT SendMessage(UINT msg, WPARAM wParam=0, LPARAM lParam=0);
|
||||
int GetDlgCtrlID();
|
||||
HINSTANCE GetInstance();
|
||||
#endif
|
||||
};
|
||||
|
||||
class ListBox : public Window {
|
||||
#if PLAT_GTK
|
||||
WindowID list;
|
||||
WindowID scroller;
|
||||
int current;
|
||||
#endif
|
||||
public:
|
||||
ListBox();
|
||||
virtual ~ListBox();
|
||||
ListBox &operator=(WindowID id_) {
|
||||
id = id_;
|
||||
return *this;
|
||||
}
|
||||
void Create(Window &parent, int ctrlID);
|
||||
void Clear();
|
||||
void Append(char *s);
|
||||
int Length();
|
||||
void Select(int n);
|
||||
int GetSelection();
|
||||
int Find(const char *prefix);
|
||||
void GetValue(int n, char *value, int len);
|
||||
void Sort();
|
||||
};
|
||||
|
||||
class Menu {
|
||||
MenuID id;
|
||||
public:
|
||||
Menu();
|
||||
MenuID GetID() { return id; }
|
||||
void CreatePopUp();
|
||||
void Destroy();
|
||||
void Show(Point pt, Window &w);
|
||||
};
|
||||
|
||||
// Platform class used to retrieve system wide parameters such as double click speed
|
||||
// and chrome colour. Not a creatable object, more of a module with several functions.
|
||||
class Platform {
|
||||
// Private so Platform objects can not be copied
|
||||
Platform(const Platform &) {}
|
||||
Platform &operator=(const Platform &) { return *this; }
|
||||
public:
|
||||
// Should be private because no new Platforms are ever created
|
||||
// but gcc warns about this
|
||||
Platform() {}
|
||||
~Platform() {}
|
||||
static Colour Chrome();
|
||||
static Colour ChromeHighlight();
|
||||
static const char *DefaultFont();
|
||||
static int DefaultFontSize();
|
||||
static unsigned int DoubleClickTime();
|
||||
static void DebugDisplay(const char *s);
|
||||
static bool IsKeyDown(int key);
|
||||
static long SendScintilla(
|
||||
WindowID w, unsigned int msg, unsigned long wParam=0, long lParam=0);
|
||||
|
||||
// These are utility functions not really tied to a platform
|
||||
static int Minimum(int a, int b);
|
||||
static int Maximum(int a, int b);
|
||||
static void DebugPrintf(const char *format, ...);
|
||||
static int Clamp(int val, int minVal, int maxVal);
|
||||
};
|
||||
|
||||
#endif
|
180
contrib/src/stc/scintilla/include/PropSet.h
Normal file
180
contrib/src/stc/scintilla/include/PropSet.h
Normal file
@@ -0,0 +1,180 @@
|
||||
// SciTE - Scintilla based Text Editor
|
||||
// PropSet.h - a java style properties file module
|
||||
// Copyright 1998-2000 by Neil Hodgson <neilh@scintilla.org>
|
||||
// The License.txt file describes the conditions under which this software may be distributed.
|
||||
|
||||
#ifndef PROPSET_H
|
||||
#define PROPSET_H
|
||||
|
||||
bool EqualCaseInsensitive(const char *a, const char *b);
|
||||
|
||||
// Define another string class.
|
||||
// While it would be 'better' to use std::string, that doubles the executable size.
|
||||
|
||||
inline char *StringDup(const char *s) {
|
||||
if (!s)
|
||||
return 0;
|
||||
char *sNew = new char[strlen(s) + 1];
|
||||
if (sNew)
|
||||
strcpy(sNew, s);
|
||||
return sNew;
|
||||
}
|
||||
|
||||
class SString {
|
||||
char *s;
|
||||
public:
|
||||
SString() {
|
||||
s = 0;
|
||||
}
|
||||
SString(const SString &source) {
|
||||
s = StringDup(source.s);
|
||||
}
|
||||
SString(const char *s_) {
|
||||
s = StringDup(s_);
|
||||
}
|
||||
SString(int i) {
|
||||
char number[100];
|
||||
sprintf(number, "%0d", i);
|
||||
//itoa(i, number, 10);
|
||||
s = StringDup(number);
|
||||
}
|
||||
~SString() {
|
||||
delete []s;
|
||||
s = 0;
|
||||
}
|
||||
SString &operator=(const SString &source) {
|
||||
if (this != &source) {
|
||||
delete []s;
|
||||
s = StringDup(source.s);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
bool operator==(const SString &other) const {
|
||||
if ((s == 0) && (other.s == 0))
|
||||
return true;
|
||||
if ((s == 0) || (other.s == 0))
|
||||
return false;
|
||||
return strcmp(s, other.s) == 0;
|
||||
}
|
||||
bool operator==(const char *sother) const {
|
||||
if ((s == 0) && (sother == 0))
|
||||
return true;
|
||||
if ((s == 0) || (sother == 0))
|
||||
return false;
|
||||
return strcmp(s, sother) == 0;
|
||||
}
|
||||
const char *c_str() const {
|
||||
if (s)
|
||||
return s;
|
||||
else
|
||||
return "";
|
||||
}
|
||||
int length() const {
|
||||
if (s)
|
||||
return strlen(s);
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
char operator[](int i) {
|
||||
if (s)
|
||||
return s[i];
|
||||
else
|
||||
return '\0';
|
||||
}
|
||||
SString &operator +=(const char *sother) {
|
||||
int len = length();
|
||||
int lenOther = strlen(sother);
|
||||
char *sNew = new char[len + lenOther + 1];
|
||||
if (sNew) {
|
||||
if (s)
|
||||
memcpy(sNew, s, len);
|
||||
memcpy(sNew + len, sother, lenOther);
|
||||
sNew[len + lenOther] = '\0';
|
||||
delete []s;
|
||||
s = sNew;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
int value() {
|
||||
if (s)
|
||||
return atoi(s);
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
class PropSet {
|
||||
private:
|
||||
char **vals;
|
||||
int size;
|
||||
int used;
|
||||
public:
|
||||
PropSet *superPS;
|
||||
PropSet();
|
||||
~PropSet();
|
||||
void EnsureCanAddEntry();
|
||||
void Set(const char *key, const char *val);
|
||||
void Set(char *keyval);
|
||||
SString Get(const char *key);
|
||||
int GetInt(const char *key, int defaultValue=0);
|
||||
SString GetWild(const char *keybase, const char *filename);
|
||||
SString GetNewExpand(const char *keybase, const char *filename);
|
||||
void Clear();
|
||||
void ReadFromMemory(const char *data, int len);
|
||||
void Read(const char *filename);
|
||||
};
|
||||
|
||||
// This is a fixed length list of strings suitable for display in combo boxes
|
||||
// as a memory of user entries
|
||||
template<int sz>
|
||||
class EntryMemory {
|
||||
SString entries[sz];
|
||||
public:
|
||||
void Insert(SString s) {
|
||||
for (int i=0;i<sz;i++) {
|
||||
if (entries[i] == s) {
|
||||
for (int j=i;j>0;j--) {
|
||||
entries[j] = entries[j-1];
|
||||
}
|
||||
entries[0] = s;
|
||||
return;
|
||||
}
|
||||
}
|
||||
for (int k=sz-1;k>0;k--) {
|
||||
entries[k] = entries[k-1];
|
||||
}
|
||||
entries[0] = s;
|
||||
}
|
||||
int Length() const {
|
||||
int len = 0;
|
||||
for (int i=0;i<sz;i++)
|
||||
if (entries[i].length())
|
||||
len++;
|
||||
return len;
|
||||
}
|
||||
SString At(int n) const {
|
||||
return entries[n];
|
||||
}
|
||||
};
|
||||
|
||||
class WordList {
|
||||
public:
|
||||
// Each word contains at least one character - a empty word acts as sentinal at the end.
|
||||
char **words;
|
||||
char *list;
|
||||
int len;
|
||||
bool onlyLineEnds; // Delimited by any white space or only line ends
|
||||
int starts[256];
|
||||
WordList(bool onlyLineEnds_ = false) :
|
||||
words(0), list(0), len(0), onlyLineEnds(onlyLineEnds_) {}
|
||||
~WordList() { Clear(); }
|
||||
operator bool() { return list; }
|
||||
const char *operator[](int ind) { return words[ind]; }
|
||||
void Clear();
|
||||
void Set(const char *s);
|
||||
char *Allocate(int size);
|
||||
void SetFromAllocated();
|
||||
bool InList(const char *s);
|
||||
};
|
||||
|
||||
#endif
|
134
contrib/src/stc/scintilla/include/SciLexer.h
Normal file
134
contrib/src/stc/scintilla/include/SciLexer.h
Normal file
@@ -0,0 +1,134 @@
|
||||
// Scintilla source code edit control
|
||||
// SciLexer - interface to the added lexer functions in the SciLexer version of the edit control
|
||||
// Copyright 1998-2000 by Neil Hodgson <neilh@scintilla.org>
|
||||
// The License.txt file describes the conditions under which this software may be distributed.
|
||||
|
||||
#ifndef SCILEXER_H
|
||||
#define SCILEXER_H
|
||||
|
||||
// SciLexer features - not in standard Scintilla
|
||||
|
||||
#define SCLEX_CONTAINER 0
|
||||
#define SCLEX_NULL 1
|
||||
#define SCLEX_PYTHON 2
|
||||
#define SCLEX_CPP 3
|
||||
#define SCLEX_HTML 4
|
||||
#define SCLEX_XML 5
|
||||
#define SCLEX_PERL 6
|
||||
#define SCLEX_SQL 7
|
||||
#define SCLEX_VB 8
|
||||
#define SCLEX_PROPERTIES 9
|
||||
#define SCLEX_ERRORLIST 10
|
||||
#define SCLEX_MAKEFILE 11
|
||||
#define SCLEX_BATCH 12
|
||||
|
||||
// Lexical states for SCLEX_PYTHON
|
||||
#define SCE_P_DEFAULT 0
|
||||
#define SCE_P_COMMENTLINE 1
|
||||
#define SCE_P_NUMBER 2
|
||||
#define SCE_P_STRING 3
|
||||
#define SCE_P_CHARACTER 4
|
||||
#define SCE_P_WORD 5
|
||||
#define SCE_P_TRIPLE 6
|
||||
#define SCE_P_TRIPLEDOUBLE 7
|
||||
#define SCE_P_CLASSNAME 8
|
||||
#define SCE_P_DEFNAME 9
|
||||
#define SCE_P_OPERATOR 10
|
||||
#define SCE_P_IDENTIFIER 11
|
||||
|
||||
// Lexical states for SCLEX_CPP, SCLEX_VB
|
||||
#define SCE_C_DEFAULT 0
|
||||
#define SCE_C_COMMENT 1
|
||||
#define SCE_C_COMMENTLINE 2
|
||||
#define SCE_C_COMMENTDOC 3
|
||||
#define SCE_C_NUMBER 4
|
||||
#define SCE_C_WORD 5
|
||||
#define SCE_C_STRING 6
|
||||
#define SCE_C_CHARACTER 7
|
||||
#define SCE_C_PUNTUATION 8
|
||||
#define SCE_C_PREPROCESSOR 9
|
||||
#define SCE_C_OPERATOR 10
|
||||
#define SCE_C_IDENTIFIER 11
|
||||
#define SCE_C_STRINGEOL 12
|
||||
|
||||
// Lexical states for SCLEX_HTML, SCLEX_xML
|
||||
#define SCE_H_DEFAULT 0
|
||||
#define SCE_H_TAG 1
|
||||
#define SCE_H_TAGUNKNOWN 2
|
||||
#define SCE_H_ATTRIBUTE 3
|
||||
#define SCE_H_ATTRIBUTEUNKNOWN 4
|
||||
#define SCE_H_NUMBER 5
|
||||
#define SCE_H_DOUBLESTRING 6
|
||||
#define SCE_H_SINGLESTRING 7
|
||||
#define SCE_H_OTHER 8
|
||||
#define SCE_H_COMMENT 9
|
||||
#define SCE_H_ENTITY 10
|
||||
// Embedded Javascript
|
||||
#define SCE_HJ_START 11
|
||||
#define SCE_HJ_DEFAULT 12
|
||||
#define SCE_HJ_COMMENT 13
|
||||
#define SCE_HJ_COMMENTLINE 14
|
||||
#define SCE_HJ_COMMENTDOC 15
|
||||
#define SCE_HJ_NUMBER 16
|
||||
#define SCE_HJ_WORD 17
|
||||
#define SCE_HJ_KEYWORD 18
|
||||
#define SCE_HJ_DOUBLESTRING 19
|
||||
#define SCE_HJ_SINGLESTRING 20
|
||||
#define SCE_HJ_SYMBOLS 21
|
||||
#define SCE_HJ_STRINGEOL 28
|
||||
// XML and ASP
|
||||
#define SCE_H_TAGEND 22
|
||||
#define SCE_H_XMLSTART 23
|
||||
#define SCE_H_XMLEND 24
|
||||
#define SCE_H_SCRIPT 25
|
||||
#define SCE_H_ASP 26
|
||||
#define SCE_H_ASPAT 27
|
||||
// Embedded VBScript
|
||||
#define SCE_HB_START 40
|
||||
#define SCE_HB_DEFAULT 41
|
||||
#define SCE_HB_COMMENTLINE 42
|
||||
#define SCE_HB_NUMBER 43
|
||||
#define SCE_HB_WORD 44
|
||||
#define SCE_HB_STRING 45
|
||||
#define SCE_HB_IDENTIFIER 46
|
||||
#define SCE_HB_STRINGEOL 47
|
||||
// Embedded Python
|
||||
#define SCE_HP_START 50
|
||||
#define SCE_HP_DEFAULT 51
|
||||
#define SCE_HP_COMMENTLINE 52
|
||||
#define SCE_HP_NUMBER 53
|
||||
#define SCE_HP_STRING 54
|
||||
#define SCE_HP_CHARACTER 55
|
||||
#define SCE_HP_WORD 56
|
||||
#define SCE_HP_TRIPLE 57
|
||||
#define SCE_HP_TRIPLEDOUBLE 58
|
||||
#define SCE_HP_CLASSNAME 59
|
||||
#define SCE_HP_DEFNAME 60
|
||||
#define SCE_HP_OPERATOR 61
|
||||
#define SCE_HP_IDENTIFIER 62
|
||||
|
||||
// Lexical states for SCLEX_PERL
|
||||
#define SCE_PL_DEFAULT 0
|
||||
#define SCE_PL_HERE 1
|
||||
#define SCE_PL_COMMENTLINE 2
|
||||
#define SCE_PL_POD 3
|
||||
#define SCE_PL_NUMBER 4
|
||||
#define SCE_PL_WORD 5
|
||||
#define SCE_PL_STRING 6
|
||||
#define SCE_PL_CHARACTER 7
|
||||
#define SCE_PL_PUNCTUATION 8
|
||||
#define SCE_PL_PREPROCESSOR 9
|
||||
#define SCE_PL_OPERATOR 10
|
||||
#define SCE_PL_IDENTIFIER 11
|
||||
#define SCE_PL_SCALAR 12
|
||||
#define SCE_PL_ARRAY 13
|
||||
#define SCE_PL_HASH 14
|
||||
#define SCE_PL_SYMBOLTABLE 15
|
||||
#define SCE_PL_REF 16
|
||||
#define SCE_PL_REGEX 17
|
||||
#define SCE_PL_REGSUBST 18
|
||||
#define SCE_PL_LONGQUOTE 19
|
||||
#define SCE_PL_BACKTICKS 20
|
||||
#define SCE_PL_DATASECTION 21
|
||||
|
||||
#endif
|
415
contrib/src/stc/scintilla/include/Scintilla.h
Normal file
415
contrib/src/stc/scintilla/include/Scintilla.h
Normal file
@@ -0,0 +1,415 @@
|
||||
// Scintilla source code edit control
|
||||
// Scintilla.h - interface to the edit control
|
||||
// Copyright 1998-2000 by Neil Hodgson <neilh@scintilla.org>
|
||||
// The License.txt file describes the conditions under which this software may be distributed.
|
||||
|
||||
#ifndef SCINTILLA_H
|
||||
#define SCINTILLA_H
|
||||
|
||||
// Compile-time configuration options
|
||||
#define MACRO_SUPPORT 1 // Comment out to remove macro hooks
|
||||
|
||||
#if PLAT_GTK
|
||||
#include <gdk/gdk.h>
|
||||
#include <gtk/gtkvbox.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define SCINTILLA(obj) GTK_CHECK_CAST (obj, scintilla_get_type (), ScintillaObject)
|
||||
#define SCINTILLA_CLASS(klass) GTK_CHECK_CLASS_CAS T (klass, scintilla_get_type (), ScintillaClass)
|
||||
#define IS_SCINTILLA(obj) GTK_CHECK_TYPE (obj, scintilla_get_type ())
|
||||
|
||||
typedef struct _ScintillaObject ScintillaObject;
|
||||
typedef struct _ScintillaClass ScintillaClass;
|
||||
|
||||
struct _ScintillaObject
|
||||
{
|
||||
GtkFixed vbox;
|
||||
void *pscin;
|
||||
};
|
||||
|
||||
struct _ScintillaClass
|
||||
{
|
||||
GtkFixedClass parent_class;
|
||||
|
||||
void (* command) (ScintillaObject *ttt);
|
||||
void (* notify) (ScintillaObject *ttt);
|
||||
};
|
||||
|
||||
guint scintilla_get_type (void);
|
||||
GtkWidget* scintilla_new (void);
|
||||
void scintilla_set_id (ScintillaObject *sci,int id);
|
||||
long scintilla_send_message (ScintillaObject *sci,int iMessage,int wParam,int lParam);
|
||||
|
||||
#include "WinDefs.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#if PLAT_WX
|
||||
#include "WinDefs.h"
|
||||
#endif
|
||||
|
||||
// Both GTK and Windows
|
||||
|
||||
#define INVALID_POSITION -1
|
||||
|
||||
// Define start of Scintilla messages to be greater than all edit (EM_*) messages
|
||||
// as many EM_ messages can be used.
|
||||
#define SCI_START 2000
|
||||
#define SCI_OPTIONAL_START 3000
|
||||
#define SCI_LEXER_START 4000
|
||||
|
||||
#define SCI_ADDTEXT SCI_START + 1
|
||||
#define SCI_ADDSTYLEDTEXT SCI_START + 2
|
||||
#define SCI_INSERTTEXT SCI_START + 3
|
||||
#define SCI_CLEARALL SCI_START + 4
|
||||
#define SCI_GETLENGTH SCI_START + 6
|
||||
#define SCI_GETCHARAT SCI_START + 7
|
||||
#define SCI_GETCURRENTPOS SCI_START + 8
|
||||
#define SCI_GETANCHOR SCI_START + 9
|
||||
#define SCI_GETSTYLEAT SCI_START + 10
|
||||
|
||||
#define SCI_REDO SCI_START + 11
|
||||
#define SCI_SETUNDOCOLLECTION SCI_START + 12
|
||||
#define SCI_SELECTALL SCI_START + 13
|
||||
#define SCI_SETSAVEPOINT SCI_START + 14
|
||||
#define SCI_GETSTYLEDTEXT SCI_START + 15
|
||||
#define SCI_CANREDO SCI_START + 16
|
||||
#define SCI_MARKERLINEFROMHANDLE SCI_START + 17
|
||||
#define SCI_MARKERDELETEHANDLE SCI_START + 18
|
||||
|
||||
#define SC_UNDOCOLLECT_NONE 0
|
||||
#define SC_UNDOCOLLECT_AUTOSTART 1
|
||||
|
||||
#define SCI_GETVIEWWS SCI_START + 20
|
||||
#define SCI_SETVIEWWS SCI_START + 21
|
||||
#define SCI_CHANGEPOSITION SCI_START + 22
|
||||
#define SCI_GOTOLINE SCI_START + 24
|
||||
#define SCI_GOTOPOS SCI_START + 25
|
||||
#define SCI_SETANCHOR SCI_START + 26
|
||||
#define SCI_GETCURLINE SCI_START + 27
|
||||
#define SCI_GETENDSTYLED SCI_START + 28
|
||||
#define SCI_CONVERTEOLS SCI_START + 29
|
||||
|
||||
#define SCI_GETEOLMODE SCI_START + 30
|
||||
#define SCI_SETEOLMODE SCI_START + 31
|
||||
|
||||
#define SC_EOL_CRLF 0
|
||||
#define SC_EOL_CR 1
|
||||
#define SC_EOL_LF 2
|
||||
|
||||
#define SCI_STARTSTYLING SCI_START + 32
|
||||
#define SCI_SETSTYLING SCI_START + 33
|
||||
|
||||
#define SCI_SETBUFFEREDDRAW SCI_START + 35
|
||||
#define SCI_SETTABWIDTH SCI_START + 36
|
||||
#define SCI_SETCODEPAGE SCI_START + 37
|
||||
#define SCI_SETUSEPALETTE SCI_START + 39
|
||||
|
||||
#define MARKER_MAX 31
|
||||
|
||||
#define SC_MARK_CIRCLE 0
|
||||
#define SC_MARK_ROUNDRECT 1
|
||||
#define SC_MARK_ARROW 2
|
||||
#define SC_MARK_SMALLRECT 3
|
||||
#define SC_MARK_SHORTARROW 4
|
||||
#define SC_MARK_EMPTY 5
|
||||
#define SC_MARK_ARROWDOWN 6
|
||||
#define SC_MARK_MINUS 7
|
||||
#define SC_MARK_PLUS 8
|
||||
|
||||
#define SCI_MARKERDEFINE SCI_START + 40
|
||||
#define SCI_MARKERSETFORE SCI_START + 41
|
||||
#define SCI_MARKERSETBACK SCI_START + 42
|
||||
#define SCI_MARKERADD SCI_START + 43
|
||||
#define SCI_MARKERDELETE SCI_START + 44
|
||||
#define SCI_MARKERDELETEALL SCI_START + 45
|
||||
#define SCI_MARKERGET SCI_START + 46
|
||||
#define SCI_MARKERNEXT SCI_START + 47
|
||||
#define SCI_MARKERPREVIOUS SCI_START + 48
|
||||
|
||||
#define SC_MARKNUM_FOLDER 30
|
||||
#define SC_MARKNUM_FOLDEROPEN 31
|
||||
|
||||
#define SC_MASK_FOLDERS ((1<<SC_MARKNUM_FOLDER) | (1<<SC_MARKNUM_FOLDEROPEN))
|
||||
|
||||
#define SC_MARGIN_SYMBOL 0
|
||||
#define SC_MARGIN_NUMBER 1
|
||||
|
||||
#define SCI_SETMARGINTYPEN SCI_START + 240
|
||||
#define SCI_GETMARGINTYPEN SCI_START + 241
|
||||
#define SCI_SETMARGINWIDTHN SCI_START + 242
|
||||
#define SCI_GETMARGINWIDTHN SCI_START + 243
|
||||
#define SCI_SETMARGINMASKN SCI_START + 244
|
||||
#define SCI_GETMARGINMASKN SCI_START + 245
|
||||
#define SCI_SETMARGINSENSITIVEN SCI_START + 246
|
||||
#define SCI_GETMARGINSENSITIVEN SCI_START + 247
|
||||
|
||||
#define STYLE_DEFAULT 32
|
||||
#define STYLE_LINENUMBER 33
|
||||
#define STYLE_BRACELIGHT 34
|
||||
#define STYLE_BRACEBAD 35
|
||||
#define STYLE_CONTROLCHAR 36
|
||||
#define STYLE_MAX 63
|
||||
|
||||
#define SCI_STYLECLEARALL SCI_START + 50
|
||||
#define SCI_STYLESETFORE SCI_START + 51
|
||||
#define SCI_STYLESETBACK SCI_START + 52
|
||||
#define SCI_STYLESETBOLD SCI_START + 53
|
||||
#define SCI_STYLESETITALIC SCI_START + 54
|
||||
#define SCI_STYLESETSIZE SCI_START + 55
|
||||
#define SCI_STYLESETFONT SCI_START + 56
|
||||
#define SCI_STYLESETEOLFILLED SCI_START + 57
|
||||
#define SCI_STYLERESETDEFAULT SCI_START + 58
|
||||
|
||||
#define SCI_SETSELFORE SCI_START + 67
|
||||
#define SCI_SETSELBACK SCI_START + 68
|
||||
#define SCI_SETCARETFORE SCI_START + 69
|
||||
|
||||
#define SCI_ASSIGNCMDKEY SCI_START + 70
|
||||
#define SCI_CLEARCMDKEY SCI_START + 71
|
||||
#define SCI_CLEARALLCMDKEYS SCI_START + 72
|
||||
|
||||
#define SCI_SETSTYLINGEX SCI_START + 73
|
||||
|
||||
#define SCI_GETCARETPERIOD SCI_START + 75
|
||||
#define SCI_SETCARETPERIOD SCI_START + 76
|
||||
#define SCI_SETWORDCHARS SCI_START + 77
|
||||
|
||||
#define SCI_BEGINUNDOACTION SCI_START + 78
|
||||
#define SCI_ENDUNDOACTION SCI_START + 79
|
||||
|
||||
#define INDIC_MAX 7
|
||||
|
||||
#define INDIC_PLAIN 0
|
||||
#define INDIC_SQUIGGLE 1
|
||||
#define INDIC_TT 2
|
||||
|
||||
#define INDIC0_MASK 32
|
||||
#define INDIC1_MASK 64
|
||||
#define INDIC2_MASK 128
|
||||
#define INDICS_MASK (INDIC0_MASK | INDIC1_MASK | INDIC2_MASK)
|
||||
|
||||
#define SCI_INDICSETSTYLE SCI_START + 80
|
||||
#define SCI_INDICGETSTYLE SCI_START + 81
|
||||
#define SCI_INDICSETFORE SCI_START + 82
|
||||
#define SCI_INDICGETFORE SCI_START + 83
|
||||
|
||||
#define SCI_SETSTYLEBITS SCI_START + 90
|
||||
#define SCI_GETSTYLEBITS SCI_START + 91
|
||||
#define SCI_SETLINESTATE SCI_START + 92
|
||||
#define SCI_GETLINESTATE SCI_START + 93
|
||||
#define SCI_GETMAXLINESTATE SCI_START + 94
|
||||
|
||||
#define SCI_AUTOCSHOW SCI_START + 100
|
||||
#define SCI_AUTOCCANCEL SCI_START + 101
|
||||
#define SCI_AUTOCACTIVE SCI_START + 102
|
||||
#define SCI_AUTOCPOSSTART SCI_START + 103
|
||||
#define SCI_AUTOCCOMPLETE SCI_START + 104
|
||||
#define SCI_AUTOCSTOPS SCI_START + 105
|
||||
|
||||
#define SCI_CALLTIPSHOW SCI_START + 200
|
||||
#define SCI_CALLTIPCANCEL SCI_START + 201
|
||||
#define SCI_CALLTIPACTIVE SCI_START + 202
|
||||
#define SCI_CALLTIPPOSSTART SCI_START + 203
|
||||
#define SCI_CALLTIPSETHLT SCI_START + 204
|
||||
#define SCI_CALLTIPSETBACK SCI_START + 205
|
||||
|
||||
#define SC_FOLDLEVELBASE 0x400
|
||||
#define SC_FOLDLEVELWHITEFLAG 0x1000
|
||||
#define SC_FOLDLEVELHEADERFLAG 0x2000
|
||||
#define SC_FOLDLEVELNUMBERMASK 0x0FFF
|
||||
|
||||
#define SCI_VISIBLEFROMDOCLINE SCI_START + 220
|
||||
#define SCI_DOCLINEFROMVISIBLE SCI_START + 221
|
||||
#define SCI_SETFOLDLEVEL SCI_START + 222
|
||||
#define SCI_GETFOLDLEVEL SCI_START + 223
|
||||
#define SCI_GETLASTCHILD SCI_START + 224
|
||||
#define SCI_GETFOLDPARENT SCI_START + 225
|
||||
#define SCI_SHOWLINES SCI_START + 226
|
||||
#define SCI_HIDELINES SCI_START + 227
|
||||
#define SCI_GETLINEVISIBLE SCI_START + 228
|
||||
#define SCI_SETFOLDEXPANDED SCI_START + 229
|
||||
#define SCI_GETFOLDEXPANDED SCI_START + 230
|
||||
#define SCI_TOGGLEFOLD SCI_START + 231
|
||||
#define SCI_ENSUREVISIBLE SCI_START + 232
|
||||
#define SCI_SETFOLDFLAGS SCI_START + 233
|
||||
|
||||
// Key messages
|
||||
#define SCI_LINEDOWN SCI_START + 300
|
||||
#define SCI_LINEDOWNEXTEND SCI_START + 301
|
||||
#define SCI_LINEUP SCI_START + 302
|
||||
#define SCI_LINEUPEXTEND SCI_START + 303
|
||||
#define SCI_CHARLEFT SCI_START + 304
|
||||
#define SCI_CHARLEFTEXTEND SCI_START + 305
|
||||
#define SCI_CHARRIGHT SCI_START + 306
|
||||
#define SCI_CHARRIGHTEXTEND SCI_START + 307
|
||||
#define SCI_WORDLEFT SCI_START + 308
|
||||
#define SCI_WORDLEFTEXTEND SCI_START + 309
|
||||
#define SCI_WORDRIGHT SCI_START + 310
|
||||
#define SCI_WORDRIGHTEXTEND SCI_START + 311
|
||||
#define SCI_HOME SCI_START + 312
|
||||
#define SCI_HOMEEXTEND SCI_START + 313
|
||||
#define SCI_LINEEND SCI_START + 314
|
||||
#define SCI_LINEENDEXTEND SCI_START + 315
|
||||
#define SCI_DOCUMENTSTART SCI_START + 316
|
||||
#define SCI_DOCUMENTSTARTEXTEND SCI_START + 317
|
||||
#define SCI_DOCUMENTEND SCI_START + 318
|
||||
#define SCI_DOCUMENTENDEXTEND SCI_START + 319
|
||||
#define SCI_PAGEUP SCI_START + 320
|
||||
#define SCI_PAGEUPEXTEND SCI_START + 321
|
||||
#define SCI_PAGEDOWN SCI_START + 322
|
||||
#define SCI_PAGEDOWNEXTEND SCI_START + 323
|
||||
#define SCI_EDITTOGGLEOVERTYPE SCI_START + 324
|
||||
#define SCI_CANCEL SCI_START + 325
|
||||
#define SCI_DELETEBACK SCI_START + 326
|
||||
#define SCI_TAB SCI_START + 327
|
||||
#define SCI_BACKTAB SCI_START + 328
|
||||
#define SCI_NEWLINE SCI_START + 329
|
||||
#define SCI_FORMFEED SCI_START + 330
|
||||
#define SCI_VCHOME SCI_START + 331
|
||||
#define SCI_VCHOMEEXTEND SCI_START + 332
|
||||
#define SCI_ZOOMIN SCI_START + 333
|
||||
#define SCI_ZOOMOUT SCI_START + 334
|
||||
#define SCI_DELWORDLEFT SCI_START + 335
|
||||
#define SCI_DELWORDRIGHT SCI_START + 336
|
||||
|
||||
#define SCI_LINELENGTH SCI_START + 350
|
||||
#define SCI_BRACEHIGHLIGHT SCI_START + 351
|
||||
#define SCI_BRACEBADLIGHT SCI_START + 352
|
||||
#define SCI_BRACEMATCH SCI_START + 353
|
||||
#define SCI_GETVIEWEOL SCI_START + 355
|
||||
#define SCI_SETVIEWEOL SCI_START + 356
|
||||
#define SCI_GETDOCPOINTER SCI_START + 357
|
||||
#define SCI_SETDOCPOINTER SCI_START + 358
|
||||
#define SCI_SETMODEVENTMASK SCI_START + 359
|
||||
|
||||
#define EDGE_NONE 0
|
||||
#define EDGE_LINE 1
|
||||
#define EDGE_BACKGROUND 2
|
||||
|
||||
#define SCI_GETEDGECOLUMN SCI_START + 360
|
||||
#define SCI_SETEDGECOLUMN SCI_START + 361
|
||||
#define SCI_GETEDGEMODE SCI_START + 362
|
||||
#define SCI_SETEDGEMODE SCI_START + 363
|
||||
#define SCI_GETEDGECOLOUR SCI_START + 364
|
||||
#define SCI_SETEDGECOLOUR SCI_START + 365
|
||||
|
||||
#define SCI_SEARCHANCHOR SCI_START + 366
|
||||
#define SCI_SEARCHNEXT SCI_START + 367
|
||||
#define SCI_SEARCHPREV SCI_START + 368
|
||||
|
||||
#define CARET_SLOP 0x01 // Show caret within N lines of edge when it's scrolled to view
|
||||
#define CARET_CENTER 0x02 // Center caret on screen when it's scrolled to view
|
||||
#define CARET_STRICT 0x04 // OR this with CARET_CENTER to reposition even when visible, or
|
||||
// OR this with CARET_SLOP to reposition whenever outside slop border
|
||||
|
||||
#define SCI_SETCARETPOLICY SCI_START + 369
|
||||
|
||||
// GTK+ Specific
|
||||
#define SCI_GRABFOCUS SCI_START + 400
|
||||
|
||||
// Optional module for macro recording
|
||||
#ifdef MACRO_SUPPORT
|
||||
typedef void (tMacroRecorder)(UINT iMessage, WPARAM wParam, LPARAM lParam,
|
||||
void *userData);
|
||||
#define SCI_STARTRECORD SCI_OPTIONAL_START + 1
|
||||
#define SCI_STOPRECORD SCI_OPTIONAL_START + 2
|
||||
#endif
|
||||
|
||||
#define SCI_SETLEXER SCI_LEXER_START + 1
|
||||
#define SCI_GETLEXER SCI_LEXER_START + 2
|
||||
#define SCI_COLOURISE SCI_LEXER_START + 3
|
||||
#define SCI_SETPROPERTY SCI_LEXER_START + 4
|
||||
#define SCI_SETKEYWORDS SCI_LEXER_START + 5
|
||||
|
||||
// Notifications
|
||||
|
||||
// Type of modification and the action which caused the modification
|
||||
// These are defined as a bit mask to make it easy to specify which notifications are wanted.
|
||||
// One bit is set from each of SC_MOD_* and SC_PERFORMED_*.
|
||||
#define SC_MOD_INSERTTEXT 0x1
|
||||
#define SC_MOD_DELETETEXT 0x2
|
||||
#define SC_MOD_CHANGESTYLE 0x4
|
||||
#define SC_MOD_CHANGEFOLD 0x8
|
||||
#define SC_PERFORMED_USER 0x10
|
||||
#define SC_PERFORMED_UNDO 0x20
|
||||
#define SC_PERFORMED_REDO 0x40
|
||||
#define SC_LASTSTEPINUNDOREDO 0x100
|
||||
|
||||
#define SC_MODEVENTMASKALL 0x377
|
||||
|
||||
struct SCNotification {
|
||||
NMHDR nmhdr;
|
||||
int position; // SCN_STYLENEEDED, SCN_MODIFIED
|
||||
int ch; // SCN_CHARADDED, SCN_KEY
|
||||
int modifiers; // SCN_KEY
|
||||
int modificationType; // SCN_MODIFIED
|
||||
const char *text; // SCN_MODIFIED
|
||||
int length; // SCN_MODIFIED
|
||||
int linesAdded; // SCN_MODIFIED
|
||||
#ifdef MACRO_SUPPORT
|
||||
int message; // SCN_MACRORECORD
|
||||
int wParam; // SCN_MACRORECORD
|
||||
int lParam; // SCN_MACRORECORD
|
||||
#endif
|
||||
int line; // SCN_MODIFIED
|
||||
int foldLevelNow; // SCN_MODIFIED
|
||||
int foldLevelPrev; // SCN_MODIFIED
|
||||
int margin; // SCN_MARGINCLICK
|
||||
};
|
||||
|
||||
#define SCN_STYLENEEDED 2000
|
||||
#define SCN_CHARADDED 2001
|
||||
#define SCN_SAVEPOINTREACHED 2002
|
||||
#define SCN_SAVEPOINTLEFT 2003
|
||||
#define SCN_MODIFYATTEMPTRO 2004
|
||||
// GTK+ Specific to work around focus and accelerator problems:
|
||||
#define SCN_KEY 2005
|
||||
#define SCN_DOUBLECLICK 2006
|
||||
#define SCN_UPDATEUI 2007
|
||||
// The old name for SCN_UPDATEUI:
|
||||
#define SCN_CHECKBRACE 2007
|
||||
#define SCN_MODIFIED 2008
|
||||
// Optional module for macro recording
|
||||
#ifdef MACRO_SUPPORT
|
||||
#define SCN_MACRORECORD 2009
|
||||
#endif
|
||||
#define SCN_MARGINCLICK 2010
|
||||
#define SCN_NEEDSHOWN 2011
|
||||
|
||||
#ifdef STATIC_BUILD
|
||||
void Scintilla_RegisterClasses(HINSTANCE hInstance);
|
||||
#endif
|
||||
|
||||
// Deprecation section listing all API features that are deprecated and will
|
||||
// will be removed completely in a future version.
|
||||
// To enable these features define INCLUDE_DEPRECATED_FEATURES
|
||||
|
||||
#ifdef INCLUDE_DEPRECATED_FEATURES
|
||||
|
||||
// Default style settings. These are deprecated and will be removed in a future version.
|
||||
#define SCI_SETFORE SCI_START + 60
|
||||
#define SCI_SETBACK SCI_START + 61
|
||||
#define SCI_SETBOLD SCI_START + 62
|
||||
#define SCI_SETITALIC SCI_START + 63
|
||||
#define SCI_SETSIZE SCI_START + 64
|
||||
#define SCI_SETFONT SCI_START + 65
|
||||
|
||||
#define SCI_APPENDUNDOSTARTACTION SCI_START + 74
|
||||
|
||||
#define SC_UNDOCOLLECT_MANUALSTART 2
|
||||
|
||||
// Deprecated in release 1.22
|
||||
#define SCI_SETMARGINWIDTH SCI_START + 34
|
||||
#define SCI_SETLINENUMBERWIDTH SCI_START + 38
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
218
contrib/src/stc/scintilla/include/WinDefs.h
Normal file
218
contrib/src/stc/scintilla/include/WinDefs.h
Normal file
@@ -0,0 +1,218 @@
|
||||
// Scintilla source code edit control
|
||||
// WinDefs.h - the subset of definitions from Windows needed by Scintilla for GTK+
|
||||
// Copyright 1998-2000 by Neil Hodgson <neilh@scintilla.org>
|
||||
// The License.txt file describes the conditions under which this software may be distributed.
|
||||
|
||||
#ifndef WINDEFS_H
|
||||
#define WINDEFS_H
|
||||
|
||||
#define WORD short
|
||||
#define WPARAM unsigned long
|
||||
#define LPARAM long
|
||||
#define LRESULT long
|
||||
#define DWORD long
|
||||
|
||||
#define UINT unsigned int
|
||||
#define LPSTR char *
|
||||
#define LONG long
|
||||
|
||||
/* RTF control */
|
||||
#define EM_CANPASTE (1074)
|
||||
#define EM_CANUNDO (198)
|
||||
#define EM_CHARFROMPOS (215)
|
||||
#define EM_DISPLAYBAND (1075)
|
||||
#define EM_EMPTYUNDOBUFFER (205)
|
||||
#define EM_EXGETSEL (1076)
|
||||
#define EM_EXLIMITTEXT (1077)
|
||||
#define EM_EXLINEFROMCHAR (1078)
|
||||
#define EM_EXSETSEL (1079)
|
||||
#define EM_FINDTEXT (1080)
|
||||
#define EM_FINDTEXTEX (1103)
|
||||
#define EM_FINDWORDBREAK (1100)
|
||||
#define EM_FMTLINES (200)
|
||||
#define EM_FORMATRANGE (1081)
|
||||
#define EM_GETCHARFORMAT (1082)
|
||||
#define EM_GETEVENTMASK (1083)
|
||||
#define EM_GETFIRSTVISIBLELINE (206)
|
||||
#define EM_GETHANDLE (189)
|
||||
#define EM_GETLIMITTEXT (213)
|
||||
#define EM_GETLINE (196)
|
||||
#define EM_GETLINECOUNT (186)
|
||||
#define EM_GETMARGINS (212)
|
||||
#define EM_GETMODIFY (184)
|
||||
#define EM_GETIMECOLOR (1129)
|
||||
#define EM_GETIMEOPTIONS (1131)
|
||||
#define EM_GETOPTIONS (1102)
|
||||
#define EM_GETOLEINTERFACE (1084)
|
||||
#define EM_GETPARAFORMAT (1085)
|
||||
#define EM_GETPASSWORDCHAR (210)
|
||||
#define EM_GETPUNCTUATION (1125)
|
||||
#define EM_GETRECT (178)
|
||||
#define EM_GETSEL (176)
|
||||
#define EM_GETSELTEXT (1086)
|
||||
#define EM_GETTEXTRANGE (1099)
|
||||
#define EM_GETTHUMB (190)
|
||||
#define EM_GETWORDBREAKPROC (209)
|
||||
#define EM_GETWORDBREAKPROCEX (1104)
|
||||
#define EM_GETWORDWRAPMODE (1127)
|
||||
#define EM_HIDESELECTION (1087)
|
||||
#define EM_LIMITTEXT (197)
|
||||
#define EM_LINEFROMCHAR (201)
|
||||
#define EM_LINEINDEX (187)
|
||||
#define EM_LINELENGTH (193)
|
||||
#define EM_LINESCROLL (182)
|
||||
#define EM_PASTESPECIAL (1088)
|
||||
#define EM_POSFROMCHAR (214)
|
||||
#define EM_REPLACESEL (194)
|
||||
#define EM_REQUESTRESIZE (1089)
|
||||
#define EM_SCROLL (181)
|
||||
#define EM_SCROLLCARET (183)
|
||||
#define EM_SELECTIONTYPE (1090)
|
||||
#define EM_SETBKGNDCOLOR (1091)
|
||||
#define EM_SETCHARFORMAT (1092)
|
||||
#define EM_SETEVENTMASK (1093)
|
||||
#define EM_SETHANDLE (188)
|
||||
#define EM_SETIMECOLOR (1128)
|
||||
#define EM_SETIMEOPTIONS (1130)
|
||||
#define EM_SETLIMITTEXT (197)
|
||||
#define EM_SETMARGINS (211)
|
||||
#define EM_SETMODIFY (185)
|
||||
#define EM_SETOLECALLBACK (1094)
|
||||
#define EM_SETOPTIONS (1101)
|
||||
#define EM_SETPARAFORMAT (1095)
|
||||
#define EM_SETPASSWORDCHAR (204)
|
||||
#define EM_SETPUNCTUATION (1124)
|
||||
#define EM_SETREADONLY (207)
|
||||
#define EM_SETRECT (179)
|
||||
#define EM_SETRECTNP (180)
|
||||
#define EM_SETSEL (177)
|
||||
#define EM_SETTABSTOPS (203)
|
||||
#define EM_SETTARGETDEVICE (1096)
|
||||
#define EM_SETWORDBREAKPROC (208)
|
||||
#define EM_SETWORDBREAKPROCEX (1105)
|
||||
#define EM_SETWORDWRAPMODE (1126)
|
||||
#define EM_STREAMIN (1097)
|
||||
#define EM_STREAMOUT (1098)
|
||||
#define EM_UNDO (199)
|
||||
|
||||
#define WM_NULL (0)
|
||||
#define WM_CLEAR (771)
|
||||
#define WM_COMMAND (273)
|
||||
#define WM_COPY (769)
|
||||
#define WM_CUT (768)
|
||||
#define WM_GETTEXT (13)
|
||||
#define WM_GETTEXTLENGTH (14)
|
||||
#define WM_NOTIFY (78)
|
||||
#define WM_PASTE (770)
|
||||
#define WM_SETTEXT (12)
|
||||
#define WM_UNDO (772)
|
||||
|
||||
#define EN_CHANGE (768)
|
||||
#define EN_KILLFOCUS (512)
|
||||
#define EN_SETFOCUS (256)
|
||||
|
||||
#define EC_LEFTMARGIN 1
|
||||
#define EC_RIGHTMARGIN 2
|
||||
#define EC_USEFONTINFO 0xffff
|
||||
|
||||
#if PLAT_GTK
|
||||
#define VK_DOWN GDK_Down
|
||||
#define VK_UP GDK_Up
|
||||
#define VK_LEFT GDK_Left
|
||||
#define VK_RIGHT GDK_Right
|
||||
#define VK_HOME GDK_Home
|
||||
#define VK_END GDK_End
|
||||
#define VK_PRIOR GDK_Page_Up
|
||||
#define VK_NEXT GDK_Page_Down
|
||||
#define VK_DELETE GDK_Delete
|
||||
#define VK_INSERT GDK_Insert
|
||||
#define VK_ESCAPE GDK_Escape
|
||||
#define VK_BACK GDK_BackSpace
|
||||
#define VK_TAB GDK_Tab
|
||||
#define VK_RETURN GDK_Return
|
||||
#define VK_ADD GDK_KP_Add
|
||||
#define VK_SUBTRACT GDK_KP_Subtract
|
||||
#endif
|
||||
|
||||
#if PLAT_WX
|
||||
#define VK_DOWN WXK_DOWN
|
||||
#define VK_UP WXK_UP
|
||||
#define VK_LEFT WXK_LEFT
|
||||
#define VK_RIGHT WXK_RIGHT
|
||||
#define VK_HOME WXK_HOME
|
||||
#define VK_END WXK_END
|
||||
#define VK_PRIOR WXK_PRIOR
|
||||
#define VK_NEXT WXK_NEXT
|
||||
#define VK_DELETE WXK_DELETE
|
||||
#define VK_INSERT WXK_INSERT
|
||||
#define VK_ESCAPE WXK_ESCAPE
|
||||
#define VK_BACK WXK_BACK
|
||||
#define VK_TAB WXK_TAB
|
||||
#define VK_RETURN WXK_RETURN
|
||||
#define VK_ADD WXK_ADD
|
||||
#define VK_SUBTRACT WXK_SUBTRACT
|
||||
|
||||
// Are these needed any more
|
||||
#define LPSTR char *
|
||||
#define LONG long
|
||||
#define LPDWORD (long *)
|
||||
#endif
|
||||
|
||||
/* SELCHANGE structure */
|
||||
#define SEL_EMPTY (0)
|
||||
#define SEL_TEXT (1)
|
||||
#define SEL_OBJECT (2)
|
||||
#define SEL_MULTICHAR (4)
|
||||
#define SEL_MULTIOBJECT (8)
|
||||
|
||||
/* FINDREPLACE structure */
|
||||
#define FR_MATCHCASE (0x4)
|
||||
#define FR_WHOLEWORD (0x2)
|
||||
#define FR_DOWN (0x1)
|
||||
|
||||
#define SHIFT_PRESSED 1
|
||||
#define LEFT_CTRL_PRESSED 2
|
||||
#define LEFT_ALT_PRESSED 4
|
||||
|
||||
struct RECT {
|
||||
LONG left;
|
||||
LONG top;
|
||||
LONG right;
|
||||
LONG bottom;
|
||||
};
|
||||
|
||||
struct CHARRANGE {
|
||||
LONG cpMin;
|
||||
LONG cpMax;
|
||||
};
|
||||
|
||||
struct TEXTRANGE {
|
||||
CHARRANGE chrg;
|
||||
LPSTR lpstrText;
|
||||
};
|
||||
|
||||
struct FINDTEXTEX {
|
||||
CHARRANGE chrg;
|
||||
LPSTR lpstrText;
|
||||
CHARRANGE chrgText;
|
||||
};
|
||||
|
||||
struct NMHDR {
|
||||
WindowID hwndFrom;
|
||||
UINT idFrom;
|
||||
UINT code;
|
||||
};
|
||||
|
||||
struct FORMATRANGE {
|
||||
SurfaceID hdc;
|
||||
SurfaceID hdcTarget;
|
||||
RECT rc;
|
||||
RECT rcPage;
|
||||
CHARRANGE chrg;
|
||||
};
|
||||
|
||||
#define MAKELONG(a, b) ((a) | ((b) << 16))
|
||||
#define LOWORD(x) (x & 0xffff)
|
||||
#define HIWORD(x) (x >> 16)
|
||||
|
||||
#endif
|
112
contrib/src/stc/scintilla/src/Accessor.cxx
Normal file
112
contrib/src/stc/scintilla/src/Accessor.cxx
Normal file
@@ -0,0 +1,112 @@
|
||||
// SciTE - Scintilla based Text Editor
|
||||
// Accessor.cxx - rapid easy access to contents of a Scintilla
|
||||
// Copyright 1998-2000 by Neil Hodgson <neilh@scintilla.org>
|
||||
// The License.txt file describes the conditions under which this software may be distributed.
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "Platform.h"
|
||||
|
||||
#include "PropSet.h"
|
||||
#include "Accessor.h"
|
||||
#include "Scintilla.h"
|
||||
|
||||
void Accessor::Fill(int position) {
|
||||
if (lenDoc == -1)
|
||||
lenDoc = Platform::SendScintilla(id, WM_GETTEXTLENGTH, 0, 0);
|
||||
startPos = position - slopSize;
|
||||
if (startPos + bufferSize > lenDoc)
|
||||
startPos = lenDoc - bufferSize;
|
||||
if (startPos < 0)
|
||||
startPos = 0;
|
||||
endPos = startPos + bufferSize;
|
||||
if (endPos > lenDoc)
|
||||
endPos = lenDoc;
|
||||
|
||||
TEXTRANGE tr = {{startPos, endPos}, buf};
|
||||
Platform::SendScintilla(id, EM_GETTEXTRANGE, 0, reinterpret_cast<LPARAM>(&tr));
|
||||
}
|
||||
|
||||
char Accessor::StyleAt(int position) {
|
||||
return static_cast<char>(Platform::SendScintilla(
|
||||
id, SCI_GETSTYLEAT, position, 0));
|
||||
}
|
||||
|
||||
int Accessor::GetLine(int position) {
|
||||
return Platform::SendScintilla(id, EM_LINEFROMCHAR, position, 0);
|
||||
}
|
||||
|
||||
int Accessor::LineStart(int line) {
|
||||
return Platform::SendScintilla(id, EM_LINEINDEX, line, 0);
|
||||
}
|
||||
|
||||
int Accessor::LevelAt(int line) {
|
||||
return Platform::SendScintilla(id, SCI_GETFOLDLEVEL, line, 0);
|
||||
}
|
||||
|
||||
int Accessor::Length() {
|
||||
if (lenDoc == -1)
|
||||
lenDoc = Platform::SendScintilla(id, WM_GETTEXTLENGTH, 0, 0);
|
||||
return lenDoc;
|
||||
}
|
||||
|
||||
int Accessor::GetLineState(int line) {
|
||||
return Platform::SendScintilla(id, SCI_GETLINESTATE, line);
|
||||
}
|
||||
|
||||
int Accessor::SetLineState(int line, int state) {
|
||||
return Platform::SendScintilla(id, SCI_SETLINESTATE, line, state);
|
||||
}
|
||||
|
||||
void StylingContext::StartAt(unsigned int start, char chMask) {
|
||||
Platform::SendScintilla(id, SCI_STARTSTYLING, start, chMask);
|
||||
}
|
||||
|
||||
void StylingContext::ColourSegment(unsigned int start, unsigned int end, int chAttr) {
|
||||
// Only perform styling if non empty range
|
||||
if (end != start - 1) {
|
||||
if (end < start) {
|
||||
Platform::DebugPrintf("Bad colour positions %d - %d\n", start, end);
|
||||
}
|
||||
|
||||
if (validLen + (end - start + 1) >= bufferSize)
|
||||
Flush();
|
||||
if (validLen + (end - start + 1) >= bufferSize) {
|
||||
// Too big for buffer so send directly
|
||||
Platform::SendScintilla(id, SCI_SETSTYLING, end - start + 1, chAttr);
|
||||
} else {
|
||||
if (chAttr != chWhile)
|
||||
chFlags = 0;
|
||||
chAttr |= chFlags;
|
||||
for (unsigned int i = start; i <= end; i++) {
|
||||
styleBuf[validLen++] = chAttr;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void StylingContext::StartSegment(unsigned int pos) {
|
||||
startSeg = pos;
|
||||
}
|
||||
|
||||
void StylingContext::ColourTo(unsigned int pos, int chAttr) {
|
||||
ColourSegment(startSeg, pos, chAttr);
|
||||
startSeg = pos+1;
|
||||
}
|
||||
|
||||
int StylingContext::GetLine(int position) {
|
||||
return Platform::SendScintilla(id, EM_LINEFROMCHAR, position, 0);
|
||||
}
|
||||
|
||||
void StylingContext::SetLevel(int line, int level) {
|
||||
Platform::SendScintilla(id, SCI_SETFOLDLEVEL, line, level);
|
||||
}
|
||||
|
||||
void StylingContext::Flush() {
|
||||
if (validLen > 0) {
|
||||
Platform::SendScintilla(id, SCI_SETSTYLINGEX, validLen,
|
||||
reinterpret_cast<LPARAM>(styleBuf));
|
||||
validLen = 0;
|
||||
}
|
||||
}
|
104
contrib/src/stc/scintilla/src/AutoComplete.cxx
Normal file
104
contrib/src/stc/scintilla/src/AutoComplete.cxx
Normal file
@@ -0,0 +1,104 @@
|
||||
// Scintilla source code edit control
|
||||
// AutoComplete.cxx - defines the auto completion list box
|
||||
// Copyright 1998-2000 by Neil Hodgson <neilh@scintilla.org>
|
||||
// The License.txt file describes the conditions under which this software may be distributed.
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "Platform.h"
|
||||
|
||||
#include "AutoComplete.h"
|
||||
|
||||
AutoComplete::AutoComplete() {
|
||||
lb = 0;
|
||||
active = false;
|
||||
posStart = 0;
|
||||
strcpy(stopChars, "");
|
||||
}
|
||||
|
||||
AutoComplete::~AutoComplete() {
|
||||
lb.Destroy();
|
||||
}
|
||||
|
||||
bool AutoComplete::Active() {
|
||||
return active;
|
||||
}
|
||||
|
||||
void AutoComplete::Start(Window &parent, int ctrlID, int position, int startLen_) {
|
||||
if (!lb.Created()) {
|
||||
lb.Create(parent, ctrlID);
|
||||
}
|
||||
lb.Clear();
|
||||
active = true;
|
||||
startLen = startLen_;
|
||||
posStart = position;
|
||||
}
|
||||
|
||||
void AutoComplete::SetStopChars(const char *stopChars_) {
|
||||
strncpy(stopChars, stopChars_, sizeof(stopChars));
|
||||
stopChars[sizeof(stopChars) - 1] = '\0';
|
||||
}
|
||||
|
||||
bool AutoComplete::IsStopChar(char ch) {
|
||||
return ch && strchr(stopChars, ch);
|
||||
}
|
||||
|
||||
int AutoComplete::SetList(const char *list) {
|
||||
int maxStrLen = 12;
|
||||
lb.Clear();
|
||||
char *words = new char[strlen(list) + 1];
|
||||
if (words) {
|
||||
strcpy(words, list);
|
||||
char *startword = words;
|
||||
int i = 0;
|
||||
for (; words && words[i]; i++) {
|
||||
if (words[i] == ' ') {
|
||||
words[i] = '\0';
|
||||
lb.Append(startword);
|
||||
maxStrLen = Platform::Maximum(maxStrLen, strlen(startword));
|
||||
startword = words + i + 1;
|
||||
}
|
||||
}
|
||||
if (startword) {
|
||||
lb.Append(startword);
|
||||
maxStrLen = Platform::Maximum(maxStrLen, strlen(startword));
|
||||
}
|
||||
delete []words;
|
||||
}
|
||||
lb.Sort();
|
||||
return maxStrLen;
|
||||
}
|
||||
|
||||
void AutoComplete::Show() {
|
||||
lb.Show();
|
||||
lb.Select(0);
|
||||
}
|
||||
|
||||
void AutoComplete::Cancel() {
|
||||
if (lb.Created()) {
|
||||
lb.Destroy();
|
||||
lb = 0;
|
||||
active = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void AutoComplete::Move(int delta) {
|
||||
int count = lb.Length();
|
||||
int current = lb.GetSelection();
|
||||
current += delta;
|
||||
if (current >= count)
|
||||
current = count - 1;
|
||||
if (current < 0)
|
||||
current = 0;
|
||||
lb.Select(current);
|
||||
}
|
||||
|
||||
void AutoComplete::Select(const char *word) {
|
||||
int pos = lb.Find(word);
|
||||
//Platform::DebugPrintf("Autocompleting at <%s> %d\n", wordCurrent, pos);
|
||||
if (pos != -1)
|
||||
lb.Select(pos);
|
||||
}
|
||||
|
43
contrib/src/stc/scintilla/src/AutoComplete.h
Normal file
43
contrib/src/stc/scintilla/src/AutoComplete.h
Normal file
@@ -0,0 +1,43 @@
|
||||
// Scintilla source code edit control
|
||||
// AutoComplete.h - defines the auto completion list box
|
||||
// Copyright 1998-2000 by Neil Hodgson <neilh@scintilla.org>
|
||||
// The License.txt file describes the conditions under which this software may be distributed.
|
||||
|
||||
#ifndef AUTOCOMPLETE_H
|
||||
#define AUTOCOMPLETE_H
|
||||
|
||||
class AutoComplete {
|
||||
bool active;
|
||||
char stopChars[256];
|
||||
public:
|
||||
ListBox lb;
|
||||
int posStart;
|
||||
int startLen;
|
||||
|
||||
AutoComplete();
|
||||
~AutoComplete();
|
||||
|
||||
// Is the auto completion list displayed?
|
||||
bool Active();
|
||||
|
||||
// Display the auto completion list positioned to be near a character position
|
||||
void Start(Window &parent, int ctrlID, int position, int startLen_);
|
||||
|
||||
// The stop chars are characters which, when typed, cause the auto completion list to disappear
|
||||
void SetStopChars(const char *stopChars_);
|
||||
bool IsStopChar(char ch);
|
||||
|
||||
// The list string contains a sequence of words separated by spaces
|
||||
int SetList(const char *list);
|
||||
|
||||
void Show();
|
||||
void Cancel();
|
||||
|
||||
// Move the current list element by delta, scrolling appropriately
|
||||
void Move(int delta);
|
||||
|
||||
// Select a list element that starts with word as the current element
|
||||
void Select(const char *word);
|
||||
};
|
||||
|
||||
#endif
|
168
contrib/src/stc/scintilla/src/CallTip.cxx
Normal file
168
contrib/src/stc/scintilla/src/CallTip.cxx
Normal file
@@ -0,0 +1,168 @@
|
||||
// Scintilla source code edit control
|
||||
// CallTip.cxx - code for displaying call tips
|
||||
// Copyright 1998-2000 by Neil Hodgson <neilh@scintilla.org>
|
||||
// The License.txt file describes the conditions under which this software may be distributed.
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "Platform.h"
|
||||
|
||||
#include "CallTip.h"
|
||||
|
||||
CallTip::CallTip() {
|
||||
wCallTip = 0;
|
||||
inCallTipMode = false;
|
||||
posStartCallTip = 0;
|
||||
val = 0;
|
||||
startHighlight = 0;
|
||||
endHighlight = 0;
|
||||
|
||||
colourBG.desired = Colour(0xff, 0xff, 0xff);
|
||||
colourUnSel.desired = Colour(0x80, 0x80, 0x80);
|
||||
colourSel.desired = Colour(0, 0, 0x80);
|
||||
colourShade.desired = Colour(0, 0, 0);
|
||||
colourLight.desired = Colour(0xc0, 0xc0, 0xc0);
|
||||
}
|
||||
|
||||
CallTip::~CallTip() {
|
||||
wCallTip.Destroy();
|
||||
delete []val;
|
||||
val = 0;
|
||||
}
|
||||
|
||||
void CallTip::RefreshColourPalette(Palette &pal, bool want) {
|
||||
pal.WantFind(colourBG, want);
|
||||
pal.WantFind(colourUnSel, want);
|
||||
pal.WantFind(colourSel, want);
|
||||
pal.WantFind(colourShade, want);
|
||||
pal.WantFind(colourLight, want);
|
||||
}
|
||||
|
||||
void CallTip::PaintCT(Surface *surfaceWindow) {
|
||||
if (!val)
|
||||
return;
|
||||
PRectangle rcClientPos = wCallTip.GetClientPosition();
|
||||
PRectangle rcClientSize(0, 0, rcClientPos.right - rcClientPos.left,
|
||||
rcClientPos.bottom - rcClientPos.top);
|
||||
PRectangle rcClient(1, 1, rcClientSize.right - 1, rcClientSize.bottom - 1);
|
||||
|
||||
surfaceWindow->FillRectangle(rcClient, colourBG.allocated);
|
||||
// To make a nice small call tip window, it is only sized to fit most normal characters without accents
|
||||
int lineHeight = surfaceWindow->Height(font);
|
||||
int ascent = surfaceWindow->Ascent(font) - surfaceWindow->InternalLeading(font);
|
||||
|
||||
// For each line...
|
||||
// Draw the definition in three parts: before highlight, highlighted, after highlight
|
||||
int ytext = rcClient.top + ascent + 1;
|
||||
char *chunkVal = val;
|
||||
bool moreChunks = true;
|
||||
while (moreChunks) {
|
||||
char *chunkEnd = strchr(chunkVal, '\n');
|
||||
if (chunkEnd == NULL) {
|
||||
chunkEnd = chunkVal + strlen(chunkVal);
|
||||
moreChunks = false;
|
||||
}
|
||||
int chunkOffset = chunkVal - val;
|
||||
int chunkLength = chunkEnd - chunkVal;
|
||||
int chunkEndOffset = chunkOffset + chunkLength;
|
||||
int thisStartHighlight = Platform::Maximum(startHighlight, chunkOffset);
|
||||
thisStartHighlight = Platform::Minimum(thisStartHighlight, chunkEndOffset);
|
||||
thisStartHighlight -= chunkOffset;
|
||||
int thisEndHighlight = Platform::Maximum(endHighlight, chunkOffset);
|
||||
thisEndHighlight = Platform::Minimum(thisEndHighlight, chunkEndOffset);
|
||||
thisEndHighlight -= chunkOffset;
|
||||
int x = 5;
|
||||
int xEnd = x + surfaceWindow->WidthText(font, chunkVal, thisStartHighlight);
|
||||
rcClient.left = x;
|
||||
rcClient.top = ytext - ascent - 1;
|
||||
rcClient.right = xEnd;
|
||||
surfaceWindow->DrawText(rcClient, font, ytext,
|
||||
chunkVal, thisStartHighlight,
|
||||
colourUnSel.allocated, colourBG.allocated);
|
||||
x = xEnd;
|
||||
|
||||
xEnd = x + surfaceWindow->WidthText(font, chunkVal + thisStartHighlight,
|
||||
thisEndHighlight - thisStartHighlight);
|
||||
rcClient.top = ytext;
|
||||
rcClient.left = x;
|
||||
rcClient.right = xEnd;
|
||||
surfaceWindow->DrawText(rcClient, font, ytext,
|
||||
chunkVal + thisStartHighlight, thisEndHighlight - thisStartHighlight,
|
||||
colourSel.allocated, colourBG.allocated);
|
||||
x = xEnd;
|
||||
|
||||
xEnd = x + surfaceWindow->WidthText(font, chunkVal + thisEndHighlight,
|
||||
chunkLength - thisEndHighlight);
|
||||
rcClient.left = x;
|
||||
rcClient.right = xEnd;
|
||||
surfaceWindow->DrawText(rcClient, font, ytext,
|
||||
chunkVal + thisEndHighlight, chunkLength - thisEndHighlight,
|
||||
colourUnSel.allocated, colourBG.allocated);
|
||||
chunkVal = chunkEnd + 1;
|
||||
ytext += lineHeight;
|
||||
}
|
||||
// Draw a raised border around the edges of the window
|
||||
surfaceWindow->MoveTo(0, rcClientSize.bottom - 1);
|
||||
surfaceWindow->PenColour(colourShade.allocated);
|
||||
surfaceWindow->LineTo(rcClientSize.right - 1, rcClientSize.bottom - 1);
|
||||
surfaceWindow->LineTo(rcClientSize.right - 1, 0);
|
||||
surfaceWindow->PenColour(colourLight.allocated);
|
||||
surfaceWindow->LineTo(0, 0);
|
||||
surfaceWindow->LineTo(0, rcClientSize.bottom - 1);
|
||||
}
|
||||
|
||||
PRectangle CallTip::CallTipStart(int pos, Point pt, const char *defn,
|
||||
const char *faceName, int size) {
|
||||
Surface surfaceMeasure;
|
||||
surfaceMeasure.Init();
|
||||
int deviceHeight = (size * surfaceMeasure.LogPixelsY()) / 72;
|
||||
font.Create(faceName, deviceHeight);
|
||||
if (val)
|
||||
delete []val;
|
||||
val = new char[strlen(defn) + 1];
|
||||
if (!val)
|
||||
return PRectangle();
|
||||
strcpy(val, defn);
|
||||
startHighlight = 0;
|
||||
endHighlight = 0;
|
||||
inCallTipMode = true;
|
||||
posStartCallTip = pos;
|
||||
// Look for multiple lines in the text
|
||||
// Only support \n here - simply means container must avoid \r!
|
||||
int width = 0;
|
||||
int numLines = 1;
|
||||
const char *newline;
|
||||
const char *look = val;
|
||||
while ((newline = strchr(look, '\n')) != NULL) {
|
||||
int thisWidth = surfaceMeasure.WidthText(font, look, newline - look);
|
||||
width = Platform::Maximum(width, thisWidth);
|
||||
look = newline + 1;
|
||||
numLines++;
|
||||
}
|
||||
int lastWidth = surfaceMeasure.WidthText(font, look, strlen(look));
|
||||
width = Platform::Maximum(width, lastWidth) + 10;
|
||||
int lineHeight = surfaceMeasure.Height(font);
|
||||
// Extra line for border and an empty line at top and bottom
|
||||
int height = lineHeight * numLines - surfaceMeasure.InternalLeading(font) + 2 + 2;
|
||||
return PRectangle(pt.x -5, pt.y + lineHeight + 1, pt.x + width - 5, pt.y + lineHeight + 1 + height);
|
||||
}
|
||||
|
||||
|
||||
void CallTip::CallTipCancel() {
|
||||
inCallTipMode = false;
|
||||
if (wCallTip.Created()) {
|
||||
wCallTip.Destroy();
|
||||
}
|
||||
}
|
||||
|
||||
void CallTip::SetHighlight(int start, int end) {
|
||||
// Avoid flashing by checking something has really changed
|
||||
if ((start != startHighlight) || (end != endHighlight)) {
|
||||
startHighlight = start;
|
||||
endHighlight = end;
|
||||
if (wCallTip.Created()) {
|
||||
wCallTip.InvalidateAll();
|
||||
}
|
||||
}
|
||||
}
|
46
contrib/src/stc/scintilla/src/CallTip.h
Normal file
46
contrib/src/stc/scintilla/src/CallTip.h
Normal file
@@ -0,0 +1,46 @@
|
||||
// Scintilla source code edit control
|
||||
// CallTip.h - interface to the call tip control
|
||||
// Copyright 1998-2000 by Neil Hodgson <neilh@scintilla.org>
|
||||
// The License.txt file describes the conditions under which this software may be distributed.
|
||||
|
||||
#ifndef CALLTIP_H
|
||||
#define CALLTIP_H
|
||||
|
||||
const char callClassName[] = "CallTip";
|
||||
|
||||
class CallTip {
|
||||
int startHighlight;
|
||||
int endHighlight;
|
||||
char *val;
|
||||
Font font;
|
||||
public:
|
||||
Window wCallTip;
|
||||
Window wDraw;
|
||||
bool inCallTipMode;
|
||||
int posStartCallTip;
|
||||
ColourPair colourBG;
|
||||
ColourPair colourUnSel;
|
||||
ColourPair colourSel;
|
||||
ColourPair colourShade;
|
||||
ColourPair colourLight;
|
||||
|
||||
CallTip();
|
||||
~CallTip();
|
||||
|
||||
// Claim or accept palette entries for the colours required to paint a calltip
|
||||
void RefreshColourPalette(Palette &pal, bool want);
|
||||
|
||||
void PaintCT(Surface *surfaceWindow);
|
||||
|
||||
// Setup the calltip and return a rectangle of the area required
|
||||
PRectangle CallTipStart(int pos, Point pt, const char *defn,
|
||||
const char *faceName, int size);
|
||||
|
||||
void CallTipCancel();
|
||||
|
||||
// Set a range of characters to be displayed in a highlight style.
|
||||
// Commonly used to highlight the current parameter.
|
||||
void SetHighlight(int start, int end);
|
||||
};
|
||||
|
||||
#endif
|
950
contrib/src/stc/scintilla/src/CellBuffer.cxx
Normal file
950
contrib/src/stc/scintilla/src/CellBuffer.cxx
Normal file
@@ -0,0 +1,950 @@
|
||||
// Scintilla source code edit control
|
||||
// CellBuffer.cxx - manages a buffer of cells
|
||||
// Copyright 1998-2000 by Neil Hodgson <neilh@scintilla.org>
|
||||
// The License.txt file describes the conditions under which this software may be distributed.
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "Platform.h"
|
||||
|
||||
#include "Scintilla.h"
|
||||
#include "SVector.h"
|
||||
#include "CellBuffer.h"
|
||||
|
||||
MarkerHandleSet::MarkerHandleSet() {
|
||||
root = 0;
|
||||
}
|
||||
|
||||
MarkerHandleSet::~MarkerHandleSet() {
|
||||
MarkerHandleNumber *mhn = root;
|
||||
while (mhn) {
|
||||
MarkerHandleNumber *mhnToFree = mhn;
|
||||
mhn = mhn->next;
|
||||
delete mhnToFree;
|
||||
}
|
||||
root = 0;
|
||||
}
|
||||
|
||||
int MarkerHandleSet::Length() {
|
||||
int c = 0;
|
||||
MarkerHandleNumber *mhn = root;
|
||||
while (mhn) {
|
||||
c++;
|
||||
mhn = mhn->next;
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
int MarkerHandleSet::NumberFromHandle(int handle) {
|
||||
MarkerHandleNumber *mhn = root;
|
||||
while (mhn) {
|
||||
if (mhn->handle == handle) {
|
||||
return mhn->number;
|
||||
}
|
||||
mhn = mhn->next;
|
||||
}
|
||||
return - 1;
|
||||
}
|
||||
|
||||
int MarkerHandleSet::MarkValue() {
|
||||
unsigned int m = 0;
|
||||
MarkerHandleNumber *mhn = root;
|
||||
while (mhn) {
|
||||
m |= (1 << mhn->number);
|
||||
mhn = mhn->next;
|
||||
}
|
||||
return m;
|
||||
}
|
||||
|
||||
bool MarkerHandleSet::Contains(int handle) {
|
||||
MarkerHandleNumber *mhn = root;
|
||||
while (mhn) {
|
||||
if (mhn->handle == handle) {
|
||||
return true;
|
||||
}
|
||||
mhn = mhn->next;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool MarkerHandleSet::InsertHandle(int handle, int markerNum) {
|
||||
MarkerHandleNumber *mhn = new MarkerHandleNumber;
|
||||
if (!mhn)
|
||||
return false;
|
||||
mhn->handle = handle;
|
||||
mhn->number = markerNum;
|
||||
mhn->next = root;
|
||||
root = mhn;
|
||||
return true;
|
||||
}
|
||||
|
||||
void MarkerHandleSet::RemoveHandle(int handle) {
|
||||
MarkerHandleNumber **pmhn = &root;
|
||||
while (*pmhn) {
|
||||
MarkerHandleNumber *mhn = *pmhn;
|
||||
if (mhn->handle == handle) {
|
||||
*pmhn = mhn->next;
|
||||
delete mhn;
|
||||
return;
|
||||
}
|
||||
pmhn = &((*pmhn)->next);
|
||||
}
|
||||
}
|
||||
|
||||
void MarkerHandleSet::RemoveNumber(int markerNum) {
|
||||
MarkerHandleNumber **pmhn = &root;
|
||||
while (*pmhn) {
|
||||
MarkerHandleNumber *mhn = *pmhn;
|
||||
if (mhn->number == markerNum) {
|
||||
*pmhn = mhn->next;
|
||||
delete mhn;
|
||||
return;
|
||||
}
|
||||
pmhn = &((*pmhn)->next);
|
||||
}
|
||||
}
|
||||
|
||||
void MarkerHandleSet::CombineWith(MarkerHandleSet *other) {
|
||||
MarkerHandleNumber **pmhn = &root;
|
||||
while (*pmhn) {
|
||||
pmhn = &((*pmhn)->next);
|
||||
}
|
||||
*pmhn = other->root;
|
||||
other->root = 0;
|
||||
}
|
||||
|
||||
LineVector::LineVector() {
|
||||
linesData = 0;
|
||||
lines = 0;
|
||||
levels = 0;
|
||||
Init();
|
||||
}
|
||||
|
||||
LineVector::~LineVector() {
|
||||
for (int line = 0; line < lines; line++) {
|
||||
delete linesData[line].handleSet;
|
||||
linesData[line].handleSet = 0;
|
||||
}
|
||||
delete []linesData;
|
||||
linesData = 0;
|
||||
delete []levels;
|
||||
levels = 0;
|
||||
}
|
||||
|
||||
void LineVector::Init() {
|
||||
for (int line = 0; line < lines; line++) {
|
||||
delete linesData[line].handleSet;
|
||||
linesData[line].handleSet = 0;
|
||||
}
|
||||
delete []linesData;
|
||||
linesData = new LineData[static_cast<int>(growSize)];
|
||||
size = growSize;
|
||||
lines = 1;
|
||||
delete []levels;
|
||||
levels = 0;
|
||||
sizeLevels = 0;
|
||||
}
|
||||
|
||||
void LineVector::Expand(int sizeNew) {
|
||||
LineData *linesDataNew = new LineData[sizeNew];
|
||||
if (linesDataNew) {
|
||||
for (int i = 0; i < size; i++)
|
||||
linesDataNew[i] = linesData[i];
|
||||
// Do not delete handleSets here as they are transferred to new linesData
|
||||
delete []linesData;
|
||||
linesData = linesDataNew;
|
||||
size = sizeNew;
|
||||
} else {
|
||||
Platform::DebugPrintf("No memory available\n");
|
||||
// TODO: Blow up
|
||||
}
|
||||
}
|
||||
|
||||
void LineVector::ExpandLevels(int sizeNew) {
|
||||
if (sizeNew == -1)
|
||||
sizeNew = size;
|
||||
int *levelsNew = new int[sizeNew];
|
||||
if (levelsNew) {
|
||||
int i = 0;
|
||||
for (; i < sizeLevels; i++)
|
||||
levelsNew[i] = levels[i];
|
||||
for (; i < sizeNew; i++)
|
||||
levelsNew[i] = SC_FOLDLEVELBASE;
|
||||
delete []levels;
|
||||
levels = levelsNew;
|
||||
sizeLevels = sizeNew;
|
||||
} else {
|
||||
Platform::DebugPrintf("No memory available\n");
|
||||
// TODO: Blow up
|
||||
}
|
||||
}
|
||||
|
||||
void LineVector::InsertValue(int pos, int value) {
|
||||
//Platform::DebugPrintf("InsertValue[%d] = %d\n", pos, value);
|
||||
if ((lines + 2) >= size) {
|
||||
Expand(size + growSize);
|
||||
if (levels) {
|
||||
ExpandLevels(size + growSize);
|
||||
}
|
||||
}
|
||||
lines++;
|
||||
for (int i = lines + 1; i > pos; i--) {
|
||||
linesData[i] = linesData[i - 1];
|
||||
}
|
||||
linesData[pos].startPosition = value;
|
||||
linesData[pos].handleSet = 0;
|
||||
}
|
||||
|
||||
void LineVector::SetValue(int pos, int value) {
|
||||
//Platform::DebugPrintf("SetValue[%d] = %d\n", pos, value);
|
||||
if ((pos + 2) >= size) {
|
||||
//Platform::DebugPrintf("Resize %d %d\n", size,pos);
|
||||
Expand(pos + growSize);
|
||||
//Platform::DebugPrintf("end Resize %d %d\n", size,pos);
|
||||
lines = pos;
|
||||
if (levels) {
|
||||
ExpandLevels(pos + growSize);
|
||||
}
|
||||
}
|
||||
linesData[pos].startPosition = value;
|
||||
}
|
||||
|
||||
void LineVector::Remove(int pos) {
|
||||
//Platform::DebugPrintf("Remove %d\n", pos);
|
||||
// Retain the markers from the deleted line by oring them into the previous line
|
||||
if (pos > 0) {
|
||||
MergeMarkers(pos - 1);
|
||||
}
|
||||
for (int i = pos; i < lines; i++) {
|
||||
linesData[i] = linesData[i + 1];
|
||||
}
|
||||
lines--;
|
||||
}
|
||||
|
||||
int LineVector::LineFromPosition(int pos) {
|
||||
//Platform::DebugPrintf("LineFromPostion %d lines=%d end = %d\n", pos, lines, linesData[lines].startPosition);
|
||||
if (lines == 0)
|
||||
return 0;
|
||||
//Platform::DebugPrintf("LineFromPosition %d\n", pos);
|
||||
if (pos >= linesData[lines].startPosition)
|
||||
return lines - 1;
|
||||
int lower = 0;
|
||||
int upper = lines;
|
||||
int middle = 0;
|
||||
do {
|
||||
middle = (upper + lower + 1) / 2; // Round high
|
||||
if (pos < linesData[middle].startPosition) {
|
||||
upper = middle - 1;
|
||||
} else {
|
||||
lower = middle;
|
||||
}
|
||||
} while (lower < upper);
|
||||
//Platform::DebugPrintf("LineFromPostion %d %d %d\n", pos, lower, linesData[lower].startPosition, linesData[lower > 1 ? lower - 1 : 0].startPosition);
|
||||
return lower;
|
||||
}
|
||||
|
||||
int LineVector::AddMark(int line, int markerNum) {
|
||||
handleCurrent++;
|
||||
if (!linesData[line].handleSet) {
|
||||
// Need new structure to hold marker handle
|
||||
linesData[line].handleSet = new MarkerHandleSet;
|
||||
if (!linesData[line].handleSet)
|
||||
return - 1;
|
||||
}
|
||||
linesData[line].handleSet->InsertHandle(handleCurrent, markerNum);
|
||||
|
||||
return handleCurrent;
|
||||
}
|
||||
|
||||
void LineVector::MergeMarkers(int pos) {
|
||||
if (linesData[pos].handleSet || linesData[pos + 1].handleSet) {
|
||||
if (linesData[pos].handleSet && linesData[pos + 1].handleSet) {
|
||||
linesData[pos].handleSet->CombineWith(linesData[pos].handleSet);
|
||||
linesData[pos].handleSet = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LineVector::DeleteMark(int line, int markerNum) {
|
||||
if (linesData[line].handleSet) {
|
||||
if (markerNum == -1) {
|
||||
delete linesData[line].handleSet;
|
||||
linesData[line].handleSet = 0;
|
||||
} else {
|
||||
linesData[line].handleSet->RemoveNumber(markerNum);
|
||||
if (linesData[line].handleSet->Length() == 0) {
|
||||
delete linesData[line].handleSet;
|
||||
linesData[line].handleSet = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LineVector::DeleteMarkFromHandle(int markerHandle) {
|
||||
int line = LineFromHandle(markerHandle);
|
||||
if (line >= 0) {
|
||||
linesData[line].handleSet->RemoveHandle(markerHandle);
|
||||
if (linesData[line].handleSet->Length() == 0) {
|
||||
delete linesData[line].handleSet;
|
||||
linesData[line].handleSet = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int LineVector::LineFromHandle(int markerHandle) {
|
||||
for (int line = 0; line < lines; line++) {
|
||||
if (linesData[line].handleSet) {
|
||||
if (linesData[line].handleSet->Contains(markerHandle)) {
|
||||
return line;
|
||||
}
|
||||
}
|
||||
}
|
||||
return - 1;
|
||||
}
|
||||
|
||||
Action::Action() {
|
||||
at = startAction;
|
||||
position = 0;
|
||||
data = 0;
|
||||
lenData = 0;
|
||||
}
|
||||
|
||||
Action::~Action() {
|
||||
Destroy();
|
||||
}
|
||||
|
||||
void Action::Create(actionType at_, int position_, char *data_, int lenData_) {
|
||||
delete []data;
|
||||
position = position_;
|
||||
at = at_;
|
||||
data = data_;
|
||||
lenData = lenData_;
|
||||
}
|
||||
|
||||
void Action::Destroy() {
|
||||
delete []data;
|
||||
data = 0;
|
||||
}
|
||||
|
||||
void Action::Grab(Action *source) {
|
||||
delete []data;
|
||||
|
||||
position = source->position;
|
||||
at = source->at;
|
||||
data = source->data;
|
||||
lenData = source->lenData;
|
||||
|
||||
// Ownership of source data transferred to this
|
||||
source->position = 0;
|
||||
source->at = startAction;
|
||||
source->data = 0;
|
||||
source->lenData = 0;
|
||||
}
|
||||
|
||||
CellBuffer::CellBuffer(int initialLength) {
|
||||
body = new char[initialLength];
|
||||
size = initialLength;
|
||||
length = 0;
|
||||
part1len = 0;
|
||||
gaplen = initialLength;
|
||||
part2body = body + gaplen;
|
||||
readOnly = false;
|
||||
|
||||
lenActions = 100;
|
||||
actions = new Action[lenActions];
|
||||
maxAction = 0;
|
||||
currentAction = 0;
|
||||
collectingUndo = undoCollectAutoStart;
|
||||
undoSequenceDepth = 0;
|
||||
savePoint = 0;
|
||||
|
||||
actions[currentAction].Create(startAction);
|
||||
}
|
||||
|
||||
CellBuffer::~CellBuffer() {
|
||||
delete []body;
|
||||
body = 0;
|
||||
delete []actions;
|
||||
actions = 0;
|
||||
}
|
||||
|
||||
void CellBuffer::GapTo(int position) {
|
||||
if (position == part1len)
|
||||
return;
|
||||
if (position < part1len) {
|
||||
int diff = part1len - position;
|
||||
//Platform::DebugPrintf("Move gap backwards to %d diff = %d part1len=%d length=%d \n", position,diff, part1len, length);
|
||||
for (int i = 0; i < diff; i++)
|
||||
body[part1len + gaplen - i - 1] = body[part1len - i - 1];
|
||||
} else { // position > part1len
|
||||
int diff = position - part1len;
|
||||
//Platform::DebugPrintf("Move gap forwards to %d diff =%d\n", position,diff);
|
||||
for (int i = 0; i < diff; i++)
|
||||
body[part1len + i] = body[part1len + gaplen + i];
|
||||
}
|
||||
part1len = position;
|
||||
part2body = body + gaplen;
|
||||
}
|
||||
|
||||
void CellBuffer::RoomFor(int insertionLength) {
|
||||
//Platform::DebugPrintf("need room %d %d\n", gaplen, insertionLength);
|
||||
if (gaplen <= insertionLength) {
|
||||
//Platform::DebugPrintf("need room %d %d\n", gaplen, insertionLength);
|
||||
GapTo(length);
|
||||
int newSize = size + insertionLength + 4000;
|
||||
//Platform::DebugPrintf("moved gap %d\n", newSize);
|
||||
char *newBody = new char[newSize];
|
||||
memcpy(newBody, body, size);
|
||||
delete []body;
|
||||
body = newBody;
|
||||
gaplen += newSize - size;
|
||||
part2body = body + gaplen;
|
||||
size = newSize;
|
||||
//Platform::DebugPrintf("end need room %d %d - size=%d length=%d\n", gaplen, insertionLength,size,length);
|
||||
}
|
||||
}
|
||||
|
||||
// To make it easier to write code that uses ByteAt, a position outside the range of the buffer
|
||||
// can be retrieved. All characters outside the range have the value '\0'.
|
||||
char CellBuffer::ByteAt(int position) {
|
||||
if (position < part1len) {
|
||||
if (position < 0) {
|
||||
return '\0';
|
||||
} else {
|
||||
return body[position];
|
||||
}
|
||||
} else {
|
||||
if (position >= length) {
|
||||
return '\0';
|
||||
} else {
|
||||
return part2body[position];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CellBuffer::SetByteAt(int position, char ch) {
|
||||
|
||||
if (position < 0) {
|
||||
//Platform::DebugPrintf("Bad position %d\n",position);
|
||||
return;
|
||||
}
|
||||
if (position >= length + 11) {
|
||||
Platform::DebugPrintf("Very Bad position %d of %d\n", position, length);
|
||||
//exit(2);
|
||||
return;
|
||||
}
|
||||
if (position >= length) {
|
||||
//Platform::DebugPrintf("Bad position %d of %d\n",position,length);
|
||||
return;
|
||||
}
|
||||
|
||||
if (position < part1len) {
|
||||
body[position] = ch;
|
||||
} else {
|
||||
part2body[position] = ch;
|
||||
}
|
||||
}
|
||||
|
||||
char CellBuffer::CharAt(int position) {
|
||||
return ByteAt(position*2);
|
||||
}
|
||||
|
||||
void CellBuffer::GetCharRange(char *buffer, int position, int lengthRetrieve) {
|
||||
if (lengthRetrieve < 0)
|
||||
return;
|
||||
if (position < 0)
|
||||
return;
|
||||
int bytePos = position * 2;
|
||||
if ((bytePos + lengthRetrieve * 2) > length) {
|
||||
Platform::DebugPrintf("Bad GetCharRange %d for %d of %d\n",bytePos,
|
||||
lengthRetrieve, length);
|
||||
return;
|
||||
}
|
||||
GapTo(0); // Move the buffer so its easy to subscript into it
|
||||
char *pb = part2body + bytePos;
|
||||
while (lengthRetrieve--) {
|
||||
*buffer++ = *pb;
|
||||
pb +=2;
|
||||
}
|
||||
}
|
||||
|
||||
char CellBuffer::StyleAt(int position) {
|
||||
return ByteAt(position*2 + 1);
|
||||
}
|
||||
|
||||
const char *CellBuffer::InsertString(int position, char *s, int insertLength) {
|
||||
char *data = 0;
|
||||
// InsertString and DeleteChars are the bottleneck though which all changes occur
|
||||
if (!readOnly) {
|
||||
if (collectingUndo) {
|
||||
// Save into the undo/redo stack, but only the characters - not the formatting
|
||||
// This takes up about half load time
|
||||
data = new char[insertLength / 2];
|
||||
for (int i = 0; i < insertLength / 2; i++) {
|
||||
data[i] = s[i * 2];
|
||||
}
|
||||
AppendAction(insertAction, position, data, insertLength / 2);
|
||||
}
|
||||
|
||||
BasicInsertString(position, s, insertLength);
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
void CellBuffer::InsertCharStyle(int position, char ch, char style) {
|
||||
char s[2];
|
||||
s[0] = ch;
|
||||
s[1] = style;
|
||||
InsertString(position*2, s, 2);
|
||||
}
|
||||
|
||||
bool CellBuffer::SetStyleAt(int position, char style, char mask) {
|
||||
char curVal = ByteAt(position*2 + 1);
|
||||
if ((curVal & mask) != style) {
|
||||
SetByteAt(position*2 + 1, (curVal & ~mask) | style);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool CellBuffer::SetStyleFor(int position, int lengthStyle, char style, char mask) {
|
||||
int bytePos = position * 2 + 1;
|
||||
bool changed = false;
|
||||
while (lengthStyle--) {
|
||||
char curVal = ByteAt(bytePos);
|
||||
if ((curVal & mask) != style) {
|
||||
SetByteAt(bytePos, (curVal & ~mask) | style);
|
||||
changed = true;
|
||||
}
|
||||
bytePos += 2;
|
||||
}
|
||||
return changed;
|
||||
}
|
||||
|
||||
void CellBuffer::EnsureUndoRoom() {
|
||||
//Platform::DebugPrintf("%% %d action %d %d %d\n", at, position, length, currentAction);
|
||||
if (currentAction >= 2) {
|
||||
// Have to test that there is room for 2 more actions in the array
|
||||
// as two actions may be created by this function
|
||||
if (currentAction >= (lenActions - 2)) {
|
||||
// Run out of undo nodes so extend the array
|
||||
int lenActionsNew = lenActions * 2;
|
||||
Action *actionsNew = new Action[lenActionsNew];
|
||||
if (!actionsNew)
|
||||
return;
|
||||
for (int act = 0; act <= currentAction; act++)
|
||||
actionsNew[act].Grab(&actions[act]);
|
||||
delete []actions;
|
||||
lenActions = lenActionsNew;
|
||||
actions = actionsNew;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CellBuffer::AppendAction(actionType at, int position, char *data, int lengthData) {
|
||||
EnsureUndoRoom();
|
||||
//Platform::DebugPrintf("%% %d action %d %d %d\n", at, position, lengthData, currentAction);
|
||||
if (currentAction >= 2) {
|
||||
// See if current action can be coalesced into previous action
|
||||
// Will work if both are inserts or deletes and position is same or two different
|
||||
if ((at != actions[currentAction - 1].at) || (abs(position - actions[currentAction - 1].position) > 2)) {
|
||||
currentAction++;
|
||||
} else if (currentAction == savePoint) {
|
||||
currentAction++;
|
||||
}
|
||||
} else {
|
||||
currentAction++;
|
||||
}
|
||||
actions[currentAction].Create(at, position, data, lengthData);
|
||||
if ((collectingUndo == undoCollectAutoStart) && (0 == undoSequenceDepth)) {
|
||||
currentAction++;
|
||||
actions[currentAction].Create(startAction);
|
||||
}
|
||||
maxAction = currentAction;
|
||||
}
|
||||
|
||||
const char *CellBuffer::DeleteChars(int position, int deleteLength) {
|
||||
// InsertString and DeleteChars are the bottleneck though which all changes occur
|
||||
char *data = 0;
|
||||
if (!readOnly) {
|
||||
if (collectingUndo) {
|
||||
// Save into the undo/redo stack, but only the characters - not the formatting
|
||||
data = new char[deleteLength / 2];
|
||||
for (int i = 0; i < deleteLength / 2; i++) {
|
||||
data[i] = ByteAt(position + i * 2);
|
||||
}
|
||||
AppendAction(removeAction, position, data, deleteLength / 2);
|
||||
}
|
||||
|
||||
BasicDeleteChars(position, deleteLength);
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
int CellBuffer::ByteLength() {
|
||||
return length;
|
||||
}
|
||||
|
||||
int CellBuffer::Length() {
|
||||
return ByteLength() / 2;
|
||||
}
|
||||
|
||||
int CellBuffer::Lines() {
|
||||
//Platform::DebugPrintf("Lines = %d\n", lv.lines);
|
||||
return lv.lines;
|
||||
}
|
||||
|
||||
int CellBuffer::LineStart(int line) {
|
||||
if (line < 0)
|
||||
return 0;
|
||||
else if (line > lv.lines)
|
||||
return length;
|
||||
else
|
||||
return lv.linesData[line].startPosition;
|
||||
}
|
||||
|
||||
bool CellBuffer::IsReadOnly() {
|
||||
return readOnly;
|
||||
}
|
||||
|
||||
void CellBuffer::SetReadOnly(bool set) {
|
||||
readOnly = set;
|
||||
}
|
||||
|
||||
void CellBuffer::SetSavePoint() {
|
||||
savePoint = currentAction;
|
||||
}
|
||||
|
||||
bool CellBuffer::IsSavePoint() {
|
||||
return savePoint == currentAction;
|
||||
}
|
||||
|
||||
int CellBuffer::AddMark(int line, int markerNum) {
|
||||
if ((line >= 0) && (line < lv.lines)) {
|
||||
return lv.AddMark(line, markerNum);
|
||||
}
|
||||
return - 1;
|
||||
}
|
||||
|
||||
void CellBuffer::DeleteMark(int line, int markerNum) {
|
||||
if ((line >= 0) && (line < lv.lines)) {
|
||||
lv.DeleteMark(line, markerNum);
|
||||
}
|
||||
}
|
||||
|
||||
void CellBuffer::DeleteMarkFromHandle(int markerHandle) {
|
||||
lv.DeleteMarkFromHandle(markerHandle);
|
||||
}
|
||||
|
||||
int CellBuffer::GetMark(int line) {
|
||||
if ((line >= 0) && (line < lv.lines) && (lv.linesData[line].handleSet))
|
||||
return lv.linesData[line].handleSet->MarkValue();
|
||||
return 0;
|
||||
}
|
||||
|
||||
void CellBuffer::DeleteAllMarks(int markerNum) {
|
||||
for (int line = 0; line < lv.lines; line++) {
|
||||
lv.DeleteMark(line, markerNum);
|
||||
}
|
||||
}
|
||||
|
||||
int CellBuffer::LineFromHandle(int markerHandle) {
|
||||
return lv.LineFromHandle(markerHandle);
|
||||
}
|
||||
|
||||
// Without undo
|
||||
|
||||
void CellBuffer::BasicInsertString(int position, char *s, int insertLength) {
|
||||
//Platform::DebugPrintf("Inserting at %d for %d\n", position, insertLength);
|
||||
if (insertLength == 0)
|
||||
return;
|
||||
RoomFor(insertLength);
|
||||
GapTo(position);
|
||||
|
||||
memcpy(body + part1len, s, insertLength);
|
||||
length += insertLength;
|
||||
part1len += insertLength;
|
||||
gaplen -= insertLength;
|
||||
part2body = body + gaplen;
|
||||
|
||||
int lineInsert = lv.LineFromPosition(position / 2) + 1;
|
||||
// Point all the lines after the insertion point further along in the buffer
|
||||
for (int lineAfter = lineInsert; lineAfter <= lv.lines; lineAfter++) {
|
||||
lv.linesData[lineAfter].startPosition += insertLength / 2;
|
||||
}
|
||||
char chPrev = ' ';
|
||||
if ((position - 2) >= 0)
|
||||
chPrev = ByteAt(position - 2);
|
||||
char chAfter = ' ';
|
||||
if ((position + insertLength) < length)
|
||||
chAfter = ByteAt(position + insertLength);
|
||||
if (chPrev == '\r' && chAfter == '\n') {
|
||||
//Platform::DebugPrintf("Splitting a crlf pair at %d\n", lineInsert);
|
||||
// Splitting up a crlf pair at position
|
||||
lv.InsertValue(lineInsert, position / 2);
|
||||
lineInsert++;
|
||||
}
|
||||
char ch = ' ';
|
||||
for (int i = 0; i < insertLength; i += 2) {
|
||||
ch = s[i];
|
||||
if (ch == '\r') {
|
||||
//Platform::DebugPrintf("Inserting cr at %d\n", lineInsert);
|
||||
lv.InsertValue(lineInsert, (position + i) / 2 + 1);
|
||||
lineInsert++;
|
||||
} else if (ch == '\n') {
|
||||
if (chPrev == '\r') {
|
||||
//Platform::DebugPrintf("Patching cr before lf at %d\n", lineInsert-1);
|
||||
// Patch up what was end of line
|
||||
lv.SetValue(lineInsert - 1, (position + i) / 2 + 1);
|
||||
} else {
|
||||
//Platform::DebugPrintf("Inserting lf at %d\n", lineInsert);
|
||||
lv.InsertValue(lineInsert, (position + i) / 2 + 1);
|
||||
lineInsert++;
|
||||
}
|
||||
}
|
||||
chPrev = ch;
|
||||
}
|
||||
// Joining two lines where last insertion is cr and following text starts with lf
|
||||
if (chAfter == '\n') {
|
||||
if (ch == '\r') {
|
||||
//Platform::DebugPrintf("Joining cr before lf at %d\n", lineInsert-1);
|
||||
// End of line already in buffer so drop the newly created one
|
||||
lv.Remove(lineInsert - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CellBuffer::BasicDeleteChars(int position, int deleteLength) {
|
||||
//Platform::DebugPrintf("Deleting at %d for %d\n", position, deleteLength);
|
||||
if (deleteLength == 0)
|
||||
return;
|
||||
|
||||
if ((position == 0) && (deleteLength == length)) {
|
||||
// If whole buffer is being deleted, faster to reinitialise lines data
|
||||
// than to delete each line.
|
||||
//printf("Whole buffer being deleted\n");
|
||||
lv.Init();
|
||||
} else {
|
||||
// Have to fix up line positions before doing deletion as looking at text in buffer
|
||||
// to work out which lines have been removed
|
||||
|
||||
int lineRemove = lv.LineFromPosition(position / 2) + 1;
|
||||
// Point all the lines after the insertion point further along in the buffer
|
||||
for (int lineAfter = lineRemove; lineAfter <= lv.lines; lineAfter++) {
|
||||
lv.linesData[lineAfter].startPosition -= deleteLength / 2;
|
||||
}
|
||||
char chPrev = ' ';
|
||||
if (position >= 2)
|
||||
chPrev = ByteAt(position - 2);
|
||||
char chBefore = chPrev;
|
||||
char chNext = ' ';
|
||||
if (position < length)
|
||||
chNext = ByteAt(position);
|
||||
bool ignoreNL = false;
|
||||
if (chPrev == '\r' && chNext == '\n') {
|
||||
//Platform::DebugPrintf("Deleting lf after cr, move line end to cr at %d\n", lineRemove);
|
||||
// Move back one
|
||||
lv.SetValue(lineRemove, position / 2);
|
||||
lineRemove++;
|
||||
ignoreNL = true; // First \n is not real deletion
|
||||
}
|
||||
|
||||
char ch = chNext;
|
||||
for (int i = 0; i < deleteLength; i += 2) {
|
||||
chNext = ' ';
|
||||
if ((position + i + 2) < length)
|
||||
chNext = ByteAt(position + i + 2);
|
||||
//Platform::DebugPrintf("Deleting %d %x\n", i, ch);
|
||||
if (ch == '\r') {
|
||||
if (chNext != '\n') {
|
||||
//Platform::DebugPrintf("Removing cr end of line\n");
|
||||
lv.Remove(lineRemove);
|
||||
}
|
||||
} else if ((ch == '\n') && !ignoreNL) {
|
||||
//Platform::DebugPrintf("Removing lf end of line\n");
|
||||
lv.Remove(lineRemove);
|
||||
ignoreNL = false; // Further \n are not real deletions
|
||||
}
|
||||
|
||||
ch = chNext;
|
||||
}
|
||||
// May have to fix up end if last deletion causes cr to be next to lf
|
||||
// or removes one of a crlf pair
|
||||
char chAfter = ' ';
|
||||
if ((position + deleteLength) < length)
|
||||
chAfter = ByteAt(position + deleteLength);
|
||||
if (chBefore == '\r' && chAfter == '\n') {
|
||||
//d.printf("Joining cr before lf at %d\n", lineRemove);
|
||||
// Using lineRemove-1 as cr ended line before start of deletion
|
||||
lv.Remove(lineRemove - 1);
|
||||
lv.SetValue(lineRemove - 1, position / 2 + 1);
|
||||
}
|
||||
}
|
||||
GapTo(position);
|
||||
length -= deleteLength;
|
||||
gaplen += deleteLength;
|
||||
part2body = body + gaplen;
|
||||
}
|
||||
|
||||
undoCollectionType CellBuffer::SetUndoCollection(undoCollectionType collectUndo) {
|
||||
collectingUndo = collectUndo;
|
||||
undoSequenceDepth = 0;
|
||||
return collectingUndo;
|
||||
}
|
||||
|
||||
bool CellBuffer::IsCollectingUndo() {
|
||||
return collectingUndo;
|
||||
}
|
||||
|
||||
void CellBuffer::AppendUndoStartAction() {
|
||||
EnsureUndoRoom();
|
||||
// Finish any currently active undo sequence
|
||||
undoSequenceDepth = 0;
|
||||
if (actions[currentAction].at != startAction) {
|
||||
undoSequenceDepth++;
|
||||
currentAction++;
|
||||
actions[currentAction].Create(startAction);
|
||||
maxAction = currentAction;
|
||||
}
|
||||
}
|
||||
|
||||
void CellBuffer::BeginUndoAction() {
|
||||
EnsureUndoRoom();
|
||||
if (undoSequenceDepth == 0) {
|
||||
if (actions[currentAction].at != startAction) {
|
||||
currentAction++;
|
||||
actions[currentAction].Create(startAction);
|
||||
maxAction = currentAction;
|
||||
}
|
||||
}
|
||||
undoSequenceDepth++;
|
||||
}
|
||||
|
||||
void CellBuffer::EndUndoAction() {
|
||||
EnsureUndoRoom();
|
||||
undoSequenceDepth--;
|
||||
if (0 == undoSequenceDepth) {
|
||||
if (actions[currentAction].at != startAction) {
|
||||
currentAction++;
|
||||
actions[currentAction].Create(startAction);
|
||||
maxAction = currentAction;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CellBuffer::DeleteUndoHistory() {
|
||||
for (int i = 1; i < maxAction; i++)
|
||||
actions[i].Destroy();
|
||||
maxAction = 0;
|
||||
currentAction = 0;
|
||||
savePoint = 0;
|
||||
}
|
||||
|
||||
bool CellBuffer::CanUndo() {
|
||||
return (!readOnly) && ((currentAction > 0) && (maxAction > 0));
|
||||
}
|
||||
|
||||
int CellBuffer::StartUndo() {
|
||||
// Drop any trailing startAction
|
||||
if (actions[currentAction].at == startAction && currentAction > 0)
|
||||
currentAction--;
|
||||
|
||||
// Count the steps in this action
|
||||
int act = currentAction;
|
||||
while (actions[act].at != startAction && act > 0) {
|
||||
act--;
|
||||
}
|
||||
return currentAction - act;
|
||||
}
|
||||
|
||||
const Action &CellBuffer::UndoStep() {
|
||||
const Action &actionStep = actions[currentAction];
|
||||
if (actionStep.at == insertAction) {
|
||||
BasicDeleteChars(actionStep.position, actionStep.lenData*2);
|
||||
} else if (actionStep.at == removeAction) {
|
||||
char *styledData = new char[actionStep.lenData * 2];
|
||||
for (int i = 0; i < actionStep.lenData; i++) {
|
||||
styledData[i*2] = actionStep.data[i];
|
||||
styledData[i*2+1] = 0;
|
||||
}
|
||||
BasicInsertString(actionStep.position, styledData, actionStep.lenData*2);
|
||||
delete []styledData;
|
||||
}
|
||||
currentAction--;
|
||||
return actionStep;
|
||||
}
|
||||
|
||||
bool CellBuffer::CanRedo() {
|
||||
return (!readOnly) && (maxAction > currentAction);
|
||||
}
|
||||
|
||||
int CellBuffer::StartRedo() {
|
||||
// Drop any leading startAction
|
||||
if (actions[currentAction].at == startAction && currentAction < maxAction)
|
||||
currentAction++;
|
||||
|
||||
// Count the steps in this action
|
||||
int act = currentAction;
|
||||
while (actions[act].at != startAction && act < maxAction) {
|
||||
act++;
|
||||
}
|
||||
return act - currentAction;
|
||||
}
|
||||
|
||||
const Action &CellBuffer::RedoStep() {
|
||||
const Action &actionStep = actions[currentAction];
|
||||
if (actionStep.at == insertAction) {
|
||||
char *styledData = new char[actionStep.lenData * 2];
|
||||
for (int i = 0; i < actionStep.lenData; i++) {
|
||||
styledData[i*2] = actionStep.data[i];
|
||||
styledData[i*2+1] = 0;
|
||||
}
|
||||
BasicInsertString(actionStep.position, styledData, actionStep.lenData*2);
|
||||
delete []styledData;
|
||||
} else if (actionStep.at == removeAction) {
|
||||
BasicDeleteChars(actionStep.position, actionStep.lenData*2);
|
||||
}
|
||||
currentAction++;
|
||||
return actionStep;
|
||||
}
|
||||
|
||||
int CellBuffer::SetLineState(int line, int state) {
|
||||
int stateOld = lineStates[line];
|
||||
lineStates[line] = state;
|
||||
return stateOld;
|
||||
}
|
||||
|
||||
int CellBuffer::GetLineState(int line) {
|
||||
return lineStates[line];
|
||||
}
|
||||
|
||||
int CellBuffer::GetMaxLineState() {
|
||||
return lineStates.Length();
|
||||
}
|
||||
|
||||
int CellBuffer::SetLevel(int line, int level) {
|
||||
int prev = 0;
|
||||
if ((line >= 0) && (line < lv.lines)) {
|
||||
if (!lv.levels) {
|
||||
lv.ExpandLevels();
|
||||
}
|
||||
prev = lv.levels[line];
|
||||
if (lv.levels[line] != level) {
|
||||
lv.levels[line] = level;
|
||||
}
|
||||
}
|
||||
return prev;
|
||||
}
|
||||
|
||||
int CellBuffer::GetLevel(int line) {
|
||||
if (lv.levels && (line >= 0) && (line < lv.lines)) {
|
||||
return lv.levels[line];
|
||||
} else {
|
||||
return SC_FOLDLEVELBASE;
|
||||
}
|
||||
}
|
||||
|
197
contrib/src/stc/scintilla/src/CellBuffer.h
Normal file
197
contrib/src/stc/scintilla/src/CellBuffer.h
Normal file
@@ -0,0 +1,197 @@
|
||||
// Scintilla source code edit control
|
||||
// CellBuffer.h - manages the text of the document
|
||||
// Copyright 1998-2000 by Neil Hodgson <neilh@scintilla.org>
|
||||
// The License.txt file describes the conditions under which this software may be distributed.
|
||||
|
||||
#ifndef CELLBUFFER_H
|
||||
#define CELLBUFFER_H
|
||||
|
||||
// This holds the marker identifier and the marker type to display.
|
||||
// MarkerHandleNumbers are members of lists.
|
||||
struct MarkerHandleNumber {
|
||||
int handle;
|
||||
int number;
|
||||
MarkerHandleNumber *next;
|
||||
};
|
||||
|
||||
// A marker handle set contains any number of MarkerHandleNumbers
|
||||
class MarkerHandleSet {
|
||||
MarkerHandleNumber *root;
|
||||
public:
|
||||
MarkerHandleSet();
|
||||
~MarkerHandleSet();
|
||||
int Length();
|
||||
int NumberFromHandle(int handle);
|
||||
int MarkValue(); // Bit set of marker numbers
|
||||
bool Contains(int handle);
|
||||
bool InsertHandle(int handle, int markerNum);
|
||||
void RemoveHandle(int handle);
|
||||
void RemoveNumber(int markerNum);
|
||||
void CombineWith(MarkerHandleSet *other);
|
||||
};
|
||||
|
||||
// Each line stores the starting position of the first character of the line in the cell buffer
|
||||
// and potentially a marker handle set. Often a line will not have any attached markers.
|
||||
struct LineData {
|
||||
int startPosition;
|
||||
MarkerHandleSet *handleSet;
|
||||
LineData() : startPosition(0), handleSet(0) {
|
||||
}
|
||||
};
|
||||
|
||||
// The line vector contains information about each of the lines in a cell buffer.
|
||||
class LineVector {
|
||||
public:
|
||||
enum { growSize = 4000 };
|
||||
int lines;
|
||||
LineData *linesData;
|
||||
int size;
|
||||
int *levels;
|
||||
int sizeLevels;
|
||||
|
||||
// Handles are allocated sequentially and should never have to be reused as 32 bit ints are very big.
|
||||
int handleCurrent;
|
||||
|
||||
LineVector();
|
||||
~LineVector();
|
||||
void Init();
|
||||
|
||||
void Expand(int sizeNew);
|
||||
void ExpandLevels(int sizeNew=-1);
|
||||
void InsertValue(int pos, int value);
|
||||
void SetValue(int pos, int value);
|
||||
void Remove(int pos);
|
||||
int LineFromPosition(int pos);
|
||||
|
||||
int AddMark(int line, int marker);
|
||||
void MergeMarkers(int pos);
|
||||
void DeleteMark(int line, int markerNum);
|
||||
void DeleteMarkFromHandle(int markerHandle);
|
||||
int LineFromHandle(int markerHandle);
|
||||
};
|
||||
|
||||
// Actions are used to store all the information required to perform one undo/redo step.
|
||||
enum actionType { insertAction, removeAction, startAction };
|
||||
|
||||
class Action {
|
||||
public:
|
||||
actionType at;
|
||||
int position;
|
||||
char *data;
|
||||
int lenData;
|
||||
|
||||
Action();
|
||||
~Action();
|
||||
void Create(actionType at_, int position_=0, char *data_=0, int lenData_=0);
|
||||
void Destroy();
|
||||
void Grab(Action *source);
|
||||
};
|
||||
|
||||
enum undoCollectionType { undoCollectNone, undoCollectAutoStart, undoCollectManualStart };
|
||||
|
||||
// Holder for an expandable array of characters that supports undo and line markers
|
||||
// Based on article "Data Structures in a Bit-Mapped Text Editor"
|
||||
// by Wilfred J. Hansen, Byte January 1987, page 183
|
||||
class CellBuffer {
|
||||
private:
|
||||
char *body;
|
||||
int size;
|
||||
int length;
|
||||
int part1len;
|
||||
int gaplen;
|
||||
char *part2body;
|
||||
bool readOnly;
|
||||
|
||||
Action *actions;
|
||||
int lenActions;
|
||||
int maxAction;
|
||||
int currentAction;
|
||||
undoCollectionType collectingUndo;
|
||||
int undoSequenceDepth;
|
||||
int savePoint;
|
||||
|
||||
LineVector lv;
|
||||
|
||||
SVector<int, 4000> lineStates;
|
||||
|
||||
void GapTo(int position);
|
||||
void RoomFor(int insertionLength);
|
||||
|
||||
void EnsureUndoRoom();
|
||||
void AppendAction(actionType at, int position, char *data, int length);
|
||||
|
||||
inline char ByteAt(int position);
|
||||
void SetByteAt(int position, char ch);
|
||||
|
||||
public:
|
||||
|
||||
CellBuffer(int initialLength = 4000);
|
||||
~CellBuffer();
|
||||
|
||||
// Retrieving positions outside the range of the buffer works and returns 0
|
||||
char CharAt(int position);
|
||||
void GetCharRange(char *buffer, int position, int lengthRetrieve);
|
||||
char StyleAt(int position);
|
||||
|
||||
int ByteLength();
|
||||
int Length();
|
||||
int Lines();
|
||||
int LineStart(int line);
|
||||
int LineFromPosition(int pos) { return lv.LineFromPosition(pos); }
|
||||
const char *InsertString(int position, char *s, int insertLength);
|
||||
void InsertCharStyle(int position, char ch, char style);
|
||||
|
||||
// Setting styles for positions outside the range of the buffer is safe and has no effect.
|
||||
// True is returned if the style of a character changed.
|
||||
bool SetStyleAt(int position, char style, char mask=(char)0xff);
|
||||
bool SetStyleFor(int position, int length, char style, char mask);
|
||||
|
||||
const char *DeleteChars(int position, int deleteLength);
|
||||
|
||||
bool IsReadOnly();
|
||||
void SetReadOnly(bool set);
|
||||
|
||||
// The save point is a marker in the undo stack where the container has stated that
|
||||
// the buffer was saved. Undo and redo can move over the save point.
|
||||
void SetSavePoint();
|
||||
bool IsSavePoint();
|
||||
|
||||
// Line marker functions
|
||||
int AddMark(int line, int markerNum);
|
||||
void DeleteMark(int line, int markerNum);
|
||||
void DeleteMarkFromHandle(int markerHandle);
|
||||
int GetMark(int line);
|
||||
void DeleteAllMarks(int markerNum);
|
||||
int LineFromHandle(int markerHandle);
|
||||
|
||||
// Without undo
|
||||
void BasicInsertString(int position, char *s, int insertLength);
|
||||
void BasicDeleteChars(int position, int deleteLength);
|
||||
|
||||
undoCollectionType SetUndoCollection(undoCollectionType collectUndo);
|
||||
bool IsCollectingUndo();
|
||||
void AppendUndoStartAction();
|
||||
void BeginUndoAction();
|
||||
void EndUndoAction();
|
||||
void DeleteUndoHistory();
|
||||
|
||||
// To perform an undo, StartUndo is called to retreive the number of steps, then UndoStep is
|
||||
// called that many times. Similarly for redo.
|
||||
bool CanUndo();
|
||||
int StartUndo();
|
||||
const Action &UndoStep();
|
||||
bool CanRedo();
|
||||
int StartRedo();
|
||||
const Action &RedoStep();
|
||||
|
||||
int SetLineState(int line, int state);
|
||||
int GetLineState(int line);
|
||||
int GetMaxLineState();
|
||||
|
||||
int SetLevel(int line, int level);
|
||||
int GetLevel(int line);
|
||||
};
|
||||
|
||||
#define CELL_SIZE 2
|
||||
|
||||
#endif
|
203
contrib/src/stc/scintilla/src/ContractionState.cxx
Normal file
203
contrib/src/stc/scintilla/src/ContractionState.cxx
Normal file
@@ -0,0 +1,203 @@
|
||||
// Scintilla source code edit control
|
||||
// ContractionState.cxx - manages visibility of lines for folding
|
||||
// Copyright 1998-2000 by Neil Hodgson <neilh@scintilla.org>
|
||||
// The License.txt file describes the conditions under which this software may be distributed.
|
||||
|
||||
#include "Platform.h"
|
||||
|
||||
#include "ContractionState.h"
|
||||
|
||||
OneLine::OneLine() {
|
||||
displayLine = 0;
|
||||
docLine = 0;
|
||||
visible = true;
|
||||
expanded = true;
|
||||
}
|
||||
|
||||
ContractionState::ContractionState() {
|
||||
lines = 0;
|
||||
size = 0;
|
||||
linesInDoc = 1;
|
||||
linesInDisplay = 1;
|
||||
valid = false;
|
||||
}
|
||||
|
||||
ContractionState::~ContractionState() {
|
||||
Clear();
|
||||
}
|
||||
|
||||
void ContractionState::MakeValid() const {
|
||||
if (!valid) {
|
||||
// Could be cleverer by keeping the index of the last still valid entry
|
||||
// rather than invalidating all.
|
||||
int linePrev = -1;
|
||||
int lineDisplay = 0;
|
||||
for (int line=0; line<linesInDoc; line++) {
|
||||
lines[line].displayLine = lineDisplay;
|
||||
if (lines[line].visible) {
|
||||
lines[lineDisplay].docLine = line;
|
||||
lineDisplay++;
|
||||
}
|
||||
}
|
||||
valid = true;
|
||||
}
|
||||
}
|
||||
|
||||
void ContractionState::Clear() {
|
||||
delete []lines;
|
||||
lines = 0;
|
||||
size = 0;
|
||||
linesInDoc = 1;
|
||||
linesInDisplay = 1;
|
||||
}
|
||||
|
||||
int ContractionState::LinesInDoc() const {
|
||||
return linesInDoc;
|
||||
}
|
||||
|
||||
int ContractionState::LinesDisplayed() const {
|
||||
return linesInDisplay;
|
||||
}
|
||||
|
||||
int ContractionState::DisplayFromDoc(int lineDoc) const {
|
||||
if (size == 0) {
|
||||
return lineDoc;
|
||||
}
|
||||
MakeValid();
|
||||
if ((lineDoc >= 0) && (lineDoc < linesInDoc)) {
|
||||
return lines[lineDoc].displayLine;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int ContractionState::DocFromDisplay(int lineDisplay) const {
|
||||
if (lineDisplay <= 0)
|
||||
return 0;
|
||||
if (lineDisplay >= linesInDisplay)
|
||||
return linesInDoc-1;
|
||||
if (size == 0)
|
||||
return lineDisplay;
|
||||
MakeValid();
|
||||
return lines[lineDisplay].docLine;
|
||||
}
|
||||
|
||||
void ContractionState::Grow(int sizeNew) {
|
||||
OneLine *linesNew = new OneLine[sizeNew];
|
||||
if (linesNew) {
|
||||
int i = 0;
|
||||
for (; i < size; i++) {
|
||||
linesNew[i] = lines[i];
|
||||
}
|
||||
for (; i < sizeNew; i++) {
|
||||
linesNew[i].displayLine = i;
|
||||
}
|
||||
delete []lines;
|
||||
lines = linesNew;
|
||||
size = sizeNew;
|
||||
valid = false;
|
||||
} else {
|
||||
Platform::DebugPrintf("No memory available\n");
|
||||
// TODO: Blow up
|
||||
}
|
||||
}
|
||||
|
||||
void ContractionState::InsertLines(int lineDoc, int lineCount) {
|
||||
if (size == 0) {
|
||||
linesInDoc += lineCount;
|
||||
linesInDisplay += lineCount;
|
||||
return;
|
||||
}
|
||||
//Platform::DebugPrintf("InsertLine[%d] = %d\n", lineDoc);
|
||||
if ((linesInDoc + 2) >= size) {
|
||||
Grow(size + growSize);
|
||||
}
|
||||
linesInDoc += lineCount;
|
||||
linesInDisplay += lineCount;
|
||||
for (int i = linesInDoc + 1; i >= lineDoc + lineCount; i--) {
|
||||
lines[i].visible = lines[i - lineCount].visible;
|
||||
lines[i].expanded = lines[i - lineCount].expanded;
|
||||
}
|
||||
for (int d=0;d<lineCount;d++) {
|
||||
lines[lineDoc+d].visible = true; // Should inherit visibility from context ?
|
||||
lines[lineDoc+d].expanded = true;
|
||||
}
|
||||
valid = false;
|
||||
}
|
||||
|
||||
void ContractionState::DeleteLines(int lineDoc, int lineCount) {
|
||||
if (size == 0) {
|
||||
linesInDoc -= lineCount;
|
||||
linesInDisplay -= lineCount;
|
||||
return;
|
||||
}
|
||||
int delta = 0;
|
||||
for (int d=0;d<lineCount;d++)
|
||||
if (lines[lineDoc+d].visible)
|
||||
delta--;
|
||||
for (int i = lineDoc; i < linesInDoc-lineCount; i++) {
|
||||
lines[i].visible = lines[i + lineCount].visible;
|
||||
lines[i].expanded = lines[i + lineCount].expanded;
|
||||
}
|
||||
linesInDoc -= lineCount;
|
||||
linesInDisplay += delta;
|
||||
valid = false;
|
||||
}
|
||||
|
||||
bool ContractionState::GetVisible(int lineDoc) const {
|
||||
if (size == 0)
|
||||
return true;
|
||||
if ((lineDoc >= 0) && (lineDoc < linesInDoc)) {
|
||||
return lines[lineDoc].visible;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool ContractionState::SetVisible(int lineDocStart, int lineDocEnd, bool visible) {
|
||||
if (size == 0) {
|
||||
Grow(lineDocEnd + growSize);
|
||||
}
|
||||
// TODO: modify docLine members to mirror displayLine
|
||||
int delta = 0;
|
||||
// Change lineDocs
|
||||
if ((lineDocStart <= lineDocEnd) && (lineDocStart >= 0) && (lineDocEnd < linesInDoc)) {
|
||||
for (int line=lineDocStart; line <= lineDocEnd; line++) {
|
||||
if (lines[line].visible != visible) {
|
||||
delta += visible ? 1 : -1;
|
||||
lines[line].visible = visible;
|
||||
}
|
||||
lines[line].displayLine += delta;
|
||||
}
|
||||
if (delta != 0) {
|
||||
for (int line=lineDocEnd+1; line <= linesInDoc; line++) {
|
||||
lines[line].displayLine += delta;
|
||||
}
|
||||
}
|
||||
}
|
||||
linesInDisplay += delta;
|
||||
valid = false;
|
||||
return delta != 0;
|
||||
}
|
||||
|
||||
bool ContractionState::GetExpanded(int lineDoc) const {
|
||||
if (size == 0)
|
||||
return true;
|
||||
if ((lineDoc >= 0) && (lineDoc < linesInDoc)) {
|
||||
return lines[lineDoc].expanded;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool ContractionState::SetExpanded(int lineDoc, bool expanded) {
|
||||
if (size == 0) {
|
||||
Grow(lineDoc + growSize);
|
||||
}
|
||||
if ((lineDoc >= 0) && (lineDoc < linesInDoc)) {
|
||||
if (lines[lineDoc].expanded != expanded) {
|
||||
lines[lineDoc].expanded = expanded;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
50
contrib/src/stc/scintilla/src/ContractionState.h
Normal file
50
contrib/src/stc/scintilla/src/ContractionState.h
Normal file
@@ -0,0 +1,50 @@
|
||||
// Scintilla source code edit control
|
||||
// ContractionState.h - manages visibility of lines for folding
|
||||
// Copyright 1998-2000 by Neil Hodgson <neilh@scintilla.org>
|
||||
// The License.txt file describes the conditions under which this software may be distributed.
|
||||
|
||||
#ifndef CONTRACTIONSTATE_H
|
||||
#define CONTRACTIONSTATE_H
|
||||
|
||||
class OneLine {
|
||||
public:
|
||||
int displayLine; // position within set of visible lines
|
||||
int docLine; // inverse of displayLine
|
||||
bool visible;
|
||||
bool expanded;
|
||||
|
||||
OneLine();
|
||||
virtual ~OneLine() {}
|
||||
};
|
||||
|
||||
class ContractionState {
|
||||
void Grow(int sizeNew);
|
||||
enum { growSize = 4000 };
|
||||
int linesInDoc;
|
||||
int linesInDisplay;
|
||||
mutable OneLine *lines;
|
||||
int size;
|
||||
mutable bool valid;
|
||||
void MakeValid() const;
|
||||
public:
|
||||
ContractionState();
|
||||
virtual ~ContractionState();
|
||||
|
||||
void Clear();
|
||||
|
||||
int LinesInDoc() const;
|
||||
int LinesDisplayed() const;
|
||||
int DisplayFromDoc(int lineDoc) const;
|
||||
int DocFromDisplay(int lineDisplay) const;
|
||||
|
||||
void InsertLines(int lineDoc, int lineCount);
|
||||
void DeleteLines(int lineDoc, int lineCount);
|
||||
|
||||
bool GetVisible(int lineDoc) const;
|
||||
bool SetVisible(int lineDocStart, int lineDocEnd, bool visible);
|
||||
|
||||
bool GetExpanded(int lineDoc) const;
|
||||
bool SetExpanded(int lineDoc, bool expanded);
|
||||
};
|
||||
|
||||
#endif
|
734
contrib/src/stc/scintilla/src/Document.cxx
Normal file
734
contrib/src/stc/scintilla/src/Document.cxx
Normal file
@@ -0,0 +1,734 @@
|
||||
// Scintilla source code edit control
|
||||
// Document.cxx - text document that handles notifications, DBCS, styling, words and end of line
|
||||
// Copyright 1998-2000 by Neil Hodgson <neilh@scintilla.org>
|
||||
// The License.txt file describes the conditions under which this software may be distributed.
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "Platform.h"
|
||||
|
||||
#include "Scintilla.h"
|
||||
#include "SVector.h"
|
||||
#include "CellBuffer.h"
|
||||
#include "Document.h"
|
||||
|
||||
Document::Document() {
|
||||
refCount = 0;
|
||||
#ifdef unix
|
||||
eolMode = SC_EOL_LF;
|
||||
#else
|
||||
eolMode = SC_EOL_CRLF;
|
||||
#endif
|
||||
dbcsCodePage = 0;
|
||||
stylingBits = 5;
|
||||
stylingBitsMask = 0x1F;
|
||||
stylingPos = 0;
|
||||
stylingMask = 0;
|
||||
for (int ch = 0; ch < 256; ch++) {
|
||||
wordchars[ch] = isalnum(ch) || ch == '_';
|
||||
}
|
||||
endStyled = 0;
|
||||
enteredCount = 0;
|
||||
tabInChars = 8;
|
||||
watchers = 0;
|
||||
lenWatchers = 0;
|
||||
}
|
||||
|
||||
Document::~Document() {
|
||||
for (int i = 0; i < lenWatchers; i++) {
|
||||
watchers[i].watcher->NotifyDeleted(this, watchers[i].userData);
|
||||
}
|
||||
delete []watchers;
|
||||
watchers = 0;
|
||||
lenWatchers = 0;
|
||||
}
|
||||
|
||||
// Increase reference count and return its previous value.
|
||||
int Document::AddRef() {
|
||||
return refCount++;
|
||||
}
|
||||
|
||||
// Decrease reference count and return its provius value.
|
||||
// Delete the document if reference count reaches zero.
|
||||
int Document::Release() {
|
||||
int curRefCount = --refCount;
|
||||
if (curRefCount == 0)
|
||||
delete this;
|
||||
return curRefCount;
|
||||
}
|
||||
|
||||
void Document::SetSavePoint() {
|
||||
cb.SetSavePoint();
|
||||
NotifySavePoint(true);
|
||||
}
|
||||
|
||||
int Document::LineStart(int line) {
|
||||
return cb.LineStart(line);
|
||||
}
|
||||
|
||||
int Document::LineFromPosition(int pos) {
|
||||
return cb.LineFromPosition(pos);
|
||||
}
|
||||
|
||||
int Document::LineEndPosition(int position) {
|
||||
int line = LineFromPosition(position);
|
||||
if (line == LinesTotal() - 1) {
|
||||
position = LineStart(line + 1);
|
||||
} else {
|
||||
position = LineStart(line + 1) - 1;
|
||||
// When line terminator is CR+LF, may need to go back one more
|
||||
if ((position > LineStart(line)) && (cb.CharAt(position - 1) == '\r')) {
|
||||
position--;
|
||||
}
|
||||
}
|
||||
return position;
|
||||
}
|
||||
|
||||
int Document::VCHomePosition(int position) {
|
||||
int line = LineFromPosition(position);
|
||||
int startPosition = LineStart(line);
|
||||
int endLine = LineStart(line + 1) - 1;
|
||||
int startText = startPosition;
|
||||
while (startText < endLine && (cb.CharAt(startText) == ' ' || cb.CharAt(startText) == '\t' ) )
|
||||
startText++;
|
||||
if (position == startText)
|
||||
return startPosition;
|
||||
else
|
||||
return startText;
|
||||
}
|
||||
|
||||
int Document::SetLevel(int line, int level) {
|
||||
int prev = cb.SetLevel(line, level);
|
||||
if (prev != level) {
|
||||
DocModification mh(SC_MOD_CHANGEFOLD, LineStart(line), 0, 0, 0);
|
||||
mh.line = line;
|
||||
mh.foldLevelNow = level;
|
||||
mh.foldLevelPrev = prev;
|
||||
NotifyModified(mh);
|
||||
}
|
||||
return prev;
|
||||
}
|
||||
|
||||
static bool IsSubordinate(int levelStart, int levelTry) {
|
||||
if (levelTry & SC_FOLDLEVELWHITEFLAG)
|
||||
return true;
|
||||
else
|
||||
return (levelStart & SC_FOLDLEVELNUMBERMASK) < (levelTry & SC_FOLDLEVELNUMBERMASK);
|
||||
}
|
||||
|
||||
int Document::GetLastChild(int lineParent, int level) {
|
||||
if (level == -1)
|
||||
level = GetLevel(lineParent) & SC_FOLDLEVELNUMBERMASK;
|
||||
int maxLine = LinesTotal();
|
||||
int lineMaxSubord = lineParent;
|
||||
while ((lineMaxSubord < maxLine-1) && IsSubordinate(level, GetLevel(lineMaxSubord+1))) {
|
||||
lineMaxSubord++;
|
||||
}
|
||||
if (lineMaxSubord > lineParent) {
|
||||
if (level > (GetLevel(lineMaxSubord+1) & SC_FOLDLEVELNUMBERMASK)) {
|
||||
// Have chewed up some whitespace that belongs to a parent so seek back
|
||||
if ((lineMaxSubord > lineParent) && (GetLevel(lineMaxSubord) & SC_FOLDLEVELWHITEFLAG)) {
|
||||
lineMaxSubord--;
|
||||
}
|
||||
}
|
||||
}
|
||||
return lineMaxSubord;
|
||||
}
|
||||
|
||||
int Document::GetFoldParent(int line) {
|
||||
int level = GetLevel(line);
|
||||
int lineLook = line-1;
|
||||
while ((lineLook > 0) && (
|
||||
(!(GetLevel(lineLook) & SC_FOLDLEVELHEADERFLAG)) ||
|
||||
((GetLevel(lineLook) & SC_FOLDLEVELNUMBERMASK) >= level))
|
||||
) {
|
||||
lineLook--;
|
||||
}
|
||||
if ((GetLevel(lineLook) & SC_FOLDLEVELHEADERFLAG) &&
|
||||
((GetLevel(lineLook) & SC_FOLDLEVELNUMBERMASK) < level)) {
|
||||
return lineLook;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
int Document::ClampPositionIntoDocument(int pos) {
|
||||
return Platform::Clamp(pos, 0, Length());
|
||||
}
|
||||
|
||||
bool Document::IsCrLf(int pos) {
|
||||
if (pos < 0)
|
||||
return false;
|
||||
if (pos >= (Length() - 1))
|
||||
return false;
|
||||
return (cb.CharAt(pos) == '\r') && (cb.CharAt(pos + 1) == '\n');
|
||||
}
|
||||
|
||||
bool Document::IsDBCS(int pos) {
|
||||
#if PLAT_WIN
|
||||
if (dbcsCodePage) {
|
||||
// Anchor DBCS calculations at start of line because start of line can
|
||||
// not be a DBCS trail byte.
|
||||
int startLine = pos;
|
||||
while (startLine > 0 && cb.CharAt(startLine) != '\r' && cb.CharAt(startLine) != '\n')
|
||||
startLine--;
|
||||
while (startLine <= pos) {
|
||||
if (IsDBCSLeadByteEx(dbcsCodePage, cb.CharAt(startLine))) {
|
||||
startLine++;
|
||||
if (startLine >= pos)
|
||||
return true;
|
||||
}
|
||||
startLine++;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
// Normalise a position so that it is not halfway through a two byte character.
|
||||
// This can occur in two situations -
|
||||
// When lines are terminated with \r\n pairs which should be treated as one character.
|
||||
// When displaying DBCS text such as Japanese.
|
||||
// If moving, move the position in the indicated direction.
|
||||
int Document::MovePositionOutsideChar(int pos, int moveDir, bool checkLineEnd) {
|
||||
//Platform::DebugPrintf("NoCRLF %d %d\n", pos, moveDir);
|
||||
// If out of range, just return value - should be fixed up after
|
||||
if (pos < 0)
|
||||
return pos;
|
||||
if (pos > Length())
|
||||
return pos;
|
||||
|
||||
// Position 0 and Length() can not be between any two characters
|
||||
if (pos == 0)
|
||||
return pos;
|
||||
if (pos == Length())
|
||||
return pos;
|
||||
|
||||
// assert pos > 0 && pos < Length()
|
||||
if (checkLineEnd && IsCrLf(pos - 1)) {
|
||||
if (moveDir > 0)
|
||||
return pos + 1;
|
||||
else
|
||||
return pos - 1;
|
||||
}
|
||||
|
||||
// Not between CR and LF
|
||||
|
||||
#if PLAT_WIN
|
||||
if (dbcsCodePage) {
|
||||
// Anchor DBCS calculations at start of line because start of line can
|
||||
// not be a DBCS trail byte.
|
||||
int startLine = pos;
|
||||
while (startLine > 0 && cb.CharAt(startLine) != '\r' && cb.CharAt(startLine) != '\n')
|
||||
startLine--;
|
||||
bool atLeadByte = false;
|
||||
while (startLine < pos) {
|
||||
if (atLeadByte)
|
||||
atLeadByte = false;
|
||||
else if (IsDBCSLeadByteEx(dbcsCodePage, cb.CharAt(startLine)))
|
||||
atLeadByte = true;
|
||||
else
|
||||
atLeadByte = false;
|
||||
startLine++;
|
||||
//Platform::DebugPrintf("DBCS %s\n", atlead ? "D" : "-");
|
||||
}
|
||||
|
||||
if (atLeadByte) {
|
||||
// Position is between a lead byte and a trail byte
|
||||
if (moveDir > 0)
|
||||
return pos + 1;
|
||||
else
|
||||
return pos - 1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
void Document::ModifiedAt(int pos) {
|
||||
if (endStyled > pos)
|
||||
endStyled = pos;
|
||||
}
|
||||
|
||||
// Document only modified by gateways DeleteChars, InsertStyledString, Undo, Redo, and SetStyleAt.
|
||||
// SetStyleAt does not change the persistent state of a document
|
||||
|
||||
// Unlike Undo, Redo, and InsertStyledString, the pos argument is a cell number not a char number
|
||||
void Document::DeleteChars(int pos, int len) {
|
||||
if (enteredCount == 0) {
|
||||
enteredCount++;
|
||||
if (cb.IsReadOnly())
|
||||
NotifyModifyAttempt();
|
||||
if (!cb.IsReadOnly()) {
|
||||
int prevLinesTotal = LinesTotal();
|
||||
bool startSavePoint = cb.IsSavePoint();
|
||||
const char *text = cb.DeleteChars(pos*2, len * 2);
|
||||
if (startSavePoint && cb.IsCollectingUndo())
|
||||
NotifySavePoint(!startSavePoint);
|
||||
ModifiedAt(pos);
|
||||
int modFlags = SC_MOD_DELETETEXT | SC_PERFORMED_USER;
|
||||
DocModification mh(modFlags, pos, len, LinesTotal() - prevLinesTotal, text);
|
||||
NotifyModified(mh);
|
||||
}
|
||||
enteredCount--;
|
||||
}
|
||||
}
|
||||
|
||||
void Document::InsertStyledString(int position, char *s, int insertLength) {
|
||||
if (enteredCount == 0) {
|
||||
enteredCount++;
|
||||
if (cb.IsReadOnly())
|
||||
NotifyModifyAttempt();
|
||||
if (!cb.IsReadOnly()) {
|
||||
int prevLinesTotal = LinesTotal();
|
||||
bool startSavePoint = cb.IsSavePoint();
|
||||
const char *text = cb.InsertString(position, s, insertLength);
|
||||
if (startSavePoint && cb.IsCollectingUndo())
|
||||
NotifySavePoint(!startSavePoint);
|
||||
ModifiedAt(position / 2);
|
||||
|
||||
int modFlags = SC_MOD_INSERTTEXT | SC_PERFORMED_USER;
|
||||
DocModification mh(modFlags, position / 2, insertLength / 2, LinesTotal() - prevLinesTotal, text);
|
||||
NotifyModified(mh);
|
||||
}
|
||||
enteredCount--;
|
||||
}
|
||||
}
|
||||
|
||||
int Document::Undo() {
|
||||
int newPos = 0;
|
||||
if (enteredCount == 0) {
|
||||
enteredCount++;
|
||||
bool startSavePoint = cb.IsSavePoint();
|
||||
int steps = cb.StartUndo();
|
||||
for (int step=0; step<steps; step++) {
|
||||
int prevLinesTotal = LinesTotal();
|
||||
const Action &action = cb.UndoStep();
|
||||
int cellPosition = action.position / 2;
|
||||
ModifiedAt(cellPosition);
|
||||
newPos = cellPosition;
|
||||
|
||||
int modFlags = SC_PERFORMED_UNDO;
|
||||
// With undo, an insertion action becomes a deletion notification
|
||||
if (action.at == removeAction) {
|
||||
newPos += action.lenData;
|
||||
modFlags |= SC_MOD_INSERTTEXT;
|
||||
} else {
|
||||
modFlags |= SC_MOD_DELETETEXT;
|
||||
}
|
||||
if (step == steps-1)
|
||||
modFlags |= SC_LASTSTEPINUNDOREDO;
|
||||
NotifyModified(DocModification(modFlags, cellPosition, action.lenData,
|
||||
LinesTotal() - prevLinesTotal, action.data));
|
||||
}
|
||||
|
||||
bool endSavePoint = cb.IsSavePoint();
|
||||
if (startSavePoint != endSavePoint)
|
||||
NotifySavePoint(endSavePoint);
|
||||
enteredCount--;
|
||||
}
|
||||
return newPos;
|
||||
}
|
||||
|
||||
int Document::Redo() {
|
||||
int newPos = 0;
|
||||
if (enteredCount == 0) {
|
||||
enteredCount++;
|
||||
bool startSavePoint = cb.IsSavePoint();
|
||||
int steps = cb.StartRedo();
|
||||
for (int step=0; step<steps; step++) {
|
||||
int prevLinesTotal = LinesTotal();
|
||||
const Action &action = cb.RedoStep();
|
||||
int cellPosition = action.position / 2;
|
||||
ModifiedAt(cellPosition);
|
||||
newPos = cellPosition;
|
||||
|
||||
int modFlags = SC_PERFORMED_REDO;
|
||||
if (action.at == insertAction) {
|
||||
newPos += action.lenData;
|
||||
modFlags |= SC_MOD_INSERTTEXT;
|
||||
} else {
|
||||
modFlags |= SC_MOD_DELETETEXT;
|
||||
}
|
||||
if (step == steps-1)
|
||||
modFlags |= SC_LASTSTEPINUNDOREDO;
|
||||
NotifyModified(DocModification(modFlags, cellPosition, action.lenData,
|
||||
LinesTotal() - prevLinesTotal, action.data));
|
||||
}
|
||||
|
||||
bool endSavePoint = cb.IsSavePoint();
|
||||
if (startSavePoint != endSavePoint)
|
||||
NotifySavePoint(endSavePoint);
|
||||
enteredCount--;
|
||||
}
|
||||
return newPos;
|
||||
}
|
||||
|
||||
void Document::InsertChar(int pos, char ch) {
|
||||
char chs[2];
|
||||
chs[0] = ch;
|
||||
chs[1] = 0;
|
||||
InsertStyledString(pos*2, chs, 2);
|
||||
}
|
||||
|
||||
// Insert a null terminated string
|
||||
void Document::InsertString(int position, const char *s) {
|
||||
InsertString(position, s, strlen(s));
|
||||
}
|
||||
|
||||
// Insert a string with a length
|
||||
void Document::InsertString(int position, const char *s, int insertLength) {
|
||||
char *sWithStyle = new char[insertLength * 2];
|
||||
if (sWithStyle) {
|
||||
for (int i = 0; i < insertLength; i++) {
|
||||
sWithStyle[i*2] = s[i];
|
||||
sWithStyle[i*2 + 1] = 0;
|
||||
}
|
||||
InsertStyledString(position*2, sWithStyle, insertLength*2);
|
||||
delete []sWithStyle;
|
||||
}
|
||||
}
|
||||
|
||||
void Document::DelChar(int pos) {
|
||||
if (IsCrLf(pos)) {
|
||||
DeleteChars(pos, 2);
|
||||
} else if (IsDBCS(pos)) {
|
||||
DeleteChars(pos, 2);
|
||||
} else if (pos < Length()) {
|
||||
DeleteChars(pos, 1);
|
||||
}
|
||||
}
|
||||
|
||||
int Document::DelCharBack(int pos) {
|
||||
if (pos <= 0) {
|
||||
return pos;
|
||||
} else if (IsCrLf(pos - 2)) {
|
||||
DeleteChars(pos - 2, 2);
|
||||
return pos - 2;
|
||||
} else if (IsDBCS(pos - 1)) {
|
||||
DeleteChars(pos - 2, 2);
|
||||
return pos - 2;
|
||||
} else {
|
||||
DeleteChars(pos - 1, 1);
|
||||
return pos - 1;
|
||||
}
|
||||
}
|
||||
|
||||
void Document::Indent(bool forwards, int lineBottom, int lineTop) {
|
||||
if (forwards) {
|
||||
// Indent by a tab
|
||||
for (int line = lineBottom; line >= lineTop; line--) {
|
||||
InsertChar(LineStart(line), '\t');
|
||||
}
|
||||
} else {
|
||||
// Dedent - suck white space off the front of the line to dedent by equivalent of a tab
|
||||
for (int line = lineBottom; line >= lineTop; line--) {
|
||||
int ispc = 0;
|
||||
while (ispc < tabInChars && cb.CharAt(LineStart(line) + ispc) == ' ')
|
||||
ispc++;
|
||||
int posStartLine = LineStart(line);
|
||||
if (ispc == tabInChars) {
|
||||
DeleteChars(posStartLine, ispc);
|
||||
} else if (cb.CharAt(posStartLine + ispc) == '\t') {
|
||||
DeleteChars(posStartLine, ispc + 1);
|
||||
} else { // Hit a non-white
|
||||
DeleteChars(posStartLine, ispc);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Document::ConvertLineEnds(int eolModeSet) {
|
||||
BeginUndoAction();
|
||||
for (int pos = 0; pos < Length(); pos++) {
|
||||
if (cb.CharAt(pos) == '\r') {
|
||||
if (cb.CharAt(pos+1) == '\n') {
|
||||
if (eolModeSet != SC_EOL_CRLF) {
|
||||
DeleteChars(pos, 2);
|
||||
if (eolModeSet == SC_EOL_CR)
|
||||
InsertString(pos, "\r", 1);
|
||||
else
|
||||
InsertString(pos, "\n", 1);
|
||||
} else {
|
||||
pos++;
|
||||
}
|
||||
} else {
|
||||
if (eolModeSet != SC_EOL_CR) {
|
||||
DeleteChars(pos, 1);
|
||||
if (eolModeSet == SC_EOL_CRLF) {
|
||||
InsertString(pos, "\r\n", 2);
|
||||
pos++;
|
||||
} else {
|
||||
InsertString(pos, "\n", 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (cb.CharAt(pos) == '\n') {
|
||||
if (eolModeSet != SC_EOL_LF) {
|
||||
DeleteChars(pos, 1);
|
||||
if (eolModeSet == SC_EOL_CRLF) {
|
||||
InsertString(pos, "\r\n", 2);
|
||||
pos++;
|
||||
} else {
|
||||
InsertString(pos, "\r", 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
EndUndoAction();
|
||||
}
|
||||
|
||||
bool Document::IsWordChar(unsigned char ch) {
|
||||
return wordchars[ch];
|
||||
}
|
||||
|
||||
int Document::ExtendWordSelect(int pos, int delta) {
|
||||
if (delta < 0) {
|
||||
while (pos > 0 && IsWordChar(cb.CharAt(pos - 1)))
|
||||
pos--;
|
||||
} else {
|
||||
while (pos < (Length()) && IsWordChar(cb.CharAt(pos)))
|
||||
pos++;
|
||||
}
|
||||
return pos;
|
||||
}
|
||||
|
||||
int Document::NextWordStart(int pos, int delta) {
|
||||
if (delta < 0) {
|
||||
while (pos > 0 && (cb.CharAt(pos - 1) == ' ' || cb.CharAt(pos - 1) == '\t'))
|
||||
pos--;
|
||||
if (isspace(cb.CharAt(pos - 1))) { // Back up to previous line
|
||||
while (pos > 0 && isspace(cb.CharAt(pos - 1)))
|
||||
pos--;
|
||||
} else {
|
||||
bool startAtWordChar = IsWordChar(cb.CharAt(pos - 1));
|
||||
while (pos > 0 && !isspace(cb.CharAt(pos - 1)) && (startAtWordChar == IsWordChar(cb.CharAt(pos - 1))))
|
||||
pos--;
|
||||
}
|
||||
} else {
|
||||
bool startAtWordChar = IsWordChar(cb.CharAt(pos));
|
||||
while (pos < (Length()) && isspace(cb.CharAt(pos)))
|
||||
pos++;
|
||||
while (pos < (Length()) && !isspace(cb.CharAt(pos)) && (startAtWordChar == IsWordChar(cb.CharAt(pos))))
|
||||
pos++;
|
||||
while (pos < (Length()) && (cb.CharAt(pos) == ' ' || cb.CharAt(pos) == '\t'))
|
||||
pos++;
|
||||
}
|
||||
return pos;
|
||||
}
|
||||
|
||||
bool Document::IsWordAt(int start, int end) {
|
||||
int lengthDoc = Length();
|
||||
if (start > 0) {
|
||||
char ch = CharAt(start - 1);
|
||||
if (IsWordChar(ch))
|
||||
return false;
|
||||
}
|
||||
if (end < lengthDoc - 1) {
|
||||
char ch = CharAt(end);
|
||||
if (IsWordChar(ch))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Find text in document, supporting both forward and backward
|
||||
// searches (just pass minPos > maxPos to do a backward search)
|
||||
// Has not been tested with backwards DBCS searches yet.
|
||||
long Document::FindText(int minPos, int maxPos, const char *s, bool caseSensitive, bool word) {
|
||||
bool forward = minPos <= maxPos;
|
||||
int increment = forward ? 1 : -1;
|
||||
|
||||
// Range endpoints should not be inside DBCS characters, but just in case, move them.
|
||||
int startPos = MovePositionOutsideChar(minPos, increment, false);
|
||||
int endPos = MovePositionOutsideChar(maxPos, increment, false);
|
||||
|
||||
// Compute actual search ranges needed
|
||||
int lengthFind = strlen(s);
|
||||
int endSearch = 0;
|
||||
if (startPos <= endPos) {
|
||||
endSearch = endPos - lengthFind + 1;
|
||||
} else {
|
||||
endSearch = endPos;
|
||||
}
|
||||
//Platform::DebugPrintf("Find %d %d %s %d\n", startPos, endPos, ft->lpstrText, lengthFind);
|
||||
char firstChar = s[0];
|
||||
if (!caseSensitive)
|
||||
firstChar = toupper(firstChar);
|
||||
int pos = startPos;
|
||||
while (forward ? (pos < endSearch) : (pos >= endSearch)) {
|
||||
char ch = CharAt(pos);
|
||||
if (caseSensitive) {
|
||||
if (ch == firstChar) {
|
||||
bool found = true;
|
||||
for (int posMatch = 1; posMatch < lengthFind && found; posMatch++) {
|
||||
ch = CharAt(pos + posMatch);
|
||||
if (ch != s[posMatch])
|
||||
found = false;
|
||||
}
|
||||
if (found) {
|
||||
if ((!word) || IsWordAt(pos, pos + lengthFind))
|
||||
return pos;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (toupper(ch) == firstChar) {
|
||||
bool found = true;
|
||||
for (int posMatch = 1; posMatch < lengthFind && found; posMatch++) {
|
||||
ch = CharAt(pos + posMatch);
|
||||
if (toupper(ch) != toupper(s[posMatch]))
|
||||
found = false;
|
||||
}
|
||||
if (found) {
|
||||
if ((!word) || IsWordAt(pos, pos + lengthFind))
|
||||
return pos;
|
||||
}
|
||||
}
|
||||
}
|
||||
pos += increment;
|
||||
if (dbcsCodePage) {
|
||||
// Ensure trying to match from start of character
|
||||
pos = MovePositionOutsideChar(pos, increment, false);
|
||||
}
|
||||
}
|
||||
//Platform::DebugPrintf("Not found\n");
|
||||
return - 1;
|
||||
}
|
||||
|
||||
int Document::LinesTotal() {
|
||||
return cb.Lines();
|
||||
}
|
||||
|
||||
void Document::SetWordChars(unsigned char *chars) {
|
||||
int ch;
|
||||
for (ch = 0; ch < 256; ch++) {
|
||||
wordchars[ch] = false;
|
||||
}
|
||||
if (chars) {
|
||||
while (*chars) {
|
||||
wordchars[*chars] = true;
|
||||
chars++;
|
||||
}
|
||||
} else {
|
||||
for (ch = 0; ch < 256; ch++) {
|
||||
wordchars[ch] = isalnum(ch) || ch == '_';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Document::SetStylingBits(int bits) {
|
||||
stylingBits = bits;
|
||||
stylingBitsMask = 0;
|
||||
for (int bit=0; bit<stylingBits; bit++) {
|
||||
stylingBitsMask <<= 1;
|
||||
stylingBitsMask |= 1;
|
||||
}
|
||||
}
|
||||
|
||||
void Document::StartStyling(int position, char mask) {
|
||||
stylingPos = position;
|
||||
stylingMask = mask;
|
||||
}
|
||||
|
||||
void Document::SetStyleFor(int length, char style) {
|
||||
if (enteredCount == 0) {
|
||||
enteredCount++;
|
||||
int prevEndStyled = endStyled;
|
||||
if (cb.SetStyleFor(stylingPos, length, style, stylingMask)) {
|
||||
DocModification mh(SC_MOD_CHANGESTYLE | SC_PERFORMED_USER,
|
||||
prevEndStyled, length);
|
||||
NotifyModified(mh);
|
||||
}
|
||||
stylingPos += length;
|
||||
endStyled = stylingPos;
|
||||
enteredCount--;
|
||||
}
|
||||
}
|
||||
|
||||
void Document::SetStyles(int length, char *styles) {
|
||||
if (enteredCount == 0) {
|
||||
enteredCount++;
|
||||
int prevEndStyled = endStyled;
|
||||
bool didChange = false;
|
||||
for (int iPos = 0; iPos < length; iPos++, stylingPos++) {
|
||||
if (cb.SetStyleAt(stylingPos, styles[iPos], stylingMask)) {
|
||||
didChange = true;
|
||||
}
|
||||
}
|
||||
endStyled = stylingPos;
|
||||
if (didChange) {
|
||||
DocModification mh(SC_MOD_CHANGESTYLE | SC_PERFORMED_USER,
|
||||
prevEndStyled, endStyled - prevEndStyled);
|
||||
NotifyModified(mh);
|
||||
}
|
||||
enteredCount--;
|
||||
}
|
||||
}
|
||||
|
||||
bool Document::AddWatcher(DocWatcher *watcher, void *userData) {
|
||||
for (int i = 0; i < lenWatchers; i++) {
|
||||
if ((watchers[i].watcher == watcher) &&
|
||||
(watchers[i].userData == userData))
|
||||
return false;
|
||||
}
|
||||
WatcherWithUserData *pwNew = new WatcherWithUserData[lenWatchers + 1];
|
||||
if (!pwNew)
|
||||
return false;
|
||||
for (int j = 0; j < lenWatchers; j++)
|
||||
pwNew[j] = watchers[j];
|
||||
pwNew[lenWatchers].watcher = watcher;
|
||||
pwNew[lenWatchers].userData = userData;
|
||||
delete []watchers;
|
||||
watchers = pwNew;
|
||||
lenWatchers++;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Document::RemoveWatcher(DocWatcher *watcher, void *userData) {
|
||||
for (int i = 0; i < lenWatchers; i++) {
|
||||
if ((watchers[i].watcher == watcher) &&
|
||||
(watchers[i].userData == userData)) {
|
||||
if (lenWatchers == 1) {
|
||||
delete []watchers;
|
||||
watchers = 0;
|
||||
lenWatchers = 0;
|
||||
} else {
|
||||
WatcherWithUserData *pwNew = new WatcherWithUserData[lenWatchers];
|
||||
if (!pwNew)
|
||||
return false;
|
||||
for (int j = 0; j < lenWatchers - 1; j++) {
|
||||
pwNew[j] = (j < i) ? watchers[j] : watchers[j + 1];
|
||||
}
|
||||
delete []watchers;
|
||||
watchers = pwNew;
|
||||
lenWatchers--;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void Document::NotifyModifyAttempt() {
|
||||
for (int i = 0; i < lenWatchers; i++) {
|
||||
watchers[i].watcher->NotifyModifyAttempt(this, watchers[i].userData);
|
||||
}
|
||||
}
|
||||
|
||||
void Document::NotifySavePoint(bool atSavePoint) {
|
||||
for (int i = 0; i < lenWatchers; i++) {
|
||||
watchers[i].watcher->NotifySavePoint(this, watchers[i].userData, atSavePoint);
|
||||
}
|
||||
}
|
||||
|
||||
void Document::NotifyModified(DocModification mh) {
|
||||
for (int i = 0; i < lenWatchers; i++) {
|
||||
watchers[i].watcher->NotifyModified(this, mh, watchers[i].userData);
|
||||
}
|
||||
}
|
222
contrib/src/stc/scintilla/src/Document.h
Normal file
222
contrib/src/stc/scintilla/src/Document.h
Normal file
@@ -0,0 +1,222 @@
|
||||
// Scintilla source code edit control
|
||||
// Document.h - text document that handles notifications, DBCS, styling, words and end of line
|
||||
// Copyright 1998-2000 by Neil Hodgson <neilh@scintilla.org>
|
||||
// The License.txt file describes the conditions under which this software may be distributed.
|
||||
|
||||
#ifndef DOCUMENT_H
|
||||
#define DOCUMENT_H
|
||||
|
||||
// A Position is a position within a document between two characters or at the beginning or end.
|
||||
// Sometimes used as a character index where it identifies the character after the position.
|
||||
typedef int Position;
|
||||
const Position invalidPosition = -1;
|
||||
|
||||
// The range class represents a range of text in a document.
|
||||
// The two values are not sorted as one end may be more significant than the other
|
||||
// as is the case for the selection where the end position is the position of the caret.
|
||||
// If either position is invalidPosition then the range is invalid and most operations will fail.
|
||||
class Range {
|
||||
public:
|
||||
Position start;
|
||||
Position end;
|
||||
|
||||
Range(Position pos=0) :
|
||||
start(pos), end(pos) {
|
||||
};
|
||||
Range(Position start_, Position end_) :
|
||||
start(start_), end(end_) {
|
||||
};
|
||||
|
||||
bool Valid() const {
|
||||
return (start != invalidPosition) && (end != invalidPosition);
|
||||
}
|
||||
|
||||
bool Contains(Position pos) const {
|
||||
if (start < end) {
|
||||
return (pos >= start && pos <= end);
|
||||
} else {
|
||||
return (pos <= start && pos >= end);
|
||||
}
|
||||
}
|
||||
|
||||
bool Contains(Range other) const {
|
||||
return Contains(other.start) && Contains(other.end);
|
||||
}
|
||||
|
||||
bool Overlaps(Range other) const {
|
||||
return
|
||||
Contains(other.start) ||
|
||||
Contains(other.end) ||
|
||||
other.Contains(start) ||
|
||||
other.Contains(end);
|
||||
}
|
||||
};
|
||||
|
||||
class DocWatcher;
|
||||
class DocModification;
|
||||
|
||||
class Document {
|
||||
|
||||
public:
|
||||
// Used to pair watcher pointer with user data
|
||||
class WatcherWithUserData {
|
||||
public:
|
||||
DocWatcher *watcher;
|
||||
void *userData;
|
||||
WatcherWithUserData() {
|
||||
watcher = 0;
|
||||
userData = 0;
|
||||
}
|
||||
};
|
||||
|
||||
private:
|
||||
int refCount;
|
||||
CellBuffer cb;
|
||||
bool wordchars[256];
|
||||
int stylingPos;
|
||||
int stylingMask;
|
||||
int endStyled;
|
||||
int enteredCount;
|
||||
|
||||
WatcherWithUserData *watchers;
|
||||
int lenWatchers;
|
||||
|
||||
public:
|
||||
int stylingBits;
|
||||
int stylingBitsMask;
|
||||
|
||||
int eolMode;
|
||||
int dbcsCodePage;
|
||||
int tabInChars;
|
||||
|
||||
Document();
|
||||
virtual ~Document();
|
||||
|
||||
int AddRef();
|
||||
int Release();
|
||||
|
||||
int LineFromPosition(int pos);
|
||||
int ClampPositionIntoDocument(int pos);
|
||||
bool IsCrLf(int pos);
|
||||
int MovePositionOutsideChar(int pos, int moveDir, bool checkLineEnd=true);
|
||||
|
||||
// Gateways to modifying document
|
||||
void DeleteChars(int pos, int len);
|
||||
void InsertStyledString(int position, char *s, int insertLength);
|
||||
int Undo();
|
||||
int Redo();
|
||||
bool CanUndo() { return cb.CanUndo(); }
|
||||
bool CanRedo() { return cb.CanRedo(); }
|
||||
void DeleteUndoHistory() { cb.DeleteUndoHistory(); }
|
||||
undoCollectionType SetUndoCollection(undoCollectionType collectUndo) {
|
||||
return cb.SetUndoCollection(collectUndo);
|
||||
}
|
||||
void AppendUndoStartAction() { cb.AppendUndoStartAction(); }
|
||||
void BeginUndoAction() { cb.BeginUndoAction(); }
|
||||
void EndUndoAction() { cb.EndUndoAction(); }
|
||||
void SetSavePoint();
|
||||
bool IsSavePoint() { return cb.IsSavePoint(); }
|
||||
void Indent(bool forwards, int lineBottom, int lineTop);
|
||||
void ConvertLineEnds(int eolModeSet);
|
||||
void SetReadOnly(bool set) { cb.SetReadOnly(set); }
|
||||
|
||||
void InsertChar(int pos, char ch);
|
||||
void InsertString(int position, const char *s);
|
||||
void InsertString(int position, const char *s, int insertLength);
|
||||
void DelChar(int pos);
|
||||
int DelCharBack(int pos);
|
||||
|
||||
char CharAt(int position) { return cb.CharAt(position); }
|
||||
void GetCharRange(char *buffer, int position, int lengthRetrieve) {
|
||||
cb.GetCharRange(buffer, position, lengthRetrieve);
|
||||
}
|
||||
char StyleAt(int position) { return cb.StyleAt(position); }
|
||||
int GetMark(int line) { return cb.GetMark(line); }
|
||||
int AddMark(int line, int markerNum) { return cb.AddMark(line, markerNum); }
|
||||
void DeleteMark(int line, int markerNum) { cb.DeleteMark(line, markerNum); }
|
||||
void DeleteMarkFromHandle(int markerHandle) { cb.DeleteMarkFromHandle(markerHandle); }
|
||||
void DeleteAllMarks(int markerNum) { cb.DeleteAllMarks(markerNum); }
|
||||
int LineFromHandle(int markerHandle) { return cb.LineFromHandle(markerHandle); }
|
||||
int LineStart(int line);
|
||||
int LineEndPosition(int position);
|
||||
int VCHomePosition(int position);
|
||||
|
||||
int SetLevel(int line, int level);
|
||||
int GetLevel(int line) { return cb.GetLevel(line); }
|
||||
int GetLastChild(int lineParent, int level=-1);
|
||||
int GetFoldParent(int line);
|
||||
|
||||
void Indent(bool forwards);
|
||||
int ExtendWordSelect(int pos, int delta);
|
||||
int NextWordStart(int pos, int delta);
|
||||
int Length() { return cb.Length(); }
|
||||
long FindText(int minPos, int maxPos, const char *s, bool caseSensitive, bool word);
|
||||
long FindText(WORD iMessage,WPARAM wParam,LPARAM lParam);
|
||||
int LinesTotal();
|
||||
|
||||
void SetWordChars(unsigned char *chars);
|
||||
void SetStylingBits(int bits);
|
||||
void StartStyling(int position, char mask);
|
||||
void SetStyleFor(int length, char style);
|
||||
void SetStyles(int length, char *styles);
|
||||
int GetEndStyled() { return endStyled; }
|
||||
|
||||
int SetLineState(int line, int state) { return cb.SetLineState(line, state); }
|
||||
int GetLineState(int line) { return cb.GetLineState(line); }
|
||||
int GetMaxLineState() { return cb.GetMaxLineState(); }
|
||||
|
||||
bool AddWatcher(DocWatcher *watcher, void *userData);
|
||||
bool RemoveWatcher(DocWatcher *watcher, void *userData);
|
||||
const WatcherWithUserData *GetWatchers() const { return watchers; }
|
||||
int GetLenWatchers() const { return lenWatchers; }
|
||||
|
||||
private:
|
||||
bool IsDBCS(int pos);
|
||||
bool IsWordChar(unsigned char ch);
|
||||
bool IsWordAt(int start, int end);
|
||||
void ModifiedAt(int pos);
|
||||
|
||||
void NotifyModifyAttempt();
|
||||
void NotifySavePoint(bool atSavePoint);
|
||||
void NotifyModified(DocModification mh);
|
||||
};
|
||||
|
||||
// To optimise processing of document modifications by DocWatchers, a hint is passed indicating the
|
||||
// scope of the change.
|
||||
// If the DocWatcher is a document view then this can be used to optimise screen updating.
|
||||
class DocModification {
|
||||
public:
|
||||
int modificationType;
|
||||
int position;
|
||||
int length;
|
||||
int linesAdded; // Negative if lines deleted
|
||||
const char *text; // Only valid for changes to text, not for changes to style
|
||||
int line;
|
||||
int foldLevelNow;
|
||||
int foldLevelPrev;
|
||||
|
||||
DocModification(int modificationType_, int position_=0, int length_=0,
|
||||
int linesAdded_=0, const char *text_=0) :
|
||||
modificationType(modificationType_),
|
||||
position(position_),
|
||||
length(length_),
|
||||
linesAdded(linesAdded_),
|
||||
text(text_),
|
||||
line(0),
|
||||
foldLevelNow(0),
|
||||
foldLevelPrev(0) {}
|
||||
};
|
||||
|
||||
// A class that wants to receive notifications from a Document must be derived from DocWatcher
|
||||
// and implement the notification methods. It can then be added to the watcher list with AddWatcher.
|
||||
class DocWatcher {
|
||||
public:
|
||||
virtual ~DocWatcher() {}
|
||||
|
||||
virtual void NotifyModifyAttempt(Document *doc, void *userData) = 0;
|
||||
virtual void NotifySavePoint(Document *doc, void *userData, bool atSavePoint) = 0;
|
||||
virtual void NotifyModified(Document *doc, DocModification mh, void *userData) = 0;
|
||||
virtual void NotifyDeleted(Document *doc, void *userData) = 0;
|
||||
};
|
||||
|
||||
#endif
|
3693
contrib/src/stc/scintilla/src/Editor.cxx
Normal file
3693
contrib/src/stc/scintilla/src/Editor.cxx
Normal file
File diff suppressed because it is too large
Load Diff
281
contrib/src/stc/scintilla/src/Editor.h
Normal file
281
contrib/src/stc/scintilla/src/Editor.h
Normal file
@@ -0,0 +1,281 @@
|
||||
// Scintilla source code edit control
|
||||
// Editor.h - defines the main editor class
|
||||
// Copyright 1998-2000 by Neil Hodgson <neilh@scintilla.org>
|
||||
// The License.txt file describes the conditions under which this software may be distributed.
|
||||
|
||||
#ifndef EDITOR_H
|
||||
#define EDITOR_H
|
||||
|
||||
class Caret {
|
||||
public:
|
||||
bool active;
|
||||
bool on;
|
||||
int period;
|
||||
|
||||
Caret();
|
||||
};
|
||||
|
||||
class Timer {
|
||||
|
||||
public:
|
||||
bool ticking;
|
||||
int ticksToWait;
|
||||
enum {tickSize = 100};
|
||||
int tickerID;
|
||||
|
||||
Timer();
|
||||
};
|
||||
|
||||
class LineLayout {
|
||||
public:
|
||||
// Drawing is only performed for maxLineLength characters on each line.
|
||||
enum {maxLineLength = 4000};
|
||||
int numCharsInLine;
|
||||
char chars[maxLineLength];
|
||||
char styles[maxLineLength];
|
||||
char indicators[maxLineLength];
|
||||
int positions[maxLineLength];
|
||||
};
|
||||
|
||||
class Editor : public DocWatcher {
|
||||
protected: // ScintillaBase subclass needs access to much of Editor
|
||||
|
||||
// On GTK+, Scintilla is a container widget holding two scroll bars and a drawing area
|
||||
// whereas on Windows there is just one window with both scroll bars turned on.
|
||||
// Therefore, on GTK+ the following are separate windows but only one window on Windows.
|
||||
Window wMain; // The Scintilla parent window
|
||||
Window wDraw; // The text drawing area
|
||||
|
||||
// Style resources may be expensive to allocate so are cached between uses.
|
||||
// When a style attribute is changed, this cache is flushed.
|
||||
bool stylesValid;
|
||||
ViewStyle vs;
|
||||
Palette palette;
|
||||
|
||||
bool hideSelection;
|
||||
bool inOverstrike;
|
||||
|
||||
// In bufferedDraw mode, graphics operations are drawn to a pixmap and then copied to
|
||||
// the screen. This avoids flashing but is about 30% slower.
|
||||
bool bufferedDraw;
|
||||
|
||||
int xOffset; // Horizontal scrolled amount in pixels
|
||||
int xCaretMargin; // Ensure this many pixels visible on both sides of caret
|
||||
|
||||
Surface pixmapLine;
|
||||
Surface pixmapSelMargin;
|
||||
Surface pixmapSelPattern;
|
||||
// Intellimouse support - currently only implemented for Windows
|
||||
unsigned int ucWheelScrollLines;
|
||||
short cWheelDelta; //wheel delta from roll
|
||||
|
||||
KeyMap kmap;
|
||||
|
||||
Caret caret;
|
||||
Timer timer;
|
||||
|
||||
Point lastClick;
|
||||
unsigned int lastClickTime;
|
||||
enum { selChar, selWord, selLine } selectionType;
|
||||
Point ptMouseLast;
|
||||
bool firstExpose;
|
||||
bool inDragDrop;
|
||||
bool dropWentOutside;
|
||||
int posDrag;
|
||||
int posDrop;
|
||||
int lastXChosen;
|
||||
int lineAnchor;
|
||||
int originalAnchorPos;
|
||||
int currentPos;
|
||||
int anchor;
|
||||
int topLine;
|
||||
int posTopLine;
|
||||
|
||||
bool needUpdateUI;
|
||||
Position braces[2];
|
||||
int bracesMatchStyle;
|
||||
|
||||
int edgeState;
|
||||
int theEdge;
|
||||
|
||||
enum { notPainting, painting, paintAbandoned } paintState;
|
||||
PRectangle rcPaint;
|
||||
bool paintingAllText;
|
||||
|
||||
int modEventMask;
|
||||
|
||||
char *dragChars;
|
||||
int lenDrag;
|
||||
bool dragIsRectangle;
|
||||
enum { selStream, selRectangle, selRectangleFixed } selType;
|
||||
int xStartSelect;
|
||||
int xEndSelect;
|
||||
|
||||
int caretPolicy;
|
||||
int caretSlop;
|
||||
|
||||
int searchAnchor;
|
||||
|
||||
#ifdef MACRO_SUPPORT
|
||||
int recordingMacro;
|
||||
#endif
|
||||
|
||||
int foldFlags;
|
||||
ContractionState cs;
|
||||
|
||||
Document *pdoc;
|
||||
|
||||
Editor();
|
||||
virtual ~Editor();
|
||||
virtual void Initialise() = 0;
|
||||
virtual void Finalise();
|
||||
|
||||
void InvalidateStyleData();
|
||||
void InvalidateStyleRedraw();
|
||||
virtual void RefreshColourPalette(Palette &pal, bool want);
|
||||
void RefreshStyleData();
|
||||
void DropGraphics();
|
||||
|
||||
PRectangle GetClientRectangle();
|
||||
PRectangle GetTextRectangle();
|
||||
|
||||
int LinesOnScreen();
|
||||
int LinesToScroll();
|
||||
int MaxScrollPos();
|
||||
Point LocationFromPosition(unsigned int pos);
|
||||
int XFromPosition(unsigned int pos);
|
||||
int PositionFromLocation(Point pt);
|
||||
int PositionFromLineX(int line, int x);
|
||||
int LineFromLocation(Point pt);
|
||||
void SetTopLine(int topLineNew);
|
||||
|
||||
void RedrawRect(PRectangle rc);
|
||||
void Redraw();
|
||||
void RedrawSelMargin();
|
||||
PRectangle RectangleFromRange(int start, int end);
|
||||
void InvalidateRange(int start, int end);
|
||||
|
||||
int CurrentPosition();
|
||||
bool SelectionEmpty();
|
||||
int SelectionStart(int line=-1);
|
||||
int SelectionEnd(int line=-1);
|
||||
void SetSelection(int currentPos_, int anchor_);
|
||||
void SetSelection(int currentPos_);
|
||||
void SetEmptySelection(int currentPos_);
|
||||
int MovePositionTo(int newPos, bool extend = false);
|
||||
int MovePositionSoVisible(int pos, int moveDir);
|
||||
void SetLastXChosen();
|
||||
|
||||
void ScrollTo(int line);
|
||||
virtual void ScrollText(int linesToMove);
|
||||
void HorizontalScrollTo(int xPos);
|
||||
void EnsureCaretVisible(bool useMargin=true);
|
||||
void ShowCaretAtCurrentPosition();
|
||||
void DropCaret();
|
||||
void InvalidateCaret();
|
||||
|
||||
void PaintSelMargin(Surface *surface, PRectangle &rc);
|
||||
void LayoutLine(int line, Surface *surface, ViewStyle &vstyle, LineLayout &ll);
|
||||
void DrawLine(Surface *surface, ViewStyle &vsDraw, int line, int xStart,
|
||||
PRectangle rcLine, LineLayout &ll);
|
||||
void Paint(Surface *surfaceWindow, PRectangle rcArea);
|
||||
long FormatRange(bool draw, FORMATRANGE *pfr);
|
||||
|
||||
virtual void SetVerticalScrollPos() = 0;
|
||||
virtual void SetHorizontalScrollPos() = 0;
|
||||
virtual bool ModifyScrollBars(int nMax, int nPage) = 0;
|
||||
void SetScrollBarsTo(PRectangle rsClient);
|
||||
void SetScrollBars();
|
||||
|
||||
virtual void AddChar(char ch);
|
||||
void ClearSelection();
|
||||
void ClearAll();
|
||||
void Cut();
|
||||
void PasteRectangular(int pos, const char *ptr, int len);
|
||||
virtual void Copy() = 0;
|
||||
virtual void Paste() = 0;
|
||||
void Clear();
|
||||
void SelectAll();
|
||||
void Undo();
|
||||
void Redo();
|
||||
void DelChar();
|
||||
void DelCharBack();
|
||||
virtual void ClaimSelection() = 0;
|
||||
|
||||
virtual void NotifyChange() = 0;
|
||||
virtual void NotifyFocus(bool focus);
|
||||
virtual void NotifyParent(SCNotification scn) = 0;
|
||||
virtual void NotifyStyleNeeded(int endStyleNeeded);
|
||||
void NotifyChar(char ch);
|
||||
void NotifySavePoint(bool isSavePoint);
|
||||
void NotifyModifyAttempt();
|
||||
virtual void NotifyDoubleClick(Point pt, bool shift);
|
||||
void NotifyUpdateUI();
|
||||
bool NotifyMarginClick(Point pt, bool shift, bool ctrl, bool alt);
|
||||
void NotifyNeedShown(int pos, int len);
|
||||
|
||||
void NotifyModifyAttempt(Document *document, void *userData);
|
||||
void NotifySavePoint(Document *document, void *userData, bool atSavePoint);
|
||||
void NotifyModified(Document *document, DocModification mh, void *userData);
|
||||
void NotifyDeleted(Document *document, void *userData);
|
||||
|
||||
#ifdef MACRO_SUPPORT
|
||||
void NotifyMacroRecord(UINT iMessage, WPARAM wParam, LPARAM lParam);
|
||||
#endif
|
||||
|
||||
void PageMove(int direction, bool extend=false);
|
||||
virtual int KeyCommand(UINT iMessage);
|
||||
virtual int KeyDefault(int /* key */, int /*modifiers*/);
|
||||
int KeyDown(int key, bool shift, bool ctrl, bool alt);
|
||||
|
||||
bool GetWhitespaceVisible();
|
||||
void SetWhitespaceVisible(bool view);
|
||||
|
||||
void Indent(bool forwards);
|
||||
|
||||
long FindText(UINT iMessage,WPARAM wParam,LPARAM lParam);
|
||||
void SearchAnchor();
|
||||
long SearchText(UINT iMessage,WPARAM wParam,LPARAM lParam);
|
||||
void GoToLine(int lineNo);
|
||||
|
||||
char *CopyRange(int start, int end);
|
||||
int SelectionRangeLength();
|
||||
char *CopySelectionRange();
|
||||
void CopySelectionIntoDrag();
|
||||
void SetDragPosition(int newPos);
|
||||
virtual void StartDrag();
|
||||
void DropAt(int position, const char *value, bool moving, bool rectangular);
|
||||
// PositionInSelection returns 0 if position in selection, -1 if position before selection, and 1 if after.
|
||||
// Before means either before any line of selection or before selection on its line, with a similar meaning to after
|
||||
int PositionInSelection(int pos);
|
||||
bool PointInSelection(Point pt);
|
||||
bool PointInSelMargin(Point pt);
|
||||
virtual void ButtonDown(Point pt, unsigned int curTime, bool shift, bool ctrl, bool alt);
|
||||
void ButtonMove(Point pt);
|
||||
void ButtonUp(Point pt, unsigned int curTime, bool ctrl);
|
||||
|
||||
void Tick();
|
||||
virtual void SetTicking(bool on) = 0;
|
||||
virtual void SetMouseCapture(bool on) = 0;
|
||||
virtual bool HaveMouseCapture() = 0;
|
||||
|
||||
void CheckForChangeOutsidePaint(Range r);
|
||||
int BraceMatch(int position, int maxReStyle);
|
||||
void SetBraceHighlight(Position pos0, Position pos1, int matchStyle);
|
||||
|
||||
void SetDocPointer(Document *document);
|
||||
|
||||
void Expand(int &line, bool doExpand);
|
||||
void ToggleContraction(int line);
|
||||
void EnsureLineVisible(int line);
|
||||
|
||||
virtual LRESULT DefWndProc(UINT iMessage, WPARAM wParam, LPARAM lParam) = 0;
|
||||
|
||||
public:
|
||||
// Public so scintilla_send_message can use it
|
||||
virtual LRESULT WndProc(UINT iMessage, WPARAM wParam, LPARAM lParam);
|
||||
// Public so scintilla_set_id can use it
|
||||
int ctrlID;
|
||||
};
|
||||
|
||||
#endif
|
45
contrib/src/stc/scintilla/src/Indicator.cxx
Normal file
45
contrib/src/stc/scintilla/src/Indicator.cxx
Normal file
@@ -0,0 +1,45 @@
|
||||
// Scintilla source code edit control
|
||||
// Indicator.cxx - defines the style of indicators which are text decorations such as underlining
|
||||
// Copyright 1998-2000 by Neil Hodgson <neilh@scintilla.org>
|
||||
// The License.txt file describes the conditions under which this software may be distributed.
|
||||
|
||||
#include "Platform.h"
|
||||
|
||||
#include "Scintilla.h"
|
||||
#include "Indicator.h"
|
||||
|
||||
void Indicator::Draw(Surface *surface, PRectangle &rc) {
|
||||
surface->PenColour(fore.allocated);
|
||||
int ymid = (rc.bottom + rc.top) / 2;
|
||||
if (style == INDIC_SQUIGGLE) {
|
||||
surface->MoveTo(rc.left, rc.top);
|
||||
int x = rc.left + 2;
|
||||
int y = 2;
|
||||
while (x < rc.right) {
|
||||
surface->LineTo(x, rc.top + y);
|
||||
x += 2;
|
||||
y = 2 - y;
|
||||
}
|
||||
surface->LineTo(rc.right, rc.top + y); // Finish the line
|
||||
} else if (style == INDIC_TT) {
|
||||
surface->MoveTo(rc.left, ymid);
|
||||
int x = rc.left + 5;
|
||||
while (x < rc.right) {
|
||||
surface->LineTo(x, ymid);
|
||||
surface->MoveTo(x-3, ymid);
|
||||
surface->LineTo(x-3, ymid+2);
|
||||
x++;
|
||||
surface->MoveTo(x, ymid);
|
||||
x += 5;
|
||||
}
|
||||
surface->LineTo(rc.right, ymid); // Finish the line
|
||||
if (x - 3 <= rc.right) {
|
||||
surface->MoveTo(x-3, ymid);
|
||||
surface->LineTo(x-3, ymid+2);
|
||||
}
|
||||
} else { // Either INDIC_PLAIN or unknown
|
||||
surface->MoveTo(rc.left, ymid);
|
||||
surface->LineTo(rc.right, ymid);
|
||||
}
|
||||
}
|
||||
|
18
contrib/src/stc/scintilla/src/Indicator.h
Normal file
18
contrib/src/stc/scintilla/src/Indicator.h
Normal file
@@ -0,0 +1,18 @@
|
||||
// Scintilla source code edit control
|
||||
// Indicator.h - defines the style of indicators which are text decorations such as underlining
|
||||
// Copyright 1998-2000 by Neil Hodgson <neilh@scintilla.org>
|
||||
// The License.txt file describes the conditions under which this software may be distributed.
|
||||
|
||||
#ifndef INDICATOR_H
|
||||
#define INDICATOR_H
|
||||
|
||||
class Indicator {
|
||||
public:
|
||||
int style;
|
||||
ColourPair fore;
|
||||
Indicator() : style(INDIC_PLAIN), fore(Colour(0,0,0)) {
|
||||
}
|
||||
void Draw(Surface *surface, PRectangle &rc);
|
||||
};
|
||||
|
||||
#endif
|
111
contrib/src/stc/scintilla/src/KeyMap.cxx
Normal file
111
contrib/src/stc/scintilla/src/KeyMap.cxx
Normal file
@@ -0,0 +1,111 @@
|
||||
// Scintilla source code edit control
|
||||
// KeyMap.cxx - defines a mapping between keystrokes and commands
|
||||
// Copyright 1998-2000 by Neil Hodgson <neilh@scintilla.org>
|
||||
// The License.txt file describes the conditions under which this software may be distributed.
|
||||
|
||||
#include "Platform.h"
|
||||
|
||||
#include "Scintilla.h"
|
||||
|
||||
#include "KeyMap.h"
|
||||
|
||||
KeyMap::KeyMap() : kmap(0), len(0), alloc(0) {
|
||||
for (int i = 0; MapDefault[i].key; i++) {
|
||||
AssignCmdKey(MapDefault[i].key,
|
||||
MapDefault[i].modifiers,
|
||||
MapDefault[i].msg);
|
||||
}
|
||||
}
|
||||
|
||||
KeyMap::~KeyMap() {
|
||||
Clear();
|
||||
}
|
||||
|
||||
void KeyMap::Clear() {
|
||||
delete []kmap;
|
||||
kmap = 0;
|
||||
len = 0;
|
||||
alloc = 0;
|
||||
}
|
||||
|
||||
void KeyMap::AssignCmdKey(int key, int modifiers, UINT msg) {
|
||||
if ((len+1) >= alloc) {
|
||||
KeyToCommand *ktcNew = new KeyToCommand[alloc + 5];
|
||||
if (!ktcNew)
|
||||
return;
|
||||
for (int k=0;k<len;k++)
|
||||
ktcNew[k] = kmap[k];
|
||||
alloc += 5;
|
||||
delete []kmap;
|
||||
kmap = ktcNew;
|
||||
}
|
||||
for (int keyIndex = 0; keyIndex < len; keyIndex++) {
|
||||
if ((key == kmap[keyIndex].key) && (modifiers == kmap[keyIndex].modifiers)) {
|
||||
kmap[keyIndex].msg = msg;
|
||||
return;
|
||||
}
|
||||
}
|
||||
kmap[len].key = key;
|
||||
kmap[len].modifiers = modifiers;
|
||||
kmap[len].msg = msg;
|
||||
len++;
|
||||
}
|
||||
|
||||
UINT KeyMap::Find(int key, int modifiers) {
|
||||
for (int i=0; i < len; i++) {
|
||||
if ((key == kmap[i].key) && (modifiers == kmap[i].modifiers)) {
|
||||
return kmap[i].msg;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
KeyToCommand KeyMap::MapDefault[] = {
|
||||
VK_DOWN, SCI_NORM, SCI_LINEDOWN,
|
||||
VK_DOWN, SCI_SHIFT, SCI_LINEDOWNEXTEND,
|
||||
VK_UP, SCI_NORM, SCI_LINEUP,
|
||||
VK_UP, SCI_SHIFT, SCI_LINEUPEXTEND,
|
||||
VK_LEFT, SCI_NORM, SCI_CHARLEFT,
|
||||
VK_LEFT, SCI_SHIFT, SCI_CHARLEFTEXTEND,
|
||||
VK_LEFT, SCI_CTRL, SCI_WORDLEFT,
|
||||
VK_LEFT, SCI_CSHIFT, SCI_WORDLEFTEXTEND,
|
||||
VK_RIGHT, SCI_NORM, SCI_CHARRIGHT,
|
||||
VK_RIGHT, SCI_SHIFT, SCI_CHARRIGHTEXTEND,
|
||||
VK_RIGHT, SCI_CTRL, SCI_WORDRIGHT,
|
||||
VK_RIGHT, SCI_CSHIFT, SCI_WORDRIGHTEXTEND,
|
||||
VK_HOME, SCI_NORM, SCI_VCHOME,
|
||||
VK_HOME, SCI_SHIFT, SCI_VCHOMEEXTEND,
|
||||
VK_HOME, SCI_CTRL, SCI_DOCUMENTSTART,
|
||||
VK_HOME, SCI_CSHIFT, SCI_DOCUMENTSTARTEXTEND,
|
||||
VK_END, SCI_NORM, SCI_LINEEND,
|
||||
VK_END, SCI_SHIFT, SCI_LINEENDEXTEND,
|
||||
VK_END, SCI_CTRL, SCI_DOCUMENTEND,
|
||||
VK_END, SCI_CSHIFT, SCI_DOCUMENTENDEXTEND,
|
||||
VK_PRIOR, SCI_NORM, SCI_PAGEUP,
|
||||
VK_PRIOR, SCI_SHIFT, SCI_PAGEUPEXTEND,
|
||||
VK_NEXT, SCI_NORM, SCI_PAGEDOWN,
|
||||
VK_NEXT, SCI_SHIFT, SCI_PAGEDOWNEXTEND,
|
||||
VK_DELETE, SCI_NORM, WM_CLEAR,
|
||||
VK_DELETE, SCI_SHIFT, WM_CUT,
|
||||
VK_DELETE, SCI_CTRL, SCI_DELWORDRIGHT,
|
||||
VK_INSERT, SCI_NORM, SCI_EDITTOGGLEOVERTYPE,
|
||||
VK_INSERT, SCI_SHIFT, WM_PASTE,
|
||||
VK_INSERT, SCI_CTRL, WM_COPY,
|
||||
VK_ESCAPE, SCI_NORM, SCI_CANCEL,
|
||||
VK_BACK, SCI_NORM, SCI_DELETEBACK,
|
||||
VK_BACK, SCI_CTRL, SCI_DELWORDLEFT,
|
||||
'Z', SCI_CTRL, WM_UNDO,
|
||||
'Y', SCI_CTRL, SCI_REDO,
|
||||
'X', SCI_CTRL, WM_CUT,
|
||||
'C', SCI_CTRL, WM_COPY,
|
||||
'V', SCI_CTRL, WM_PASTE,
|
||||
'A', SCI_CTRL, SCI_SELECTALL,
|
||||
VK_TAB, SCI_NORM, SCI_TAB,
|
||||
VK_TAB, SCI_SHIFT, SCI_BACKTAB,
|
||||
VK_RETURN, SCI_NORM, SCI_NEWLINE,
|
||||
'L', SCI_CTRL, SCI_FORMFEED,
|
||||
VK_ADD, SCI_CTRL, SCI_ZOOMIN,
|
||||
VK_SUBTRACT, SCI_CTRL, SCI_ZOOMOUT,
|
||||
0,0,0,
|
||||
};
|
||||
|
35
contrib/src/stc/scintilla/src/KeyMap.h
Normal file
35
contrib/src/stc/scintilla/src/KeyMap.h
Normal file
@@ -0,0 +1,35 @@
|
||||
// Scintilla source code edit control
|
||||
// KeyMap.h - defines a mapping between keystrokes and commands
|
||||
// Copyright 1998-2000 by Neil Hodgson <neilh@scintilla.org>
|
||||
// The License.txt file describes the conditions under which this software may be distributed.
|
||||
|
||||
#ifndef KEYTOCOMMAND_H
|
||||
#define KEYTOCOMMAND_H
|
||||
|
||||
#define SCI_NORM 0
|
||||
#define SCI_SHIFT SHIFT_PRESSED
|
||||
#define SCI_CTRL LEFT_CTRL_PRESSED
|
||||
#define SCI_ALT LEFT_ALT_PRESSED
|
||||
#define SCI_CSHIFT (SCI_CTRL | SCI_SHIFT)
|
||||
|
||||
class KeyToCommand {
|
||||
public:
|
||||
int key;
|
||||
int modifiers;
|
||||
UINT msg;
|
||||
};
|
||||
|
||||
class KeyMap {
|
||||
KeyToCommand *kmap;
|
||||
int len;
|
||||
int alloc;
|
||||
static KeyToCommand MapDefault[];
|
||||
public:
|
||||
KeyMap();
|
||||
~KeyMap();
|
||||
void Clear();
|
||||
void AssignCmdKey(int key, int modifiers, UINT msg);
|
||||
UINT Find(int key, int modifiers); // 0 returned on failure
|
||||
};
|
||||
|
||||
#endif
|
2217
contrib/src/stc/scintilla/src/KeyWords.cxx
Normal file
2217
contrib/src/stc/scintilla/src/KeyWords.cxx
Normal file
File diff suppressed because it is too large
Load Diff
125
contrib/src/stc/scintilla/src/LineMarker.cxx
Normal file
125
contrib/src/stc/scintilla/src/LineMarker.cxx
Normal file
@@ -0,0 +1,125 @@
|
||||
// Scintilla source code edit control
|
||||
// LineMarker.cxx - defines the look of a line marker in the margin
|
||||
// Copyright 1998-2000 by Neil Hodgson <neilh@scintilla.org>
|
||||
// The License.txt file describes the conditions under which this software may be distributed.
|
||||
|
||||
#include "Platform.h"
|
||||
|
||||
#include "Scintilla.h"
|
||||
#include "LineMarker.h"
|
||||
|
||||
void LineMarker::Draw(Surface *surface, PRectangle &rc) {
|
||||
int minDim = Platform::Minimum(rc.Width(), rc.Height());
|
||||
minDim--; // Ensure does not go beyond edge
|
||||
int centreX = (rc.right + rc.left) / 2;
|
||||
int centreY = (rc.bottom + rc.top) / 2;
|
||||
int dimOn2 = minDim / 2;
|
||||
int dimOn4 = minDim / 4;
|
||||
if (rc.Width() > (rc.Height() * 2)) {
|
||||
// Wide column is line number so move to left to try to avoid overlapping number
|
||||
centreX = rc.left + dimOn2 + 1;
|
||||
}
|
||||
if (markType == SC_MARK_ROUNDRECT) {
|
||||
PRectangle rcRounded = rc;
|
||||
rcRounded.left = rc.left + 1;
|
||||
rcRounded.right = rc.right - 1;
|
||||
surface->RoundedRectangle(rcRounded, fore.allocated, back.allocated);
|
||||
} else if (markType == SC_MARK_CIRCLE) {
|
||||
PRectangle rcCircle;
|
||||
rcCircle.left = centreX - dimOn2;
|
||||
rcCircle.top = centreY - dimOn2;
|
||||
rcCircle.right = centreX + dimOn2;
|
||||
rcCircle.bottom = centreY + dimOn2;
|
||||
surface->Ellipse(rcCircle, fore.allocated, back.allocated);
|
||||
} else if (markType == SC_MARK_ARROW) {
|
||||
Point pts[] = {
|
||||
Point(centreX - dimOn4, centreY - dimOn2),
|
||||
Point(centreX - dimOn4, centreY + dimOn2),
|
||||
Point(centreX + dimOn2 - dimOn4, centreY),
|
||||
};
|
||||
surface->Polygon(pts, sizeof(pts) / sizeof(pts[0]),
|
||||
fore.allocated, back.allocated);
|
||||
|
||||
} else if (markType == SC_MARK_ARROWDOWN) {
|
||||
Point pts[] = {
|
||||
Point(centreX - dimOn2, centreY - dimOn4),
|
||||
Point(centreX + dimOn2, centreY - dimOn4),
|
||||
Point(centreX, centreY + dimOn2 - dimOn4),
|
||||
};
|
||||
surface->Polygon(pts, sizeof(pts) / sizeof(pts[0]),
|
||||
fore.allocated, back.allocated);
|
||||
|
||||
} else if (markType == SC_MARK_PLUS) {
|
||||
int armSize = dimOn2-2;
|
||||
Point xpts[] = {
|
||||
Point(centreX - armSize, centreY),
|
||||
Point(centreX, centreY),
|
||||
Point(centreX, centreY - armSize),
|
||||
Point(centreX, centreY - armSize),
|
||||
Point(centreX, centreY),
|
||||
Point(centreX + armSize, centreY),
|
||||
Point(centreX + armSize, centreY),
|
||||
Point(centreX, centreY),
|
||||
Point(centreX, centreY + armSize),
|
||||
Point(centreX, centreY + armSize),
|
||||
Point(centreX, centreY),
|
||||
Point(centreX - armSize, centreY),
|
||||
};
|
||||
Point pts[] = {
|
||||
Point(centreX - armSize, centreY - 1),
|
||||
Point(centreX - 1, centreY - 1),
|
||||
Point(centreX - 1, centreY - armSize),
|
||||
Point(centreX + 1, centreY - armSize),
|
||||
Point(centreX + 1, centreY - 1),
|
||||
Point(centreX + armSize, centreY -1),
|
||||
Point(centreX + armSize, centreY +1),
|
||||
Point(centreX + 1, centreY + 1),
|
||||
Point(centreX + 1, centreY + armSize),
|
||||
Point(centreX - 1, centreY + armSize),
|
||||
Point(centreX - 1, centreY + 1),
|
||||
Point(centreX - armSize, centreY + 1),
|
||||
};
|
||||
surface->Polygon(pts, sizeof(pts) / sizeof(pts[0]),
|
||||
fore.allocated, back.allocated);
|
||||
|
||||
} else if (markType == SC_MARK_MINUS) {
|
||||
int armSize = dimOn2-2;
|
||||
Point pts[] = {
|
||||
Point(centreX - armSize, centreY - 1),
|
||||
Point(centreX + armSize, centreY -1),
|
||||
Point(centreX + armSize, centreY +1),
|
||||
Point(centreX - armSize, centreY + 1),
|
||||
};
|
||||
Point xpts[] = {
|
||||
Point(centreX - armSize, centreY),
|
||||
Point(centreX + armSize, centreY),
|
||||
Point(centreX + armSize, centreY),
|
||||
Point(centreX - armSize, centreY),
|
||||
};
|
||||
surface->Polygon(pts, sizeof(pts) / sizeof(pts[0]),
|
||||
fore.allocated, back.allocated);
|
||||
|
||||
} else if (markType == SC_MARK_SMALLRECT) {
|
||||
PRectangle rcSmall;
|
||||
rcSmall.left = rc.left + 1;
|
||||
rcSmall.top = rc.top + 2;
|
||||
rcSmall.right = rc.right - 1;
|
||||
rcSmall.bottom = rc.bottom - 2;
|
||||
surface->RectangleDraw(rcSmall, fore.allocated, back.allocated);
|
||||
} else if (markType == SC_MARK_EMPTY) {
|
||||
// An invisible marker so don't draw anything
|
||||
} else { // SC_MARK_SHORTARROW
|
||||
Point pts[] = {
|
||||
Point(centreX, centreY + dimOn2),
|
||||
Point(centreX + dimOn2, centreY),
|
||||
Point(centreX, centreY - dimOn2),
|
||||
Point(centreX, centreY - dimOn4),
|
||||
Point(centreX - dimOn4, centreY - dimOn4),
|
||||
Point(centreX - dimOn4, centreY + dimOn4),
|
||||
Point(centreX, centreY + dimOn4),
|
||||
Point(centreX, centreY + dimOn2),
|
||||
};
|
||||
surface->Polygon(pts, sizeof(pts) / sizeof(pts[0]),
|
||||
fore.allocated, back.allocated);
|
||||
}
|
||||
}
|
22
contrib/src/stc/scintilla/src/LineMarker.h
Normal file
22
contrib/src/stc/scintilla/src/LineMarker.h
Normal file
@@ -0,0 +1,22 @@
|
||||
// Scintilla source code edit control
|
||||
// LineMarker.h - defines the look of a line marker in the margin
|
||||
// Copyright 1998-2000 by Neil Hodgson <neilh@scintilla.org>
|
||||
// The License.txt file describes the conditions under which this software may be distributed.
|
||||
|
||||
#ifndef LINEMARKER_H
|
||||
#define LINEMARKER_H
|
||||
|
||||
class LineMarker {
|
||||
public:
|
||||
int markType;
|
||||
ColourPair fore;
|
||||
ColourPair back;
|
||||
LineMarker() {
|
||||
markType = SC_MARK_CIRCLE;
|
||||
fore = Colour(0,0,0);
|
||||
back = Colour(0xff,0xff,0xff);
|
||||
}
|
||||
void Draw(Surface *surface, PRectangle &rc);
|
||||
};
|
||||
|
||||
#endif
|
399
contrib/src/stc/scintilla/src/PropSet.cxx
Normal file
399
contrib/src/stc/scintilla/src/PropSet.cxx
Normal file
@@ -0,0 +1,399 @@
|
||||
// SciTE - Scintilla based Text Editor
|
||||
// PropSet.cxx - a java style properties file module
|
||||
// Copyright 1998-2000 by Neil Hodgson <neilh@scintilla.org>
|
||||
// The License.txt file describes the conditions under which this software may be distributed.
|
||||
|
||||
// Maintain a dictionary of properties
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "Platform.h"
|
||||
|
||||
#include "PropSet.h"
|
||||
|
||||
bool EqualCaseInsensitive(const char *a, const char *b) {
|
||||
#if PLAT_GTK
|
||||
return 0 == strcasecmp(a, b);
|
||||
#elif PLAT_WIN
|
||||
return 0 == stricmp(a, b);
|
||||
#elif PLAT_WX
|
||||
return 0 == wxStricmp(a, b);
|
||||
#endif
|
||||
}
|
||||
|
||||
// Get a line of input. If end of line escaped with '\\' then continue reading.
|
||||
static bool GetFullLine(const char *&fpc, int &lenData, char *s, int len) {
|
||||
bool continuation = true;
|
||||
while ((len > 1) && lenData > 0) {
|
||||
char ch = *fpc;
|
||||
fpc++;
|
||||
lenData--;
|
||||
if ((ch == '\r') || (ch == '\n')) {
|
||||
if (!continuation) {
|
||||
if ((lenData > 0) && (ch == '\r') && ((*fpc) == '\n')) {
|
||||
// munch the second half of a crlf
|
||||
fpc++;
|
||||
lenData--;
|
||||
}
|
||||
*s++ = '\0';
|
||||
return true;
|
||||
}
|
||||
} else if ((ch == '\\') && (lenData > 0) && ((*fpc == '\r') || (*fpc == '\n'))) {
|
||||
continuation = true;
|
||||
} else {
|
||||
continuation = false;
|
||||
*s++ = ch;
|
||||
len--;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
PropSet::PropSet() {
|
||||
superPS = 0;
|
||||
size = 10;
|
||||
used = 0;
|
||||
vals = new char * [size];
|
||||
}
|
||||
|
||||
PropSet::~PropSet() {
|
||||
superPS = 0;
|
||||
Clear();
|
||||
delete []vals;
|
||||
}
|
||||
|
||||
void PropSet::EnsureCanAddEntry() {
|
||||
if (used >= size - 2) {
|
||||
int newsize = size + 10;
|
||||
char **newvals = new char * [newsize];
|
||||
|
||||
for (int i = 0; i < used; i++) {
|
||||
newvals[i] = vals[i];
|
||||
}
|
||||
delete []vals;
|
||||
vals = newvals;
|
||||
size = newsize;
|
||||
}
|
||||
}
|
||||
|
||||
void PropSet::Set(const char *key, const char *val) {
|
||||
EnsureCanAddEntry();
|
||||
for (int i = 0; i < used; i += 2) {
|
||||
if (EqualCaseInsensitive(vals[i], key)) {
|
||||
// Replace current value
|
||||
delete [](vals[i + 1]);
|
||||
vals[i + 1] = StringDup(val);
|
||||
return;
|
||||
}
|
||||
}
|
||||
// Not found
|
||||
vals[used++] = StringDup(key);
|
||||
vals[used++] = StringDup(val);
|
||||
}
|
||||
|
||||
void PropSet::Set(char *keyval) {
|
||||
char *eqat = strchr(keyval, '=');
|
||||
if (eqat) {
|
||||
*eqat = '\0';
|
||||
Set(keyval, eqat + 1);
|
||||
*eqat = '=';
|
||||
}
|
||||
}
|
||||
|
||||
SString PropSet::Get(const char *key) {
|
||||
for (int i = 0; i < used; i += 2) {
|
||||
if (EqualCaseInsensitive(vals[i], key)) {
|
||||
return vals[i + 1];
|
||||
}
|
||||
}
|
||||
if (superPS) {
|
||||
// Failed here, so try in base property set
|
||||
return superPS->Get(key);
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
int PropSet::GetInt(const char *key, int defaultValue) {
|
||||
SString val = Get(key);
|
||||
if (val.length())
|
||||
return Get(key).value();
|
||||
else
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
bool isprefix(const char *target, const char *prefix) {
|
||||
while (*target && *prefix) {
|
||||
if (toupper(*target) != toupper(*prefix))
|
||||
return false;
|
||||
target++;
|
||||
prefix++;
|
||||
}
|
||||
if (*prefix)
|
||||
return false;
|
||||
else
|
||||
return true;
|
||||
}
|
||||
|
||||
bool issuffix(const char *target, const char *suffix) {
|
||||
int lentarget = strlen(target);
|
||||
int lensuffix = strlen(suffix);
|
||||
if (lensuffix > lentarget)
|
||||
return false;
|
||||
for (int i = lensuffix - 1; i >= 0; i--) {
|
||||
if (toupper(target[i + lentarget - lensuffix]) != toupper(suffix[i]))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
SString PropSet::GetWild(const char *keybase, const char *filename) {
|
||||
for (int i = 0; i < used; i += 2) {
|
||||
if (isprefix(vals[i], keybase)) {
|
||||
char *orgkeyfile = vals[i] + strlen(keybase);
|
||||
char *keyfile = NULL;
|
||||
|
||||
if (strstr(orgkeyfile, "$(") == orgkeyfile) {
|
||||
char *cpendvar = strchr(orgkeyfile, ')');
|
||||
if (cpendvar) {
|
||||
int lenvar = cpendvar - orgkeyfile - 2; // Subtract the $()
|
||||
char *var = static_cast<char *>(malloc(lenvar + 1));
|
||||
strncpy(var, orgkeyfile + 2, lenvar);
|
||||
var[lenvar] = '\0';
|
||||
SString s = Get(var);
|
||||
free(var);
|
||||
keyfile = strdup(s.c_str());
|
||||
}
|
||||
}
|
||||
char *keyptr = keyfile;
|
||||
|
||||
if (keyfile == NULL)
|
||||
keyfile = orgkeyfile;
|
||||
|
||||
for (; ; ) {
|
||||
char *del = strchr(keyfile, ';');
|
||||
if (del == NULL)
|
||||
del = keyfile + strlen(keyfile);
|
||||
char delchr = *del;
|
||||
*del = '\0';
|
||||
if (*keyfile == '*') {
|
||||
if (issuffix(filename, keyfile + 1)) {
|
||||
*del = delchr;
|
||||
free(keyptr);
|
||||
return vals[i + 1];
|
||||
}
|
||||
} else if (EqualCaseInsensitive(keyfile, filename)) {
|
||||
*del = delchr;
|
||||
free(keyptr);
|
||||
return vals[i + 1];
|
||||
}
|
||||
if (delchr == '\0')
|
||||
break;
|
||||
*del = delchr;
|
||||
keyfile = del + 1;
|
||||
}
|
||||
free(keyptr);
|
||||
|
||||
if (EqualCaseInsensitive(vals[i], keybase)) {
|
||||
return vals[i + 1];
|
||||
}
|
||||
}
|
||||
}
|
||||
if (superPS) {
|
||||
// Failed here, so try in base property set
|
||||
return superPS->GetWild(keybase, filename);
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
SString PropSet::GetNewExpand(const char *keybase, const char *filename) {
|
||||
char *base = StringDup(GetWild(keybase, filename).c_str());
|
||||
char *cpvar = strstr(base, "$(");
|
||||
while (cpvar) {
|
||||
char *cpendvar = strchr(cpvar, ')');
|
||||
if (cpendvar) {
|
||||
int lenvar = cpendvar - cpvar - 2; // Subtract the $()
|
||||
char *var = new char[lenvar + 1];
|
||||
strncpy(var, cpvar + 2, lenvar);
|
||||
var[lenvar] = '\0';
|
||||
SString val = GetWild(var, filename);
|
||||
int newlenbase = strlen(base) + val.length() - lenvar;
|
||||
char *newbase = new char[newlenbase];
|
||||
strncpy(newbase, base, cpvar - base);
|
||||
strcpy(newbase + (cpvar - base), val.c_str());
|
||||
strcpy(newbase + (cpvar - base) + val.length(), cpendvar + 1);
|
||||
delete []var;
|
||||
delete []base;
|
||||
base = newbase;
|
||||
}
|
||||
cpvar = strstr(base, "$(");
|
||||
}
|
||||
SString sret = base;
|
||||
delete []base;
|
||||
return sret;
|
||||
}
|
||||
|
||||
void PropSet::Clear() {
|
||||
for (int i = 0; i < used; i++) {
|
||||
delete [](vals[i]);
|
||||
vals[i] = 0;
|
||||
}
|
||||
used = 0;
|
||||
}
|
||||
|
||||
void PropSet::ReadFromMemory(const char *data, int len) {
|
||||
if (len > 0) {
|
||||
const char *pd = data;
|
||||
char linebuf[60000];
|
||||
while (GetFullLine(pd, len, linebuf, sizeof(linebuf))) {
|
||||
if (isalpha(linebuf[0]))
|
||||
Set(linebuf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PropSet::Read(const char *filename) {
|
||||
//printf("Opening properties <%s>\n", filename);
|
||||
Clear();
|
||||
char propsData[60000];
|
||||
FILE *rcfile = fopen(filename, "rb");
|
||||
if (rcfile) {
|
||||
int lenFile = fread(propsData, 1, sizeof(propsData), rcfile);
|
||||
fclose(rcfile);
|
||||
ReadFromMemory(propsData, lenFile);
|
||||
} else {
|
||||
//printf("Could not open <%s>\n", filename);
|
||||
}
|
||||
}
|
||||
|
||||
static bool iswordsep(char ch, bool onlyLineEnds) {
|
||||
if (!isspace(ch))
|
||||
return false;
|
||||
if (!onlyLineEnds)
|
||||
return true;
|
||||
return ch == '\r' || ch == '\n';
|
||||
}
|
||||
|
||||
// Creates an array that points into each word in the string and puts \0 terminators
|
||||
// after each word.
|
||||
static char **ArrayFromWordList(char *wordlist, bool onlyLineEnds = false) {
|
||||
char prev = '\n';
|
||||
int words = 0;
|
||||
for (int j = 0; wordlist[j]; j++) {
|
||||
if (!iswordsep(wordlist[j], onlyLineEnds) && iswordsep(prev, onlyLineEnds))
|
||||
words++;
|
||||
prev = wordlist[j];
|
||||
}
|
||||
char **keywords = new char * [words + 1];
|
||||
if (keywords) {
|
||||
words = 0;
|
||||
prev = '\0';
|
||||
int len = strlen(wordlist);
|
||||
for (int k = 0; k < len; k++) {
|
||||
if (!iswordsep(wordlist[k], onlyLineEnds)) {
|
||||
if (!prev) {
|
||||
keywords[words] = &wordlist[k];
|
||||
words++;
|
||||
}
|
||||
} else {
|
||||
wordlist[k] = '\0';
|
||||
}
|
||||
prev = wordlist[k];
|
||||
}
|
||||
keywords[words] = &wordlist[len];
|
||||
}
|
||||
return keywords;
|
||||
}
|
||||
|
||||
void WordList::Clear() {
|
||||
if (words) {
|
||||
delete []words;
|
||||
delete []list;
|
||||
}
|
||||
words = 0;
|
||||
list = 0;
|
||||
len = 0;
|
||||
}
|
||||
|
||||
void WordList::Set(const char *s) {
|
||||
len = 0;
|
||||
list = StringDup(s);
|
||||
words = ArrayFromWordList(list, onlyLineEnds);
|
||||
}
|
||||
|
||||
char *WordList::Allocate(int size) {
|
||||
list = new char[size + 1];
|
||||
list[size] = '\0';
|
||||
return list;
|
||||
}
|
||||
|
||||
void WordList::SetFromAllocated() {
|
||||
len = 0;
|
||||
words = ArrayFromWordList(list, onlyLineEnds);
|
||||
}
|
||||
|
||||
// Shell sort based upon public domain C implementation by Raymond Gardner 1991
|
||||
// Used here because of problems with mingw qsort.
|
||||
static void SortWordList(char **words, unsigned int len) {
|
||||
unsigned int gap = len / 2;
|
||||
|
||||
while (gap > 0) {
|
||||
unsigned int i = gap;
|
||||
while (i < len) {
|
||||
unsigned int j = i;
|
||||
char **a = words + j;
|
||||
do {
|
||||
j -= gap;
|
||||
char **b = a;
|
||||
a -= gap;
|
||||
if (strcmp(*a, *b) > 0) {
|
||||
char *tmp = *a;
|
||||
*a = *b;
|
||||
*b = tmp;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
} while (j >= gap);
|
||||
i++;
|
||||
}
|
||||
gap = gap / 2;
|
||||
}
|
||||
}
|
||||
|
||||
bool WordList::InList(const char *s) {
|
||||
if (0 == words)
|
||||
return false;
|
||||
if (len == 0) {
|
||||
for (int i = 0; words[i][0]; i++)
|
||||
len++;
|
||||
SortWordList(words, len);
|
||||
for (int k = 0; k < (sizeof(starts) / sizeof(starts[0])); k++)
|
||||
starts[k] = -1;
|
||||
for (int l = len - 1; l >= 0; l--) {
|
||||
unsigned char indexChar = words[l][0];
|
||||
starts[indexChar] = l;
|
||||
}
|
||||
}
|
||||
unsigned char firstChar = s[0];
|
||||
int j = starts[firstChar];
|
||||
if (j >= 0) {
|
||||
while (words[j][0] == firstChar) {
|
||||
if (s[1] == words[j][1]) {
|
||||
const char *a = words[j] + 1;
|
||||
const char *b = s + 1;
|
||||
while (*a && *a == *b) {
|
||||
a++;
|
||||
b++;
|
||||
}
|
||||
if (!*a && !*b)
|
||||
return true;
|
||||
}
|
||||
j++;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
110
contrib/src/stc/scintilla/src/SVector.h
Normal file
110
contrib/src/stc/scintilla/src/SVector.h
Normal file
@@ -0,0 +1,110 @@
|
||||
// Scintilla source code edit control
|
||||
// SVector.h - a simple expandable vector
|
||||
// Copyright 1998-1999 by Neil Hodgson <neilh@hare.net.au>
|
||||
// The License.txt file describes the conditions under which this software may be distributed.
|
||||
|
||||
#ifndef SVECTOR_H
|
||||
#define SVECTOR_H
|
||||
|
||||
// A simple expandable vector.
|
||||
// T must support assignment.
|
||||
// Storage not allocated for elements until an element is used.
|
||||
// This makes it very lightweight unless used so is a good match for optional features.
|
||||
template<class T, int sizeIncrement>
|
||||
class SVector {
|
||||
T *v;
|
||||
unsigned int size; // Number of elements allocated
|
||||
unsigned int len; // Number of elements in vector
|
||||
bool allocFailure; // A memory allocation call has failed
|
||||
|
||||
// Internally allocate more elements than the user wants to avoid
|
||||
// thrashng the memory allocator
|
||||
void SizeTo(int newSize) {
|
||||
if (newSize < sizeIncrement)
|
||||
newSize += sizeIncrement;
|
||||
else
|
||||
newSize = (newSize * 3) / 2;
|
||||
T* newv = new T[newSize];
|
||||
if (!newv) {
|
||||
allocFailure = true;
|
||||
return;
|
||||
}
|
||||
size = newSize;
|
||||
for (int i=0; i<len; i++) {
|
||||
newv[i] = v[i];
|
||||
}
|
||||
delete []v;
|
||||
v = newv;
|
||||
}
|
||||
|
||||
public:
|
||||
SVector() {
|
||||
allocFailure = false;
|
||||
v = 0;
|
||||
len = 0;
|
||||
size = 0;
|
||||
}
|
||||
~SVector() {
|
||||
Free();
|
||||
}
|
||||
SVector(const SVector &other) {
|
||||
allocFailure = false;
|
||||
v = 0;
|
||||
len = 0;
|
||||
size = 0;
|
||||
if (other.Length() > 0) {
|
||||
SizeTo(other.Length());
|
||||
if (!allocFailure) {
|
||||
for (int i=0;i<other.Length();i++)
|
||||
v[i] = other.v[i];
|
||||
len = other.Length();
|
||||
}
|
||||
}
|
||||
}
|
||||
SVector &operator=(const SVector &other) {
|
||||
if (this != &other) {
|
||||
delete []v;
|
||||
allocFailure = false;
|
||||
v = 0;
|
||||
len = 0;
|
||||
size = 0;
|
||||
if (other.Length() > 0) {
|
||||
SizeTo(other.Length());
|
||||
if (!allocFailure) {
|
||||
for (int i=0;i<other.Length();i++)
|
||||
v[i] = other.v[i];
|
||||
}
|
||||
len = other.Length();
|
||||
}
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
T &operator[](unsigned int i) {
|
||||
if (i >= len) {
|
||||
if (i >= size) {
|
||||
SizeTo(i);
|
||||
}
|
||||
len = i+1;
|
||||
}
|
||||
return v[i];
|
||||
}
|
||||
void Free() {
|
||||
delete []v;
|
||||
v = 0;
|
||||
size = 0;
|
||||
len = 0;
|
||||
}
|
||||
void SetLength(int newLen) {
|
||||
if (newLength > len) {
|
||||
if (newLength >= size) {
|
||||
SizeTo(newLength);
|
||||
}
|
||||
}
|
||||
len = newLen;
|
||||
}
|
||||
int Length() const {
|
||||
return len;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
399
contrib/src/stc/scintilla/src/ScintillaBase.cxx
Normal file
399
contrib/src/stc/scintilla/src/ScintillaBase.cxx
Normal file
@@ -0,0 +1,399 @@
|
||||
// Scintilla source code edit control
|
||||
// ScintillaBase.cxx - an enhanced subclass of Editor with calltips, autocomplete and context menu
|
||||
// Copyright 1998-2000 by Neil Hodgson <neilh@scintilla.org>
|
||||
// The License.txt file describes the conditions under which this software may be distributed.
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "Platform.h"
|
||||
|
||||
#include "Scintilla.h"
|
||||
#ifdef SCI_LEXER
|
||||
#include "SciLexer.h"
|
||||
#include "PropSet.h"
|
||||
#include "Accessor.h"
|
||||
#include "KeyWords.h"
|
||||
#endif
|
||||
#include "ContractionState.h"
|
||||
#include "SVector.h"
|
||||
#include "CellBuffer.h"
|
||||
#include "CallTip.h"
|
||||
#include "KeyMap.h"
|
||||
#include "Indicator.h"
|
||||
#include "LineMarker.h"
|
||||
#include "Style.h"
|
||||
#include "ViewStyle.h"
|
||||
#include "AutoComplete.h"
|
||||
#include "Document.h"
|
||||
#include "Editor.h"
|
||||
#include "ScintillaBase.h"
|
||||
|
||||
ScintillaBase::ScintillaBase() {
|
||||
#ifdef SCI_LEXER
|
||||
lexLanguage = SCLEX_CONTAINER;
|
||||
for (int wl=0;wl<numWordLists;wl++)
|
||||
keyWordLists[wl] = new WordList;
|
||||
#endif
|
||||
}
|
||||
|
||||
ScintillaBase::~ScintillaBase() {}
|
||||
|
||||
void ScintillaBase::Finalise() {
|
||||
popup.Destroy();
|
||||
}
|
||||
|
||||
void ScintillaBase::RefreshColourPalette(Palette &pal, bool want) {
|
||||
Editor::RefreshColourPalette(pal, want);
|
||||
ct.RefreshColourPalette(pal, want);
|
||||
}
|
||||
|
||||
void ScintillaBase::AddChar(char ch) {
|
||||
bool acActiveBeforeCharAdded = ac.Active();
|
||||
Editor::AddChar(ch);
|
||||
if (acActiveBeforeCharAdded)
|
||||
AutoCompleteChanged(ch);
|
||||
}
|
||||
|
||||
void ScintillaBase::Command(int cmdId) {
|
||||
|
||||
switch (cmdId) {
|
||||
|
||||
case idAutoComplete: // Nothing to do
|
||||
break;
|
||||
|
||||
case idCallTip: // Nothing to do
|
||||
break;
|
||||
|
||||
case idcmdUndo:
|
||||
WndProc(WM_UNDO, 0, 0);
|
||||
break;
|
||||
|
||||
case idcmdRedo:
|
||||
WndProc(SCI_REDO, 0, 0);
|
||||
break;
|
||||
|
||||
case idcmdCut:
|
||||
WndProc(WM_CUT, 0, 0);
|
||||
break;
|
||||
|
||||
case idcmdCopy:
|
||||
WndProc(WM_COPY, 0, 0);
|
||||
break;
|
||||
|
||||
case idcmdPaste:
|
||||
WndProc(WM_PASTE, 0, 0);
|
||||
break;
|
||||
|
||||
case idcmdDelete:
|
||||
WndProc(WM_CLEAR, 0, 0);
|
||||
break;
|
||||
|
||||
case idcmdSelectAll:
|
||||
WndProc(SCI_SELECTALL, 0, 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int ScintillaBase::KeyCommand(UINT iMessage) {
|
||||
// Most key commands cancel autocompletion mode
|
||||
if (ac.Active()) {
|
||||
switch (iMessage) {
|
||||
// Except for these
|
||||
case SCI_LINEDOWN:
|
||||
AutoCompleteMove(1);
|
||||
return 0;
|
||||
case SCI_LINEUP:
|
||||
AutoCompleteMove( -1);
|
||||
return 0;
|
||||
case SCI_PAGEDOWN:
|
||||
AutoCompleteMove(5);
|
||||
return 0;
|
||||
case SCI_PAGEUP:
|
||||
AutoCompleteMove( -5);
|
||||
return 0;
|
||||
case SCI_VCHOME:
|
||||
AutoCompleteMove( -5000);
|
||||
return 0;
|
||||
case SCI_LINEEND:
|
||||
AutoCompleteMove(5000);
|
||||
return 0;
|
||||
case SCI_DELETEBACK:
|
||||
DelCharBack();
|
||||
AutoCompleteChanged();
|
||||
EnsureCaretVisible();
|
||||
return 0;
|
||||
case SCI_TAB:
|
||||
AutoCompleteCompleted();
|
||||
return 0;
|
||||
|
||||
default:
|
||||
ac.Cancel();
|
||||
}
|
||||
}
|
||||
|
||||
if (ct.inCallTipMode) {
|
||||
if (
|
||||
(iMessage != SCI_CHARLEFT) &&
|
||||
(iMessage != SCI_CHARLEFTEXTEND) &&
|
||||
(iMessage != SCI_CHARRIGHT) &&
|
||||
(iMessage != SCI_CHARLEFTEXTEND) &&
|
||||
(iMessage != SCI_EDITTOGGLEOVERTYPE) &&
|
||||
(iMessage != SCI_DELETEBACK)
|
||||
) {
|
||||
ct.CallTipCancel();
|
||||
}
|
||||
if (iMessage == SCI_DELETEBACK) {
|
||||
if (currentPos <= ct.posStartCallTip) {
|
||||
ct.CallTipCancel();
|
||||
}
|
||||
}
|
||||
}
|
||||
return Editor::KeyCommand(iMessage);
|
||||
}
|
||||
|
||||
void ScintillaBase::AutoCompleteStart(int lenEntered, const char *list) {
|
||||
//Platform::DebugPrintf("AutoCOmplete %s\n", list);
|
||||
ct.CallTipCancel();
|
||||
|
||||
ac.Start(wDraw, idAutoComplete, currentPos, lenEntered);
|
||||
|
||||
PRectangle rcClient = GetClientRectangle();
|
||||
Point pt = LocationFromPosition(currentPos-lenEntered);
|
||||
|
||||
//Platform::DebugPrintf("Auto complete %x\n", lbAutoComplete);
|
||||
int heightLB = 100;
|
||||
int widthLB = 100;
|
||||
if (pt.x >= rcClient.right - widthLB) {
|
||||
HorizontalScrollTo(xOffset + pt.x - rcClient.right + widthLB);
|
||||
Redraw();
|
||||
pt = LocationFromPosition(currentPos);
|
||||
}
|
||||
PRectangle rcac;
|
||||
rcac.left = pt.x - 5;
|
||||
if (pt.y >= rcClient.bottom - heightLB && // Wont fit below.
|
||||
pt.y >= (rcClient.bottom + rcClient.top) / 2) { // and there is more room above.
|
||||
rcac.top = pt.y - heightLB;
|
||||
if (rcac.top < 0) {
|
||||
heightLB += rcac.top;
|
||||
rcac.top = 0;
|
||||
}
|
||||
} else {
|
||||
rcac.top = pt.y + vs.lineHeight;
|
||||
}
|
||||
rcac.right = rcac.left + widthLB;
|
||||
rcac.bottom = Platform::Minimum(rcac.top + heightLB, rcClient.bottom);
|
||||
ac.lb.SetPositionRelative(rcac, wMain);
|
||||
ac.lb.SetFont(vs.styles[0].font);
|
||||
|
||||
int maxStrLen = ac.SetList(list);
|
||||
|
||||
// Fiddle the position of the list so it is right next to the target and wide enough for all its strings
|
||||
PRectangle rcList = ac.lb.GetPosition();
|
||||
int heightAlloced = rcList.bottom - rcList.top;
|
||||
// Make an allowance for large strings in list
|
||||
rcList.left = pt.x - 5;
|
||||
rcList.right = rcList.left + Platform::Maximum(widthLB, maxStrLen * 8 + 16);
|
||||
if (pt.y >= rcClient.bottom - heightLB && // Wont fit below.
|
||||
pt.y >= (rcClient.bottom + rcClient.top) / 2) { // and there is more room above.
|
||||
rcList.top = pt.y - heightAlloced;
|
||||
} else {
|
||||
rcList.top = pt.y + vs.lineHeight;
|
||||
}
|
||||
rcList.bottom = rcList.top + heightAlloced;
|
||||
ac.lb.SetPositionRelative(rcList, wMain);
|
||||
//lbAutoComplete.SetPosition(rcList);
|
||||
ac.Show();
|
||||
}
|
||||
|
||||
void ScintillaBase::AutoCompleteCancel() {
|
||||
ac.Cancel();
|
||||
}
|
||||
|
||||
void ScintillaBase::AutoCompleteMove(int delta) {
|
||||
ac.Move(delta);
|
||||
}
|
||||
|
||||
void ScintillaBase::AutoCompleteChanged(char ch) {
|
||||
if (currentPos <= ac.posStart) {
|
||||
ac.Cancel();
|
||||
} else if (ac.IsStopChar(ch)) {
|
||||
ac.Cancel();
|
||||
} else {
|
||||
char wordCurrent[1000];
|
||||
int i;
|
||||
int startWord = ac.posStart - ac.startLen;
|
||||
for (i = startWord; i < currentPos; i++)
|
||||
wordCurrent[i - startWord] = pdoc->CharAt(i);
|
||||
wordCurrent[i - startWord] = '\0';
|
||||
ac.Select(wordCurrent);
|
||||
}
|
||||
}
|
||||
|
||||
void ScintillaBase::AutoCompleteCompleted() {
|
||||
int item = ac.lb.GetSelection();
|
||||
char selected[200];
|
||||
if (item != -1) {
|
||||
ac.lb.GetValue(item, selected, sizeof(selected));
|
||||
}
|
||||
ac.Cancel();
|
||||
if (currentPos != ac.posStart) {
|
||||
pdoc->DeleteChars(ac.posStart, currentPos - ac.posStart);
|
||||
}
|
||||
SetEmptySelection(ac.posStart);
|
||||
if (item != -1) {
|
||||
pdoc->InsertString(currentPos, selected + ac.startLen);
|
||||
SetEmptySelection(currentPos + strlen(selected + ac.startLen));
|
||||
}
|
||||
}
|
||||
|
||||
void ScintillaBase::ContextMenu(Point pt) {
|
||||
popup.CreatePopUp();
|
||||
AddToPopUp("Undo", idcmdUndo, pdoc->CanUndo());
|
||||
AddToPopUp("Redo", idcmdRedo, pdoc->CanRedo());
|
||||
AddToPopUp("");
|
||||
AddToPopUp("Cut", idcmdCut, currentPos != anchor);
|
||||
AddToPopUp("Copy", idcmdCopy, currentPos != anchor);
|
||||
AddToPopUp("Paste", idcmdPaste, WndProc(EM_CANPASTE, 0, 0));
|
||||
AddToPopUp("Delete", idcmdDelete, currentPos != anchor);
|
||||
AddToPopUp("");
|
||||
AddToPopUp("Select All", idcmdSelectAll);
|
||||
popup.Show(pt, wMain);
|
||||
}
|
||||
|
||||
void ScintillaBase::ButtonDown(Point pt, unsigned int curTime, bool shift, bool ctrl, bool alt) {
|
||||
AutoCompleteCancel();
|
||||
ct.CallTipCancel();
|
||||
Editor::ButtonDown(pt, curTime, shift, ctrl, alt);
|
||||
}
|
||||
|
||||
#ifdef SCI_LEXER
|
||||
void ScintillaBase::Colourise(int start, int end) {
|
||||
int lengthDoc = Platform::SendScintilla(wMain.GetID(), SCI_GETLENGTH, 0, 0);
|
||||
if (end == -1)
|
||||
end = lengthDoc;
|
||||
int len = end - start;
|
||||
|
||||
PropSet props;
|
||||
|
||||
StylingContext styler(wMain.GetID(), props);
|
||||
|
||||
int styleStart = 0;
|
||||
if (start > 0)
|
||||
styleStart = styler.StyleAt(start - 1);
|
||||
|
||||
ColouriseDoc(pdoc->dbcsCodePage, start, len, styleStart, lexLanguage, keyWordLists, styler);
|
||||
styler.Flush();
|
||||
}
|
||||
#endif
|
||||
|
||||
void ScintillaBase::NotifyStyleNeeded(int endStyleNeeded) {
|
||||
#ifdef SCI_LEXER
|
||||
if (lexLanguage != SCLEX_CONTAINER) {
|
||||
int endStyled = Platform::SendScintilla(wMain.GetID(), SCI_GETENDSTYLED, 0, 0);
|
||||
int lineEndStyled = Platform::SendScintilla(wMain.GetID(), EM_LINEFROMCHAR, endStyled, 0);
|
||||
endStyled = Platform::SendScintilla(wMain.GetID(), EM_LINEINDEX, lineEndStyled, 0);
|
||||
Colourise(endStyled, endStyleNeeded);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
Editor::NotifyStyleNeeded(endStyleNeeded);
|
||||
}
|
||||
|
||||
LRESULT ScintillaBase::WndProc(UINT iMessage, WPARAM wParam, LPARAM lParam) {
|
||||
switch (iMessage) {
|
||||
case SCI_AUTOCSHOW:
|
||||
AutoCompleteStart(wParam, reinterpret_cast<const char *>(lParam));
|
||||
break;
|
||||
|
||||
case SCI_AUTOCCANCEL:
|
||||
AutoCompleteCancel();
|
||||
break;
|
||||
|
||||
case SCI_AUTOCACTIVE:
|
||||
return ac.Active();
|
||||
|
||||
case SCI_AUTOCPOSSTART:
|
||||
return ac.posStart;
|
||||
|
||||
case SCI_AUTOCCOMPLETE:
|
||||
AutoCompleteCompleted();
|
||||
break;
|
||||
|
||||
case SCI_AUTOCSTOPS:
|
||||
ac.SetStopChars(reinterpret_cast<char *>(lParam));
|
||||
break;
|
||||
|
||||
case SCI_CALLTIPSHOW: {
|
||||
AutoCompleteCancel();
|
||||
if (!ct.wCallTip.Created()) {
|
||||
PRectangle rc = ct.CallTipStart(currentPos, LocationFromPosition(wParam),
|
||||
reinterpret_cast<char *>(lParam),
|
||||
vs.styles[0].fontName, vs.styles[0].size);
|
||||
// If the call-tip window would be out of the client
|
||||
// space, adjust so it displays above the text.
|
||||
PRectangle rcClient = GetClientRectangle();
|
||||
if (rc.bottom > rcClient.bottom) {
|
||||
int offset = vs.lineHeight + rc.Height();
|
||||
rc.top -= offset;
|
||||
rc.bottom -= offset;
|
||||
}
|
||||
// Now display the window.
|
||||
CreateCallTipWindow(rc);
|
||||
ct.wCallTip.SetPositionRelative(rc, wDraw);
|
||||
ct.wCallTip.Show();
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case SCI_CALLTIPCANCEL:
|
||||
ct.CallTipCancel();
|
||||
break;
|
||||
|
||||
case SCI_CALLTIPACTIVE:
|
||||
return ct.inCallTipMode;
|
||||
|
||||
case SCI_CALLTIPPOSSTART:
|
||||
return ct.posStartCallTip;
|
||||
|
||||
case SCI_CALLTIPSETHLT:
|
||||
ct.SetHighlight(wParam, lParam);
|
||||
break;
|
||||
|
||||
case SCI_CALLTIPSETBACK:
|
||||
ct.colourBG = Colour(wParam);
|
||||
InvalidateStyleRedraw();
|
||||
break;
|
||||
|
||||
#ifdef SCI_LEXER
|
||||
case SCI_SETLEXER:
|
||||
lexLanguage = wParam;
|
||||
break;
|
||||
|
||||
case SCI_GETLEXER:
|
||||
return lexLanguage;
|
||||
|
||||
case SCI_COLOURISE:
|
||||
Colourise(wParam, lParam);
|
||||
break;
|
||||
|
||||
case SCI_SETPROPERTY:
|
||||
props.Set(reinterpret_cast<const char *>(wParam),
|
||||
reinterpret_cast<const char *>(lParam));
|
||||
break;
|
||||
|
||||
case SCI_SETKEYWORDS:
|
||||
if ((wParam >= 0) && (wParam < numWordLists)) {
|
||||
keyWordLists[wParam]->Clear();
|
||||
keyWordLists[wParam]->Set(reinterpret_cast<const char *>(lParam));
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
return Editor::WndProc(iMessage, wParam, lParam);
|
||||
}
|
||||
return 0l;
|
||||
}
|
68
contrib/src/stc/scintilla/src/ScintillaBase.h
Normal file
68
contrib/src/stc/scintilla/src/ScintillaBase.h
Normal file
@@ -0,0 +1,68 @@
|
||||
// Scintilla source code edit control
|
||||
// ScintillaBase.h - defines an enhanced subclass of Editor with calltips, autocomplete and context menu
|
||||
// Copyright 1998-2000 by Neil Hodgson <neilh@scintilla.org>
|
||||
// The License.txt file describes the conditions under which this software may be distributed.
|
||||
|
||||
#ifndef SCINTILLABASE_H
|
||||
#define SCINTILLABASE_H
|
||||
|
||||
class ScintillaBase : public Editor {
|
||||
protected:
|
||||
// Enumeration of commands and child windows
|
||||
enum {
|
||||
idCallTip=1,
|
||||
idAutoComplete=2,
|
||||
|
||||
idcmdUndo=10,
|
||||
idcmdRedo=11,
|
||||
idcmdCut=12,
|
||||
idcmdCopy=13,
|
||||
idcmdPaste=14,
|
||||
idcmdDelete=15,
|
||||
idcmdSelectAll=16
|
||||
};
|
||||
|
||||
Menu popup;
|
||||
AutoComplete ac;
|
||||
|
||||
CallTip ct;
|
||||
|
||||
#ifdef SCI_LEXER
|
||||
int lexLanguage;
|
||||
PropSet props;
|
||||
enum {numWordLists=5};
|
||||
WordList *keyWordLists[numWordLists];
|
||||
void Colourise(int start, int end);
|
||||
#endif
|
||||
|
||||
ScintillaBase();
|
||||
virtual ~ScintillaBase();
|
||||
virtual void Initialise() = 0;
|
||||
virtual void Finalise() = 0;
|
||||
|
||||
virtual void RefreshColourPalette(Palette &pal, bool want);
|
||||
|
||||
virtual void AddChar(char ch);
|
||||
void Command(int cmdId);
|
||||
virtual int KeyCommand(UINT iMessage);
|
||||
|
||||
void AutoCompleteStart(int lenEntered, const char *list);
|
||||
void AutoCompleteCancel();
|
||||
void AutoCompleteMove(int delta);
|
||||
void AutoCompleteChanged(char ch=0);
|
||||
void AutoCompleteCompleted();
|
||||
|
||||
virtual void CreateCallTipWindow(PRectangle rc) = 0;
|
||||
|
||||
virtual void AddToPopUp(const char *label, int cmd=0, bool enabled=true) = 0;
|
||||
void ContextMenu(Point pt);
|
||||
|
||||
virtual void ButtonDown(Point pt, unsigned int curTime, bool shift, bool ctrl, bool alt);
|
||||
|
||||
virtual void NotifyStyleNeeded(int endStyleNeeded);
|
||||
public:
|
||||
// Public so scintilla_send_message can use it
|
||||
virtual LRESULT WndProc(UINT iMessage, WPARAM wParam, LPARAM lParam);
|
||||
};
|
||||
|
||||
#endif
|
63
contrib/src/stc/scintilla/src/Style.cxx
Normal file
63
contrib/src/stc/scintilla/src/Style.cxx
Normal file
@@ -0,0 +1,63 @@
|
||||
// Scintilla source code edit control
|
||||
// Style.cxx - defines the font and colour style for a class of text
|
||||
// Copyright 1998-2000 by Neil Hodgson <neilh@scintilla.org>
|
||||
// The License.txt file describes the conditions under which this software may be distributed.
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "Platform.h"
|
||||
|
||||
#include "Style.h"
|
||||
|
||||
Style::Style() {
|
||||
Clear();
|
||||
}
|
||||
|
||||
Style::~Style() {
|
||||
font.Release();
|
||||
}
|
||||
|
||||
Style &Style::operator=(const Style &source) {
|
||||
if (this == &source)
|
||||
return *this;
|
||||
Clear();
|
||||
fore.desired = source.fore.desired;
|
||||
back.desired = source.back.desired;
|
||||
bold = source.bold;
|
||||
italic = source.italic;
|
||||
size = source.size;
|
||||
strcpy(fontName, source.fontName);
|
||||
eolFilled = source.eolFilled;
|
||||
return *this;
|
||||
}
|
||||
|
||||
void Style::Clear(Colour fore_, Colour back_, int size_, const char *fontName_,
|
||||
bool bold_, bool italic_, bool eolFilled_) {
|
||||
fore.desired = fore_;
|
||||
back.desired = back_;
|
||||
bold = bold_;
|
||||
italic = italic_;
|
||||
size = size_;
|
||||
strcpy(fontName, fontName_);
|
||||
eolFilled = eolFilled_;
|
||||
font.Release();
|
||||
}
|
||||
|
||||
void Style::Realise(Surface &surface, int zoomLevel) {
|
||||
int sizeZoomed = size + zoomLevel;
|
||||
if (sizeZoomed <= 2) // Hangs if sizeZoomed <= 1
|
||||
sizeZoomed = 2;
|
||||
|
||||
int deviceHeight = (sizeZoomed * surface.LogPixelsY()) / 72;
|
||||
font.Create(fontName, deviceHeight, bold, italic);
|
||||
|
||||
ascent = surface.Ascent(font);
|
||||
descent = surface.Descent(font);
|
||||
// Probably more typographically correct to include leading
|
||||
// but that means more complex drawing as leading must be erased
|
||||
//lineHeight = surface.ExternalLeading() + surface.Height();
|
||||
externalLeading = surface.ExternalLeading(font);
|
||||
lineHeight = surface.Height(font);
|
||||
aveCharWidth = surface.AverageCharWidth(font);
|
||||
spaceWidth = surface.WidthChar(font, ' ');
|
||||
}
|
37
contrib/src/stc/scintilla/src/Style.h
Normal file
37
contrib/src/stc/scintilla/src/Style.h
Normal file
@@ -0,0 +1,37 @@
|
||||
// Scintilla source code edit control
|
||||
// Style.h - defines the font and colour style for a class of text
|
||||
// Copyright 1998-2000 by Neil Hodgson <neilh@scintilla.org>
|
||||
// The License.txt file describes the conditions under which this software may be distributed.
|
||||
|
||||
#ifndef STYLE_H
|
||||
#define STYLE_H
|
||||
|
||||
class Style {
|
||||
public:
|
||||
ColourPair fore;
|
||||
ColourPair back;
|
||||
bool bold;
|
||||
bool italic;
|
||||
int size;
|
||||
char fontName[100];
|
||||
bool eolFilled;
|
||||
|
||||
Font font;
|
||||
unsigned int lineHeight;
|
||||
unsigned int ascent;
|
||||
unsigned int descent;
|
||||
unsigned int externalLeading;
|
||||
unsigned int aveCharWidth;
|
||||
unsigned int spaceWidth;
|
||||
|
||||
Style();
|
||||
~Style();
|
||||
Style &operator=(const Style &source);
|
||||
void Clear(Colour fore_=Colour(0,0,0), Colour back_=Colour(0xff,0xff,0xff),
|
||||
int size_=Platform::DefaultFontSize(),
|
||||
const char *fontName_=Platform::DefaultFont(),
|
||||
bool bold_=false, bool italic_=false, bool eolFilled_=false);
|
||||
void Realise(Surface &surface, int zoomLevel);
|
||||
};
|
||||
|
||||
#endif
|
183
contrib/src/stc/scintilla/src/ViewStyle.cxx
Normal file
183
contrib/src/stc/scintilla/src/ViewStyle.cxx
Normal file
@@ -0,0 +1,183 @@
|
||||
// Scintilla source code edit control
|
||||
// ViewStyle.cxx - store information on how the document is to be viewed
|
||||
// Copyright 1998-2000 by Neil Hodgson <neilh@scintilla.org>
|
||||
// The License.txt file describes the conditions under which this software may be distributed.
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "Platform.h"
|
||||
|
||||
#include "Scintilla.h"
|
||||
#include "Indicator.h"
|
||||
#include "LineMarker.h"
|
||||
#include "Style.h"
|
||||
#include "ViewStyle.h"
|
||||
|
||||
MarginStyle::MarginStyle() :
|
||||
symbol(false), width(16), mask(0xffffffff), sensitive(false) {
|
||||
}
|
||||
|
||||
ViewStyle::ViewStyle() {
|
||||
Init();
|
||||
}
|
||||
|
||||
ViewStyle::ViewStyle(const ViewStyle &source) {
|
||||
Init();
|
||||
for (int sty=0;sty<=STYLE_MAX;sty++) {
|
||||
styles[sty] = source.styles[sty];
|
||||
}
|
||||
for (int mrk=0;mrk<=MARKER_MAX;mrk++) {
|
||||
markers[mrk] = source.markers[mrk];
|
||||
}
|
||||
for (int ind=0;ind<=INDIC_MAX;ind++) {
|
||||
indicators[ind] = source.indicators[ind];
|
||||
}
|
||||
|
||||
selforeset = source.selforeset;
|
||||
selforeground.desired = source.selforeground.desired;
|
||||
selbackset = source.selbackset;
|
||||
selbackground.desired = source.selbackground.desired;
|
||||
selbar.desired = source.selbar.desired;
|
||||
selbarlight.desired = source.selbarlight.desired;
|
||||
caretcolour.desired = source.caretcolour.desired;
|
||||
edgecolour.desired = source.edgecolour.desired;
|
||||
leftMarginWidth = source.leftMarginWidth;
|
||||
rightMarginWidth = source.rightMarginWidth;
|
||||
for (int i=0;i < margins; i++) {
|
||||
ms[i] = source.ms[i];
|
||||
}
|
||||
symbolMargin = source.symbolMargin;
|
||||
maskInLine = source.maskInLine;
|
||||
fixedColumnWidth = source.fixedColumnWidth;
|
||||
zoomLevel = source.zoomLevel;
|
||||
viewWhitespace = source.viewWhitespace;
|
||||
viewEOL = source.viewEOL;
|
||||
showMarkedLines = source.showMarkedLines;
|
||||
}
|
||||
|
||||
ViewStyle::~ViewStyle() {
|
||||
}
|
||||
|
||||
void ViewStyle::Init() {
|
||||
indicators[0].style = INDIC_SQUIGGLE;
|
||||
indicators[0].fore = Colour(0, 0x7f, 0);
|
||||
indicators[1].style = INDIC_TT;
|
||||
indicators[1].fore = Colour(0, 0, 0xff);
|
||||
indicators[2].style = INDIC_PLAIN;
|
||||
indicators[2].fore = Colour(0xff, 0, 0);
|
||||
|
||||
lineHeight = 1;
|
||||
maxAscent = 1;
|
||||
maxDescent = 1;
|
||||
aveCharWidth = 8;
|
||||
spaceWidth = 8;
|
||||
|
||||
selforeset = false;
|
||||
selforeground.desired = Colour(0xff, 0, 0);
|
||||
selbackset = true;
|
||||
selbackground.desired = Colour(0xc0, 0xc0, 0xc0);
|
||||
selbar.desired = Platform::Chrome();
|
||||
selbarlight.desired = Platform::ChromeHighlight();
|
||||
styles[STYLE_LINENUMBER].fore.desired = Colour(0, 0, 0);
|
||||
styles[STYLE_LINENUMBER].back.desired = Platform::Chrome();
|
||||
//caretcolour.desired = Colour(0xff, 0, 0);
|
||||
caretcolour.desired = Colour(0, 0, 0);
|
||||
edgecolour.desired = Colour(0xc0, 0xc0, 0xc0);
|
||||
|
||||
leftMarginWidth = 1;
|
||||
rightMarginWidth = 1;
|
||||
ms[0].symbol = false;
|
||||
ms[0].width = 0;
|
||||
ms[0].mask = 0;
|
||||
ms[1].symbol = true;
|
||||
ms[1].width = 16;
|
||||
ms[1].mask = ~SC_MASK_FOLDERS;
|
||||
ms[2].symbol = true;
|
||||
ms[2].width = 14; // Nice width for arrows
|
||||
ms[2].mask = SC_MASK_FOLDERS;
|
||||
ms[2].width = 0; // Nice width for arrows
|
||||
ms[2].mask = 0;
|
||||
fixedColumnWidth = leftMarginWidth;
|
||||
symbolMargin = false;
|
||||
maskInLine = 0xffffffff;
|
||||
for (int margin=0; margin < margins; margin++) {
|
||||
fixedColumnWidth += ms[margin].width;
|
||||
symbolMargin = symbolMargin || ms[margin].symbol;
|
||||
if (ms[margin].width > 0)
|
||||
maskInLine &= ~ms[margin].mask;
|
||||
}
|
||||
zoomLevel = 0;
|
||||
viewWhitespace = false;
|
||||
viewEOL = false;
|
||||
showMarkedLines = true;
|
||||
}
|
||||
|
||||
void ViewStyle::RefreshColourPalette(Palette &pal, bool want) {
|
||||
unsigned int i;
|
||||
for (i=0;i<(sizeof(styles)/sizeof(styles[0]));i++) {
|
||||
pal.WantFind(styles[i].fore, want);
|
||||
pal.WantFind(styles[i].back, want);
|
||||
}
|
||||
for (i=0;i<(sizeof(indicators)/sizeof(indicators[0]));i++) {
|
||||
pal.WantFind(indicators[i].fore, want);
|
||||
}
|
||||
for (i=0;i<(sizeof(markers)/sizeof(markers[0]));i++) {
|
||||
pal.WantFind(markers[i].fore, want);
|
||||
pal.WantFind(markers[i].back, want);
|
||||
}
|
||||
pal.WantFind(selforeground, want);
|
||||
pal.WantFind(selbackground, want);
|
||||
pal.WantFind(selbar, want);
|
||||
pal.WantFind(selbarlight, want);
|
||||
pal.WantFind(caretcolour, want);
|
||||
pal.WantFind(edgecolour, want);
|
||||
}
|
||||
|
||||
void ViewStyle::Refresh(Surface &surface) {
|
||||
selbar.desired = Platform::Chrome();
|
||||
selbarlight.desired = Platform::ChromeHighlight();
|
||||
maxAscent = 1;
|
||||
maxDescent = 1;
|
||||
for (unsigned int i=0;i<(sizeof(styles)/sizeof(styles[0]));i++) {
|
||||
styles[i].Realise(surface, zoomLevel);
|
||||
if (maxAscent < styles[i].ascent)
|
||||
maxAscent = styles[i].ascent;
|
||||
if (maxDescent < styles[i].descent)
|
||||
maxDescent = styles[i].descent;
|
||||
}
|
||||
|
||||
lineHeight = maxAscent + maxDescent;
|
||||
aveCharWidth = styles[STYLE_DEFAULT].aveCharWidth;
|
||||
spaceWidth = styles[STYLE_DEFAULT].spaceWidth;
|
||||
|
||||
fixedColumnWidth = leftMarginWidth;
|
||||
symbolMargin = false;
|
||||
maskInLine = 0xffffffff;
|
||||
for (int margin=0; margin < margins; margin++) {
|
||||
fixedColumnWidth += ms[margin].width;
|
||||
symbolMargin = symbolMargin || ms[margin].symbol;
|
||||
if (ms[margin].width > 0)
|
||||
maskInLine &= ~ms[margin].mask;
|
||||
}
|
||||
}
|
||||
|
||||
void ViewStyle::ResetDefaultStyle() {
|
||||
styles[STYLE_DEFAULT].Clear();
|
||||
}
|
||||
|
||||
void ViewStyle::ClearStyles() {
|
||||
// Reset all styles to be like the default style
|
||||
for (int i=0; i<=STYLE_MAX; i++) {
|
||||
if (i != STYLE_DEFAULT) {
|
||||
styles[i].Clear(
|
||||
styles[STYLE_DEFAULT].fore.desired,
|
||||
styles[STYLE_DEFAULT].back.desired,
|
||||
styles[STYLE_DEFAULT].size,
|
||||
styles[STYLE_DEFAULT].fontName,
|
||||
styles[STYLE_DEFAULT].bold,
|
||||
styles[STYLE_DEFAULT].italic);
|
||||
}
|
||||
}
|
||||
styles[STYLE_LINENUMBER].back.desired = Platform::Chrome();
|
||||
}
|
||||
|
59
contrib/src/stc/scintilla/src/ViewStyle.h
Normal file
59
contrib/src/stc/scintilla/src/ViewStyle.h
Normal file
@@ -0,0 +1,59 @@
|
||||
// Scintilla source code edit control
|
||||
// ViewStyle.h - store information on how the document is to be viewed
|
||||
// Copyright 1998-2000 by Neil Hodgson <neilh@scintilla.org>
|
||||
// The License.txt file describes the conditions under which this software may be distributed.
|
||||
|
||||
#ifndef VIEWSTYLE_H
|
||||
#define VIEWSTYLE_H
|
||||
|
||||
class MarginStyle {
|
||||
public:
|
||||
bool symbol;
|
||||
int width;
|
||||
int mask;
|
||||
bool sensitive;
|
||||
MarginStyle();
|
||||
};
|
||||
|
||||
class ViewStyle {
|
||||
public:
|
||||
Style styles[STYLE_MAX + 1];
|
||||
LineMarker markers[MARKER_MAX + 1];
|
||||
Indicator indicators[INDIC_MAX + 1];
|
||||
int lineHeight;
|
||||
unsigned int maxAscent;
|
||||
unsigned int maxDescent;
|
||||
unsigned int aveCharWidth;
|
||||
unsigned int spaceWidth;
|
||||
bool selforeset;
|
||||
ColourPair selforeground;
|
||||
bool selbackset;
|
||||
ColourPair selbackground;
|
||||
ColourPair selbar;
|
||||
ColourPair selbarlight;
|
||||
// Margins are ordered: Line Numbers, Selection Margin, Spacing Margin
|
||||
int leftMarginWidth; // Spacing margin on left of text
|
||||
int rightMarginWidth; // Spacing margin on left of text
|
||||
enum { margins=3 };
|
||||
bool symbolMargin;
|
||||
int maskInLine; // Mask for markers to be put into text because there is nowhere for them to go in margin
|
||||
MarginStyle ms[margins];
|
||||
int fixedColumnWidth;
|
||||
int zoomLevel;
|
||||
bool viewWhitespace;
|
||||
bool viewEOL;
|
||||
bool showMarkedLines;
|
||||
ColourPair caretcolour;
|
||||
ColourPair edgecolour;
|
||||
|
||||
ViewStyle();
|
||||
ViewStyle(const ViewStyle &source);
|
||||
~ViewStyle();
|
||||
void Init();
|
||||
void RefreshColourPalette(Palette &pal, bool want);
|
||||
void Refresh(Surface &surface);
|
||||
void ResetDefaultStyle();
|
||||
void ClearStyles();
|
||||
};
|
||||
|
||||
#endif
|
1386
contrib/src/stc/stc.cpp
Normal file
1386
contrib/src/stc/stc.cpp
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user