123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479 |
- // This module implements the "official" high-level API of the Qt port of
- // Scintilla. It is modelled on QTextEdit - a method of the same name should
- // behave in the same way.
- //
- // Copyright (c) 2017 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/qsciscintilla.h"
- #include <string.h>
- #include <QAction>
- #include <QApplication>
- #include <QColor>
- #include <QEvent>
- #include <QImage>
- #include <QIODevice>
- #include <QKeyEvent>
- #include <QKeySequence>
- #include <QMenu>
- #include <QPoint>
- #include "Qsci/qsciabstractapis.h"
- #include "Qsci/qscicommandset.h"
- #include "Qsci/qscilexer.h"
- #include "Qsci/qscistyle.h"
- #include "Qsci/qscistyledtext.h"
- // Make sure these match the values in Scintilla.h. We don't #include that
- // file because it just causes more clashes.
- #define KEYWORDSET_MAX 8
- #define MARKER_MAX 31
- // The list separators for auto-completion and user lists.
- const char acSeparator = '\x03';
- const char userSeparator = '\x04';
- // The default fold margin width.
- static const int defaultFoldMarginWidth = 14;
- // The default set of characters that make up a word.
- static const char *defaultWordChars = "_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
- // Forward declarations.
- static QColor asQColor(long sci_colour);
- // The ctor.
- QsciScintilla::QsciScintilla(QWidget *parent)
- : QsciScintillaBase(parent),
- allocatedMarkers(0), allocatedIndicators(7), oldPos(-1), selText(false),
- fold(FoldStyle::NoFoldStyle), foldmargin(2), autoInd(false),
- braceMode(BraceMatch::NoBraceMatch), acSource(AutoCompletionSource::AcsNone), acThresh(-1),
- wchars(defaultWordChars), call_tips_position(CallTipsPosition::CallTipsBelowText),
- call_tips_style(CallTipsStyle::CallTipsNoContext), maxCallTips(-1),
- use_single(AcusNever), explicit_fillups(""), fillups_enabled(false)
- {
- connect(this,SIGNAL(SCN_MODIFYATTEMPTRO()),
- SIGNAL(modificationAttempted()));
- connect(this,SIGNAL(SCN_MODIFIED(int,int,const char *,int,int,int,int,int,int,int)),
- SLOT(handleModified(int,int,const char *,int,int,int,int,int,int,int)));
- connect(this,SIGNAL(SCN_CALLTIPCLICK(int)),
- SLOT(handleCallTipClick(int)));
- connect(this,SIGNAL(SCN_CHARADDED(int)),
- SLOT(handleCharAdded(int)));
- connect(this,SIGNAL(SCN_INDICATORCLICK(int,int)),
- SLOT(handleIndicatorClick(int,int)));
- connect(this,SIGNAL(SCN_INDICATORRELEASE(int,int)),
- SLOT(handleIndicatorRelease(int,int)));
- connect(this,SIGNAL(SCN_MARGINCLICK(int,int,int)),
- SLOT(handleMarginClick(int,int,int)));
- connect(this,SIGNAL(SCN_MARGINRIGHTCLICK(int,int,int)),
- SLOT(handleMarginRightClick(int,int,int)));
- connect(this,SIGNAL(SCN_SAVEPOINTREACHED()),
- SLOT(handleSavePointReached()));
- connect(this,SIGNAL(SCN_SAVEPOINTLEFT()),
- SLOT(handleSavePointLeft()));
- connect(this,SIGNAL(SCN_UPDATEUI(int)),
- SLOT(handleUpdateUI(int)));
- connect(this,SIGNAL(QSCN_SELCHANGED(bool)),
- SLOT(handleSelectionChanged(bool)));
- connect(this,SIGNAL(SCN_AUTOCSELECTION(const char *,int)),
- SLOT(handleAutoCompletionSelection()));
- connect(this,SIGNAL(SCN_USERLISTSELECTION(const char *,int)),
- SLOT(handleUserListSelection(const char *,int)));
- // Set the default font.
- setFont(QApplication::font());
- // Set the default fore and background colours.
- QPalette pal = QApplication::palette();
- setColor(pal.text().color());
- setPaper(pal.base().color());
- setSelectionForegroundColor(pal.highlightedText().color());
- setSelectionBackgroundColor(pal.highlight().color());
- #if defined(Q_OS_WIN)
- setEolMode(EolMode::EolWindows);
- #else
- // Note that EolMac is pre-OS/X.
- setEolMode(EolMode::EolUnix);
- #endif
- // Capturing the mouse seems to cause problems on multi-head systems. Qt
- // should do the right thing anyway.
- SendScintilla(SCI_SETMOUSEDOWNCAPTURES, 0UL);
- setMatchedBraceForegroundColor(Qt::blue);
- setUnmatchedBraceForegroundColor(Qt::red);
- setAnnotationDisplay(AnnotationStandard);
- setLexer();
- // Set the visible policy. These are the same as SciTE's defaults
- // which, presumably, are sensible.
- SendScintilla(SCI_SETVISIBLEPOLICY, VISIBLE_STRICT | VISIBLE_SLOP, 4);
- // The default behaviour is unexpected.
- SendScintilla(SCI_AUTOCSETCASEINSENSITIVEBEHAVIOUR,
- SC_CASEINSENSITIVEBEHAVIOUR_IGNORECASE);
- // Create the standard command set.
- stdCmds = new QsciCommandSet(this);
- doc.display(this,0);
- }
- // The dtor.
- QsciScintilla::~QsciScintilla()
- {
- // Detach any current lexer.
- detachLexer();
- doc.undisplay(this);
- delete stdCmds;
- }
- // Return the current text colour.
- QColor QsciScintilla::color() const
- {
- return nl_text_colour;
- }
- // Set the text colour.
- void QsciScintilla::setColor(const QColor &c)
- {
- if (lex.isNull())
- {
- // Assume style 0 applies to everything so that we don't need to use
- // SCI_STYLECLEARALL which clears everything.
- SendScintilla(SCI_STYLESETFORE, 0, c);
- nl_text_colour = c;
- }
- }
- // Return the overwrite mode.
- bool QsciScintilla::overwriteMode() const
- {
- return SendScintilla(SCI_GETOVERTYPE);
- }
- // Set the overwrite mode.
- void QsciScintilla::setOverwriteMode(bool overwrite)
- {
- SendScintilla(SCI_SETOVERTYPE, overwrite);
- }
- // Return the current paper colour.
- QColor QsciScintilla::paper() const
- {
- return nl_paper_colour;
- }
- // Set the paper colour.
- void QsciScintilla::setPaper(const QColor &c)
- {
- if (lex.isNull())
- {
- // Assume style 0 applies to everything so that we don't need to use
- // SCI_STYLECLEARALL which clears everything. We still have to set the
- // default style as well for the background without any text.
- SendScintilla(SCI_STYLESETBACK, 0, c);
- SendScintilla(SCI_STYLESETBACK, STYLE_DEFAULT, c);
- nl_paper_colour = c;
- }
- }
- // Set the default font.
- void QsciScintilla::setFont(const QFont &f)
- {
- if (lex.isNull())
- {
- // Assume style 0 applies to everything so that we don't need to use
- // SCI_STYLECLEARALL which clears everything.
- setStylesFont(f, 0);
- QWidget::setFont(f);
- }
- }
- // Enable/disable auto-indent.
- void QsciScintilla::setAutoIndent(bool autoindent)
- {
- autoInd = autoindent;
- }
- // Set the brace matching mode.
- void QsciScintilla::setBraceMatching(BraceMatch bm)
- {
- braceMode = bm;
- }
- // Handle the addition of a character.
- void QsciScintilla::handleCharAdded(int ch)
- {
- // Ignore if there is a selection.
- long pos = SendScintilla(SCI_GETSELECTIONSTART);
- if (pos != SendScintilla(SCI_GETSELECTIONEND) || pos == 0)
- return;
- // If auto-completion is already active then see if this character is a
- // start character. If it is then create a new list which will be a subset
- // of the current one. The case where it isn't a start character seems to
- // be handled correctly elsewhere.
- if (isListActive() && isStartChar(ch))
- {
- cancelList();
- startAutoCompletion(acSource, false, use_single == AcusAlways);
- return;
- }
- // Handle call tips.
- if (call_tips_style != CallTipsStyle::CallTipsNone && !lex.isNull() && strchr("(),", ch) != NULL)
- callTip();
- // Handle auto-indentation.
- if (autoInd)
- if (lex.isNull() || (lex->autoIndentStyle() & AiMaintain))
- maintainIndentation(ch, pos);
- else
- autoIndentation(ch, pos);
- // See if we might want to start auto-completion.
- if (!isCallTipActive() && acSource != AutoCompletionSource::AcsNone)
- if (isStartChar(ch))
- startAutoCompletion(acSource, false, use_single == AcusAlways);
- else if (acThresh >= 1 && isWordCharacter(ch))
- startAutoCompletion(acSource, true, use_single == AcusAlways);
- }
- // See if a call tip is active.
- bool QsciScintilla::isCallTipActive() const
- {
- return SendScintilla(SCI_CALLTIPACTIVE);
- }
- // Handle a possible change to any current call tip.
- void QsciScintilla::callTip()
- {
- QsciAbstractAPIs *apis = lex->apis();
- if (!apis)
- return;
- int pos, commas = 0;
- bool found = false;
- char ch;
- pos = SendScintilla(SCI_GETCURRENTPOS);
- // Move backwards through the line looking for the start of the current
- // call tip and working out which argument it is.
- while ((ch = getCharacter(pos)) != '\0')
- {
- if (ch == ',')
- ++commas;
- else if (ch == ')')
- {
- int depth = 1;
- // Ignore everything back to the start of the corresponding
- // parenthesis.
- while ((ch = getCharacter(pos)) != '\0')
- {
- if (ch == ')')
- ++depth;
- else if (ch == '(' && --depth == 0)
- break;
- }
- }
- else if (ch == '(')
- {
- found = true;
- break;
- }
- }
- // Cancel any existing call tip.
- SendScintilla(SCI_CALLTIPCANCEL);
- // Done if there is no new call tip to set.
- if (!found)
- return;
- QStringList context = apiContext(pos, pos, ctPos);
- if (context.isEmpty())
- return;
- // The last word is complete, not partial.
- context << QString();
- ct_cursor = 0;
- ct_shifts.clear();
- ct_entries = apis->callTips(context, commas, call_tips_style, ct_shifts);
- int nr_entries = ct_entries.count();
- if (nr_entries == 0)
- return;
- if (maxCallTips > 0 && maxCallTips < nr_entries)
- {
- ct_entries = ct_entries.mid(0, maxCallTips);
- nr_entries = maxCallTips;
- }
- int shift;
- QString ct;
- int nr_shifts = ct_shifts.count();
- if (maxCallTips < 0 && nr_entries > 1)
- {
- shift = (nr_shifts > 0 ? ct_shifts.first() : 0);
- ct = ct_entries[0];
- ct.prepend('\002');
- }
- else
- {
- if (nr_shifts > nr_entries)
- nr_shifts = nr_entries;
- // Find the biggest shift.
- shift = 0;
- for (int i = 0; i < nr_shifts; ++i)
- {
- int sh = ct_shifts[i];
- if (shift < sh)
- shift = sh;
- }
- ct = ct_entries.join("\n");
- }
- QByteArray ct_ba = ct.toLatin1();
- const char *cts = ct_ba.data();
- SendScintilla(SCI_CALLTIPSHOW, adjustedCallTipPosition(shift), cts);
- // Done if there is more than one call tip.
- if (nr_entries > 1)
- return;
- // Highlight the current argument.
- const char *astart;
- if (commas == 0)
- astart = strchr(cts, '(');
- else
- for (astart = strchr(cts, ','); astart && --commas > 0; astart = strchr(astart + 1, ','))
- ;
- if (!astart || !*++astart)
- return;
- // The end is at the next comma or unmatched closing parenthesis.
- const char *aend;
- int depth = 0;
- for (aend = astart; *aend; ++aend)
- {
- char ch = *aend;
- if (ch == ',' && depth == 0)
- break;
- else if (ch == '(')
- ++depth;
- else if (ch == ')')
- {
- if (depth == 0)
- break;
- --depth;
- }
- }
- if (astart != aend)
- SendScintilla(SCI_CALLTIPSETHLT, astart - cts, aend - cts);
- }
- // Handle a call tip click.
- void QsciScintilla::handleCallTipClick(int dir)
- {
- int nr_entries = ct_entries.count();
- // Move the cursor while bounds checking.
- if (dir == 1)
- {
- if (ct_cursor - 1 < 0)
- return;
- --ct_cursor;
- }
- else if (dir == 2)
- {
- if (ct_cursor + 1 >= nr_entries)
- return;
- ++ct_cursor;
- }
- else
- return;
- int shift = (ct_shifts.count() > ct_cursor ? ct_shifts[ct_cursor] : 0);
- QString ct = ct_entries[ct_cursor];
- // Add the arrows.
- if (ct_cursor < nr_entries - 1)
- ct.prepend('\002');
- if (ct_cursor > 0)
- ct.prepend('\001');
- SendScintilla(SCI_CALLTIPSHOW, adjustedCallTipPosition(shift), ct.toLatin1().data());
- }
- // Shift the position of the call tip (to take any context into account) but
- // don't go before the start of the line.
- int QsciScintilla::adjustedCallTipPosition(int ctshift) const
- {
- int ct = ctPos;
- if (ctshift)
- {
- int ctmin = SendScintilla(SCI_POSITIONFROMLINE, SendScintilla(SCI_LINEFROMPOSITION, ct));
- if (ct - ctshift < ctmin)
- ct = ctmin;
- }
- return ct;
- }
- // Return the list of words that make up the context preceding the given
- // position. The list will only have more than one element if there is a lexer
- // set and it defines start strings. If so, then the last element might be
- // empty if a start string has just been typed. On return pos is at the start
- // of the context.
- QStringList QsciScintilla::apiContext(int pos, int &context_start,
- int &last_word_start)
- {
- enum {
- Either,
- Separator,
- Word
- };
- QStringList words;
- int good_pos = pos, expecting = Either;
- last_word_start = -1;
- while (pos > 0)
- {
- if (getSeparator(pos))
- {
- if (expecting == Either)
- words.prepend(QString());
- else if (expecting == Word)
- break;
- good_pos = pos;
- expecting = Word;
- }
- else
- {
- QString word = getWord(pos);
- if (word.isEmpty() || expecting == Separator)
- break;
- words.prepend(word);
- good_pos = pos;
- expecting = Separator;
- // Return the position of the start of the last word if required.
- if (last_word_start < 0)
- last_word_start = pos;
- }
- // Strip any preceding spaces (mainly around operators).
- char ch;
- while ((ch = getCharacter(pos)) != '\0')
- {
- // This is the same definition of space that Scintilla uses.
- if (ch != ' ' && (ch < 0x09 || ch > 0x0d))
- {
- ++pos;
- break;
- }
- }
- }
- // A valid sequence always starts with a word and so should be expecting a
- // separator.
- if (expecting != Separator)
- words.clear();
- context_start = good_pos;
- return words;
- }
- // Try and get a lexer's word separator from the text before the current
- // position. Return true if one was found and adjust the position accordingly.
- bool QsciScintilla::getSeparator(int &pos) const
- {
- int opos = pos;
- // Go through each separator.
- for (int i = 0; i < wseps.count(); ++i)
- {
- const QString &ws = wseps[i];
- // Work backwards.
- uint l;
- for (l = ws.length(); l; --l)
- {
- char ch = getCharacter(pos);
- if (ch == '\0' || ws.at(l - 1) != ch)
- break;
- }
- if (!l)
- return true;
- // Reset for the next separator.
- pos = opos;
- }
- return false;
- }
- // Try and get a word from the text before the current position. Return the
- // word if one was found and adjust the position accordingly.
- QString QsciScintilla::getWord(int &pos) const
- {
- QString word;
- bool numeric = true;
- char ch;
- while ((ch = getCharacter(pos)) != '\0')
- {
- if (!isWordCharacter(ch))
- {
- ++pos;
- break;
- }
- if (ch < '0' || ch > '9')
- numeric = false;
- word.prepend(ch);
- }
- // We don't auto-complete numbers.
- if (numeric)
- word.truncate(0);
- return word;
- }
- // Get the "next" character (ie. the one before the current position) in the
- // current line. The character will be '\0' if there are no more.
- char QsciScintilla::getCharacter(int &pos) const
- {
- if (pos <= 0)
- return '\0';
- char ch = SendScintilla(SCI_GETCHARAT, --pos);
- // Don't go past the end of the previous line.
- if (ch == '\n' || ch == '\r')
- {
- ++pos;
- return '\0';
- }
- return ch;
- }
- // See if a character is an auto-completion start character, ie. the last
- // character of a word separator.
- bool QsciScintilla::isStartChar(char ch) const
- {
- QString s = QChar(ch);
- for (int i = 0; i < wseps.count(); ++i)
- if (wseps[i].endsWith(s))
- return true;
- return false;
- }
- // Possibly start auto-completion.
- void QsciScintilla::startAutoCompletion(AutoCompletionSource acs,
- bool checkThresh, bool choose_single)
- {
- int start, ignore;
- QStringList context = apiContext(SendScintilla(SCI_GETCURRENTPOS), start,
- ignore);
- if (context.isEmpty())
- return;
- // Get the last word's raw data and length.
- ScintillaBytes s = textAsBytes(context.last());
- const char *last_data = ScintillaBytesConstData(s);
- int last_len = s.length();
- if (checkThresh && last_len < acThresh)
- return;
- // Generate the string representing the valid words to select from.
- QStringList wlist;
- if ((acs == AutoCompletionSource::AcsAll || acs == AutoCompletionSource::AcsAPIs) && !lex.isNull())
- {
- QsciAbstractAPIs *apis = lex->apis();
- if (apis)
- apis->updateAutoCompletionList(context, wlist);
- }
- if (acs == AutoCompletionSource::AcsAll || acs == AutoCompletionSource::AcsDocument)
- {
- int sflags = SCFIND_WORDSTART;
- if (!SendScintilla(SCI_AUTOCGETIGNORECASE))
- sflags |= SCFIND_MATCHCASE;
- SendScintilla(SCI_SETSEARCHFLAGS, sflags);
- int pos = 0;
- int dlen = SendScintilla(SCI_GETLENGTH);
- int caret = SendScintilla(SCI_GETCURRENTPOS);
- int clen = caret - start;
- char *orig_context = new char[clen + 1];
- SendScintilla(SCI_GETTEXTRANGE, start, caret, orig_context);
- for (;;)
- {
- int fstart;
- SendScintilla(SCI_SETTARGETSTART, pos);
- SendScintilla(SCI_SETTARGETEND, dlen);
- if ((fstart = SendScintilla(SCI_SEARCHINTARGET, clen, orig_context)) < 0)
- break;
- // Move past the root part.
- pos = fstart + clen;
- // Skip if this is the context we are auto-completing.
- if (pos == caret)
- continue;
- // Get the rest of this word.
- QString w = last_data;
- while (pos < dlen)
- {
- char ch = SendScintilla(SCI_GETCHARAT, pos);
- if (!isWordCharacter(ch))
- break;
- w += ch;
- ++pos;
- }
- // Add the word if it isn't already there.
- if (!w.isEmpty())
- {
- bool keep;
- // If there are APIs then check if the word is already present
- // as an API word (i.e. with a trailing space).
- if (acs == AutoCompletionSource::AcsAll)
- {
- QString api_w = w;
- api_w.append(' ');
- keep = !wlist.contains(api_w);
- }
- else
- {
- keep = true;
- }
- if (keep && !wlist.contains(w))
- wlist.append(w);
- }
- }
- delete []orig_context;
- }
- if (wlist.isEmpty())
- return;
- wlist.sort();
- SendScintilla(SCI_AUTOCSETCHOOSESINGLE, choose_single);
- SendScintilla(SCI_AUTOCSETSEPARATOR, acSeparator);
- ScintillaBytes wlist_s = textAsBytes(wlist.join(QChar(acSeparator)));
- SendScintilla(SCI_AUTOCSHOW, last_len, ScintillaBytesConstData(wlist_s));
- }
- // Maintain the indentation of the previous line.
- void QsciScintilla::maintainIndentation(char ch, long pos)
- {
- if (ch != '\r' && ch != '\n')
- return;
- int curr_line = SendScintilla(SCI_LINEFROMPOSITION, pos);
- // Get the indentation of the preceding non-zero length line.
- int ind = 0;
- for (int line = curr_line - 1; line >= 0; --line)
- {
- if (SendScintilla(SCI_GETLINEENDPOSITION, line) >
- SendScintilla(SCI_POSITIONFROMLINE, line))
- {
- ind = indentation(line);
- break;
- }
- }
- if (ind > 0)
- autoIndentLine(pos, curr_line, ind);
- }
- // Implement auto-indentation.
- void QsciScintilla::autoIndentation(char ch, long pos)
- {
- int curr_line = SendScintilla(SCI_LINEFROMPOSITION, pos);
- int ind_width = indentWidth();
- long curr_line_start = SendScintilla(SCI_POSITIONFROMLINE, curr_line);
- const char *block_start = lex->blockStart();
- bool start_single = (block_start && qstrlen(block_start) == 1);
- const char *block_end = lex->blockEnd();
- bool end_single = (block_end && qstrlen(block_end) == 1);
- if (end_single && block_end[0] == ch)
- {
- if (!(lex->autoIndentStyle() & AiClosing) && rangeIsWhitespace(curr_line_start, pos - 1))
- autoIndentLine(pos, curr_line, blockIndent(curr_line - 1) - ind_width);
- }
- else if (start_single && block_start[0] == ch)
- {
- // De-indent if we have already indented because the previous line was
- // a start of block keyword.
- if (!(lex->autoIndentStyle() & AiOpening) && curr_line > 0 && getIndentState(curr_line - 1) == isKeywordStart && rangeIsWhitespace(curr_line_start, pos - 1))
- autoIndentLine(pos, curr_line, blockIndent(curr_line - 1) - ind_width);
- }
- else if (ch == '\r' || ch == '\n')
- {
- // Don't auto-indent the line (ie. preserve its existing indentation)
- // if we have inserted a new line above by pressing return at the start
- // of this line - in other words, if the previous line is empty.
- long prev_line_length = SendScintilla(SCI_GETLINEENDPOSITION, curr_line - 1) - SendScintilla(SCI_POSITIONFROMLINE, curr_line - 1);
- if (prev_line_length != 0)
- autoIndentLine(pos, curr_line, blockIndent(curr_line - 1));
- }
- }
- // Set the indentation for a line.
- void QsciScintilla::autoIndentLine(long pos, int line, int indent)
- {
- if (indent < 0)
- return;
- long pos_before = SendScintilla(SCI_GETLINEINDENTPOSITION, line);
- SendScintilla(SCI_SETLINEINDENTATION, line, indent);
- long pos_after = SendScintilla(SCI_GETLINEINDENTPOSITION, line);
- long new_pos = -1;
- if (pos_after > pos_before)
- new_pos = pos + (pos_after - pos_before);
- else if (pos_after < pos_before && pos >= pos_after)
- if (pos >= pos_before)
- new_pos = pos + (pos_after - pos_before);
- else
- new_pos = pos_after;
- if (new_pos >= 0)
- SendScintilla(SCI_SETSEL, new_pos, new_pos);
- }
- // Return the indentation of the block defined by the given line (or something
- // significant before).
- int QsciScintilla::blockIndent(int line)
- {
- if (line < 0)
- return 0;
- // Handle the trvial case.
- if (!lex->blockStartKeyword() && !lex->blockStart() && !lex->blockEnd())
- return indentation(line);
- int line_limit = line - lex->blockLookback();
- if (line_limit < 0)
- line_limit = 0;
- for (int l = line; l >= line_limit; --l)
- {
- IndentState istate = getIndentState(l);
- if (istate != isNone)
- {
- int ind_width = indentWidth();
- int ind = indentation(l);
- if (istate == isBlockStart)
- {
- if (!(lex -> autoIndentStyle() & AiOpening))
- ind += ind_width;
- }
- else if (istate == isBlockEnd)
- {
- if (lex -> autoIndentStyle() & AiClosing)
- ind -= ind_width;
- if (ind < 0)
- ind = 0;
- }
- else if (line == l)
- ind += ind_width;
- return ind;
- }
- }
- return indentation(line);
- }
- // Return true if all characters starting at spos up to, but not including
- // epos, are spaces or tabs.
- bool QsciScintilla::rangeIsWhitespace(long spos, long epos)
- {
- while (spos < epos)
- {
- char ch = SendScintilla(SCI_GETCHARAT, spos);
- if (ch != ' ' && ch != '\t')
- return false;
- ++spos;
- }
- return true;
- }
- // Returns the indentation state of a line.
- QsciScintilla::IndentState QsciScintilla::getIndentState(int line)
- {
- IndentState istate;
- // Get the styled text.
- long spos = SendScintilla(SCI_POSITIONFROMLINE, line);
- long epos = SendScintilla(SCI_POSITIONFROMLINE, line + 1);
- char *text = new char[(epos - spos + 1) * 2];
- SendScintilla(SCI_GETSTYLEDTEXT, spos, epos, text);
- int style, bstart_off, bend_off;
- // Block start/end takes precedence over keywords.
- const char *bstart_words = lex->blockStart(&style);
- bstart_off = findStyledWord(text, style, bstart_words);
- const char *bend_words = lex->blockEnd(&style);
- bend_off = findStyledWord(text, style, bend_words);
- // If there is a block start but no block end characters then ignore it
- // unless the block start is the last significant thing on the line, ie.
- // assume Python-like blocking.
- if (bstart_off >= 0 && !bend_words)
- for (int i = bstart_off * 2; text[i] != '\0'; i += 2)
- if (!QChar(text[i]).isSpace())
- return isNone;
- if (bstart_off > bend_off)
- istate = isBlockStart;
- else if (bend_off > bstart_off)
- istate = isBlockEnd;
- else
- {
- const char *words = lex->blockStartKeyword(&style);
- istate = (findStyledWord(text,style,words) >= 0) ? isKeywordStart : isNone;
- }
- delete[] text;
- return istate;
- }
- // text is a pointer to some styled text (ie. a character byte followed by a
- // style byte). style is a style number. words is a space separated list of
- // words. Returns the position in the text immediately after the last one of
- // the words with the style. The reason we are after the last, and not the
- // first, occurance is that we are looking for words that start and end a block
- // where the latest one is the most significant.
- int QsciScintilla::findStyledWord(const char *text, int style,
- const char *words)
- {
- if (!words)
- return -1;
- // Find the range of text with the style we are looking for.
- const char *stext;
- for (stext = text; stext[1] != style; stext += 2)
- if (stext[0] == '\0')
- return -1;
- // Move to the last character.
- const char *etext = stext;
- while (etext[2] != '\0')
- etext += 2;
- // Backtrack until we find the style. There will be one.
- while (etext[1] != style)
- etext -= 2;
- // Look for each word in turn.
- while (words[0] != '\0')
- {
- // Find the end of the word.
- const char *eword = words;
- while (eword[1] != ' ' && eword[1] != '\0')
- ++eword;
- // Now search the text backwards.
- const char *wp = eword;
- for (const char *tp = etext; tp >= stext; tp -= 2)
- {
- if (tp[0] != wp[0] || tp[1] != style)
- {
- // Reset the search.
- wp = eword;
- continue;
- }
- // See if all the word has matched.
- if (wp-- == words)
- return ((tp - text) / 2) + (eword - words) + 1;
- }
- // Move to the start of the next word if there is one.
- words = eword + 1;
- if (words[0] == ' ')
- ++words;
- }
- return -1;
- }
- // Return true if the code page is UTF8.
- bool QsciScintilla::isUtf8() const
- {
- return (SendScintilla(SCI_GETCODEPAGE) == SC_CP_UTF8);
- }
- // Set the code page.
- void QsciScintilla::setUtf8(bool cp)
- {
- SendScintilla(SCI_SETCODEPAGE, (cp ? SC_CP_UTF8 : 0));
- }
- // Return the end-of-line mode.
- QsciScintilla::EolMode QsciScintilla::eolMode() const
- {
- return (QsciScintilla::EolMode)SendScintilla(SCI_GETEOLMODE);
- }
- // Set the end-of-line mode.
- void QsciScintilla::setEolMode(QsciScintilla::EolMode mode)
- {
- SendScintilla(SCI_SETEOLMODE, mode);
- }
- // Convert the end-of-lines to a particular mode.
- void QsciScintilla::convertEols(EolMode mode)
- {
- SendScintilla(SCI_CONVERTEOLS, mode);
- }
- // Add an edge column.
- void QsciScintilla::addEdgeColumn(int colnr, const QColor &col)
- {
- SendScintilla(SCI_MULTIEDGEADDLINE, colnr, col);
- }
- // Clear all multi-edge columns.
- void QsciScintilla::clearEdgeColumns()
- {
- SendScintilla(SCI_MULTIEDGECLEARALL);
- }
- // Return the edge colour.
- QColor QsciScintilla::edgeColor() const
- {
- return asQColor(SendScintilla(SCI_GETEDGECOLOUR));
- }
- // Set the edge colour.
- void QsciScintilla::setEdgeColor(const QColor &col)
- {
- SendScintilla(SCI_SETEDGECOLOUR, col);
- }
- // Return the edge column.
- int QsciScintilla::edgeColumn() const
- {
- return SendScintilla(SCI_GETEDGECOLUMN);
- }
- // Set the edge column.
- void QsciScintilla::setEdgeColumn(int colnr)
- {
- SendScintilla(SCI_SETEDGECOLUMN, colnr);
- }
- // Return the edge mode.
- QsciScintilla::EdgeMode QsciScintilla::edgeMode() const
- {
- return (EdgeMode)SendScintilla(SCI_GETEDGEMODE);
- }
- // Set the edge mode.
- void QsciScintilla::setEdgeMode(EdgeMode mode)
- {
- SendScintilla(SCI_SETEDGEMODE, mode);
- }
- // Return the end-of-line visibility.
- bool QsciScintilla::eolVisibility() const
- {
- return SendScintilla(SCI_GETVIEWEOL);
- }
- // Set the end-of-line visibility.
- void QsciScintilla::setEolVisibility(bool visible)
- {
- SendScintilla(SCI_SETVIEWEOL, visible);
- }
- // Return the extra ascent.
- int QsciScintilla::extraAscent() const
- {
- return SendScintilla(SCI_GETEXTRAASCENT);
- }
- // Set the extra ascent.
- void QsciScintilla::setExtraAscent(int extra)
- {
- SendScintilla(SCI_SETEXTRAASCENT, extra);
- }
- // Return the extra descent.
- int QsciScintilla::extraDescent() const
- {
- return SendScintilla(SCI_GETEXTRADESCENT);
- }
- // Set the extra descent.
- void QsciScintilla::setExtraDescent(int extra)
- {
- SendScintilla(SCI_SETEXTRADESCENT, extra);
- }
- // Return the whitespace size.
- int QsciScintilla::whitespaceSize() const
- {
- return SendScintilla(SCI_GETWHITESPACESIZE);
- }
- // Set the whitespace size.
- void QsciScintilla::setWhitespaceSize(int size)
- {
- SendScintilla(SCI_SETWHITESPACESIZE, size);
- }
- // Set the whitespace background colour.
- void QsciScintilla::setWhitespaceBackgroundColor(const QColor &col)
- {
- SendScintilla(SCI_SETWHITESPACEBACK, col.isValid(), col);
- }
- // Set the whitespace foreground colour.
- void QsciScintilla::setWhitespaceForegroundColor(const QColor &col)
- {
- SendScintilla(SCI_SETWHITESPACEFORE, col.isValid(), col);
- }
- // Return the whitespace visibility.
- QsciScintilla::WhitespaceVisibility QsciScintilla::whitespaceVisibility() const
- {
- return (WhitespaceVisibility)SendScintilla(SCI_GETVIEWWS);
- }
- // Set the whitespace visibility.
- void QsciScintilla::setWhitespaceVisibility(WhitespaceVisibility mode)
- {
- SendScintilla(SCI_SETVIEWWS, mode);
- }
- // Return the tab draw mode.
- QsciScintilla::TabDrawMode QsciScintilla::tabDrawMode() const
- {
- return (TabDrawMode)SendScintilla(SCI_GETTABDRAWMODE);
- }
- // Set the tab draw mode.
- void QsciScintilla::setTabDrawMode(TabDrawMode mode)
- {
- SendScintilla(SCI_SETTABDRAWMODE, mode);
- }
- // Return the line wrap mode.
- QsciScintilla::WrapMode QsciScintilla::wrapMode() const
- {
- return (WrapMode)SendScintilla(SCI_GETWRAPMODE);
- }
- // Set the line wrap mode.
- void QsciScintilla::setWrapMode(WrapMode mode)
- {
- SendScintilla(SCI_SETLAYOUTCACHE,
- (mode == WrapNone ? SC_CACHE_CARET : SC_CACHE_DOCUMENT));
- SendScintilla(SCI_SETWRAPMODE, mode);
- }
- // Return the line wrap indent mode.
- QsciScintilla::WrapIndentMode QsciScintilla::wrapIndentMode() const
- {
- return (WrapIndentMode)SendScintilla(SCI_GETWRAPINDENTMODE);
- }
- // Set the line wrap indent mode.
- void QsciScintilla::setWrapIndentMode(WrapIndentMode mode)
- {
- SendScintilla(SCI_SETWRAPINDENTMODE, mode);
- }
- // Set the line wrap visual flags.
- void QsciScintilla::setWrapVisualFlags(WrapVisualFlag endFlag,
- WrapVisualFlag startFlag, int indent)
- {
- int flags = SC_WRAPVISUALFLAG_NONE;
- int loc = SC_WRAPVISUALFLAGLOC_DEFAULT;
- switch (endFlag)
- {
- case WrapFlagByText:
- flags |= SC_WRAPVISUALFLAG_END;
- loc |= SC_WRAPVISUALFLAGLOC_END_BY_TEXT;
- break;
- case WrapFlagByBorder:
- flags |= SC_WRAPVISUALFLAG_END;
- break;
- case WrapFlagInMargin:
- flags |= SC_WRAPVISUALFLAG_MARGIN;
- break;
- }
- switch (startFlag)
- {
- case WrapFlagByText:
- flags |= SC_WRAPVISUALFLAG_START;
- loc |= SC_WRAPVISUALFLAGLOC_START_BY_TEXT;
- break;
- case WrapFlagByBorder:
- flags |= SC_WRAPVISUALFLAG_START;
- break;
- case WrapFlagInMargin:
- flags |= SC_WRAPVISUALFLAG_MARGIN;
- break;
- }
- SendScintilla(SCI_SETWRAPVISUALFLAGS, flags);
- SendScintilla(SCI_SETWRAPVISUALFLAGSLOCATION, loc);
- SendScintilla(SCI_SETWRAPSTARTINDENT, indent);
- }
- // Set the folding style.
- void QsciScintilla::setFolding(FoldStyle folding, int margin)
- {
- fold = folding;
- foldmargin = margin;
- if (folding == FoldStyle::NoFoldStyle)
- {
- SendScintilla(SCI_SETMARGINWIDTHN, margin, 0L);
- return;
- }
- int mask = SendScintilla(SCI_GETMODEVENTMASK);
- SendScintilla(SCI_SETMODEVENTMASK, mask | SC_MOD_CHANGEFOLD);
- SendScintilla(SCI_SETFOLDFLAGS, SC_FOLDFLAG_LINEAFTER_CONTRACTED);
- SendScintilla(SCI_SETMARGINTYPEN, margin, (long)SC_MARGIN_SYMBOL);
- SendScintilla(SCI_SETMARGINMASKN, margin, SC_MASK_FOLDERS);
- SendScintilla(SCI_SETMARGINSENSITIVEN, margin, 1);
- // Set the marker symbols to use.
- switch (folding)
- {
- case FoldStyle::PlainFoldStyle:
- setFoldMarker(SC_MARKNUM_FOLDEROPEN, SC_MARK_MINUS);
- setFoldMarker(SC_MARKNUM_FOLDER, SC_MARK_PLUS);
- setFoldMarker(SC_MARKNUM_FOLDERSUB);
- setFoldMarker(SC_MARKNUM_FOLDERTAIL);
- setFoldMarker(SC_MARKNUM_FOLDEREND);
- setFoldMarker(SC_MARKNUM_FOLDEROPENMID);
- setFoldMarker(SC_MARKNUM_FOLDERMIDTAIL);
- break;
- case FoldStyle::CircledFoldStyle:
- setFoldMarker(SC_MARKNUM_FOLDEROPEN, SC_MARK_CIRCLEMINUS);
- setFoldMarker(SC_MARKNUM_FOLDER, SC_MARK_CIRCLEPLUS);
- setFoldMarker(SC_MARKNUM_FOLDERSUB);
- setFoldMarker(SC_MARKNUM_FOLDERTAIL);
- setFoldMarker(SC_MARKNUM_FOLDEREND);
- setFoldMarker(SC_MARKNUM_FOLDEROPENMID);
- setFoldMarker(SC_MARKNUM_FOLDERMIDTAIL);
- break;
- case FoldStyle::BoxedFoldStyle:
- setFoldMarker(SC_MARKNUM_FOLDEROPEN, SC_MARK_BOXMINUS);
- setFoldMarker(SC_MARKNUM_FOLDER, SC_MARK_BOXPLUS);
- setFoldMarker(SC_MARKNUM_FOLDERSUB);
- setFoldMarker(SC_MARKNUM_FOLDERTAIL);
- setFoldMarker(SC_MARKNUM_FOLDEREND);
- setFoldMarker(SC_MARKNUM_FOLDEROPENMID);
- setFoldMarker(SC_MARKNUM_FOLDERMIDTAIL);
- break;
- case FoldStyle::CircledTreeFoldStyle:
- setFoldMarker(SC_MARKNUM_FOLDEROPEN, SC_MARK_CIRCLEMINUS);
- setFoldMarker(SC_MARKNUM_FOLDER, SC_MARK_CIRCLEPLUS);
- setFoldMarker(SC_MARKNUM_FOLDERSUB, SC_MARK_VLINE);
- setFoldMarker(SC_MARKNUM_FOLDERTAIL, SC_MARK_LCORNERCURVE);
- setFoldMarker(SC_MARKNUM_FOLDEREND, SC_MARK_CIRCLEPLUSCONNECTED);
- setFoldMarker(SC_MARKNUM_FOLDEROPENMID, SC_MARK_CIRCLEMINUSCONNECTED);
- setFoldMarker(SC_MARKNUM_FOLDERMIDTAIL, SC_MARK_TCORNERCURVE);
- break;
- case FoldStyle::BoxedTreeFoldStyle:
- setFoldMarker(SC_MARKNUM_FOLDEROPEN, SC_MARK_BOXMINUS);
- setFoldMarker(SC_MARKNUM_FOLDER, SC_MARK_BOXPLUS);
- setFoldMarker(SC_MARKNUM_FOLDERSUB, SC_MARK_VLINE);
- setFoldMarker(SC_MARKNUM_FOLDERTAIL, SC_MARK_LCORNER);
- setFoldMarker(SC_MARKNUM_FOLDEREND, SC_MARK_BOXPLUSCONNECTED);
- setFoldMarker(SC_MARKNUM_FOLDEROPENMID, SC_MARK_BOXMINUSCONNECTED);
- setFoldMarker(SC_MARKNUM_FOLDERMIDTAIL, SC_MARK_TCORNER);
- break;
- }
- SendScintilla(SCI_SETMARGINWIDTHN, margin, defaultFoldMarginWidth);
- }
- // Clear all current folds.
- void QsciScintilla::clearFolds()
- {
- recolor();
- int maxLine = SendScintilla(SCI_GETLINECOUNT);
- for (int line = 0; line < maxLine; line++)
- {
- int level = SendScintilla(SCI_GETFOLDLEVEL, line);
- if (level & SC_FOLDLEVELHEADERFLAG)
- {
- SendScintilla(SCI_SETFOLDEXPANDED, line, 1);
- foldExpand(line, true, false, 0, level);
- line--;
- }
- }
- }
- // Set up a folder marker.
- void QsciScintilla::setFoldMarker(int marknr, int mark)
- {
- SendScintilla(SCI_MARKERDEFINE, marknr, mark);
- if (mark != SC_MARK_EMPTY)
- {
- SendScintilla(SCI_MARKERSETFORE, marknr, QColor(Qt::white));
- SendScintilla(SCI_MARKERSETBACK, marknr, QColor(Qt::black));
- }
- }
- // Handle a click in the fold margin. This is mostly taken from SciTE.
- void QsciScintilla::foldClick(int lineClick, int bstate)
- {
- bool shift = bstate & Qt::ShiftModifier;
- bool ctrl = bstate & Qt::ControlModifier;
- if (shift && ctrl)
- {
- foldAll();
- return;
- }
- int levelClick = SendScintilla(SCI_GETFOLDLEVEL, lineClick);
- if (levelClick & SC_FOLDLEVELHEADERFLAG)
- {
- if (shift)
- {
- // Ensure all children are visible.
- SendScintilla(SCI_SETFOLDEXPANDED, lineClick, 1);
- foldExpand(lineClick, true, true, 100, levelClick);
- }
- else if (ctrl)
- {
- if (SendScintilla(SCI_GETFOLDEXPANDED, lineClick))
- {
- // Contract this line and all its children.
- SendScintilla(SCI_SETFOLDEXPANDED, lineClick, 0L);
- foldExpand(lineClick, false, true, 0, levelClick);
- }
- else
- {
- // Expand this line and all its children.
- SendScintilla(SCI_SETFOLDEXPANDED, lineClick, 1);
- foldExpand(lineClick, true, true, 100, levelClick);
- }
- }
- else
- {
- // Toggle this line.
- SendScintilla(SCI_TOGGLEFOLD, lineClick);
- }
- }
- }
- // Do the hard work of hiding and showing lines. This is mostly taken from
- // SciTE.
- void QsciScintilla::foldExpand(int &line, bool doExpand, bool force,
- int visLevels, int level)
- {
- int lineMaxSubord = SendScintilla(SCI_GETLASTCHILD, line,
- level & SC_FOLDLEVELNUMBERMASK);
- line++;
- while (line <= lineMaxSubord)
- {
- if (force)
- {
- if (visLevels > 0)
- SendScintilla(SCI_SHOWLINES, line, line);
- else
- SendScintilla(SCI_HIDELINES, line, line);
- }
- else if (doExpand)
- SendScintilla(SCI_SHOWLINES, line, line);
- int levelLine = level;
- if (levelLine == -1)
- levelLine = SendScintilla(SCI_GETFOLDLEVEL, line);
- if (levelLine & SC_FOLDLEVELHEADERFLAG)
- {
- if (force)
- {
- if (visLevels > 1)
- SendScintilla(SCI_SETFOLDEXPANDED, line, 1);
- else
- SendScintilla(SCI_SETFOLDEXPANDED, line, 0L);
- foldExpand(line, doExpand, force, visLevels - 1);
- }
- else if (doExpand)
- {
- if (!SendScintilla(SCI_GETFOLDEXPANDED, line))
- SendScintilla(SCI_SETFOLDEXPANDED, line, 1);
- foldExpand(line, true, force, visLevels - 1);
- }
- else
- foldExpand(line, false, force, visLevels - 1);
- }
- else
- line++;
- }
- }
- // Fully expand (if there is any line currently folded) all text. Otherwise,
- // fold all text. This is mostly taken from SciTE.
- void QsciScintilla::foldAll(bool children)
- {
- recolor();
- int maxLine = SendScintilla(SCI_GETLINECOUNT);
- bool expanding = true;
- for (int lineSeek = 0; lineSeek < maxLine; lineSeek++)
- {
- if (SendScintilla(SCI_GETFOLDLEVEL,lineSeek) & SC_FOLDLEVELHEADERFLAG)
- {
- expanding = !SendScintilla(SCI_GETFOLDEXPANDED, lineSeek);
- break;
- }
- }
- for (int line = 0; line < maxLine; line++)
- {
- int level = SendScintilla(SCI_GETFOLDLEVEL, line);
- if (!(level & SC_FOLDLEVELHEADERFLAG))
- continue;
- if (children ||
- (SC_FOLDLEVELBASE == (level & SC_FOLDLEVELNUMBERMASK)))
- {
- if (expanding)
- {
- SendScintilla(SCI_SETFOLDEXPANDED, line, 1);
- foldExpand(line, true, false, 0, level);
- line--;
- }
- else
- {
- int lineMaxSubord = SendScintilla(SCI_GETLASTCHILD, line, -1);
- SendScintilla(SCI_SETFOLDEXPANDED, line, 0L);
- if (lineMaxSubord > line)
- SendScintilla(SCI_HIDELINES, line + 1, lineMaxSubord);
- }
- }
- }
- }
- // Handle a fold change. This is mostly taken from SciTE.
- void QsciScintilla::foldChanged(int line,int levelNow,int levelPrev)
- {
- if (levelNow & SC_FOLDLEVELHEADERFLAG)
- {
- if (!(levelPrev & SC_FOLDLEVELHEADERFLAG))
- SendScintilla(SCI_SETFOLDEXPANDED, line, 1);
- }
- else if (levelPrev & SC_FOLDLEVELHEADERFLAG)
- {
- if (!SendScintilla(SCI_GETFOLDEXPANDED, line))
- {
- // Removing the fold from one that has been contracted so should
- // expand. Otherwise lines are left invisible with no way to make
- // them visible.
- foldExpand(line, true, false, 0, levelPrev);
- }
- }
- }
- // Toggle the fold for a line if it contains a fold marker.
- void QsciScintilla::foldLine(int line)
- {
- SendScintilla(SCI_TOGGLEFOLD, line);
- }
- // Return the list of folded lines.
- QList<int> QsciScintilla::contractedFolds() const
- {
- QList<int> folds;
- int linenr = 0, fold_line;
- while ((fold_line = SendScintilla(SCI_CONTRACTEDFOLDNEXT, linenr)) >= 0)
- {
- folds.append(fold_line);
- linenr = fold_line + 1;
- }
- return folds;
- }
- // Set the fold state from a list.
- void QsciScintilla::setContractedFolds(const QList<int> &folds)
- {
- for (int i = 0; i < folds.count(); ++i)
- {
- int line = folds[i];
- int last_line = SendScintilla(SCI_GETLASTCHILD, line, -1);
- SendScintilla(SCI_SETFOLDEXPANDED, line, 0L);
- SendScintilla(SCI_HIDELINES, line + 1, last_line);
- }
- }
- // Handle the SCN_MODIFIED notification.
- void QsciScintilla::handleModified(int pos, int mtype, const char *text,
- int len, int added, int line, int foldNow, int foldPrev, int token,
- int annotationLinesAdded)
- {
- if (mtype & SC_MOD_CHANGEFOLD)
- {
- if (fold)
- foldChanged(line, foldNow, foldPrev);
- }
- if (mtype & (SC_MOD_INSERTTEXT | SC_MOD_DELETETEXT))
- {
- emit textChanged();
- if (added != 0)
- emit linesChanged();
- }
- }
- // Zoom in a number of points.
- void QsciScintilla::zoomIn(int range)
- {
- zoomTo(SendScintilla(SCI_GETZOOM) + range);
- }
- // Zoom in a single point.
- void QsciScintilla::zoomIn()
- {
- SendScintilla(SCI_ZOOMIN);
- }
- // Zoom out a number of points.
- void QsciScintilla::zoomOut(int range)
- {
- zoomTo(SendScintilla(SCI_GETZOOM) - range);
- }
- // Zoom out a single point.
- void QsciScintilla::zoomOut()
- {
- SendScintilla(SCI_ZOOMOUT);
- }
- // Set the zoom to a number of points.
- void QsciScintilla::zoomTo(int size)
- {
- if (size < -10)
- size = -10;
- else if (size > 20)
- size = 20;
- SendScintilla(SCI_SETZOOM, size);
- }
- // Find the first occurrence of a string.
- bool QsciScintilla::findFirst(const QString &expr, bool re, bool cs, bool wo,
- bool wrap, bool forward, int line, int index, bool show, bool posix)
- {
- if (expr.isEmpty())
- {
- findState.status = FindState::Idle;
- return false;
- }
- findState.status = FindState::Finding;
- findState.expr = expr;
- findState.wrap = wrap;
- findState.forward = forward;
- findState.flags =
- (cs ? SCFIND_MATCHCASE : 0) |
- (wo ? SCFIND_WHOLEWORD : 0) |
- (re ? SCFIND_REGEXP : 0) |
- (posix ? SCFIND_POSIX : 0);
- if (line < 0 || index < 0)
- findState.startpos = SendScintilla(SCI_GETCURRENTPOS);
- else
- findState.startpos = positionFromLineIndex(line, index);
- if (forward)
- findState.endpos = SendScintilla(SCI_GETLENGTH);
- else
- findState.endpos = 0;
- findState.show = show;
- return doFind();
- }
- // Find the first occurrence of a string in the current selection.
- bool QsciScintilla::findFirstInSelection(const QString &expr, bool re, bool cs,
- bool wo, bool forward, bool show, bool posix)
- {
- if (expr.isEmpty())
- {
- findState.status = FindState::Idle;
- return false;
- }
- findState.status = FindState::FindingInSelection;
- findState.expr = expr;
- findState.wrap = false;
- findState.forward = forward;
- findState.flags =
- (cs ? SCFIND_MATCHCASE : 0) |
- (wo ? SCFIND_WHOLEWORD : 0) |
- (re ? SCFIND_REGEXP : 0) |
- (posix ? SCFIND_POSIX : 0);
- findState.startpos_orig = SendScintilla(SCI_GETSELECTIONSTART);
- findState.endpos_orig = SendScintilla(SCI_GETSELECTIONEND);
- if (forward)
- {
- findState.startpos = findState.startpos_orig;
- findState.endpos = findState.endpos_orig;
- }
- else
- {
- findState.startpos = findState.endpos_orig;
- findState.endpos = findState.startpos_orig;
- }
- findState.show = show;
- return doFind();
- }
- // Find the next occurrence of a string.
- bool QsciScintilla::findNext()
- {
- if (findState.status == FindState::Idle)
- return false;
- return doFind();
- }
- // Do the hard work of the find methods.
- bool QsciScintilla::doFind()
- {
- SendScintilla(SCI_SETSEARCHFLAGS, findState.flags);
- int pos = simpleFind();
- // See if it was found. If not and wraparound is wanted, try again.
- if (pos == -1 && findState.wrap)
- {
- if (findState.forward)
- {
- findState.startpos = 0;
- findState.endpos = SendScintilla(SCI_GETLENGTH);
- }
- else
- {
- findState.startpos = SendScintilla(SCI_GETLENGTH);
- findState.endpos = 0;
- }
- pos = simpleFind();
- }
- if (pos == -1)
- {
- // Restore the original selection.
- if (findState.status == FindState::FindingInSelection)
- SendScintilla(SCI_SETSEL, findState.startpos_orig,
- findState.endpos_orig);
- findState.status = FindState::Idle;
- return false;
- }
- // It was found.
- long targstart = SendScintilla(SCI_GETTARGETSTART);
- long targend = SendScintilla(SCI_GETTARGETEND);
- // Ensure the text found is visible if required.
- if (findState.show)
- {
- int startLine = SendScintilla(SCI_LINEFROMPOSITION, targstart);
- int endLine = SendScintilla(SCI_LINEFROMPOSITION, targend);
- for (int i = startLine; i <= endLine; ++i)
- SendScintilla(SCI_ENSUREVISIBLEENFORCEPOLICY, i);
- }
- // Now set the selection.
- SendScintilla(SCI_SETSEL, targstart, targend);
- // Finally adjust the start position so that we don't find the same one
- // again.
- if (findState.forward)
- findState.startpos = targend;
- else if ((findState.startpos = targstart - 1) < 0)
- findState.startpos = 0;
- return true;
- }
- // Do a simple find between the start and end positions.
- int QsciScintilla::simpleFind()
- {
- if (findState.startpos == findState.endpos)
- return -1;
- SendScintilla(SCI_SETTARGETSTART, findState.startpos);
- SendScintilla(SCI_SETTARGETEND, findState.endpos);
- ScintillaBytes s = textAsBytes(findState.expr);
- return SendScintilla(SCI_SEARCHINTARGET, s.length(),
- ScintillaBytesConstData(s));
- }
- // Replace the text found with the previous find method.
- void QsciScintilla::replace(const QString &replaceStr)
- {
- if (findState.status == FindState::Idle)
- return;
- long start = SendScintilla(SCI_GETSELECTIONSTART);
- long orig_len = SendScintilla(SCI_GETSELECTIONEND) - start;
- SendScintilla(SCI_TARGETFROMSELECTION);
- int cmd = (findState.flags & SCFIND_REGEXP) ? SCI_REPLACETARGETRE : SCI_REPLACETARGET;
- ScintillaBytes s = textAsBytes(replaceStr);
- long len = SendScintilla(cmd, -1, ScintillaBytesConstData(s));
- // Reset the selection.
- SendScintilla(SCI_SETSELECTIONSTART, start);
- SendScintilla(SCI_SETSELECTIONEND, start + len);
- // Fix the original selection.
- findState.endpos_orig += (len - orig_len);
- if (findState.forward)
- findState.startpos = start + len;
- }
- // Query the modified state.
- bool QsciScintilla::isModified() const
- {
- return doc.isModified();
- }
- // Set the modified state.
- void QsciScintilla::setModified(bool m)
- {
- if (!m)
- SendScintilla(SCI_SETSAVEPOINT);
- }
- // Handle the SCN_INDICATORCLICK notification.
- void QsciScintilla::handleIndicatorClick(int pos, int modifiers)
- {
- int state = mapModifiers(modifiers);
- int line, index;
- lineIndexFromPosition(pos, &line, &index);
- emit indicatorClicked(line, index, Qt::KeyboardModifiers(state));
- }
- // Handle the SCN_INDICATORRELEASE notification.
- void QsciScintilla::handleIndicatorRelease(int pos, int modifiers)
- {
- int state = mapModifiers(modifiers);
- int line, index;
- lineIndexFromPosition(pos, &line, &index);
- emit indicatorReleased(line, index, Qt::KeyboardModifiers(state));
- }
- // Handle the SCN_MARGINCLICK notification.
- void QsciScintilla::handleMarginClick(int pos, int modifiers, int margin)
- {
- int state = mapModifiers(modifiers);
- int line = SendScintilla(SCI_LINEFROMPOSITION, pos);
- if (fold && margin == foldmargin)
- foldClick(line, state);
- else
- emit marginClicked(margin, line, Qt::KeyboardModifiers(state));
- }
- // Handle the SCN_MARGINRIGHTCLICK notification.
- void QsciScintilla::handleMarginRightClick(int pos, int modifiers, int margin)
- {
- int state = mapModifiers(modifiers);
- int line = SendScintilla(SCI_LINEFROMPOSITION, pos);
- emit marginRightClicked(margin, line, Qt::KeyboardModifiers(state));
- }
- // Handle the SCN_SAVEPOINTREACHED notification.
- void QsciScintilla::handleSavePointReached()
- {
- doc.setModified(false);
- emit modificationChanged(false);
- }
- // Handle the SCN_SAVEPOINTLEFT notification.
- void QsciScintilla::handleSavePointLeft()
- {
- doc.setModified(true);
- emit modificationChanged(true);
- }
- // Handle the QSCN_SELCHANGED signal.
- void QsciScintilla::handleSelectionChanged(bool yes)
- {
- selText = yes;
- emit copyAvailable(yes);
- emit selectionChanged();
- }
- // Get the current selection.
- void QsciScintilla::getSelection(int *lineFrom, int *indexFrom, int *lineTo,
- int *indexTo) const
- {
- if (selText)
- {
- lineIndexFromPosition(SendScintilla(SCI_GETSELECTIONSTART), lineFrom,
- indexFrom);
- lineIndexFromPosition(SendScintilla(SCI_GETSELECTIONEND), lineTo,
- indexTo);
- }
- else
- *lineFrom = *indexFrom = *lineTo = *indexTo = -1;
- }
- // Sets the current selection.
- void QsciScintilla::setSelection(int lineFrom, int indexFrom, int lineTo,
- int indexTo)
- {
- SendScintilla(SCI_SETSEL, positionFromLineIndex(lineFrom, indexFrom),
- positionFromLineIndex(lineTo, indexTo));
- }
- // Set the background colour of selected text.
- void QsciScintilla::setSelectionBackgroundColor(const QColor &col)
- {
- int alpha = col.alpha();
- if (alpha == 255)
- alpha = SC_ALPHA_NOALPHA;
- SendScintilla(SCI_SETSELBACK, 1, col);
- SendScintilla(SCI_SETSELALPHA, alpha);
- }
- // Set the foreground colour of selected text.
- void QsciScintilla::setSelectionForegroundColor(const QColor &col)
- {
- SendScintilla(SCI_SETSELFORE, 1, col);
- }
- // Reset the background colour of selected text to the default.
- void QsciScintilla::resetSelectionBackgroundColor()
- {
- SendScintilla(SCI_SETSELALPHA, SC_ALPHA_NOALPHA);
- SendScintilla(SCI_SETSELBACK, 0UL);
- }
- // Reset the foreground colour of selected text to the default.
- void QsciScintilla::resetSelectionForegroundColor()
- {
- SendScintilla(SCI_SETSELFORE, 0UL);
- }
- // Set the fill to the end-of-line for the selection.
- void QsciScintilla::setSelectionToEol(bool filled)
- {
- SendScintilla(SCI_SETSELEOLFILLED, filled);
- }
- // Return the fill to the end-of-line for the selection.
- bool QsciScintilla::selectionToEol() const
- {
- return SendScintilla(SCI_GETSELEOLFILLED);
- }
- // Set the width of the caret.
- void QsciScintilla::setCaretWidth(int width)
- {
- SendScintilla(SCI_SETCARETWIDTH, width);
- }
- // Set the foreground colour of the caret.
- void QsciScintilla::setCaretForegroundColor(const QColor &col)
- {
- SendScintilla(SCI_SETCARETFORE, col);
- }
- // Set the background colour of the line containing the caret.
- void QsciScintilla::setCaretLineBackgroundColor(const QColor &col)
- {
- int alpha = col.alpha();
- if (alpha == 255)
- alpha = SC_ALPHA_NOALPHA;
- SendScintilla(SCI_SETCARETLINEBACK, col);
- SendScintilla(SCI_SETCARETLINEBACKALPHA, alpha);
- }
- // Set the state of the background colour of the line containing the caret.
- void QsciScintilla::setCaretLineVisible(bool enable)
- {
- SendScintilla(SCI_SETCARETLINEVISIBLE, enable);
- }
- // Set the background colour of a hotspot area.
- void QsciScintilla::setHotspotBackgroundColor(const QColor &col)
- {
- SendScintilla(SCI_SETSELBACK, 1, col);
- }
- // Set the foreground colour of a hotspot area.
- void QsciScintilla::setHotspotForegroundColor(const QColor &col)
- {
- SendScintilla(SCI_SETHOTSPOTACTIVEFORE, 1, col);
- }
- // Reset the background colour of a hotspot area to the default.
- void QsciScintilla::resetHotspotBackgroundColor()
- {
- SendScintilla(SCI_SETSELBACK, 0UL);
- }
- // Reset the foreground colour of a hotspot area to the default.
- void QsciScintilla::resetHotspotForegroundColor()
- {
- SendScintilla(SCI_SETHOTSPOTACTIVEFORE, 0UL);
- }
- // Set the underline of a hotspot area.
- void QsciScintilla::setHotspotUnderline(bool enable)
- {
- SendScintilla(SCI_SETHOTSPOTACTIVEUNDERLINE, enable);
- }
- // Set the wrapping of a hotspot area.
- void QsciScintilla::setHotspotWrap(bool enable)
- {
- SendScintilla(SCI_SETHOTSPOTSINGLELINE, !enable);
- }
- // Query the read-only state.
- bool QsciScintilla::isReadOnly() const
- {
- return SendScintilla(SCI_GETREADONLY);
- }
- // Set the read-only state.
- void QsciScintilla::setReadOnly(bool ro)
- {
- setAttribute(Qt::WA_InputMethodEnabled, !ro);
- SendScintilla(SCI_SETREADONLY, ro);
- }
- // Append the given text.
- void QsciScintilla::append(const QString &text)
- {
- bool ro = ensureRW();
- ScintillaBytes s = textAsBytes(text);
- SendScintilla(SCI_APPENDTEXT, s.length(), ScintillaBytesConstData(s));
- SendScintilla(SCI_EMPTYUNDOBUFFER);
- setReadOnly(ro);
- }
- // Insert the given text at the current position.
- void QsciScintilla::insert(const QString &text)
- {
- insertAtPos(text, -1);
- }
- // Insert the given text at the given line and offset.
- void QsciScintilla::insertAt(const QString &text, int line, int index)
- {
- insertAtPos(text, positionFromLineIndex(line, index));
- }
- // Insert the given text at the given position.
- void QsciScintilla::insertAtPos(const QString &text, int pos)
- {
- bool ro = ensureRW();
- SendScintilla(SCI_BEGINUNDOACTION);
- SendScintilla(SCI_INSERTTEXT, pos,
- ScintillaBytesConstData(textAsBytes(text)));
- SendScintilla(SCI_ENDUNDOACTION);
- setReadOnly(ro);
- }
- // Begin a sequence of undoable actions.
- void QsciScintilla::beginUndoAction()
- {
- SendScintilla(SCI_BEGINUNDOACTION);
- }
- // End a sequence of undoable actions.
- void QsciScintilla::endUndoAction()
- {
- SendScintilla(SCI_ENDUNDOACTION);
- }
- // Redo a sequence of actions.
- void QsciScintilla::redo()
- {
- SendScintilla(SCI_REDO);
- }
- // Undo a sequence of actions.
- void QsciScintilla::undo()
- {
- SendScintilla(SCI_UNDO);
- }
- // See if there is something to redo.
- bool QsciScintilla::isRedoAvailable() const
- {
- return SendScintilla(SCI_CANREDO);
- }
- // See if there is something to undo.
- bool QsciScintilla::isUndoAvailable() const
- {
- return SendScintilla(SCI_CANUNDO);
- }
- // Return the number of lines.
- int QsciScintilla::lines() const
- {
- return SendScintilla(SCI_GETLINECOUNT);
- }
- // Return the line at a position.
- int QsciScintilla::lineAt(const QPoint &pos) const
- {
- long chpos = SendScintilla(SCI_POSITIONFROMPOINTCLOSE, pos.x(), pos.y());
- if (chpos < 0)
- return -1;
- return SendScintilla(SCI_LINEFROMPOSITION, chpos);
- }
- // Return the length of a line.
- int QsciScintilla::lineLength(int line) const
- {
- if (line < 0 || line >= SendScintilla(SCI_GETLINECOUNT))
- return -1;
- return SendScintilla(SCI_LINELENGTH, line);
- }
- // Return the length of the current text.
- int QsciScintilla::length() const
- {
- return SendScintilla(SCI_GETTEXTLENGTH);
- }
- // Remove any selected text.
- void QsciScintilla::removeSelectedText()
- {
- SendScintilla(SCI_REPLACESEL, "");
- }
- // Replace any selected text.
- void QsciScintilla::replaceSelectedText(const QString &text)
- {
- SendScintilla(SCI_REPLACESEL, ScintillaBytesConstData(textAsBytes(text)));
- }
- // Return the current selected text.
- QString QsciScintilla::selectedText() const
- {
- if (!selText)
- return QString();
- char *buf = new char[SendScintilla(SCI_GETSELECTIONEND) - SendScintilla(SCI_GETSELECTIONSTART) + 1];
- SendScintilla(SCI_GETSELTEXT, buf);
- QString qs = bytesAsText(buf);
- delete[] buf;
- return qs;
- }
- // Return the current text.
- QString QsciScintilla::text() const
- {
- int buflen = length() + 1;
- char *buf = new char[buflen];
- SendScintilla(SCI_GETTEXT, buflen, buf);
- QString qs = bytesAsText(buf);
- delete[] buf;
- return qs;
- }
- // Return the text of a line.
- QString QsciScintilla::text(int line) const
- {
- int line_len = lineLength(line);
- if (line_len < 1)
- return QString();
- char *buf = new char[line_len + 1];
- SendScintilla(SCI_GETLINE, line, buf);
- buf[line_len] = '\0';
- QString qs = bytesAsText(buf);
- delete[] buf;
- return qs;
- }
- // Return the text between two positions.
- QString QsciScintilla::text(int start, int end) const
- {
- char *buf = new char[end - start + 1];
- SendScintilla(SCI_GETTEXTRANGE, start, end, buf);
- QString text = bytesAsText(buf);
- delete[] buf;
- return text;
- }
- // Return the text as encoded bytes between two positions.
- QByteArray QsciScintilla::bytes(int start, int end) const
- {
- QByteArray bytes(end - start + 1, '\0');
- SendScintilla(SCI_GETTEXTRANGE, start, end, bytes.data());
- return bytes;
- }
- // Set the given text.
- void QsciScintilla::setText(const QString &text)
- {
- bool ro = ensureRW();
- SendScintilla(SCI_SETTEXT, ScintillaBytesConstData(textAsBytes(text)));
- SendScintilla(SCI_EMPTYUNDOBUFFER);
- setReadOnly(ro);
- }
- // Get the cursor position
- void QsciScintilla::getCursorPosition(int *line, int *index) const
- {
- lineIndexFromPosition(SendScintilla(SCI_GETCURRENTPOS), line, index);
- }
- // Set the cursor position
- void QsciScintilla::setCursorPosition(int line, int index)
- {
- SendScintilla(SCI_GOTOPOS, positionFromLineIndex(line, index));
- }
- // Ensure the cursor is visible.
- void QsciScintilla::ensureCursorVisible()
- {
- SendScintilla(SCI_SCROLLCARET);
- }
- // Ensure a line is visible.
- void QsciScintilla::ensureLineVisible(int line)
- {
- SendScintilla(SCI_ENSUREVISIBLEENFORCEPOLICY, line);
- }
- // Copy text to the clipboard.
- void QsciScintilla::copy()
- {
- SendScintilla(SCI_COPY);
- }
- // Cut text to the clipboard.
- void QsciScintilla::cut()
- {
- SendScintilla(SCI_CUT);
- }
- // Paste text from the clipboard.
- void QsciScintilla::paste()
- {
- SendScintilla(SCI_PASTE);
- }
- // Select all text, or deselect any selected text.
- void QsciScintilla::selectAll(bool select)
- {
- if (select)
- SendScintilla(SCI_SELECTALL);
- else
- SendScintilla(SCI_SETANCHOR, SendScintilla(SCI_GETCURRENTPOS));
- }
- // Delete all text.
- void QsciScintilla::clear()
- {
- bool ro = ensureRW();
- SendScintilla(SCI_BEGINUNDOACTION);
- SendScintilla(SCI_CLEARALL);
- SendScintilla(SCI_ENDUNDOACTION);
- setReadOnly(ro);
- }
- // Return the indentation of a line.
- int QsciScintilla::indentation(int line) const
- {
- return SendScintilla(SCI_GETLINEINDENTATION, line);
- }
- // Set the indentation of a line.
- void QsciScintilla::setIndentation(int line, int indentation)
- {
- SendScintilla(SCI_BEGINUNDOACTION);
- SendScintilla(SCI_SETLINEINDENTATION, line, indentation);
- SendScintilla(SCI_ENDUNDOACTION);
- }
- // Indent a line.
- void QsciScintilla::indent(int line)
- {
- setIndentation(line, indentation(line) + indentWidth());
- }
- // Unindent a line.
- void QsciScintilla::unindent(int line)
- {
- int newIndent = indentation(line) - indentWidth();
- if (newIndent < 0)
- newIndent = 0;
- setIndentation(line, newIndent);
- }
- // Return the indentation of the current line.
- int QsciScintilla::currentIndent() const
- {
- return indentation(SendScintilla(SCI_LINEFROMPOSITION,
- SendScintilla(SCI_GETCURRENTPOS)));
- }
- // Return the current indentation width.
- int QsciScintilla::indentWidth() const
- {
- int w = indentationWidth();
- if (w == 0)
- w = tabWidth();
- return w;
- }
- // Return the state of indentation guides.
- bool QsciScintilla::indentationGuides() const
- {
- return (SendScintilla(SCI_GETINDENTATIONGUIDES) != SC_IV_NONE);
- }
- // Enable and disable indentation guides.
- void QsciScintilla::setIndentationGuides(bool enable)
- {
- int iv;
- if (!enable)
- iv = SC_IV_NONE;
- else if (lex.isNull())
- iv = SC_IV_REAL;
- else
- iv = lex->indentationGuideView();
- SendScintilla(SCI_SETINDENTATIONGUIDES, iv);
- }
- // Set the background colour of indentation guides.
- void QsciScintilla::setIndentationGuidesBackgroundColor(const QColor &col)
- {
- SendScintilla(SCI_STYLESETBACK, STYLE_INDENTGUIDE, col);
- }
- // Set the foreground colour of indentation guides.
- void QsciScintilla::setIndentationGuidesForegroundColor(const QColor &col)
- {
- SendScintilla(SCI_STYLESETFORE, STYLE_INDENTGUIDE, col);
- }
- // Return the indentation width.
- int QsciScintilla::indentationWidth() const
- {
- return SendScintilla(SCI_GETINDENT);
- }
- // Set the indentation width.
- void QsciScintilla::setIndentationWidth(int width)
- {
- SendScintilla(SCI_SETINDENT, width);
- }
- // Return the tab width.
- int QsciScintilla::tabWidth() const
- {
- return SendScintilla(SCI_GETTABWIDTH);
- }
- // Set the tab width.
- void QsciScintilla::setTabWidth(int width)
- {
- SendScintilla(SCI_SETTABWIDTH, width);
- }
- // Return the effect of the backspace key.
- bool QsciScintilla::backspaceUnindents() const
- {
- return SendScintilla(SCI_GETBACKSPACEUNINDENTS);
- }
- // Set the effect of the backspace key.
- void QsciScintilla::setBackspaceUnindents(bool unindents)
- {
- SendScintilla(SCI_SETBACKSPACEUNINDENTS, unindents);
- }
- // Return the effect of the tab key.
- bool QsciScintilla::tabIndents() const
- {
- return SendScintilla(SCI_GETTABINDENTS);
- }
- // Set the effect of the tab key.
- void QsciScintilla::setTabIndents(bool indents)
- {
- SendScintilla(SCI_SETTABINDENTS, indents);
- }
- // Return the indentation use of tabs.
- bool QsciScintilla::indentationsUseTabs() const
- {
- return SendScintilla(SCI_GETUSETABS);
- }
- // Set the indentation use of tabs.
- void QsciScintilla::setIndentationsUseTabs(bool tabs)
- {
- SendScintilla(SCI_SETUSETABS, tabs);
- }
- // Return the number of margins.
- int QsciScintilla::margins() const
- {
- return SendScintilla(SCI_GETMARGINS);
- }
- // Set the number of margins.
- void QsciScintilla::setMargins(int margins)
- {
- SendScintilla(SCI_SETMARGINS, margins);
- }
- // Return the margin background colour.
- QColor QsciScintilla::marginBackgroundColor(int margin) const
- {
- return asQColor(SendScintilla(SCI_GETMARGINBACKN, margin));
- }
- // Set the margin background colour.
- void QsciScintilla::setMarginBackgroundColor(int margin, const QColor &col)
- {
- SendScintilla(SCI_SETMARGINBACKN, margin, col);
- }
- // Return the margin options.
- int QsciScintilla::marginOptions() const
- {
- return SendScintilla(SCI_GETMARGINOPTIONS);
- }
- // Set the margin options.
- void QsciScintilla::setMarginOptions(int options)
- {
- SendScintilla(SCI_SETMARGINOPTIONS, options);
- }
- // Return the margin type.
- QsciScintilla::MarginType QsciScintilla::marginType(int margin) const
- {
- return (MarginType)SendScintilla(SCI_GETMARGINTYPEN, margin);
- }
- // Set the margin type.
- void QsciScintilla::setMarginType(int margin, MarginType type)
- {
- SendScintilla(SCI_SETMARGINTYPEN, margin, type);
- }
- // Clear margin text.
- void QsciScintilla::clearMarginText(int line)
- {
- if (line < 0)
- SendScintilla(SCI_MARGINTEXTCLEARALL);
- else
- SendScintilla(SCI_MARGINSETTEXT, line, (const char *)0);
- }
- // Annotate a line.
- void QsciScintilla::setMarginText(int line, const QString &text, int style)
- {
- int style_offset = SendScintilla(SCI_MARGINGETSTYLEOFFSET);
- SendScintilla(SCI_MARGINSETTEXT, line,
- ScintillaBytesConstData(textAsBytes(text)));
- SendScintilla(SCI_MARGINSETSTYLE, line, style - style_offset);
- }
- // Annotate a line.
- void QsciScintilla::setMarginText(int line, const QString &text, const QsciStyle &style)
- {
- style.apply(this);
- setMarginText(line, text, style.style());
- }
- // Annotate a line.
- void QsciScintilla::setMarginText(int line, const QsciStyledText &text)
- {
- text.apply(this);
- setMarginText(line, text.text(), text.style());
- }
- // Annotate a line.
- void QsciScintilla::setMarginText(int line, const QList<QsciStyledText> &text)
- {
- char *styles;
- ScintillaBytes styled_text = styleText(text, &styles,
- SendScintilla(SCI_MARGINGETSTYLEOFFSET));
- SendScintilla(SCI_MARGINSETTEXT, line,
- ScintillaBytesConstData(styled_text));
- SendScintilla(SCI_MARGINSETSTYLES, line, styles);
- delete[] styles;
- }
- // Return the state of line numbers in a margin.
- bool QsciScintilla::marginLineNumbers(int margin) const
- {
- return SendScintilla(SCI_GETMARGINTYPEN, margin);
- }
- // Enable and disable line numbers in a margin.
- void QsciScintilla::setMarginLineNumbers(int margin, bool lnrs)
- {
- SendScintilla(SCI_SETMARGINTYPEN, margin,
- lnrs ? SC_MARGIN_NUMBER : SC_MARGIN_SYMBOL);
- }
- // Return the marker mask of a margin.
- int QsciScintilla::marginMarkerMask(int margin) const
- {
- return SendScintilla(SCI_GETMARGINMASKN, margin);
- }
- // Set the marker mask of a margin.
- void QsciScintilla::setMarginMarkerMask(int margin,int mask)
- {
- SendScintilla(SCI_SETMARGINMASKN, margin, mask);
- }
- // Return the state of a margin's sensitivity.
- bool QsciScintilla::marginSensitivity(int margin) const
- {
- return SendScintilla(SCI_GETMARGINSENSITIVEN, margin);
- }
- // Enable and disable a margin's sensitivity.
- void QsciScintilla::setMarginSensitivity(int margin,bool sens)
- {
- SendScintilla(SCI_SETMARGINSENSITIVEN, margin, sens);
- }
- // Return the width of a margin.
- int QsciScintilla::marginWidth(int margin) const
- {
- return SendScintilla(SCI_GETMARGINWIDTHN, margin);
- }
- // Set the width of a margin.
- void QsciScintilla::setMarginWidth(int margin, int width)
- {
- SendScintilla(SCI_SETMARGINWIDTHN, margin, width);
- }
- // Set the width of a margin to the width of some text.
- void QsciScintilla::setMarginWidth(int margin, const QString &s)
- {
- int width = SendScintilla(SCI_TEXTWIDTH, STYLE_LINENUMBER,
- ScintillaBytesConstData(textAsBytes(s)));
- setMarginWidth(margin, width);
- }
- // Set the background colour of all margins.
- void QsciScintilla::setMarginsBackgroundColor(const QColor &col)
- {
- handleStylePaperChange(col, STYLE_LINENUMBER);
- }
- // Set the foreground colour of all margins.
- void QsciScintilla::setMarginsForegroundColor(const QColor &col)
- {
- handleStyleColorChange(col, STYLE_LINENUMBER);
- }
- // Set the font of all margins.
- void QsciScintilla::setMarginsFont(const QFont &f)
- {
- setStylesFont(f, STYLE_LINENUMBER);
- }
- // Define an indicator.
- int QsciScintilla::indicatorDefine(IndicatorStyle style, int indicatorNumber)
- {
- checkIndicator(indicatorNumber);
- if (indicatorNumber >= 0)
- SendScintilla(SCI_INDICSETSTYLE, indicatorNumber,
- static_cast<long>(style));
- return indicatorNumber;
- }
- // Return the state of an indicator being drawn under the text.
- bool QsciScintilla::indicatorDrawUnder(int indicatorNumber) const
- {
- if (indicatorNumber < 0 || indicatorNumber >= INDIC_IME)
- return false;
- return SendScintilla(SCI_INDICGETUNDER, indicatorNumber);
- }
- // Set the state of indicators being drawn under the text.
- void QsciScintilla::setIndicatorDrawUnder(bool under, int indicatorNumber)
- {
- if (indicatorNumber < INDIC_IME)
- {
- // We ignore allocatedIndicators to allow any indicators defined
- // elsewhere (e.g. in lexers) to be set.
- if (indicatorNumber < 0)
- {
- for (int i = 0; i < INDIC_IME; ++i)
- SendScintilla(SCI_INDICSETUNDER, i, under);
- }
- else
- {
- SendScintilla(SCI_INDICSETUNDER, indicatorNumber, under);
- }
- }
- }
- // Set the indicator foreground colour.
- void QsciScintilla::setIndicatorForegroundColor(const QColor &col,
- int indicatorNumber)
- {
- if (indicatorNumber < INDIC_IME)
- {
- int alpha = col.alpha();
- // We ignore allocatedIndicators to allow any indicators defined
- // elsewhere (e.g. in lexers) to be set.
- if (indicatorNumber < 0)
- {
- for (int i = 0; i < INDIC_IME; ++i)
- {
- SendScintilla(SCI_INDICSETFORE, i, col);
- SendScintilla(SCI_INDICSETALPHA, i, alpha);
- }
- }
- else
- {
- SendScintilla(SCI_INDICSETFORE, indicatorNumber, col);
- SendScintilla(SCI_INDICSETALPHA, indicatorNumber, alpha);
- }
- }
- }
- // Set the indicator hover foreground colour.
- void QsciScintilla::setIndicatorHoverForegroundColor(const QColor &col,
- int indicatorNumber)
- {
- if (indicatorNumber < INDIC_IME)
- {
- // We ignore allocatedIndicators to allow any indicators defined
- // elsewhere (e.g. in lexers) to be set.
- if (indicatorNumber < 0)
- {
- for (int i = 0; i < INDIC_IME; ++i)
- SendScintilla(SCI_INDICSETHOVERFORE, i, col);
- }
- else
- {
- SendScintilla(SCI_INDICSETHOVERFORE, indicatorNumber, col);
- }
- }
- }
- // Set the indicator hover style.
- void QsciScintilla::setIndicatorHoverStyle(IndicatorStyle style,
- int indicatorNumber)
- {
- if (indicatorNumber < INDIC_IME)
- {
- // We ignore allocatedIndicators to allow any indicators defined
- // elsewhere (e.g. in lexers) to be set.
- if (indicatorNumber < 0)
- {
- for (int i = 0; i < INDIC_IME; ++i)
- SendScintilla(SCI_INDICSETHOVERSTYLE, i,
- static_cast<long>(style));
- }
- else
- {
- SendScintilla(SCI_INDICSETHOVERSTYLE, indicatorNumber,
- static_cast<long>(style));
- }
- }
- }
- // Set the indicator outline colour.
- void QsciScintilla::setIndicatorOutlineColor(const QColor &col, int indicatorNumber)
- {
- if (indicatorNumber < INDIC_IME)
- {
- int alpha = col.alpha();
- // We ignore allocatedIndicators to allow any indicators defined
- // elsewhere (e.g. in lexers) to be set.
- if (indicatorNumber < 0)
- {
- for (int i = 0; i < INDIC_IME; ++i)
- SendScintilla(SCI_INDICSETOUTLINEALPHA, i, alpha);
- }
- else
- {
- SendScintilla(SCI_INDICSETOUTLINEALPHA, indicatorNumber, alpha);
- }
- }
- }
- // Fill a range with an indicator.
- void QsciScintilla::fillIndicatorRange(int lineFrom, int indexFrom,
- int lineTo, int indexTo, int indicatorNumber)
- {
- if (indicatorNumber < INDIC_IME)
- {
- int start = positionFromLineIndex(lineFrom, indexFrom);
- int finish = positionFromLineIndex(lineTo, indexTo);
- // We ignore allocatedIndicators to allow any indicators defined
- // elsewhere (e.g. in lexers) to be set.
- if (indicatorNumber < 0)
- {
- for (int i = 0; i < INDIC_IME; ++i)
- {
- SendScintilla(SCI_SETINDICATORCURRENT, i);
- SendScintilla(SCI_INDICATORFILLRANGE, start, finish - start);
- }
- }
- else
- {
- SendScintilla(SCI_SETINDICATORCURRENT, indicatorNumber);
- SendScintilla(SCI_INDICATORFILLRANGE, start, finish - start);
- }
- }
- }
- // Clear a range with an indicator.
- void QsciScintilla::clearIndicatorRange(int lineFrom, int indexFrom,
- int lineTo, int indexTo, int indicatorNumber)
- {
- if (indicatorNumber < INDIC_IME)
- {
- int start = positionFromLineIndex(lineFrom, indexFrom);
- int finish = positionFromLineIndex(lineTo, indexTo);
- // We ignore allocatedIndicators to allow any indicators defined
- // elsewhere (e.g. in lexers) to be set.
- if (indicatorNumber < 0)
- {
- for (int i = 0; i < INDIC_IME; ++i)
- {
- SendScintilla(SCI_SETINDICATORCURRENT, i);
- SendScintilla(SCI_INDICATORCLEARRANGE, start, finish - start);
- }
- }
- else
- {
- SendScintilla(SCI_SETINDICATORCURRENT, indicatorNumber);
- SendScintilla(SCI_INDICATORCLEARRANGE, start, finish - start);
- }
- }
- }
- // Define a marker based on a symbol.
- int QsciScintilla::markerDefine(MarkerSymbol sym, int markerNumber)
- {
- checkMarker(markerNumber);
- if (markerNumber >= 0)
- SendScintilla(SCI_MARKERDEFINE, markerNumber, static_cast<long>(sym));
- return markerNumber;
- }
- // Define a marker based on a character.
- int QsciScintilla::markerDefine(char ch, int markerNumber)
- {
- checkMarker(markerNumber);
- if (markerNumber >= 0)
- SendScintilla(SCI_MARKERDEFINE, markerNumber,
- static_cast<long>(SC_MARK_CHARACTER) + ch);
- return markerNumber;
- }
- // Define a marker based on a QPixmap.
- int QsciScintilla::markerDefine(const QPixmap &pm, int markerNumber)
- {
- checkMarker(markerNumber);
- if (markerNumber >= 0)
- SendScintilla(SCI_MARKERDEFINEPIXMAP, markerNumber, pm);
- return markerNumber;
- }
- // Define a marker based on a QImage.
- int QsciScintilla::markerDefine(const QImage &im, int markerNumber)
- {
- checkMarker(markerNumber);
- if (markerNumber >= 0)
- {
- SendScintilla(SCI_RGBAIMAGESETHEIGHT, im.height());
- SendScintilla(SCI_RGBAIMAGESETWIDTH, im.width());
- SendScintilla(SCI_MARKERDEFINERGBAIMAGE, markerNumber, im);
- }
- return markerNumber;
- }
- // Add a marker to a line.
- int QsciScintilla::markerAdd(int linenr, int markerNumber)
- {
- if (markerNumber < 0 || markerNumber > MARKER_MAX || (allocatedMarkers & (1 << markerNumber)) == 0)
- return -1;
- return SendScintilla(SCI_MARKERADD, linenr, markerNumber);
- }
- // Get the marker mask for a line.
- unsigned QsciScintilla::markersAtLine(int linenr) const
- {
- return SendScintilla(SCI_MARKERGET, linenr);
- }
- // Delete a marker from a line.
- void QsciScintilla::markerDelete(int linenr, int markerNumber)
- {
- if (markerNumber <= MARKER_MAX)
- {
- if (markerNumber < 0)
- {
- unsigned am = allocatedMarkers;
- for (int m = 0; m <= MARKER_MAX; ++m)
- {
- if (am & 1)
- SendScintilla(SCI_MARKERDELETE, linenr, m);
- am >>= 1;
- }
- }
- else if (allocatedMarkers & (1 << markerNumber))
- SendScintilla(SCI_MARKERDELETE, linenr, markerNumber);
- }
- }
- // Delete a marker from the text.
- void QsciScintilla::markerDeleteAll(int markerNumber)
- {
- if (markerNumber <= MARKER_MAX)
- {
- if (markerNumber < 0)
- SendScintilla(SCI_MARKERDELETEALL, -1);
- else if (allocatedMarkers & (1 << markerNumber))
- SendScintilla(SCI_MARKERDELETEALL, markerNumber);
- }
- }
- // Delete a marker handle from the text.
- void QsciScintilla::markerDeleteHandle(int mhandle)
- {
- SendScintilla(SCI_MARKERDELETEHANDLE, mhandle);
- }
- // Return the line containing a marker instance.
- int QsciScintilla::markerLine(int mhandle) const
- {
- return SendScintilla(SCI_MARKERLINEFROMHANDLE, mhandle);
- }
- // Search forwards for a marker.
- int QsciScintilla::markerFindNext(int linenr, unsigned mask) const
- {
- return SendScintilla(SCI_MARKERNEXT, linenr, mask);
- }
- // Search backwards for a marker.
- int QsciScintilla::markerFindPrevious(int linenr, unsigned mask) const
- {
- return SendScintilla(SCI_MARKERPREVIOUS, linenr, mask);
- }
- // Set the marker background colour.
- void QsciScintilla::setMarkerBackgroundColor(const QColor &col, int markerNumber)
- {
- if (markerNumber <= MARKER_MAX)
- {
- int alpha = col.alpha();
- // An opaque background would make the text invisible.
- if (alpha == 255)
- alpha = SC_ALPHA_NOALPHA;
- if (markerNumber < 0)
- {
- unsigned am = allocatedMarkers;
- for (int m = 0; m <= MARKER_MAX; ++m)
- {
- if (am & 1)
- {
- SendScintilla(SCI_MARKERSETBACK, m, col);
- SendScintilla(SCI_MARKERSETALPHA, m, alpha);
- }
- am >>= 1;
- }
- }
- else if (allocatedMarkers & (1 << markerNumber))
- {
- SendScintilla(SCI_MARKERSETBACK, markerNumber, col);
- SendScintilla(SCI_MARKERSETALPHA, markerNumber, alpha);
- }
- }
- }
- // Set the marker foreground colour.
- void QsciScintilla::setMarkerForegroundColor(const QColor &col, int markerNumber)
- {
- if (markerNumber <= MARKER_MAX)
- {
- if (markerNumber < 0)
- {
- unsigned am = allocatedMarkers;
- for (int m = 0; m <= MARKER_MAX; ++m)
- {
- if (am & 1)
- SendScintilla(SCI_MARKERSETFORE, m, col);
- am >>= 1;
- }
- }
- else if (allocatedMarkers & (1 << markerNumber))
- {
- SendScintilla(SCI_MARKERSETFORE, markerNumber, col);
- }
- }
- }
- // Check a marker, allocating a marker number if necessary.
- void QsciScintilla::checkMarker(int &markerNumber)
- {
- allocateId(markerNumber, allocatedMarkers, 0, MARKER_MAX);
- }
- // Check an indicator, allocating an indicator number if necessary.
- void QsciScintilla::checkIndicator(int &indicatorNumber)
- {
- allocateId(indicatorNumber, allocatedIndicators, INDIC_CONTAINER,
- INDIC_IME - 1);
- }
- // Make sure an identifier is valid and allocate it if necessary.
- void QsciScintilla::allocateId(int &id, unsigned &allocated, int min, int max)
- {
- if (id >= 0)
- {
- // Note that we allow existing identifiers to be explicitly redefined.
- if (id > max)
- id = -1;
- }
- else
- {
- unsigned aids = allocated >> min;
- // Find the smallest unallocated identifier.
- for (id = min; id <= max; ++id)
- {
- if ((aids & 1) == 0)
- break;
- aids >>= 1;
- }
- }
- // Allocate the identifier if it is valid.
- if (id >= 0)
- allocated |= (1 << id);
- }
- // Reset the fold margin colours.
- void QsciScintilla::resetFoldMarginColors()
- {
- SendScintilla(SCI_SETFOLDMARGINHICOLOUR, 0, 0L);
- SendScintilla(SCI_SETFOLDMARGINCOLOUR, 0, 0L);
- }
- // Set the fold margin colours.
- void QsciScintilla::setFoldMarginColors(const QColor &fore, const QColor &back)
- {
- SendScintilla(SCI_SETFOLDMARGINHICOLOUR, 1, fore);
- SendScintilla(SCI_SETFOLDMARGINCOLOUR, 1, back);
- }
- // Set the call tips background colour.
- void QsciScintilla::setCallTipsBackgroundColor(const QColor &col)
- {
- SendScintilla(SCI_CALLTIPSETBACK, col);
- }
- // Set the call tips foreground colour.
- void QsciScintilla::setCallTipsForegroundColor(const QColor &col)
- {
- SendScintilla(SCI_CALLTIPSETFORE, col);
- }
- // Set the call tips highlight colour.
- void QsciScintilla::setCallTipsHighlightColor(const QColor &col)
- {
- SendScintilla(SCI_CALLTIPSETFOREHLT, col);
- }
- // Set the matched brace background colour.
- void QsciScintilla::setMatchedBraceBackgroundColor(const QColor &col)
- {
- SendScintilla(SCI_STYLESETBACK, STYLE_BRACELIGHT, col);
- }
- // Set the matched brace foreground colour.
- void QsciScintilla::setMatchedBraceForegroundColor(const QColor &col)
- {
- SendScintilla(SCI_STYLESETFORE, STYLE_BRACELIGHT, col);
- }
- // Set the matched brace indicator.
- void QsciScintilla::setMatchedBraceIndicator(int indicatorNumber)
- {
- SendScintilla(SCI_BRACEHIGHLIGHTINDICATOR, 1, indicatorNumber);
- }
- // Reset the matched brace indicator.
- void QsciScintilla::resetMatchedBraceIndicator()
- {
- SendScintilla(SCI_BRACEHIGHLIGHTINDICATOR, 0, 0L);
- }
- // Set the unmatched brace background colour.
- void QsciScintilla::setUnmatchedBraceBackgroundColor(const QColor &col)
- {
- SendScintilla(SCI_STYLESETBACK, STYLE_BRACEBAD, col);
- }
- // Set the unmatched brace foreground colour.
- void QsciScintilla::setUnmatchedBraceForegroundColor(const QColor &col)
- {
- SendScintilla(SCI_STYLESETFORE, STYLE_BRACEBAD, col);
- }
- // Set the unmatched brace indicator.
- void QsciScintilla::setUnmatchedBraceIndicator(int indicatorNumber)
- {
- SendScintilla(SCI_BRACEBADLIGHTINDICATOR, 1, indicatorNumber);
- }
- // Reset the unmatched brace indicator.
- void QsciScintilla::resetUnmatchedBraceIndicator()
- {
- SendScintilla(SCI_BRACEBADLIGHTINDICATOR, 0, 0L);
- }
- // Detach any lexer.
- void QsciScintilla::detachLexer()
- {
- if (!lex.isNull())
- {
- lex->setEditor(0);
- lex->disconnect(this);
- SendScintilla(SCI_STYLERESETDEFAULT);
- SendScintilla(SCI_STYLECLEARALL);
- }
- }
- // Set the lexer.
- void QsciScintilla::setLexer(QsciLexer *lexer)
- {
- // Detach any current lexer.
- detachLexer();
- // Connect up the new lexer.
- lex = lexer;
- if (lex)
- {
- SendScintilla(SCI_CLEARDOCUMENTSTYLE);
- if (lex->lexer())
- SendScintilla(SCI_SETLEXERLANGUAGE, lex->lexer());
- else
- SendScintilla(SCI_SETLEXER, lex->lexerId());
- lex->setEditor(this);
- connect(lex,SIGNAL(colorChanged(const QColor &, int)),
- SLOT(handleStyleColorChange(const QColor &, int)));
- connect(lex,SIGNAL(eolFillChanged(bool, int)),
- SLOT(handleStyleEolFillChange(bool, int)));
- connect(lex,SIGNAL(fontChanged(const QFont &, int)),
- SLOT(handleStyleFontChange(const QFont &, int)));
- connect(lex,SIGNAL(paperChanged(const QColor &, int)),
- SLOT(handleStylePaperChange(const QColor &, int)));
- connect(lex,SIGNAL(propertyChanged(const char *, const char *)),
- SLOT(handlePropertyChange(const char *, const char *)));
- SendScintilla(SCI_SETPROPERTY, "fold", "1");
- SendScintilla(SCI_SETPROPERTY, "fold.html", "1");
- // Set the keywords. Scintilla allows for sets numbered 0 to
- // KEYWORDSET_MAX (although the lexers only seem to exploit 0 to
- // KEYWORDSET_MAX - 1). We number from 1 in line with SciTE's property
- // files.
- for (int k = 0; k <= KEYWORDSET_MAX; ++k)
- {
- const char *kw = lex -> keywords(k + 1);
- if (!kw)
- kw = "";
- SendScintilla(SCI_SETKEYWORDS, k, kw);
- }
- // Initialise each style. Do the default first so its (possibly
- // incorrect) font setting gets reset when style 0 is set.
- setLexerStyle(STYLE_DEFAULT);
- int nrStyles = 1 << SendScintilla(SCI_GETSTYLEBITS);
- for (int s = 0; s < nrStyles; ++s)
- if (!lex->description(s).isEmpty())
- setLexerStyle(s);
- // Initialise the properties.
- lex->refreshProperties();
- // Set the auto-completion fillups and word separators.
- setAutoCompletionFillupsEnabled(fillups_enabled);
- wseps = lex->autoCompletionWordSeparators();
- wchars = lex->wordCharacters();
- if (!wchars)
- wchars = defaultWordChars;
- SendScintilla(SCI_AUTOCSETIGNORECASE, !lex->caseSensitive());
- recolor();
- }
- else
- {
- SendScintilla(SCI_SETLEXER, SCLEX_CONTAINER);
- setColor(nl_text_colour);
- setPaper(nl_paper_colour);
- SendScintilla(SCI_AUTOCSETFILLUPS, "");
- SendScintilla(SCI_AUTOCSETIGNORECASE, false);
- wseps.clear();
- wchars = defaultWordChars;
- }
- }
- // Set a particular style of the current lexer.
- void QsciScintilla::setLexerStyle(int style)
- {
- handleStyleColorChange(lex->color(style), style);
- handleStyleEolFillChange(lex->eolFill(style), style);
- handleStyleFontChange(lex->font(style), style);
- handleStylePaperChange(lex->paper(style), style);
- }
- // Get the current lexer.
- QsciLexer *QsciScintilla::lexer() const
- {
- return lex;
- }
- // Handle a change in lexer style foreground colour.
- void QsciScintilla::handleStyleColorChange(const QColor &c, int style)
- {
- SendScintilla(SCI_STYLESETFORE, style, c);
- }
- // Handle a change in lexer style end-of-line fill.
- void QsciScintilla::handleStyleEolFillChange(bool eolfill, int style)
- {
- SendScintilla(SCI_STYLESETEOLFILLED, style, eolfill);
- }
- // Handle a change in lexer style font.
- void QsciScintilla::handleStyleFontChange(const QFont &f, int style)
- {
- setStylesFont(f, style);
- if (style == lex->braceStyle())
- {
- setStylesFont(f, STYLE_BRACELIGHT);
- setStylesFont(f, STYLE_BRACEBAD);
- }
- }
- // Set the font for a style.
- void QsciScintilla::setStylesFont(const QFont &f, int style)
- {
- SendScintilla(SCI_STYLESETFONT, style, f.family().toLatin1().data());
- SendScintilla(SCI_STYLESETSIZEFRACTIONAL, style,
- long(f.pointSizeF() * SC_FONT_SIZE_MULTIPLIER));
- // Pass the Qt weight via the back door.
- SendScintilla(SCI_STYLESETWEIGHT, style, -f.weight());
- SendScintilla(SCI_STYLESETITALIC, style, f.italic());
- SendScintilla(SCI_STYLESETUNDERLINE, style, f.underline());
- // Tie the font settings of the default style to that of style 0 (the style
- // conventionally used for whitespace by lexers). This is needed so that
- // fold marks, indentations, edge columns etc are set properly.
- if (style == 0)
- setStylesFont(f, STYLE_DEFAULT);
- }
- // Handle a change in lexer style background colour.
- void QsciScintilla::handleStylePaperChange(const QColor &c, int style)
- {
- SendScintilla(SCI_STYLESETBACK, style, c);
- }
- // Handle a change in lexer property.
- void QsciScintilla::handlePropertyChange(const char *prop, const char *val)
- {
- SendScintilla(SCI_SETPROPERTY, prop, val);
- }
- // Handle a change to the user visible user interface.
- void QsciScintilla::handleUpdateUI(int)
- {
- int newPos = SendScintilla(SCI_GETCURRENTPOS);
- if (newPos != oldPos)
- {
- oldPos = newPos;
- int line = SendScintilla(SCI_LINEFROMPOSITION, newPos);
- int col = SendScintilla(SCI_GETCOLUMN, newPos);
- emit cursorPositionChanged(line, col);
- }
- if (braceMode != BraceMatch::NoBraceMatch)
- braceMatch();
- }
- // Handle brace matching.
- void QsciScintilla::braceMatch()
- {
- long braceAtCaret, braceOpposite;
- findMatchingBrace(braceAtCaret, braceOpposite, braceMode);
- if (braceAtCaret >= 0 && braceOpposite < 0)
- {
- SendScintilla(SCI_BRACEBADLIGHT, braceAtCaret);
- SendScintilla(SCI_SETHIGHLIGHTGUIDE, 0UL);
- }
- else
- {
- char chBrace = SendScintilla(SCI_GETCHARAT, braceAtCaret);
- SendScintilla(SCI_BRACEHIGHLIGHT, braceAtCaret, braceOpposite);
- long columnAtCaret = SendScintilla(SCI_GETCOLUMN, braceAtCaret);
- long columnOpposite = SendScintilla(SCI_GETCOLUMN, braceOpposite);
- if (chBrace == ':')
- {
- long lineStart = SendScintilla(SCI_LINEFROMPOSITION, braceAtCaret);
- long indentPos = SendScintilla(SCI_GETLINEINDENTPOSITION,
- lineStart);
- long indentPosNext = SendScintilla(SCI_GETLINEINDENTPOSITION,
- lineStart + 1);
- columnAtCaret = SendScintilla(SCI_GETCOLUMN, indentPos);
- long columnAtCaretNext = SendScintilla(SCI_GETCOLUMN,
- indentPosNext);
- long indentSize = SendScintilla(SCI_GETINDENT);
- if (columnAtCaretNext - indentSize > 1)
- columnAtCaret = columnAtCaretNext - indentSize;
- if (columnOpposite == 0)
- columnOpposite = columnAtCaret;
- }
- long column = columnAtCaret;
- if (column > columnOpposite)
- column = columnOpposite;
- SendScintilla(SCI_SETHIGHLIGHTGUIDE, column);
- }
- }
- // Check if the character at a position is a brace.
- long QsciScintilla::checkBrace(long pos, int brace_style, bool &colonMode)
- {
- long brace_pos = -1;
- char ch = SendScintilla(SCI_GETCHARAT, pos);
- if (ch == ':')
- {
- // A bit of a hack, we should really use a virtual.
- if (!lex.isNull() && qstrcmp(lex->lexer(), "python") == 0)
- {
- brace_pos = pos;
- colonMode = true;
- }
- }
- else if (ch && strchr("[](){}<>", ch))
- {
- if (brace_style < 0)
- brace_pos = pos;
- else
- {
- int style = SendScintilla(SCI_GETSTYLEAT, pos) & 0x1f;
- if (style == brace_style)
- brace_pos = pos;
- }
- }
- return brace_pos;
- }
- // Find a brace and it's match. Return true if the current position is inside
- // a pair of braces.
- bool QsciScintilla::findMatchingBrace(long &brace, long &other,BraceMatch mode)
- {
- bool colonMode = false;
- int brace_style = (lex.isNull() ? -1 : lex->braceStyle());
- brace = -1;
- other = -1;
- long caretPos = SendScintilla(SCI_GETCURRENTPOS);
- if (caretPos > 0)
- brace = checkBrace(caretPos - 1, brace_style, colonMode);
- bool isInside = false;
- if (brace < 0 && mode == BraceMatch::SloppyBraceMatch)
- {
- brace = checkBrace(caretPos, brace_style, colonMode);
- if (brace >= 0 && !colonMode)
- isInside = true;
- }
- if (brace >= 0)
- {
- if (colonMode)
- {
- // Find the end of the Python indented block.
- long lineStart = SendScintilla(SCI_LINEFROMPOSITION, brace);
- long lineMaxSubord = SendScintilla(SCI_GETLASTCHILD, lineStart, -1);
- other = SendScintilla(SCI_GETLINEENDPOSITION, lineMaxSubord);
- }
- else
- other = SendScintilla(SCI_BRACEMATCH, brace, 0L);
- if (other > brace)
- isInside = !isInside;
- }
- return isInside;
- }
- // Move to the matching brace.
- void QsciScintilla::moveToMatchingBrace()
- {
- gotoMatchingBrace(false);
- }
- // Select to the matching brace.
- void QsciScintilla::selectToMatchingBrace()
- {
- gotoMatchingBrace(true);
- }
- // Move to the matching brace and optionally select the text.
- void QsciScintilla::gotoMatchingBrace(bool select)
- {
- long braceAtCaret;
- long braceOpposite;
- bool isInside = findMatchingBrace(braceAtCaret, braceOpposite,
- BraceMatch::SloppyBraceMatch);
- if (braceOpposite >= 0)
- {
- // Convert the character positions into caret positions based on
- // whether the caret position was inside or outside the braces.
- if (isInside)
- {
- if (braceOpposite > braceAtCaret)
- braceAtCaret++;
- else
- braceOpposite++;
- }
- else
- {
- if (braceOpposite > braceAtCaret)
- braceOpposite++;
- else
- braceAtCaret++;
- }
- ensureLineVisible(SendScintilla(SCI_LINEFROMPOSITION, braceOpposite));
- if (select)
- SendScintilla(SCI_SETSEL, braceAtCaret, braceOpposite);
- else
- SendScintilla(SCI_SETSEL, braceOpposite, braceOpposite);
- }
- }
- // Return a position from a line number and an index within the line.
- int QsciScintilla::positionFromLineIndex(int line, int index) const
- {
- int pos = SendScintilla(SCI_POSITIONFROMLINE, line);
- // Allow for multi-byte characters.
- for(int i = 0; i < index; i++)
- pos = SendScintilla(SCI_POSITIONAFTER, pos);
- return pos;
- }
- // Return a line number and an index within the line from a position.
- void QsciScintilla::lineIndexFromPosition(int position, int *line, int *index) const
- {
- int lin = SendScintilla(SCI_LINEFROMPOSITION, position);
- int linpos = SendScintilla(SCI_POSITIONFROMLINE, lin);
- int indx = 0;
- // Allow for multi-byte characters.
- while (linpos < position)
- {
- int new_linpos = SendScintilla(SCI_POSITIONAFTER, linpos);
- // If the position hasn't moved then we must be at the end of the text
- // (which implies that the position passed was beyond the end of the
- // text).
- if (new_linpos == linpos)
- break;
- linpos = new_linpos;
- ++indx;
- }
- *line = lin;
- *index = indx;
- }
- // Set the source of the automatic auto-completion list.
- void QsciScintilla::setAutoCompletionSource(AutoCompletionSource source)
- {
- acSource = source;
- }
- // Set the threshold for automatic auto-completion.
- void QsciScintilla::setAutoCompletionThreshold(int thresh)
- {
- acThresh = thresh;
- }
- // Set the auto-completion word separators if there is no current lexer.
- void QsciScintilla::setAutoCompletionWordSeparators(const QStringList &separators)
- {
- if (lex.isNull())
- wseps = separators;
- }
- // Explicitly auto-complete from all sources.
- void QsciScintilla::autoCompleteFromAll()
- {
- startAutoCompletion(AutoCompletionSource::AcsAll, false, use_single != AcusNever);
- }
- // Explicitly auto-complete from the APIs.
- void QsciScintilla::autoCompleteFromAPIs()
- {
- startAutoCompletion(AutoCompletionSource::AcsAPIs, false, use_single != AcusNever);
- }
- // Explicitly auto-complete from the document.
- void QsciScintilla::autoCompleteFromDocument()
- {
- startAutoCompletion(AutoCompletionSource::AcsDocument, false, use_single != AcusNever);
- }
- // Check if a character can be in a word.
- bool QsciScintilla::isWordCharacter(char ch) const
- {
- return (strchr(wchars, ch) != NULL);
- }
- // Return the set of valid word characters.
- const char *QsciScintilla::wordCharacters() const
- {
- return wchars;
- }
- // Recolour the document.
- void QsciScintilla::recolor(int start, int end)
- {
- SendScintilla(SCI_COLOURISE, start, end);
- }
- // Registered a QPixmap image.
- void QsciScintilla::registerImage(int id, const QPixmap &pm)
- {
- SendScintilla(SCI_REGISTERIMAGE, id, pm);
- }
- // Registered a QImage image.
- void QsciScintilla::registerImage(int id, const QImage &im)
- {
- SendScintilla(SCI_RGBAIMAGESETHEIGHT, im.height());
- SendScintilla(SCI_RGBAIMAGESETWIDTH, im.width());
- SendScintilla(SCI_REGISTERRGBAIMAGE, id, im);
- }
- // Clear all registered images.
- void QsciScintilla::clearRegisteredImages()
- {
- SendScintilla(SCI_CLEARREGISTEREDIMAGES);
- }
- // Enable auto-completion fill-ups.
- void QsciScintilla::setAutoCompletionFillupsEnabled(bool enable)
- {
- const char *fillups;
- if (!enable)
- fillups = "";
- else if (!lex.isNull())
- fillups = lex->autoCompletionFillups();
- else
- fillups = explicit_fillups.data();
- SendScintilla(SCI_AUTOCSETFILLUPS, fillups);
- fillups_enabled = enable;
- }
- // See if auto-completion fill-ups are enabled.
- bool QsciScintilla::autoCompletionFillupsEnabled() const
- {
- return fillups_enabled;
- }
- // Set the fill-up characters for auto-completion if there is no current lexer.
- void QsciScintilla::setAutoCompletionFillups(const char *fillups)
- {
- explicit_fillups = fillups;
- setAutoCompletionFillupsEnabled(fillups_enabled);
- }
- // Set the case sensitivity for auto-completion.
- void QsciScintilla::setAutoCompletionCaseSensitivity(bool cs)
- {
- SendScintilla(SCI_AUTOCSETIGNORECASE, !cs);
- }
- // Return the case sensitivity for auto-completion.
- bool QsciScintilla::autoCompletionCaseSensitivity() const
- {
- return !SendScintilla(SCI_AUTOCGETIGNORECASE);
- }
- // Set the replace word mode for auto-completion.
- void QsciScintilla::setAutoCompletionReplaceWord(bool replace)
- {
- SendScintilla(SCI_AUTOCSETDROPRESTOFWORD, replace);
- }
- // Return the replace word mode for auto-completion.
- bool QsciScintilla::autoCompletionReplaceWord() const
- {
- return SendScintilla(SCI_AUTOCGETDROPRESTOFWORD);
- }
- // Set the single item mode for auto-completion.
- void QsciScintilla::setAutoCompletionUseSingle(AutoCompletionUseSingle single)
- {
- use_single = single;
- }
- // Return the single item mode for auto-completion.
- QsciScintilla::AutoCompletionUseSingle QsciScintilla::autoCompletionUseSingle() const
- {
- return use_single;
- }
- // Set the single item mode for auto-completion (deprecated).
- void QsciScintilla::setAutoCompletionShowSingle(bool single)
- {
- use_single = (single ? AcusExplicit : AcusNever);
- }
- // Return the single item mode for auto-completion (deprecated).
- bool QsciScintilla::autoCompletionShowSingle() const
- {
- return (use_single != AcusNever);
- }
- // Set current call tip position.
- void QsciScintilla::setCallTipsPosition(CallTipsPosition position)
- {
- SendScintilla(SCI_CALLTIPSETPOSITION, (position == CallTipsPosition::CallTipsAboveText));
- call_tips_position = position;
- }
- // Set current call tip style.
- void QsciScintilla::setCallTipsStyle(CallTipsStyle style)
- {
- call_tips_style = style;
- }
- // Set maximum number of call tips displayed.
- void QsciScintilla::setCallTipsVisible(int nr)
- {
- maxCallTips = nr;
- }
- // Set the document to display.
- void QsciScintilla::setDocument(const QsciDocument &document)
- {
- if (doc.pdoc != document.pdoc)
- {
- doc.undisplay(this);
- doc.attach(document);
- doc.display(this,&document);
- }
- }
- // Ensure the document is read-write and return true if was was read-only.
- bool QsciScintilla::ensureRW()
- {
- bool ro = isReadOnly();
- if (ro)
- setReadOnly(false);
- return ro;
- }
- // Return the number of the first visible line.
- int QsciScintilla::firstVisibleLine() const
- {
- return SendScintilla(SCI_GETFIRSTVISIBLELINE);
- }
- // Set the number of the first visible line.
- void QsciScintilla::setFirstVisibleLine(int linenr)
- {
- SendScintilla(SCI_SETFIRSTVISIBLELINE, linenr);
- }
- // Return the height in pixels of the text in a particular line.
- int QsciScintilla::textHeight(int linenr) const
- {
- return SendScintilla(SCI_TEXTHEIGHT, linenr);
- }
- // See if auto-completion or user list is active.
- bool QsciScintilla::isListActive() const
- {
- return SendScintilla(SCI_AUTOCACTIVE);
- }
- // Cancel any current auto-completion or user list.
- void QsciScintilla::cancelList()
- {
- SendScintilla(SCI_AUTOCCANCEL);
- }
- // Handle a selection from the auto-completion list.
- void QsciScintilla::handleAutoCompletionSelection()
- {
- if (!lex.isNull())
- {
- QsciAbstractAPIs *apis = lex->apis();
- if (apis)
- apis->autoCompletionSelected(acSelection);
- }
- }
- // Display a user list.
- void QsciScintilla::showUserList(int id, const QStringList &list)
- {
- // Sanity check to make sure auto-completion doesn't get confused.
- if (id <= 0)
- return;
- SendScintilla(SCI_AUTOCSETSEPARATOR, userSeparator);
- ScintillaBytes s = textAsBytes(list.join(QChar(userSeparator)));
- SendScintilla(SCI_USERLISTSHOW, id, ScintillaBytesConstData(s));
- }
- // Translate the SCN_USERLISTSELECTION notification into something more useful.
- void QsciScintilla::handleUserListSelection(const char *text, int id)
- {
- emit userListActivated(id, QString(text));
- // Make sure the editor hasn't been deactivated as a side effect.
- activateWindow();
- }
- // Return the case sensitivity of any lexer.
- bool QsciScintilla::caseSensitive() const
- {
- return lex.isNull() ? true : lex->caseSensitive();
- }
- // Return true if the current list is an auto-completion list rather than a
- // user list.
- bool QsciScintilla::isAutoCompletionList() const
- {
- return (SendScintilla(SCI_AUTOCGETSEPARATOR) == acSeparator);
- }
- // Read the text from a QIODevice.
- bool QsciScintilla::read(QIODevice *io)
- {
- const int min_size = 1024 * 8;
- int buf_size = min_size;
- char *buf = new char[buf_size];
- int data_len = 0;
- bool ok = true;
- qint64 part;
- // Read the whole lot in so we don't have to worry about character
- // boundaries.
- do
- {
- // Make sure there is a minimum amount of room.
- if (buf_size - data_len < min_size)
- {
- buf_size *= 2;
- char *new_buf = new char[buf_size * 2];
- memcpy(new_buf, buf, data_len);
- delete[] buf;
- buf = new_buf;
- }
- part = io->read(buf + data_len, buf_size - data_len - 1);
- data_len += part;
- }
- while (part > 0);
- if (part < 0)
- ok = false;
- else
- {
- buf[data_len] = '\0';
- bool ro = ensureRW();
- SendScintilla(SCI_SETTEXT, buf);
- SendScintilla(SCI_EMPTYUNDOBUFFER);
- setReadOnly(ro);
- }
- delete[] buf;
- return ok;
- }
- // Write the text to a QIODevice.
- bool QsciScintilla::write(QIODevice *io) const
- {
- const char *buf = reinterpret_cast<const char *>(SendScintillaPtrResult(SCI_GETCHARACTERPOINTER));
- const char *bp = buf;
- uint buflen = qstrlen(buf);
- while (buflen > 0)
- {
- qint64 part = io->write(bp, buflen);
- if (part < 0)
- return false;
- bp += part;
- buflen -= part;
- }
- return true;
- }
- // Return the word at the given coordinates.
- QString QsciScintilla::wordAtLineIndex(int line, int index) const
- {
- return wordAtPosition(positionFromLineIndex(line, index));
- }
- // Return the word at the given coordinates.
- QString QsciScintilla::wordAtPoint(const QPoint &point) const
- {
- long close_pos = SendScintilla(SCI_POSITIONFROMPOINTCLOSE, point.x(),
- point.y());
- return wordAtPosition(close_pos);
- }
- // Return the word at the given position.
- QString QsciScintilla::wordAtPosition(int position) const
- {
- if (position < 0)
- return QString();
- long start_pos = SendScintilla(SCI_WORDSTARTPOSITION, position, true);
- long end_pos = SendScintilla(SCI_WORDENDPOSITION, position, true);
- if (start_pos >= end_pos)
- return QString();
- return text(start_pos, end_pos);
- }
- // Return the display style for annotations.
- QsciScintilla::AnnotationDisplay QsciScintilla::annotationDisplay() const
- {
- return (AnnotationDisplay)SendScintilla(SCI_ANNOTATIONGETVISIBLE);
- }
- // Set the display style for annotations.
- void QsciScintilla::setAnnotationDisplay(QsciScintilla::AnnotationDisplay display)
- {
- SendScintilla(SCI_ANNOTATIONSETVISIBLE, display);
- setScrollBars();
- }
- // Clear annotations.
- void QsciScintilla::clearAnnotations(int line)
- {
- if (line >= 0)
- SendScintilla(SCI_ANNOTATIONSETTEXT, line, (const char *)0);
- else
- SendScintilla(SCI_ANNOTATIONCLEARALL);
- setScrollBars();
- }
- // Annotate a line.
- void QsciScintilla::annotate(int line, const QString &text, int style)
- {
- int style_offset = SendScintilla(SCI_ANNOTATIONGETSTYLEOFFSET);
- ScintillaBytes s = textAsBytes(text);
- SendScintilla(SCI_ANNOTATIONSETTEXT, line, ScintillaBytesConstData(s));
- SendScintilla(SCI_ANNOTATIONSETSTYLE, line, style - style_offset);
- setScrollBars();
- }
- // Annotate a line.
- void QsciScintilla::annotate(int line, const QString &text, const QsciStyle &style)
- {
- style.apply(this);
- annotate(line, text, style.style());
- }
- // Annotate a line.
- void QsciScintilla::annotate(int line, const QsciStyledText &text)
- {
- text.apply(this);
- annotate(line, text.text(), text.style());
- }
- // Annotate a line.
- void QsciScintilla::annotate(int line, const QList<QsciStyledText> &text)
- {
- char *styles;
- ScintillaBytes styled_text = styleText(text, &styles,
- SendScintilla(SCI_ANNOTATIONGETSTYLEOFFSET));
- SendScintilla(SCI_ANNOTATIONSETTEXT, line,
- ScintillaBytesConstData(styled_text));
- SendScintilla(SCI_ANNOTATIONSETSTYLES, line, styles);
- delete[] styles;
- }
- // Get the annotation for a line, if any.
- QString QsciScintilla::annotation(int line) const
- {
- char *buf = new char[SendScintilla(SCI_ANNOTATIONGETTEXT, line, (const char *)0) + 1];
- buf[SendScintilla(SCI_ANNOTATIONGETTEXT, line, buf)] = '\0';
- QString qs = bytesAsText(buf);
- delete[] buf;
- return qs;
- }
- // Convert a list of styled text to the low-level arrays.
- QsciScintillaBase::ScintillaBytes QsciScintilla::styleText(const QList<QsciStyledText> &styled_text, char **styles, int style_offset)
- {
- QString text;
- int i;
- // Build the full text.
- for (i = 0; i < styled_text.count(); ++i)
- {
- const QsciStyledText &st = styled_text[i];
- st.apply(this);
- text.append(st.text());
- }
- ScintillaBytes s = textAsBytes(text);
- // There is a style byte for every byte.
- char *sp = *styles = new char[s.length()];
- for (i = 0; i < styled_text.count(); ++i)
- {
- const QsciStyledText &st = styled_text[i];
- ScintillaBytes part = textAsBytes(st.text());
- int part_length = part.length();
- for (int c = 0; c < part_length; ++c)
- *sp++ = (char)(st.style() - style_offset);
- }
- return s;
- }
- // Convert Scintilla modifiers to the Qt equivalent.
- int QsciScintilla::mapModifiers(int modifiers)
- {
- int state = 0;
- if (modifiers & SCMOD_SHIFT)
- state |= Qt::ShiftModifier;
- if (modifiers & SCMOD_CTRL)
- state |= Qt::ControlModifier;
- if (modifiers & SCMOD_ALT)
- state |= Qt::AltModifier;
- if (modifiers & (SCMOD_SUPER | SCMOD_META))
- state |= Qt::MetaModifier;
- return state;
- }
- // Re-implemented to handle shortcut overrides.
- bool QsciScintilla::event(QEvent *e)
- {
- if (e->type() == QEvent::ShortcutOverride && !isReadOnly())
- {
- QKeyEvent *ke = static_cast<QKeyEvent *>(e);
- if (ke->key())
- {
- // We want ordinary characters.
- if ((ke->modifiers() == Qt::NoModifier || ke->modifiers() == Qt::ShiftModifier || ke->modifiers() == Qt::KeypadModifier) && ke->key() < Qt::Key_Escape)
- {
- ke->accept();
- return true;
- }
- // We want any key that is bound.
- QsciCommand *cmd = stdCmds->boundTo(ke->key() | (ke->modifiers() & ~Qt::KeypadModifier));
- if (cmd)
- {
- ke->accept();
- return true;
- }
- }
- }
- return QsciScintillaBase::event(e);
- }
- // Re-implemented to handle chenges to the enabled state.
- void QsciScintilla::changeEvent(QEvent *e)
- {
- QsciScintillaBase::changeEvent(e);
- if (e->type() != QEvent::EnabledChange)
- return;
- if (isEnabled())
- SendScintilla(SCI_SETCARETSTYLE, CARETSTYLE_LINE);
- else
- SendScintilla(SCI_SETCARETSTYLE, CARETSTYLE_INVISIBLE);
- QColor fore = palette().color(QPalette::Disabled, QPalette::Text);
- QColor back = palette().color(QPalette::Disabled, QPalette::Base);
- if (lex.isNull())
- {
- if (isEnabled())
- {
- fore = nl_text_colour;
- back = nl_paper_colour;
- }
- SendScintilla(SCI_STYLESETFORE, 0, fore);
- // Assume style 0 applies to everything so that we don't need to use
- // SCI_STYLECLEARALL which clears everything. We still have to set the
- // default style as well for the background without any text.
- SendScintilla(SCI_STYLESETBACK, 0, back);
- SendScintilla(SCI_STYLESETBACK, STYLE_DEFAULT, back);
- }
- else
- {
- setEnabledColors(STYLE_DEFAULT, fore, back);
- int nrStyles = 1 << SendScintilla(SCI_GETSTYLEBITS);
- for (int s = 0; s < nrStyles; ++s)
- if (!lex->description(s).isNull())
- setEnabledColors(s, fore, back);
- }
- }
- // Set the foreground and background colours for a style.
- void QsciScintilla::setEnabledColors(int style, QColor &fore, QColor &back)
- {
- if (isEnabled())
- {
- fore = lex->color(style);
- back = lex->paper(style);
- }
- handleStyleColorChange(fore, style);
- handleStylePaperChange(back, style);
- }
- // Re-implemented to implement a more Qt-like context menu.
- void QsciScintilla::contextMenuEvent(QContextMenuEvent *e)
- {
- QMenu *menu = createStandardContextMenu();
- if (menu)
- {
- menu->setAttribute(Qt::WA_DeleteOnClose);
- menu->popup(e->globalPos());
- }
- }
- // Create an instance of the standard context menu.
- QMenu *QsciScintilla::createStandardContextMenu()
- {
- bool read_only = isReadOnly();
- bool has_selection = hasSelectedText();
- QMenu *menu = new QMenu(this);
- QAction *action;
- if (!read_only)
- {
- action = menu->addAction(tr("&Undo"), this, SLOT(undo()));
- set_shortcut(action, QsciCommand::Undo);
- action->setEnabled(isUndoAvailable());
- action = menu->addAction(tr("&Redo"), this, SLOT(redo()));
- set_shortcut(action, QsciCommand::Redo);
- action->setEnabled(isRedoAvailable());
- menu->addSeparator();
- action = menu->addAction(tr("Cu&t"), this, SLOT(cut()));
- set_shortcut(action, QsciCommand::SelectionCut);
- action->setEnabled(has_selection);
- }
- action = menu->addAction(tr("&Copy"), this, SLOT(copy()));
- set_shortcut(action, QsciCommand::SelectionCopy);
- action->setEnabled(has_selection);
- if (!read_only)
- {
- action = menu->addAction(tr("&Paste"), this, SLOT(paste()));
- set_shortcut(action, QsciCommand::Paste);
- action->setEnabled(SendScintilla(SCI_CANPASTE));
- action = menu->addAction(tr("Delete"), this, SLOT(delete_selection()));
- action->setEnabled(has_selection);
- }
- if (!menu->isEmpty())
- menu->addSeparator();
- action = menu->addAction(tr("Select All"), this, SLOT(selectAll()));
- set_shortcut(action, QsciCommand::SelectAll);
- action->setEnabled(length() != 0);
- return menu;
- }
- // Set the shortcut for an action using any current key binding.
- void QsciScintilla::set_shortcut(QAction *action, QsciCommand::Command cmd_id) const
- {
- QsciCommand *cmd = stdCmds->find(cmd_id);
- if (cmd && cmd->key())
- action->setShortcut(QKeySequence(cmd->key()));
- }
- // Delete the current selection.
- void QsciScintilla::delete_selection()
- {
- SendScintilla(SCI_CLEAR);
- }
- // Convert a Scintilla colour to a QColor.
- static QColor asQColor(long sci_colour)
- {
- return QColor(
- ((int)sci_colour) & 0x00ff,
- ((int)(sci_colour >> 8)) & 0x00ff,
- ((int)(sci_colour >> 16)) & 0x00ff);
- }
|