ScintillaQt.cpp 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732
  1. // The implementation of the Qt specific subclass of ScintillaBase.
  2. //
  3. // Copyright (c) 2017 Riverbank Computing Limited <info@riverbankcomputing.com>
  4. //
  5. // This file is part of QScintilla.
  6. //
  7. // This file may be used under the terms of the GNU General Public License
  8. // version 3.0 as published by the Free Software Foundation and appearing in
  9. // the file LICENSE included in the packaging of this file. Please review the
  10. // following information to ensure the GNU General Public License version 3.0
  11. // requirements will be met: http://www.gnu.org/copyleft/gpl.html.
  12. //
  13. // If you do not wish to use this file under the terms of the GPL version 3.0
  14. // then you may purchase a commercial license. For more information contact
  15. // info@riverbankcomputing.com.
  16. //
  17. // This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
  18. // WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  19. #include <string.h>
  20. #include <qapplication.h>
  21. #include <qbytearray.h>
  22. #include <qdrag.h>
  23. #include <qevent.h>
  24. #include <qmimedata.h>
  25. #include <qpainter.h>
  26. #include <qscrollbar.h>
  27. #include <qstring.h>
  28. #include "Qsci/qsciscintillabase.h"
  29. #include "ScintillaQt.h"
  30. #include "SciClasses.h"
  31. // We want to use the Scintilla notification names as Qt signal names.
  32. #undef SCEN_CHANGE
  33. #undef SCN_AUTOCCANCELLED
  34. #undef SCN_AUTOCCHARDELETED
  35. #undef SCN_AUTOCCOMPLETED
  36. #undef SCN_AUTOCSELECTION
  37. #undef SCN_CALLTIPCLICK
  38. #undef SCN_CHARADDED
  39. #undef SCN_DOUBLECLICK
  40. #undef SCN_DWELLEND
  41. #undef SCN_DWELLSTART
  42. #undef SCN_FOCUSIN
  43. #undef SCN_FOCUSOUT
  44. #undef SCN_HOTSPOTCLICK
  45. #undef SCN_HOTSPOTDOUBLECLICK
  46. #undef SCN_HOTSPOTRELEASECLICK
  47. #undef SCN_INDICATORCLICK
  48. #undef SCN_INDICATORRELEASE
  49. #undef SCN_MACRORECORD
  50. #undef SCN_MARGINCLICK
  51. #undef SCN_MARGINRIGHTCLICK
  52. #undef SCN_MODIFIED
  53. #undef SCN_MODIFYATTEMPTRO
  54. #undef SCN_NEEDSHOWN
  55. #undef SCN_PAINTED
  56. #undef SCN_SAVEPOINTLEFT
  57. #undef SCN_SAVEPOINTREACHED
  58. #undef SCN_STYLENEEDED
  59. #undef SCN_UPDATEUI
  60. #undef SCN_USERLISTSELECTION
  61. #undef SCN_ZOOM
  62. enum
  63. {
  64. SCEN_CHANGE = 768,
  65. SCN_AUTOCCANCELLED = 2025,
  66. SCN_AUTOCCHARDELETED = 2026,
  67. SCN_AUTOCCOMPLETED = 2030,
  68. SCN_AUTOCSELECTION = 2022,
  69. SCN_CALLTIPCLICK = 2021,
  70. SCN_CHARADDED = 2001,
  71. SCN_DOUBLECLICK = 2006,
  72. SCN_DWELLEND = 2017,
  73. SCN_DWELLSTART = 2016,
  74. SCN_FOCUSIN = 2028,
  75. SCN_FOCUSOUT = 2029,
  76. SCN_HOTSPOTCLICK = 2019,
  77. SCN_HOTSPOTDOUBLECLICK = 2020,
  78. SCN_HOTSPOTRELEASECLICK = 2027,
  79. SCN_INDICATORCLICK = 2023,
  80. SCN_INDICATORRELEASE = 2024,
  81. SCN_MACRORECORD = 2009,
  82. SCN_MARGINCLICK = 2010,
  83. SCN_MARGINRIGHTCLICK = 2031,
  84. SCN_MODIFIED = 2008,
  85. SCN_MODIFYATTEMPTRO = 2004,
  86. SCN_NEEDSHOWN = 2011,
  87. SCN_PAINTED = 2013,
  88. SCN_SAVEPOINTLEFT = 2003,
  89. SCN_SAVEPOINTREACHED = 2002,
  90. SCN_STYLENEEDED = 2000,
  91. SCN_UPDATEUI = 2007,
  92. SCN_USERLISTSELECTION = 2014,
  93. SCN_ZOOM = 2018
  94. };
  95. // The ctor.
  96. QsciScintillaQt::QsciScintillaQt(QsciScintillaBase *qsb_)
  97. : vMax(0), hMax(0), vPage(0), hPage(0), capturedMouse(false), qsb(qsb_)
  98. {
  99. wMain = qsb->viewport();
  100. // This is ignored.
  101. imeInteraction = imeInline;
  102. for (int i = 0; i <= static_cast<int>(tickPlatform); ++i)
  103. timers[i] = 0;
  104. Initialise();
  105. }
  106. // The dtor.
  107. QsciScintillaQt::~QsciScintillaQt()
  108. {
  109. Finalise();
  110. }
  111. // Initialise the instance.
  112. void QsciScintillaQt::Initialise()
  113. {
  114. }
  115. // Tidy up the instance.
  116. void QsciScintillaQt::Finalise()
  117. {
  118. for (int i = 0; i <= static_cast<int>(tickPlatform); ++i)
  119. FineTickerCancel(static_cast<TickReason>(i));
  120. ScintillaBase::Finalise();
  121. }
  122. // Start a drag.
  123. void QsciScintillaQt::StartDrag()
  124. {
  125. inDragDrop = ddDragging;
  126. QDrag *qdrag = new QDrag(qsb);
  127. qdrag->setMimeData(mimeSelection(drag));
  128. #if QT_VERSION >= 0x040300
  129. Qt::DropAction action = qdrag->exec(Qt::MoveAction | Qt::CopyAction, Qt::MoveAction);
  130. #else
  131. Qt::DropAction action = qdrag->start(Qt::MoveAction);
  132. #endif
  133. // Remove the dragged text if it was a move to another widget or
  134. // application.
  135. if (action == Qt::MoveAction && qdrag->target() != qsb->viewport())
  136. ClearSelection();
  137. SetDragPosition(QSCI_SCI_NAMESPACE(SelectionPosition)());
  138. inDragDrop = ddNone;
  139. }
  140. // Re-implement to trap certain messages.
  141. sptr_t QsciScintillaQt::WndProc(unsigned int iMessage, uptr_t wParam,
  142. sptr_t lParam)
  143. {
  144. switch (iMessage)
  145. {
  146. case SCI_GETDIRECTFUNCTION:
  147. return reinterpret_cast<sptr_t>(DirectFunction);
  148. case SCI_GETDIRECTPOINTER:
  149. return reinterpret_cast<sptr_t>(this);
  150. }
  151. return ScintillaBase::WndProc(iMessage, wParam, lParam);
  152. }
  153. // Windows nonsense.
  154. sptr_t QsciScintillaQt::DefWndProc(unsigned int, uptr_t, sptr_t)
  155. {
  156. return 0;
  157. }
  158. // Grab or release the mouse (and keyboard).
  159. void QsciScintillaQt::SetMouseCapture(bool on)
  160. {
  161. if (mouseDownCaptures)
  162. if (on)
  163. qsb->viewport()->grabMouse();
  164. else
  165. qsb->viewport()->releaseMouse();
  166. capturedMouse = on;
  167. }
  168. // Return true if the mouse/keyboard are currently grabbed.
  169. bool QsciScintillaQt::HaveMouseCapture()
  170. {
  171. return capturedMouse;
  172. }
  173. // Set the position of the vertical scrollbar.
  174. void QsciScintillaQt::SetVerticalScrollPos()
  175. {
  176. QScrollBar *sb = qsb->verticalScrollBar();
  177. bool was_blocked = sb->blockSignals(true);
  178. sb->setValue(topLine);
  179. sb->blockSignals(was_blocked);
  180. }
  181. // Set the position of the horizontal scrollbar.
  182. void QsciScintillaQt::SetHorizontalScrollPos()
  183. {
  184. QScrollBar *sb = qsb->horizontalScrollBar();
  185. bool was_blocked = sb->blockSignals(true);
  186. sb->setValue(xOffset);
  187. sb->blockSignals(was_blocked);
  188. }
  189. // Set the extent of the vertical and horizontal scrollbars and return true if
  190. // the view needs re-drawing.
  191. bool QsciScintillaQt::ModifyScrollBars(int nMax,int nPage)
  192. {
  193. bool modified = false;
  194. QScrollBar *sb;
  195. int vNewPage = nPage;
  196. int vNewMax = nMax - vNewPage + 1;
  197. if (vMax != vNewMax || vPage != vNewPage)
  198. {
  199. vMax = vNewMax;
  200. vPage = vNewPage;
  201. modified = true;
  202. sb = qsb->verticalScrollBar();
  203. sb->setMaximum(vMax);
  204. sb->setPageStep(vPage);
  205. }
  206. int hNewPage = GetTextRectangle().Width();
  207. int hNewMax = (scrollWidth > hNewPage) ? scrollWidth - hNewPage : 0;
  208. int charWidth = vs.styles[STYLE_DEFAULT].aveCharWidth;
  209. sb = qsb->horizontalScrollBar();
  210. if (hMax != hNewMax || hPage != hNewPage || sb->singleStep() != charWidth)
  211. {
  212. hMax = hNewMax;
  213. hPage = hNewPage;
  214. modified = true;
  215. sb->setMaximum(hMax);
  216. sb->setPageStep(hPage);
  217. sb->setSingleStep(charWidth);
  218. }
  219. return modified;
  220. }
  221. // Called after SCI_SETWRAPMODE and SCI_SETHSCROLLBAR.
  222. void QsciScintillaQt::ReconfigureScrollBars()
  223. {
  224. // Hide or show the scrollbars if needed.
  225. bool hsb = (horizontalScrollBarVisible && !Wrapping());
  226. qsb->setHorizontalScrollBarPolicy(hsb ? Qt::ScrollBarAsNeeded : Qt::ScrollBarAlwaysOff);
  227. qsb->setVerticalScrollBarPolicy(verticalScrollBarVisible ? Qt::ScrollBarAsNeeded : Qt::ScrollBarAlwaysOff);
  228. }
  229. // Notify interested parties of any change in the document.
  230. void QsciScintillaQt::NotifyChange()
  231. {
  232. emit qsb->SCEN_CHANGE();
  233. }
  234. // Notify interested parties of various events. This is the main mapping
  235. // between Scintilla notifications and Qt signals.
  236. void QsciScintillaQt::NotifyParent(SCNotification scn)
  237. {
  238. switch (scn.nmhdr.code)
  239. {
  240. case SCN_CALLTIPCLICK:
  241. emit qsb->SCN_CALLTIPCLICK(scn.position);
  242. break;
  243. case SCN_AUTOCCANCELLED:
  244. emit qsb->SCN_AUTOCCANCELLED();
  245. break;
  246. case SCN_AUTOCCHARDELETED:
  247. emit qsb->SCN_AUTOCCHARDELETED();
  248. break;
  249. case SCN_AUTOCCOMPLETED:
  250. emit qsb->SCN_AUTOCCOMPLETED(scn.text, scn.lParam, scn.ch,
  251. scn.listCompletionMethod);
  252. break;
  253. case SCN_AUTOCSELECTION:
  254. emit qsb->SCN_AUTOCSELECTION(scn.text, scn.lParam, scn.ch,
  255. scn.listCompletionMethod);
  256. emit qsb->SCN_AUTOCSELECTION(scn.text, scn.lParam);
  257. break;
  258. case SCN_CHARADDED:
  259. emit qsb->SCN_CHARADDED(scn.ch);
  260. break;
  261. case SCN_DOUBLECLICK:
  262. emit qsb->SCN_DOUBLECLICK(scn.position, scn.line, scn.modifiers);
  263. break;
  264. case SCN_DWELLEND:
  265. emit qsb->SCN_DWELLEND(scn.position, scn.x, scn.y);
  266. break;
  267. case SCN_DWELLSTART:
  268. emit qsb->SCN_DWELLSTART(scn.position, scn.x, scn.y);
  269. break;
  270. case SCN_FOCUSIN:
  271. emit qsb->SCN_FOCUSIN();
  272. break;
  273. case SCN_FOCUSOUT:
  274. emit qsb->SCN_FOCUSOUT();
  275. break;
  276. case SCN_HOTSPOTCLICK:
  277. emit qsb->SCN_HOTSPOTCLICK(scn.position, scn.modifiers);
  278. break;
  279. case SCN_HOTSPOTDOUBLECLICK:
  280. emit qsb->SCN_HOTSPOTDOUBLECLICK(scn.position, scn.modifiers);
  281. break;
  282. case SCN_HOTSPOTRELEASECLICK:
  283. emit qsb->SCN_HOTSPOTRELEASECLICK(scn.position, scn.modifiers);
  284. break;
  285. case SCN_INDICATORCLICK:
  286. emit qsb->SCN_INDICATORCLICK(scn.position, scn.modifiers);
  287. break;
  288. case SCN_INDICATORRELEASE:
  289. emit qsb->SCN_INDICATORRELEASE(scn.position, scn.modifiers);
  290. break;
  291. case SCN_MACRORECORD:
  292. emit qsb->SCN_MACRORECORD(scn.message, scn.wParam,
  293. reinterpret_cast<void *>(scn.lParam));
  294. break;
  295. case SCN_MARGINCLICK:
  296. emit qsb->SCN_MARGINCLICK(scn.position, scn.modifiers, scn.margin);
  297. break;
  298. case SCN_MARGINRIGHTCLICK:
  299. emit qsb->SCN_MARGINRIGHTCLICK(scn.position, scn.modifiers,
  300. scn.margin);
  301. break;
  302. case SCN_MODIFIED:
  303. {
  304. char *text;
  305. // Give some protection to the Python bindings.
  306. if (scn.text && (scn.modificationType & (SC_MOD_INSERTTEXT|SC_MOD_DELETETEXT) != 0))
  307. {
  308. text = new char[scn.length + 1];
  309. memcpy(text, scn.text, scn.length);
  310. text[scn.length] = '\0';
  311. }
  312. else
  313. {
  314. text = 0;
  315. }
  316. emit qsb->SCN_MODIFIED(scn.position, scn.modificationType, text,
  317. scn.length, scn.linesAdded, scn.line, scn.foldLevelNow,
  318. scn.foldLevelPrev, scn.token, scn.annotationLinesAdded);
  319. if (text)
  320. delete[] text;
  321. break;
  322. }
  323. case SCN_MODIFYATTEMPTRO:
  324. emit qsb->SCN_MODIFYATTEMPTRO();
  325. break;
  326. case SCN_NEEDSHOWN:
  327. emit qsb->SCN_NEEDSHOWN(scn.position, scn.length);
  328. break;
  329. case SCN_PAINTED:
  330. emit qsb->SCN_PAINTED();
  331. break;
  332. case SCN_SAVEPOINTLEFT:
  333. emit qsb->SCN_SAVEPOINTLEFT();
  334. break;
  335. case SCN_SAVEPOINTREACHED:
  336. emit qsb->SCN_SAVEPOINTREACHED();
  337. break;
  338. case SCN_STYLENEEDED:
  339. emit qsb->SCN_STYLENEEDED(scn.position);
  340. break;
  341. case SCN_UPDATEUI:
  342. emit qsb->SCN_UPDATEUI(scn.updated);
  343. break;
  344. case SCN_USERLISTSELECTION:
  345. emit qsb->SCN_USERLISTSELECTION(scn.text, scn.wParam, scn.ch,
  346. scn.listCompletionMethod);
  347. emit qsb->SCN_USERLISTSELECTION(scn.text, scn.wParam);
  348. break;
  349. case SCN_ZOOM:
  350. emit qsb->SCN_ZOOM();
  351. break;
  352. default:
  353. qWarning("Unknown notification: %u", scn.nmhdr.code);
  354. }
  355. }
  356. // Convert a selection to mime data.
  357. QMimeData *QsciScintillaQt::mimeSelection(
  358. const QSCI_SCI_NAMESPACE(SelectionText) &text) const
  359. {
  360. return qsb->toMimeData(QByteArray(text.Data()), text.rectangular);
  361. }
  362. // Copy the selected text to the clipboard.
  363. void QsciScintillaQt::CopyToClipboard(
  364. const QSCI_SCI_NAMESPACE(SelectionText) &selectedText)
  365. {
  366. QApplication::clipboard()->setMimeData(mimeSelection(selectedText));
  367. }
  368. // Implement copy.
  369. void QsciScintillaQt::Copy()
  370. {
  371. if (!sel.Empty())
  372. {
  373. QSCI_SCI_NAMESPACE(SelectionText) text;
  374. CopySelectionRange(&text);
  375. CopyToClipboard(text);
  376. }
  377. }
  378. // Implement pasting text.
  379. void QsciScintillaQt::Paste()
  380. {
  381. pasteFromClipboard(QClipboard::Clipboard);
  382. }
  383. // Paste text from either the clipboard or selection.
  384. void QsciScintillaQt::pasteFromClipboard(QClipboard::Mode mode)
  385. {
  386. int len;
  387. const char *s;
  388. bool rectangular;
  389. const QMimeData *source = QApplication::clipboard()->mimeData(mode);
  390. if (!source || !qsb->canInsertFromMimeData(source))
  391. return;
  392. QByteArray text = qsb->fromMimeData(source, rectangular);
  393. len = text.length();
  394. s = text.data();
  395. std::string dest = QSCI_SCI_NAMESPACE(Document)::TransformLineEnds(s, len,
  396. pdoc->eolMode);
  397. QSCI_SCI_NAMESPACE(SelectionText) selText;
  398. selText.Copy(dest, (IsUnicodeMode() ? SC_CP_UTF8 : 0),
  399. vs.styles[STYLE_DEFAULT].characterSet, rectangular, false);
  400. QSCI_SCI_NAMESPACE(UndoGroup) ug(pdoc);
  401. ClearSelection();
  402. InsertPasteShape(selText.Data(), selText.Length(),
  403. selText.rectangular ? pasteRectangular : pasteStream);
  404. EnsureCaretVisible();
  405. }
  406. // Create a call tip window.
  407. void QsciScintillaQt::CreateCallTipWindow(QSCI_SCI_NAMESPACE(PRectangle) rc)
  408. {
  409. if (!ct.wCallTip.Created())
  410. ct.wCallTip = ct.wDraw = new QsciSciCallTip(qsb, this);
  411. QsciSciCallTip *w = reinterpret_cast<QsciSciCallTip *>(ct.wCallTip.GetID());
  412. w->resize(rc.right - rc.left, rc.bottom - rc.top);
  413. ct.wCallTip.Show();
  414. }
  415. // Add an item to the right button menu.
  416. void QsciScintillaQt::AddToPopUp(const char *label, int cmd, bool enabled)
  417. {
  418. QsciSciPopup *pm = static_cast<QsciSciPopup *>(popup.GetID());
  419. if (*label)
  420. pm->addItem(qApp->translate("ContextMenu", label), cmd, enabled, this);
  421. else
  422. pm->addSeparator();
  423. }
  424. // Claim the selection.
  425. void QsciScintillaQt::ClaimSelection()
  426. {
  427. bool isSel = !sel.Empty();
  428. if (isSel)
  429. {
  430. QClipboard *cb = QApplication::clipboard();
  431. // If we support X11 style selection then make it available now.
  432. if (cb->supportsSelection())
  433. {
  434. QSCI_SCI_NAMESPACE(SelectionText) text;
  435. CopySelectionRange(&text);
  436. if (text.Data())
  437. cb->setMimeData(mimeSelection(text), QClipboard::Selection);
  438. }
  439. primarySelection = true;
  440. }
  441. else
  442. primarySelection = false;
  443. emit qsb->QSCN_SELCHANGED(isSel);
  444. }
  445. // Unclaim the selection.
  446. void QsciScintillaQt::UnclaimSelection()
  447. {
  448. if (primarySelection)
  449. {
  450. primarySelection = false;
  451. qsb->viewport()->update();
  452. }
  453. }
  454. // Implemented to provide compatibility with the Windows version.
  455. sptr_t QsciScintillaQt::DirectFunction(QsciScintillaQt *sciThis, unsigned int iMessage,
  456. uptr_t wParam, sptr_t lParam)
  457. {
  458. return sciThis->WndProc(iMessage,wParam,lParam);
  459. }
  460. // Draw the contents of the widget.
  461. void QsciScintillaQt::paintEvent(QPaintEvent *e)
  462. {
  463. QSCI_SCI_NAMESPACE(Surface) *sw;
  464. const QRect &qr = e->rect();
  465. rcPaint.left = qr.left();
  466. rcPaint.top = qr.top();
  467. rcPaint.right = qr.right() + 1;
  468. rcPaint.bottom = qr.bottom() + 1;
  469. QSCI_SCI_NAMESPACE(PRectangle) rcClient = GetClientRectangle();
  470. paintingAllText = rcPaint.Contains(rcClient);
  471. sw = QSCI_SCI_NAMESPACE(Surface)::Allocate(SC_TECHNOLOGY_DEFAULT);
  472. if (!sw)
  473. return;
  474. QPainter painter(qsb->viewport());
  475. paintState = painting;
  476. sw->Init(&painter);
  477. sw->SetUnicodeMode(CodePage() == SC_CP_UTF8);
  478. Paint(sw, rcPaint);
  479. delete sw;
  480. // If the painting area was insufficient to cover the new style or brace
  481. // highlight positions then repaint the whole thing.
  482. if (paintState == paintAbandoned)
  483. {
  484. // Do a full re-paint immediately. This may only be needed on OS X (to
  485. // avoid flicker).
  486. paintingAllText = true;
  487. sw = QSCI_SCI_NAMESPACE(Surface)::Allocate(SC_TECHNOLOGY_DEFAULT);
  488. if (!sw)
  489. return;
  490. QPainter painter(qsb->viewport());
  491. paintState = painting;
  492. sw->Init(&painter);
  493. sw->SetUnicodeMode(CodePage() == SC_CP_UTF8);
  494. Paint(sw, rcPaint);
  495. delete sw;
  496. qsb->viewport()->update();
  497. }
  498. paintState = notPainting;
  499. }
  500. // Re-implemented to drive the tickers.
  501. void QsciScintillaQt::timerEvent(QTimerEvent *e)
  502. {
  503. for (int i = 0; i <= static_cast<int>(tickPlatform); ++i)
  504. if (timers[i] == e->timerId())
  505. TickFor(static_cast<TickReason>(i));
  506. }
  507. // Re-implemented to say we support fine tickers.
  508. bool QsciScintillaQt::FineTickerAvailable()
  509. {
  510. return true;
  511. }
  512. // Re-implemented to stop a ticker.
  513. void QsciScintillaQt::FineTickerCancel(TickReason reason)
  514. {
  515. int &ticker = timers[static_cast<int>(reason)];
  516. if (ticker != 0)
  517. {
  518. killTimer(ticker);
  519. ticker = 0;
  520. }
  521. }
  522. // Re-implemented to check if a particular ticker is running.
  523. bool QsciScintillaQt::FineTickerRunning(TickReason reason)
  524. {
  525. return (timers[static_cast<int>(reason)] != 0);
  526. }
  527. // Re-implemented to start a ticker.
  528. void QsciScintillaQt::FineTickerStart(TickReason reason, int ms, int)
  529. {
  530. int &ticker = timers[static_cast<int>(reason)];
  531. if (ticker != 0)
  532. killTimer(ticker);
  533. ticker = startTimer(ms);
  534. }
  535. // Re-implemented to support idle processing.
  536. bool QsciScintillaQt::SetIdle(bool on)
  537. {
  538. if (on)
  539. {
  540. if (!idler.state)
  541. {
  542. QTimer *timer = reinterpret_cast<QTimer *>(idler.idlerID);
  543. if (!timer)
  544. {
  545. idler.idlerID = timer = new QTimer(this);
  546. connect(timer, SIGNAL(timeout()), this, SLOT(onIdle()));
  547. }
  548. timer->start(0);
  549. idler.state = true;
  550. }
  551. }
  552. else if (idler.state)
  553. {
  554. reinterpret_cast<QTimer *>(idler.idlerID)->stop();
  555. idler.state = false;
  556. }
  557. return true;
  558. }
  559. // Invoked to trigger any idle processing.
  560. void QsciScintillaQt::onIdle()
  561. {
  562. if (!Idle())
  563. SetIdle(false);
  564. }