notepad-plus-plus/scintilla/gtk/ScintillaGTK.h

338 lines
13 KiB
C
Raw Normal View History

2019-05-04 18:14:48 +00:00
// Scintilla source code edit control
// ScintillaGTK.h - GTK+ specific subclass of ScintillaBase
// Copyright 1998-2004 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
#ifndef SCINTILLAGTK_H
#define SCINTILLAGTK_H
namespace Scintilla::Internal {
2019-05-04 18:14:48 +00:00
class ScintillaGTKAccessible;
#define OBJECT_CLASS GObjectClass
struct FontOptions {
cairo_antialias_t antialias {};
cairo_subpixel_order_t order {};
cairo_hint_style_t hint {};
FontOptions() noexcept = default;
explicit FontOptions(GtkWidget *widget) noexcept;
bool operator==(const FontOptions &other) const noexcept;
};
2019-05-04 18:14:48 +00:00
class ScintillaGTK : public ScintillaBase {
friend class ScintillaGTKAccessible;
_ScintillaObject *sci;
Window wText;
Window scrollbarv;
Window scrollbarh;
GtkAdjustment *adjustmentv;
GtkAdjustment *adjustmenth;
int verticalScrollBarWidth;
int horizontalScrollBarHeight;
Update scintilla 5.3.4 and lexilla 5.2.4 with: https://www.scintilla.org/scintilla534.zip Released 8 March 2023. Add multithreaded wrap to significantly improve performance of wrapping large files. More typesafe bindings of *Full APIs in ScintillaCall. Feature #1477. Fix overlapping of text with line end wrap marker. Bug #2378. Fix clipping of line end wrap symbol for SC_WRAPVISUALFLAGLOC_END_BY_TEXT. Where a multi-byte character contains multiple styles, display each byte as a representation. This makes it easier to see and fix lexers that change styles mid-character, commonly because they use fixed size buffers. Fix a potential crash with autocompletion list fill-ups where a SCN_CHARADDED handler retriggered an autocompletion list, but with no items that match the typed character. lexilla523 Released 8 March 2023. Add scripts/PromoteNew.bat script to promote .new files after checking. Makefile: Remove 1024-byte line length limit.. Ruby: Add new lexical classes for % literals SCE_RB_STRING_W (%w non-interpolable string array), SCE_RB_STRING_I (%i non-interpolable symbol array), SCE_RB_STRING_QI (%I interpolable symbol array), and SCE_RB_STRING_QS (%s symbol). Issue #124. Ruby: Disambiguate %= which may be a quote or modulo assignment. Issue #124, Bug #1255, Bug #2182. Ruby: Fix additional fold level for single character in SCE_RB_STRING_QW. Issue #132. Ruby: Set SCE_RB_HERE_QQ for unquoted and double-quoted heredocs and SCE_RB_HERE_QX for backticks-quoted heredocs. Issue #134. Ruby: Recognise #{} inside SCE_RB_HERE_QQ and SCE_RB_HERE_QX. Issue #134. Ruby: Improve regex and heredoc recognition. Issue #136. Ruby: Highlight #@, #@@ and #$ style interpolation. Issue #140. Ruby: Fix folding for multiple heredocs started on one line. Fix folding when there is a space after heredoc opening delimiter. Issue #135. YAML: Remove 1024-byte line length limit. https://www.scintilla.org/lexilla524.zip Released 13 March 2023. C++: Fix failure to recognize keywords containing upper case. Issue #149. GDScript: Support % and $ node paths. Issue #145, Pull request #146. Close #13338
2023-03-10 02:37:21 +00:00
PRectangle rectangleClient;
2019-05-04 18:14:48 +00:00
SelectionText primary;
SelectionPosition posPrimary;
2019-05-04 18:14:48 +00:00
UniqueGdkEvent evbtn;
2019-05-04 18:14:48 +00:00
guint buttonMouse;
bool capturedMouse;
bool dragWasDropped;
int lastKey;
int rectangularSelectionModifier;
GtkWidgetClass *parentClass;
static inline GdkAtom atomUTF8 {};
static inline GdkAtom atomUTF8Mime {};
static inline GdkAtom atomString {};
static inline GdkAtom atomUriList {};
static inline GdkAtom atomDROPFILES_DND {};
2019-05-04 18:14:48 +00:00
GdkAtom atomSought;
size_t inClearSelection = 0;
2019-05-04 18:14:48 +00:00
#if PLAT_GTK_WIN32
CLIPFORMAT cfColumnSelect;
#endif
bool preeditInitialized;
2019-05-04 18:14:48 +00:00
Window wPreedit;
Window wPreeditDraw;
UniqueIMContext im_context;
GUnicodeScript lastNonCommonScript;
2019-05-04 18:14:48 +00:00
GtkSettings *settings;
gulong settingsHandlerId;
2019-05-04 18:14:48 +00:00
// Wheel mouse support
unsigned int linesPerScroll;
gint64 lastWheelMouseTime;
2019-05-04 18:14:48 +00:00
gint lastWheelMouseDirection;
gint wheelMouseIntensity;
gdouble smoothScrollY;
gdouble smoothScrollX;
#if GTK_CHECK_VERSION(3,0,0)
cairo_rectangle_list_t *rgnUpdate;
#else
GdkRegion *rgnUpdate;
#endif
bool repaintFullWindow;
guint styleIdleID;
guint scrollBarIdleID = 0;
FontOptions fontOptionsPrevious;
2019-05-04 18:14:48 +00:00
int accessibilityEnabled;
AtkObject *accessible;
public:
explicit ScintillaGTK(_ScintillaObject *sci_);
// Deleted so ScintillaGTK objects can not be copied.
ScintillaGTK(const ScintillaGTK &) = delete;
ScintillaGTK(ScintillaGTK &&) = delete;
ScintillaGTK &operator=(const ScintillaGTK &) = delete;
ScintillaGTK &operator=(ScintillaGTK &&) = delete;
~ScintillaGTK() override;
static ScintillaGTK *FromWidget(GtkWidget *widget) noexcept;
static void ClassInit(OBJECT_CLASS *object_class, GtkWidgetClass *widget_class, GtkContainerClass *container_class);
2019-05-04 18:14:48 +00:00
private:
void Init();
void Finalise() override;
bool AbandonPaint() override;
void DisplayCursor(Window::Cursor c) override;
bool DragThreshold(Point ptStart, Point ptNow) override;
void StartDrag() override;
Sci::Position TargetAsUTF8(char *text) const;
Sci::Position EncodedFromUTF8(const char *utf8, char *encoded) const;
bool ValidCodePage(int codePage) const override;
std::string UTF8FromEncoded(std::string_view encoded) const override;
std::string EncodedFromUTF8(std::string_view utf8) const override;
2019-05-04 18:14:48 +00:00
public: // Public for scintilla_send_message
sptr_t WndProc(Scintilla::Message iMessage, Scintilla::uptr_t wParam, Scintilla::sptr_t lParam) override;
2019-05-04 18:14:48 +00:00
private:
sptr_t DefWndProc(Scintilla::Message iMessage, Scintilla::uptr_t wParam, Scintilla::sptr_t lParam) override;
2019-05-04 18:14:48 +00:00
struct TimeThunk {
TickReason reason;
ScintillaGTK *scintilla;
guint timer;
TimeThunk() noexcept : reason(TickReason::caret), scintilla(nullptr), timer(0) {}
2019-05-04 18:14:48 +00:00
};
TimeThunk timers[static_cast<size_t>(TickReason::dwell)+1];
2019-05-04 18:14:48 +00:00
bool FineTickerRunning(TickReason reason) override;
void FineTickerStart(TickReason reason, int millis, int tolerance) override;
void FineTickerCancel(TickReason reason) override;
bool SetIdle(bool on) override;
void SetMouseCapture(bool on) override;
bool HaveMouseCapture() override;
bool PaintContains(PRectangle rc) override;
void FullPaint();
Update scintilla 5.3.4 and lexilla 5.2.4 with: https://www.scintilla.org/scintilla534.zip Released 8 March 2023. Add multithreaded wrap to significantly improve performance of wrapping large files. More typesafe bindings of *Full APIs in ScintillaCall. Feature #1477. Fix overlapping of text with line end wrap marker. Bug #2378. Fix clipping of line end wrap symbol for SC_WRAPVISUALFLAGLOC_END_BY_TEXT. Where a multi-byte character contains multiple styles, display each byte as a representation. This makes it easier to see and fix lexers that change styles mid-character, commonly because they use fixed size buffers. Fix a potential crash with autocompletion list fill-ups where a SCN_CHARADDED handler retriggered an autocompletion list, but with no items that match the typed character. lexilla523 Released 8 March 2023. Add scripts/PromoteNew.bat script to promote .new files after checking. Makefile: Remove 1024-byte line length limit.. Ruby: Add new lexical classes for % literals SCE_RB_STRING_W (%w non-interpolable string array), SCE_RB_STRING_I (%i non-interpolable symbol array), SCE_RB_STRING_QI (%I interpolable symbol array), and SCE_RB_STRING_QS (%s symbol). Issue #124. Ruby: Disambiguate %= which may be a quote or modulo assignment. Issue #124, Bug #1255, Bug #2182. Ruby: Fix additional fold level for single character in SCE_RB_STRING_QW. Issue #132. Ruby: Set SCE_RB_HERE_QQ for unquoted and double-quoted heredocs and SCE_RB_HERE_QX for backticks-quoted heredocs. Issue #134. Ruby: Recognise #{} inside SCE_RB_HERE_QQ and SCE_RB_HERE_QX. Issue #134. Ruby: Improve regex and heredoc recognition. Issue #136. Ruby: Highlight #@, #@@ and #$ style interpolation. Issue #140. Ruby: Fix folding for multiple heredocs started on one line. Fix folding when there is a space after heredoc opening delimiter. Issue #135. YAML: Remove 1024-byte line length limit. https://www.scintilla.org/lexilla524.zip Released 13 March 2023. C++: Fix failure to recognize keywords containing upper case. Issue #149. GDScript: Support % and $ node paths. Issue #145, Pull request #146. Close #13338
2023-03-10 02:37:21 +00:00
void SetClientRectangle();
2019-05-04 18:14:48 +00:00
PRectangle GetClientRectangle() const override;
void ScrollText(Sci::Line linesToMove) override;
void SetVerticalScrollPos() override;
void SetHorizontalScrollPos() override;
bool ModifyScrollBars(Sci::Line nMax, Sci::Line nPage) override;
void ReconfigureScrollBars() override;
void SetScrollBars() override;
2019-05-04 18:14:48 +00:00
void NotifyChange() override;
void NotifyFocus(bool focus) override;
void NotifyParent(Scintilla::NotificationData scn) override;
void NotifyKey(Scintilla::Keys key, Scintilla::KeyMod modifiers);
2019-05-04 18:14:48 +00:00
void NotifyURIDropped(const char *list);
const char *CharacterSetID() const;
std::unique_ptr<CaseFolder> CaseFolderForEncoding() override;
std::string CaseMapString(const std::string &s, CaseMapping caseMapping) override;
int KeyDefault(Scintilla::Keys key, Scintilla::KeyMod modifiers) override;
2019-05-04 18:14:48 +00:00
void CopyToClipboard(const SelectionText &selectedText) override;
void Copy() override;
void RequestSelection(GdkAtom atomSelection);
2019-05-04 18:14:48 +00:00
void Paste() override;
void CreateCallTipWindow(PRectangle rc) override;
void AddToPopUp(const char *label, int cmd = 0, bool enabled = true) override;
bool OwnPrimarySelection();
void ClaimSelection() override;
static bool IsStringAtom(GdkAtom type);
2019-05-04 18:14:48 +00:00
void GetGtkSelectionText(GtkSelectionData *selectionData, SelectionText &selText);
void InsertSelection(GtkClipboard *clipBoard, GtkSelectionData *selectionData);
public: // Public for SelectionReceiver
GObject *MainObject() const noexcept;
void ReceivedClipboard(GtkClipboard *clipBoard, GtkSelectionData *selection_data) noexcept;
private:
2019-05-04 18:14:48 +00:00
void ReceivedSelection(GtkSelectionData *selection_data);
void ReceivedDrop(GtkSelectionData *selection_data);
static void GetSelection(GtkSelectionData *selection_data, guint info, SelectionText *text);
void StoreOnClipboard(SelectionText *clipText);
static void ClipboardGetSelection(GtkClipboard *clip, GtkSelectionData *selection_data, guint info, void *data);
static void ClipboardClearSelection(GtkClipboard *clip, void *data);
2019-05-04 18:14:48 +00:00
void ClearPrimarySelection();
void PrimaryGetSelectionThis(GtkClipboard *clip, GtkSelectionData *selection_data, guint info);
static void PrimaryGetSelection(GtkClipboard *clip, GtkSelectionData *selection_data, guint info, gpointer pSci);
void PrimaryClearSelectionThis(GtkClipboard *clip);
static void PrimaryClearSelection(GtkClipboard *clip, gpointer pSci);
2019-05-04 18:14:48 +00:00
void UnclaimSelection(GdkEventSelection *selection_event);
void Resize(int width, int height);
// Callback functions
void RealizeThis(GtkWidget *widget);
static void Realize(GtkWidget *widget);
void UnRealizeThis(GtkWidget *widget);
static void UnRealize(GtkWidget *widget);
void MapThis();
static void Map(GtkWidget *widget);
void UnMapThis();
static void UnMap(GtkWidget *widget);
gint FocusInThis(GtkWidget *widget);
static gint FocusIn(GtkWidget *widget, GdkEventFocus *event);
gint FocusOutThis(GtkWidget *widget);
static gint FocusOut(GtkWidget *widget, GdkEventFocus *event);
static void SizeRequest(GtkWidget *widget, GtkRequisition *requisition);
#if GTK_CHECK_VERSION(3,0,0)
static void GetPreferredWidth(GtkWidget *widget, gint *minimalWidth, gint *naturalWidth);
static void GetPreferredHeight(GtkWidget *widget, gint *minimalHeight, gint *naturalHeight);
#endif
static void SizeAllocate(GtkWidget *widget, GtkAllocation *allocation);
void CheckForFontOptionChange();
2019-05-04 18:14:48 +00:00
#if GTK_CHECK_VERSION(3,0,0)
gboolean DrawTextThis(cairo_t *cr);
static gboolean DrawText(GtkWidget *widget, cairo_t *cr, ScintillaGTK *sciThis);
gboolean DrawThis(cairo_t *cr);
static gboolean DrawMain(GtkWidget *widget, cairo_t *cr);
#else
gboolean ExposeTextThis(GtkWidget *widget, GdkEventExpose *ose);
static gboolean ExposeText(GtkWidget *widget, GdkEventExpose *ose, ScintillaGTK *sciThis);
gboolean Expose(GtkWidget *widget, GdkEventExpose *ose);
static gboolean ExposeMain(GtkWidget *widget, GdkEventExpose *ose);
#endif
void ForAll(GtkCallback callback, gpointer callback_data);
static void MainForAll(GtkContainer *container, gboolean include_internals, GtkCallback callback, gpointer callback_data);
static void ScrollSignal(GtkAdjustment *adj, ScintillaGTK *sciThis);
static void ScrollHSignal(GtkAdjustment *adj, ScintillaGTK *sciThis);
gint PressThis(GdkEventButton *event);
static gint Press(GtkWidget *widget, GdkEventButton *event);
static gint MouseRelease(GtkWidget *widget, GdkEventButton *event);
static gint ScrollEvent(GtkWidget *widget, GdkEventScroll *event);
static gint Motion(GtkWidget *widget, GdkEventMotion *event);
gboolean KeyThis(GdkEventKey *event);
static gboolean KeyPress(GtkWidget *widget, GdkEventKey *event);
static gboolean KeyRelease(GtkWidget *widget, GdkEventKey *event);
#if GTK_CHECK_VERSION(3,0,0)
gboolean DrawPreeditThis(GtkWidget *widget, cairo_t *cr);
static gboolean DrawPreedit(GtkWidget *widget, cairo_t *cr, ScintillaGTK *sciThis);
#else
gboolean ExposePreeditThis(GtkWidget *widget, GdkEventExpose *ose);
static gboolean ExposePreedit(GtkWidget *widget, GdkEventExpose *ose, ScintillaGTK *sciThis);
#endif
AtkObject *GetAccessibleThis(GtkWidget *widget);
static AtkObject *GetAccessible(GtkWidget *widget);
2019-05-04 18:14:48 +00:00
bool KoreanIME();
void CommitThis(char *commitStr);
static void Commit(GtkIMContext *context, char *str, ScintillaGTK *sciThis);
void PreeditChangedInlineThis();
void PreeditChangedWindowedThis();
static void PreeditChanged(GtkIMContext *context, ScintillaGTK *sciThis);
Update to Scintilla 5.3.3 and Lexilla 5.2.2 update to https://www.scintilla.org/scintilla533.zip with: 1. Released 8 February 2023. 2. Fix SCI_LINESJOIN bug where carriage returns were incorrectly retained. Bug #2372. 3. Fix SCI_VERTICALCENTRECARET to update the vertical scroll position. 4. When an autocompletion list is shown in response to SCN_CHARADDED, do not process character as fill-up or stop. This avoids closing immediately when a character may both trigger and finish autocompletion. 5. On Cocoa fix character input bug where dotless 'i' and some other extended Latin characters could not be entered. The change also stops SCI_ASSIGNCMDKEY from working with these characters on Cocoa. Bug #2374. 6. On GTK, support IME context. Feature #1476. 7. On GTK on Win32, fix scrolling speed to not be too fast. Bug #2375. 8. On Qt, fix indicator drawing past left of text pane over margin. Bug #2373, Bug #1956. 9. On Qt, allow scrolling with mouse wheel when scroll bar hidden. and https://www.scintilla.org/lexilla522.zip with 1. Released 8 February 2023. 2. C++: Fix keywords that start with non-ASCII. Also affects other lexers. Issue #130. 3. Matlab: Include more prefix and suffix characters in numeric literals. Issue #120. 4. Matlab: More accurate treatment of line ends inside strings. Matlab and Octave are different here. Issue #18. 5. Modula-3: Don't treat identifier suffix that matches keyword as keyword. Issue #129. 6. Modula-3: Fix endless loop in folder. Issue #128. 7. Modula-3: Fix access to lines beyond document end in folder. Issue #131. 8. Python: Don't highlight match and case as keywords in contexts where they probably aren't used as keywords. Pull request #122. 9. X12: Support empty envelopes. Bug #2369. update CMakeLists.txt to latest changes within vcxproj file Close #13082
2023-02-09 16:57:24 +00:00
bool RetrieveSurroundingThis(GtkIMContext *context);
static gboolean RetrieveSurrounding(GtkIMContext *context, ScintillaGTK *sciThis);
bool DeleteSurroundingThis(GtkIMContext *context, gint characterOffset, gint characterCount);
static gboolean DeleteSurrounding(GtkIMContext *context, gint characterOffset, gint characterCount,
ScintillaGTK *sciThis);
void MoveImeCarets(Sci::Position pos);
void DrawImeIndicator(int indicator, Sci::Position len);
2019-05-04 18:14:48 +00:00
void SetCandidateWindowPos();
static void StyleSetText(GtkWidget *widget, GtkStyle *previous, void *);
static void RealizeText(GtkWidget *widget, void *);
2019-05-04 18:14:48 +00:00
static void Dispose(GObject *object);
static void Destroy(GObject *object);
static void SelectionReceived(GtkWidget *widget, GtkSelectionData *selection_data,
guint time);
2019-05-04 18:14:48 +00:00
static void SelectionGet(GtkWidget *widget, GtkSelectionData *selection_data,
guint info, guint time);
2019-05-04 18:14:48 +00:00
static gint SelectionClear(GtkWidget *widget, GdkEventSelection *selection_event);
gboolean DragMotionThis(GdkDragContext *context, gint x, gint y, guint dragtime);
static gboolean DragMotion(GtkWidget *widget, GdkDragContext *context,
gint x, gint y, guint dragtime);
2019-05-04 18:14:48 +00:00
static void DragLeave(GtkWidget *widget, GdkDragContext *context,
guint time);
2019-05-04 18:14:48 +00:00
static void DragEnd(GtkWidget *widget, GdkDragContext *context);
static gboolean Drop(GtkWidget *widget, GdkDragContext *context,
gint x, gint y, guint time);
2019-05-04 18:14:48 +00:00
static void DragDataReceived(GtkWidget *widget, GdkDragContext *context,
gint x, gint y, GtkSelectionData *selection_data, guint info, guint time);
2019-05-04 18:14:48 +00:00
static void DragDataGet(GtkWidget *widget, GdkDragContext *context,
GtkSelectionData *selection_data, guint info, guint time);
2019-05-04 18:14:48 +00:00
static gboolean TimeOut(gpointer ptt);
static gboolean IdleCallback(gpointer pSci);
static gboolean StyleIdle(gpointer pSci);
void IdleWork() override;
void QueueIdleWork(WorkItems items, Sci::Position upTo) override;
2019-05-04 18:14:48 +00:00
void SetDocPointer(Document *document) override;
static void PopUpCB(GtkMenuItem *menuItem, ScintillaGTK *sciThis);
#if GTK_CHECK_VERSION(3,0,0)
static gboolean DrawCT(GtkWidget *widget, cairo_t *cr, CallTip *ctip);
#else
static gboolean ExposeCT(GtkWidget *widget, GdkEventExpose *ose, CallTip *ctip);
#endif
static gboolean PressCT(GtkWidget *widget, GdkEventButton *event, ScintillaGTK *sciThis);
static sptr_t DirectFunction(sptr_t ptr,
unsigned int iMessage, uptr_t wParam, sptr_t lParam);
static sptr_t DirectStatusFunction(sptr_t ptr,
unsigned int iMessage, uptr_t wParam, sptr_t lParam, int *pStatus);
2019-05-04 18:14:48 +00:00
};
// helper class to watch a GObject lifetime and get notified when it dies
class GObjectWatcher {
GObject *weakRef;
void WeakNotifyThis(GObject *obj G_GNUC_UNUSED) {
PLATFORM_ASSERT(obj == weakRef);
Destroyed();
weakRef = nullptr;
2019-05-04 18:14:48 +00:00
}
static void WeakNotify(gpointer data, GObject *obj) {
static_cast<GObjectWatcher *>(data)->WeakNotifyThis(obj);
2019-05-04 18:14:48 +00:00
}
public:
GObjectWatcher(GObject *obj) :
weakRef(obj) {
2019-05-04 18:14:48 +00:00
g_object_weak_ref(weakRef, WeakNotify, this);
}
// Deleted so GObjectWatcher objects can not be copied.
GObjectWatcher(const GObjectWatcher&) = delete;
GObjectWatcher(GObjectWatcher&&) = delete;
GObjectWatcher&operator=(const GObjectWatcher&) = delete;
GObjectWatcher&operator=(GObjectWatcher&&) = delete;
2019-05-04 18:14:48 +00:00
virtual ~GObjectWatcher() {
if (weakRef) {
g_object_weak_unref(weakRef, WeakNotify, this);
}
}
virtual void Destroyed() {}
bool IsDestroyed() const {
return weakRef != nullptr;
2019-05-04 18:14:48 +00:00
}
};
std::string ConvertText(const char *s, size_t len, const char *charSetDest,
const char *charSetSource, bool transliterations, bool silent=false);
2019-05-04 18:14:48 +00:00
}
#endif