238
223
gint PressThis(GdkEventButton *event);
239
224
static gint Press(GtkWidget *widget, GdkEventButton *event);
240
225
static gint MouseRelease(GtkWidget *widget, GdkEventButton *event);
241
#if PLAT_GTK_WIN32 || (GTK_MAJOR_VERSION >= 2)
242
226
static gint ScrollEvent(GtkWidget *widget, GdkEventScroll *event);
244
227
static gint Motion(GtkWidget *widget, GdkEventMotion *event);
245
228
gboolean KeyThis(GdkEventKey *event);
246
229
static gboolean KeyPress(GtkWidget *widget, GdkEventKey *event);
247
230
static gboolean KeyRelease(GtkWidget *widget, GdkEventKey *event);
248
#if GTK_MAJOR_VERSION >= 2
249
231
gboolean ExposePreeditThis(GtkWidget *widget, GdkEventExpose *ose);
250
232
static gboolean ExposePreedit(GtkWidget *widget, GdkEventExpose *ose, ScintillaGTK *sciThis);
251
233
void CommitThis(char *str);
252
234
static void Commit(GtkIMContext *context, char *str, ScintillaGTK *sciThis);
253
235
void PreeditChangedThis();
254
236
static void PreeditChanged(GtkIMContext *context, ScintillaGTK *sciThis);
256
237
static gint StyleSetText(GtkWidget *widget, GtkStyle *previous, void*);
257
238
static gint RealizeText(GtkWidget *widget, void*);
258
#if GLIB_MAJOR_VERSION < 2
259
static void Destroy(GtkObject *object);
261
239
static void Destroy(GObject *object);
263
240
static void SelectionReceived(GtkWidget *widget, GtkSelectionData *selection_data,
265
242
static void SelectionGet(GtkWidget *widget, GtkSelectionData *selection_data,
266
243
guint info, guint time);
267
244
static gint SelectionClear(GtkWidget *widget, GdkEventSelection *selection_event);
268
#if GTK_MAJOR_VERSION < 2
269
static gint SelectionNotify(GtkWidget *widget, GdkEventSelection *selection_event);
271
245
static void DragBegin(GtkWidget *widget, GdkDragContext *context);
272
246
gboolean DragMotionThis(GdkDragContext *context, gint x, gint y, guint dragtime);
273
247
static gboolean DragMotion(GtkWidget *widget, GdkDragContext *context,
282
256
static void DragDataGet(GtkWidget *widget, GdkDragContext *context,
283
257
GtkSelectionData *selection_data, guint info, guint time);
284
258
static gint TimeOut(ScintillaGTK *sciThis);
285
static gint IdleCallback(ScintillaGTK *sciThis);
259
static gboolean IdleCallback(ScintillaGTK *sciThis);
260
static gboolean StyleIdle(ScintillaGTK *sciThis);
261
virtual void QueueStyling(int upTo);
286
262
static void PopUpCB(ScintillaGTK *sciThis, guint action, GtkWidget *widget);
288
264
gint ExposeTextThis(GtkWidget *widget, GdkEventExpose *ose);
346
319
adjustmentv(0), adjustmenth(0),
347
320
scrollBarWidth(30), scrollBarHeight(30),
348
321
capturedMouse(false), dragWasDropped(false),
349
lastKey(0), parentClass(0),
350
#ifdef INTERNATIONAL_INPUT
351
#if GTK_MAJOR_VERSION < 2
322
lastKey(0), rectangularSelectionModifier(SCMOD_CTRL), parentClass(0),
355
323
im_context(NULL),
358
324
lastWheelMouseDirection(0),
359
325
wheelMouseIntensity(0),
407
379
gdk_window_show(widget->window);
408
380
gdk_cursor_destroy(cursor);
409
381
widget->style = gtk_style_attach(widget->style, widget->window);
410
#ifdef INTERNATIONAL_INPUT
411
#if GTK_MAJOR_VERSION < 2
412
if (gdk_im_ready() && (ic_attr = gdk_ic_attr_new()) != NULL) {
414
GdkColormap *colormap;
416
GdkICAttr *attr = ic_attr;
417
GdkICAttributesType attrmask = GDK_IC_ALL_REQ;
419
GdkIMStyle supported_style = (GdkIMStyle) (GDK_IM_PREEDIT_NONE |
420
GDK_IM_PREEDIT_NOTHING |
421
GDK_IM_PREEDIT_POSITION |
423
GDK_IM_STATUS_NOTHING);
425
if (widget->style && widget->style->font->type != GDK_FONT_FONTSET)
426
supported_style = (GdkIMStyle) ((int) supported_style & ~GDK_IM_PREEDIT_POSITION);
428
attr->style = style = gdk_im_decide_style(supported_style);
429
attr->client_window = widget->window;
431
if ((colormap = gtk_widget_get_colormap (widget)) != gtk_widget_get_default_colormap ()) {
432
attrmask = (GdkICAttributesType) ((int) attrmask | GDK_IC_PREEDIT_COLORMAP);
433
attr->preedit_colormap = colormap;
436
switch (style & GDK_IM_PREEDIT_MASK) {
437
case GDK_IM_PREEDIT_POSITION:
438
if (widget->style && widget->style->font->type != GDK_FONT_FONTSET) {
439
g_warning("over-the-spot style requires fontset");
443
attrmask = (GdkICAttributesType) ((int) attrmask | GDK_IC_PREEDIT_POSITION_REQ);
444
gdk_window_get_size(widget->window, &width, &height);
445
attr->spot_location.x = 0;
446
attr->spot_location.y = height;
447
attr->preedit_area.x = 0;
448
attr->preedit_area.y = 0;
449
attr->preedit_area.width = width;
450
attr->preedit_area.height = height;
451
attr->preedit_fontset = widget->style->font;
455
ic = gdk_ic_new(attr, attrmask);
458
g_warning("Can't create input context.");
460
mask = gdk_window_get_events(widget->window);
461
mask = (GdkEventMask) ((int) mask | gdk_ic_get_events(ic));
462
gdk_window_set_events(widget->window, mask);
464
if (GTK_WIDGET_HAS_FOCUS(widget))
465
gdk_im_begin(ic, widget->window);
469
382
wPreedit = gtk_window_new(GTK_WINDOW_POPUP);
470
383
wPreeditDraw = gtk_drawing_area_new();
471
384
GtkWidget *predrw = PWidget(wPreeditDraw); // No code inside the G_OBJECT macro
482
395
g_signal_connect(G_OBJECT(im_context), "preedit_changed",
483
396
G_CALLBACK(PreeditChanged), this);
484
397
gtk_im_context_set_client_window(im_context, widget->window);
487
398
GtkWidget *widtxt = PWidget(wText); // // No code inside the G_OBJECT macro
488
#if GLIB_MAJOR_VERSION < 2
489
gtk_signal_connect_after(GTK_OBJECT(widtxt), "style_set",
490
GtkSignalFunc(ScintillaGTK::StyleSetText), NULL);
491
gtk_signal_connect_after(GTK_OBJECT(widtxt), "realize",
492
GtkSignalFunc(ScintillaGTK::RealizeText), NULL);
494
399
g_signal_connect_after(G_OBJECT(widtxt), "style_set",
495
400
G_CALLBACK(ScintillaGTK::StyleSetText), NULL);
496
401
g_signal_connect_after(G_OBJECT(widtxt), "realize",
497
402
G_CALLBACK(ScintillaGTK::RealizeText), NULL);
499
403
gtk_widget_realize(widtxt);
500
404
gtk_widget_realize(PWidget(scrollbarv));
501
405
gtk_widget_realize(PWidget(scrollbarh));
515
419
gtk_widget_unrealize(PWidget(wText));
516
420
gtk_widget_unrealize(PWidget(scrollbarv));
517
421
gtk_widget_unrealize(PWidget(scrollbarh));
518
#ifdef INTERNATIONAL_INPUT
519
#if GTK_MAJOR_VERSION < 2
525
gdk_ic_attr_destroy(ic_attr);
529
422
gtk_widget_unrealize(PWidget(wPreedit));
530
423
gtk_widget_unrealize(PWidget(wPreeditDraw));
531
424
g_object_unref(im_context);
532
425
im_context = NULL;
535
426
if (GTK_WIDGET_CLASS(parentClass)->unrealize)
536
427
GTK_WIDGET_CLASS(parentClass)->unrealize(widget);
616
#ifdef INTERNATIONAL_INPUT
617
#if GTK_MAJOR_VERSION < 2
618
gint ScintillaGTK::CursorMoved(GtkWidget *widget, int xoffset, int yoffset, ScintillaGTK *sciThis) {
619
if (GTK_WIDGET_HAS_FOCUS(widget) && gdk_im_ready() && sciThis->ic &&
620
(gdk_ic_get_style(sciThis->ic) & GDK_IM_PREEDIT_POSITION)) {
621
sciThis->ic_attr->spot_location.x = xoffset;
622
sciThis->ic_attr->spot_location.y = yoffset;
623
gdk_ic_set_attr(sciThis->ic, sciThis->ic_attr, GDK_IC_SPOT_LOCATION);
628
507
gint ScintillaGTK::CursorMoved(GtkWidget *, int xoffset, int yoffset, ScintillaGTK *sciThis) {
629
508
GdkRectangle area;
630
509
area.x = xoffset;
634
513
gtk_im_context_set_cursor_location(sciThis->im_context, &area);
639
gint ScintillaGTK::CursorMoved(GtkWidget *, int, int, ScintillaGTK *) {
644
517
gint ScintillaGTK::FocusInThis(GtkWidget *widget) {
646
519
GTK_WIDGET_SET_FLAGS(widget, GTK_HAS_FOCUS);
647
520
SetFocusState(true);
648
#ifdef INTERNATIONAL_INPUT
649
#if GTK_MAJOR_VERSION < 2
651
gdk_im_begin(ic, widget->window);
653
521
if (im_context != NULL) {
654
522
gchar *str = NULL;
729
589
sciThis->Resize(allocation->width, allocation->height);
731
#ifdef INTERNATIONAL_INPUT
732
#if GTK_MAJOR_VERSION < 2
733
if (sciThis->ic && (gdk_ic_get_style(sciThis->ic) & GDK_IM_PREEDIT_POSITION)) {
736
gdk_window_get_size(widget->window, &width, &height);
737
sciThis->ic_attr->preedit_area.width = width;
738
sciThis->ic_attr->preedit_area.height = height;
740
gdk_ic_set_attr(sciThis->ic, sciThis->ic_attr, GDK_IC_PREEDIT_AREA);
745
592
sciThis->errorStatus = SC_STATUS_FAILURE;
769
616
gtk_widget_set_parent(PWidget(wText), PWidget(wMain));
770
617
GtkWidget *widtxt = PWidget(wText); // No code inside the G_OBJECT macro
771
618
gtk_widget_show(widtxt);
772
#if GLIB_MAJOR_VERSION < 2
773
gtk_signal_connect(GTK_OBJECT(widtxt), "expose_event",
774
GtkSignalFunc(ScintillaGTK::ExposeText), this);
776
619
g_signal_connect(G_OBJECT(widtxt), "expose_event",
777
620
G_CALLBACK(ScintillaGTK::ExposeText), this);
779
621
gtk_widget_set_events(widtxt, GDK_EXPOSURE_MASK);
780
#if GTK_MAJOR_VERSION >= 2
781
622
// Avoid background drawing flash
782
623
gtk_widget_set_double_buffered(widtxt, FALSE);
784
624
gtk_drawing_area_size(GTK_DRAWING_AREA(widtxt),
786
626
adjustmentv = gtk_adjustment_new(0.0, 0.0, 201.0, 1.0, 20.0, 20.0);
787
627
scrollbarv = gtk_vscrollbar_new(GTK_ADJUSTMENT(adjustmentv));
788
628
GTK_WIDGET_UNSET_FLAGS(PWidget(scrollbarv), GTK_CAN_FOCUS);
789
#if GLIB_MAJOR_VERSION < 2
790
gtk_signal_connect(adjustmentv, "value_changed",
791
GtkSignalFunc(ScrollSignal), this);
793
629
g_signal_connect(G_OBJECT(adjustmentv), "value_changed",
794
630
G_CALLBACK(ScrollSignal), this);
796
631
gtk_widget_set_parent(PWidget(scrollbarv), PWidget(wMain));
797
632
gtk_widget_show(PWidget(scrollbarv));
799
634
adjustmenth = gtk_adjustment_new(0.0, 0.0, 101.0, 1.0, 20.0, 20.0);
800
635
scrollbarh = gtk_hscrollbar_new(GTK_ADJUSTMENT(adjustmenth));
801
636
GTK_WIDGET_UNSET_FLAGS(PWidget(scrollbarh), GTK_CAN_FOCUS);
802
#if GLIB_MAJOR_VERSION < 2
803
gtk_signal_connect(adjustmenth, "value_changed",
804
GtkSignalFunc(ScrollHSignal), this);
806
637
g_signal_connect(G_OBJECT(adjustmenth), "value_changed",
807
638
G_CALLBACK(ScrollHSignal), this);
809
639
gtk_widget_set_parent(PWidget(scrollbarh), PWidget(wMain));
810
640
gtk_widget_show(PWidget(scrollbarh));
878
702
reinterpret_cast<GdkEvent *>(&evbtn));
882
705
static char *ConvertText(int *lenResult, char *s, size_t len, const char *charSetDest,
883
const char *charSetSource, bool transliterations) {
706
const char *charSetSource, bool transliterations, bool silent=false) {
707
// s is not const because of different versions of iconv disagreeing about const
885
709
char *destForm = 0;
886
710
Converter conv(charSetDest, charSetSource, transliterations);
892
716
size_t outLeft = len*3+1;
893
717
size_t conversions = conv.Convert(&pin, &inLeft, &pout, &outLeft);
894
718
if (conversions == ((size_t)(-1))) {
895
fprintf(stderr, "iconv %s->%s failed for %s\n", charSetSource, charSetDest, static_cast<char *>(s));
720
fprintf(stderr, "iconv %s->%s failed for %s\n",
721
charSetSource, charSetDest, static_cast<char *>(s));
896
722
delete []destForm;
963
783
return inputLength;
965
785
// Need to convert
967
786
const char *charSetBuffer = CharacterSetID();
968
787
if (*charSetBuffer) {
969
//~ fprintf(stderr, "Encode %s %d\n", charSetBuffer, inputLength);
970
788
int outLength = 0;
971
789
char *tmpEncoded = ConvertText(&outLength, utf8, inputLength, charSetBuffer, "UTF-8", true);
972
790
if (tmpEncoded) {
973
//~ fprintf(stderr, " \"%s\"\n", tmpEncoded);
975
792
memcpy(encoded, tmpEncoded, outLength);
1049
877
bool ScintillaGTK::SetIdle(bool on) {
1051
879
// Start idler, if it's not running.
1052
if (idler.state == false) {
1053
881
idler.state = true;
1054
idler.idlerID = reinterpret_cast<IdlerID>
1055
(gtk_idle_add((GtkFunction)IdleCallback, this));
882
idler.idlerID = reinterpret_cast<IdlerID>(
883
g_idle_add_full(G_PRIORITY_DEFAULT_IDLE,
884
reinterpret_cast<GSourceFunc>(IdleCallback), this, NULL));
1058
887
// Stop idler, if it's running
1059
if (idler.state == true) {
1060
889
idler.state = false;
1061
gtk_idle_remove(GPOINTER_TO_UINT(idler.idlerID));
890
g_source_remove(GPOINTER_TO_UINT(idler.idlerID));
1098
927
// Redraw all of text area. This paint will not be abandoned.
1099
928
void ScintillaGTK::FullPaint() {
1100
#if GTK_MAJOR_VERSION < 2
1101
paintState = painting;
1102
rcPaint = GetClientRectangle();
1103
//Platform::DebugPrintf("ScintillaGTK::FullPaint %0d,%0d %0d,%0d\n",
1104
// rcPaint.left, rcPaint.top, rcPaint.right, rcPaint.bottom);
1105
paintingAllText = true;
1106
if ((PWidget(wText))->window) {
1107
Surface *sw = Surface::Allocate();
1109
sw->Init(PWidget(wText)->window, PWidget(wText));
1115
paintState = notPainting;
1117
929
wText.InvalidateAll();
1121
932
PRectangle ScintillaGTK::GetClientRectangle() {
1160
971
// rc.left, rc.top, rc.right, rc.bottom);
1161
972
GtkWidget *wi = PWidget(wText);
1163
#if GTK_MAJOR_VERSION < 2
1164
PRectangle rc = GetClientRectangle();
1165
GdkGC *gc = gdk_gc_new(wi->window);
1167
// Set up gc so we get GraphicsExposures from gdk_draw_pixmap
1168
// which calls XCopyArea
1169
gdk_gc_set_exposures(gc, TRUE);
1171
// Redraw exposed bit : scrolling upwards
1173
gdk_draw_pixmap(wi->window,
1177
rc.Width()-1, rc.Height() - diff);
1178
SyncPaint(PRectangle(0, rc.Height() - diff,
1179
rc.Width(), rc.Height()+1));
1181
// Redraw exposed bit : scrolling downwards
1183
gdk_draw_pixmap(wi->window,
1187
rc.Width()-1, rc.Height() + diff);
1188
SyncPaint(PRectangle(0, 0, rc.Width(), -diff));
1191
// Look for any graphics expose
1193
while ((event = gdk_event_get_graphics_expose(wi->window)) != NULL) {
1194
gtk_widget_event(wi, event);
1195
if (event->expose.count == 0) {
1196
gdk_event_free(event);
1199
gdk_event_free(event);
1204
974
gdk_window_scroll(wi->window, 0, -diff);
1205
975
gdk_window_process_updates(wi->window, FALSE);
1209
978
void ScintillaGTK::SetVerticalScrollPos() {
1259
1028
void ScintillaGTK::NotifyChange() {
1260
#if GLIB_MAJOR_VERSION < 2
1261
gtk_signal_emit(GTK_OBJECT(sci), scintilla_signals[COMMAND_SIGNAL],
1262
Platform::LongFromTwoShorts(GetCtrlID(), SCEN_CHANGE), PWidget(wMain));
1264
1029
g_signal_emit(G_OBJECT(sci), scintilla_signals[COMMAND_SIGNAL], 0,
1265
1030
Platform::LongFromTwoShorts(GetCtrlID(), SCEN_CHANGE), PWidget(wMain));
1269
1033
void ScintillaGTK::NotifyFocus(bool focus) {
1270
#if GLIB_MAJOR_VERSION < 2
1271
gtk_signal_emit(GTK_OBJECT(sci), scintilla_signals[COMMAND_SIGNAL],
1272
Platform::LongFromTwoShorts
1273
(GetCtrlID(), focus ? SCEN_SETFOCUS : SCEN_KILLFOCUS), PWidget(wMain));
1275
1034
g_signal_emit(G_OBJECT(sci), scintilla_signals[COMMAND_SIGNAL], 0,
1276
1035
Platform::LongFromTwoShorts
1277
1036
(GetCtrlID(), focus ? SCEN_SETFOCUS : SCEN_KILLFOCUS), PWidget(wMain));
1281
1039
void ScintillaGTK::NotifyParent(SCNotification scn) {
1282
1040
scn.nmhdr.hwndFrom = PWidget(wMain);
1283
1041
scn.nmhdr.idFrom = GetCtrlID();
1284
#if GLIB_MAJOR_VERSION < 2
1285
gtk_signal_emit(GTK_OBJECT(sci), scintilla_signals[NOTIFY_SIGNAL],
1288
1042
g_signal_emit(G_OBJECT(sci), scintilla_signals[NOTIFY_SIGNAL], 0,
1289
1043
GetCtrlID(), &scn);
1293
1046
void ScintillaGTK::NotifyKey(int key, int modifiers) {
1313
1066
return ::CharacterSetID(vs.styles[STYLE_DEFAULT].characterSet);
1069
class CaseFolderUTF8 : public CaseFolderTable {
1074
virtual size_t Fold(char *folded, size_t sizeFolded, const char *mixed, size_t lenMixed) {
1075
if ((lenMixed == 1) && (sizeFolded > 0)) {
1076
folded[0] = mapping[static_cast<unsigned char>(mixed[0])];
1079
gchar *mapped = g_utf8_casefold(mixed, lenMixed);
1080
size_t lenMapped = strlen(mapped);
1081
if (lenMapped < sizeFolded) {
1082
memcpy(folded, mapped, lenMapped);
1092
CaseFolder *ScintillaGTK::CaseFolderForEncoding() {
1093
if (pdoc->dbcsCodePage == SC_CP_UTF8) {
1094
return new CaseFolderUTF8();
1096
CaseFolderTable *pcf = new CaseFolderTable();
1097
const char *charSetBuffer = CharacterSetID();
1098
if ((pdoc->dbcsCodePage == 0) && charSetBuffer) {
1099
pcf->StandardASCII();
1100
// Only for single byte encodings
1101
for (int i=0x80; i<0x100; i++) {
1102
char sCharacter[2] = "A";
1104
int convertedLength = 1;
1105
const char *sUTF8 = ConvertText(&convertedLength, sCharacter, 1,
1106
"UTF-8", charSetBuffer, false);
1108
gchar *mapped = g_utf8_casefold(sUTF8, strlen(sUTF8));
1110
int mappedLength = strlen(mapped);
1111
const char *mappedBack = ConvertText(&mappedLength, mapped,
1112
mappedLength, charSetBuffer, "UTF-8", false, true);
1113
if (mappedBack && (strlen(mappedBack) == 1) && (mappedBack[0] != sCharacter[0])) {
1114
pcf->SetTranslation(sCharacter[0], mappedBack[0]);
1116
delete []mappedBack;
1127
std::string ScintillaGTK::CaseMapString(const std::string &s, int caseMapping) {
1129
return std::string();
1131
if (caseMapping == cmSame)
1134
const char *needsFree1 = 0; // Must be freed with delete []
1135
const char *charSetBuffer = CharacterSetID();
1136
const char *sUTF8 = s.c_str();
1137
int rangeBytes = s.size();
1139
int convertedLength = rangeBytes;
1140
// Change text to UTF-8
1141
if (!IsUnicodeMode()) {
1143
if (*charSetBuffer) {
1144
sUTF8 = ConvertText(&convertedLength, const_cast<char *>(s.c_str()), rangeBytes,
1145
"UTF-8", charSetBuffer, false);
1149
gchar *mapped; // Must be freed with g_free
1150
if (caseMapping == cmUpper) {
1151
mapped = g_utf8_strup(sUTF8, convertedLength);
1153
mapped = g_utf8_strdown(sUTF8, convertedLength);
1155
int mappedLength = strlen(mapped);
1156
char *mappedBack = mapped;
1158
char *needsFree2 = 0; // Must be freed with delete []
1159
if (!IsUnicodeMode()) {
1160
if (*charSetBuffer) {
1161
mappedBack = ConvertText(&mappedLength, mapped, mappedLength, charSetBuffer, "UTF-8", false);
1162
needsFree2 = mappedBack;
1166
std::string ret(mappedBack, mappedLength);
1168
delete []needsFree1;
1169
delete []needsFree2;
1316
1173
int ScintillaGTK::KeyDefault(int key, int modifiers) {
1317
1174
if (!(modifiers & SCI_CTRL) && !(modifiers & SCI_ALT)) {
1318
1175
if (key < 256) {
1378
1235
ct.wDraw = gtk_drawing_area_new();
1379
1236
GtkWidget *widcdrw = PWidget(ct.wDraw); // // No code inside the G_OBJECT macro
1380
1237
gtk_container_add(GTK_CONTAINER(PWidget(ct.wCallTip)), widcdrw);
1381
#if GLIB_MAJOR_VERSION < 2
1382
gtk_signal_connect(GTK_OBJECT(widcdrw), "expose_event",
1383
GtkSignalFunc(ScintillaGTK::ExposeCT), &ct);
1384
gtk_signal_connect(GTK_OBJECT(widcdrw), "button_press_event",
1385
GtkSignalFunc(ScintillaGTK::PressCT), static_cast<void *>(this));
1387
1238
g_signal_connect(G_OBJECT(widcdrw), "expose_event",
1388
1239
G_CALLBACK(ScintillaGTK::ExposeCT), &ct);
1389
1240
g_signal_connect(G_OBJECT(widcdrw), "button_press_event",
1390
1241
G_CALLBACK(ScintillaGTK::PressCT), static_cast<void *>(this));
1392
1242
gtk_widget_set_events(widcdrw,
1393
1243
GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK);
1487
1337
} else { // UTF-8
1488
1338
dest = Document::TransformLineEnds(&len, data, len, pdoc->eolMode);
1489
1339
selText.Set(dest, len, SC_CP_UTF8, 0, isRectangular, false);
1490
#ifdef USE_CONVERTER
1491
1340
const char *charSetBuffer = CharacterSetID();
1492
1341
if (!IsUnicodeMode() && *charSetBuffer) {
1493
//fprintf(stderr, "Convert to locale %s\n", CharacterSetID());
1494
// Convert to locale
1495
dest = ConvertText(&len, selText.s, selText.len, charSetBuffer, "UTF-8", true);
1496
selText.Set(dest, len, pdoc->dbcsCodePage,
1497
vs.styles[STYLE_DEFAULT].characterSet, selText.rectangular, false);
1342
// Convert to locale
1343
dest = ConvertText(&len, selText.s, selText.len, charSetBuffer, "UTF-8", true);
1344
selText.Set(dest, len, pdoc->dbcsCodePage,
1345
vs.styles[STYLE_DEFAULT].characterSet, selText.rectangular, false);
1513
1360
SelectionText selText;
1514
1361
GetGtkSelectionText(selection_data, selText);
1516
pdoc->BeginUndoAction();
1517
1364
if (selection_data->selection != GDK_SELECTION_PRIMARY) {
1518
1365
ClearSelection();
1520
int selStart = SelectionStart();
1367
SelectionPosition selStart = sel.IsRectangular() ?
1368
sel.Rectangular().Start() :
1369
sel.Range(sel.Main()).Start();
1522
1371
if (selText.rectangular) {
1523
1372
PasteRectangular(selStart, selText.s, selText.len);
1525
pdoc->InsertString(currentPos, selText.s, selText.len);
1526
SetEmptySelection(currentPos + selText.len);
1374
InsertPaste(selStart, selText.s, selText.len);
1528
pdoc->EndUndoAction();
1529
1376
EnsureCaretVisible();
1595
1441
// All other tested aplications behave benignly by ignoring the \0.
1596
1442
// The #if is here because on Windows cfColumnSelect clip entry is used
1597
1443
// instead as standard indicator of rectangularness (so no need to kludge)
1598
int len = strlen(text->s);
1444
const char *textData = text->s ? text->s : "";
1445
int len = strlen(textData);
1599
1446
#if PLAT_GTK_WIN32 == 0
1600
1447
if (text->rectangular)
1604
1451
if (info == TARGET_UTF8_STRING) {
1605
gtk_selection_data_set_text(selection_data, text->s, len);
1452
gtk_selection_data_set_text(selection_data, textData, len);
1607
1454
gtk_selection_data_set(selection_data,
1608
1455
static_cast<GdkAtom>(GDK_SELECTION_TYPE_STRING),
1609
8, reinterpret_cast<unsigned char *>(text->s), len);
1456
8, reinterpret_cast<const unsigned char *>(textData), len);
1611
1458
delete converted;
1614
char *selBuffer = text->s;
1617
if ((info == TARGET_UTF8_STRING) || (info == TARGET_STRING)) {
1618
int len = strlen(selBuffer);
1619
#ifdef USE_CONVERTER
1620
// Possible character set conversion
1621
const char *charSetBuffer = ::CharacterSetID(text->characterSet);
1622
if (info == TARGET_UTF8_STRING) {
1623
//fprintf(stderr, "Copy to clipboard as UTF-8\n");
1624
if (text->codePage != SC_CP_UTF8) {
1626
//fprintf(stderr, "Convert to UTF-8 from %s\n", charSetBuffer);
1627
tmputf = ConvertText(&len, selBuffer, len, "UTF-8", charSetBuffer, false);
1630
} else if (info == TARGET_STRING) {
1631
if (text->codePage == SC_CP_UTF8) {
1632
//fprintf(stderr, "Convert to locale %s\n", charSetBuffer);
1633
// Convert to locale
1634
tmputf = ConvertText(&len, selBuffer, len, charSetBuffer, "UTF-8", true);
1640
// Here is a somewhat evil kludge.
1641
// As I can not work out how to store data on the clipboard in multiple formats
1642
// and need some way to mark the clipping as being stream or rectangular,
1643
// the terminating \0 is included in the length for rectangular clippings.
1644
// All other tested aplications behave benignly by ignoring the \0.
1645
// The #if is here because on Windows cfColumnSelect clip entry is used
1646
// instead as standard indicator of rectangularness (so no need to kludge)
1647
#if PLAT_GTK_WIN32 == 0
1648
if (text->rectangular)
1651
gtk_selection_data_set(selection_data,
1652
(info == TARGET_STRING) ?
1653
static_cast<GdkAtom>(GDK_SELECTION_TYPE_STRING) : atomUTF8,
1654
8, reinterpret_cast<unsigned char *>(selBuffer),
1656
} else if ((info == TARGET_TEXT) || (info == TARGET_COMPOUND_TEXT)) {
1662
gdk_string_to_compound_text(reinterpret_cast<char *>(selBuffer),
1663
&encoding, &format, &text, &new_length);
1664
gtk_selection_data_set(selection_data, encoding, format, text, new_length);
1665
gdk_free_compound_text(text);
1669
#endif /* Gtk >= 2 */
1671
1460
#if PLAT_GTK_WIN32
1672
1461
delete newline_normalized;
1804
1605
gtk_widget_grab_focus(PWidget(wMain));
1805
1606
if (event->button == 1) {
1806
// On X, instead of sending literal modifiers use control instead of alt
1607
// On X, instead of sending literal modifiers use the user specified
1608
// modifier, defaulting to control instead of alt.
1807
1609
// This is because most X window managers grab alt + click for moving
1809
ButtonDown(pt, event->time,
1810
(event->state & GDK_SHIFT_MASK) != 0,
1811
(event->state & GDK_CONTROL_MASK) != 0,
1812
(event->state & GDK_CONTROL_MASK) != 0);
1814
ButtonDown(pt, event->time,
1815
(event->state & GDK_SHIFT_MASK) != 0,
1816
(event->state & GDK_CONTROL_MASK) != 0,
1817
(event->state & GDK_MOD1_MASK) != 0);
1610
ButtonDown(pt, event->time,
1611
(event->state & GDK_SHIFT_MASK) != 0,
1612
(event->state & GDK_CONTROL_MASK) != 0,
1613
(event->state & modifierTranslated(rectangularSelectionModifier)) != 0);
1819
1614
} else if (event->button == 2) {
1820
1615
// Grab the primary selection if it exists
1821
Position pos = PositionFromLocation(pt);
1616
SelectionPosition pos = SPositionFromLocation(pt, false, false, UserVirtualSpace());
1822
1617
if (OwnPrimarySelection() && primary.s == NULL)
1823
1618
CopySelectionRange(&primary);
1825
1621
SetSelection(pos, pos);
1826
1622
atomSought = atomUTF8;
1827
1623
gtk_selection_convert(GTK_WIDGET(PWidget(wMain)), GDK_SELECTION_PRIMARY,
2375
2141
//fprintf(stderr, "Expose %0d,%0d %0d,%0d\n",
2376
2142
//ose->area.x, ose->area.y, ose->area.width, ose->area.height);
2378
#if GTK_MAJOR_VERSION < 2
2380
paintState = painting;
2382
rcPaint.left = ose->area.x;
2383
rcPaint.top = ose->area.y;
2384
rcPaint.right = ose->area.x + ose->area.width;
2385
rcPaint.bottom = ose->area.y + ose->area.height;
2387
PRectangle rcClient = GetClientRectangle();
2388
paintingAllText = rcPaint.Contains(rcClient);
2389
Surface *surfaceWindow = Surface::Allocate();
2390
if (surfaceWindow) {
2391
surfaceWindow->Init(PWidget(wMain)->window, PWidget(wMain));
2393
// Fill the corner between the scrollbars
2394
if (verticalScrollBarVisible) {
2395
if (horizontalScrollBarVisible && (wrapState == eWrapNone)) {
2396
PRectangle rcCorner = wMain.GetClientPosition();
2397
rcCorner.left = rcCorner.right - scrollBarWidth + 1;
2398
rcCorner.top = rcCorner.bottom - scrollBarHeight + 1;
2399
//fprintf(stderr, "Corner %0d,%0d %0d,%0d\n",
2400
//rcCorner.left, rcCorner.top, rcCorner.right, rcCorner.bottom);
2401
surfaceWindow->FillRectangle(rcCorner,
2402
vs.styles[STYLE_LINENUMBER].back.allocated);
2406
//Paint(surfaceWindow, rcPaint);
2407
surfaceWindow->Release();
2408
delete surfaceWindow;
2410
if (paintState == paintAbandoned) {
2411
// Painting area was insufficient to cover new styling or brace highlight positions
2414
paintState = notPainting;
2417
// For GTK+ 2, the text is painted in ExposeText
2144
// The text is painted in ExposeText
2418
2145
gtk_container_propagate_expose(
2419
2146
GTK_CONTAINER(PWidget(wMain)), PWidget(scrollbarh), ose);
2420
2147
gtk_container_propagate_expose(
2421
2148
GTK_CONTAINER(PWidget(wMain)), PWidget(scrollbarv), ose);
2424
2150
} catch (...) {
2425
2151
errorStatus = SC_STATUS_FAILURE;
2493
2212
gint x, gint y, guint dragtime) {
2495
2214
Point npt(x, y);
2496
SetDragPosition(PositionFromLocation(npt));
2215
SetDragPosition(SPositionFromLocation(npt, false, false, UserVirtualSpace()));
2497
2216
GdkDragAction preferredAction = context->suggested_action;
2498
int pos = PositionFromLocation(npt);
2499
if ((inDragDrop == ddDragging) && (0 == PositionInSelection(pos))) {
2217
SelectionPosition pos = SPositionFromLocation(npt);
2218
if ((inDragDrop == ddDragging) && (PositionInSelection(pos.Position()))) {
2500
2219
// Avoid dragging selection onto itself as that produces a move
2501
2220
// with no real effect but which creates undo actions.
2502
2221
preferredAction = static_cast<GdkDragAction>(0);
2569
2288
ScintillaGTK *sciThis = ScintillaFromWidget(widget);
2571
2290
sciThis->dragWasDropped = true;
2572
if (sciThis->currentPos != sciThis->anchor) {
2291
if (!sciThis->sel.Empty()) {
2573
2292
sciThis->GetSelection(selection_data, info, &sciThis->drag);
2575
2294
if (context->action == GDK_ACTION_MOVE) {
2576
int selStart = sciThis->SelectionStart();
2577
int selEnd = sciThis->SelectionEnd();
2578
if (sciThis->posDrop > selStart) {
2579
if (sciThis->posDrop > selEnd)
2580
sciThis->posDrop = sciThis->posDrop - (selEnd - selStart);
2582
sciThis->posDrop = selStart;
2583
sciThis->posDrop = sciThis->pdoc->ClampPositionIntoDocument(sciThis->posDrop);
2295
for (size_t r=0; r<sciThis->sel.Count(); r++) {
2296
if (sciThis->posDrop >= sciThis->sel.Range(r).Start()) {
2297
if (sciThis->posDrop > sciThis->sel.Range(r).End()) {
2298
sciThis->posDrop.Add(-sciThis->sel.Range(r).Length());
2300
sciThis->posDrop.Add(-SelectionRange(sciThis->posDrop, sciThis->sel.Range(r).Start()).Length());
2585
2304
sciThis->ClearSelection();
2587
sciThis->SetDragPosition(invalidPosition);
2306
sciThis->SetDragPosition(SelectionPosition(invalidPosition));
2588
2307
} catch (...) {
2589
2308
sciThis->errorStatus = SC_STATUS_FAILURE;
2330
gboolean ScintillaGTK::StyleIdle(ScintillaGTK *sciThis) {
2331
sciThis->IdleStyling();
2332
// Idler will be automatically stopped
2336
void ScintillaGTK::QueueStyling(int upTo) {
2337
Editor::QueueStyling(upTo);
2338
if (!styleNeeded.active) {
2339
// Only allow one style needed to be queued
2340
styleNeeded.active = true;
2341
g_idle_add_full(G_PRIORITY_HIGH_IDLE,
2342
reinterpret_cast<GSourceFunc>(StyleIdle), this, NULL);
2611
2346
void ScintillaGTK::PopUpCB(ScintillaGTK *sciThis, guint action, GtkWidget *) {
2613
2348
sciThis->Command(action);
2667
2398
extern void Platform_Initialise();
2668
2399
extern void Platform_Finalise();
2670
#if GLIB_MAJOR_VERSION < 2
2671
GtkType scintilla_get_type() {
2672
static GtkType scintilla_type = 0;
2675
if (!scintilla_type) {
2676
Platform_Initialise();
2677
static GtkTypeInfo scintilla_info = {
2679
sizeof (ScintillaObject),
2680
sizeof (ScintillaClass),
2681
(GtkClassInitFunc) scintilla_class_init,
2682
(GtkObjectInitFunc) scintilla_init,
2688
scintilla_type = gtk_type_unique(gtk_container_get_type(), &scintilla_info);
2693
return scintilla_type;
2696
2401
GType scintilla_get_type() {
2697
2402
static GType scintilla_type = 0;
2738
2440
// of the signal handlers here (those that currently attached to wDraw
2739
2441
// in Initialise() may require coordinate translation?)
2741
#if GLIB_MAJOR_VERSION < 2
2742
object_class->destroy = Destroy;
2744
2443
object_class->finalize = Destroy;
2746
2444
widget_class->size_request = SizeRequest;
2747
2445
widget_class->size_allocate = SizeAllocate;
2748
2446
widget_class->expose_event = ExposeMain;
2749
#if GTK_MAJOR_VERSION < 2
2750
widget_class->draw = Draw;
2752
2447
widget_class->motion_notify_event = Motion;
2753
2448
widget_class->button_press_event = Press;
2754
2449
widget_class->button_release_event = MouseRelease;
2755
#if PLAT_GTK_WIN32 || (GTK_MAJOR_VERSION >= 2)
2756
2450
widget_class->scroll_event = ScrollEvent;
2758
2451
widget_class->key_press_event = KeyPress;
2759
2452
widget_class->key_release_event = KeyRelease;
2760
2453
widget_class->focus_in_event = FocusIn;
2796
2480
GtkWidgetClass *widget_class = (GtkWidgetClass*) klass;
2797
2481
GtkContainerClass *container_class = (GtkContainerClass*) klass;
2799
#if GLIB_MAJOR_VERSION < 2
2800
parent_class = (GtkWidgetClass*) gtk_type_class(gtk_container_get_type());
2802
scintilla_signals[COMMAND_SIGNAL] = gtk_signal_new(
2805
GTK_CLASS_TYPE(object_class),
2806
GTK_SIGNAL_OFFSET(ScintillaClass, command),
2809
2, MARSHAL_ARGUMENTS);
2811
scintilla_signals[NOTIFY_SIGNAL] = gtk_signal_new(
2814
GTK_CLASS_TYPE(object_class),
2815
GTK_SIGNAL_OFFSET(ScintillaClass, notify),
2818
2, MARSHAL_ARGUMENTS);
2819
gtk_object_class_add_signals(object_class,
2820
reinterpret_cast<unsigned int *>(scintilla_signals), LAST_SIGNAL);
2822
2483
GSignalFlags sigflags = GSignalFlags(G_SIGNAL_ACTION | G_SIGNAL_RUN_LAST);
2823
2484
scintilla_signals[COMMAND_SIGNAL] = g_signal_new(