📄 scintillagtk.cxx.svn-base
字号:
gtk_drag_begin(GTK_WIDGET(PWidget(wMain)),
tl,
static_cast<GdkDragAction>(GDK_ACTION_COPY | GDK_ACTION_MOVE),
evbtn.button,
reinterpret_cast<GdkEvent *>(&evbtn));
}
#ifdef USE_CONVERTER
static char *ConvertText(int *lenResult, char *s, size_t len, const char *charSetDest,
const char *charSetSource, bool transliterations) {
*lenResult = 0;
char *destForm = 0;
Converter conv(charSetDest, charSetSource, transliterations);
if (conv) {
destForm = new char[len*3+1];
char *pin = s;
size_t inLeft = len;
char *pout = destForm;
size_t outLeft = len*3+1;
size_t conversions = conv.Convert(&pin, &inLeft, &pout, &outLeft);
if (conversions == ((size_t)(-1))) {
fprintf(stderr, "iconv %s->%s failed for %s\n", charSetSource, charSetDest, static_cast<char *>(s));
delete []destForm;
destForm = 0;
} else {
//fprintf(stderr, "iconv OK %s %d\n", destForm, pout - destForm);
*pout = '\0';
*lenResult = pout - destForm;
}
} else {
fprintf(stderr, "Can not iconv %s %s\n", charSetDest, charSetSource);
}
if (!destForm) {
destForm = new char[1];
destForm[0] = '\0';
*lenResult = 0;
}
return destForm;
}
#endif
// Returns the target converted to UTF8.
// Return the length in bytes.
int ScintillaGTK::TargetAsUTF8(char *text) {
int targetLength = targetEnd - targetStart;
if (IsUnicodeMode()) {
if (text) {
pdoc->GetCharRange(text, targetStart, targetLength);
}
} else {
// Need to convert
#ifdef USE_CONVERTER
const char *charSetBuffer = CharacterSetID();
if (*charSetBuffer) {
//~ fprintf(stderr, "AsUTF8 %s %d %0d-%0d\n", charSetBuffer, targetLength, targetStart, targetEnd);
char *s = new char[targetLength];
if (s) {
pdoc->GetCharRange(s, targetStart, targetLength);
//~ fprintf(stderr, " \"%s\"\n", s);
if (text) {
char *tmputf = ConvertText(&targetLength, s, targetLength, "UTF-8", charSetBuffer, false);
memcpy(text, tmputf, targetLength);
delete []tmputf;
//~ fprintf(stderr, " \"%s\"\n", text);
}
delete []s;
}
} else {
if (text) {
pdoc->GetCharRange(text, targetStart, targetLength);
}
}
#else
// Fail
return 0;
#endif
}
//~ fprintf(stderr, "Length = %d bytes\n", targetLength);
return targetLength;
}
// Translates a nul terminated UTF8 string into the document encoding.
// Return the length of the result in bytes.
int ScintillaGTK::EncodedFromUTF8(char *utf8, char *encoded) {
int inputLength = (lengthForEncode >= 0) ? lengthForEncode : strlen(utf8);
if (IsUnicodeMode()) {
if (encoded) {
memcpy(encoded, utf8, inputLength);
}
return inputLength;
} else {
// Need to convert
#ifdef USE_CONVERTER
const char *charSetBuffer = CharacterSetID();
if (*charSetBuffer) {
//~ fprintf(stderr, "Encode %s %d\n", charSetBuffer, inputLength);
int outLength = 0;
char *tmpEncoded = ConvertText(&outLength, utf8, inputLength, charSetBuffer, "UTF-8", true);
if (tmpEncoded) {
//~ fprintf(stderr, " \"%s\"\n", tmpEncoded);
if (encoded) {
memcpy(encoded, tmpEncoded, outLength);
}
delete []tmpEncoded;
}
return outLength;
} else {
if (encoded) {
memcpy(encoded, utf8, inputLength);
}
return inputLength;
}
#endif
}
// Fail
return 0;
}
bool ScintillaGTK::ValidCodePage(int codePage) const {
return codePage == 0 || codePage == SC_CP_UTF8 || codePage == SC_CP_DBCS;
}
sptr_t ScintillaGTK::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
switch (iMessage) {
case SCI_GRABFOCUS:
gtk_widget_grab_focus(PWidget(wMain));
break;
case SCI_GETDIRECTFUNCTION:
return reinterpret_cast<sptr_t>(DirectFunction);
case SCI_GETDIRECTPOINTER:
return reinterpret_cast<sptr_t>(this);
#ifdef SCI_LEXER
case SCI_LOADLEXERLIBRARY:
LexerManager::GetInstance()->Load(reinterpret_cast<const char*>(wParam));
break;
#endif
case SCI_TARGETASUTF8:
return TargetAsUTF8(reinterpret_cast<char*>(lParam));
case SCI_ENCODEDFROMUTF8:
return EncodedFromUTF8(reinterpret_cast<char*>(wParam),
reinterpret_cast<char*>(lParam));
default:
return ScintillaBase::WndProc(iMessage, wParam, lParam);
}
return 0l;
}
sptr_t ScintillaGTK::DefWndProc(unsigned int, uptr_t, sptr_t) {
return 0;
}
void ScintillaGTK::SetTicking(bool on) {
if (timer.ticking != on) {
timer.ticking = on;
if (timer.ticking) {
timer.tickerID = reinterpret_cast<TickerID>(gtk_timeout_add(timer.tickSize, (GtkFunction)TimeOut, this));
} else {
gtk_timeout_remove(GPOINTER_TO_UINT(timer.tickerID));
}
}
timer.ticksToWait = caret.period;
}
bool ScintillaGTK::SetIdle(bool on) {
if (on) {
// Start idler, if it's not running.
if (idler.state == false) {
idler.state = true;
idler.idlerID = reinterpret_cast<IdlerID>
(gtk_idle_add((GtkFunction)IdleCallback, this));
}
} else {
// Stop idler, if it's running
if (idler.state == true) {
idler.state = false;
gtk_idle_remove(GPOINTER_TO_UINT(idler.idlerID));
}
}
return true;
}
void ScintillaGTK::SetMouseCapture(bool on) {
if (mouseDownCaptures) {
if (on) {
gtk_grab_add(GTK_WIDGET(PWidget(wMain)));
} else {
gtk_grab_remove(GTK_WIDGET(PWidget(wMain)));
}
}
capturedMouse = on;
}
bool ScintillaGTK::HaveMouseCapture() {
return capturedMouse;
}
bool ScintillaGTK::PaintContains(PRectangle rc) {
bool contains = true;
if (paintState == painting) {
if (!rcPaint.Contains(rc)) {
contains = false;
} else if (rgnUpdate) {
GdkRectangle grc = {rc.left, rc.top,
rc.right - rc.left, rc.bottom - rc.top};
if (gdk_region_rect_in(rgnUpdate, &grc) != GDK_OVERLAP_RECTANGLE_IN) {
contains = false;
}
}
}
return contains;
}
// Redraw all of text area. This paint will not be abandoned.
void ScintillaGTK::FullPaint() {
#if GTK_MAJOR_VERSION < 2
paintState = painting;
rcPaint = GetClientRectangle();
//Platform::DebugPrintf("ScintillaGTK::FullPaint %0d,%0d %0d,%0d\n",
// rcPaint.left, rcPaint.top, rcPaint.right, rcPaint.bottom);
paintingAllText = true;
if ((PWidget(wText))->window) {
Surface *sw = Surface::Allocate();
if (sw) {
sw->Init(PWidget(wText)->window, PWidget(wText));
Paint(sw, rcPaint);
sw->Release();
delete sw;
}
}
paintState = notPainting;
#else
wText.InvalidateAll();
#endif
}
PRectangle ScintillaGTK::GetClientRectangle() {
PRectangle rc = wMain.GetClientPosition();
if (verticalScrollBarVisible)
rc.right -= scrollBarWidth;
if (horizontalScrollBarVisible && (wrapState == eWrapNone))
rc.bottom -= scrollBarHeight;
// Move to origin
rc.right -= rc.left;
rc.bottom -= rc.top;
rc.left = 0;
rc.top = 0;
return rc;
}
// Synchronously paint a rectangle of the window.
void ScintillaGTK::SyncPaint(PRectangle rc) {
paintState = painting;
rcPaint = rc;
PRectangle rcClient = GetClientRectangle();
paintingAllText = rcPaint.Contains(rcClient);
if ((PWidget(wText))->window) {
Surface *sw = Surface::Allocate();
if (sw) {
sw->Init(PWidget(wText)->window, PWidget(wText));
Paint(sw, rc);
sw->Release();
delete sw;
}
}
if (paintState == paintAbandoned) {
// Painting area was insufficient to cover new styling or brace highlight positions
FullPaint();
}
paintState = notPainting;
}
void ScintillaGTK::ScrollText(int linesToMove) {
int diff = vs.lineHeight * -linesToMove;
//Platform::DebugPrintf("ScintillaGTK::ScrollText %d %d %0d,%0d %0d,%0d\n", linesToMove, diff,
// rc.left, rc.top, rc.right, rc.bottom);
GtkWidget *wi = PWidget(wText);
#if GTK_MAJOR_VERSION < 2
PRectangle rc = GetClientRectangle();
GdkGC *gc = gdk_gc_new(wi->window);
// Set up gc so we get GraphicsExposures from gdk_draw_pixmap
// which calls XCopyArea
gdk_gc_set_exposures(gc, TRUE);
// Redraw exposed bit : scrolling upwards
if (diff > 0) {
gdk_draw_pixmap(wi->window,
gc, wi->window,
0, diff,
0, 0,
rc.Width()-1, rc.Height() - diff);
SyncPaint(PRectangle(0, rc.Height() - diff,
rc.Width(), rc.Height()+1));
// Redraw exposed bit : scrolling downwards
} else {
gdk_draw_pixmap(wi->window,
gc, wi->window,
0, 0,
0, -diff,
rc.Width()-1, rc.Height() + diff);
SyncPaint(PRectangle(0, 0, rc.Width(), -diff));
}
// Look for any graphics expose
GdkEvent* event;
while ((event = gdk_event_get_graphics_expose(wi->window)) != NULL) {
gtk_widget_event(wi, event);
if (event->expose.count == 0) {
gdk_event_free(event);
break;
}
gdk_event_free(event);
}
gdk_gc_unref(gc);
#else
gdk_window_scroll(wi->window, 0, -diff);
gdk_window_process_updates(wi->window, FALSE);
#endif
}
void ScintillaGTK::SetVerticalScrollPos() {
DwellEnd(true);
gtk_adjustment_set_value(GTK_ADJUSTMENT(adjustmentv), topLine);
}
void ScintillaGTK::SetHorizontalScrollPos() {
DwellEnd(true);
gtk_adjustment_set_value(GTK_ADJUSTMENT(adjustmenth), xOffset / 2);
}
bool ScintillaGTK::ModifyScrollBars(int nMax, int nPage) {
bool modified = false;
int pageScroll = LinesToScroll();
if (GTK_ADJUSTMENT(adjustmentv)->upper != (nMax + 1) ||
GTK_ADJUSTMENT(adjustmentv)->page_size != nPage ||
GTK_ADJUSTMENT(adjustmentv)->page_increment != pageScroll) {
GTK_ADJUSTMENT(adjustmentv)->upper = nMax + 1;
GTK_ADJUSTMENT(adjustmentv)->page_size = nPage;
GTK_ADJUSTMENT(adjustmentv)->page_increment = pageScroll;
gtk_adjustment_changed(GTK_ADJUSTMENT(adjustmentv));
modified = true;
}
PRectangle rcText = GetTextRectangle();
int horizEndPreferred = scrollWidth;
if (horizEndPreferred < 0)
horizEndPreferred = 0;
unsigned int pageWidth = rcText.Width();
unsigned int pageIncrement = pageWidth / 3;
unsigned int charWidth = vs.styles[STYLE_DEFAULT].aveCharWidth;
if (GTK_ADJUSTMENT(adjustmenth)->upper != horizEndPreferred ||
GTK_ADJUSTMENT(adjustmenth)->page_size != pageWidth ||
GTK_ADJUSTMENT(adjustmenth)->page_increment != pageIncrement ||
GTK_ADJUSTMENT(adjustmenth)->step_increment != charWidth) {
GTK_ADJUSTMENT(adjustmenth)->upper = horizEndPreferred;
GTK_ADJUSTMENT(adjustmenth)->step_increment = charWidth;
GTK_ADJUSTMENT(adjustmenth)->page_size = pageWidth;
GTK_ADJUSTMENT(adjustmenth)->page_increment = pageIncrement;
gtk_adjustment_changed(GTK_ADJUSTMENT(adjustmenth));
modified = true;
}
return modified;
}
void ScintillaGTK::ReconfigureScrollBars() {
PRectangle rc = wMain.GetClientPosition();
Resize(rc.Width(), rc.Height());
}
void ScintillaGTK::NotifyChange() {
#if GLIB_MAJOR_VERSION < 2
gtk_signal_emit(GTK_OBJECT(sci), scintilla_signals[COMMAND_SIGNAL],
Platform::LongFromTwoShorts(GetCtrlID(), SCEN_CHANGE), PWidget(wMain));
#else
g_signal_emit(G_OBJECT(sci), scintilla_signals[COMMAND_SIGNAL], 0,
Platform::LongFromTwoShorts(GetCtrlID(), SCEN_CHANGE), PWidget(wMain));
#endif
}
void ScintillaGTK::NotifyFocus(bool focus) {
#if GLIB_MAJOR_VERSION < 2
gtk_signal_emit(GTK_OBJECT(sci), scintilla_signals[COMMAND_SIGNAL],
Platform::LongFromTwoShorts
(GetCtrlID(), focus ? SCEN_SETFOCUS : SCEN_KILLFOCUS), PWidget(wMain));
#else
g_signal_emit(G_OBJECT(sci), scintilla_signals[COMMAND_SIGNAL], 0,
Platform::LongFromTwoShorts
(GetCtrlID(), focus ? SCEN_SETFOCUS : SCEN_KILLFOCUS), PWidget(wMain));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -