mirror of
https://github.com/NohamR/Reclass.git
synced 2026-05-10 19:59:21 +00:00
Initial commit: ReclassX structured binary editor
This commit is contained in:
867
third_party/qscintilla/src/qsciscintillabase.cpp
vendored
Normal file
867
third_party/qscintilla/src/qsciscintillabase.cpp
vendored
Normal file
@@ -0,0 +1,867 @@
|
||||
// This module implements the "official" low-level API.
|
||||
//
|
||||
// Copyright (c) 2023 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||
//
|
||||
// This file is part of QScintilla.
|
||||
//
|
||||
// This file may be used under the terms of the GNU General Public License
|
||||
// version 3.0 as published by the Free Software Foundation and appearing in
|
||||
// the file LICENSE included in the packaging of this file. Please review the
|
||||
// following information to ensure the GNU General Public License version 3.0
|
||||
// requirements will be met: http://www.gnu.org/copyleft/gpl.html.
|
||||
//
|
||||
// If you do not wish to use this file under the terms of the GPL version 3.0
|
||||
// then you may purchase a commercial license. For more information contact
|
||||
// info@riverbankcomputing.com.
|
||||
//
|
||||
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
||||
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
|
||||
#include "Qsci/qsciscintillabase.h"
|
||||
|
||||
#include <QApplication>
|
||||
#include <QClipboard>
|
||||
#include <QColor>
|
||||
#include <QContextMenuEvent>
|
||||
#include <QDragEnterEvent>
|
||||
#include <QDragMoveEvent>
|
||||
#include <QDropEvent>
|
||||
#include <QDragLeaveEvent>
|
||||
#include <QFocusEvent>
|
||||
#include <QKeyEvent>
|
||||
#include <QList>
|
||||
#include <QMimeData>
|
||||
#include <QMouseEvent>
|
||||
#include <QPaintEvent>
|
||||
#include <QScrollBar>
|
||||
#include <QStyle>
|
||||
|
||||
#include "SciAccessibility.h"
|
||||
#include "ScintillaQt.h"
|
||||
|
||||
|
||||
// The #defines in Scintilla.h and the enums in qsciscintillabase.h conflict
|
||||
// (because we want to use the same names) so we have to undefine those we use
|
||||
// in this file.
|
||||
#undef SCI_SETCARETPERIOD
|
||||
#undef SCK_DOWN
|
||||
#undef SCK_UP
|
||||
#undef SCK_LEFT
|
||||
#undef SCK_RIGHT
|
||||
#undef SCK_HOME
|
||||
#undef SCK_END
|
||||
#undef SCK_PRIOR
|
||||
#undef SCK_NEXT
|
||||
#undef SCK_DELETE
|
||||
#undef SCK_INSERT
|
||||
#undef SCK_ESCAPE
|
||||
#undef SCK_BACK
|
||||
#undef SCK_TAB
|
||||
#undef SCK_RETURN
|
||||
#undef SCK_ADD
|
||||
#undef SCK_SUBTRACT
|
||||
#undef SCK_DIVIDE
|
||||
#undef SCK_WIN
|
||||
#undef SCK_RWIN
|
||||
#undef SCK_MENU
|
||||
#undef SCN_URIDROPPED
|
||||
|
||||
|
||||
// Remember if we have linked the lexers.
|
||||
static bool lexersLinked = false;
|
||||
|
||||
// The list of instances.
|
||||
static QList<QsciScintillaBase *> poolList;
|
||||
|
||||
// Mime support.
|
||||
static const QLatin1String mimeTextPlain("text/plain");
|
||||
static const QLatin1String mimeRectangularWin("MSDEVColumnSelect");
|
||||
static const QLatin1String mimeRectangular("text/x-qscintilla-rectangular");
|
||||
|
||||
#if QT_VERSION < 0x060000 && defined(Q_OS_OSX)
|
||||
extern void initialiseRectangularPasteboardMime();
|
||||
#endif
|
||||
|
||||
|
||||
// The ctor.
|
||||
QsciScintillaBase::QsciScintillaBase(QWidget *parent)
|
||||
: QAbstractScrollArea(parent), preeditPos(-1), preeditNrBytes(0),
|
||||
clickCausedFocus(false)
|
||||
{
|
||||
#if !defined(QT_NO_ACCESSIBILITY)
|
||||
QsciAccessibleScintillaBase::initialise();
|
||||
#endif
|
||||
|
||||
connectVerticalScrollBar();
|
||||
connectHorizontalScrollBar();
|
||||
|
||||
setAcceptDrops(true);
|
||||
setFocusPolicy(Qt::WheelFocus);
|
||||
setAttribute(Qt::WA_KeyCompression);
|
||||
setAttribute(Qt::WA_InputMethodEnabled);
|
||||
setInputMethodHints(
|
||||
Qt::ImhNoAutoUppercase|Qt::ImhNoPredictiveText|Qt::ImhMultiLine);
|
||||
|
||||
viewport()->setBackgroundRole(QPalette::Base);
|
||||
viewport()->setMouseTracking(true);
|
||||
viewport()->setAttribute(Qt::WA_NoSystemBackground);
|
||||
|
||||
triple_click.setSingleShot(true);
|
||||
|
||||
#if QT_VERSION < 0x060000 && defined(Q_OS_OSX)
|
||||
initialiseRectangularPasteboardMime();
|
||||
#endif
|
||||
|
||||
sci = new QsciScintillaQt(this);
|
||||
|
||||
SendScintilla(SCI_SETCARETPERIOD, QApplication::cursorFlashTime() / 2);
|
||||
|
||||
// Make sure the lexers are linked in.
|
||||
if (!lexersLinked)
|
||||
{
|
||||
Scintilla_LinkLexers();
|
||||
lexersLinked = true;
|
||||
}
|
||||
|
||||
// Add it to the pool.
|
||||
poolList.append(this);
|
||||
}
|
||||
|
||||
|
||||
// The dtor.
|
||||
QsciScintillaBase::~QsciScintillaBase()
|
||||
{
|
||||
// The QsciScintillaQt object isn't a child so delete it explicitly.
|
||||
delete sci;
|
||||
|
||||
// Remove it from the pool.
|
||||
poolList.removeAt(poolList.indexOf(this));
|
||||
}
|
||||
|
||||
|
||||
// Return an instance from the pool.
|
||||
QsciScintillaBase *QsciScintillaBase::pool()
|
||||
{
|
||||
return poolList.first();
|
||||
}
|
||||
|
||||
|
||||
// Tell Scintilla to update the scroll bars. Scintilla should be doing this
|
||||
// itself.
|
||||
void QsciScintillaBase::setScrollBars()
|
||||
{
|
||||
sci->SetScrollBars();
|
||||
}
|
||||
|
||||
|
||||
// Send a message to the real Scintilla widget using the low level Scintilla
|
||||
// API.
|
||||
long QsciScintillaBase::SendScintilla(unsigned int msg, unsigned long wParam,
|
||||
long lParam) const
|
||||
{
|
||||
return sci->WndProc(msg, wParam, lParam);
|
||||
}
|
||||
|
||||
|
||||
// Overloaded message send.
|
||||
long QsciScintillaBase::SendScintilla(unsigned int msg, unsigned long wParam,
|
||||
void *lParam) const
|
||||
{
|
||||
return sci->WndProc(msg, wParam, reinterpret_cast<sptr_t>(lParam));
|
||||
}
|
||||
|
||||
|
||||
// Overloaded message send.
|
||||
long QsciScintillaBase::SendScintilla(unsigned int msg, uintptr_t wParam,
|
||||
const char *lParam) const
|
||||
{
|
||||
return sci->WndProc(msg, wParam, reinterpret_cast<sptr_t>(lParam));
|
||||
}
|
||||
|
||||
|
||||
// Overloaded message send.
|
||||
long QsciScintillaBase::SendScintilla(unsigned int msg,
|
||||
const char *lParam) const
|
||||
{
|
||||
return sci->WndProc(msg, static_cast<uptr_t>(0),
|
||||
reinterpret_cast<sptr_t>(lParam));
|
||||
}
|
||||
|
||||
|
||||
// Overloaded message send.
|
||||
long QsciScintillaBase::SendScintilla(unsigned int msg, const char *wParam,
|
||||
const char *lParam) const
|
||||
{
|
||||
return sci->WndProc(msg, reinterpret_cast<uptr_t>(wParam),
|
||||
reinterpret_cast<sptr_t>(lParam));
|
||||
}
|
||||
|
||||
|
||||
// Overloaded message send.
|
||||
long QsciScintillaBase::SendScintilla(unsigned int msg, long wParam) const
|
||||
{
|
||||
return sci->WndProc(msg, static_cast<uptr_t>(wParam),
|
||||
static_cast<sptr_t>(0));
|
||||
}
|
||||
|
||||
|
||||
// Overloaded message send.
|
||||
long QsciScintillaBase::SendScintilla(unsigned int msg, int wParam) const
|
||||
{
|
||||
return sci->WndProc(msg, static_cast<uptr_t>(wParam),
|
||||
static_cast<sptr_t>(0));
|
||||
}
|
||||
|
||||
|
||||
// Overloaded message send.
|
||||
long QsciScintillaBase::SendScintilla(unsigned int msg, long cpMin, long cpMax,
|
||||
char *lpstrText) const
|
||||
{
|
||||
Sci_TextRange tr;
|
||||
|
||||
tr.chrg.cpMin = cpMin;
|
||||
tr.chrg.cpMax = cpMax;
|
||||
tr.lpstrText = lpstrText;
|
||||
|
||||
return sci->WndProc(msg, static_cast<uptr_t>(0),
|
||||
reinterpret_cast<sptr_t>(&tr));
|
||||
}
|
||||
|
||||
|
||||
// Overloaded message send.
|
||||
long QsciScintillaBase::SendScintilla(unsigned int msg, unsigned long wParam,
|
||||
const QColor &col) const
|
||||
{
|
||||
sptr_t lParam = (col.blue() << 16) | (col.green() << 8) | col.red();
|
||||
|
||||
return sci->WndProc(msg, wParam, lParam);
|
||||
}
|
||||
|
||||
|
||||
// Overloaded message send.
|
||||
long QsciScintillaBase::SendScintilla(unsigned int msg, const QColor &col) const
|
||||
{
|
||||
uptr_t wParam = (col.blue() << 16) | (col.green() << 8) | col.red();
|
||||
|
||||
return sci->WndProc(msg, wParam, static_cast<sptr_t>(0));
|
||||
}
|
||||
|
||||
|
||||
// Overloaded message send.
|
||||
long QsciScintillaBase::SendScintilla(unsigned int msg, unsigned long wParam,
|
||||
QPainter *hdc, const QRect &rc, long cpMin, long cpMax) const
|
||||
{
|
||||
Sci_RangeToFormat rf;
|
||||
|
||||
rf.hdc = rf.hdcTarget = reinterpret_cast<Scintilla::SurfaceID>(hdc);
|
||||
|
||||
rf.rc.left = rc.left();
|
||||
rf.rc.top = rc.top();
|
||||
rf.rc.right = rc.right() + 1;
|
||||
rf.rc.bottom = rc.bottom() + 1;
|
||||
|
||||
rf.chrg.cpMin = cpMin;
|
||||
rf.chrg.cpMax = cpMax;
|
||||
|
||||
return sci->WndProc(msg, wParam, reinterpret_cast<sptr_t>(&rf));
|
||||
}
|
||||
|
||||
|
||||
// Overloaded message send.
|
||||
long QsciScintillaBase::SendScintilla(unsigned int msg, unsigned long wParam,
|
||||
const QPixmap &lParam) const
|
||||
{
|
||||
return sci->WndProc(msg, wParam, reinterpret_cast<sptr_t>(&lParam));
|
||||
}
|
||||
|
||||
|
||||
// Overloaded message send.
|
||||
long QsciScintillaBase::SendScintilla(unsigned int msg, unsigned long wParam,
|
||||
const QImage &lParam) const
|
||||
{
|
||||
return sci->WndProc(msg, wParam, reinterpret_cast<sptr_t>(&lParam));
|
||||
}
|
||||
|
||||
|
||||
// Send a message to the real Scintilla widget using the low level Scintilla
|
||||
// API that returns a pointer result.
|
||||
void *QsciScintillaBase::SendScintillaPtrResult(unsigned int msg) const
|
||||
{
|
||||
return reinterpret_cast<void *>(sci->WndProc(msg, static_cast<uptr_t>(0),
|
||||
static_cast<sptr_t>(0)));
|
||||
}
|
||||
|
||||
|
||||
// Re-implemented to handle font changes
|
||||
void QsciScintillaBase::changeEvent(QEvent *e)
|
||||
{
|
||||
if (e->type() == QEvent::FontChange || e->type() == QEvent::ApplicationFontChange)
|
||||
sci->InvalidateStyleRedraw();
|
||||
|
||||
QAbstractScrollArea::changeEvent(e);
|
||||
}
|
||||
|
||||
|
||||
// Re-implemented to handle the context menu.
|
||||
void QsciScintillaBase::contextMenuEvent(QContextMenuEvent *e)
|
||||
{
|
||||
sci->ContextMenu(Scintilla::Point(e->globalX(), e->globalY()));
|
||||
}
|
||||
|
||||
|
||||
// Re-implemented to tell the widget it has the focus.
|
||||
void QsciScintillaBase::focusInEvent(QFocusEvent *e)
|
||||
{
|
||||
sci->SetFocusState(true);
|
||||
clickCausedFocus = (e->reason() == Qt::MouseFocusReason);
|
||||
QAbstractScrollArea::focusInEvent(e);
|
||||
}
|
||||
|
||||
|
||||
// Re-implemented to tell the widget it has lost the focus.
|
||||
void QsciScintillaBase::focusOutEvent(QFocusEvent *e)
|
||||
{
|
||||
if (e->reason() == Qt::ActiveWindowFocusReason)
|
||||
{
|
||||
// Only tell Scintilla we have lost focus if the new active window
|
||||
// isn't our auto-completion list. This is probably only an issue on
|
||||
// Linux and there are still problems because subsequent focus out
|
||||
// events don't always seem to get generated (at least with Qt5).
|
||||
|
||||
QWidget *aw = QApplication::activeWindow();
|
||||
|
||||
if (!aw || aw->parent() != this || !aw->inherits("QsciSciListBox"))
|
||||
sci->SetFocusState(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
sci->SetFocusState(false);
|
||||
}
|
||||
|
||||
QAbstractScrollArea::focusOutEvent(e);
|
||||
}
|
||||
|
||||
|
||||
// Re-implemented to make sure tabs are passed to the editor.
|
||||
bool QsciScintillaBase::focusNextPrevChild(bool next)
|
||||
{
|
||||
if (!sci->pdoc->IsReadOnly())
|
||||
return false;
|
||||
|
||||
return QAbstractScrollArea::focusNextPrevChild(next);
|
||||
}
|
||||
|
||||
|
||||
// Handle key presses.
|
||||
void QsciScintillaBase::keyPressEvent(QKeyEvent *e)
|
||||
{
|
||||
int modifiers = 0;
|
||||
|
||||
if (e->modifiers() & Qt::ShiftModifier)
|
||||
modifiers |= SCMOD_SHIFT;
|
||||
|
||||
if (e->modifiers() & Qt::ControlModifier)
|
||||
modifiers |= SCMOD_CTRL;
|
||||
|
||||
if (e->modifiers() & Qt::AltModifier)
|
||||
modifiers |= SCMOD_ALT;
|
||||
|
||||
if (e->modifiers() & Qt::MetaModifier)
|
||||
modifiers |= SCMOD_META;
|
||||
|
||||
int key = commandKey(e->key(), modifiers);
|
||||
|
||||
if (key)
|
||||
{
|
||||
bool consumed = false;
|
||||
|
||||
sci->KeyDownWithModifiers(key, modifiers, &consumed);
|
||||
|
||||
if (consumed)
|
||||
{
|
||||
e->accept();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
QString text = e->text();
|
||||
|
||||
if (!text.isEmpty() && text[0].isPrint())
|
||||
{
|
||||
QByteArray bytes = textAsBytes(text);
|
||||
sci->AddCharUTF(bytes.data(), bytes.length());
|
||||
e->accept();
|
||||
}
|
||||
else
|
||||
{
|
||||
QAbstractScrollArea::keyPressEvent(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Map a Qt key to a valid Scintilla command key, or 0 if none.
|
||||
int QsciScintillaBase::commandKey(int qt_key, int &modifiers)
|
||||
{
|
||||
int key;
|
||||
|
||||
switch (qt_key)
|
||||
{
|
||||
case Qt::Key_Down:
|
||||
key = SCK_DOWN;
|
||||
break;
|
||||
|
||||
case Qt::Key_Up:
|
||||
key = SCK_UP;
|
||||
break;
|
||||
|
||||
case Qt::Key_Left:
|
||||
key = SCK_LEFT;
|
||||
break;
|
||||
|
||||
case Qt::Key_Right:
|
||||
key = SCK_RIGHT;
|
||||
break;
|
||||
|
||||
case Qt::Key_Home:
|
||||
key = SCK_HOME;
|
||||
break;
|
||||
|
||||
case Qt::Key_End:
|
||||
key = SCK_END;
|
||||
break;
|
||||
|
||||
case Qt::Key_PageUp:
|
||||
key = SCK_PRIOR;
|
||||
break;
|
||||
|
||||
case Qt::Key_PageDown:
|
||||
key = SCK_NEXT;
|
||||
break;
|
||||
|
||||
case Qt::Key_Delete:
|
||||
key = SCK_DELETE;
|
||||
break;
|
||||
|
||||
case Qt::Key_Insert:
|
||||
key = SCK_INSERT;
|
||||
break;
|
||||
|
||||
case Qt::Key_Escape:
|
||||
key = SCK_ESCAPE;
|
||||
break;
|
||||
|
||||
case Qt::Key_Backspace:
|
||||
key = SCK_BACK;
|
||||
break;
|
||||
|
||||
case Qt::Key_Tab:
|
||||
key = SCK_TAB;
|
||||
break;
|
||||
|
||||
case Qt::Key_Backtab:
|
||||
// Scintilla assumes a backtab is shift-tab.
|
||||
key = SCK_TAB;
|
||||
modifiers |= SCMOD_SHIFT;
|
||||
break;
|
||||
|
||||
case Qt::Key_Return:
|
||||
case Qt::Key_Enter:
|
||||
key = SCK_RETURN;
|
||||
break;
|
||||
|
||||
case Qt::Key_Super_L:
|
||||
key = SCK_WIN;
|
||||
break;
|
||||
|
||||
case Qt::Key_Super_R:
|
||||
key = SCK_RWIN;
|
||||
break;
|
||||
|
||||
case Qt::Key_Menu:
|
||||
key = SCK_MENU;
|
||||
break;
|
||||
|
||||
default:
|
||||
if ((key = qt_key) > 0x7f)
|
||||
key = 0;
|
||||
}
|
||||
|
||||
return key;
|
||||
}
|
||||
|
||||
|
||||
// Encode a QString as bytes.
|
||||
QByteArray QsciScintillaBase::textAsBytes(const QString &text) const
|
||||
{
|
||||
if (sci->IsUnicodeMode())
|
||||
return text.toUtf8();
|
||||
|
||||
return text.toLatin1();
|
||||
}
|
||||
|
||||
|
||||
// Decode bytes as a QString.
|
||||
QString QsciScintillaBase::bytesAsText(const char *bytes, int size) const
|
||||
{
|
||||
if (sci->IsUnicodeMode())
|
||||
return QString::fromUtf8(bytes, size);
|
||||
|
||||
return QString::fromLatin1(bytes, size);
|
||||
}
|
||||
|
||||
|
||||
// Handle a mouse button double click.
|
||||
void QsciScintillaBase::mouseDoubleClickEvent(QMouseEvent *e)
|
||||
{
|
||||
if (e->button() != Qt::LeftButton)
|
||||
{
|
||||
e->ignore();
|
||||
return;
|
||||
}
|
||||
|
||||
setFocus();
|
||||
|
||||
// Make sure Scintilla will interpret this as a double-click.
|
||||
unsigned clickTime = sci->lastClickTime + Scintilla::Platform::DoubleClickTime() - 1;
|
||||
|
||||
sci->ButtonDownWithModifiers(Scintilla::Point(e->x(), e->y()), clickTime,
|
||||
eventModifiers(e));
|
||||
|
||||
// Remember the current position and time in case it turns into a triple
|
||||
// click.
|
||||
triple_click_at = e->globalPos();
|
||||
triple_click.start(QApplication::doubleClickInterval());
|
||||
}
|
||||
|
||||
|
||||
// Handle a mouse move.
|
||||
void QsciScintillaBase::mouseMoveEvent(QMouseEvent *e)
|
||||
{
|
||||
sci->ButtonMoveWithModifiers(Scintilla::Point(e->x(), e->y()), 0,
|
||||
eventModifiers(e));
|
||||
}
|
||||
|
||||
|
||||
// Handle a mouse button press.
|
||||
void QsciScintillaBase::mousePressEvent(QMouseEvent *e)
|
||||
{
|
||||
setFocus();
|
||||
|
||||
Scintilla::Point pt(e->x(), e->y());
|
||||
|
||||
if (e->button() == Qt::LeftButton || e->button() == Qt::RightButton)
|
||||
{
|
||||
unsigned clickTime;
|
||||
|
||||
// It is a triple click if the timer is running and the mouse hasn't
|
||||
// moved too much.
|
||||
if (triple_click.isActive() && (e->globalPos() - triple_click_at).manhattanLength() < QApplication::startDragDistance())
|
||||
clickTime = sci->lastClickTime + Scintilla::Platform::DoubleClickTime() - 1;
|
||||
else
|
||||
clickTime = sci->lastClickTime + Scintilla::Platform::DoubleClickTime() + 1;
|
||||
|
||||
triple_click.stop();
|
||||
|
||||
// Scintilla uses the Alt modifier to initiate rectangular selection.
|
||||
// However the GTK port (under X11, not Windows) uses the Control
|
||||
// modifier (by default, although it is configurable). It does this
|
||||
// because most X11 window managers hijack Alt-drag to move the window.
|
||||
// We do the same, except that (for the moment at least) we don't allow
|
||||
// the modifier to be configured.
|
||||
bool shift = e->modifiers() & Qt::ShiftModifier;
|
||||
bool ctrl = e->modifiers() & Qt::ControlModifier;
|
||||
#if defined(Q_OS_MAC) || defined(Q_OS_WIN)
|
||||
bool alt = e->modifiers() & Qt::AltModifier;
|
||||
#else
|
||||
bool alt = ctrl;
|
||||
#endif
|
||||
|
||||
if (e->button() == Qt::LeftButton)
|
||||
sci->ButtonDownWithModifiers(pt, clickTime,
|
||||
QsciScintillaQt::ModifierFlags(shift, ctrl, alt));
|
||||
else
|
||||
sci->RightButtonDownWithModifiers(pt, clickTime,
|
||||
QsciScintillaQt::ModifierFlags(shift, ctrl, alt));
|
||||
}
|
||||
else if (e->button() == Qt::MiddleButton)
|
||||
{
|
||||
QClipboard *cb = QApplication::clipboard();
|
||||
|
||||
if (cb->supportsSelection())
|
||||
{
|
||||
int pos = sci->PositionFromLocation(pt);
|
||||
|
||||
sci->sel.Clear();
|
||||
sci->SetSelection(pos, pos);
|
||||
|
||||
sci->pasteFromClipboard(QClipboard::Selection);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Handle a mouse button releases.
|
||||
void QsciScintillaBase::mouseReleaseEvent(QMouseEvent *e)
|
||||
{
|
||||
if (e->button() != Qt::LeftButton)
|
||||
return;
|
||||
|
||||
Scintilla::Point pt(e->x(), e->y());
|
||||
|
||||
if (sci->HaveMouseCapture())
|
||||
{
|
||||
bool ctrl = e->modifiers() & Qt::ControlModifier;
|
||||
|
||||
sci->ButtonUpWithModifiers(pt, 0,
|
||||
QsciScintillaQt::ModifierFlags(false, ctrl, false));
|
||||
}
|
||||
|
||||
if (!sci->pdoc->IsReadOnly() && !sci->PointInSelMargin(pt) && qApp->autoSipEnabled())
|
||||
{
|
||||
QStyle::RequestSoftwareInputPanel rsip = QStyle::RequestSoftwareInputPanel(style()->styleHint(QStyle::SH_RequestSoftwareInputPanel));
|
||||
|
||||
if (!clickCausedFocus || rsip == QStyle::RSIP_OnMouseClick)
|
||||
qApp->inputMethod()->show();
|
||||
}
|
||||
|
||||
clickCausedFocus = false;
|
||||
}
|
||||
|
||||
|
||||
// Handle paint events.
|
||||
void QsciScintillaBase::paintEvent(QPaintEvent *e)
|
||||
{
|
||||
sci->paintEvent(e);
|
||||
}
|
||||
|
||||
|
||||
// Handle resize events.
|
||||
void QsciScintillaBase::resizeEvent(QResizeEvent *)
|
||||
{
|
||||
sci->ChangeSize();
|
||||
}
|
||||
|
||||
|
||||
// Re-implemented to suppress the default behaviour as Scintilla works at a
|
||||
// more fundamental level. Note that this means that replacing the scrollbars
|
||||
// with custom versions does not work.
|
||||
void QsciScintillaBase::scrollContentsBy(int, int)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
// Handle the vertical scrollbar.
|
||||
void QsciScintillaBase::handleVSb(int value)
|
||||
{
|
||||
sci->ScrollTo(value);
|
||||
}
|
||||
|
||||
|
||||
// Handle the horizontal scrollbar.
|
||||
void QsciScintillaBase::handleHSb(int value)
|
||||
{
|
||||
sci->HorizontalScrollTo(value);
|
||||
}
|
||||
|
||||
|
||||
// Handle drag enters.
|
||||
void QsciScintillaBase::dragEnterEvent(QDragEnterEvent *e)
|
||||
{
|
||||
QsciScintillaBase::dragMoveEvent(e);
|
||||
}
|
||||
|
||||
|
||||
// Handle drag leaves.
|
||||
void QsciScintillaBase::dragLeaveEvent(QDragLeaveEvent *)
|
||||
{
|
||||
sci->SetDragPosition(Scintilla::SelectionPosition());
|
||||
}
|
||||
|
||||
|
||||
// Handle drag moves.
|
||||
void QsciScintillaBase::dragMoveEvent(QDragMoveEvent *e)
|
||||
{
|
||||
if (e->mimeData()->hasUrls())
|
||||
{
|
||||
e->acceptProposedAction();
|
||||
}
|
||||
else
|
||||
{
|
||||
sci->SetDragPosition(
|
||||
sci->SPositionFromLocation(
|
||||
Scintilla::Point(e->pos().x(), e->pos().y()), false,
|
||||
false, sci->UserVirtualSpace()));
|
||||
|
||||
acceptAction(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Handle drops.
|
||||
void QsciScintillaBase::dropEvent(QDropEvent *e)
|
||||
{
|
||||
if (e->mimeData()->hasUrls())
|
||||
{
|
||||
e->acceptProposedAction();
|
||||
|
||||
foreach (const QUrl &url, e->mimeData()->urls())
|
||||
emit SCN_URIDROPPED(url);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
acceptAction(e);
|
||||
|
||||
if (!e->isAccepted())
|
||||
return;
|
||||
|
||||
bool moving;
|
||||
int len;
|
||||
const char *s;
|
||||
bool rectangular;
|
||||
|
||||
moving = (e->dropAction() == Qt::MoveAction);
|
||||
|
||||
QByteArray text = fromMimeData(e->mimeData(), rectangular);
|
||||
len = text.length();
|
||||
s = text.data();
|
||||
|
||||
std::string dest = Scintilla::Document::TransformLineEnds(s, len,
|
||||
sci->pdoc->eolMode);
|
||||
|
||||
sci->DropAt(sci->posDrop, dest.c_str(), dest.length(), moving,
|
||||
rectangular);
|
||||
|
||||
sci->Redraw();
|
||||
}
|
||||
|
||||
|
||||
void QsciScintillaBase::acceptAction(QDropEvent *e)
|
||||
{
|
||||
if (sci->pdoc->IsReadOnly() || !canInsertFromMimeData(e->mimeData()))
|
||||
e->ignore();
|
||||
else
|
||||
e->acceptProposedAction();
|
||||
}
|
||||
|
||||
|
||||
// See if a MIME data object can be decoded.
|
||||
bool QsciScintillaBase::canInsertFromMimeData(const QMimeData *source) const
|
||||
{
|
||||
return source->hasFormat(mimeTextPlain);
|
||||
}
|
||||
|
||||
|
||||
// Create text from a MIME data object.
|
||||
QByteArray QsciScintillaBase::fromMimeData(const QMimeData *source, bool &rectangular) const
|
||||
{
|
||||
// See if it is rectangular. We try all of the different formats that
|
||||
// Scintilla supports in case we are working across different platforms.
|
||||
if (source->hasFormat(mimeRectangularWin))
|
||||
rectangular = true;
|
||||
else if (source->hasFormat(mimeRectangular))
|
||||
rectangular = true;
|
||||
else
|
||||
rectangular = false;
|
||||
|
||||
// Note that we don't support Scintilla's hack of adding a '\0' as Qt
|
||||
// strips it off under the covers when pasting from another process.
|
||||
QString utf8 = source->text();
|
||||
QByteArray text;
|
||||
|
||||
if (sci->IsUnicodeMode())
|
||||
text = utf8.toUtf8();
|
||||
else
|
||||
text = utf8.toLatin1();
|
||||
|
||||
return text;
|
||||
}
|
||||
|
||||
|
||||
// Create a MIME data object for some text.
|
||||
QMimeData *QsciScintillaBase::toMimeData(const QByteArray &text, bool rectangular) const
|
||||
{
|
||||
QMimeData *mime = new QMimeData;
|
||||
|
||||
QString utf8;
|
||||
|
||||
if (sci->IsUnicodeMode())
|
||||
utf8 = QString::fromUtf8(text.constData(), text.size());
|
||||
else
|
||||
utf8 = QString::fromLatin1(text.constData(), text.size());
|
||||
|
||||
mime->setText(utf8);
|
||||
|
||||
if (rectangular)
|
||||
{
|
||||
// Use the platform specific "standard" for specifying a rectangular
|
||||
// selection.
|
||||
#if defined(Q_OS_WIN)
|
||||
mime->setData(mimeRectangularWin, QByteArray());
|
||||
#else
|
||||
mime->setData(mimeRectangular, QByteArray());
|
||||
#endif
|
||||
}
|
||||
|
||||
return mime;
|
||||
}
|
||||
|
||||
|
||||
// Connect up the vertical scroll bar.
|
||||
void QsciScintillaBase::connectVerticalScrollBar()
|
||||
{
|
||||
connect(verticalScrollBar(), SIGNAL(valueChanged(int)),
|
||||
SLOT(handleVSb(int)));
|
||||
}
|
||||
|
||||
|
||||
// Connect up the horizontal scroll bar.
|
||||
void QsciScintillaBase::connectHorizontalScrollBar()
|
||||
{
|
||||
connect(horizontalScrollBar(), SIGNAL(valueChanged(int)),
|
||||
SLOT(handleHSb(int)));
|
||||
}
|
||||
|
||||
|
||||
//! Replace the vertical scroll bar.
|
||||
void QsciScintillaBase::replaceVerticalScrollBar(QScrollBar *scrollBar)
|
||||
{
|
||||
setVerticalScrollBar(scrollBar);
|
||||
connectVerticalScrollBar();
|
||||
}
|
||||
|
||||
|
||||
// Replace the horizontal scroll bar.
|
||||
void QsciScintillaBase::replaceHorizontalScrollBar(QScrollBar *scrollBar)
|
||||
{
|
||||
setHorizontalScrollBar(scrollBar);
|
||||
connectHorizontalScrollBar();
|
||||
}
|
||||
|
||||
|
||||
// Return true if a context menu should be displayed. This is provided as a
|
||||
// helper to QsciScintilla::contextMenuEvent(). A proper design would break
|
||||
// backwards compatibility.
|
||||
bool QsciScintillaBase::contextMenuNeeded(int x, int y) const
|
||||
{
|
||||
Scintilla::Point pt(x, y);
|
||||
|
||||
// Clear any selection if the mouse is outside.
|
||||
if (!sci->PointInSelection(pt))
|
||||
sci->SetEmptySelection(sci->PositionFromLocation(pt));
|
||||
|
||||
// Respect SC_POPUP_*.
|
||||
return sci->ShouldDisplayPopup(pt);
|
||||
}
|
||||
|
||||
|
||||
// Return the Scintilla keyboard modifiers set for a mouse event.
|
||||
int QsciScintillaBase::eventModifiers(QMouseEvent *e)
|
||||
{
|
||||
bool shift = e->modifiers() & Qt::ShiftModifier;
|
||||
bool ctrl = e->modifiers() & Qt::ControlModifier;
|
||||
bool alt = e->modifiers() & Qt::AltModifier;
|
||||
|
||||
return QsciScintillaQt::ModifierFlags(shift, ctrl, alt);
|
||||
}
|
||||
Reference in New Issue
Block a user