Use QScintilla instead of own implementation of a code editor

This is a first rough implementation of QScintilla support as SQL text
editor.

It should work mostly and build fine with qmake as well as cmake. The
new code supports all the features of the old one plus adding a few
subtle improvements. The main point of this, however, is reducing the
code we have to maintain and making it easier to add new features to the
editor.
This commit is contained in:
Martin Kleusberg
2015-04-16 11:44:32 +02:00
parent 569dffbc25
commit cde2393539
172 changed files with 87330 additions and 677 deletions
+4
View File
@@ -24,9 +24,13 @@ src/translations/*.qm
src/grammar/sqlite3TokenTypes.txt
libs/*/Makefile*
libs/*/*/Makefile*
libs/*/debug/
libs/*/*/debug/
libs/*/release/
libs/*/*/release/
libs/*/*.a
libs/*/*/*.a
# Ignore .DS_Store files on OSX
.DS_Store
+9 -4
View File
@@ -24,10 +24,12 @@ endif()
set(ANTLR_DIR libs/antlr-2.7.7)
set(QHEXEDIT_DIR libs/qhexedit)
set(QCUSTOMPLOT_DIR libs/qcustomplot-source)
set(QSCINTILLA_DIR libs/qscintilla/Qt4Qt5)
add_subdirectory(${ANTLR_DIR})
add_subdirectory(${QHEXEDIT_DIR})
add_subdirectory(${QCUSTOMPLOT_DIR})
add_subdirectory(${QSCINTILLA_DIR})
if(USE_QT5)
find_package(Qt5Widgets REQUIRED)
@@ -62,7 +64,6 @@ set(SQLB_MOC_HDR
src/ImportCsvDialog.h
src/MainWindow.h
src/PreferencesDialog.h
src/SQLiteSyntaxHighlighter.h
src/SqlExecutionArea.h
src/VacuumDialog.h
src/sqlitetablemodel.h
@@ -71,6 +72,7 @@ set(SQLB_MOC_HDR
src/Application.h
src/CipherDialog.h
src/ExportSqlDialog.h
src/SqlUiLexer.h
)
set(SQLB_SRC
@@ -84,7 +86,6 @@ set(SQLB_SRC
src/ImportCsvDialog.cpp
src/MainWindow.cpp
src/PreferencesDialog.cpp
src/SQLiteSyntaxHighlighter.cpp
src/SqlExecutionArea.cpp
src/VacuumDialog.cpp
src/sqlitedb.cpp
@@ -99,6 +100,7 @@ set(SQLB_SRC
src/Application.cpp
src/CipherDialog.cpp
src/ExportSqlDialog.cpp
src/SqlUiLexer.cpp
)
set(SQLB_FORMS
@@ -208,6 +210,7 @@ include_directories(
${ANTLR_DIR}
${QHEXEDIT_DIR}
${QCUSTOMPLOT_DIR}
${QSCINTILLA_DIR}
${ADDITIONAL_INCLUDE_PATHS}
src)
@@ -224,17 +227,19 @@ if(USE_QT5)
qt5_use_modules(${PROJECT_NAME} Gui Widgets Network Test PrintSupport)
set(QT_LIBRARIES "")
endif()
add_dependencies(${PROJECT_NAME} antlr qhexedit qcustomplot)
add_dependencies(${PROJECT_NAME} antlr qhexedit qcustomplot qscintilla2)
link_directories(
"${CMAKE_CURRENT_BINARY_DIR}/${ANTLR_DIR}"
"${CMAKE_CURRENT_BINARY_DIR}/${QHEXEDIT_DIR}"
"${CMAKE_CURRENT_BINARY_DIR}/${QCUSTOMPLOT_DIR}")
"${CMAKE_CURRENT_BINARY_DIR}/${QCUSTOMPLOT_DIR}"
"${CMAKE_CURRENT_BINARY_DIR}/${QSCINTILLA_DIR}")
target_link_libraries(${PROJECT_NAME}
antlr
qhexedit
qcustomplot
qscintilla2
${QT_LIBRARIES}
${WIN32_STATIC_LINK}
${LIBSQLITE}
File diff suppressed because it is too large Load Diff
+685
View File
@@ -0,0 +1,685 @@
QScintilla is Copyright (C) 2015 Riverbank Computing Limited
<info@riverbankcomputing.com>
You may use, distribute and copy QScintilla under the terms of GNU
General Public License version 3, which is displayed below.
-------------------------------------------------------------------------
GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The GNU General Public License is a free, copyleft license for
software and other kinds of works.
The licenses for most software and other practical works are designed
to take away your freedom to share and change the works. By contrast,
the GNU General Public License is intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users. We, the Free Software Foundation, use the
GNU General Public License for most of our software; it applies also to
any other work released this way by its authors. You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.
To protect your rights, we need to prevent others from denying you
these rights or asking you to surrender the rights. Therefore, you have
certain responsibilities if you distribute copies of the software, or if
you modify it: responsibilities to respect the freedom of others.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must pass on to the recipients the same
freedoms that you received. You must make sure that they, too, receive
or can get the source code. And you must show them these terms so they
know their rights.
Developers that use the GNU GPL protect your rights with two steps:
(1) assert copyright on the software, and (2) offer you this License
giving you legal permission to copy, distribute and/or modify it.
For the developers' and authors' protection, the GPL clearly explains
that there is no warranty for this free software. For both users' and
authors' sake, the GPL requires that modified versions be marked as
changed, so that their problems will not be attributed erroneously to
authors of previous versions.
Some devices are designed to deny users access to install or run
modified versions of the software inside them, although the manufacturer
can do so. This is fundamentally incompatible with the aim of
protecting users' freedom to change the software. The systematic
pattern of such abuse occurs in the area of products for individuals to
use, which is precisely where it is most unacceptable. Therefore, we
have designed this version of the GPL to prohibit the practice for those
products. If such problems arise substantially in other domains, we
stand ready to extend this provision to those domains in future versions
of the GPL, as needed to protect the freedom of users.
Finally, every program is threatened constantly by software patents.
States should not allow patents to restrict development and use of
software on general-purpose computers, but in those that do, we wish to
avoid the special danger that patents applied to a free program could
make it effectively proprietary. To prevent this, the GPL assures that
patents cannot be used to render the program non-free.
The precise terms and conditions for copying, distribution and
modification follow.
TERMS AND CONDITIONS
0. Definitions.
"This License" refers to version 3 of the GNU General Public License.
"Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.
"The Program" refers to any copyrightable work licensed under this
License. Each licensee is addressed as "you". "Licensees" and
"recipients" may be individuals or organizations.
To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy. The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.
A "covered work" means either the unmodified Program or a work based
on the Program.
To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy. Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.
To "convey" a work means any kind of propagation that enables other
parties to make or receive copies. Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.
An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License. If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.
1. Source Code.
The "source code" for a work means the preferred form of the work
for making modifications to it. "Object code" means any non-source
form of a work.
A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.
The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form. A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.
The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities. However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work. For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.
The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.
The Corresponding Source for a work in source code form is that
same work.
2. Basic Permissions.
All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met. This License explicitly affirms your unlimited
permission to run the unmodified Program. The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work. This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.
You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force. You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright. Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.
Conveying under any other circumstances is permitted solely under
the conditions stated below. Sublicensing is not allowed; section 10
makes it unnecessary.
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.
When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.
4. Conveying Verbatim Copies.
You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.
You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.
5. Conveying Modified Source Versions.
You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:
a) The work must carry prominent notices stating that you modified
it, and giving a relevant date.
b) The work must carry prominent notices stating that it is
released under this License and any conditions added under section
7. This requirement modifies the requirement in section 4 to
"keep intact all notices".
c) You must license the entire work, as a whole, under this
License to anyone who comes into possession of a copy. This
License will therefore apply, along with any applicable section 7
additional terms, to the whole of the work, and all its parts,
regardless of how they are packaged. This License gives no
permission to license the work in any other way, but it does not
invalidate such permission if you have separately received it.
d) If the work has interactive user interfaces, each must display
Appropriate Legal Notices; however, if the Program has interactive
interfaces that do not display Appropriate Legal Notices, your
work need not make them do so.
A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit. Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.
6. Conveying Non-Source Forms.
You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:
a) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by the
Corresponding Source fixed on a durable physical medium
customarily used for software interchange.
b) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by a
written offer, valid for at least three years and valid for as
long as you offer spare parts or customer support for that product
model, to give anyone who possesses the object code either (1) a
copy of the Corresponding Source for all the software in the
product that is covered by this License, on a durable physical
medium customarily used for software interchange, for a price no
more than your reasonable cost of physically performing this
conveying of source, or (2) access to copy the
Corresponding Source from a network server at no charge.
c) Convey individual copies of the object code with a copy of the
written offer to provide the Corresponding Source. This
alternative is allowed only occasionally and noncommercially, and
only if you received the object code with such an offer, in accord
with subsection 6b.
d) Convey the object code by offering access from a designated
place (gratis or for a charge), and offer equivalent access to the
Corresponding Source in the same way through the same place at no
further charge. You need not require recipients to copy the
Corresponding Source along with the object code. If the place to
copy the object code is a network server, the Corresponding Source
may be on a different server (operated by you or a third party)
that supports equivalent copying facilities, provided you maintain
clear directions next to the object code saying where to find the
Corresponding Source. Regardless of what server hosts the
Corresponding Source, you remain obligated to ensure that it is
available for as long as needed to satisfy these requirements.
e) Convey the object code using peer-to-peer transmission, provided
you inform other peers where the object code and Corresponding
Source of the work are being offered to the general public at no
charge under subsection 6d.
A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.
A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling. In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage. For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product. A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.
"Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source. The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.
If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information. But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).
The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed. Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.
Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.
7. Additional Terms.
"Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law. If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.
When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it. (Additional permissions may be written to require their own
removal in certain cases when you modify the work.) You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.
Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:
a) Disclaiming warranty or limiting liability differently from the
terms of sections 15 and 16 of this License; or
b) Requiring preservation of specified reasonable legal notices or
author attributions in that material or in the Appropriate Legal
Notices displayed by works containing it; or
c) Prohibiting misrepresentation of the origin of that material, or
requiring that modified versions of such material be marked in
reasonable ways as different from the original version; or
d) Limiting the use for publicity purposes of names of licensors or
authors of the material; or
e) Declining to grant rights under trademark law for use of some
trade names, trademarks, or service marks; or
f) Requiring indemnification of licensors and authors of that
material by anyone who conveys the material (or modified versions of
it) with contractual assumptions of liability to the recipient, for
any liability that these contractual assumptions directly impose on
those licensors and authors.
All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10. If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term. If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.
If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.
Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.
8. Termination.
You may not propagate or modify a covered work except as expressly
provided under this License. Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).
However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.
Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.
Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License. If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.
9. Acceptance Not Required for Having Copies.
You are not required to accept this License in order to receive or
run a copy of the Program. Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance. However,
nothing other than this License grants you permission to propagate or
modify any covered work. These actions infringe copyright if you do
not accept this License. Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.
10. Automatic Licensing of Downstream Recipients.
Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License. You are not responsible
for enforcing compliance by third parties with this License.
An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations. If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.
You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License. For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.
11. Patents.
A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based. The
work thus licensed is called the contributor's "contributor version".
A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version. For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.
Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.
In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement). To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.
If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients. "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.
If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.
A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License. You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.
Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.
12. No Surrender of Others' Freedom.
If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all. For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.
13. Use with the GNU Affero General Public License.
Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU Affero General Public License into a single
combined work, and to convey the resulting work. The terms of this
License will continue to apply to the part which is the covered work,
but the special requirements of the GNU Affero General Public License,
section 13, concerning interaction through a network will apply to the
combination as such.
14. Revised Versions of this License.
The Free Software Foundation may publish revised and/or new versions of
the GNU General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the
Program specifies that a certain numbered version of the GNU General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation. If the Program does not specify a version number of the
GNU General Public License, you may choose any version ever published
by the Free Software Foundation.
If the Program specifies that a proxy can decide which future
versions of the GNU General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.
Later license versions may give you additional or different
permissions. However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.
15. Disclaimer of Warranty.
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. Limitation of Liability.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.
17. Interpretation of Sections 15 and 16.
If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Also add information on how to contact you by electronic and paper mail.
If the program does terminal interaction, make it output a short
notice like this when it starts in an interactive mode:
<program> Copyright (C) <year> <name of author>
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, your program's commands
might be different; for a GUI interface, you would use an "about box".
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU GPL, see
<http://www.gnu.org/licenses/>.
The GNU General Public License does not permit incorporating your program
into proprietary programs. If your program is a subroutine library, you
may consider it more useful to permit linking proprietary applications with
the library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License. But first, please read
<http://www.gnu.org/philosophy/why-not-lgpl.html>.
-------------------------------------------------------------------------
+384
View File
@@ -0,0 +1,384 @@
v2.9 20th April 2015
- Based on Scintilla v3.5.4.
- Added UserLiteral, InactiveUserLiteral, TaskMarker, InactiveTaskMarker,
EscapeSequence, InactiveEscapeSequence, setHighlightBackQuotedStrings(),
highlightBackQuotedStrings(), setHighlightEscapeSequences(),
highlightEscapeSequences(), setVerbatimStringEscapeSequencesAllowed() and
verbatimStringEscapeSequencesAllowed() to QsciLexerCPP.
- Added CommentKeyword, DeclareInputPort, DeclareOutputPort,
DeclareInputOutputPort, PortConnection and the inactive versions of all
styles to QsciLexerVerilog.
- Added CommentBlock to QsciLexerVHDL.
- Added AnnotationIndented to QsciScintilla::AnnotationDisplay.
- Added FullBoxIndicator, ThickCompositionIndicator, ThinCompositionIndicator
and TextColorIndicator to QsciScintilla::IndicatorStyle.
- Added setIndicatorHoverForegroundColor() and setIndicatorHoverStyle() to
QsciScintilla.
- Added Bookmark to QsciScintilla::MarkerSymbol.
- Added WrapWhitespace to QsciScintilla::WrapMode.
- Added SCLEX_AS, SCLEX_BIBTEX, SCLEX_DMAP, SCLEX_DMIS, SCLEX_IHEX,
SCLEX_REGISTRY, SCLEX_SREC and SCLEX_TEHEX to QsciScintillaBase.
- Added SCI_CHANGEINSERTION to QsciScintillaBase.
- Added SCI_CLEARTABSTOPS, SCI_ADDTABSTOP and SCI_GETNEXTTABSTOP to
QsciScintillaBase.
- Added SCI_GETIMEINTERACTION, SCI_SETIMEINTERACTION, SC_IME_WINDOWED and
SC_IME_INLINE to QsciScintillaBase.
- Added SC_MARK_BOOKMARK to QsciScintillaBase.
- Added INDIC_COMPOSITIONTHIN, INDIC_FULLBOX, INDIC_TEXTFORE, INDIC_IME,
INDIC_IME_MAX, SC_INDICVALUEBIT, SC_INDICVALUEMASK,
SC_INDICFLAG_VALUEBEFORE, SCI_INDICSETHOVERSTYLE, SCI_INDICGETHOVERSTYLE,
SCI_INDICSETHOVERFORE, SCI_INDICGETHOVERFORE, SCI_INDICSETFLAGS and
SCI_INDICGETFLAGS to QsciScintillaBase.
- Added SCI_SETTARGETRANGE and SCI_GETTARGETRANGE to QsciScintillaBase.
- Added SCFIND_CXX11REGEX to QsciScintillaBase.
- Added SCI_CALLTIPSETPOSSTART to QsciScintillaBase.
- Added SC_FOLDFLAG_LINESTATE to QsciScintillaBase.
- Added SC_WRAP_WHITESPACE to QsciScintillaBase.
- Added SC_PHASES_ONE, SC_PHASES_TWO, SC_PHASES_MULTIPLE, SCI_GETPHASESDRAW
and SCI_SETPHASESDRAW to QsciScintillaBase.
- Added SC_STATUS_OK, SC_STATUS_FAILURE, SC_STATUS_BADALLOC,
SC_STATUS_WARN_START and SC_STATUS_WARNREGEX to QsciScintillaBase.
- Added SC_MULTIAUTOC_ONCE, SC_MULTIAUTOC_EACH, SCI_AUTOCSETMULTI and
SCI_AUTOCGETMULTI to QsciScintillaBase.
- Added ANNOTATION_INDENTED to QsciScintillaBase.
- Added SCI_DROPSELECTIONN to QsciScintillaBase.
- Added SC_TECHNOLOGY_DIRECTWRITERETAIN and SC_TECHNOLOGY_DIRECTWRITEDC to
QsciScintillaBase.
- Added SC_LINE_END_TYPE_DEFAULT, SC_LINE_END_TYPE_UNICODE,
SCI_GETLINEENDTYPESSUPPORTED, SCI_SETLINEENDTYPESALLOWED,
SCI_GETLINEENDTYPESALLOWED and SCI_GETLINEENDTYPESACTIVE to
QsciScintillaBase.
- Added SCI_ALLOCATESUBSTYLES, SCI_GETSUBSTYLESSTART, SCI_GETSUBSTYLESLENGTH,
SCI_GETSTYLEFROMSUBSTYLE, SCI_GETPRIMARYSTYLEFROMSTYLE, SCI_FREESUBSTYLES,
SCI_SETIDENTIFIERS, SCI_DISTANCETOSECONDARYSTYLES and SCI_GETSUBSTYLEBASES
to QsciScintillaBase.
- Added SC_MOD_INSERTCHECK and SC_MOD_CHANGETABSTOPS to QsciScintillaBase.
- Qt v3 and PyQt v3 are no longer supported.
v2.8.4 11th September 2014
- Added setHotspotForegroundColor(), resetHotspotForegroundColor(),
setHotspotBackgroundColor(), resetHotspotBackgroundColor(),
setHotspotUnderline() and setHotspotWrap() to QsciScintilla.
- Added SCI_SETHOTSPOTSINGLELINE to QsciScintillaBase.
- Bug fixes.
v2.8.3 3rd July 2014
- Added the QsciLexerCoffeeScript class.
- Font sizes are now handled as floating point values rather than integers.
- Bug fixes.
v2.8.2 26th May 2014
- Added the QsciLexerAVS class.
- Added the QsciLexerPO class.
- Added the --sysroot, --no-sip-files and --no-qsci-api options to the Python
bindings' configure.py.
- Cross-compilation (specifically to iOS and Android) is now supported.
- configure.py has been refactored and relicensed so that it can be used as a
template for wrapping other bindings.
- Bug fixes.
v2.8.1 14th March 2014
- Added support for iOS and Android.
- Added support for retina displays.
- A qscintilla2.prf file is installed so that application .pro files only
need to add CONFIG += qscintilla2.
- Updated the keywords recognised by the Octave lexer.
- Bug fixes.
v2.8 9th November 2013
- Based on Scintilla v3.3.6.
- Added the SCN_FOCUSIN() and SCN_FOCUSOUT() signals to QsciScintillaBase.
- Added PreProcessorCommentLineDoc and InactivePreProcessorCommentLineDoc to
QsciLexerCPP.
- Added SCLEX_LITERATEHASKELL, SCLEX_KVIRC, SCLEX_RUST and SCLEX_STTXT to
QsciScintillaBase.
- Added ThickCompositionIndicator to QsciScintilla::IndicatorStyle.
- Added INDIC_COMPOSITIONTHICK to QsciScintillaBase.
- Added SC_FOLDACTION_CONTRACT, SC_FOLDACTION_EXPAND and SC_FOLDACTION_TOGGLE
to QsciScintillaBase.
- Added SCI_FOLDLINE, SCI_FOLDCHILDREN, SCI_EXPANDCHILDREN and SCI_FOLDALL to
QsciScintillaBase.
- Added SC_AUTOMATICFOLD_SHOW, SC_AUTOMATICFOLD_CLICK and
SC_AUTOMATICFOLD_CHANGE to QsciScintillaBase.
- Added SCI_SETAUTOMATICFOLD and SCI_GETAUTOMATICFOLD to QsciScintillaBase.
- Added SC_ORDER_PRESORTED, SC_ORDER_PERFORMSORT and SC_ORDER_CUSTOM to
QsciScintillaBase.
- Added SCI_AUTOCSETORDER and SCI_AUTOCGETORDER to QsciScintillaBase.
- Added SCI_POSITIONRELATIVE to QsciScintillaBase.
- Added SCI_RELEASEALLEXTENDEDSTYLES and SCI_ALLOCATEEXTENDEDSTYLES to
QsciScintillaBase.
- Added SCI_SCROLLRANGE to QsciScintillaBase.
- Added SCI_SETCARETLINEVISIBLEALWAYS and SCI_GETCARETLINEVISIBLEALWAYS to
QsciScintillaBase.
- Added SCI_SETMOUSESELECTIONRECTANGULARSWITCH and
SCI_GETMOUSESELECTIONRECTANGULARSWITCH to QsciScintillaBase.
- Added SCI_SETREPRESENTATION, SCI_GETREPRESENTATION and
SCI_CLEARREPRESENTATION to QsciScintillaBase.
- Input methods are now properly supported.
v2.7.2 16th June 2013
- The build script for the Python bindings now has a --pyqt argument for
specifying PyQt4 or PyQt5.
- The default EOL mode on OS/X is now EolUnix.
- Bug fixes.
v2.7.1 1st March 2013
- Added support for the final release of Qt v5.
- The build script for the Python bindings should now work with SIP v5.
- Bug fixes.
v2.7 8th December 2012
- Based on Scintilla v3.2.3.
- Added support for Qt v5-rc1.
- Added HashQuotedString, InactiveHashQuotedString, PreProcessorComment,
InactivePreProcessorComment, setHighlightHashQuotedStrings() and
highlightHashQuotedStrings() to QsciLexerCpp.
- Added Variable, setHSSLanguage(), HSSLanguage(), setLessLanguage(),
LessLanguage(), setSCCSLanguage() and SCCSLanguage() to QsciLexerCSS.
- Added setOverwriteMode() and overwriteMode() to QsciScintilla.
- Added wordAtLineIndex() to QsciScintilla.
- Added findFirstInSelection() to QsciScintilla.
- Added CallTipsPosition, callTipsPosition() and setCallTipsPosition() to
QsciScintilla.
- Added WrapFlagInMargin to QsciScintilla::WrapVisualFlag.
- Added SquigglePixmapIndicator to QsciScintilla::IndicatorStyle.
- The weight of a font (rather than whether it is just bold or not) is now
respected.
- Added SCLEX_AVS, SCLEX_COFFEESCRIPT, SCLEX_ECL, SCLEX_OSCRIPT,
SCLEX_TCMD and SCLEX_VISUALPROLOG to QsciScintillaBase.
- Added SC_CASEINSENSITIVEBEHAVIOUR_IGNORECASE and
SC_CASEINSENSITIVEBEHAVIOUR_RESPECTCASE to QsciScintillaBase.
- Added SC_FONT_SIZE_MULTIPLIER to QsciScintillaBase.
- Added SC_WEIGHT_NORMAL, SC_WEIGHT_SEMIBOLD and SC_WEIGHT_BOLD to
QsciScintillaBase.
- Added SC_WRAPVISUALFLAG_MARGIN to QsciScintillaBase.
- Added INDIC_SQUIGGLEPIXMAP to QsciScintillaBase.
- Added SCI_AUTOCSETCASEINSENSITIVEBEHAVIOUR,
SCI_AUTOCGETCASEINSENSITIVEBEHAVIOUR, SCI_CALLTIPSETPOSITION,
SCI_COUNTCHARACTERS, SCI_CREATELOADER, SCI_DELETERANGE,
SCI_FINDINDICATORFLASH, SCI_FINDINDICATORHIDE, SCI_FINDINDICATORSHOW,
SCI_GETALLLINESVISIBLE, SCI_GETGAPPOSITION, SCI_GETPUNCTUATIONCHARS,
SCI_GETRANGEPOINTER, SCI_GETSELECTIONEMPTY, SCI_GETTECHNOLOGY,
SCI_GETWHITESPACECHARS, SCI_GETWORDCHARS, SCI_RGBAIMAGESETSCALE,
SCI_SETPUNCTUATIONCHARS, SCI_SETTECHNOLOGY, SCI_STYLESETSIZEFRACTIONAL,
SCI_STYLEGETSIZEFRACTIONAL, SCI_STYLESETWEIGHT and SCI_STYLEGETWEIGHT to
QsciScintillaBase.
- Removed SCI_GETUSEPALETTE and SCI_SETUSEPALETTE from QsciScintillaBase.
- Bug fixes.
v2.6.2 20th June 2012
- Added support for Qt v5-alpha.
- QsciLexer::wordCharacters() is now part of the public API.
- Bug fixes.
v2.6.1 10th February 2012
- Support SCI_NAMESPACE to enable all internal Scintilla classes to be put
into the Scintilla namespace.
- APIs now allow for spaces between the end of a word and the opening
parenthesis.
- Building against Qt v3 is fixed.
v2.6 11th November 2011
- Based on Scintilla v2.29.
- Added Command, command() and execute() to QsciCommand.
- Added boundTo() and find() to QsciCommandSet.
- Added createStandardContextMenu() to QsciScintilla.
- Added StraightBoxIndicator, DashesIndicator, DotsIndicator,
SquiggleLowIndicator and DotBoxIndicator to QsciScintilla::IndicatorStyle.
- Added markerDefine() to QsciScintilla.
- Added MoNone, MoSublineSelect, marginOptions() and setMarginOptions() to
QsciScintilla.
- Added registerImage() to QsciScintilla.
- Added setIndicatorOutlineColor() to QsciScintilla.
- Added setMatchedBraceIndicator(), resetMatchedBraceIndicator(),
setUnmatchedBraceIndicator() and resetUnmatchedBraceIndicator() to
QsciScintilla.
- Added highlightTripleQuotedStrings() and setHighlightTripleQuotedStrings()
to QsciLexerCpp.
- Added Label to QsciLexerLua.
- Added DoubleQuotedStringVar, Translation, RegexVar, SubstitutionVar,
BackticksVar, DoubleQuotedHereDocumentVar, BacktickHereDocumentVar,
QuotedStringQQVar, QuotedStringQXVar, QuotedStringQRVar, setFoldAtElse()
and foldAtElse() to QsciLexerPerl.
- Added highlightSubidentifiers() and setHighlightSubidentifiers() to
QsciLexerPython.
- Added INDIC_STRAIGHTBOX, INDIC_DASH, INDIC_DOTS, INDIC_SQUIGGLELOW and
INDIC_DOTBOX to QsciScintillaBase.
- Added SC_MARGINOPTION_NONE and SC_MARGINOPTION_SUBLINESELECT to
QsciScintillaBase.
- Added SC_MARK_RGBAIMAGE to QsciScintillaBase.
- Added SCI_BRACEBADLIGHTINDICATOR, SCI_BRACEHIGHLIGHTINDICATOR,
SCI_GETIDENTIFIER, SCI_GETMARGINOPTIONS, SCI_INDICGETOUTLINEALPHA,
SCI_INDICSETOUTLINEALPHA, SCI_MARKERDEFINERGBAIMAGE,
SCI_MARKERENABLEHIGHLIGHT, SCI_MARKERSETBACKSELECTED,
SCI_MOVESELECTEDLINESDOWN, SCI_MOVESELECTEDLINESUP, SCI_REGISTERRGBAIMAGE,
SCI_RGBAIMAGESETHEIGHT, SCI_RGBAIMAGESETWIDTH, SCI_SCROLLTOEND,
SCI_SCROLLTOSTART, SCI_SETEMPTYSELECTION, SCI_SETIDENTIFIER and
SCI_SETMARGINOPTIONS to QsciScintillaBase.
v2.5.1 17th April 2011
- Added QsciLexerMatlab and QsciLexerOctave.
v2.5 29th March 2011
- Based on Scintilla v2.25.
- Rectangular selections are now fully supported and compatible with SciTE.
- The signature of the fromMimeData() and toMimeData() methods of
QsciScintillaBase have changed incompatibly in order to support rectangular
selections.
- Added QsciScintilla::setAutoCompletionUseSingle() to replace the now
deprecated setAutoCompletionShowSingle().
- Added QsciScintilla::autoCompletionUseSingle() to replace the now
deprecated autoCompletionShowSingle().
- QsciScintilla::setAutoCompletionCaseSensitivity() is no longer ignored if a
lexer has been set.
- Added FullRectangle, LeftRectangle and Underline to the
QsciScintilla::MarkerSymbol enum.
- Added setExtraAscent(), extraAscent(), setExtraDescent() and extraDescent()
to QsciScintilla.
- Added setWhitespaceSize() and whitespaceSize() to QsciScintilla.
- Added replaceSelectedText() to QsciScintilla.
- Added setWhitespaceBackgroundColor() and setWhitespaceForegroundColor() to
QsciScintilla.
- Added setWrapIndentMode() and wrapIndentMode() to QsciScintilla.
- Added setFirstVisibleLine() to QsciScintilla.
- Added setContractedFolds() and contractedFolds() to QsciScintilla.
- Added the SCN_HOTSPOTRELEASECLICK() signal to QsciScintillaBase.
- The signature of the QsciScintillaBase::SCN_UPDATEUI() signal has changed.
- Added the RawString and inactive styles to QsciLexerCPP.
- Added MediaRule to QsciLexerCSS.
- Added BackquoteString, RawString, KeywordSet5, KeywordSet6 and KeywordSet7
to QsciLexerD.
- Added setDjangoTemplates(), djangoTemplates(), setMakoTemplates() and
makoTemplates() to QsciLexerHTML.
- Added KeywordSet5, KeywordSet6, KeywordSet7 and KeywordSet8 to
QsciLexerLua.
- Added setInitialSpaces() and initialSpaces() to QsciLexerProperties.
- Added setFoldCompact(), foldCompact(), setStringsOverNewlineAllowed() and
stringsOverNewlineAllowed() to QsciLexerPython.
- Added setFoldComments(), foldComments(), setFoldCompact() and foldCompact()
to QsciLexerRuby.
- Added setFoldComments() and foldComments(), and removed setFoldCompact()
and foldCompact() from QsciLexerTCL.
- Added setFoldComments(), foldComments(), setFoldCompact(), foldCompact(),
setProcessComments(), processComments(), setProcessIf(), and processIf() to
QsciLexerTeX.
- Added QuotedIdentifier, setDottedWords(), dottedWords(), setFoldAtElse(),
foldAtElse(), setFoldOnlyBegin(), foldOnlyBegin(), setHashComments(),
hashComments(), setQuotedIdentifiers() and quotedIdentifiers() to
QsciLexerSQL.
- The Python bindings now allow optional arguments to be specified as keyword
arguments.
- The Python bindings will now build using the protected-is-public hack if
possible.
v2.4.6 23rd December 2010
- Added support for indicators to the high-level API, i.e. added the
IndicatorStyle enum, the clearIndicatorRange(), fillIndicatorRange(),
indicatorDefine(), indicatorDrawUnder(), setIndicatorDrawUnder() and
setIndicatorForegroundColor methods, and the indicatorClicked() and
indicatorReleased() signals to QsciScintilla.
- Added support for the Key style in QsciLexerProperties.
- Added an API file for Python v2.7.
- Added the --no-timestamp command line option to the Python bindings'
configure.py.
v2.4.5 31st August 2010
- A bug fix release.
v2.4.4 12th July 2010
- Added the canInsertFromMimeData(), fromMimeData() and toMimeData() methods
to QsciScintillaBase.
- QsciScintilla::markerDefine() now allows existing markers to be redefined.
v2.4.3 17th March 2010
- Added clearFolds() to QsciScintilla.
v2.4.2 20th January 2010
- Updated Spanish translations from Jaime Seuma.
- Fixed compilation problems with Qt v3 and Qt v4 prior to v4.5.
v2.4.1 14th January 2010
- Added the QsciLexerSpice and QsciLexerVerilog classes.
- Significant performance improvements when handling long lines.
- The Python bindings include automatically generated docstrings by default.
- Added an API file for Python v3.
v2.4 5th June 2009
- Based on Scintilla v1.78.
- Added the QsciLexerCustom, QsciStyle and QsciStyledText classes.
- Added annotate(), annotation(), clearAnnotations(), setAnnotationDisplay()
and annotationDisplay() to QsciScintilla.
- Added setMarginText(), clearMarginText(), setMarginType() and marginType()
to QsciScintilla.
- Added QsciLexer::lexerId() so that container lexers can be implemented.
- Added editor() and styleBitsNeeded() to QsciLexer.
- Added setDollarsAllowed() and dollarsAllowed() to QsciLexerCPP.
- Added setFoldScriptComments(), foldScriptComments(),
setFoldScriptHeredocs() and foldScriptHeredocs() to QsciLexerHTML.
- Added setSmartHighlighting() and smartHighlighting() to QsciLexerPascal.
(Note that the Scintilla Pascal lexer has changed so that any saved colour
and font settings will not be properly restored.)
- Added setFoldPackages(), foldPackages(), setFoldPODBlocks() and
foldPODBlocks() to QsciLexerPerl.
- Added setV2UnicodeAllowed(), v2UnicodeAllowed(), setV3BinaryOctalAllowed(),
v3BinaryOctalAllowed(), setV3BytesAllowed and v3BytesAllowed() to
QsciLexerPython.
- Added setScriptsStyled() and scriptsStyled() to QsciLexerXML.
- Added Spanish translations from Jaime Seuma.
v2.3.2 17th November 2008
- A bug fix release.
v2.3.1 6th November 2008
- Based on Scintilla v1.77.
- Added the read() and write() methods to QsciScintilla to allow a file to be
read and written while minimising the conversions.
- Added the positionFromLineIndex() and lineIndexFromPosition() methods to
QsciScintilla to convert between a Scintilla character address and a
QScintilla character address.
- Added QsciScintilla::wordAtPoint() to return the word at the given screen
coordinates.
- QSciScintilla::setSelection() now allows the carat to be left at either the
start or the end of the selection.
- 'with' is now treated as a keyword by the Python lexer.
v2.3 20th September 2008
- Based on Scintilla v1.76.
- The new QsciAbstractAPIs class allows applications to replace the default
implementation of the language APIs used for auto-completion lists and call
tips.
- Added QsciScintilla::apiContext() to allow applications to determine the
context used for auto-completion and call tips.
- Added the QsciLexerFortran, QsciLexerFortran77, QsciLexerPascal,
QsciLexerPostScript, QsciLexerTCL, QsciLexerXML and QsciLexerYAML classes.
- QsciScintilla::setFolding() will now accept an optional margin number.
v2.2 27th February 2008
- Based on Scintilla v1.75.
- A lexer's default colour, paper and font are now written to and read from
the settings.
- Windows64 is now supported.
- The signature of the QsciScintillaBase::SCN_MACRORECORD() signal has
changed slightly.
- Changed the licensing to match the current Qt licenses, including GPL v3.
v2.1 1st June 2007
- A slightly revised API, incompatible with QScintilla v2.0.
- Lexers now remember their style settings. A lexer no longer has to be the
current lexer when changing a style's color, end-of-line fill, font or
paper.
- The color(), eolFill(), font() and paper() methods of QsciLexer now return
the current values for a style rather than the default values.
- The setDefaultColor(), setDefaultFont() and setDefaultPaper() methods of
QsciLexer are no longer slots and no longer virtual.
- The defaultColor(), defaultFont() and defaultPaper() methods of QsciLexer
are no longer virtual.
- The color(), eolFill(), font() and paper() methods of all QsciLexer derived
classes (except for QsciLexer itself) have been renamed defaultColor(),
defaultEolFill(), defaultFont() and defaultPaper() respectively.
v2.0 26th May 2007
- A revised API, incompatible with QScintilla v1.
- Hugely improved autocompletion and call tips support.
- Supports both Qt v3 and Qt v4.
- Includes Python bindings.
+158
View File
@@ -0,0 +1,158 @@
cmake_minimum_required(VERSION 2.8.7)
if(USE_QT5)
set(CMAKE_AUTOMOC ON)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
find_package(Qt5Widgets REQUIRED)
else()
find_package(Qt4 COMPONENTS QtCore QtGui REQUIRED)
include("${QT_USE_FILE}")
add_definitions(${QT_DEFINITIONS})
endif()
add_definitions(-DSCINTILLA_QT)
add_definitions(-DSCI_LEXER)
set(QSCINTILLA_SRC
qsciscintilla.cpp
qsciscintillabase.cpp
qsciabstractapis.cpp
qsciapis.cpp
qscicommand.cpp
qscicommandset.cpp
qscidocument.cpp
qscilexer.cpp
qscilexersql.cpp
qscimacro.cpp
qsciprinter.cpp
qscistyle.cpp
qscistyledtext.cpp
MacPasteboardMime.cpp
InputMethod.cpp
SciClasses.cpp
ListBoxQt.cpp
PlatQt.cpp
ScintillaQt.cpp
../lexers/LexSQL.cpp
../lexlib/Accessor.cpp
../lexlib/CharacterCategory.cpp
../lexlib/CharacterSet.cpp
../lexlib/LexerBase.cpp
../lexlib/LexerModule.cpp
../lexlib/LexerNoExceptions.cpp
../lexlib/LexerSimple.cpp
../lexlib/PropSetSimple.cpp
../lexlib/StyleContext.cpp
../lexlib/WordList.cpp
../src/AutoComplete.cpp
../src/CallTip.cpp
../src/CaseConvert.cpp
../src/CaseFolder.cpp
../src/Catalogue.cpp
../src/CellBuffer.cpp
../src/CharClassify.cpp
../src/ContractionState.cpp
../src/Decoration.cpp
../src/Document.cpp
../src/Editor.cpp
../src/EditModel.cpp
../src/EditView.cpp
../src/ExternalLexer.cpp
../src/Indicator.cpp
../src/KeyMap.cpp
../src/LineMarker.cpp
../src/MarginView.cpp
../src/PerLine.cpp
../src/PositionCache.cpp
../src/RESearch.cpp
../src/RunStyles.cpp
../src/ScintillaBase.cpp
../src/Selection.cpp
../src/Style.cpp
../src/UniConversion.cpp
../src/ViewStyle.cpp
../src/XPM.cpp
)
set(QSCINTILLA_HDR
)
set(QSCINTILLA_MOC_HDR
./Qsci/qsciglobal.h
./Qsci/qsciscintilla.h
./Qsci/qsciscintillabase.h
./Qsci/qsciabstractapis.h
./Qsci/qsciapis.h
./Qsci/qscicommand.h
./Qsci/qscicommandset.h
./Qsci/qscidocument.h
./Qsci/qscilexer.h
./Qsci/qscilexersql.h
./Qsci/qscimacro.h
./Qsci/qsciprinter.h
./Qsci/qscistyle.h
./Qsci/qscistyledtext.h
ListBoxQt.h
SciClasses.h
SciNamespace.h
ScintillaQt.h
../include/ILexer.h
../include/Platform.h
../include/SciLexer.h
../include/Scintilla.h
../include/ScintillaWidget.h
../lexlib/Accessor.h
../lexlib/CharacterCategory.h
../lexlib/CharacterSet.h
../lexlib/LexAccessor.h
../lexlib/LexerBase.h
../lexlib/LexerModule.h
../lexlib/LexerNoExceptions.h
../lexlib/LexerSimple.h
../lexlib/OptionSet.h
../lexlib/PropSetSimple.h
../lexlib/StyleContext.h
../lexlib/SubStyles.h
../lexlib/WordList.h
../src/AutoComplete.h
../src/CallTip.h
../src/CaseConvert.h
../src/CaseFolder.h
../src/Catalogue.h
../src/CellBuffer.h
../src/CharClassify.h
../src/ContractionState.h
../src/Decoration.h
../src/Document.h
../src/Editor.h
../src/ExternalLexer.h
../src/FontQuality.h
../src/Indicator.h
../src/KeyMap.h
../src/LineMarker.h
../src/Partitioning.h
../src/PerLine.h
../src/PositionCache.h
../src/RESearch.h
../src/RunStyles.h
../src/ScintillaBase.h
../src/Selection.h
../src/SplitVector.h
../src/Style.h
../src/UnicodeFromUTF8.h
../src/UniConversion.h
../src/ViewStyle.h
../src/XPM.h
)
if(NOT USE_QT5)
QT4_WRAP_CPP(QSCINTILLA_MOC ${QSCINTILLA_MOC_HDR})
endif()
include_directories(. ../include ../lexlib ../src)
add_library(qscintilla2 ${QSCINTILLA_SRC} ${QSCINTILLA_HDR} ${QSCINTILLA_MOC_HDR} ${QSCINTILLA_MOC})
if(USE_QT5)
qt5_use_modules(qscintilla2 Widgets PrintSupport)
endif()
+182
View File
@@ -0,0 +1,182 @@
// Copyright (c) 2015 Riverbank Computing Limited
// Copyright (c) 2011 Archaeopteryx Software, Inc.
// Copyright (c) 1990-2011, Scientific Toolworks, Inc.
//
// The License.txt file describes the conditions under which this software may
// be distributed.
#include <qglobal.h>
#include "Qsci/qsciscintillabase.h"
#include <QColor>
#include <QFont>
#include <QInputMethodEvent>
#include <QRect>
#include <QTextCharFormat>
#include <QTextFormat>
#include <QVariant>
#include <QVarLengthArray>
#include "ScintillaQt.h"
#define INDIC_INPUTMETHOD 24
void QsciScintillaBase::inputMethodEvent(QInputMethodEvent *event)
{
// Do nothing if it appears to be a non-event. This can sometimes happen
// (but why?) on losing focus.
if (event->commitString().isEmpty() && event->preeditString().isEmpty() && event->replacementLength() == 0)
return;
ScintillaBytes bytes;
// Clear the current selection.
sci->ClearSelection();
if (preeditPos >= 0)
sci->SetSelection(preeditPos, preeditPos);
// Insert the commit string.
if (!event->commitString().isEmpty() || event->replacementLength()) {
// Select the text to be removed.
int commitPos = SendScintilla(SCI_GETCURRENTPOS);
int start = commitPos + event->replacementStart();
int end = start + event->replacementLength();
sci->SetSelection(start, end);
// Replace the selection with the commit string.
bytes = textAsBytes(event->commitString());
sci->AddCharUTF(bytes.data(), bytes.length());
}
// Select the previous preedit string.
int pos = SendScintilla(SCI_GETCURRENTPOS);
sci->SetSelection(pos, pos + preeditNrBytes);
// Replace the selection with the new preedit string.
bool recording = sci->recordingMacro;
sci->recordingMacro = false;
SendScintilla(SCI_SETUNDOCOLLECTION, false);
bytes = textAsBytes(event->preeditString());
sci->AddCharUTF(bytes.data(), bytes.length());
SendScintilla(SCI_SETUNDOCOLLECTION, true);
sci->recordingMacro = recording;
sci->SetSelection(pos, pos);
// Store the state of the current preedit string.
preeditString = event->preeditString();
preeditNrBytes = bytes.length();
preeditPos = preeditNrBytes ? SendScintilla(SCI_GETCURRENTPOS) : -1;
if (preeditNrBytes) {
// Apply attributes to the preedit string.
int indicNum = 0;
sci->ShowCaretAtCurrentPosition();
foreach (QInputMethodEvent::Attribute a, event->attributes()) {
QString prefix = preeditString.left(a.start);
int prefixLength = textAsBytes(prefix).length();
int caretPos = preeditPos + prefixLength;
if (a.type == QInputMethodEvent::Cursor) {
sci->SetSelection(caretPos, caretPos);
if (!a.length)
sci->DropCaret();
} else if (a.type == QInputMethodEvent::TextFormat) {
Q_ASSERT(a.value.canConvert(QVariant::TextFormat));
QTextFormat format = a.value.value<QTextFormat>();
Q_ASSERT(format.isCharFormat());
QTextCharFormat charFormat = format.toCharFormat();
if (charFormat.underlineStyle() != QTextCharFormat::NoUnderline) {
QString sub = preeditString.mid(a.start, a.length);
int subLength = textAsBytes(sub).length();
// Set temporary indicator for underline style.
QColor uc = charFormat.underlineColor();
int style = INDIC_COMPOSITIONTHICK;
if (charFormat.underlineStyle() == QTextCharFormat::DashUnderline)
style = INDIC_DASH;
SendScintilla(SCI_INDICSETSTYLE, INDIC_INPUTMETHOD + indicNum, style);
SendScintilla(SCI_INDICSETFORE, INDIC_INPUTMETHOD + indicNum, uc.rgb());
SendScintilla(SCI_SETINDICATORCURRENT, INDIC_INPUTMETHOD + indicNum);
SendScintilla(SCI_INDICATORFILLRANGE, caretPos, subLength);
indicNum++;
}
}
}
}
}
QVariant QsciScintillaBase::inputMethodQuery(Qt::InputMethodQuery query) const
{
int pos = SendScintilla(SCI_GETCURRENTPOS);
int line = SendScintilla(SCI_LINEFROMPOSITION, pos);
switch (query) {
#if QT_VERSION >= 0x050000
case Qt::ImHints:
return QWidget::inputMethodQuery(query);
#endif
case Qt::ImMicroFocus:
{
int startPos = (preeditPos >= 0) ? preeditPos : pos;
Point pt = sci->LocationFromPosition(startPos);
int width = SendScintilla(SCI_GETCARETWIDTH);
int height = SendScintilla(SCI_TEXTHEIGHT, line);
return QRect(pt.x, pt.y, width, height);
}
case Qt::ImFont:
{
char fontName[64];
int style = SendScintilla(SCI_GETSTYLEAT, pos);
int len = SendScintilla(SCI_STYLEGETFONT, style, (sptr_t)fontName);
int size = SendScintilla(SCI_STYLEGETSIZE, style);
bool italic = SendScintilla(SCI_STYLEGETITALIC, style);
int weight = SendScintilla(SCI_STYLEGETBOLD, style) ? QFont::Bold : -1;
return QFont(QString::fromUtf8(fontName, len), size, weight, italic);
}
case Qt::ImCursorPosition:
{
int paraStart = sci->pdoc->ParaUp(pos);
return pos - paraStart;
}
case Qt::ImSurroundingText:
{
int paraStart = sci->pdoc->ParaUp(pos);
int paraEnd = sci->pdoc->ParaDown(pos);
QVarLengthArray<char,1024> buffer(paraEnd - paraStart + 1);
Sci_CharacterRange charRange;
charRange.cpMin = paraStart;
charRange.cpMax = paraEnd;
Sci_TextRange textRange;
textRange.chrg = charRange;
textRange.lpstrText = buffer.data();
SendScintilla(SCI_GETTEXTRANGE, 0, (sptr_t)&textRange);
return bytesAsText(buffer.constData());
}
case Qt::ImCurrentSelection:
{
QVarLengthArray<char,1024> buffer(SendScintilla(SCI_GETSELTEXT));
SendScintilla(SCI_GETSELTEXT, 0, (sptr_t)buffer.data());
return bytesAsText(buffer.constData());
}
default:
return QVariant();
}
}
+328
View File
@@ -0,0 +1,328 @@
// This module implements the specialisation of QListBox that handles the
// Scintilla double-click callback.
//
// Copyright (c) 2015 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 "ListBoxQt.h"
#include <stdlib.h>
#include "SciClasses.h"
#include "Qsci/qsciscintilla.h"
QsciListBoxQt::QsciListBoxQt()
: cb_action(0), cb_data(0), slb(0), visible_rows(5), utf8(false)
{
}
void QsciListBoxQt::SetFont(QSCI_SCI_NAMESPACE(Font) &font)
{
QFont *f = reinterpret_cast<QFont *>(font.GetID());
if (f)
slb->setFont(*f);
}
void QsciListBoxQt::Create(QSCI_SCI_NAMESPACE(Window) &parent, int,
QSCI_SCI_NAMESPACE(Point), int, bool unicodeMode, int)
{
utf8 = unicodeMode;
// The parent we want is the QsciScintillaBase, not the text area.
wid = slb = new QsciSciListBox(reinterpret_cast<QWidget *>(parent.GetID())->parentWidget(), this);
}
void QsciListBoxQt::SetAverageCharWidth(int)
{
// We rely on sizeHint() for the size of the list box rather than make
// calculations based on the average character width and the number of
// visible rows.
}
void QsciListBoxQt::SetVisibleRows(int vrows)
{
// We only pretend to implement this.
visible_rows = vrows;
}
int QsciListBoxQt::GetVisibleRows() const
{
return visible_rows;
}
QSCI_SCI_NAMESPACE(PRectangle) QsciListBoxQt::GetDesiredRect()
{
QSCI_SCI_NAMESPACE(PRectangle) rc(0, 0, 100, 100);
if (slb)
{
QSize sh = slb->sizeHint();
rc.right = sh.width();
rc.bottom = sh.height();
}
return rc;
}
int QsciListBoxQt::CaretFromEdge()
{
int dist = 0;
// Find the width of the biggest image.
for (xpmMap::const_iterator it = xset.begin(); it != xset.end(); ++it)
{
int w = it.value().width();
if (dist < w)
dist = w;
}
if (slb)
dist += slb->frameWidth();
// Fudge factor - adjust if required.
dist += 3;
return dist;
}
void QsciListBoxQt::Clear()
{
Q_ASSERT(slb);
slb->clear();
}
void QsciListBoxQt::Append(char *s, int type)
{
Q_ASSERT(slb);
QString qs;
if (utf8)
qs = QString::fromUtf8(s);
else
qs = QString::fromLatin1(s);
xpmMap::const_iterator it;
if (type < 0 || (it = xset.find(type)) == xset.end())
slb->addItem(qs);
else
slb->addItemPixmap(it.value(), qs);
}
int QsciListBoxQt::Length()
{
Q_ASSERT(slb);
return slb->count();
}
void QsciListBoxQt::Select(int n)
{
Q_ASSERT(slb);
slb->setCurrentRow(n);
}
int QsciListBoxQt::GetSelection()
{
Q_ASSERT(slb);
return slb->currentRow();
}
int QsciListBoxQt::Find(const char *prefix)
{
Q_ASSERT(slb);
return slb->find(prefix);
}
void QsciListBoxQt::GetValue(int n, char *value, int len)
{
Q_ASSERT(slb);
QString selection = slb->text(n);
bool trim_selection = false;
QObject *sci_obj = slb->parent();
if (sci_obj->inherits("QsciScintilla"))
{
QsciScintilla *sci = static_cast<QsciScintilla *>(sci_obj);
if (sci->isAutoCompletionList())
{
// Save the full selection and trim the value we return.
sci->acSelection = selection;
trim_selection = true;
}
}
if (selection.isEmpty() || len <= 0)
value[0] = '\0';
else
{
const char *s;
int slen;
QByteArray bytes;
if (utf8)
bytes = selection.toUtf8();
else
bytes = selection.toLatin1();
s = bytes.data();
slen = bytes.length();
while (slen-- && len--)
{
if (trim_selection && *s == ' ')
break;
*value++ = *s++;
}
*value = '\0';
}
}
void QsciListBoxQt::Sort()
{
Q_ASSERT(slb);
slb->sortItems();
}
void QsciListBoxQt::RegisterImage(int type, const char *xpm_data)
{
xset.insert(type, *reinterpret_cast<const QPixmap *>(xpm_data));
}
void QsciListBoxQt::RegisterRGBAImage(int type, int, int,
const unsigned char *pixelsImage)
{
QPixmap pm;
#if QT_VERSION >= 0x040700
pm.convertFromImage(*reinterpret_cast<const QImage *>(pixelsImage));
#else
pm = QPixmap::fromImage(*reinterpret_cast<const QImage *>(pixelsImage));
#endif
xset.insert(type, pm);
}
void QsciListBoxQt::ClearRegisteredImages()
{
xset.clear();
}
void QsciListBoxQt::SetDoubleClickAction(
QSCI_SCI_NAMESPACE(CallBackAction) action, void *data)
{
cb_action = action;
cb_data = data;
}
void QsciListBoxQt::SetList(const char *list, char separator, char typesep)
{
char *words;
Clear();
if ((words = qstrdup(list)) != NULL)
{
char *startword = words;
char *numword = NULL;
for (int i = 0; words[i] != '\0'; i++)
{
if (words[i] == separator)
{
words[i] = '\0';
if (numword)
*numword = '\0';
Append(startword, numword ? atoi(numword + 1) : -1);
startword = words + i + 1;
numword = NULL;
}
else if (words[i] == typesep)
{
numword = words + i;
}
}
if (startword)
{
if (numword)
*numword = '\0';
Append(startword, numword ? atoi(numword + 1) : -1);
}
delete[] words;
}
}
// The ListBox methods that need to be implemented explicitly.
QSCI_SCI_NAMESPACE(ListBox)::ListBox()
{
}
QSCI_SCI_NAMESPACE(ListBox)::~ListBox()
{
}
QSCI_SCI_NAMESPACE(ListBox) *QSCI_SCI_NAMESPACE(ListBox)::Allocate()
{
return new QsciListBoxQt();
}
+76
View File
@@ -0,0 +1,76 @@
// This defines the specialisation of QListBox that handles the Scintilla
// double-click callback.
//
// Copyright (c) 2015 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 <qmap.h>
#include <qpixmap.h>
#include <qstring.h>
#include "SciNamespace.h"
#include "Platform.h"
class QsciSciListBox;
// This is an internal class but it is referenced by a public class so it has
// to have a Qsci prefix rather than being put in the Scintilla namespace
// which would mean exposing the SCI_NAMESPACE mechanism).
class QsciListBoxQt : public QSCI_SCI_NAMESPACE(ListBox)
{
public:
QsciListBoxQt();
QSCI_SCI_NAMESPACE(CallBackAction) cb_action;
void *cb_data;
virtual void SetFont(QSCI_SCI_NAMESPACE(Font) &font);
virtual void Create(QSCI_SCI_NAMESPACE(Window) &parent, int,
QSCI_SCI_NAMESPACE(Point), int, bool unicodeMode, int);
virtual void SetAverageCharWidth(int);
virtual void SetVisibleRows(int);
virtual int GetVisibleRows() const;
virtual QSCI_SCI_NAMESPACE(PRectangle) GetDesiredRect();
virtual int CaretFromEdge();
virtual void Clear();
virtual void Append(char *s, int type = -1);
virtual int Length();
virtual void Select(int n);
virtual int GetSelection();
virtual int Find(const char *prefix);
virtual void GetValue(int n, char *value, int len);
virtual void Sort();
virtual void RegisterImage(int type, const char *xpm_data);
virtual void RegisterRGBAImage(int type, int width, int height,
const unsigned char *pixelsImage);
virtual void ClearRegisteredImages();
virtual void SetDoubleClickAction(
QSCI_SCI_NAMESPACE(CallBackAction) action, void *data);
virtual void SetList(const char *list, char separator, char typesep);
private:
QsciSciListBox *slb;
int visible_rows;
bool utf8;
typedef QMap<int, QPixmap> xpmMap;
xpmMap xset;
};
@@ -0,0 +1,111 @@
// This module implements part of the support for rectangular selections on
// OS/X. It is a separate file to avoid clashes between OS/X and Scintilla
// data types.
//
// Copyright (c) 2015 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 <qglobal.h>
#if (QT_VERSION >= 0x040200 && QT_VERSION < 0x050000 && defined(Q_OS_MAC)) || (QT_VERSION >= 0x050200 && defined(Q_OS_OSX))
#include <QByteArray>
#include <QLatin1String>
#include <QList>
#include <QString>
#include <QStringList>
#include <QVariant>
#include <QMacPasteboardMime>
static const QLatin1String mimeRectangular("text/x-qscintilla-rectangular");
static const QLatin1String utiRectangularMac("com.scintilla.utf16-plain-text.rectangular");
class RectangularPasteboardMime : public QMacPasteboardMime
{
public:
RectangularPasteboardMime() : QMacPasteboardMime(MIME_ALL)
{
}
bool canConvert(const QString &mime, QString flav)
{
return mime == mimeRectangular && flav == utiRectangularMac;
}
QList<QByteArray> convertFromMime(const QString &, QVariant data, QString)
{
QList<QByteArray> converted;
converted.append(data.toByteArray());
return converted;
}
QVariant convertToMime(const QString &, QList<QByteArray> data, QString)
{
QByteArray converted;
foreach (QByteArray i, data)
{
converted += i;
}
return QVariant(converted);
}
QString convertorName()
{
return QString("QScintillaRectangular");
}
QString flavorFor(const QString &mime)
{
if (mime == mimeRectangular)
return QString(utiRectangularMac);
return QString();
}
QString mimeFor(QString flav)
{
if (flav == utiRectangularMac)
return QString(mimeRectangular);
return QString();
}
};
// Initialise the singleton instance.
void initialiseRectangularPasteboardMime()
{
static RectangularPasteboardMime *instance = 0;
if (!instance)
{
instance = new RectangularPasteboardMime();
qRegisterDraggedTypes(QStringList(utiRectangularMac));
}
}
#endif
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,98 @@
// This module defines interface to the QsciAbstractAPIs class.
//
// Copyright (c) 2015 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.
#ifndef QSCIABSTRACTAPIS_H
#define QSCIABSTRACTAPIS_H
#ifdef __APPLE__
extern "C++" {
#endif
#include <QList>
#include <QObject>
#include <QStringList>
#include <Qsci/qsciglobal.h>
#include <Qsci/qsciscintilla.h>
class QsciLexer;
//! \brief The QsciAbstractAPIs class represents the interface to the textual
//! API information used in call tips and for auto-completion. A sub-class
//! will provide the actual implementation of the interface.
//!
//! API information is specific to a particular language lexer but can be
//! shared by multiple instances of the lexer.
class QSCINTILLA_EXPORT QsciAbstractAPIs : public QObject
{
Q_OBJECT
public:
//! Constructs a QsciAbstractAPIs instance attached to lexer \a lexer. \a
//! lexer becomes the instance's parent object although the instance can
//! also be subsequently attached to other lexers.
QsciAbstractAPIs(QsciLexer *lexer);
//! Destroy the QsciAbstractAPIs instance.
virtual ~QsciAbstractAPIs();
//! Return the lexer that the instance is attached to.
QsciLexer *lexer() const;
//! Update the list \a list with API entries derived from \a context. \a
//! context is the list of words in the text preceding the cursor position.
//! The characters that make up a word and the characters that separate
//! words are defined by the lexer. The last word is a partial word and
//! may be empty if the user has just entered a word separator.
virtual void updateAutoCompletionList(const QStringList &context,
QStringList &list) = 0;
//! This is called when the user selects the entry \a selection from the
//! auto-completion list. A sub-class can use this as a hint to provide
//! more specific API entries in future calls to
//! updateAutoCompletionList(). The default implementation does nothing.
virtual void autoCompletionSelected(const QString &selection);
//! Return the call tips valid for the context \a context. (Note that the
//! last word of the context will always be empty.) \a commas is the number
//! of commas the user has typed after the context and before the cursor
//! position. The exact position of the list of call tips can be adjusted
//! by specifying a corresponding left character shift in \a shifts. This
//! is normally done to correct for any displayed context according to \a
//! style.
//!
//! \sa updateAutoCompletionList()
virtual QStringList callTips(const QStringList &context, int commas,
QsciScintilla::CallTipsStyle style, QList<int> &shifts) = 0;
private:
QsciLexer *lex;
QsciAbstractAPIs(const QsciAbstractAPIs &);
QsciAbstractAPIs &operator=(const QsciAbstractAPIs &);
};
#ifdef __APPLE__
}
#endif
#endif
+221
View File
@@ -0,0 +1,221 @@
// This module defines interface to the QsciAPIs class.
//
// Copyright (c) 2015 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.
#ifndef QSCIAPIS_H
#define QSCIAPIS_H
#ifdef __APPLE__
extern "C++" {
#endif
#include <QList>
#include <QObject>
#include <QPair>
#include <QStringList>
#include <Qsci/qsciabstractapis.h>
#include <Qsci/qsciglobal.h>
#include <Qsci/qsciscintilla.h>
class QsciAPIsPrepared;
class QsciAPIsWorker;
class QsciLexer;
//! \brief The QsciAPIs class provies an implementation of the textual API
//! information used in call tips and for auto-completion.
//!
//! Raw API information is read from one or more files. Each API function is
//! described by a single line of text comprising the function's name, followed
//! by the function's optional comma separated parameters enclosed in
//! parenthesis, and finally followed by optional explanatory text.
//!
//! A function name may be followed by a `?' and a number. The number is used
//! by auto-completion to display a registered QPixmap with the function name.
//!
//! All function names are used by auto-completion, but only those that include
//! function parameters are used in call tips.
//!
//! QScintilla only deals with prepared API information and not the raw
//! information described above. This is done so that large APIs can be
//! handled while still being responsive to user input. The conversion of raw
//! information to prepared information is time consuming (think tens of
//! seconds) and implemented in a separate thread. Prepared information can
//! be quickly saved to and loaded from files. Such files are portable between
//! different architectures.
//!
//! QScintilla based applications that want to support large APIs would
//! normally provide the user with the ability to specify a set of, possibly
//! project specific, raw API files and convert them to prepared files that are
//! loaded quickly when the application is invoked.
class QSCINTILLA_EXPORT QsciAPIs : public QsciAbstractAPIs
{
Q_OBJECT
public:
//! Constructs a QsciAPIs instance attached to lexer \a lexer. \a lexer
//! becomes the instance's parent object although the instance can also be
//! subsequently attached to other lexers.
QsciAPIs(QsciLexer *lexer);
//! Destroy the QsciAPIs instance.
virtual ~QsciAPIs();
//! Add the single raw API entry \a entry to the current set.
//!
//! \sa clear(), load(), remove()
void add(const QString &entry);
//! Deletes all raw API information.
//!
//! \sa add(), load(), remove()
void clear();
//! Load the API information from the file named \a filename, adding it to
//! the current set. Returns true if successful, otherwise false.
bool load(const QString &filename);
//! Remove the single raw API entry \a entry from the current set.
//!
//! \sa add(), clear(), load()
void remove(const QString &entry);
//! Convert the current raw API information to prepared API information.
//! This is implemented by a separate thread.
//!
//! \sa cancelPreparation()
void prepare();
//! Cancel the conversion of the current raw API information to prepared
//! API information.
//!
//! \sa prepare()
void cancelPreparation();
//! Return the default name of the prepared API information file. It is
//! based on the name of the associated lexer and in the directory defined
//! by the QSCIDIR environment variable. If the environment variable isn't
//! set then $HOME/.qsci is used.
QString defaultPreparedName() const;
//! Check to see is a prepared API information file named \a filename
//! exists. If \a filename is empty then the value returned by
//! defaultPreparedName() is used. Returns true if successful, otherwise
//! false.
//!
//! \sa defaultPreparedName()
bool isPrepared(const QString &filename = QString()) const;
//! Load the prepared API information from the file named \a filename. If
//! \a filename is empty then a name is constructed based on the name of
//! the associated lexer and saved in the directory defined by the QSCIDIR
//! environment variable. If the environment variable isn't set then
//! $HOME/.qsci is used. Returns true if successful, otherwise false.
bool loadPrepared(const QString &filename = QString());
//! Save the prepared API information to the file named \a filename. If
//! \a filename is empty then a name is constructed based on the name of
//! the associated lexer and saved in the directory defined by the QSCIDIR
//! environment variable. If the environment variable isn't set then
//! $HOME/.qsci is used. Returns true if successful, otherwise false.
bool savePrepared(const QString &filename = QString()) const;
//! \reimp
virtual void updateAutoCompletionList(const QStringList &context,
QStringList &list);
//! \reimp
virtual void autoCompletionSelected(const QString &sel);
//! \reimp
virtual QStringList callTips(const QStringList &context, int commas,
QsciScintilla::CallTipsStyle style, QList<int> &shifts);
//! \internal Reimplemented to receive termination events from the worker
//! thread.
virtual bool event(QEvent *e);
//! Return a list of the installed raw API file names for the associated
//! lexer.
QStringList installedAPIFiles() const;
signals:
//! This signal is emitted when the conversion of raw API information to
//! prepared API information has been cancelled.
//!
//! \sa apiPreparationFinished(), apiPreparationStarted()
void apiPreparationCancelled();
//! This signal is emitted when the conversion of raw API information to
//! prepared API information starts and can be used to give some visual
//! feedback to the user.
//!
//! \sa apiPreparationCancelled(), apiPreparationFinished()
void apiPreparationStarted();
//! This signal is emitted when the conversion of raw API information to
//! prepared API information has finished.
//!
//! \sa apiPreparationCancelled(), apiPreparationStarted()
void apiPreparationFinished();
private:
friend class QsciAPIsPrepared;
friend class QsciAPIsWorker;
// This indexes a word in a set of raw APIs. The first part indexes the
// entry in the set, the second part indexes the word within the entry.
typedef QPair<quint32, quint32> WordIndex;
// This is a list of word indexes.
typedef QList<WordIndex> WordIndexList;
QsciAPIsWorker *worker;
QStringList old_context;
QStringList::const_iterator origin;
int origin_len;
QString unambiguous_context;
QStringList apis;
QsciAPIsPrepared *prep;
static bool enoughCommas(const QString &s, int commas);
QStringList positionOrigin(const QStringList &context, QString &path);
bool originStartsWith(const QString &path, const QString &wsep);
const WordIndexList *wordIndexOf(const QString &word) const;
void lastCompleteWord(const QString &word, QStringList &with_context,
bool &unambig);
void lastPartialWord(const QString &word, QStringList &with_context,
bool &unambig);
void addAPIEntries(const WordIndexList &wl, bool complete,
QStringList &with_context, bool &unambig);
QString prepName(const QString &filename, bool mkpath = false) const;
void deleteWorker();
QsciAPIs(const QsciAPIs &);
QsciAPIs &operator=(const QsciAPIs &);
};
#ifdef __APPLE__
}
#endif
#endif
+413
View File
@@ -0,0 +1,413 @@
// This defines the interface to the QsciCommand class.
//
// Copyright (c) 2015 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.
#ifndef QSCICOMMAND_H
#define QSCICOMMAND_H
#ifdef __APPLE__
extern "C++" {
#endif
#include <qstring.h>
#include <Qsci/qsciglobal.h>
#include <Qsci/qsciscintillabase.h>
class QsciScintilla;
//! \brief The QsciCommand class represents an internal editor command that may
//! have one or two keys bound to it.
//!
//! Methods are provided to change the keys bound to the command and to remove
//! a key binding. Each command has a user friendly description of the command
//! for use in key mapping dialogs.
class QSCINTILLA_EXPORT QsciCommand
{
public:
//! This enum defines the different commands that can be assigned to a key.
enum Command {
//! Move down one line.
LineDown = QsciScintillaBase::SCI_LINEDOWN,
//! Extend the selection down one line.
LineDownExtend = QsciScintillaBase::SCI_LINEDOWNEXTEND,
//! Extend the rectangular selection down one line.
LineDownRectExtend = QsciScintillaBase::SCI_LINEDOWNRECTEXTEND,
//! Scroll the view down one line.
LineScrollDown = QsciScintillaBase::SCI_LINESCROLLDOWN,
//! Move up one line.
LineUp = QsciScintillaBase::SCI_LINEUP,
//! Extend the selection up one line.
LineUpExtend = QsciScintillaBase::SCI_LINEUPEXTEND,
//! Extend the rectangular selection up one line.
LineUpRectExtend = QsciScintillaBase::SCI_LINEUPRECTEXTEND,
//! Scroll the view up one line.
LineScrollUp = QsciScintillaBase::SCI_LINESCROLLUP,
//! Scroll to the start of the document.
ScrollToStart = QsciScintillaBase::SCI_SCROLLTOSTART,
//! Scroll to the end of the document.
ScrollToEnd = QsciScintillaBase::SCI_SCROLLTOEND,
//! Scroll vertically to centre the current line.
VerticalCentreCaret = QsciScintillaBase::SCI_VERTICALCENTRECARET,
//! Move down one paragraph.
ParaDown = QsciScintillaBase::SCI_PARADOWN,
//! Extend the selection down one paragraph.
ParaDownExtend = QsciScintillaBase::SCI_PARADOWNEXTEND,
//! Move up one paragraph.
ParaUp = QsciScintillaBase::SCI_PARAUP,
//! Extend the selection up one paragraph.
ParaUpExtend = QsciScintillaBase::SCI_PARAUPEXTEND,
//! Move left one character.
CharLeft = QsciScintillaBase::SCI_CHARLEFT,
//! Extend the selection left one character.
CharLeftExtend = QsciScintillaBase::SCI_CHARLEFTEXTEND,
//! Extend the rectangular selection left one character.
CharLeftRectExtend = QsciScintillaBase::SCI_CHARLEFTRECTEXTEND,
//! Move right one character.
CharRight = QsciScintillaBase::SCI_CHARRIGHT,
//! Extend the selection right one character.
CharRightExtend = QsciScintillaBase::SCI_CHARRIGHTEXTEND,
//! Extend the rectangular selection right one character.
CharRightRectExtend = QsciScintillaBase::SCI_CHARRIGHTRECTEXTEND,
//! Move left one word.
WordLeft = QsciScintillaBase::SCI_WORDLEFT,
//! Extend the selection left one word.
WordLeftExtend = QsciScintillaBase::SCI_WORDLEFTEXTEND,
//! Move right one word.
WordRight = QsciScintillaBase::SCI_WORDRIGHT,
//! Extend the selection right one word.
WordRightExtend = QsciScintillaBase::SCI_WORDRIGHTEXTEND,
//! Move to the end of the previous word.
WordLeftEnd = QsciScintillaBase::SCI_WORDLEFTEND,
//! Extend the selection to the end of the previous word.
WordLeftEndExtend = QsciScintillaBase::SCI_WORDLEFTENDEXTEND,
//! Move to the end of the next word.
WordRightEnd = QsciScintillaBase::SCI_WORDRIGHTEND,
//! Extend the selection to the end of the next word.
WordRightEndExtend = QsciScintillaBase::SCI_WORDRIGHTENDEXTEND,
//! Move left one word part.
WordPartLeft = QsciScintillaBase::SCI_WORDPARTLEFT,
//! Extend the selection left one word part.
WordPartLeftExtend = QsciScintillaBase::SCI_WORDPARTLEFTEXTEND,
//! Move right one word part.
WordPartRight = QsciScintillaBase::SCI_WORDPARTRIGHT,
//! Extend the selection right one word part.
WordPartRightExtend = QsciScintillaBase::SCI_WORDPARTRIGHTEXTEND,
//! Move to the start of the document line.
Home = QsciScintillaBase::SCI_HOME,
//! Extend the selection to the start of the document line.
HomeExtend = QsciScintillaBase::SCI_HOMEEXTEND,
//! Extend the rectangular selection to the start of the document line.
HomeRectExtend = QsciScintillaBase::SCI_HOMERECTEXTEND,
//! Move to the start of the displayed line.
HomeDisplay = QsciScintillaBase::SCI_HOMEDISPLAY,
//! Extend the selection to the start of the displayed line.
HomeDisplayExtend = QsciScintillaBase::SCI_HOMEDISPLAYEXTEND,
//! Move to the start of the displayed or document line.
HomeWrap = QsciScintillaBase::SCI_HOMEWRAP,
//! Extend the selection to the start of the displayed or document
//! line.
HomeWrapExtend = QsciScintillaBase::SCI_HOMEWRAPEXTEND,
//! Move to the first visible character in the document line.
VCHome = QsciScintillaBase::SCI_VCHOME,
//! Extend the selection to the first visible character in the document
//! line.
VCHomeExtend = QsciScintillaBase::SCI_VCHOMEEXTEND,
//! Extend the rectangular selection to the first visible character in
//! the document line.
VCHomeRectExtend = QsciScintillaBase::SCI_VCHOMERECTEXTEND,
//! Move to the first visible character of the displayed or document
//! line.
VCHomeWrap = QsciScintillaBase::SCI_VCHOMEWRAP,
//! Extend the selection to the first visible character of the
//! displayed or document line.
VCHomeWrapExtend = QsciScintillaBase::SCI_VCHOMEWRAPEXTEND,
//! Move to the end of the document line.
LineEnd = QsciScintillaBase::SCI_LINEEND,
//! Extend the selection to the end of the document line.
LineEndExtend = QsciScintillaBase::SCI_LINEENDEXTEND,
//! Extend the rectangular selection to the end of the document line.
LineEndRectExtend = QsciScintillaBase::SCI_LINEENDRECTEXTEND,
//! Move to the end of the displayed line.
LineEndDisplay = QsciScintillaBase::SCI_LINEENDDISPLAY,
//! Extend the selection to the end of the displayed line.
LineEndDisplayExtend = QsciScintillaBase::SCI_LINEENDDISPLAYEXTEND,
//! Move to the end of the displayed or document line.
LineEndWrap = QsciScintillaBase::SCI_LINEENDWRAP,
//! Extend the selection to the end of the displayed or document line.
LineEndWrapExtend = QsciScintillaBase::SCI_LINEENDWRAPEXTEND,
//! Move to the start of the document.
DocumentStart = QsciScintillaBase::SCI_DOCUMENTSTART,
//! Extend the selection to the start of the document.
DocumentStartExtend = QsciScintillaBase::SCI_DOCUMENTSTARTEXTEND,
//! Move to the end of the document.
DocumentEnd = QsciScintillaBase::SCI_DOCUMENTEND,
//! Extend the selection to the end of the document.
DocumentEndExtend = QsciScintillaBase::SCI_DOCUMENTENDEXTEND,
//! Move up one page.
PageUp = QsciScintillaBase::SCI_PAGEUP,
//! Extend the selection up one page.
PageUpExtend = QsciScintillaBase::SCI_PAGEUPEXTEND,
//! Extend the rectangular selection up one page.
PageUpRectExtend = QsciScintillaBase::SCI_PAGEUPRECTEXTEND,
//! Move down one page.
PageDown = QsciScintillaBase::SCI_PAGEDOWN,
//! Extend the selection down one page.
PageDownExtend = QsciScintillaBase::SCI_PAGEDOWNEXTEND,
//! Extend the rectangular selection down one page.
PageDownRectExtend = QsciScintillaBase::SCI_PAGEDOWNRECTEXTEND,
//! Stuttered move up one page.
StutteredPageUp = QsciScintillaBase::SCI_STUTTEREDPAGEUP,
//! Stuttered extend the selection up one page.
StutteredPageUpExtend = QsciScintillaBase::SCI_STUTTEREDPAGEUPEXTEND,
//! Stuttered move down one page.
StutteredPageDown = QsciScintillaBase::SCI_STUTTEREDPAGEDOWN,
//! Stuttered extend the selection down one page.
StutteredPageDownExtend = QsciScintillaBase::SCI_STUTTEREDPAGEDOWNEXTEND,
//! Delete the current character.
Delete = QsciScintillaBase::SCI_CLEAR,
//! Delete the previous character.
DeleteBack = QsciScintillaBase::SCI_DELETEBACK,
//! Delete the previous character if not at start of line.
DeleteBackNotLine = QsciScintillaBase::SCI_DELETEBACKNOTLINE,
//! Delete the word to the left.
DeleteWordLeft = QsciScintillaBase::SCI_DELWORDLEFT,
//! Delete the word to the right.
DeleteWordRight = QsciScintillaBase::SCI_DELWORDRIGHT,
//! Delete right to the end of the next word.
DeleteWordRightEnd = QsciScintillaBase::SCI_DELWORDRIGHTEND,
//! Delete the line to the left.
DeleteLineLeft = QsciScintillaBase::SCI_DELLINELEFT,
//! Delete the line to the right.
DeleteLineRight = QsciScintillaBase::SCI_DELLINERIGHT,
//! Delete the current line.
LineDelete = QsciScintillaBase::SCI_LINEDELETE,
//! Cut the current line to the clipboard.
LineCut = QsciScintillaBase::SCI_LINECUT,
//! Copy the current line to the clipboard.
LineCopy = QsciScintillaBase::SCI_LINECOPY,
//! Transpose the current and previous lines.
LineTranspose = QsciScintillaBase::SCI_LINETRANSPOSE,
//! Duplicate the current line.
LineDuplicate = QsciScintillaBase::SCI_LINEDUPLICATE,
//! Select the whole document.
SelectAll = QsciScintillaBase::SCI_SELECTALL,
//! Move the selected lines up one line.
MoveSelectedLinesUp = QsciScintillaBase::SCI_MOVESELECTEDLINESUP,
//! Move the selected lines down one line.
MoveSelectedLinesDown = QsciScintillaBase::SCI_MOVESELECTEDLINESDOWN,
//! Duplicate the selection.
SelectionDuplicate = QsciScintillaBase::SCI_SELECTIONDUPLICATE,
//! Convert the selection to lower case.
SelectionLowerCase = QsciScintillaBase::SCI_LOWERCASE,
//! Convert the selection to upper case.
SelectionUpperCase = QsciScintillaBase::SCI_UPPERCASE,
//! Cut the selection to the clipboard.
SelectionCut = QsciScintillaBase::SCI_CUT,
//! Copy the selection to the clipboard.
SelectionCopy = QsciScintillaBase::SCI_COPY,
//! Paste from the clipboard.
Paste = QsciScintillaBase::SCI_PASTE,
//! Toggle insert/overtype.
EditToggleOvertype = QsciScintillaBase::SCI_EDITTOGGLEOVERTYPE,
//! Insert a platform dependent newline.
Newline = QsciScintillaBase::SCI_NEWLINE,
//! Insert a formfeed.
Formfeed = QsciScintillaBase::SCI_FORMFEED,
//! Indent one level.
Tab = QsciScintillaBase::SCI_TAB,
//! De-indent one level.
Backtab = QsciScintillaBase::SCI_BACKTAB,
//! Cancel any current operation.
Cancel = QsciScintillaBase::SCI_CANCEL,
//! Undo the last command.
Undo = QsciScintillaBase::SCI_UNDO,
//! Redo the last command.
Redo = QsciScintillaBase::SCI_REDO,
//! Zoom in.
ZoomIn = QsciScintillaBase::SCI_ZOOMIN,
//! Zoom out.
ZoomOut = QsciScintillaBase::SCI_ZOOMOUT,
};
//! Return the command that will be executed by this instance.
Command command() const {return scicmd;}
//! Execute the command.
void execute();
//! Binds the key \a key to the command. If \a key is 0 then the key
//! binding is removed. If \a key is invalid then the key binding is
//! unchanged. Valid keys are any visible or control character or any
//! of \c Qt::Key_Down, \c Qt::Key_Up, \c Qt::Key_Left, \c Qt::Key_Right,
//! \c Qt::Key_Home, \c Qt::Key_End, \c Qt::Key_PageUp,
//! \c Qt::Key_PageDown, \c Qt::Key_Delete, \c Qt::Key_Insert,
//! \c Qt::Key_Escape, \c Qt::Key_Backspace, \c Qt::Key_Tab,
//! \c Qt::Key_Backtab, \c Qt::Key_Return, \c Qt::Key_Enter,
//! \c Qt::Key_Super_L, \c Qt::Key_Super_R or \c Qt::Key_Menu. Keys may be
//! modified with any combination of \c Qt::ShiftModifier,
//! \c Qt::ControlModifier, \c Qt::AltModifier and \c Qt::MetaModifier.
//!
//! \sa key(), setAlternateKey(), validKey()
void setKey(int key);
//! Binds the alternate key \a altkey to the command. If \a key is 0
//! then the alternate key binding is removed.
//!
//! \sa alternateKey(), setKey(), validKey()
void setAlternateKey(int altkey);
//! The key that is currently bound to the command is returned.
//!
//! \sa setKey(), alternateKey()
int key() const {return qkey;}
//! The alternate key that is currently bound to the command is
//! returned.
//!
//! \sa setAlternateKey(), key()
int alternateKey() const {return qaltkey;}
//! If the key \a key is valid then true is returned.
static bool validKey(int key);
//! The user friendly description of the command is returned.
QString description() const;
private:
friend class QsciCommandSet;
QsciCommand(QsciScintilla *qs, Command cmd, int key, int altkey,
const char *desc);
void bindKey(int key,int &qk,int &scik);
QsciScintilla *qsCmd;
Command scicmd;
int qkey, scikey, qaltkey, scialtkey;
const char *descCmd;
QsciCommand(const QsciCommand &);
QsciCommand &operator=(const QsciCommand &);
};
#ifdef __APPLE__
}
#endif
#endif
@@ -0,0 +1,97 @@
// This defines the interface to the QsciCommandSet class.
//
// Copyright (c) 2015 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.
#ifndef QSCICOMMANDSET_H
#define QSCICOMMANDSET_H
#ifdef __APPLE__
extern "C++" {
#endif
#include <qglobal.h>
#include <QList>
#include <Qsci/qsciglobal.h>
#include <Qsci/qscicommand.h>
QT_BEGIN_NAMESPACE
class QSettings;
QT_END_NAMESPACE
class QsciScintilla;
//! \brief The QsciCommandSet class represents the set of all internal editor
//! commands that may have keys bound.
//!
//! Methods are provided to access the individual commands and to read and
//! write the current bindings from and to settings files.
class QSCINTILLA_EXPORT QsciCommandSet
{
public:
//! The key bindings for each command in the set are read from the
//! settings \a qs. \a prefix is prepended to the key of each entry.
//! true is returned if there was no error.
//!
//! \sa writeSettings()
bool readSettings(QSettings &qs, const char *prefix = "/Scintilla");
//! The key bindings for each command in the set are written to the
//! settings \a qs. \a prefix is prepended to the key of each entry.
//! true is returned if there was no error.
//!
//! \sa readSettings()
bool writeSettings(QSettings &qs, const char *prefix = "/Scintilla");
//! The commands in the set are returned as a list.
QList<QsciCommand *> &commands() {return cmds;}
//! The primary keys bindings for all commands are removed.
void clearKeys();
//! The alternate keys bindings for all commands are removed.
void clearAlternateKeys();
// Find the command that is bound to \a key.
QsciCommand *boundTo(int key) const;
// Find a specific command \a command.
QsciCommand *find(QsciCommand::Command command) const;
private:
friend class QsciScintilla;
QsciCommandSet(QsciScintilla *qs);
~QsciCommandSet();
QsciScintilla *qsci;
QList<QsciCommand *> cmds;
QsciCommandSet(const QsciCommandSet &);
QsciCommandSet &operator=(const QsciCommandSet &);
};
#ifdef __APPLE__
}
#endif
#endif
@@ -0,0 +1,69 @@
// This defines the interface to the QsciDocument class.
//
// Copyright (c) 2015 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.
#ifndef QSCIDOCUMENT_H
#define QSCIDOCUMENT_H
#ifdef __APPLE__
extern "C++" {
#endif
#include <Qsci/qsciglobal.h>
class QsciScintillaBase;
class QsciDocumentP;
//! \brief The QsciDocument class represents a document to be edited.
//!
//! It is an opaque class that can be attached to multiple instances of
//! QsciScintilla to create different simultaneous views of the same document.
//! QsciDocument uses implicit sharing so that copying class instances is a
//! cheap operation.
class QSCINTILLA_EXPORT QsciDocument
{
public:
//! Create a new unattached document.
QsciDocument();
virtual ~QsciDocument();
QsciDocument(const QsciDocument &);
QsciDocument &operator=(const QsciDocument &);
private:
friend class QsciScintilla;
void attach(const QsciDocument &that);
void detach();
void display(QsciScintillaBase *qsb, const QsciDocument *from);
void undisplay(QsciScintillaBase *qsb);
bool isModified() const;
void setModified(bool m);
QsciDocumentP *pdoc;
};
#ifdef __APPLE__
}
#endif
#endif
+62
View File
@@ -0,0 +1,62 @@
// This module defines various things common to all of the Scintilla Qt port.
//
// Copyright (c) 2015 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.
#ifndef QSCIGLOBAL_H
#define QSCIGLOBAL_H
#ifdef __APPLE__
extern "C++" {
#endif
#include <qglobal.h>
#define QSCINTILLA_VERSION 0x020900
#define QSCINTILLA_VERSION_STR "2.9"
// Under Windows, define QSCINTILLA_MAKE_DLL to create a Scintilla DLL, or
// define QSCINTILLA_DLL to link against a Scintilla DLL, or define neither
// to either build or link against a static Scintilla library.
#if defined(Q_OS_WIN)
#if defined(QSCINTILLA_DLL)
#define QSCINTILLA_EXPORT __declspec(dllimport)
#elif defined(QSCINTILLA_MAKE_DLL)
#define QSCINTILLA_EXPORT __declspec(dllexport)
#endif
#endif
#if !defined(QSCINTILLA_EXPORT)
#define QSCINTILLA_EXPORT
#endif
#if !defined(QT_BEGIN_NAMESPACE)
#define QT_BEGIN_NAMESPACE
#define QT_END_NAMESPACE
#endif
#ifdef __APPLE__
}
#endif
#endif
+358
View File
@@ -0,0 +1,358 @@
// This defines the interface to the QsciLexer class.
//
// Copyright (c) 2015 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.
#ifndef QSCILEXER_H
#define QSCILEXER_H
#ifdef __APPLE__
extern "C++" {
#endif
#include <QColor>
#include <QFont>
#include <QMap>
#include <QObject>
#include <QString>
#include <Qsci/qsciglobal.h>
QT_BEGIN_NAMESPACE
class QSettings;
QT_END_NAMESPACE
class QsciAbstractAPIs;
class QsciScintilla;
//! \brief The QsciLexer class is an abstract class used as a base for language
//! lexers.
//!
//! A lexer scans the text breaking it up into separate language objects, e.g.
//! keywords, strings, operators. The lexer then uses a different style to
//! draw each object. A style is identified by a style number and has a number
//! of attributes, including colour and font. A specific language lexer will
//! implement appropriate default styles which can be overriden by an
//! application by further sub-classing the specific language lexer.
//!
//! A lexer may provide one or more sets of words to be recognised as keywords.
//! Most lexers only provide one set, but some may support languages embedded
//! in other languages and provide several sets.
//!
//! QsciLexer provides convenience methods for saving and restoring user
//! preferences for fonts and colours.
//!
//! If you want to write a lexer for a new language then you can add it to the
//! underlying Scintilla code and implement a corresponding QsciLexer sub-class
//! to manage the different styles used. Alternatively you can implement a
//! sub-class of QsciLexerCustom.
class QSCINTILLA_EXPORT QsciLexer : public QObject
{
Q_OBJECT
public:
//! Construct a QsciLexer with parent \a parent. \a parent is typically
//! the QsciScintilla instance.
QsciLexer(QObject *parent = 0);
//! Destroy the QSciLexer.
virtual ~QsciLexer();
//! Returns the name of the language. It must be re-implemented by a
//! sub-class.
virtual const char *language() const = 0;
//! Returns the name of the lexer. If 0 is returned then the lexer's
//! numeric identifier is used. The default implementation returns 0.
//!
//! \sa lexerId()
virtual const char *lexer() const;
//! Returns the identifier (i.e. a QsciScintillaBase::SCLEX_* value) of the
//! lexer. This is only used if lexer() returns 0. The default
//! implementation returns QsciScintillaBase::SCLEX_CONTAINER.
//!
//! \sa lexer()
virtual int lexerId() const;
//! Returns the current API set or 0 if there isn't one.
//!
//! \sa setAPIs()
QsciAbstractAPIs *apis() const;
//! \internal Returns the characters that can fill up auto-completion.
virtual const char *autoCompletionFillups() const;
//! \internal Returns the list of character sequences that can separate
//! auto-completion words. The first in the list is assumed to be the
//! sequence used to separate words in the lexer's API files.
virtual QStringList autoCompletionWordSeparators() const;
//! Returns the auto-indentation style. The default is 0 if the
//! language is block structured, or QsciScintilla::AiMaintain if not.
//!
//! \sa setAutoIndentStyle(), QsciScintilla::AiMaintain,
//! QsciScintilla::AiOpening, QsciScintilla::AiClosing
int autoIndentStyle();
//! \internal Returns a space separated list of words or characters in
//! a particular style that define the end of a block for
//! auto-indentation. The style is returned via \a style.
virtual const char *blockEnd(int *style = 0) const;
//! \internal Returns the number of lines prior to the current one when
//! determining the scope of a block when auto-indenting.
virtual int blockLookback() const;
//! \internal Returns a space separated list of words or characters in
//! a particular style that define the start of a block for
//! auto-indentation. The style is returned via \a style.
virtual const char *blockStart(int *style = 0) const;
//! \internal Returns a space separated list of keywords in a
//! particular style that define the start of a block for
//! auto-indentation. The style is returned via \a style.
virtual const char *blockStartKeyword(int *style = 0) const;
//! \internal Returns the style used for braces for brace matching.
virtual int braceStyle() const;
//! \internal Returns true if the language is case sensitive. The default
//! is true.
virtual bool caseSensitive() const;
//! Returns the foreground colour of the text for style number \a style.
//! The default colour is that returned by defaultColor().
//!
//! \sa defaultColor(), paper()
virtual QColor color(int style) const;
//! Returns the end-of-line for style number \a style. The default is
//! false.
virtual bool eolFill(int style) const;
//! Returns the font for style number \a style. The default font is
//! that returned by defaultFont().
//!
//! \sa defaultFont()
virtual QFont font(int style) const;
//! \internal Returns the view used for indentation guides.
virtual int indentationGuideView() const;
//! Returns the set of keywords for the keyword set \a set recognised
//! by the lexer as a space separated string. 0 is returned if there
//! is no such set.
virtual const char *keywords(int set) const;
//! \internal Returns the number of the style used for whitespace. The
//! default implementation returns 0 which is the convention adopted by
//! most lexers.
virtual int defaultStyle() const;
//! Returns the descriptive name for style number \a style. For a valid
//! style number for this language a non-empty QString must be returned.
//! If the style number is invalid then an empty QString must be returned.
//! This is intended to be used in user preference dialogs.
virtual QString description(int style) const = 0;
//! Returns the background colour of the text for style number
//! \a style.
//!
//! \sa defaultPaper(), color()
virtual QColor paper(int style) const;
//! Returns the default text colour.
//!
//! \sa setDefaultColor()
QColor defaultColor() const;
//! Returns the default text colour for style number \a style.
virtual QColor defaultColor(int style) const;
//! Returns the default end-of-line for style number \a style. The default
//! is false.
virtual bool defaultEolFill(int style) const;
//! Returns the default font.
//!
//! \sa setDefaultFont()
QFont defaultFont() const;
//! Returns the default font for style number \a style.
virtual QFont defaultFont(int style) const;
//! Returns the default paper colour.
//!
//! \sa setDefaultPaper()
QColor defaultPaper() const;
//! Returns the default paper colour for style number \a style.
virtual QColor defaultPaper(int style) const;
//! Returns the QsciScintilla instance that the lexer is currently attached
//! to or 0 if it is unattached.
QsciScintilla *editor() const {return attached_editor;}
//! The current set of APIs is set to \a apis. If \a apis is 0 then any
//! existing APIs for this lexer are removed.
//!
//! \sa apis()
void setAPIs(QsciAbstractAPIs *apis);
//! The default text colour is set to \a c.
//!
//! \sa defaultColor(), color()
void setDefaultColor(const QColor &c);
//! The default font is set to \a f.
//!
//! \sa defaultFont(), font()
void setDefaultFont(const QFont &f);
//! The default paper colour is set to \a c.
//!
//! \sa defaultPaper(), paper()
void setDefaultPaper(const QColor &c);
//! \internal Set the QsciScintilla instance that the lexer is attached to.
virtual void setEditor(QsciScintilla *editor);
//! The colour, paper, font and end-of-line for each style number, and
//! all lexer specific properties are read from the settings \a qs.
//! \a prefix is prepended to the key of each entry. true is returned
//! if there was no error.
//!
//! \sa writeSettings(), QsciScintilla::setLexer()
bool readSettings(QSettings &qs,const char *prefix = "/Scintilla");
//! Causes all properties to be refreshed by emitting the
//! propertyChanged() signal as required.
virtual void refreshProperties();
//! Returns the number of style bits needed by the lexer. Normally this
//! should only be re-implemented by custom lexers.
virtual int styleBitsNeeded() const;
//! Returns the string of characters that comprise a word. The default is
//! 0 which implies the upper and lower case alphabetic characters and
//! underscore.
virtual const char *wordCharacters() const;
//! The colour, paper, font and end-of-line for each style number, and
//! all lexer specific properties are written to the settings \a qs.
//! \a prefix is prepended to the key of each entry. true is returned
//! if there was no error.
//!
//! \sa readSettings()
bool writeSettings(QSettings &qs,
const char *prefix = "/Scintilla") const;
public slots:
//! The auto-indentation style is set to \a autoindentstyle.
//!
//! \sa autoIndentStyle(), QsciScintilla::AiMaintain,
//! QsciScintilla::AiOpening, QsciScintilla::AiClosing
virtual void setAutoIndentStyle(int autoindentstyle);
//! The foreground colour for style number \a style is set to \a c. If
//! \a style is -1 then the colour is set for all styles.
virtual void setColor(const QColor &c,int style = -1);
//! The end-of-line fill for style number \a style is set to
//! \a eoffill. If \a style is -1 then the fill is set for all styles.
virtual void setEolFill(bool eoffill,int style = -1);
//! The font for style number \a style is set to \a f. If \a style is
//! -1 then the font is set for all styles.
virtual void setFont(const QFont &f,int style = -1);
//! The background colour for style number \a style is set to \a c. If
//! \a style is -1 then the colour is set for all styles.
virtual void setPaper(const QColor &c,int style = -1);
signals:
//! This signal is emitted when the foreground colour of style number
//! \a style has changed. The new colour is \a c.
void colorChanged(const QColor &c,int style);
//! This signal is emitted when the end-of-file fill of style number
//! \a style has changed. The new fill is \a eolfilled.
void eolFillChanged(bool eolfilled,int style);
//! This signal is emitted when the font of style number \a style has
//! changed. The new font is \a f.
void fontChanged(const QFont &f,int style);
//! This signal is emitted when the background colour of style number
//! \a style has changed. The new colour is \a c.
void paperChanged(const QColor &c,int style);
//! This signal is emitted when the value of the lexer property \a prop
//! needs to be changed. The new value is \a val.
void propertyChanged(const char *prop, const char *val);
protected:
//! The lexer's properties are read from the settings \a qs. \a prefix
//! (which has a trailing '/') should be used as a prefix to the key of
//! each setting. true is returned if there is no error.
//!
virtual bool readProperties(QSettings &qs,const QString &prefix);
//! The lexer's properties are written to the settings \a qs.
//! \a prefix (which has a trailing '/') should be used as a prefix to
//! the key of each setting. true is returned if there is no error.
//!
virtual bool writeProperties(QSettings &qs,const QString &prefix) const;
private:
struct StyleData {
QFont font;
QColor color;
QColor paper;
bool eol_fill;
};
struct StyleDataMap {
bool style_data_set;
QMap<int, StyleData> style_data;
};
StyleDataMap *style_map;
int autoIndStyle;
QFont defFont;
QColor defColor;
QColor defPaper;
QsciAbstractAPIs *apiSet;
QsciScintilla *attached_editor;
void setStyleDefaults() const;
StyleData &styleData(int style) const;
QsciLexer(const QsciLexer &);
QsciLexer &operator=(const QsciLexer &);
};
#ifdef __APPLE__
}
#endif
#endif
+294
View File
@@ -0,0 +1,294 @@
// This defines the interface to the QsciLexerSQL class.
//
// Copyright (c) 2015 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.
#ifndef QSCILEXERSQL_H
#define QSCILEXERSQL_H
#ifdef __APPLE__
extern "C++" {
#endif
#include <QObject>
#include <Qsci/qsciglobal.h>
#include <Qsci/qscilexer.h>
//! \brief The QsciLexerSQL class encapsulates the Scintilla SQL lexer.
class QSCINTILLA_EXPORT QsciLexerSQL : public QsciLexer
{
Q_OBJECT
public:
//! This enum defines the meanings of the different styles used by the
//! SQL lexer.
enum {
//! The default.
Default = 0,
//! A comment.
Comment = 1,
//! A line comment.
CommentLine = 2,
//! A JavaDoc/Doxygen style comment.
CommentDoc = 3,
//! A number.
Number = 4,
//! A keyword.
Keyword = 5,
//! A double-quoted string.
DoubleQuotedString = 6,
//! A single-quoted string.
SingleQuotedString = 7,
//! An SQL*Plus keyword.
PlusKeyword = 8,
//! An SQL*Plus prompt.
PlusPrompt = 9,
//! An operator.
Operator = 10,
//! An identifier
Identifier = 11,
//! An SQL*Plus comment.
PlusComment = 13,
//! A '#' line comment.
CommentLineHash = 15,
//! A JavaDoc/Doxygen keyword.
CommentDocKeyword = 17,
//! A JavaDoc/Doxygen keyword error.
CommentDocKeywordError = 18,
//! A keyword defined in keyword set number 5. The class must be
//! sub-classed and re-implement keywords() to make use of this style.
//! Note that keywords must be defined using lower case.
KeywordSet5 = 19,
//! A keyword defined in keyword set number 6. The class must be
//! sub-classed and re-implement keywords() to make use of this style.
//! Note that keywords must be defined using lower case.
KeywordSet6 = 20,
//! A keyword defined in keyword set number 7. The class must be
//! sub-classed and re-implement keywords() to make use of this style.
//! Note that keywords must be defined using lower case.
KeywordSet7 = 21,
//! A keyword defined in keyword set number 8. The class must be
//! sub-classed and re-implement keywords() to make use of this style.
//! Note that keywords must be defined using lower case.
KeywordSet8 = 22,
//! A quoted identifier.
QuotedIdentifier = 23,
//! A quoted operator.
QuotedOperator = 24,
};
//! Construct a QsciLexerSQL with parent \a parent. \a parent is typically
//! the QsciScintilla instance.
QsciLexerSQL(QObject *parent = 0);
//! Destroys the QsciLexerSQL instance.
virtual ~QsciLexerSQL();
//! Returns the name of the language.
const char *language() const;
//! Returns the name of the lexer. Some lexers support a number of
//! languages.
const char *lexer() const;
//! \internal Returns the style used for braces for brace matching.
int braceStyle() const;
//! Returns the foreground colour of the text for style number \a style.
//!
//! \sa defaultPaper()
QColor defaultColor(int style) const;
//! Returns the end-of-line fill for style number \a style.
bool defaultEolFill(int style) const;
//! Returns the font for style number \a style.
QFont defaultFont(int style) const;
//! Returns the background colour of the text for style number \a style.
//!
//! \sa defaultColor()
QColor defaultPaper(int style) const;
//! Returns the set of keywords for the keyword set \a set recognised by
//! the lexer as a space separated string.
const char *keywords(int set) const;
//! Returns the descriptive name for style number \a style. If the style
//! is invalid for this language then an empty QString is returned. This
//! is intended to be used in user preference dialogs.
QString description(int style) const;
//! Causes all properties to be refreshed by emitting the
//! propertyChanged() signal as required.
void refreshProperties();
//! Returns true if backslash escapes are enabled.
//!
//! \sa setBackslashEscapes()
bool backslashEscapes() const {return backslash_escapes;}
//! If \a enable is true then words may contain dots (i.e. periods or full
//! stops). The default is false.
//!
//! \sa dottedWords()
void setDottedWords(bool enable);
//! Returns true if words may contain dots (i.e. periods or full stops).
//!
//! \sa setDottedWords()
bool dottedWords() const {return allow_dotted_word;}
//! If \a fold is true then ELSE blocks can be folded. The default is
//! false.
//!
//! \sa foldAtElse()
void setFoldAtElse(bool fold);
//! Returns true if ELSE blocks can be folded.
//!
//! \sa setFoldAtElse()
bool foldAtElse() const {return at_else;}
//! Returns true if multi-line comment blocks can be folded.
//!
//! \sa setFoldComments()
bool foldComments() const {return fold_comments;}
//! Returns true if trailing blank lines are included in a fold block.
//!
//! \sa setFoldCompact()
bool foldCompact() const {return fold_compact;}
//! If \a fold is true then only BEGIN blocks can be folded. The default
//! is false.
//!
//! \sa foldOnlyBegin()
void setFoldOnlyBegin(bool fold);
//! Returns true if BEGIN blocks only can be folded.
//!
//! \sa setFoldOnlyBegin()
bool foldOnlyBegin() const {return only_begin;}
//! If \a enable is true then '#' is used as a comment character. It is
//! typically enabled for MySQL and disabled for Oracle. The default is
//! false.
//!
//! \sa hashComments()
void setHashComments(bool enable);
//! Returns true if '#' is used as a comment character.
//!
//! \sa setHashComments()
bool hashComments() const {return numbersign_comment;}
//! If \a enable is true then quoted identifiers are enabled. The default
//! is false.
//!
//! \sa quotedIdentifiers()
void setQuotedIdentifiers(bool enable);
//! Returns true if quoted identifiers are enabled.
//!
//! \sa setQuotedIdentifiers()
bool quotedIdentifiers() const {return backticks_identifier;}
public slots:
//! If \a enable is true then backslash escapes are enabled. The
//! default is false.
//!
//! \sa backslashEscapes()
virtual void setBackslashEscapes(bool enable);
//! If \a fold is true then multi-line comment blocks can be folded. The
//! default is false.
//!
//! \sa foldComments()
virtual void setFoldComments(bool fold);
//! If \a fold is true then trailing blank lines are included in a fold
//! block. The default is true.
//!
//! \sa foldCompact()
virtual void setFoldCompact(bool fold);
protected:
//! The lexer's properties are read from the settings \a qs. \a prefix
//! (which has a trailing '/') should be used as a prefix to the key of
//! each setting. true is returned if there is no error.
//!
bool readProperties(QSettings &qs, const QString &prefix);
//! The lexer's properties are written to the settings \a qs.
//! \a prefix (which has a trailing '/') should be used as a prefix to
//! the key of each setting. true is returned if there is no error.
//!
bool writeProperties(QSettings &qs, const QString &prefix) const;
private:
void setAtElseProp();
void setCommentProp();
void setCompactProp();
void setOnlyBeginProp();
void setBackticksIdentifierProp();
void setNumbersignCommentProp();
void setBackslashEscapesProp();
void setAllowDottedWordProp();
bool at_else;
bool fold_comments;
bool fold_compact;
bool only_begin;
bool backticks_identifier;
bool numbersign_comment;
bool backslash_escapes;
bool allow_dotted_word;
QsciLexerSQL(const QsciLexerSQL &);
QsciLexerSQL &operator=(const QsciLexerSQL &);
};
#ifdef __APPLE__
}
#endif
#endif
+106
View File
@@ -0,0 +1,106 @@
// This defines the interface to the QsciMacro class.
//
// Copyright (c) 2015 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.
#ifndef QSCIMACRO_H
#define QSCIMACRO_H
#ifdef __APPLE__
extern "C++" {
#endif
#include <QList>
#include <QObject>
#include <QString>
#include <Qsci/qsciglobal.h>
class QsciScintilla;
//! \brief The QsciMacro class represents a sequence of recordable editor
//! commands.
//!
//! Methods are provided to convert convert a macro to and from a textual
//! representation so that they can be easily written to and read from
//! permanent storage.
class QSCINTILLA_EXPORT QsciMacro : public QObject
{
Q_OBJECT
public:
//! Construct a QsciMacro with parent \a parent.
QsciMacro(QsciScintilla *parent);
//! Construct a QsciMacro from the printable ASCII representation \a asc,
//! with parent \a parent.
QsciMacro(const QString &asc, QsciScintilla *parent);
//! Destroy the QsciMacro instance.
virtual ~QsciMacro();
//! Clear the contents of the macro.
void clear();
//! Load the macro from the printable ASCII representation \a asc. Returns
//! true if there was no error.
//!
//! \sa save()
bool load(const QString &asc);
//! Return a printable ASCII representation of the macro. It is guaranteed
//! that only printable ASCII characters are used and that double quote
//! characters will not be used.
//!
//! \sa load()
QString save() const;
public slots:
//! Play the macro.
virtual void play();
//! Start recording user commands and add them to the macro.
virtual void startRecording();
//! Stop recording user commands.
virtual void endRecording();
private slots:
void record(unsigned int msg, unsigned long wParam, void *lParam);
private:
struct Macro {
unsigned int msg;
unsigned long wParam;
QByteArray text;
};
QsciScintilla *qsci;
QList<Macro> macro;
QsciMacro(const QsciMacro &);
QsciMacro &operator=(const QsciMacro &);
};
#ifdef __APPLE__
}
#endif
#endif
+120
View File
@@ -0,0 +1,120 @@
// This module defines interface to the QsciPrinter class.
//
// Copyright (c) 2015 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.
#ifndef QSCIPRINTER_H
#define QSCIPRINTER_H
#ifdef __APPLE__
extern "C++" {
#endif
// This is needed for Qt v5.0.0-alpha.
#if defined(B0)
#undef B0
#endif
#include <qprinter.h>
#if !defined(QT_NO_PRINTER)
#include <Qsci/qsciglobal.h>
#include <Qsci/qsciscintilla.h>
QT_BEGIN_NAMESPACE
class QRect;
class QPainter;
QT_END_NAMESPACE
class QsciScintillaBase;
//! \brief The QsciPrinter class is a sub-class of the Qt QPrinter class that
//! is able to print the text of a Scintilla document.
//!
//! The class can be further sub-classed to alter to layout of the text, adding
//! headers and footers for example.
class QSCINTILLA_EXPORT QsciPrinter : public QPrinter
{
public:
//! Constructs a printer paint device with mode \a mode.
QsciPrinter(PrinterMode mode = ScreenResolution);
//! Destroys the QsciPrinter instance.
virtual ~QsciPrinter();
//! Format a page, by adding headers and footers for example, before the
//! document text is drawn on it. \a painter is the painter to be used to
//! add customised text and graphics. \a drawing is true if the page is
//! actually being drawn rather than being sized. \a painter drawing
//! methods must only be called when \a drawing is true. \a area is the
//! area of the page that will be used to draw the text. This should be
//! modified if it is necessary to reserve space for any customised text or
//! graphics. By default the area is relative to the printable area of the
//! page. Use QPrinter::setFullPage() because calling printRange() if you
//! want to try and print over the whole page. \a pagenr is the number of
//! the page. The first page is numbered 1.
virtual void formatPage(QPainter &painter, bool drawing, QRect &area,
int pagenr);
//! Return the number of points to add to each font when printing.
//!
//! \sa setMagnification()
int magnification() const {return mag;}
//! Sets the number of points to add to each font when printing to \a
//! magnification.
//!
//! \sa magnification()
virtual void setMagnification(int magnification);
//! Print a range of lines from the Scintilla instance \a qsb. \a from is
//! the first line to print and a negative value signifies the first line
//! of text. \a to is the last line to print and a negative value
//! signifies the last line of text. true is returned if there was no
//! error.
virtual int printRange(QsciScintillaBase *qsb, int from = -1, int to = -1);
//! Return the line wrap mode used when printing. The default is
//! QsciScintilla::WrapWord.
//!
//! \sa setWrapMode()
QsciScintilla::WrapMode wrapMode() const {return wrap;}
//! Sets the line wrap mode used when printing to \a wmode.
//!
//! \sa wrapMode()
virtual void setWrapMode(QsciScintilla::WrapMode wmode);
private:
int mag;
QsciScintilla::WrapMode wrap;
QsciPrinter(const QsciPrinter &);
QsciPrinter &operator=(const QsciPrinter &);
};
#endif
#ifdef __APPLE__
}
#endif
#endif
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+197
View File
@@ -0,0 +1,197 @@
// This module defines interface to the QsciStyle class.
//
// Copyright (c) 2015 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.
#ifndef QSCISTYLE_H
#define QSCISTYLE_H
#ifdef __APPLE__
extern "C++" {
#endif
#include <qcolor.h>
#include <qfont.h>
#include <qstring.h>
#include <Qsci/qsciglobal.h>
class QsciScintillaBase;
//! \brief The QsciStyle class encapsulates all the attributes of a style.
//!
//! Each character of a document has an associated style which determines how
//! the character is displayed, e.g. its font and color. A style is identified
//! by a number. Lexers define styles for each of the language's features so
//! that they are displayed differently. Some style numbers have hard-coded
//! meanings, e.g. the style used for call tips.
class QSCINTILLA_EXPORT QsciStyle
{
public:
//! This enum defines the different ways the displayed case of the text can
//! be changed.
enum TextCase {
//! The text is displayed as its original case.
OriginalCase = 0,
//! The text is displayed as upper case.
UpperCase = 1,
//! The text is displayed as lower case.
LowerCase = 2
};
//! Constructs a QsciStyle instance for style number \a style. If \a style
//! is negative then a new style number is automatically allocated.
QsciStyle(int style = -1);
//! Constructs a QsciStyle instance for style number \a style. If \a style
//! is negative then a new style number is automatically allocated. The
//! styles description, color, paper color, font and end-of-line fill are
//! set to \a description, \a color, \a paper, \a font and \a eolFill
//! respectively.
QsciStyle(int style, const QString &description, const QColor &color,
const QColor &paper, const QFont &font, bool eolFill = false);
//! \internal Apply the style to a particular editor.
void apply(QsciScintillaBase *sci) const;
//! Returns the number of the style.
int style() const {return style_nr;}
//! The style's description is set to \a description.
//!
//! \sa description()
void setDescription(const QString &description) {style_description = description;}
//! Returns the style's description.
//!
//! \sa setDescription()
QString description() const {return style_description;}
//! The style's foreground color is set to \a color. The default is taken
//! from the application's default palette.
//!
//! \sa color()
void setColor(const QColor &color);
//! Returns the style's foreground color.
//!
//! \sa setColor()
QColor color() const {return style_color;}
//! The style's background color is set to \a paper. The default is taken
//! from the application's default palette.
//!
//! \sa paper()
void setPaper(const QColor &paper);
//! Returns the style's background color.
//!
//! \sa setPaper()
QColor paper() const {return style_paper;}
//! The style's font is set to \a font. The default is the application's
//! default font.
//!
//! \sa font()
void setFont(const QFont &font);
//! Returns the style's font.
//!
//! \sa setFont()
QFont font() const {return style_font;}
//! The style's end-of-line fill is set to \a fill. The default is false.
//!
//! \sa eolFill()
void setEolFill(bool fill);
//! Returns the style's end-of-line fill.
//!
//! \sa setEolFill()
bool eolFill() const {return style_eol_fill;}
//! The style's text case is set to \a text_case. The default is
//! OriginalCase.
//!
//! \sa textCase()
void setTextCase(TextCase text_case);
//! Returns the style's text case.
//!
//! \sa setTextCase()
TextCase textCase() const {return style_case;}
//! The style's visibility is set to \a visible. The default is true.
//!
//! \sa visible()
void setVisible(bool visible);
//! Returns the style's visibility.
//!
//! \sa setVisible()
bool visible() const {return style_visible;}
//! The style's changeability is set to \a changeable. The default is
//! true.
//!
//! \sa changeable()
void setChangeable(bool changeable);
//! Returns the style's changeability.
//!
//! \sa setChangeable()
bool changeable() const {return style_changeable;}
//! The style's sensitivity to mouse clicks is set to \a hotspot. The
//! default is false.
//!
//! \sa hotspot()
void setHotspot(bool hotspot);
//! Returns the style's sensitivity to mouse clicks.
//!
//! \sa setHotspot()
bool hotspot() const {return style_hotspot;}
//! Refresh the style settings.
void refresh();
private:
int style_nr;
QString style_description;
QColor style_color;
QColor style_paper;
QFont style_font;
bool style_eol_fill;
TextCase style_case;
bool style_visible;
bool style_changeable;
bool style_hotspot;
void init(int style);
};
#ifdef __APPLE__
}
#endif
#endif
@@ -0,0 +1,69 @@
// This module defines interface to the QsciStyledText class.
//
// Copyright (c) 2015 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.
#ifndef QSCISTYLEDTEXT_H
#define QSCISTYLEDTEXT_H
#ifdef __APPLE__
extern "C++" {
#endif
#include <qstring.h>
#include <Qsci/qsciglobal.h>
class QsciScintillaBase;
class QsciStyle;
//! \brief The QsciStyledText class is a container for a piece of text and the
//! style used to display the text.
class QSCINTILLA_EXPORT QsciStyledText
{
public:
//! Constructs a QsciStyledText instance for text \a text and style number
//! \a style.
QsciStyledText(const QString &text, int style);
//! Constructs a QsciStyledText instance for text \a text and style \a
//! style.
QsciStyledText(const QString &text, const QsciStyle &style);
//! \internal Apply the style to a particular editor.
void apply(QsciScintillaBase *sci) const;
//! Returns a reference to the text.
const QString &text() const {return styled_text;}
//! Returns the number of the style.
int style() const;
private:
QString styled_text;
int style_nr;
const QsciStyle *explicit_style;
};
#ifdef __APPLE__
}
#endif
#endif
+209
View File
@@ -0,0 +1,209 @@
// The implementation of various Qt version independent classes used by the
// rest of the port.
//
// Copyright (c) 2015 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 "SciNamespace.h"
#include "SciClasses.h"
#include <QCoreApplication>
#include <QKeyEvent>
#include <QListWidgetItem>
#include <QMouseEvent>
#include <QPainter>
#include <QPaintEvent>
#include "ScintillaQt.h"
#include "ListBoxQt.h"
// Create a call tip.
QsciSciCallTip::QsciSciCallTip(QWidget *parent, QsciScintillaQt *sci_)
: QWidget(parent, Qt::WindowFlags(Qt::Popup|Qt::FramelessWindowHint|Qt::WA_StaticContents)),
sci(sci_)
{
// Ensure that the main window keeps the focus (and the caret flashing)
// when this is displayed.
setFocusProxy(parent);
}
// Destroy a call tip.
QsciSciCallTip::~QsciSciCallTip()
{
// Ensure that the main window doesn't receive a focus out event when
// this is destroyed.
setFocusProxy(0);
}
// Paint a call tip.
void QsciSciCallTip::paintEvent(QPaintEvent *)
{
QSCI_SCI_NAMESPACE(Surface) *surfaceWindow = QSCI_SCI_NAMESPACE(Surface)::Allocate(SC_TECHNOLOGY_DEFAULT);
if (!surfaceWindow)
return;
QPainter p(this);
surfaceWindow->Init(&p);
surfaceWindow->SetUnicodeMode(sci->CodePage() == SC_CP_UTF8);
sci->ct.PaintCT(surfaceWindow);
delete surfaceWindow;
}
// Handle a mouse press in a call tip.
void QsciSciCallTip::mousePressEvent(QMouseEvent *e)
{
QSCI_SCI_NAMESPACE(Point) pt;
pt.x = e->x();
pt.y = e->y();
sci->ct.MouseClick(pt);
sci->CallTipClick();
update();
}
// Create the popup instance.
QsciSciPopup::QsciSciPopup()
{
// Set up the mapper.
connect(&mapper, SIGNAL(mapped(int)), this, SLOT(on_triggered(int)));
}
// Add an item and associated command to the popup and enable it if required.
void QsciSciPopup::addItem(const QString &label, int cmd, bool enabled,
QsciScintillaQt *sci_)
{
QAction *act = addAction(label, &mapper, SLOT(map()));
mapper.setMapping(act, cmd);
act->setEnabled(enabled);
sci = sci_;
}
// A slot to handle a menu action being triggered.
void QsciSciPopup::on_triggered(int cmd)
{
sci->Command(cmd);
}
QsciSciListBox::QsciSciListBox(QWidget *parent, QsciListBoxQt *lbx_)
: QListWidget(parent), lbx(lbx_)
{
setAttribute(Qt::WA_StaticContents);
#if defined(Q_OS_WIN)
setWindowFlags(Qt::Tool|Qt::FramelessWindowHint);
// This stops the main widget losing focus when the user clicks on this one
// (which prevents this one being destroyed).
setFocusPolicy(Qt::NoFocus);
#else
// This is the root of the focus problems under Gnome's window manager. We
// have tried many flag combinations in the past. The consensus now seems
// to be that the following works. However it might now work because of a
// change in Qt so we only enable it for recent versions in order to
// reduce the risk of breaking something that works with earlier versions.
#if QT_VERSION >= 0x040500
setWindowFlags(Qt::ToolTip|Qt::WindowStaysOnTopHint);
#else
setWindowFlags(Qt::Tool|Qt::FramelessWindowHint);
#endif
// This may not be needed.
setFocusProxy(parent);
#endif
setFrameShape(StyledPanel);
setFrameShadow(Plain);
connect(this, SIGNAL(itemDoubleClicked(QListWidgetItem *)),
SLOT(handleSelection()));
}
void QsciSciListBox::addItemPixmap(const QPixmap &pm, const QString &txt)
{
new QListWidgetItem(pm, txt, this);
}
int QsciSciListBox::find(const QString &prefix)
{
QList<QListWidgetItem *> itms = findItems(prefix,
Qt::MatchStartsWith|Qt::MatchCaseSensitive);
if (itms.size() == 0)
return -1;
return row(itms[0]);
}
QString QsciSciListBox::text(int n)
{
QListWidgetItem *itm = item(n);
if (!itm)
return QString();
return itm->text();
}
// Reimplemented to close the list when the user presses Escape.
void QsciSciListBox::keyPressEvent(QKeyEvent *e)
{
if (e->key() == Qt::Key_Escape)
{
e->accept();
close();
}
else
{
QListWidget::keyPressEvent(e);
if (!e->isAccepted())
QCoreApplication::sendEvent(parent(), e);
}
}
QsciSciListBox::~QsciSciListBox()
{
// Ensure that the main widget doesn't get a focus out event when this is
// destroyed.
setFocusProxy(0);
}
void QsciSciListBox::handleSelection()
{
if (lbx && lbx->cb_action)
lbx->cb_action(lbx->cb_data);
}
+105
View File
@@ -0,0 +1,105 @@
// The definition of various Qt version independent classes used by the rest of
// the port.
//
// Copyright (c) 2015 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.
#ifndef _SCICLASSES_H
#define _SCICLASSES_H
#include <QListWidget>
#include <QMenu>
#include <QSignalMapper>
#include <QWidget>
#include <Qsci/qsciglobal.h>
class QsciScintillaQt;
class QsciListBoxQt;
// A simple QWidget sub-class to implement a call tip. This is not put into
// the Scintilla namespace because of moc's problems with preprocessor macros.
class QsciSciCallTip : public QWidget
{
Q_OBJECT
public:
QsciSciCallTip(QWidget *parent, QsciScintillaQt *sci_);
~QsciSciCallTip();
protected:
void paintEvent(QPaintEvent *e);
void mousePressEvent(QMouseEvent *e);
private:
QsciScintillaQt *sci;
};
// A popup menu where options correspond to a numeric command. This is not put
// into the Scintilla namespace because of moc's problems with preprocessor
// macros.
class QsciSciPopup : public QMenu
{
Q_OBJECT
public:
QsciSciPopup();
void addItem(const QString &label, int cmd, bool enabled,
QsciScintillaQt *sci_);
private slots:
void on_triggered(int cmd);
private:
QsciScintillaQt *sci;
QSignalMapper mapper;
};
// This sub-class of QListBox is needed to provide slots from which we can call
// QsciListBox's double-click callback (and you thought this was a C++
// program). This is not put into the Scintilla namespace because of moc's
// problems with preprocessor macros.
class QsciSciListBox : public QListWidget
{
Q_OBJECT
public:
QsciSciListBox(QWidget *parent, QsciListBoxQt *lbx_);
virtual ~QsciSciListBox();
void addItemPixmap(const QPixmap &pm, const QString &txt);
int find(const QString &prefix);
QString text(int n);
protected:
void keyPressEvent(QKeyEvent *e);
private slots:
void handleSelection();
private:
QsciListBoxQt *lbx;
};
#endif
+35
View File
@@ -0,0 +1,35 @@
// Support for building the Scintilla code in the Scintilla namespace using the
// -DSCI_NAMESPACE compiler flag.
//
// Copyright (c) 2015 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.
#ifndef _SCINAMESPACE_H
#define _SCINAMESPACE_H
#ifdef SCI_NAMESPACE
#define QSCI_SCI_NAMESPACE(name) Scintilla::name
#define QSCI_BEGIN_SCI_NAMESPACE namespace Scintilla {
#define QSCI_END_SCI_NAMESPACE };
#else
#define QSCI_SCI_NAMESPACE(name) name
#define QSCI_BEGIN_SCI_NAMESPACE
#define QSCI_END_SCI_NAMESPACE
#endif
#endif
+694
View File
@@ -0,0 +1,694 @@
// The implementation of the Qt specific subclass of ScintillaBase.
//
// Copyright (c) 2015 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 <string.h>
#include <qapplication.h>
#include <qbytearray.h>
#include <qdrag.h>
#include <qevent.h>
#include <qmimedata.h>
#include <qpainter.h>
#include <qscrollbar.h>
#include <qstring.h>
#include "Qsci/qsciscintillabase.h"
#include "ScintillaQt.h"
#include "SciClasses.h"
// We want to use the Scintilla notification names as Qt signal names.
#undef SCEN_CHANGE
#undef SCN_AUTOCCANCELLED
#undef SCN_AUTOCCHARDELETED
#undef SCN_AUTOCSELECTION
#undef SCN_CALLTIPCLICK
#undef SCN_CHARADDED
#undef SCN_DOUBLECLICK
#undef SCN_DWELLEND
#undef SCN_DWELLSTART
#undef SCN_FOCUSIN
#undef SCN_FOCUSOUT
#undef SCN_HOTSPOTCLICK
#undef SCN_HOTSPOTDOUBLECLICK
#undef SCN_HOTSPOTRELEASECLICK
#undef SCN_INDICATORCLICK
#undef SCN_INDICATORRELEASE
#undef SCN_MACRORECORD
#undef SCN_MARGINCLICK
#undef SCN_MODIFIED
#undef SCN_MODIFYATTEMPTRO
#undef SCN_NEEDSHOWN
#undef SCN_PAINTED
#undef SCN_SAVEPOINTLEFT
#undef SCN_SAVEPOINTREACHED
#undef SCN_STYLENEEDED
#undef SCN_UPDATEUI
#undef SCN_USERLISTSELECTION
#undef SCN_ZOOM
enum
{
SCEN_CHANGE = 768,
SCN_AUTOCCANCELLED = 2025,
SCN_AUTOCCHARDELETED = 2026,
SCN_AUTOCSELECTION = 2022,
SCN_CALLTIPCLICK = 2021,
SCN_CHARADDED = 2001,
SCN_DOUBLECLICK = 2006,
SCN_DWELLEND = 2017,
SCN_DWELLSTART = 2016,
SCN_FOCUSIN = 2028,
SCN_FOCUSOUT = 2029,
SCN_HOTSPOTCLICK = 2019,
SCN_HOTSPOTDOUBLECLICK = 2020,
SCN_HOTSPOTRELEASECLICK = 2027,
SCN_INDICATORCLICK = 2023,
SCN_INDICATORRELEASE = 2024,
SCN_MACRORECORD = 2009,
SCN_MARGINCLICK = 2010,
SCN_MODIFIED = 2008,
SCN_MODIFYATTEMPTRO = 2004,
SCN_NEEDSHOWN = 2011,
SCN_PAINTED = 2013,
SCN_SAVEPOINTLEFT = 2003,
SCN_SAVEPOINTREACHED = 2002,
SCN_STYLENEEDED = 2000,
SCN_UPDATEUI = 2007,
SCN_USERLISTSELECTION = 2014,
SCN_ZOOM = 2018
};
// The ctor.
QsciScintillaQt::QsciScintillaQt(QsciScintillaBase *qsb_)
: vMax(0), hMax(0), vPage(0), hPage(0), capturedMouse(false), qsb(qsb_)
{
wMain = qsb->viewport();
// This is ignored.
imeInteraction = imeInline;
for (int i = 0; i <= static_cast<int>(tickPlatform); ++i)
timers[i] = 0;
Initialise();
}
// The dtor.
QsciScintillaQt::~QsciScintillaQt()
{
Finalise();
}
// Initialise the instance.
void QsciScintillaQt::Initialise()
{
}
// Tidy up the instance.
void QsciScintillaQt::Finalise()
{
for (int i = 0; i <= static_cast<int>(tickPlatform); ++i)
FineTickerCancel(static_cast<TickReason>(i));
ScintillaBase::Finalise();
}
// Start a drag.
void QsciScintillaQt::StartDrag()
{
inDragDrop = ddDragging;
QDrag *qdrag = new QDrag(qsb);
qdrag->setMimeData(mimeSelection(drag));
#if QT_VERSION >= 0x040300
Qt::DropAction action = qdrag->exec(Qt::MoveAction | Qt::CopyAction, Qt::MoveAction);
#else
Qt::DropAction action = qdrag->start(Qt::MoveAction);
#endif
// Remove the dragged text if it was a move to another widget or
// application.
if (action == Qt::MoveAction && qdrag->target() != qsb->viewport())
ClearSelection();
SetDragPosition(QSCI_SCI_NAMESPACE(SelectionPosition)());
inDragDrop = ddNone;
}
// Re-implement to trap certain messages.
sptr_t QsciScintillaQt::WndProc(unsigned int iMessage, uptr_t wParam,
sptr_t lParam)
{
switch (iMessage)
{
case SCI_GETDIRECTFUNCTION:
return reinterpret_cast<sptr_t>(DirectFunction);
case SCI_GETDIRECTPOINTER:
return reinterpret_cast<sptr_t>(this);
}
return ScintillaBase::WndProc(iMessage, wParam, lParam);
}
// Windows nonsense.
sptr_t QsciScintillaQt::DefWndProc(unsigned int, uptr_t, sptr_t)
{
return 0;
}
// Grab or release the mouse (and keyboard).
void QsciScintillaQt::SetMouseCapture(bool on)
{
if (mouseDownCaptures)
if (on)
qsb->viewport()->grabMouse();
else
qsb->viewport()->releaseMouse();
capturedMouse = on;
}
// Return true if the mouse/keyboard are currently grabbed.
bool QsciScintillaQt::HaveMouseCapture()
{
return capturedMouse;
}
// Set the position of the vertical scrollbar.
void QsciScintillaQt::SetVerticalScrollPos()
{
QScrollBar *sb = qsb->verticalScrollBar();
bool was_blocked = sb->blockSignals(true);
sb->setValue(topLine);
sb->blockSignals(was_blocked);
}
// Set the position of the horizontal scrollbar.
void QsciScintillaQt::SetHorizontalScrollPos()
{
QScrollBar *sb = qsb->horizontalScrollBar();
bool was_blocked = sb->blockSignals(true);
sb->setValue(xOffset);
sb->blockSignals(was_blocked);
}
// Set the extent of the vertical and horizontal scrollbars and return true if
// the view needs re-drawing.
bool QsciScintillaQt::ModifyScrollBars(int nMax,int nPage)
{
bool modified = false;
QScrollBar *sb;
int vNewPage = nPage;
int vNewMax = nMax - vNewPage + 1;
if (vMax != vNewMax || vPage != vNewPage)
{
vMax = vNewMax;
vPage = vNewPage;
modified = true;
sb = qsb->verticalScrollBar();
sb->setMaximum(vMax);
sb->setPageStep(vPage);
}
int hNewPage = GetTextRectangle().Width();
int hNewMax = (scrollWidth > hNewPage) ? scrollWidth - hNewPage : 0;
int charWidth = vs.styles[STYLE_DEFAULT].aveCharWidth;
sb = qsb->horizontalScrollBar();
if (hMax != hNewMax || hPage != hNewPage || sb->singleStep() != charWidth)
{
hMax = hNewMax;
hPage = hNewPage;
modified = true;
sb->setMaximum(hMax);
sb->setPageStep(hPage);
sb->setSingleStep(charWidth);
}
return modified;
}
// Called after SCI_SETWRAPMODE and SCI_SETHSCROLLBAR.
void QsciScintillaQt::ReconfigureScrollBars()
{
// Hide or show the scrollbars if needed.
bool hsb = (horizontalScrollBarVisible && !Wrapping());
qsb->setHorizontalScrollBarPolicy(hsb ? Qt::ScrollBarAsNeeded : Qt::ScrollBarAlwaysOff);
qsb->setVerticalScrollBarPolicy(verticalScrollBarVisible ? Qt::ScrollBarAsNeeded : Qt::ScrollBarAlwaysOff);
}
// Notify interested parties of any change in the document.
void QsciScintillaQt::NotifyChange()
{
emit qsb->SCEN_CHANGE();
}
// Notify interested parties of various events. This is the main mapping
// between Scintilla notifications and Qt signals.
void QsciScintillaQt::NotifyParent(QSCI_SCI_NAMESPACE(SCNotification) scn)
{
switch (scn.nmhdr.code)
{
case SCN_CALLTIPCLICK:
emit qsb->SCN_CALLTIPCLICK(scn.position);
break;
case SCN_AUTOCCANCELLED:
emit qsb->SCN_AUTOCCANCELLED();
break;
case SCN_AUTOCCHARDELETED:
emit qsb->SCN_AUTOCCHARDELETED();
break;
case SCN_AUTOCSELECTION:
emit qsb->SCN_AUTOCSELECTION(scn.text, scn.lParam);
break;
case SCN_CHARADDED:
emit qsb->SCN_CHARADDED(scn.ch);
break;
case SCN_DOUBLECLICK:
emit qsb->SCN_DOUBLECLICK(scn.position, scn.line, scn.modifiers);
break;
case SCN_DWELLEND:
emit qsb->SCN_DWELLEND(scn.position, scn.x, scn.y);
break;
case SCN_DWELLSTART:
emit qsb->SCN_DWELLSTART(scn.position, scn.x, scn.y);
break;
case SCN_FOCUSIN:
emit qsb->SCN_FOCUSIN();
break;
case SCN_FOCUSOUT:
emit qsb->SCN_FOCUSOUT();
break;
case SCN_HOTSPOTCLICK:
emit qsb->SCN_HOTSPOTCLICK(scn.position, scn.modifiers);
break;
case SCN_HOTSPOTDOUBLECLICK:
emit qsb->SCN_HOTSPOTDOUBLECLICK(scn.position, scn.modifiers);
break;
case SCN_HOTSPOTRELEASECLICK:
emit qsb->SCN_HOTSPOTRELEASECLICK(scn.position, scn.modifiers);
break;
case SCN_INDICATORCLICK:
emit qsb->SCN_INDICATORCLICK(scn.position, scn.modifiers);
break;
case SCN_INDICATORRELEASE:
emit qsb->SCN_INDICATORRELEASE(scn.position, scn.modifiers);
break;
case SCN_MACRORECORD:
emit qsb->SCN_MACRORECORD(scn.message, scn.wParam,
reinterpret_cast<void *>(scn.lParam));
break;
case SCN_MARGINCLICK:
emit qsb->SCN_MARGINCLICK(scn.position, scn.modifiers, scn.margin);
break;
case SCN_MODIFIED:
{
char *text;
// Give some protection to the Python bindings.
if (scn.text && (scn.modificationType & (SC_MOD_INSERTTEXT|SC_MOD_DELETETEXT) != 0))
{
text = new char[scn.length + 1];
memcpy(text, scn.text, scn.length);
text[scn.length] = '\0';
}
else
{
text = 0;
}
emit qsb->SCN_MODIFIED(scn.position, scn.modificationType, text,
scn.length, scn.linesAdded, scn.line, scn.foldLevelNow,
scn.foldLevelPrev, scn.token, scn.annotationLinesAdded);
if (text)
delete[] text;
break;
}
case SCN_MODIFYATTEMPTRO:
emit qsb->SCN_MODIFYATTEMPTRO();
break;
case SCN_NEEDSHOWN:
emit qsb->SCN_NEEDSHOWN(scn.position, scn.length);
break;
case SCN_PAINTED:
emit qsb->SCN_PAINTED();
break;
case SCN_SAVEPOINTLEFT:
emit qsb->SCN_SAVEPOINTLEFT();
break;
case SCN_SAVEPOINTREACHED:
emit qsb->SCN_SAVEPOINTREACHED();
break;
case SCN_STYLENEEDED:
emit qsb->SCN_STYLENEEDED(scn.position);
break;
case SCN_UPDATEUI:
emit qsb->SCN_UPDATEUI(scn.updated);
break;
case SCN_USERLISTSELECTION:
emit qsb->SCN_USERLISTSELECTION(scn.text, scn.wParam);
break;
case SCN_ZOOM:
emit qsb->SCN_ZOOM();
break;
default:
qWarning("Unknown notification: %u", scn.nmhdr.code);
}
}
// Convert a selection to mime data.
QMimeData *QsciScintillaQt::mimeSelection(
const QSCI_SCI_NAMESPACE(SelectionText) &text) const
{
return qsb->toMimeData(QByteArray(text.Data()), text.rectangular);
}
// Copy the selected text to the clipboard.
void QsciScintillaQt::CopyToClipboard(
const QSCI_SCI_NAMESPACE(SelectionText) &selectedText)
{
QApplication::clipboard()->setMimeData(mimeSelection(selectedText));
}
// Implement copy.
void QsciScintillaQt::Copy()
{
if (!sel.Empty())
{
QSCI_SCI_NAMESPACE(SelectionText) text;
CopySelectionRange(&text);
CopyToClipboard(text);
}
}
// Implement pasting text.
void QsciScintillaQt::Paste()
{
pasteFromClipboard(QClipboard::Clipboard);
}
// Paste text from either the clipboard or selection.
void QsciScintillaQt::pasteFromClipboard(QClipboard::Mode mode)
{
int len;
const char *s;
bool rectangular;
const QMimeData *source = QApplication::clipboard()->mimeData(mode);
if (!source || !qsb->canInsertFromMimeData(source))
return;
QByteArray text = qsb->fromMimeData(source, rectangular);
len = text.length();
s = text.data();
std::string dest = QSCI_SCI_NAMESPACE(Document)::TransformLineEnds(s, len,
pdoc->eolMode);
QSCI_SCI_NAMESPACE(SelectionText) selText;
selText.Copy(dest, (IsUnicodeMode() ? SC_CP_UTF8 : 0),
vs.styles[STYLE_DEFAULT].characterSet, rectangular, false);
QSCI_SCI_NAMESPACE(UndoGroup) ug(pdoc);
ClearSelection();
InsertPasteShape(selText.Data(), selText.Length(),
selText.rectangular ? pasteRectangular : pasteStream);
EnsureCaretVisible();
}
// Create a call tip window.
void QsciScintillaQt::CreateCallTipWindow(QSCI_SCI_NAMESPACE(PRectangle) rc)
{
if (!ct.wCallTip.Created())
ct.wCallTip = ct.wDraw = new QsciSciCallTip(qsb, this);
QsciSciCallTip *w = reinterpret_cast<QsciSciCallTip *>(ct.wCallTip.GetID());
w->resize(rc.right - rc.left, rc.bottom - rc.top);
ct.wCallTip.Show();
}
// Add an item to the right button menu.
void QsciScintillaQt::AddToPopUp(const char *label, int cmd, bool enabled)
{
QsciSciPopup *pm = static_cast<QsciSciPopup *>(popup.GetID());
if (*label)
pm->addItem(qApp->translate("ContextMenu", label), cmd, enabled, this);
else
pm->addSeparator();
}
// Claim the selection.
void QsciScintillaQt::ClaimSelection()
{
bool isSel = !sel.Empty();
if (isSel)
{
QClipboard *cb = QApplication::clipboard();
// If we support X11 style selection then make it available now.
if (cb->supportsSelection())
{
QSCI_SCI_NAMESPACE(SelectionText) text;
CopySelectionRange(&text);
if (text.Data())
cb->setMimeData(mimeSelection(text), QClipboard::Selection);
}
primarySelection = true;
}
else
primarySelection = false;
emit qsb->QSCN_SELCHANGED(isSel);
}
// Unclaim the selection.
void QsciScintillaQt::UnclaimSelection()
{
if (primarySelection)
{
primarySelection = false;
qsb->viewport()->update();
}
}
// Implemented to provide compatibility with the Windows version.
sptr_t QsciScintillaQt::DirectFunction(QsciScintillaQt *sciThis, unsigned int iMessage,
uptr_t wParam, sptr_t lParam)
{
return sciThis->WndProc(iMessage,wParam,lParam);
}
// Draw the contents of the widget.
void QsciScintillaQt::paintEvent(QPaintEvent *e)
{
QSCI_SCI_NAMESPACE(Surface) *sw = QSCI_SCI_NAMESPACE(Surface)::Allocate(SC_TECHNOLOGY_DEFAULT);
if (!sw)
return;
paintState = painting;
const QRect &qr = e->rect();
rcPaint.left = qr.left();
rcPaint.top = qr.top();
rcPaint.right = qr.right() + 1;
rcPaint.bottom = qr.bottom() + 1;
QSCI_SCI_NAMESPACE(PRectangle) rcText = GetTextRectangle();
paintingAllText = rcPaint.Contains(rcText);
QPainter painter(qsb->viewport());
sw->Init(&painter);
sw->SetUnicodeMode(CodePage() == SC_CP_UTF8);
Paint(sw, rcPaint);
delete sw;
// If the painting area was insufficient to cover the new style or brace
// highlight positions then repaint the whole thing.
if (paintState == paintAbandoned)
qsb->viewport()->update();
paintState = notPainting;
}
// Re-implemented to drive the tickers.
void QsciScintillaQt::timerEvent(QTimerEvent *e)
{
for (int i = 0; i <= static_cast<int>(tickPlatform); ++i)
if (timers[i] == e->timerId())
TickFor(static_cast<TickReason>(i));
}
// Re-implemented to say we support fine tickers.
bool QsciScintillaQt::FineTickerAvailable()
{
return true;
}
// Re-implemented to stop a ticker.
void QsciScintillaQt::FineTickerCancel(TickReason reason)
{
int &ticker = timers[static_cast<int>(reason)];
if (ticker != 0)
{
killTimer(ticker);
ticker = 0;
}
}
// Re-implemented to check if a particular ticker is running.
bool QsciScintillaQt::FineTickerRunning(TickReason reason)
{
return (timers[static_cast<int>(reason)] != 0);
}
// Re-implemented to start a ticker.
void QsciScintillaQt::FineTickerStart(TickReason reason, int ms, int)
{
int &ticker = timers[static_cast<int>(reason)];
if (ticker != 0)
killTimer(ticker);
ticker = startTimer(ms);
}
// Re-implemented to support idle processing.
bool QsciScintillaQt::SetIdle(bool on)
{
if (on)
{
if (!idler.state)
{
QTimer *timer = reinterpret_cast<QTimer *>(idler.idlerID);
if (!timer)
{
idler.idlerID = timer = new QTimer(this);
connect(timer, SIGNAL(timeout()), this, SLOT(onIdle()));
}
timer->start(0);
idler.state = true;
}
}
else if (idler.state)
{
reinterpret_cast<QTimer *>(idler.idlerID)->stop();
idler.state = false;
}
return true;
}
// Invoked to trigger any idle processing.
void QsciScintillaQt::onIdle()
{
if (!Idle())
SetIdle(false);
}
+150
View File
@@ -0,0 +1,150 @@
// The definition of the Qt specific subclass of ScintillaBase.
//
// Copyright (c) 2015 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.
#ifndef SCINTILLAQT_H
#define SCINTILLAQT_H
#include <QClipboard>
#include <QObject>
#include <Qsci/qsciglobal.h>
#include "SciNamespace.h"
// These are needed because Scintilla class header files don't manage their own
// dependencies properly.
#include <algorithm>
#include <assert.h>
#include <ctype.h>
#include <stdexcept>
#include <stdlib.h>
#include <string>
#include <map>
#include <vector>
#include "ILexer.h"
#include "Platform.h"
#include "Scintilla.h"
#include "SplitVector.h"
#include "Partitioning.h"
#include "CellBuffer.h"
#include "CharClassify.h"
#include "RunStyles.h"
#include "CaseFolder.h"
#include "Decoration.h"
#include "Document.h"
#include "Style.h"
#include "XPM.h"
#include "LineMarker.h"
#include "Indicator.h"
#include "ViewStyle.h"
#include "KeyMap.h"
#include "ContractionState.h"
#include "Selection.h"
#include "PositionCache.h"
#include "EditModel.h"
#include "MarginView.h"
#include "EditView.h"
#include "Editor.h"
#include "AutoComplete.h"
#include "CallTip.h"
#include "LexAccessor.h"
#include "Accessor.h"
#include "ScintillaBase.h"
QT_BEGIN_NAMESPACE
class QMimeData;
class QPaintEvent;
QT_END_NAMESPACE
class QsciScintillaBase;
class QsciSciCallTip;
class QsciSciPopup;
// This is an internal class but it is referenced by a public class so it has
// to have a Qsci prefix rather than being put in the Scintilla namespace
// which would mean exposing the SCI_NAMESPACE mechanism).
class QsciScintillaQt : public QObject, public QSCI_SCI_NAMESPACE(ScintillaBase)
{
Q_OBJECT
friend class QsciScintillaBase;
friend class QsciSciCallTip;
friend class QsciSciPopup;
public:
QsciScintillaQt(QsciScintillaBase *qsb_);
virtual ~QsciScintillaQt();
virtual sptr_t WndProc(unsigned int iMessage, uptr_t wParam,
sptr_t lParam);
protected:
void timerEvent(QTimerEvent *e);
private slots:
void onIdle();
private:
void Initialise();
void Finalise();
bool SetIdle(bool on);
void StartDrag();
sptr_t DefWndProc(unsigned int, uptr_t, sptr_t);
void SetMouseCapture(bool on);
bool HaveMouseCapture();
void SetVerticalScrollPos();
void SetHorizontalScrollPos();
bool ModifyScrollBars(int nMax, int nPage);
void ReconfigureScrollBars();
void NotifyChange();
void NotifyParent(QSCI_SCI_NAMESPACE(SCNotification) scn);
void CopyToClipboard(
const QSCI_SCI_NAMESPACE(SelectionText) &selectedText);
void Copy();
void Paste();
void CreateCallTipWindow(QSCI_SCI_NAMESPACE(PRectangle) rc);
void AddToPopUp(const char *label, int cmd = 0, bool enabled = true);
void ClaimSelection();
void UnclaimSelection();
static sptr_t DirectFunction(QsciScintillaQt *sci, unsigned int iMessage,
uptr_t wParam,sptr_t lParam);
QMimeData *mimeSelection(
const QSCI_SCI_NAMESPACE(SelectionText) &text) const;
void paintEvent(QPaintEvent *e);
void pasteFromClipboard(QClipboard::Mode mode);
// tickPlatform is the last of the TickReason members.
int timers[tickPlatform + 1];
bool FineTickerAvailable();
void FineTickerCancel(TickReason reason);
bool FineTickerRunning(TickReason reason);
void FineTickerStart(TickReason reason, int ms, int tolerance);
int vMax, hMax, vPage, hPage;
bool capturedMouse;
QsciScintillaBase *qsb;
};
#endif
@@ -0,0 +1,25 @@
greaterThan(QT_MAJOR_VERSION, 4) {
QT += widgets printsupport
greaterThan(QT_MINOR_VERSION, 1) {
macx:QT += macextras
}
}
INCLUDEPATH += $$[QT_INSTALL_HEADERS]
LIBS += -L$$[QT_INSTALL_LIBS]
CONFIG(debug, debug|release) {
mac: {
LIBS += -lqscintilla2_debug
} else {
win32: {
LIBS += -lqscintilla2d
} else {
LIBS += -lqscintilla2
}
}
} else {
LIBS += -lqscintilla2
}
@@ -0,0 +1,50 @@
// This module implements the QsciAbstractAPIs class.
//
// Copyright (c) 2015 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/qsciabstractapis.h"
#include "Qsci/qscilexer.h"
// The ctor.
QsciAbstractAPIs::QsciAbstractAPIs(QsciLexer *lexer)
: QObject(lexer), lex(lexer)
{
lexer->setAPIs(this);
}
// The dtor.
QsciAbstractAPIs::~QsciAbstractAPIs()
{
}
// Return the lexer.
QsciLexer *QsciAbstractAPIs::lexer() const
{
return lex;
}
// Called when the user has made a selection from the auto-completion list.
void QsciAbstractAPIs::autoCompletionSelected(const QString &selection)
{
}
+968
View File
@@ -0,0 +1,968 @@
// This module implements the QsciAPIs class.
//
// Copyright (c) 2015 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 <stdlib.h>
#include "Qsci/qsciapis.h"
#include <QApplication>
#include <QDataStream>
#include <QDir>
#include <QEvent>
#include <QFile>
#include <QLibraryInfo>
#include <QMap>
#include <QTextStream>
#include <QThread>
#include "Qsci/qscilexer.h"
// The version number of the prepared API information format.
const unsigned char PreparedDataFormatVersion = 0;
// This class contains prepared API information.
struct QsciAPIsPrepared
{
// The word dictionary is a map of individual words and a list of positions
// each occurs in the sorted list of APIs. A position is a tuple of the
// index into the list of APIs and the index into the particular API.
QMap<QString, QsciAPIs::WordIndexList> wdict;
// The case dictionary maps the case insensitive words to the form in which
// they are to be used. It is only used if the language is case
// insensitive.
QMap<QString, QString> cdict;
// The raw API information.
QStringList raw_apis;
QStringList apiWords(int api_idx, const QStringList &wseps,
bool strip_image) const;
static QString apiBaseName(const QString &api);
};
// Return a particular API entry as a list of words.
QStringList QsciAPIsPrepared::apiWords(int api_idx, const QStringList &wseps,
bool strip_image) const
{
QString base = apiBaseName(raw_apis[api_idx]);
// Remove any embedded image reference if necessary.
if (strip_image)
{
int tail = base.indexOf('?');
if (tail >= 0)
base.truncate(tail);
}
if (wseps.isEmpty())
return QStringList(base);
return base.split(wseps.first());
}
// Return the name of an API function, ie. without the arguments.
QString QsciAPIsPrepared::apiBaseName(const QString &api)
{
QString base = api;
int tail = base.indexOf('(');
if (tail >= 0)
base.truncate(tail);
return base.simplified();
}
// The user event type that signals that the worker thread has started.
const QEvent::Type WorkerStarted = static_cast<QEvent::Type>(QEvent::User + 1012);
// The user event type that signals that the worker thread has finished.
const QEvent::Type WorkerFinished = static_cast<QEvent::Type>(QEvent::User + 1013);
// The user event type that signals that the worker thread has aborted.
const QEvent::Type WorkerAborted = static_cast<QEvent::Type>(QEvent::User + 1014);
// This class is the worker thread that post-processes the API set.
class QsciAPIsWorker : public QThread
{
public:
QsciAPIsWorker(QsciAPIs *apis);
virtual ~QsciAPIsWorker();
virtual void run();
QsciAPIsPrepared *prepared;
private:
QsciAPIs *proxy;
bool abort;
};
// The worker thread ctor.
QsciAPIsWorker::QsciAPIsWorker(QsciAPIs *apis)
: proxy(apis), prepared(0), abort(false)
{
}
// The worker thread dtor.
QsciAPIsWorker::~QsciAPIsWorker()
{
// Tell the thread to stop. There is no need to bother with a mutex.
abort = true;
// Wait for it to do so and hit it if it doesn't.
if (!wait(500))
terminate();
if (prepared)
delete prepared;
}
// The worker thread entry point.
void QsciAPIsWorker::run()
{
// Sanity check.
if (!prepared)
return;
// Tell the main thread we have started.
QApplication::postEvent(proxy, new QEvent(WorkerStarted));
// Sort the full list.
prepared->raw_apis.sort();
QStringList wseps = proxy->lexer()->autoCompletionWordSeparators();
bool cs = proxy->lexer()->caseSensitive();
// Split each entry into separate words but ignoring any arguments.
for (int a = 0; a < prepared->raw_apis.count(); ++a)
{
// Check to see if we should stop.
if (abort)
break;
QStringList words = prepared->apiWords(a, wseps, true);
for (int w = 0; w < words.count(); ++w)
{
const QString &word = words[w];
// Add the word's position to any existing list for this word.
QsciAPIs::WordIndexList wil = prepared->wdict[word];
// If the language is case insensitive and we haven't seen this
// word before then save it in the case dictionary.
if (!cs && wil.count() == 0)
prepared->cdict[word.toUpper()] = word;
wil.append(QsciAPIs::WordIndex(a, w));
prepared->wdict[word] = wil;
}
}
// Tell the main thread we have finished.
QApplication::postEvent(proxy, new QEvent(abort ? WorkerAborted : WorkerFinished));
}
// The ctor.
QsciAPIs::QsciAPIs(QsciLexer *lexer)
: QsciAbstractAPIs(lexer), worker(0), origin_len(0)
{
prep = new QsciAPIsPrepared;
}
// The dtor.
QsciAPIs::~QsciAPIs()
{
deleteWorker();
delete prep;
}
// Delete the worker thread if there is one.
void QsciAPIs::deleteWorker()
{
if (worker)
{
delete worker;
worker = 0;
}
}
//! Handle termination events from the worker thread.
bool QsciAPIs::event(QEvent *e)
{
switch (e->type())
{
case WorkerStarted:
emit apiPreparationStarted();
return true;
case WorkerAborted:
deleteWorker();
emit apiPreparationCancelled();
return true;
case WorkerFinished:
delete prep;
old_context.clear();
prep = worker->prepared;
worker->prepared = 0;
deleteWorker();
// Allow the raw API information to be modified.
apis = prep->raw_apis;
emit apiPreparationFinished();
return true;
}
return QObject::event(e);
}
// Clear the current raw API entries.
void QsciAPIs::clear()
{
apis.clear();
}
// Clear out all API information.
bool QsciAPIs::load(const QString &filename)
{
QFile f(filename);
if (!f.open(QIODevice::ReadOnly))
return false;
QTextStream ts(&f);
for (;;)
{
QString line = ts.readLine();
if (line.isEmpty())
break;
apis.append(line);
}
return true;
}
// Add a single API entry.
void QsciAPIs::add(const QString &entry)
{
apis.append(entry);
}
// Remove a single API entry.
void QsciAPIs::remove(const QString &entry)
{
int idx = apis.indexOf(entry);
if (idx >= 0)
apis.removeAt(idx);
}
// Position the "origin" cursor into the API entries according to the user
// supplied context.
QStringList QsciAPIs::positionOrigin(const QStringList &context, QString &path)
{
// Get the list of words and see if the context is the same as last time we
// were called.
QStringList new_context;
bool same_context = (old_context.count() > 0 && old_context.count() < context.count());
for (int i = 0; i < context.count(); ++i)
{
QString word = context[i];
if (!lexer()->caseSensitive())
word = word.toUpper();
if (i < old_context.count() && old_context[i] != word)
same_context = false;
new_context << word;
}
// If the context has changed then reset the origin.
if (!same_context)
origin_len = 0;
// If we have a current origin (ie. the user made a specific selection in
// the current context) then adjust the origin to include the last complete
// word as the user may have entered more parts of the name without using
// auto-completion.
if (origin_len > 0)
{
const QString wsep = lexer()->autoCompletionWordSeparators().first();
int start_new = old_context.count();
int end_new = new_context.count() - 1;
if (start_new == end_new)
{
path = old_context.join(wsep);
origin_len = path.length();
}
else
{
QString fixed = *origin;
fixed.truncate(origin_len);
path = fixed;
while (start_new < end_new)
{
// Add this word to the current path.
path.append(wsep);
path.append(new_context[start_new]);
origin_len = path.length();
// Skip entries in the current origin that don't match the
// path.
while (origin != prep->raw_apis.end())
{
// See if the current origin has come to an end.
if (!originStartsWith(fixed, wsep))
origin = prep->raw_apis.end();
else if (originStartsWith(path, wsep))
break;
else
++origin;
}
if (origin == prep->raw_apis.end())
break;
++start_new;
}
}
// Terminate the path.
path.append(wsep);
// If the new text wasn't recognised then reset the origin.
if (origin == prep->raw_apis.end())
origin_len = 0;
}
if (origin_len == 0)
path.truncate(0);
// Save the "committed" context for next time.
old_context = new_context;
old_context.removeLast();
return new_context;
}
// Return true if the origin starts with the given path.
bool QsciAPIs::originStartsWith(const QString &path, const QString &wsep)
{
const QString &orig = *origin;
if (!orig.startsWith(path))
return false;
// Check that the path corresponds to the end of a word, ie. that what
// follows in the origin is either a word separator or a (.
QString tail = orig.mid(path.length());
return (!tail.isEmpty() && (tail.startsWith(wsep) || tail.at(0) == '('));
}
// Add auto-completion words to an existing list.
void QsciAPIs::updateAutoCompletionList(const QStringList &context,
QStringList &list)
{
QString path;
QStringList new_context = positionOrigin(context, path);
if (origin_len > 0)
{
const QString wsep = lexer()->autoCompletionWordSeparators().first();
QStringList::const_iterator it = origin;
unambiguous_context = path;
while (it != prep->raw_apis.end())
{
QString base = QsciAPIsPrepared::apiBaseName(*it);
if (!base.startsWith(path))
break;
// Make sure we have something after the path.
if (base != path)
{
// Get the word we are interested in (ie. the one after the
// current origin in path).
QString w = base.mid(origin_len + wsep.length()).split(wsep).first();
// Append the space, we know the origin is unambiguous.
w.append(' ');
if (!list.contains(w))
list << w;
}
++it;
}
}
else
{
// At the moment we assume we will add words from multiple contexts.
unambiguous_context.truncate(0);
bool unambig = true;
QStringList with_context;
if (new_context.last().isEmpty())
lastCompleteWord(new_context[new_context.count() - 2], with_context, unambig);
else
lastPartialWord(new_context.last(), with_context, unambig);
for (int i = 0; i < with_context.count(); ++i)
{
// Remove any unambigious context.
QString noc = with_context[i];
if (unambig)
{
int op = noc.indexOf('(');
if (op >= 0)
noc.truncate(op);
}
list << noc;
}
}
}
// Get the index list for a particular word if there is one.
const QsciAPIs::WordIndexList *QsciAPIs::wordIndexOf(const QString &word) const
{
QString csword;
// Indirect through the case dictionary if the language isn't case
// sensitive.
if (lexer()->caseSensitive())
csword = word;
else
{
csword = prep->cdict[word];
if (csword.isEmpty())
return 0;
}
// Get the possible API entries if any.
const WordIndexList *wl = &prep->wdict[csword];
if (wl->isEmpty())
return 0;
return wl;
}
// Add auto-completion words based on the last complete word entered.
void QsciAPIs::lastCompleteWord(const QString &word, QStringList &with_context, bool &unambig)
{
// Get the possible API entries if any.
const WordIndexList *wl = wordIndexOf(word);
if (wl)
addAPIEntries(*wl, true, with_context, unambig);
}
// Add auto-completion words based on the last partial word entered.
void QsciAPIs::lastPartialWord(const QString &word, QStringList &with_context, bool &unambig)
{
if (lexer()->caseSensitive())
{
QMap<QString, WordIndexList>::const_iterator it = prep->wdict.lowerBound(word);
while (it != prep->wdict.end())
{
if (!it.key().startsWith(word))
break;
addAPIEntries(it.value(), false, with_context, unambig);
++it;
}
}
else
{
QMap<QString, QString>::const_iterator it = prep->cdict.lowerBound(word);
while (it != prep->cdict.end())
{
if (!it.key().startsWith(word))
break;
addAPIEntries(prep->wdict[it.value()], false, with_context, unambig);
++it;
}
}
}
// Handle the selection of an entry in the auto-completion list.
void QsciAPIs::autoCompletionSelected(const QString &selection)
{
// If the selection is an API (ie. it has a space separating the selected
// word and the optional origin) then remember the origin.
QStringList lst = selection.split(' ');
if (lst.count() != 2)
{
origin_len = 0;
return;
}
const QString &path = lst[1];
QString owords;
if (path.isEmpty())
owords = unambiguous_context;
else
{
// Check the parenthesis.
if (!path.startsWith("(") || !path.endsWith(")"))
{
origin_len = 0;
return;
}
// Remove the parenthesis.
owords = path.mid(1, path.length() - 2);
}
origin = qLowerBound(prep->raw_apis, owords);
/*
* There is a bug somewhere, either in qLowerBound() or QList (or in GCC as
* it seems to be Linux specific and the Qt code is the same on all
* platforms) that the following line seems to fix. Note that it is
* actually the call to detach() within begin() that is the important bit.
*/
prep->raw_apis.begin();
origin_len = owords.length();
}
// Add auto-completion words for a particular word (defined by where it appears
// in the APIs) and depending on whether the word was complete (when it's
// actually the next word in the API entry that is of interest) or not.
void QsciAPIs::addAPIEntries(const WordIndexList &wl, bool complete,
QStringList &with_context, bool &unambig)
{
QStringList wseps = lexer()->autoCompletionWordSeparators();
for (int w = 0; w < wl.count(); ++w)
{
const WordIndex &wi = wl[w];
QStringList api_words = prep->apiWords(wi.first, wseps, false);
int idx = wi.second;
if (complete)
{
// Skip if this is the last word.
if (++idx >= api_words.count())
continue;
}
QString api_word;
if (idx == 0)
api_word = api_words[0] + ' ';
else
{
QStringList orgl = api_words.mid(0, idx);
QString org = orgl.join(wseps.first());
api_word = QString("%1 (%2)").arg(api_words[idx]).arg(org);
// See if the origin has been used before.
if (unambig)
if (unambiguous_context.isEmpty())
unambiguous_context = org;
else if (unambiguous_context != org)
{
unambiguous_context.truncate(0);
unambig = false;
}
}
if (!with_context.contains(api_word))
with_context.append(api_word);
}
}
// Return the call tip for a function.
QStringList QsciAPIs::callTips(const QStringList &context, int commas,
QsciScintilla::CallTipsStyle style, QList<int> &shifts)
{
QString path;
QStringList new_context = positionOrigin(context, path);
QStringList wseps = lexer()->autoCompletionWordSeparators();
QStringList cts;
if (origin_len > 0)
{
// The path should have a trailing word separator.
const QString &wsep = wseps.first();
path.chop(wsep.length());
QStringList::const_iterator it = origin;
QString prev;
// Work out the length of the context.
QStringList strip = path.split(wsep);
strip.removeLast();
int ctstart = strip.join(wsep).length();
if (ctstart)
ctstart += wsep.length();
int shift;
if (style == QsciScintilla::CallTipsContext)
{
shift = ctstart;
ctstart = 0;
}
else
shift = 0;
// Make sure we only look at the functions we are interested in.
path.append('(');
while (it != prep->raw_apis.end() && (*it).startsWith(path))
{
QString w = (*it).mid(ctstart);
if (w != prev && enoughCommas(w, commas))
{
shifts << shift;
cts << w;
prev = w;
}
++it;
}
}
else
{
const QString &fname = new_context[new_context.count() - 2];
// Find everywhere the function name appears in the APIs.
const WordIndexList *wil = wordIndexOf(fname);
if (wil)
for (int i = 0; i < wil->count(); ++i)
{
const WordIndex &wi = (*wil)[i];
QStringList awords = prep->apiWords(wi.first, wseps, true);
// Check the word is the function name and not part of any
// context.
if (wi.second != awords.count() - 1)
continue;
const QString &api = prep->raw_apis[wi.first];
int tail = api.indexOf('(');
if (tail < 0)
continue;
if (!enoughCommas(api, commas))
continue;
if (style == QsciScintilla::CallTipsNoContext)
{
shifts << 0;
cts << (fname + api.mid(tail));
}
else
{
shifts << tail - fname.length();
// Remove any image type.
int im_type = api.indexOf('?');
if (im_type <= 0)
cts << api;
else
cts << (api.left(im_type - 1) + api.mid(tail));
}
}
}
return cts;
}
// Return true if a string has enough commas in the argument list.
bool QsciAPIs::enoughCommas(const QString &s, int commas)
{
int end = s.indexOf(')');
if (end < 0)
return false;
QString w = s.left(end);
return (w.count(',') >= commas);
}
// Ensure the list is ready.
void QsciAPIs::prepare()
{
// Handle the trivial case.
if (worker)
return;
QsciAPIsPrepared *new_apis = new QsciAPIsPrepared;
new_apis->raw_apis = apis;
worker = new QsciAPIsWorker(this);
worker->prepared = new_apis;
worker->start();
}
// Cancel any current preparation.
void QsciAPIs::cancelPreparation()
{
deleteWorker();
}
// Check that a prepared API file exists.
bool QsciAPIs::isPrepared(const QString &filename) const
{
QString pname = prepName(filename);
if (pname.isEmpty())
return false;
QFileInfo fi(pname);
return fi.exists();
}
// Load the prepared API information.
bool QsciAPIs::loadPrepared(const QString &filename)
{
QString pname = prepName(filename);
if (pname.isEmpty())
return false;
// Read the prepared data and decompress it.
QFile pf(pname);
if (!pf.open(QIODevice::ReadOnly))
return false;
QByteArray cpdata = pf.readAll();
pf.close();
if (cpdata.count() == 0)
return false;
QByteArray pdata = qUncompress(cpdata);
// Extract the data.
QDataStream pds(pdata);
unsigned char vers;
pds >> vers;
if (vers > PreparedDataFormatVersion)
return false;
char *lex_name;
pds >> lex_name;
if (qstrcmp(lex_name, lexer()->lexer()) != 0)
{
delete[] lex_name;
return false;
}
delete[] lex_name;
prep->wdict.clear();
pds >> prep->wdict;
if (!lexer()->caseSensitive())
{
// Build up the case dictionary.
prep->cdict.clear();
QMap<QString, WordIndexList>::const_iterator it = prep->wdict.begin();
while (it != prep->wdict.end())
{
prep->cdict[it.key().toUpper()] = it.key();
++it;
}
}
prep->raw_apis.clear();
pds >> prep->raw_apis;
// Allow the raw API information to be modified.
apis = prep->raw_apis;
return true;
}
// Save the prepared API information.
bool QsciAPIs::savePrepared(const QString &filename) const
{
QString pname = prepName(filename, true);
if (pname.isEmpty())
return false;
// Write the prepared data to a memory buffer.
QByteArray pdata;
QDataStream pds(&pdata, QIODevice::WriteOnly);
// Use a serialisation format supported by Qt v3.0 and later.
pds.setVersion(QDataStream::Qt_3_0);
pds << PreparedDataFormatVersion;
pds << lexer()->lexer();
pds << prep->wdict;
pds << prep->raw_apis;
// Compress the data and write it.
QFile pf(pname);
if (!pf.open(QIODevice::WriteOnly|QIODevice::Truncate))
return false;
if (pf.write(qCompress(pdata)) < 0)
{
pf.close();
return false;
}
pf.close();
return true;
}
// Return the name of the default prepared API file.
QString QsciAPIs::defaultPreparedName() const
{
return prepName(QString());
}
// Return the name of a prepared API file.
QString QsciAPIs::prepName(const QString &filename, bool mkpath) const
{
// Handle the tivial case.
if (!filename.isEmpty())
return filename;
QString pdname;
char *qsci = getenv("QSCIDIR");
if (qsci)
pdname = qsci;
else
{
static const char *qsci_dir = ".qsci";
QDir pd = QDir::home();
if (mkpath && !pd.exists(qsci_dir) && !pd.mkdir(qsci_dir))
return QString();
pdname = pd.filePath(qsci_dir);
}
return QString("%1/%2.pap").arg(pdname).arg(lexer()->lexer());
}
// Return installed API files.
QStringList QsciAPIs::installedAPIFiles() const
{
QString qtdir = QLibraryInfo::location(QLibraryInfo::DataPath);
QDir apidir = QDir(QString("%1/qsci/api/%2").arg(qtdir).arg(lexer()->lexer()));
QStringList filenames;
QStringList filters;
filters << "*.api";
QFileInfoList flist = apidir.entryInfoList(filters, QDir::Files, QDir::IgnoreCase);
foreach (QFileInfo fi, flist)
filenames << fi.absoluteFilePath();
return filenames;
}
+143
View File
@@ -0,0 +1,143 @@
// This module implements the QsciCommand class.
//
// Copyright (c) 2015 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/qscicommand.h"
#include <qnamespace.h>
#include <qapplication.h>
#include "Qsci/qsciscintilla.h"
#include "Qsci/qsciscintillabase.h"
static int convert(int key);
// The ctor.
QsciCommand::QsciCommand(QsciScintilla *qs, QsciCommand::Command cmd, int key,
int altkey, const char *desc)
: qsCmd(qs), scicmd(cmd), qkey(key), qaltkey(altkey), descCmd(desc)
{
scikey = convert(qkey);
if (scikey)
qsCmd->SendScintilla(QsciScintillaBase::SCI_ASSIGNCMDKEY, scikey,
scicmd);
scialtkey = convert(qaltkey);
if (scialtkey)
qsCmd->SendScintilla(QsciScintillaBase::SCI_ASSIGNCMDKEY, scialtkey,
scicmd);
}
// Execute the command.
void QsciCommand::execute()
{
qsCmd->SendScintilla(scicmd);
}
// Bind a key to a command.
void QsciCommand::setKey(int key)
{
bindKey(key,qkey,scikey);
}
// Bind an alternate key to a command.
void QsciCommand::setAlternateKey(int altkey)
{
bindKey(altkey,qaltkey,scialtkey);
}
// Do the hard work of binding a key.
void QsciCommand::bindKey(int key,int &qk,int &scik)
{
int new_scikey;
// Ignore if it is invalid, allowing for the fact that we might be
// unbinding it.
if (key)
{
new_scikey = convert(key);
if (!new_scikey)
return;
}
else
new_scikey = 0;
if (scik)
qsCmd->SendScintilla(QsciScintillaBase::SCI_CLEARCMDKEY, scik);
qk = key;
scik = new_scikey;
if (scik)
qsCmd->SendScintilla(QsciScintillaBase::SCI_ASSIGNCMDKEY, scik, scicmd);
}
// See if a key is valid.
bool QsciCommand::validKey(int key)
{
return convert(key);
}
// Convert a Qt character to the Scintilla equivalent. Return zero if it is
// invalid.
static int convert(int key)
{
// Convert the modifiers.
int sci_mod = 0;
if (key & Qt::SHIFT)
sci_mod |= QsciScintillaBase::SCMOD_SHIFT;
if (key & Qt::CTRL)
sci_mod |= QsciScintillaBase::SCMOD_CTRL;
if (key & Qt::ALT)
sci_mod |= QsciScintillaBase::SCMOD_ALT;
if (key & Qt::META)
sci_mod |= QsciScintillaBase::SCMOD_META;
key &= ~Qt::MODIFIER_MASK;
// Convert the key.
int sci_key = QsciScintillaBase::commandKey(key, sci_mod);
if (sci_key)
sci_key |= (sci_mod << 16);
return sci_key;
}
// Return the translated user friendly description.
QString QsciCommand::description() const
{
return qApp->translate("QsciCommand", descCmd);
}
+991
View File
@@ -0,0 +1,991 @@
// This module implements the QsciCommandSet class.
//
// Copyright (c) 2015 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/qscicommandset.h"
#include <QSettings>
#include "Qsci/qscicommand.h"
#include "Qsci/qsciscintilla.h"
#include "Qsci/qsciscintillabase.h"
// Starting with QScintilla v2.7 the standard OS/X keyboard shortcuts are used
// where possible. In order to restore the behaviour of earlier versions then
// #define DONT_USE_OSX_KEYS here or add it to the qmake project (.pro) file.
#if defined(Q_OS_MAC) && !defined(DONT_USE_OSX_KEYS)
#define USING_OSX_KEYS
#else
#undef USING_OSX_KEYS
#endif
// The ctor.
QsciCommandSet::QsciCommandSet(QsciScintilla *qs) : qsci(qs)
{
struct sci_cmd {
QsciCommand::Command cmd;
int key;
int altkey;
const char *desc;
};
static struct sci_cmd cmd_table[] = {
{
QsciCommand::LineDown,
Qt::Key_Down,
#if defined(USING_OSX_KEYS)
Qt::Key_N | Qt::META,
#else
0,
#endif
QT_TRANSLATE_NOOP("QsciCommand", "Move down one line")
},
{
QsciCommand::LineDownExtend,
Qt::Key_Down | Qt::SHIFT,
#if defined(USING_OSX_KEYS)
Qt::Key_N | Qt::META | Qt::SHIFT,
#else
0,
#endif
QT_TRANSLATE_NOOP("QsciCommand", "Extend selection down one line")
},
{
QsciCommand::LineDownRectExtend,
Qt::Key_Down | Qt::ALT | Qt::SHIFT,
#if defined(USING_OSX_KEYS)
Qt::Key_N | Qt::META | Qt::ALT | Qt::SHIFT,
#else
0,
#endif
QT_TRANSLATE_NOOP("QsciCommand",
"Extend rectangular selection down one line")
},
{
QsciCommand::LineScrollDown,
Qt::Key_Down | Qt::CTRL,
0,
QT_TRANSLATE_NOOP("QsciCommand", "Scroll view down one line")
},
{
QsciCommand::LineUp,
Qt::Key_Up,
#if defined(USING_OSX_KEYS)
Qt::Key_P | Qt::META,
#else
0,
#endif
QT_TRANSLATE_NOOP("QsciCommand", "Move up one line")
},
{
QsciCommand::LineUpExtend,
Qt::Key_Up | Qt::SHIFT,
#if defined(USING_OSX_KEYS)
Qt::Key_P | Qt::META | Qt::SHIFT,
#else
0,
#endif
QT_TRANSLATE_NOOP("QsciCommand", "Extend selection up one line")
},
{
QsciCommand::LineUpRectExtend,
Qt::Key_Up | Qt::ALT | Qt::SHIFT,
#if defined(USING_OSX_KEYS)
Qt::Key_P | Qt::META | Qt::ALT | Qt::SHIFT,
#else
0,
#endif
QT_TRANSLATE_NOOP("QsciCommand",
"Extend rectangular selection up one line")
},
{
QsciCommand::LineScrollUp,
Qt::Key_Up | Qt::CTRL,
0,
QT_TRANSLATE_NOOP("QsciCommand", "Scroll view up one line")
},
{
QsciCommand::ScrollToStart,
#if defined(USING_OSX_KEYS)
Qt::Key_Home,
#else
0,
#endif
0,
QT_TRANSLATE_NOOP("QsciCommand", "Scroll to start of document")
},
{
QsciCommand::ScrollToEnd,
#if defined(USING_OSX_KEYS)
Qt::Key_End,
#else
0,
#endif
0,
QT_TRANSLATE_NOOP("QsciCommand", "Scroll to end of document")
},
{
QsciCommand::VerticalCentreCaret,
#if defined(USING_OSX_KEYS)
Qt::Key_L | Qt::META,
#else
0,
#endif
0,
QT_TRANSLATE_NOOP("QsciCommand",
"Scroll vertically to centre current line")
},
{
QsciCommand::ParaDown,
Qt::Key_BracketRight | Qt::CTRL,
0,
QT_TRANSLATE_NOOP("QsciCommand", "Move down one paragraph")
},
{
QsciCommand::ParaDownExtend,
Qt::Key_BracketRight | Qt::CTRL | Qt::SHIFT,
0,
QT_TRANSLATE_NOOP("QsciCommand",
"Extend selection down one paragraph")
},
{
QsciCommand::ParaUp,
Qt::Key_BracketLeft | Qt::CTRL,
0,
QT_TRANSLATE_NOOP("QsciCommand", "Move up one paragraph")
},
{
QsciCommand::ParaUpExtend,
Qt::Key_BracketLeft | Qt::CTRL | Qt::SHIFT,
0,
QT_TRANSLATE_NOOP("QsciCommand",
"Extend selection up one paragraph")
},
{
QsciCommand::CharLeft,
Qt::Key_Left,
#if defined(USING_OSX_KEYS)
Qt::Key_B | Qt::META,
#else
0,
#endif
QT_TRANSLATE_NOOP("QsciCommand", "Move left one character")
},
{
QsciCommand::CharLeftExtend,
Qt::Key_Left | Qt::SHIFT,
#if defined(USING_OSX_KEYS)
Qt::Key_B | Qt::META | Qt::SHIFT,
#else
0,
#endif
QT_TRANSLATE_NOOP("QsciCommand",
"Extend selection left one character")
},
{
QsciCommand::CharLeftRectExtend,
Qt::Key_Left | Qt::ALT | Qt::SHIFT,
#if defined(USING_OSX_KEYS)
Qt::Key_B | Qt::META | Qt::ALT | Qt::SHIFT,
#else
0,
#endif
QT_TRANSLATE_NOOP("QsciCommand",
"Extend rectangular selection left one character")
},
{
QsciCommand::CharRight,
Qt::Key_Right,
#if defined(USING_OSX_KEYS)
Qt::Key_F | Qt::META,
#else
0,
#endif
QT_TRANSLATE_NOOP("QsciCommand", "Move right one character")
},
{
QsciCommand::CharRightExtend,
Qt::Key_Right | Qt::SHIFT,
#if defined(USING_OSX_KEYS)
Qt::Key_F | Qt::META | Qt::SHIFT,
#else
0,
#endif
QT_TRANSLATE_NOOP("QsciCommand",
"Extend selection right one character")
},
{
QsciCommand::CharRightRectExtend,
Qt::Key_Right | Qt::ALT | Qt::SHIFT,
#if defined(USING_OSX_KEYS)
Qt::Key_F | Qt::META | Qt::ALT | Qt::SHIFT,
#else
0,
#endif
QT_TRANSLATE_NOOP("QsciCommand",
"Extend rectangular selection right one character")
},
{
QsciCommand::WordLeft,
#if defined(USING_OSX_KEYS)
Qt::Key_Left | Qt::ALT,
#else
Qt::Key_Left | Qt::CTRL,
#endif
0,
QT_TRANSLATE_NOOP("QsciCommand", "Move left one word")
},
{
QsciCommand::WordLeftExtend,
#if defined(USING_OSX_KEYS)
Qt::Key_Left | Qt::ALT | Qt::SHIFT,
#else
Qt::Key_Left | Qt::CTRL | Qt::SHIFT,
#endif
0,
QT_TRANSLATE_NOOP("QsciCommand", "Extend selection left one word")
},
{
QsciCommand::WordRight,
#if defined(USING_OSX_KEYS)
0,
#else
Qt::Key_Right | Qt::CTRL,
#endif
0,
QT_TRANSLATE_NOOP("QsciCommand", "Move right one word")
},
{
QsciCommand::WordRightExtend,
Qt::Key_Right | Qt::CTRL | Qt::SHIFT,
0,
QT_TRANSLATE_NOOP("QsciCommand", "Extend selection right one word")
},
{
QsciCommand::WordLeftEnd,
0,
0,
QT_TRANSLATE_NOOP("QsciCommand", "Move to end of previous word")
},
{
QsciCommand::WordLeftEndExtend,
0,
0,
QT_TRANSLATE_NOOP("QsciCommand",
"Extend selection to end of previous word")
},
{
QsciCommand::WordRightEnd,
#if defined(USING_OSX_KEYS)
Qt::Key_Right | Qt::ALT,
#else
0,
#endif
0,
QT_TRANSLATE_NOOP("QsciCommand", "Move to end of next word")
},
{
QsciCommand::WordRightEndExtend,
#if defined(USING_OSX_KEYS)
Qt::Key_Right | Qt::ALT | Qt::SHIFT,
#else
0,
#endif
0,
QT_TRANSLATE_NOOP("QsciCommand",
"Extend selection to end of next word")
},
{
QsciCommand::WordPartLeft,
Qt::Key_Slash | Qt::CTRL,
0,
QT_TRANSLATE_NOOP("QsciCommand", "Move left one word part")
},
{
QsciCommand::WordPartLeftExtend,
Qt::Key_Slash | Qt::CTRL | Qt::SHIFT,
0,
QT_TRANSLATE_NOOP("QsciCommand",
"Extend selection left one word part")
},
{
QsciCommand::WordPartRight,
Qt::Key_Backslash | Qt::CTRL,
0,
QT_TRANSLATE_NOOP("QsciCommand", "Move right one word part")
},
{
QsciCommand::WordPartRightExtend,
Qt::Key_Backslash | Qt::CTRL | Qt::SHIFT,
0,
QT_TRANSLATE_NOOP("QsciCommand",
"Extend selection right one word part")
},
{
QsciCommand::Home,
#if defined(USING_OSX_KEYS)
Qt::Key_A | Qt::META,
#else
0,
#endif
0,
QT_TRANSLATE_NOOP("QsciCommand", "Move to start of document line")
},
{
QsciCommand::HomeExtend,
#if defined(USING_OSX_KEYS)
Qt::Key_A | Qt::META | Qt::SHIFT,
#else
0,
#endif
0,
QT_TRANSLATE_NOOP("QsciCommand",
"Extend selection to start of document line")
},
{
QsciCommand::HomeRectExtend,
#if defined(USING_OSX_KEYS)
Qt::Key_A | Qt::META | Qt::ALT | Qt::SHIFT,
#else
0,
#endif
0,
QT_TRANSLATE_NOOP("QsciCommand",
"Extend rectangular selection to start of document line")
},
{
QsciCommand::HomeDisplay,
#if defined(USING_OSX_KEYS)
Qt::Key_Left | Qt::CTRL,
#else
Qt::Key_Home | Qt::ALT,
#endif
0,
QT_TRANSLATE_NOOP("QsciCommand", "Move to start of display line")
},
{
QsciCommand::HomeDisplayExtend,
#if defined(USING_OSX_KEYS)
Qt::Key_Left | Qt::CTRL | Qt::SHIFT,
#else
0,
#endif
0,
QT_TRANSLATE_NOOP("QsciCommand",
"Extend selection to start of display line")
},
{
QsciCommand::HomeWrap,
0,
0,
QT_TRANSLATE_NOOP("QsciCommand",
"Move to start of display or document line")
},
{
QsciCommand::HomeWrapExtend,
0,
0,
QT_TRANSLATE_NOOP("QsciCommand",
"Extend selection to start of display or document line")
},
{
QsciCommand::VCHome,
#if defined(USING_OSX_KEYS)
0,
#else
Qt::Key_Home,
#endif
0,
QT_TRANSLATE_NOOP("QsciCommand",
"Move to first visible character in document line")
},
{
QsciCommand::VCHomeExtend,
#if defined(USING_OSX_KEYS)
0,
#else
Qt::Key_Home | Qt::SHIFT,
#endif
0,
QT_TRANSLATE_NOOP("QsciCommand",
"Extend selection to first visible character in document line")
},
{
QsciCommand::VCHomeRectExtend,
#if defined(USING_OSX_KEYS)
0,
#else
Qt::Key_Home | Qt::ALT | Qt::SHIFT,
#endif
0,
QT_TRANSLATE_NOOP("QsciCommand",
"Extend rectangular selection to first visible character in document line")
},
{
QsciCommand::VCHomeWrap,
0,
0,
QT_TRANSLATE_NOOP("QsciCommand",
"Move to first visible character of display in document line")
},
{
QsciCommand::VCHomeWrapExtend,
0,
0,
QT_TRANSLATE_NOOP("QsciCommand",
"Extend selection to first visible character in display or document line")
},
{
QsciCommand::LineEnd,
#if defined(USING_OSX_KEYS)
Qt::Key_E | Qt::META,
#else
Qt::Key_End,
#endif
0,
QT_TRANSLATE_NOOP("QsciCommand", "Move to end of document line")
},
{
QsciCommand::LineEndExtend,
#if defined(USING_OSX_KEYS)
Qt::Key_E | Qt::META | Qt::SHIFT,
#else
Qt::Key_End | Qt::SHIFT,
#endif
0,
QT_TRANSLATE_NOOP("QsciCommand",
"Extend selection to end of document line")
},
{
QsciCommand::LineEndRectExtend,
#if defined(USING_OSX_KEYS)
Qt::Key_E | Qt::META | Qt::ALT | Qt::SHIFT,
#else
Qt::Key_End | Qt::ALT | Qt::SHIFT,
#endif
0,
QT_TRANSLATE_NOOP("QsciCommand",
"Extend rectangular selection to end of document line")
},
{
QsciCommand::LineEndDisplay,
#if defined(USING_OSX_KEYS)
Qt::Key_Right | Qt::CTRL,
#else
Qt::Key_End | Qt::ALT,
#endif
0,
QT_TRANSLATE_NOOP("QsciCommand", "Move to end of display line")
},
{
QsciCommand::LineEndDisplayExtend,
#if defined(USING_OSX_KEYS)
Qt::Key_Right | Qt::CTRL | Qt::SHIFT,
#else
0,
#endif
0,
QT_TRANSLATE_NOOP("QsciCommand",
"Extend selection to end of display line")
},
{
QsciCommand::LineEndWrap,
0,
0,
QT_TRANSLATE_NOOP("QsciCommand",
"Move to end of display or document line")
},
{
QsciCommand::LineEndWrapExtend,
0,
0,
QT_TRANSLATE_NOOP("QsciCommand",
"Extend selection to end of display or document line")
},
{
QsciCommand::DocumentStart,
#if defined(USING_OSX_KEYS)
Qt::Key_Up | Qt::CTRL,
#else
Qt::Key_Home | Qt::CTRL,
#endif
0,
QT_TRANSLATE_NOOP("QsciCommand", "Move to start of document")
},
{
QsciCommand::DocumentStartExtend,
#if defined(USING_OSX_KEYS)
Qt::Key_Up | Qt::CTRL | Qt::SHIFT,
#else
Qt::Key_Home | Qt::CTRL | Qt::SHIFT,
#endif
0,
QT_TRANSLATE_NOOP("QsciCommand",
"Extend selection to start of document")
},
{
QsciCommand::DocumentEnd,
#if defined(USING_OSX_KEYS)
Qt::Key_Down | Qt::CTRL,
#else
Qt::Key_End | Qt::CTRL,
#endif
0,
QT_TRANSLATE_NOOP("QsciCommand", "Move to end of document")
},
{
QsciCommand::DocumentEndExtend,
#if defined(USING_OSX_KEYS)
Qt::Key_Down | Qt::CTRL | Qt::SHIFT,
#else
Qt::Key_End | Qt::CTRL | Qt::SHIFT,
#endif
0,
QT_TRANSLATE_NOOP("QsciCommand",
"Extend selection to end of document")
},
{
QsciCommand::PageUp,
Qt::Key_PageUp,
0,
QT_TRANSLATE_NOOP("QsciCommand", "Move up one page")
},
{
QsciCommand::PageUpExtend,
Qt::Key_PageUp | Qt::SHIFT,
0,
QT_TRANSLATE_NOOP("QsciCommand", "Extend selection up one page")
},
{
QsciCommand::PageUpRectExtend,
Qt::Key_PageUp | Qt::ALT | Qt::SHIFT,
0,
QT_TRANSLATE_NOOP("QsciCommand",
"Extend rectangular selection up one page")
},
{
QsciCommand::PageDown,
Qt::Key_PageDown,
#if defined(USING_OSX_KEYS)
Qt::Key_V | Qt::META,
#else
0,
#endif
QT_TRANSLATE_NOOP("QsciCommand", "Move down one page")
},
{
QsciCommand::PageDownExtend,
Qt::Key_PageDown | Qt::SHIFT,
#if defined(USING_OSX_KEYS)
Qt::Key_V | Qt::META | Qt::SHIFT,
#else
0,
#endif
QT_TRANSLATE_NOOP("QsciCommand", "Extend selection down one page")
},
{
QsciCommand::PageDownRectExtend,
Qt::Key_PageDown | Qt::ALT | Qt::SHIFT,
#if defined(USING_OSX_KEYS)
Qt::Key_V | Qt::META | Qt::ALT | Qt::SHIFT,
#else
0,
#endif
QT_TRANSLATE_NOOP("QsciCommand",
"Extend rectangular selection down one page")
},
{
QsciCommand::StutteredPageUp,
0,
0,
QT_TRANSLATE_NOOP("QsciCommand", "Stuttered move up one page")
},
{
QsciCommand::StutteredPageUpExtend,
0,
0,
QT_TRANSLATE_NOOP("QsciCommand",
"Stuttered extend selection up one page")
},
{
QsciCommand::StutteredPageDown,
0,
0,
QT_TRANSLATE_NOOP("QsciCommand", "Stuttered move down one page")
},
{
QsciCommand::StutteredPageDownExtend,
0,
0,
QT_TRANSLATE_NOOP("QsciCommand",
"Stuttered extend selection down one page")
},
{
QsciCommand::Delete,
Qt::Key_Delete,
#if defined(USING_OSX_KEYS)
Qt::Key_D | Qt::META,
#else
0,
#endif
QT_TRANSLATE_NOOP("QsciCommand", "Delete current character")
},
{
QsciCommand::DeleteBack,
Qt::Key_Backspace,
#if defined(USING_OSX_KEYS)
Qt::Key_H | Qt::META,
#else
Qt::Key_Backspace | Qt::SHIFT,
#endif
QT_TRANSLATE_NOOP("QsciCommand", "Delete previous character")
},
{
QsciCommand::DeleteBackNotLine,
0,
0,
QT_TRANSLATE_NOOP("QsciCommand",
"Delete previous character if not at start of line")
},
{
QsciCommand::DeleteWordLeft,
Qt::Key_Backspace | Qt::CTRL,
0,
QT_TRANSLATE_NOOP("QsciCommand", "Delete word to left")
},
{
QsciCommand::DeleteWordRight,
Qt::Key_Delete | Qt::CTRL,
0,
QT_TRANSLATE_NOOP("QsciCommand", "Delete word to right")
},
{
QsciCommand::DeleteWordRightEnd,
#if defined(USING_OSX_KEYS)
Qt::Key_Delete | Qt::ALT,
#else
0,
#endif
0,
QT_TRANSLATE_NOOP("QsciCommand",
"Delete right to end of next word")
},
{
QsciCommand::DeleteLineLeft,
Qt::Key_Backspace | Qt::CTRL | Qt::SHIFT,
0,
QT_TRANSLATE_NOOP("QsciCommand", "Delete line to left")
},
{
QsciCommand::DeleteLineRight,
#if defined(USING_OSX_KEYS)
Qt::Key_K | Qt::META,
#else
Qt::Key_Delete | Qt::CTRL | Qt::SHIFT,
#endif
0,
QT_TRANSLATE_NOOP("QsciCommand", "Delete line to right")
},
{
QsciCommand::LineDelete,
Qt::Key_L | Qt::CTRL | Qt::SHIFT,
0,
QT_TRANSLATE_NOOP("QsciCommand", "Delete current line")
},
{
QsciCommand::LineCut,
Qt::Key_L | Qt::CTRL,
0,
QT_TRANSLATE_NOOP("QsciCommand", "Cut current line")
},
{
QsciCommand::LineCopy,
Qt::Key_T | Qt::CTRL | Qt::SHIFT,
0,
QT_TRANSLATE_NOOP("QsciCommand", "Copy current line")
},
{
QsciCommand::LineTranspose,
Qt::Key_T | Qt::CTRL,
0,
QT_TRANSLATE_NOOP("QsciCommand",
"Transpose current and previous lines")
},
{
QsciCommand::LineDuplicate,
0,
0,
QT_TRANSLATE_NOOP("QsciCommand", "Duplicate the current line")
},
{
QsciCommand::SelectAll,
Qt::Key_A | Qt::CTRL,
0,
QT_TRANSLATE_NOOP("QsciCommand", "Select all")
},
{
QsciCommand::MoveSelectedLinesUp,
0,
0,
QT_TRANSLATE_NOOP("QsciCommand", "Move selected lines up one line")
},
{
QsciCommand::MoveSelectedLinesDown,
0,
0,
QT_TRANSLATE_NOOP("QsciCommand",
"Move selected lines down one line")
},
{
QsciCommand::SelectionDuplicate,
Qt::Key_D | Qt::CTRL,
0,
QT_TRANSLATE_NOOP("QsciCommand", "Duplicate selection")
},
{
QsciCommand::SelectionLowerCase,
Qt::Key_U | Qt::CTRL,
0,
QT_TRANSLATE_NOOP("QsciCommand", "Convert selection to lower case")
},
{
QsciCommand::SelectionUpperCase,
Qt::Key_U | Qt::CTRL | Qt::SHIFT,
0,
QT_TRANSLATE_NOOP("QsciCommand", "Convert selection to upper case")
},
{
QsciCommand::SelectionCut,
Qt::Key_X | Qt::CTRL,
Qt::Key_Delete | Qt::SHIFT,
QT_TRANSLATE_NOOP("QsciCommand", "Cut selection")
},
{
QsciCommand::SelectionCopy,
Qt::Key_C | Qt::CTRL,
Qt::Key_Insert | Qt::CTRL,
QT_TRANSLATE_NOOP("QsciCommand", "Copy selection")
},
{
QsciCommand::Paste,
Qt::Key_V | Qt::CTRL,
Qt::Key_Insert | Qt::SHIFT,
QT_TRANSLATE_NOOP("QsciCommand", "Paste")
},
{
QsciCommand::EditToggleOvertype,
Qt::Key_Insert,
0,
QT_TRANSLATE_NOOP("QsciCommand", "Toggle insert/overtype")
},
{
QsciCommand::Newline,
Qt::Key_Return,
Qt::Key_Return | Qt::SHIFT,
QT_TRANSLATE_NOOP("QsciCommand", "Insert newline")
},
{
QsciCommand::Formfeed,
0,
0,
QT_TRANSLATE_NOOP("QsciCommand", "Formfeed")
},
{
QsciCommand::Tab,
Qt::Key_Tab,
0,
QT_TRANSLATE_NOOP("QsciCommand", "Indent one level")
},
{
QsciCommand::Backtab,
Qt::Key_Tab | Qt::SHIFT,
0,
QT_TRANSLATE_NOOP("QsciCommand", "De-indent one level")
},
{
QsciCommand::Cancel,
Qt::Key_Escape,
0,
QT_TRANSLATE_NOOP("QsciCommand", "Cancel")
},
{
QsciCommand::Undo,
Qt::Key_Z | Qt::CTRL,
Qt::Key_Backspace | Qt::ALT,
QT_TRANSLATE_NOOP("QsciCommand", "Undo last command")
},
{
QsciCommand::Redo,
#if defined(USING_OSX_KEYS)
Qt::Key_Z | Qt::CTRL | Qt::SHIFT,
#else
Qt::Key_Y | Qt::CTRL,
#endif
0,
QT_TRANSLATE_NOOP("QsciCommand", "Redo last command")
},
{
QsciCommand::ZoomIn,
Qt::Key_Plus | Qt::CTRL,
0,
QT_TRANSLATE_NOOP("QsciCommand", "Zoom in")
},
{
QsciCommand::ZoomOut,
Qt::Key_Minus | Qt::CTRL,
0,
QT_TRANSLATE_NOOP("QsciCommand", "Zoom out")
},
};
// Clear the default map.
qsci->SendScintilla(QsciScintillaBase::SCI_CLEARALLCMDKEYS);
// By default control characters don't do anything (rather than insert the
// control character into the text).
for (int k = 'A'; k <= 'Z'; ++k)
qsci->SendScintilla(QsciScintillaBase::SCI_ASSIGNCMDKEY,
k + (QsciScintillaBase::SCMOD_CTRL << 16),
QsciScintillaBase::SCI_NULL);
for (int i = 0; i < sizeof (cmd_table) / sizeof (cmd_table[0]); ++i)
cmds.append(
new QsciCommand(qsci, cmd_table[i].cmd, cmd_table[i].key,
cmd_table[i].altkey, cmd_table[i].desc));
}
// The dtor.
QsciCommandSet::~QsciCommandSet()
{
for (int i = 0; i < cmds.count(); ++i)
delete cmds.at(i);
}
// Read the command set from settings.
bool QsciCommandSet::readSettings(QSettings &qs, const char *prefix)
{
bool rc = true;
QString skey;
for (int i = 0; i < cmds.count(); ++i)
{
QsciCommand *cmd = cmds.at(i);
skey.sprintf("%s/keymap/c%d/", prefix,
static_cast<int>(cmd->command()));
int key;
bool ok;
// Read the key.
ok = qs.contains(skey + "key");
key = qs.value(skey + "key", 0).toInt();
if (ok)
cmd->setKey(key);
else
rc = false;
// Read the alternate key.
ok = qs.contains(skey + "alt");
key = qs.value(skey + "alt", 0).toInt();
if (ok)
cmd->setAlternateKey(key);
else
rc = false;
}
return rc;
}
// Write the command set to settings.
bool QsciCommandSet::writeSettings(QSettings &qs, const char *prefix)
{
bool rc = true;
QString skey;
for (int i = 0; i < cmds.count(); ++i)
{
QsciCommand *cmd = cmds.at(i);
skey.sprintf("%s/keymap/c%d/", prefix,
static_cast<int>(cmd->command()));
// Write the key.
qs.setValue(skey + "key", cmd->key());
// Write the alternate key.
qs.setValue(skey + "alt", cmd->key());
}
return rc;
}
// Clear the key bindings.
void QsciCommandSet::clearKeys()
{
for (int i = 0; i < cmds.count(); ++i)
cmds.at(i)->setKey(0);
}
// Clear the alternate key bindings.
void QsciCommandSet::clearAlternateKeys()
{
for (int i = 0; i < cmds.count(); ++i)
cmds.at(i)->setAlternateKey(0);
}
// Find the command bound to a key.
QsciCommand *QsciCommandSet::boundTo(int key) const
{
for (int i = 0; i < cmds.count(); ++i)
{
QsciCommand *cmd = cmds.at(i);
if (cmd->key() == key || cmd->alternateKey() == key)
return cmd;
}
return 0;
}
// Find a command.
QsciCommand *QsciCommandSet::find(QsciCommand::Command command) const
{
for (int i = 0; i < cmds.count(); ++i)
{
QsciCommand *cmd = cmds.at(i);
if (cmd->command() == command)
return cmd;
}
// This should never happen.
return 0;
}
+151
View File
@@ -0,0 +1,151 @@
// This module implements the QsciDocument class.
//
// Copyright (c) 2015 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/qscidocument.h"
#include "Qsci/qsciscintillabase.h"
// This internal class encapsulates the underlying document and is shared by
// QsciDocument instances.
class QsciDocumentP
{
public:
QsciDocumentP() : doc(0), nr_displays(0), nr_attaches(1), modified(false) {}
void *doc; // The Scintilla document.
int nr_displays; // The number of displays.
int nr_attaches; // The number of attaches.
bool modified; // Set if not at a save point.
};
// The ctor.
QsciDocument::QsciDocument()
{
pdoc = new QsciDocumentP();
}
// The dtor.
QsciDocument::~QsciDocument()
{
detach();
}
// The copy ctor.
QsciDocument::QsciDocument(const QsciDocument &that)
{
attach(that);
}
// The assignment operator.
QsciDocument &QsciDocument::operator=(const QsciDocument &that)
{
if (pdoc != that.pdoc)
{
detach();
attach(that);
}
return *this;
}
// Attach an existing document to this one.
void QsciDocument::attach(const QsciDocument &that)
{
++that.pdoc->nr_attaches;
pdoc = that.pdoc;
}
// Detach the underlying document.
void QsciDocument::detach()
{
if (!pdoc)
return;
if (--pdoc->nr_attaches == 0)
{
if (pdoc->doc && pdoc->nr_displays == 0)
{
QsciScintillaBase *qsb = QsciScintillaBase::pool();
// Release the explicit reference to the document. If the pool is
// empty then we just accept the memory leak.
if (qsb)
qsb->SendScintilla(QsciScintillaBase::SCI_RELEASEDOCUMENT, 0,
pdoc->doc);
}
delete pdoc;
}
pdoc = 0;
}
// Undisplay and detach the underlying document.
void QsciDocument::undisplay(QsciScintillaBase *qsb)
{
if (--pdoc->nr_attaches == 0)
delete pdoc;
else if (--pdoc->nr_displays == 0)
{
// Create an explicit reference to the document to keep it alive.
qsb->SendScintilla(QsciScintillaBase::SCI_ADDREFDOCUMENT, 0, pdoc->doc);
}
pdoc = 0;
}
// Display the underlying document.
void QsciDocument::display(QsciScintillaBase *qsb, const QsciDocument *from)
{
void *ndoc = (from ? from->pdoc->doc : 0);
// SCI_SETDOCPOINTER appears to reset the EOL mode so save and restore it.
int eol_mode = qsb->SendScintilla(QsciScintillaBase::SCI_GETEOLMODE);
qsb->SendScintilla(QsciScintillaBase::SCI_SETDOCPOINTER, 0, ndoc);
ndoc = qsb->SendScintillaPtrResult(QsciScintillaBase::SCI_GETDOCPOINTER);
qsb->SendScintilla(QsciScintillaBase::SCI_SETEOLMODE, eol_mode);
pdoc->doc = ndoc;
++pdoc->nr_displays;
}
// Return the modified state of the document.
bool QsciDocument::isModified() const
{
return pdoc->modified;
}
// Set the modified state of the document.
void QsciDocument::setModified(bool m)
{
pdoc->modified = m;
}
+740
View File
@@ -0,0 +1,740 @@
// This module implements the QsciLexer class.
//
// Copyright (c) 2015 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/qscilexer.h"
#include <qapplication.h>
#include <qcolor.h>
#include <qfont.h>
#include <qsettings.h>
#include "Qsci/qsciapis.h"
#include "Qsci/qsciscintilla.h"
#include "Qsci/qsciscintillabase.h"
// The ctor.
QsciLexer::QsciLexer(QObject *parent)
: QObject(parent),
autoIndStyle(-1), apiSet(0), attached_editor(0)
{
#if defined(Q_OS_WIN)
defFont = QFont("Verdana",10);
#elif defined(Q_OS_MAC)
defFont = QFont("Verdana", 12);
#else
defFont = QFont("Bitstream Vera Sans",9);
#endif
// Set the default fore and background colours.
QPalette pal = QApplication::palette();
defColor = pal.text().color();
defPaper = pal.base().color();
// Putting this on the heap means we can keep the style getters const.
style_map = new StyleDataMap;
style_map->style_data_set = false;
}
// The dtor.
QsciLexer::~QsciLexer()
{
delete style_map;
}
// Set the attached editor.
void QsciLexer::setEditor(QsciScintilla *editor)
{
attached_editor = editor;
if (attached_editor)
{
attached_editor->SendScintilla(QsciScintillaBase::SCI_SETSTYLEBITS,
styleBitsNeeded());
}
}
// Return the lexer name.
const char *QsciLexer::lexer() const
{
return 0;
}
// Return the lexer identifier.
int QsciLexer::lexerId() const
{
return QsciScintillaBase::SCLEX_CONTAINER;
}
// Return the number of style bits needed by the lexer.
int QsciLexer::styleBitsNeeded() const
{
if (!attached_editor)
return 5;
return attached_editor->SendScintilla(QsciScintillaBase::SCI_GETSTYLEBITSNEEDED);
}
// Make sure the style defaults have been set.
void QsciLexer::setStyleDefaults() const
{
if (!style_map->style_data_set)
{
for (int i = 0; i < 128; ++i)
if (!description(i).isEmpty())
styleData(i);
style_map->style_data_set = true;
}
}
// Return a reference to a style's data, setting up the defaults if needed.
QsciLexer::StyleData &QsciLexer::styleData(int style) const
{
StyleData &sd = style_map->style_data[style];
// See if this is a new style by checking if the colour is valid.
if (!sd.color.isValid())
{
sd.color = defaultColor(style);
sd.paper = defaultPaper(style);
sd.font = defaultFont(style);
sd.eol_fill = defaultEolFill(style);
}
return sd;
}
// Set the APIs associated with the lexer.
void QsciLexer::setAPIs(QsciAbstractAPIs *apis)
{
apiSet = apis;
}
// Return a pointer to the current APIs if there are any.
QsciAbstractAPIs *QsciLexer::apis() const
{
return apiSet;
}
// Default implementation to return the set of fill up characters that can end
// auto-completion.
const char *QsciLexer::autoCompletionFillups() const
{
return "(";
}
// Default implementation to return the view used for indentation guides.
int QsciLexer::indentationGuideView() const
{
return QsciScintillaBase::SC_IV_LOOKBOTH;
}
// Default implementation to return the list of character sequences that can
// separate auto-completion words.
QStringList QsciLexer::autoCompletionWordSeparators() const
{
return QStringList();
}
// Default implementation to return the list of keywords that can start a
// block.
const char *QsciLexer::blockStartKeyword(int *) const
{
return 0;
}
// Default implementation to return the list of characters that can start a
// block.
const char *QsciLexer::blockStart(int *) const
{
return 0;
}
// Default implementation to return the list of characters that can end a
// block.
const char *QsciLexer::blockEnd(int *) const
{
return 0;
}
// Default implementation to return the style used for braces.
int QsciLexer::braceStyle() const
{
return -1;
}
// Default implementation to return the number of lines to look back when
// auto-indenting.
int QsciLexer::blockLookback() const
{
return 20;
}
// Default implementation to return the case sensitivity of the language.
bool QsciLexer::caseSensitive() const
{
return true;
}
// Default implementation to return the characters that make up a word.
const char *QsciLexer::wordCharacters() const
{
return 0;
}
// Default implementation to return the style used for whitespace.
int QsciLexer::defaultStyle() const
{
return 0;
}
// Returns the foreground colour of the text for a style.
QColor QsciLexer::color(int style) const
{
return styleData(style).color;
}
// Returns the background colour of the text for a style.
QColor QsciLexer::paper(int style) const
{
return styleData(style).paper;
}
// Returns the font for a style.
QFont QsciLexer::font(int style) const
{
return styleData(style).font;
}
// Returns the end-of-line fill for a style.
bool QsciLexer::eolFill(int style) const
{
return styleData(style).eol_fill;
}
// Returns the set of keywords.
const char *QsciLexer::keywords(int) const
{
return 0;
}
// Returns the default EOL fill for a style.
bool QsciLexer::defaultEolFill(int) const
{
return false;
}
// Returns the default font for a style.
QFont QsciLexer::defaultFont(int) const
{
return defaultFont();
}
// Returns the default font.
QFont QsciLexer::defaultFont() const
{
return defFont;
}
// Sets the default font.
void QsciLexer::setDefaultFont(const QFont &f)
{
defFont = f;
}
// Returns the default text colour for a style.
QColor QsciLexer::defaultColor(int) const
{
return defaultColor();
}
// Returns the default text colour.
QColor QsciLexer::defaultColor() const
{
return defColor;
}
// Sets the default text colour.
void QsciLexer::setDefaultColor(const QColor &c)
{
defColor = c;
}
// Returns the default paper colour for a styles.
QColor QsciLexer::defaultPaper(int) const
{
return defaultPaper();
}
// Returns the default paper colour.
QColor QsciLexer::defaultPaper() const
{
return defPaper;
}
// Sets the default paper colour.
void QsciLexer::setDefaultPaper(const QColor &c)
{
defPaper = c;
// Normally the default values are only intended to provide defaults when a
// lexer is first setup because once a style has been referenced then a
// copy of the default is made. However the default paper is a special
// case because there is no other way to set the background colour used
// where there is no text. Therefore we also actively set it.
setPaper(c, QsciScintillaBase::STYLE_DEFAULT);
}
// Read properties from the settings.
bool QsciLexer::readProperties(QSettings &,const QString &)
{
return true;
}
// Refresh all properties.
void QsciLexer::refreshProperties()
{
}
// Write properties to the settings.
bool QsciLexer::writeProperties(QSettings &,const QString &) const
{
return true;
}
// Restore the user settings.
bool QsciLexer::readSettings(QSettings &qs,const char *prefix)
{
bool ok, flag, rc = true;
int num;
QString key, full_key;
QStringList fdesc;
setStyleDefaults();
// Read the styles.
for (int i = 0; i < 128; ++i)
{
// Ignore invalid styles.
if (description(i).isEmpty())
continue;
key.sprintf("%s/%s/style%d/",prefix,language(),i);
// Read the foreground colour.
full_key = key + "color";
ok = qs.contains(full_key);
num = qs.value(full_key).toInt();
if (ok)
setColor(QColor((num >> 16) & 0xff, (num >> 8) & 0xff, num & 0xff), i);
else
rc = false;
// Read the end-of-line fill.
full_key = key + "eolfill";
ok = qs.contains(full_key);
flag = qs.value(full_key, false).toBool();
if (ok)
setEolFill(flag, i);
else
rc = false;
// Read the font. First try the deprecated format that uses an integer
// point size.
full_key = key + "font";
ok = qs.contains(full_key);
fdesc = qs.value(full_key).toStringList();
if (ok && fdesc.count() == 5)
{
QFont f;
f.setFamily(fdesc[0]);
f.setPointSize(fdesc[1].toInt());
f.setBold(fdesc[2].toInt());
f.setItalic(fdesc[3].toInt());
f.setUnderline(fdesc[4].toInt());
setFont(f, i);
}
else
rc = false;
// Now try the newer font format that uses a floating point point size.
// It is not an error if it doesn't exist.
full_key = key + "font2";
ok = qs.contains(full_key);
fdesc = qs.value(full_key).toStringList();
if (ok)
{
// Allow for future versions with more fields.
if (fdesc.count() >= 5)
{
QFont f;
f.setFamily(fdesc[0]);
f.setPointSizeF(fdesc[1].toDouble());
f.setBold(fdesc[2].toInt());
f.setItalic(fdesc[3].toInt());
f.setUnderline(fdesc[4].toInt());
setFont(f, i);
}
else
{
rc = false;
}
}
// Read the background colour.
full_key = key + "paper";
ok = qs.contains(full_key);
num = qs.value(full_key).toInt();
if (ok)
setPaper(QColor((num >> 16) & 0xff, (num >> 8) & 0xff, num & 0xff), i);
else
rc = false;
}
// Read the properties.
key.sprintf("%s/%s/properties/",prefix,language());
if (!readProperties(qs,key))
rc = false;
refreshProperties();
// Read the rest.
key.sprintf("%s/%s/",prefix,language());
// Read the default foreground colour.
full_key = key + "defaultcolor";
ok = qs.contains(full_key);
num = qs.value(full_key).toInt();
if (ok)
setDefaultColor(QColor((num >> 16) & 0xff, (num >> 8) & 0xff, num & 0xff));
else
rc = false;
// Read the default background colour.
full_key = key + "defaultpaper";
ok = qs.contains(full_key);
num = qs.value(full_key).toInt();
if (ok)
setDefaultPaper(QColor((num >> 16) & 0xff, (num >> 8) & 0xff, num & 0xff));
else
rc = false;
// Read the default font. First try the deprecated format that uses an
// integer point size.
full_key = key + "defaultfont";
ok = qs.contains(full_key);
fdesc = qs.value(full_key).toStringList();
if (ok && fdesc.count() == 5)
{
QFont f;
f.setFamily(fdesc[0]);
f.setPointSize(fdesc[1].toInt());
f.setBold(fdesc[2].toInt());
f.setItalic(fdesc[3].toInt());
f.setUnderline(fdesc[4].toInt());
setDefaultFont(f);
}
else
rc = false;
// Now try the newer font format that uses a floating point point size. It
// is not an error if it doesn't exist.
full_key = key + "defaultfont2";
ok = qs.contains(full_key);
fdesc = qs.value(full_key).toStringList();
if (ok)
{
// Allow for future versions with more fields.
if (fdesc.count() >= 5)
{
QFont f;
f.setFamily(fdesc[0]);
f.setPointSizeF(fdesc[1].toDouble());
f.setBold(fdesc[2].toInt());
f.setItalic(fdesc[3].toInt());
f.setUnderline(fdesc[4].toInt());
setDefaultFont(f);
}
else
{
rc = false;
}
}
full_key = key + "autoindentstyle";
ok = qs.contains(full_key);
num = qs.value(full_key).toInt();
if (ok)
setAutoIndentStyle(num);
else
rc = false;
return rc;
}
// Save the user settings.
bool QsciLexer::writeSettings(QSettings &qs,const char *prefix) const
{
bool rc = true;
QString key, fmt("%1");
int num;
QStringList fdesc;
setStyleDefaults();
// Write the styles.
for (int i = 0; i < 128; ++i)
{
// Ignore invalid styles.
if (description(i).isEmpty())
continue;
QColor c;
key.sprintf("%s/%s/style%d/",prefix,language(),i);
// Write the foreground colour.
c = color(i);
num = (c.red() << 16) | (c.green() << 8) | c.blue();
qs.setValue(key + "color", num);
// Write the end-of-line fill.
qs.setValue(key + "eolfill", eolFill(i));
// Write the font using the deprecated format.
QFont f = font(i);
fdesc.clear();
fdesc += f.family();
fdesc += fmt.arg(f.pointSize());
// The casts are for Borland.
fdesc += fmt.arg((int)f.bold());
fdesc += fmt.arg((int)f.italic());
fdesc += fmt.arg((int)f.underline());
qs.setValue(key + "font", fdesc);
// Write the font using the newer format.
fdesc[1] = fmt.arg(f.pointSizeF());
qs.setValue(key + "font2", fdesc);
// Write the background colour.
c = paper(i);
num = (c.red() << 16) | (c.green() << 8) | c.blue();
qs.setValue(key + "paper", num);
}
// Write the properties.
key.sprintf("%s/%s/properties/",prefix,language());
if (!writeProperties(qs,key))
rc = false;
// Write the rest.
key.sprintf("%s/%s/",prefix,language());
// Write the default foreground colour.
num = (defColor.red() << 16) | (defColor.green() << 8) | defColor.blue();
qs.setValue(key + "defaultcolor", num);
// Write the default background colour.
num = (defPaper.red() << 16) | (defPaper.green() << 8) | defPaper.blue();
qs.setValue(key + "defaultpaper", num);
// Write the default font using the deprecated format.
fdesc.clear();
fdesc += defFont.family();
fdesc += fmt.arg(defFont.pointSize());
// The casts are for Borland.
fdesc += fmt.arg((int)defFont.bold());
fdesc += fmt.arg((int)defFont.italic());
fdesc += fmt.arg((int)defFont.underline());
qs.setValue(key + "defaultfont", fdesc);
// Write the font using the newer format.
fdesc[1] = fmt.arg(defFont.pointSizeF());
qs.setValue(key + "defaultfont2", fdesc);
qs.setValue(key + "autoindentstyle", autoIndStyle);
return rc;
}
// Return the auto-indentation style.
int QsciLexer::autoIndentStyle()
{
// We can't do this in the ctor because we want the virtuals to work.
if (autoIndStyle < 0)
autoIndStyle = (blockStartKeyword() || blockStart() || blockEnd()) ?
0 : QsciScintilla::AiMaintain;
return autoIndStyle;
}
// Set the auto-indentation style.
void QsciLexer::setAutoIndentStyle(int autoindentstyle)
{
autoIndStyle = autoindentstyle;
}
// Set the foreground colour for a style.
void QsciLexer::setColor(const QColor &c, int style)
{
if (style >= 0)
{
styleData(style).color = c;
emit colorChanged(c, style);
}
else
for (int i = 0; i < 128; ++i)
if (!description(i).isEmpty())
setColor(c, i);
}
// Set the end-of-line fill for a style.
void QsciLexer::setEolFill(bool eolfill, int style)
{
if (style >= 0)
{
styleData(style).eol_fill = eolfill;
emit eolFillChanged(eolfill, style);
}
else
for (int i = 0; i < 128; ++i)
if (!description(i).isEmpty())
setEolFill(eolfill, i);
}
// Set the font for a style.
void QsciLexer::setFont(const QFont &f, int style)
{
if (style >= 0)
{
styleData(style).font = f;
emit fontChanged(f, style);
}
else
for (int i = 0; i < 128; ++i)
if (!description(i).isEmpty())
setFont(f, i);
}
// Set the background colour for a style.
void QsciLexer::setPaper(const QColor &c, int style)
{
if (style >= 0)
{
styleData(style).paper = c;
emit paperChanged(c, style);
}
else
{
for (int i = 0; i < 128; ++i)
if (!description(i).isEmpty())
setPaper(c, i);
emit paperChanged(c, QsciScintillaBase::STYLE_DEFAULT);
}
}
+521
View File
@@ -0,0 +1,521 @@
// This module implements the QsciLexerSQL class.
//
// Copyright (c) 2015 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/qscilexersql.h"
#include <qcolor.h>
#include <qfont.h>
#include <qsettings.h>
// The ctor.
QsciLexerSQL::QsciLexerSQL(QObject *parent)
: QsciLexer(parent),
at_else(false), fold_comments(false), fold_compact(true),
only_begin(false), backticks_identifier(false),
numbersign_comment(false), backslash_escapes(false),
allow_dotted_word(false)
{
}
// The dtor.
QsciLexerSQL::~QsciLexerSQL()
{
}
// Returns the language name.
const char *QsciLexerSQL::language() const
{
return "SQL";
}
// Returns the lexer name.
const char *QsciLexerSQL::lexer() const
{
return "sql";
}
// Return the style used for braces.
int QsciLexerSQL::braceStyle() const
{
return Operator;
}
// Returns the foreground colour of the text for a style.
QColor QsciLexerSQL::defaultColor(int style) const
{
switch (style)
{
case Default:
return QColor(0x80,0x80,0x80);
case Comment:
case CommentLine:
case PlusPrompt:
case PlusComment:
case CommentLineHash:
return QColor(0x00,0x7f,0x00);
case CommentDoc:
return QColor(0x7f,0x7f,0x7f);
case Number:
return QColor(0x00,0x7f,0x7f);
case Keyword:
return QColor(0x00,0x00,0x7f);
case DoubleQuotedString:
case SingleQuotedString:
return QColor(0x7f,0x00,0x7f);
case PlusKeyword:
return QColor(0x7f,0x7f,0x00);
case Operator:
case Identifier:
break;
case CommentDocKeyword:
return QColor(0x30,0x60,0xa0);
case CommentDocKeywordError:
return QColor(0x80,0x40,0x20);
case KeywordSet5:
return QColor(0x4b,0x00,0x82);
case KeywordSet6:
return QColor(0xb0,0x00,0x40);
case KeywordSet7:
return QColor(0x8b,0x00,0x00);
case KeywordSet8:
return QColor(0x80,0x00,0x80);
}
return QsciLexer::defaultColor(style);
}
// Returns the end-of-line fill for a style.
bool QsciLexerSQL::defaultEolFill(int style) const
{
if (style == PlusPrompt)
return true;
return QsciLexer::defaultEolFill(style);
}
// Returns the font of the text for a style.
QFont QsciLexerSQL::defaultFont(int style) const
{
QFont f;
switch (style)
{
case Comment:
case CommentLine:
case PlusComment:
case CommentLineHash:
case CommentDocKeyword:
case CommentDocKeywordError:
#if defined(Q_OS_WIN)
f = QFont("Comic Sans MS",9);
#elif defined(Q_OS_MAC)
f = QFont("Comic Sans MS", 12);
#else
f = QFont("Bitstream Vera Serif",9);
#endif
break;
case Keyword:
case Operator:
f = QsciLexer::defaultFont(style);
f.setBold(true);
break;
case DoubleQuotedString:
case SingleQuotedString:
case PlusPrompt:
#if defined(Q_OS_WIN)
f = QFont("Courier New",10);
#elif defined(Q_OS_MAC)
f = QFont("Courier", 12);
#else
f = QFont("Bitstream Vera Sans Mono",9);
#endif
break;
default:
f = QsciLexer::defaultFont(style);
}
return f;
}
// Returns the set of keywords.
const char *QsciLexerSQL::keywords(int set) const
{
if (set == 1)
return
"absolute action add admin after aggregate alias all "
"allocate alter and any are array as asc assertion "
"at authorization before begin binary bit blob "
"boolean both breadth by call cascade cascaded case "
"cast catalog char character check class clob close "
"collate collation column commit completion connect "
"connection constraint constraints constructor "
"continue corresponding create cross cube current "
"current_date current_path current_role current_time "
"current_timestamp current_user cursor cycle data "
"date day deallocate dec decimal declare default "
"deferrable deferred delete depth deref desc "
"describe descriptor destroy destructor "
"deterministic dictionary diagnostics disconnect "
"distinct domain double drop dynamic each else end "
"end-exec equals escape every except exception exec "
"execute external false fetch first float for "
"foreign found from free full function general get "
"global go goto grant group grouping having host "
"hour identity if ignore immediate in indicator "
"initialize initially inner inout input insert int "
"integer intersect interval into is isolation "
"iterate join key language large last lateral "
"leading left less level like limit local localtime "
"localtimestamp locator map match minute modifies "
"modify module month names national natural nchar "
"nclob new next no none not null numeric object of "
"off old on only open operation option or order "
"ordinality out outer output pad parameter "
"parameters partial path postfix precision prefix "
"preorder prepare preserve primary prior privileges "
"procedure public read reads real recursive ref "
"references referencing relative restrict result "
"return returns revoke right role rollback rollup "
"routine row rows savepoint schema scroll scope "
"search second section select sequence session "
"session_user set sets size smallint some| space "
"specific specifictype sql sqlexception sqlstate "
"sqlwarning start state statement static structure "
"system_user table temporary terminate than then "
"time timestamp timezone_hour timezone_minute to "
"trailing transaction translation treat trigger "
"true under union unique unknown unnest update usage "
"user using value values varchar variable varying "
"view when whenever where with without work write "
"year zone";
if (set == 3)
return
"param author since return see deprecated todo";
if (set == 4)
return
"acc~ept a~ppend archive log attribute bre~ak "
"bti~tle c~hange cl~ear col~umn comp~ute conn~ect "
"copy def~ine del desc~ribe disc~onnect e~dit "
"exec~ute exit get help ho~st i~nput l~ist passw~ord "
"pau~se pri~nt pro~mpt quit recover rem~ark "
"repf~ooter reph~eader r~un sav~e set sho~w shutdown "
"spo~ol sta~rt startup store timi~ng tti~tle "
"undef~ine var~iable whenever oserror whenever "
"sqlerror";
if (set == 5)
return
"dbms_output.disable dbms_output.enable dbms_output.get_line "
"dbms_output.get_lines dbms_output.new_line dbms_output.put "
"dbms_output.put_line";
return 0;
}
// Returns the user name of a style.
QString QsciLexerSQL::description(int style) const
{
switch (style)
{
case Default:
return tr("Default");
case Comment:
return tr("Comment");
case CommentLine:
return tr("Comment line");
case CommentDoc:
return tr("JavaDoc style comment");
case Number:
return tr("Number");
case Keyword:
return tr("Keyword");
case DoubleQuotedString:
return tr("Double-quoted string");
case SingleQuotedString:
return tr("Single-quoted string");
case PlusKeyword:
return tr("SQL*Plus keyword");
case PlusPrompt:
return tr("SQL*Plus prompt");
case Operator:
return tr("Operator");
case Identifier:
return tr("Identifier");
case PlusComment:
return tr("SQL*Plus comment");
case CommentLineHash:
return tr("# comment line");
case CommentDocKeyword:
return tr("JavaDoc keyword");
case CommentDocKeywordError:
return tr("JavaDoc keyword error");
case KeywordSet5:
return tr("User defined 1");
case KeywordSet6:
return tr("User defined 2");
case KeywordSet7:
return tr("User defined 3");
case KeywordSet8:
return tr("User defined 4");
case QuotedIdentifier:
return tr("Quoted identifier");
case QuotedOperator:
return tr("Quoted operator");
}
return QString();
}
// Returns the background colour of the text for a style.
QColor QsciLexerSQL::defaultPaper(int style) const
{
if (style == PlusPrompt)
return QColor(0xe0,0xff,0xe0);
return QsciLexer::defaultPaper(style);
}
// Refresh all properties.
void QsciLexerSQL::refreshProperties()
{
setAtElseProp();
setCommentProp();
setCompactProp();
setOnlyBeginProp();
setBackticksIdentifierProp();
setNumbersignCommentProp();
setBackslashEscapesProp();
setAllowDottedWordProp();
}
// Read properties from the settings.
bool QsciLexerSQL::readProperties(QSettings &qs, const QString &prefix)
{
int rc = true;
at_else = qs.value(prefix + "atelse", false).toBool();
fold_comments = qs.value(prefix + "foldcomments", false).toBool();
fold_compact = qs.value(prefix + "foldcompact", true).toBool();
only_begin = qs.value(prefix + "onlybegin", false).toBool();
backticks_identifier = qs.value(prefix + "backticksidentifier", false).toBool();
numbersign_comment = qs.value(prefix + "numbersigncomment", false).toBool();
backslash_escapes = qs.value(prefix + "backslashescapes", false).toBool();
allow_dotted_word = qs.value(prefix + "allowdottedword", false).toBool();
return rc;
}
// Write properties to the settings.
bool QsciLexerSQL::writeProperties(QSettings &qs, const QString &prefix) const
{
int rc = true;
qs.value(prefix + "atelse", at_else);
qs.value(prefix + "foldcomments", fold_comments);
qs.value(prefix + "foldcompact", fold_compact);
qs.value(prefix + "onlybegin", only_begin);
qs.value(prefix + "backticksidentifier", backticks_identifier);
qs.value(prefix + "numbersigncomment", numbersign_comment);
qs.value(prefix + "backslashescapes", backslash_escapes);
qs.value(prefix + "allowdottedword", allow_dotted_word);
return rc;
}
// Set if ELSE blocks can be folded.
void QsciLexerSQL::setFoldAtElse(bool fold)
{
at_else = fold;
setAtElseProp();
}
// Set the "fold.sql.at.else" property.
void QsciLexerSQL::setAtElseProp()
{
emit propertyChanged("fold.sql.at.else", (at_else ? "1" : "0"));
}
// Set if comments can be folded.
void QsciLexerSQL::setFoldComments(bool fold)
{
fold_comments = fold;
setCommentProp();
}
// Set the "fold.comment" property.
void QsciLexerSQL::setCommentProp()
{
emit propertyChanged("fold.comment", (fold_comments ? "1" : "0"));
}
// Set if folds are compact
void QsciLexerSQL::setFoldCompact(bool fold)
{
fold_compact = fold;
setCompactProp();
}
// Set the "fold.compact" property.
void QsciLexerSQL::setCompactProp()
{
emit propertyChanged("fold.compact", (fold_compact ? "1" : "0"));
}
// Set if BEGIN blocks only can be folded.
void QsciLexerSQL::setFoldOnlyBegin(bool fold)
{
only_begin = fold;
setOnlyBeginProp();
}
// Set the "fold.sql.only.begin" property.
void QsciLexerSQL::setOnlyBeginProp()
{
emit propertyChanged("fold.sql.only.begin", (only_begin ? "1" : "0"));
}
// Enable quoted identifiers.
void QsciLexerSQL::setQuotedIdentifiers(bool enable)
{
backticks_identifier = enable;
setBackticksIdentifierProp();
}
// Set the "lexer.sql.backticks.identifier" property.
void QsciLexerSQL::setBackticksIdentifierProp()
{
emit propertyChanged("lexer.sql.backticks.identifier", (backticks_identifier ? "1" : "0"));
}
// Enable '#' as a comment character.
void QsciLexerSQL::setHashComments(bool enable)
{
numbersign_comment = enable;
setNumbersignCommentProp();
}
// Set the "lexer.sql.numbersign.comment" property.
void QsciLexerSQL::setNumbersignCommentProp()
{
emit propertyChanged("lexer.sql.numbersign.comment", (numbersign_comment ? "1" : "0"));
}
// Enable/disable backslash escapes.
void QsciLexerSQL::setBackslashEscapes(bool enable)
{
backslash_escapes = enable;
setBackslashEscapesProp();
}
// Set the "sql.backslash.escapes" property.
void QsciLexerSQL::setBackslashEscapesProp()
{
emit propertyChanged("sql.backslash.escapes", (backslash_escapes ? "1" : "0"));
}
// Enable dotted words.
void QsciLexerSQL::setDottedWords(bool enable)
{
allow_dotted_word = enable;
setAllowDottedWordProp();
}
// Set the "lexer.sql.allow.dotted.word" property.
void QsciLexerSQL::setAllowDottedWordProp()
{
emit propertyChanged("lexer.sql.allow.dotted.word", (allow_dotted_word ? "1" : "0"));
}
+316
View File
@@ -0,0 +1,316 @@
// This module implements the QsciMacro class.
//
// Copyright (c) 2015 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/qscimacro.h"
#include <QStringList>
#include "Qsci/qsciscintilla.h"
static int fromHex(unsigned char ch);
// The ctor.
QsciMacro::QsciMacro(QsciScintilla *parent)
: QObject(parent), qsci(parent)
{
}
// The ctor that initialises the macro.
QsciMacro::QsciMacro(const QString &asc, QsciScintilla *parent)
: QObject(parent), qsci(parent)
{
load(asc);
}
// The dtor.
QsciMacro::~QsciMacro()
{
}
// Clear the contents of the macro.
void QsciMacro::clear()
{
macro.clear();
}
// Read a macro from a string.
bool QsciMacro::load(const QString &asc)
{
bool ok = true;
macro.clear();
QStringList fields = asc.split(' ');
int f = 0;
while (f < fields.size())
{
Macro cmd;
unsigned len;
// Extract the 3 fixed fields.
if (f + 3 > fields.size())
{
ok = false;
break;
}
cmd.msg = fields[f++].toUInt(&ok);
if (!ok)
break;
cmd.wParam = fields[f++].toULong(&ok);
if (!ok)
break;
len = fields[f++].toUInt(&ok);
if (!ok)
break;
// Extract any text.
if (len)
{
if (f + 1 > fields.size())
{
ok = false;
break;
}
QByteArray ba = fields[f++].toLatin1();
const char *sp = ba.data();
if (!sp)
{
ok = false;
break;
}
// Because of historical bugs the length field is unreliable.
bool embedded_null = false;
unsigned char ch;
while ((ch = *sp++) != '\0')
{
if (ch == '"' || ch <= ' ' || ch >= 0x7f)
{
ok = false;
break;
}
if (ch == '\\')
{
int b1, b2;
if ((b1 = fromHex(*sp++)) < 0 ||
(b2 = fromHex(*sp++)) < 0)
{
ok = false;
break;
}
ch = (b1 << 4) + b2;
}
if (ch == '\0')
{
// Don't add it now as it may be the terminating '\0'.
embedded_null = true;
}
else
{
if (embedded_null)
{
// Add the pending embedded '\0'.
cmd.text += '\0';
embedded_null = false;
}
cmd.text += ch;
}
}
if (!ok)
break;
}
macro.append(cmd);
}
if (!ok)
macro.clear();
return ok;
}
// Write a macro to a string.
QString QsciMacro::save() const
{
QString ms;
QList<Macro>::const_iterator it;
for (it = macro.begin(); it != macro.end(); ++it)
{
if (!ms.isEmpty())
ms += ' ';
unsigned len = (*it).text.size();
QString m;
ms += m.sprintf("%u %lu %u", (*it).msg, (*it).wParam, len);
if (len)
{
// In Qt v3, if the length is greater than zero then it also
// includes the '\0', so we need to make sure that Qt v4 writes the
// '\0'. That the '\0' is written at all is a bug because
// QCString::size() is used instead of QCString::length(). We
// don't fix this so as not to break old macros. However this is
// still broken because we have already written the unadjusted
// length. So, in summary, the length field should be interpreted
// as a zero/non-zero value, and the end of the data is either at
// the next space or the very end of the data.
++len;
ms += ' ';
const char *cp = (*it).text.data();
while (len--)
{
unsigned char ch = *cp++;
if (ch == '\\' || ch == '"' || ch <= ' ' || ch >= 0x7f)
{
QString buf;
ms += buf.sprintf("\\%02x", ch);
}
else
ms += ch;
}
}
}
return ms;
}
// Play the macro.
void QsciMacro::play()
{
if (!qsci)
return;
QList<Macro>::const_iterator it;
for (it = macro.begin(); it != macro.end(); ++it)
qsci->SendScintilla((*it).msg, (*it).wParam, (*it).text.data());
}
// Start recording.
void QsciMacro::startRecording()
{
if (!qsci)
return;
macro.clear();
connect(qsci, SIGNAL(SCN_MACRORECORD(unsigned int, unsigned long, void *)),
SLOT(record(unsigned int, unsigned long, void *)));
qsci->SendScintilla(QsciScintillaBase::SCI_STARTRECORD);
}
// End recording.
void QsciMacro::endRecording()
{
if (!qsci)
return;
qsci->SendScintilla(QsciScintillaBase::SCI_STOPRECORD);
qsci->disconnect(this);
}
// Record a command.
void QsciMacro::record(unsigned int msg, unsigned long wParam, void *lParam)
{
Macro m;
m.msg = msg;
m.wParam = wParam;
// Determine commands which need special handling of the parameters.
switch (msg)
{
case QsciScintillaBase::SCI_ADDTEXT:
m.text = QByteArray(reinterpret_cast<const char *>(lParam), wParam);
break;
case QsciScintillaBase::SCI_REPLACESEL:
if (!macro.isEmpty() && macro.last().msg == QsciScintillaBase::SCI_REPLACESEL)
{
// This is the command used for ordinary user input so it's a
// significant space reduction to append it to the previous
// command.
macro.last().text.append(reinterpret_cast<const char *>(lParam));
return;
}
/* Drop through. */
case QsciScintillaBase::SCI_INSERTTEXT:
case QsciScintillaBase::SCI_APPENDTEXT:
case QsciScintillaBase::SCI_SEARCHNEXT:
case QsciScintillaBase::SCI_SEARCHPREV:
m.text.append(reinterpret_cast<const char *>(lParam));
break;
}
macro.append(m);
}
// Return the given hex character as a binary.
static int fromHex(unsigned char ch)
{
if (ch >= '0' && ch <= '9')
return ch - '0';
if (ch >= 'a' && ch <= 'f')
return ch - 'a' + 10;
return -1;
}
+222
View File
@@ -0,0 +1,222 @@
# The project file for the QScintilla library.
#
# Copyright (c) 2014 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 versions 2.0 or 3.0 as published by the Free Software
# Foundation and appearing in the files LICENSE.GPL2 and LICENSE.GPL3
# included in the packaging of this file. Alternatively you may (at
# your option) use any later version of the GNU General Public
# License if such license has been publicly approved by Riverbank
# Computing Limited (or its successors, if any) and the KDE Free Qt
# Foundation. In addition, as a special exception, Riverbank gives you
# certain additional rights. These rights are described in the Riverbank
# GPL Exception version 1.1, which can be found in the file
# GPL_EXCEPTION.txt in this package.
#
# If you are unsure which license is appropriate for your use, please
# contact the sales department at sales@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.
# This must be kept in sync with Python/configure.py, Python/configure-old.py,
# example-Qt4Qt5/application.pro and designer-Qt4Qt5/designer.pro.
!win32:VERSION = 11.3.0
TEMPLATE = lib
TARGET = qscintilla2
CONFIG += qt warn_off release thread exceptions staticlib debug_and_release
INCLUDEPATH += . ../include ../lexlib ../src
DEFINES += QSCINTILLA_MAKE_DLL SCINTILLA_QT SCI_LEXER
greaterThan(QT_MAJOR_VERSION, 3) {
CONFIG(staticlib) {
DEFINES -= QSCINTILLA_MAKE_DLL
}
}
greaterThan(QT_MAJOR_VERSION, 4) {
QT += widgets printsupport
greaterThan(QT_MINOR_VERSION, 1) {
macx:QT += macextras
}
# Work around QTBUG-39300.
CONFIG -= android_install
}
# Comment this in if you want the internal Scintilla classes to be placed in a
# Scintilla namespace rather than pollute the global namespace.
#DEFINES += SCI_NAMESPACE
# Handle both Qt v4 and v3.
target.path = $$[QT_INSTALL_LIBS]
isEmpty(target.path) {
target.path = $(QTDIR)/lib
}
header.path = $$[QT_INSTALL_HEADERS]
header.files = Qsci
isEmpty(header.path) {
header.path = $(QTDIR)/include/Qsci
header.files = Qsci/qsci*.h
}
trans.path = $$[QT_INSTALL_TRANSLATIONS]
trans.files = qscintilla_*.qm
isEmpty(trans.path) {
trans.path = $(QTDIR)/translations
}
qsci.path = $$[QT_INSTALL_DATA]
qsci.files = ../qsci
isEmpty(qsci.path) {
qsci.path = $(QTDIR)
}
INSTALLS += header trans qsci target
greaterThan(QT_MAJOR_VERSION, 3) {
features.path = $$[QT_INSTALL_DATA]/mkspecs/features
features.files = $$PWD/features/qscintilla2.prf
INSTALLS += features
}
HEADERS = \
./Qsci/qsciglobal.h \
./Qsci/qsciscintilla.h \
./Qsci/qsciscintillabase.h \
./Qsci/qsciabstractapis.h \
./Qsci/qsciapis.h \
./Qsci/qscicommand.h \
./Qsci/qscicommandset.h \
./Qsci/qscidocument.h \
./Qsci/qscilexer.h \
./Qsci/qscilexersql.h \
./Qsci/qscimacro.h \
./Qsci/qsciprinter.h \
./Qsci/qscistyle.h \
./Qsci/qscistyledtext.h \
ListBoxQt.h \
SciClasses.h \
SciNamespace.h \
ScintillaQt.h \
../include/ILexer.h \
../include/Platform.h \
../include/SciLexer.h \
../include/Scintilla.h \
../include/ScintillaWidget.h \
../lexlib/Accessor.h \
../lexlib/CharacterCategory.h \
../lexlib/CharacterSet.h \
../lexlib/LexAccessor.h \
../lexlib/LexerBase.h \
../lexlib/LexerModule.h \
../lexlib/LexerNoExceptions.h \
../lexlib/LexerSimple.h \
../lexlib/OptionSet.h \
../lexlib/PropSetSimple.h \
../lexlib/StyleContext.h \
../lexlib/SubStyles.h \
../lexlib/WordList.h \
../src/AutoComplete.h \
../src/CallTip.h \
../src/CaseConvert.h \
../src/CaseFolder.h \
../src/Catalogue.h \
../src/CellBuffer.h \
../src/CharClassify.h \
../src/ContractionState.h \
../src/Decoration.h \
../src/Document.h \
../src/Editor.h \
../src/ExternalLexer.h \
../src/FontQuality.h \
../src/Indicator.h \
../src/KeyMap.h \
../src/LineMarker.h \
../src/Partitioning.h \
../src/PerLine.h \
../src/PositionCache.h \
../src/RESearch.h \
../src/RunStyles.h \
../src/ScintillaBase.h \
../src/Selection.h \
../src/SplitVector.h \
../src/Style.h \
../src/UnicodeFromUTF8.h \
../src/UniConversion.h \
../src/ViewStyle.h \
../src/XPM.h
SOURCES = \
qsciscintilla.cpp \
qsciscintillabase.cpp \
qsciabstractapis.cpp \
qsciapis.cpp \
qscicommand.cpp \
qscicommandset.cpp \
qscidocument.cpp \
qscilexer.cpp \
qscilexersql.cpp \
qscimacro.cpp \
qsciprinter.cpp \
qscistyle.cpp \
qscistyledtext.cpp \
MacPasteboardMime.cpp \
InputMethod.cpp \
SciClasses.cpp \
ListBoxQt.cpp \
PlatQt.cpp \
ScintillaQt.cpp \
../lexers/LexSQL.cpp \
../lexlib/Accessor.cpp \
../lexlib/CharacterCategory.cpp \
../lexlib/CharacterSet.cpp \
../lexlib/LexerBase.cpp \
../lexlib/LexerModule.cpp \
../lexlib/LexerNoExceptions.cpp \
../lexlib/LexerSimple.cpp \
../lexlib/PropSetSimple.cpp \
../lexlib/StyleContext.cpp \
../lexlib/WordList.cpp \
../src/AutoComplete.cpp \
../src/CallTip.cpp \
../src/CaseConvert.cpp \
../src/CaseFolder.cpp \
../src/Catalogue.cpp \
../src/CellBuffer.cpp \
../src/CharClassify.cpp \
../src/ContractionState.cpp \
../src/Decoration.cpp \
../src/Document.cpp \
../src/Editor.cpp \
../src/EditModel.cpp \
../src/EditView.cpp \
../src/ExternalLexer.cpp \
../src/Indicator.cpp \
../src/KeyMap.cpp \
../src/LineMarker.cpp \
../src/MarginView.cpp \
../src/PerLine.cpp \
../src/PositionCache.cpp \
../src/RESearch.cpp \
../src/RunStyles.cpp \
../src/ScintillaBase.cpp \
../src/Selection.cpp \
../src/Style.cpp \
../src/UniConversion.cpp \
../src/ViewStyle.cpp \
../src/XPM.cpp
TRANSLATIONS = \
qscintilla_cs.ts \
qscintilla_de.ts \
qscintilla_es.ts \
qscintilla_fr.ts \
qscintilla_pt_br.ts
Binary file not shown.
File diff suppressed because it is too large Load Diff
Binary file not shown.
File diff suppressed because it is too large Load Diff
Binary file not shown.
File diff suppressed because it is too large Load Diff
Binary file not shown.
File diff suppressed because it is too large Load Diff
Binary file not shown.
File diff suppressed because it is too large Load Diff
+186
View File
@@ -0,0 +1,186 @@
// This module implements the QsciPrinter class.
//
// Copyright (c) 2015 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/qsciprinter.h"
#if !defined(QT_NO_PRINTER)
#include <QPrinter>
#include <QPainter>
#include <QStack>
#include "Qsci/qsciscintillabase.h"
// The ctor.
QsciPrinter::QsciPrinter(QPrinter::PrinterMode mode)
: QPrinter(mode), mag(0), wrap(QsciScintilla::WrapWord)
{
}
// The dtor.
QsciPrinter::~QsciPrinter()
{
}
// Format the page before the document text is drawn.
void QsciPrinter::formatPage(QPainter &, bool, QRect &, int)
{
}
// Print a range of lines to a printer.
int QsciPrinter::printRange(QsciScintillaBase *qsb, int from, int to)
{
// Sanity check.
if (!qsb)
return false;
// Setup the printing area.
QRect def_area;
def_area.setX(0);
def_area.setY(0);
def_area.setWidth(width());
def_area.setHeight(height());
// Get the page range.
int pgFrom, pgTo;
pgFrom = fromPage();
pgTo = toPage();
// Find the position range.
long startPos, endPos;
endPos = qsb->SendScintilla(QsciScintillaBase::SCI_GETLENGTH);
startPos = (from > 0 ? qsb -> SendScintilla(QsciScintillaBase::SCI_POSITIONFROMLINE,from) : 0);
if (to >= 0)
{
long toPos = qsb -> SendScintilla(QsciScintillaBase::SCI_POSITIONFROMLINE,to + 1);
if (endPos > toPos)
endPos = toPos;
}
if (startPos >= endPos)
return false;
QPainter painter(this);
bool reverse = (pageOrder() == LastPageFirst);
bool needNewPage = false;
qsb -> SendScintilla(QsciScintillaBase::SCI_SETPRINTMAGNIFICATION,mag);
qsb -> SendScintilla(QsciScintillaBase::SCI_SETPRINTWRAPMODE,wrap);
for (int i = 1; i <= numCopies(); ++i)
{
// If we are printing in reverse page order then remember the start
// position of each page.
QStack<long> pageStarts;
int currPage = 1;
long pos = startPos;
while (pos < endPos)
{
// See if we have finished the requested page range.
if (pgTo > 0 && pgTo < currPage)
break;
// See if we are going to render this page, or just see how much
// would fit onto it.
bool render = false;
if (pgFrom == 0 || pgFrom <= currPage)
{
if (reverse)
pageStarts.push(pos);
else
{
render = true;
if (needNewPage)
{
if (!newPage())
return false;
}
else
needNewPage = true;
}
}
QRect area = def_area;
formatPage(painter,render,area,currPage);
pos = qsb -> SendScintilla(QsciScintillaBase::SCI_FORMATRANGE,render,&painter,area,pos,endPos);
++currPage;
}
// All done if we are printing in normal page order.
if (!reverse)
continue;
// Now go through each page on the stack and really print it.
while (!pageStarts.isEmpty())
{
--currPage;
long ePos = pos;
pos = pageStarts.pop();
if (needNewPage)
{
if (!newPage())
return false;
}
else
needNewPage = true;
QRect area = def_area;
formatPage(painter,true,area,currPage);
qsb->SendScintilla(QsciScintillaBase::SCI_FORMATRANGE,true,&painter,area,pos,ePos);
}
}
return true;
}
// Set the print magnification in points.
void QsciPrinter::setMagnification(int magnification)
{
mag = magnification;
}
// Set the line wrap mode.
void QsciPrinter::setWrapMode(QsciScintilla::WrapMode wmode)
{
wrap = wmode;
}
#endif
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,799 @@
// This module implements the "official" low-level API.
//
// Copyright (c) 2015 Riverbank Computing Limited <info@riverbankcomputing.com>
//
// This file is part of QScintilla.
//
// This file may be used under the terms of the GNU General Public License
// version 3.0 as published by the Free Software Foundation and appearing in
// the file LICENSE included in the packaging of this file. Please review the
// following information to ensure the GNU General Public License version 3.0
// requirements will be met: http://www.gnu.org/copyleft/gpl.html.
//
// If you do not wish to use this file under the terms of the GPL version 3.0
// then you may purchase a commercial license. For more information contact
// info@riverbankcomputing.com.
//
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
#include "Qsci/qsciscintillabase.h"
#include <QApplication>
#include <QClipboard>
#include <QColor>
#include <QContextMenuEvent>
#include <QDragEnterEvent>
#include <QDragMoveEvent>
#include <QDropEvent>
#include <QDragLeaveEvent>
#include <QFocusEvent>
#include <QKeyEvent>
#include <QList>
#include <QMimeData>
#include <QMouseEvent>
#include <QPaintEvent>
#include <QScrollBar>
#include <QStyle>
#include <QTextCodec>
#include "ScintillaQt.h"
// The #defines in Scintilla.h and the enums in qsciscintillabase.h conflict
// (because we want to use the same names) so we have to undefine those we use
// in this file.
#undef SCI_SETCARETPERIOD
#undef SCK_DOWN
#undef SCK_UP
#undef SCK_LEFT
#undef SCK_RIGHT
#undef SCK_HOME
#undef SCK_END
#undef SCK_PRIOR
#undef SCK_NEXT
#undef SCK_DELETE
#undef SCK_INSERT
#undef SCK_ESCAPE
#undef SCK_BACK
#undef SCK_TAB
#undef SCK_RETURN
#undef SCK_ADD
#undef SCK_SUBTRACT
#undef SCK_DIVIDE
#undef SCK_WIN
#undef SCK_RWIN
#undef SCK_MENU
// Remember if we have linked the lexers.
static bool lexersLinked = false;
// The list of instances.
static QList<QsciScintillaBase *> poolList;
// Mime support.
static const QLatin1String mimeTextPlain("text/plain");
static const QLatin1String mimeRectangularWin("MSDEVColumnSelect");
static const QLatin1String mimeRectangular("text/x-qscintilla-rectangular");
#if (QT_VERSION >= 0x040200 && QT_VERSION < 0x050000 && defined(Q_OS_MAC)) || (QT_VERSION >= 0x050200 && defined(Q_OS_OSX))
extern void initialiseRectangularPasteboardMime();
#endif
// The ctor.
QsciScintillaBase::QsciScintillaBase(QWidget *parent)
: QAbstractScrollArea(parent), preeditPos(-1), preeditNrBytes(0)
#if QT_VERSION >= 0x050000
, clickCausedFocus(false)
#endif
{
connect(verticalScrollBar(), SIGNAL(valueChanged(int)),
SLOT(handleVSb(int)));
connect(horizontalScrollBar(), SIGNAL(valueChanged(int)),
SLOT(handleHSb(int)));
setAcceptDrops(true);
setFocusPolicy(Qt::WheelFocus);
setAttribute(Qt::WA_KeyCompression);
setAttribute(Qt::WA_InputMethodEnabled);
#if QT_VERSION >= 0x050100
setInputMethodHints(
Qt::ImhNoAutoUppercase|Qt::ImhNoPredictiveText|Qt::ImhMultiLine);
#elif QT_VERSION >= 0x040600
setInputMethodHints(Qt::ImhNoAutoUppercase|Qt::ImhNoPredictiveText);
#endif
viewport()->setBackgroundRole(QPalette::Base);
viewport()->setMouseTracking(true);
viewport()->setAttribute(Qt::WA_NoSystemBackground);
triple_click.setSingleShot(true);
#if (QT_VERSION >= 0x040200 && QT_VERSION < 0x050000 && defined(Q_OS_MAC)) || (QT_VERSION >= 0x050200 && defined(Q_OS_OSX))
initialiseRectangularPasteboardMime();
#endif
sci = new QsciScintillaQt(this);
SendScintilla(SCI_SETCARETPERIOD, QApplication::cursorFlashTime() / 2);
// Make sure the lexers are linked in.
if (!lexersLinked)
{
Scintilla_LinkLexers();
lexersLinked = true;
}
QClipboard *cb = QApplication::clipboard();
if (cb->supportsSelection())
connect(cb, SIGNAL(selectionChanged()), SLOT(handleSelection()));
// Add it to the pool.
poolList.append(this);
}
// The dtor.
QsciScintillaBase::~QsciScintillaBase()
{
// The QsciScintillaQt object isn't a child so delete it explicitly.
delete sci;
// Remove it from the pool.
poolList.removeAt(poolList.indexOf(this));
}
// Return an instance from the pool.
QsciScintillaBase *QsciScintillaBase::pool()
{
return poolList.first();
}
// Tell Scintilla to update the scroll bars. Scintilla should be doing this
// itself.
void QsciScintillaBase::setScrollBars()
{
sci->SetScrollBars();
}
// Send a message to the real Scintilla widget using the low level Scintilla
// API.
long QsciScintillaBase::SendScintilla(unsigned int msg, unsigned long wParam,
long lParam) const
{
return sci->WndProc(msg, wParam, lParam);
}
// Overloaded message send.
long QsciScintillaBase::SendScintilla(unsigned int msg, unsigned long wParam,
void *lParam) const
{
return sci->WndProc(msg, wParam, reinterpret_cast<sptr_t>(lParam));
}
// Overloaded message send.
long QsciScintillaBase::SendScintilla(unsigned int msg, unsigned long wParam,
const char *lParam) const
{
return sci->WndProc(msg, wParam, reinterpret_cast<sptr_t>(lParam));
}
// Overloaded message send.
long QsciScintillaBase::SendScintilla(unsigned int msg,
const char *lParam) const
{
return sci->WndProc(msg, static_cast<uptr_t>(0),
reinterpret_cast<sptr_t>(lParam));
}
// Overloaded message send.
long QsciScintillaBase::SendScintilla(unsigned int msg, const char *wParam,
const char *lParam) const
{
return sci->WndProc(msg, reinterpret_cast<uptr_t>(wParam),
reinterpret_cast<sptr_t>(lParam));
}
// Overloaded message send.
long QsciScintillaBase::SendScintilla(unsigned int msg, long wParam) const
{
return sci->WndProc(msg, static_cast<uptr_t>(wParam),
static_cast<sptr_t>(0));
}
// Overloaded message send.
long QsciScintillaBase::SendScintilla(unsigned int msg, int wParam) const
{
return sci->WndProc(msg, static_cast<uptr_t>(wParam),
static_cast<sptr_t>(0));
}
// Overloaded message send.
long QsciScintillaBase::SendScintilla(unsigned int msg, long cpMin, long cpMax,
char *lpstrText) const
{
QSCI_SCI_NAMESPACE(TextRange) tr;
tr.chrg.cpMin = cpMin;
tr.chrg.cpMax = cpMax;
tr.lpstrText = lpstrText;
return sci->WndProc(msg, static_cast<uptr_t>(0),
reinterpret_cast<sptr_t>(&tr));
}
// Overloaded message send.
long QsciScintillaBase::SendScintilla(unsigned int msg, unsigned long wParam,
const QColor &col) const
{
sptr_t lParam = (col.blue() << 16) | (col.green() << 8) | col.red();
return sci->WndProc(msg, wParam, lParam);
}
// Overloaded message send.
long QsciScintillaBase::SendScintilla(unsigned int msg, const QColor &col) const
{
uptr_t wParam = (col.blue() << 16) | (col.green() << 8) | col.red();
return sci->WndProc(msg, wParam, static_cast<sptr_t>(0));
}
// Overloaded message send.
long QsciScintillaBase::SendScintilla(unsigned int msg, unsigned long wParam,
QPainter *hdc, const QRect &rc, long cpMin, long cpMax) const
{
QSCI_SCI_NAMESPACE(RangeToFormat) rf;
rf.hdc = rf.hdcTarget = reinterpret_cast<QSCI_SCI_NAMESPACE(SurfaceID)>(hdc);
rf.rc.left = rc.left();
rf.rc.top = rc.top();
rf.rc.right = rc.right() + 1;
rf.rc.bottom = rc.bottom() + 1;
rf.chrg.cpMin = cpMin;
rf.chrg.cpMax = cpMax;
return sci->WndProc(msg, wParam, reinterpret_cast<sptr_t>(&rf));
}
// Overloaded message send.
long QsciScintillaBase::SendScintilla(unsigned int msg, unsigned long wParam,
const QPixmap &lParam) const
{
return sci->WndProc(msg, wParam, reinterpret_cast<sptr_t>(&lParam));
}
// Overloaded message send.
long QsciScintillaBase::SendScintilla(unsigned int msg, unsigned long wParam,
const QImage &lParam) const
{
return sci->WndProc(msg, wParam, reinterpret_cast<sptr_t>(&lParam));
}
// Send a message to the real Scintilla widget using the low level Scintilla
// API that returns a pointer result.
void *QsciScintillaBase::SendScintillaPtrResult(unsigned int msg) const
{
return reinterpret_cast<void *>(sci->WndProc(msg, static_cast<uptr_t>(0),
static_cast<sptr_t>(0)));
}
// Re-implemented to handle the context menu.
void QsciScintillaBase::contextMenuEvent(QContextMenuEvent *e)
{
sci->ContextMenu(QSCI_SCI_NAMESPACE(Point)(e->globalX(), e->globalY()));
}
// Re-implemented to tell the widget it has the focus.
void QsciScintillaBase::focusInEvent(QFocusEvent *e)
{
sci->SetFocusState(true);
#if QT_VERSION >= 0x050000
clickCausedFocus = (e->reason() == Qt::MouseFocusReason);
#endif
QAbstractScrollArea::focusInEvent(e);
}
// Re-implemented to tell the widget it has lost the focus.
void QsciScintillaBase::focusOutEvent(QFocusEvent *e)
{
if (e->reason() == Qt::ActiveWindowFocusReason)
{
// Only tell Scintilla we have lost focus if the new active window
// isn't our auto-completion list. This is probably only an issue on
// Linux and there are still problems because subsequent focus out
// events don't always seem to get generated (at least with Qt5).
QWidget *aw = QApplication::activeWindow();
if (!aw || aw->parent() != this || !aw->inherits("QsciSciListBox"))
sci->SetFocusState(false);
}
else
{
sci->SetFocusState(false);
}
QAbstractScrollArea::focusOutEvent(e);
}
// Re-implemented to make sure tabs are passed to the editor.
bool QsciScintillaBase::focusNextPrevChild(bool next)
{
if (!sci->pdoc->IsReadOnly())
return false;
return QAbstractScrollArea::focusNextPrevChild(next);
}
// Handle the selection changing.
void QsciScintillaBase::handleSelection()
{
if (!QApplication::clipboard()->ownsSelection())
sci->UnclaimSelection();
}
// Handle key presses.
void QsciScintillaBase::keyPressEvent(QKeyEvent *e)
{
int modifiers = 0;
if (e->modifiers() & Qt::ShiftModifier)
modifiers |= SCMOD_SHIFT;
if (e->modifiers() & Qt::ControlModifier)
modifiers |= SCMOD_CTRL;
if (e->modifiers() & Qt::AltModifier)
modifiers |= SCMOD_ALT;
if (e->modifiers() & Qt::MetaModifier)
modifiers |= SCMOD_META;
int key = commandKey(e->key(), modifiers);
if (key)
{
bool consumed = false;
sci->KeyDownWithModifiers(key, modifiers, &consumed);
if (consumed)
{
e->accept();
return;
}
}
QString text = e->text();
if (!text.isEmpty() && text[0].isPrint())
{
ScintillaBytes bytes = textAsBytes(text);
sci->AddCharUTF(bytes.data(), bytes.length());
e->accept();
}
else
{
QAbstractScrollArea::keyPressEvent(e);
}
}
// Map a Qt key to a valid Scintilla command key, or 0 if none.
int QsciScintillaBase::commandKey(int qt_key, int &modifiers)
{
int key;
switch (qt_key)
{
case Qt::Key_Down:
key = SCK_DOWN;
break;
case Qt::Key_Up:
key = SCK_UP;
break;
case Qt::Key_Left:
key = SCK_LEFT;
break;
case Qt::Key_Right:
key = SCK_RIGHT;
break;
case Qt::Key_Home:
key = SCK_HOME;
break;
case Qt::Key_End:
key = SCK_END;
break;
case Qt::Key_PageUp:
key = SCK_PRIOR;
break;
case Qt::Key_PageDown:
key = SCK_NEXT;
break;
case Qt::Key_Delete:
key = SCK_DELETE;
break;
case Qt::Key_Insert:
key = SCK_INSERT;
break;
case Qt::Key_Escape:
key = SCK_ESCAPE;
break;
case Qt::Key_Backspace:
key = SCK_BACK;
break;
case Qt::Key_Tab:
key = SCK_TAB;
break;
case Qt::Key_Backtab:
// Scintilla assumes a backtab is shift-tab.
key = SCK_TAB;
modifiers |= SCMOD_SHIFT;
break;
case Qt::Key_Return:
case Qt::Key_Enter:
key = SCK_RETURN;
break;
case Qt::Key_Super_L:
key = SCK_WIN;
break;
case Qt::Key_Super_R:
key = SCK_RWIN;
break;
case Qt::Key_Menu:
key = SCK_MENU;
break;
default:
if ((key = qt_key) > 0x7f)
key = 0;
}
return key;
}
// Encode a QString as bytes.
QsciScintillaBase::ScintillaBytes QsciScintillaBase::textAsBytes(const QString &text) const
{
if (sci->IsUnicodeMode())
return text.toUtf8();
return text.toLatin1();
}
// Decode bytes as a QString.
QString QsciScintillaBase::bytesAsText(const char *bytes) const
{
if (sci->IsUnicodeMode())
return QString::fromUtf8(bytes);
return QString::fromLatin1(bytes);
}
// Handle a mouse button double click.
void QsciScintillaBase::mouseDoubleClickEvent(QMouseEvent *e)
{
if (e->button() != Qt::LeftButton)
{
e->ignore();
return;
}
setFocus();
// Make sure Scintilla will interpret this as a double-click.
unsigned clickTime = sci->lastClickTime + QSCI_SCI_NAMESPACE(Platform)::DoubleClickTime() - 1;
bool shift = e->modifiers() & Qt::ShiftModifier;
bool ctrl = e->modifiers() & Qt::ControlModifier;
bool alt = e->modifiers() & Qt::AltModifier;
sci->ButtonDown(QSCI_SCI_NAMESPACE(Point)(e->x(), e->y()), clickTime,
shift, ctrl, alt);
// Remember the current position and time in case it turns into a triple
// click.
triple_click_at = e->globalPos();
triple_click.start(QApplication::doubleClickInterval());
}
// Handle a mouse move.
void QsciScintillaBase::mouseMoveEvent(QMouseEvent *e)
{
sci->ButtonMove(QSCI_SCI_NAMESPACE(Point)(e->x(), e->y()));
}
// Handle a mouse button press.
void QsciScintillaBase::mousePressEvent(QMouseEvent *e)
{
setFocus();
QSCI_SCI_NAMESPACE(Point) pt(e->x(), e->y());
if (e->button() == Qt::LeftButton)
{
unsigned clickTime;
// It is a triple click if the timer is running and the mouse hasn't
// moved too much.
if (triple_click.isActive() && (e->globalPos() - triple_click_at).manhattanLength() < QApplication::startDragDistance())
clickTime = sci->lastClickTime + QSCI_SCI_NAMESPACE(Platform)::DoubleClickTime() - 1;
else
clickTime = sci->lastClickTime + QSCI_SCI_NAMESPACE(Platform)::DoubleClickTime() + 1;
triple_click.stop();
// Scintilla uses the Alt modifier to initiate rectangular selection.
// However the GTK port (under X11, not Windows) uses the Control
// modifier (by default, although it is configurable). It does this
// because most X11 window managers hijack Alt-drag to move the window.
// We do the same, except that (for the moment at least) we don't allow
// the modifier to be configured.
bool shift = e->modifiers() & Qt::ShiftModifier;
bool ctrl = e->modifiers() & Qt::ControlModifier;
#if defined(Q_OS_MAC) || defined(Q_OS_WIN)
bool alt = e->modifiers() & Qt::AltModifier;
#else
bool alt = ctrl;
#endif
sci->ButtonDown(pt, clickTime, shift, ctrl, alt);
}
else if (e->button() == Qt::MidButton)
{
QClipboard *cb = QApplication::clipboard();
if (cb->supportsSelection())
{
int pos = sci->PositionFromLocation(pt);
sci->sel.Clear();
sci->SetSelection(pos, pos);
sci->pasteFromClipboard(QClipboard::Selection);
}
}
}
// Handle a mouse button releases.
void QsciScintillaBase::mouseReleaseEvent(QMouseEvent *e)
{
if (e->button() != Qt::LeftButton)
return;
QSCI_SCI_NAMESPACE(Point) pt(e->x(), e->y());
if (sci->HaveMouseCapture())
{
bool ctrl = e->modifiers() & Qt::ControlModifier;
sci->ButtonUp(pt, 0, ctrl);
}
#if QT_VERSION >= 0x050000
if (!sci->pdoc->IsReadOnly() && !sci->PointInSelMargin(pt) && qApp->autoSipEnabled())
{
QStyle::RequestSoftwareInputPanel rsip = QStyle::RequestSoftwareInputPanel(style()->styleHint(QStyle::SH_RequestSoftwareInputPanel));
if (!clickCausedFocus || rsip == QStyle::RSIP_OnMouseClick)
qApp->inputMethod()->show();
}
clickCausedFocus = false;
#endif
}
// Handle paint events.
void QsciScintillaBase::paintEvent(QPaintEvent *e)
{
sci->paintEvent(e);
}
// Handle resize events.
void QsciScintillaBase::resizeEvent(QResizeEvent *)
{
sci->ChangeSize();
}
// Re-implemented to suppress the default behaviour as Scintilla works at a
// more fundamental level.
void QsciScintillaBase::scrollContentsBy(int, int)
{
}
// Handle the vertical scrollbar.
void QsciScintillaBase::handleVSb(int value)
{
sci->ScrollTo(value);
}
// Handle the horizontal scrollbar.
void QsciScintillaBase::handleHSb(int value)
{
sci->HorizontalScrollTo(value);
}
// Handle drag enters.
void QsciScintillaBase::dragEnterEvent(QDragEnterEvent *e)
{
QsciScintillaBase::dragMoveEvent(e);
}
// Handle drag leaves.
void QsciScintillaBase::dragLeaveEvent(QDragLeaveEvent *)
{
sci->SetDragPosition(QSCI_SCI_NAMESPACE(SelectionPosition)());
}
// Handle drag moves.
void QsciScintillaBase::dragMoveEvent(QDragMoveEvent *e)
{
sci->SetDragPosition(
sci->SPositionFromLocation(
QSCI_SCI_NAMESPACE(Point)(e->pos().x(), e->pos().y()),
false, false, sci->UserVirtualSpace()));
acceptAction(e);
}
// Handle drops.
void QsciScintillaBase::dropEvent(QDropEvent *e)
{
bool moving;
int len;
const char *s;
bool rectangular;
acceptAction(e);
if (!e->isAccepted())
return;
moving = (e->dropAction() == Qt::MoveAction);
QByteArray text = fromMimeData(e->mimeData(), rectangular);
len = text.length();
s = text.data();
std::string dest = QSCI_SCI_NAMESPACE(Document)::TransformLineEnds(s, len,
sci->pdoc->eolMode);
sci->DropAt(sci->posDrop, dest.c_str(), dest.length(), moving,
rectangular);
sci->Redraw();
}
void QsciScintillaBase::acceptAction(QDropEvent *e)
{
if (sci->pdoc->IsReadOnly() || !canInsertFromMimeData(e->mimeData()))
e->ignore();
else
e->acceptProposedAction();
}
// See if a MIME data object can be decoded.
bool QsciScintillaBase::canInsertFromMimeData(const QMimeData *source) const
{
return source->hasFormat(mimeTextPlain);
}
// Create text from a MIME data object.
QByteArray QsciScintillaBase::fromMimeData(const QMimeData *source, bool &rectangular) const
{
// See if it is rectangular. We try all of the different formats that
// Scintilla supports in case we are working across different platforms.
if (source->hasFormat(mimeRectangularWin))
rectangular = true;
else if (source->hasFormat(mimeRectangular))
rectangular = true;
else
rectangular = false;
// Note that we don't support Scintilla's hack of adding a '\0' as Qt
// strips it off under the covers when pasting from another process.
QString utf8 = source->text();
QByteArray text;
if (sci->IsUnicodeMode())
text = utf8.toUtf8();
else
text = utf8.toLatin1();
return text;
}
// Create a MIME data object for some text.
QMimeData *QsciScintillaBase::toMimeData(const QByteArray &text, bool rectangular) const
{
QMimeData *mime = new QMimeData;
QString utf8;
if (sci->IsUnicodeMode())
utf8 = QString::fromUtf8(text.constData(), text.size());
else
utf8 = QString::fromLatin1(text.constData(), text.size());
mime->setText(utf8);
if (rectangular)
{
// Use the platform specific "standard" for specifying a rectangular
// selection.
#if defined(Q_OS_WIN)
mime->setData(mimeRectangularWin, QByteArray());
#else
mime->setData(mimeRectangular, QByteArray());
#endif
}
return mime;
}
+180
View File
@@ -0,0 +1,180 @@
// This module implements the QsciStyle class.
//
// Copyright (c) 2015 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/qscistyle.h"
#include <qapplication.h>
#include "Qsci/qsciscintillabase.h"
// A ctor.
QsciStyle::QsciStyle(int style)
{
init(style);
QPalette pal = QApplication::palette();
setColor(pal.text().color());
setPaper(pal.base().color());
setFont(QApplication::font());
setEolFill(false);
}
// A ctor.
QsciStyle::QsciStyle(int style, const QString &description,
const QColor &color, const QColor &paper, const QFont &font,
bool eolFill)
{
init(style);
setDescription(description);
setColor(color);
setPaper(paper);
setFont(font);
setEolFill(eolFill);
}
// Initialisation common to all ctors.
void QsciStyle::init(int style)
{
// The next style number to allocate. The initial values corresponds to
// the amount of space that Scintilla initially creates for styles.
static int next_style_nr = 63;
// See if a new style should be allocated. Note that we allow styles to be
// passed in that are bigger than STYLE_MAX because the styles used for
// annotations are allowed to be.
if (style < 0)
{
// Note that we don't deal with the situation where the newly allocated
// style number has already been used explicitly.
if (next_style_nr > QsciScintillaBase::STYLE_LASTPREDEFINED)
style = next_style_nr--;
}
style_nr = style;
// Initialise the minor attributes.
setTextCase(QsciStyle::OriginalCase);
setVisible(true);
setChangeable(true);
setHotspot(false);
}
// Apply the style to a particular editor.
void QsciStyle::apply(QsciScintillaBase *sci) const
{
sci->SendScintilla(QsciScintillaBase::SCI_STYLESETFORE, style_nr,
style_color);
sci->SendScintilla(QsciScintillaBase::SCI_STYLESETBACK, style_nr,
style_paper);
sci->SendScintilla(QsciScintillaBase::SCI_STYLESETFONT, style_nr,
style_font.family().toLatin1().data());
sci->SendScintilla(QsciScintillaBase::SCI_STYLESETSIZEFRACTIONAL, style_nr,
long(style_font.pointSizeF() * QsciScintillaBase::SC_FONT_SIZE_MULTIPLIER));
// Pass the Qt weight via the back door.
sci->SendScintilla(QsciScintillaBase::SCI_STYLESETWEIGHT, style_nr,
-style_font.weight());
sci->SendScintilla(QsciScintillaBase::SCI_STYLESETITALIC, style_nr,
style_font.italic());
sci->SendScintilla(QsciScintillaBase::SCI_STYLESETUNDERLINE, style_nr,
style_font.underline());
sci->SendScintilla(QsciScintillaBase::SCI_STYLESETEOLFILLED, style_nr,
style_eol_fill);
sci->SendScintilla(QsciScintillaBase::SCI_STYLESETCASE, style_nr,
(long)style_case);
sci->SendScintilla(QsciScintillaBase::SCI_STYLESETVISIBLE, style_nr,
style_visible);
sci->SendScintilla(QsciScintillaBase::SCI_STYLESETCHANGEABLE, style_nr,
style_changeable);
sci->SendScintilla(QsciScintillaBase::SCI_STYLESETHOTSPOT, style_nr,
style_hotspot);
}
// Set the color attribute.
void QsciStyle::setColor(const QColor &color)
{
style_color = color;
}
// Set the paper attribute.
void QsciStyle::setPaper(const QColor &paper)
{
style_paper = paper;
}
// Set the font attribute.
void QsciStyle::setFont(const QFont &font)
{
style_font = font;
}
// Set the eol fill attribute.
void QsciStyle::setEolFill(bool eolFill)
{
style_eol_fill = eolFill;
}
// Set the text case attribute.
void QsciStyle::setTextCase(QsciStyle::TextCase text_case)
{
style_case = text_case;
}
// Set the visible attribute.
void QsciStyle::setVisible(bool visible)
{
style_visible = visible;
}
// Set the changeable attribute.
void QsciStyle::setChangeable(bool changeable)
{
style_changeable = changeable;
}
// Set the hotspot attribute.
void QsciStyle::setHotspot(bool hotspot)
{
style_hotspot = hotspot;
}
// Refresh the style. Note that since we had to add apply() then this can't do
// anything useful so we leave it as a no-op.
void QsciStyle::refresh()
{
}
+54
View File
@@ -0,0 +1,54 @@
// This module implements the QsciStyledText class.
//
// Copyright (c) 2015 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/qscistyledtext.h"
#include "Qsci/qsciscintillabase.h"
#include "Qsci/qscistyle.h"
// A ctor.
QsciStyledText::QsciStyledText(const QString &text, int style)
: styled_text(text), style_nr(style), explicit_style(0)
{
}
// A ctor.
QsciStyledText::QsciStyledText(const QString &text, const QsciStyle &style)
: styled_text(text), style_nr(-1)
{
explicit_style = new QsciStyle(style);
}
// Return the number of the style.
int QsciStyledText::style() const
{
return explicit_style ? explicit_style->style() : style_nr;
}
// Apply any explicit style to an editor.
void QsciStyledText::apply(QsciScintillaBase *sci) const
{
if (explicit_style)
explicit_style->apply(sci);
}
+2
View File
@@ -0,0 +1,2 @@
All the documentation for QScintilla for Qt v4 and Qt v5 (including
installation instructions) can be found in doc/html-Qt4Qt5/index.html.
+98
View File
@@ -0,0 +1,98 @@
// Scintilla source code edit control
/** @file ILexer.h
** Interface between Scintilla and lexers.
**/
// Copyright 1998-2010 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
#ifndef ILEXER_H
#define ILEXER_H
#ifdef SCI_NAMESPACE
namespace Scintilla {
#endif
#ifdef _WIN32
#define SCI_METHOD __stdcall
#else
#define SCI_METHOD
#endif
enum { dvOriginal=0, dvLineEnd=1 };
class IDocument {
public:
virtual int SCI_METHOD Version() const = 0;
virtual void SCI_METHOD SetErrorStatus(int status) = 0;
virtual int SCI_METHOD Length() const = 0;
virtual void SCI_METHOD GetCharRange(char *buffer, int position, int lengthRetrieve) const = 0;
virtual char SCI_METHOD StyleAt(int position) const = 0;
virtual int SCI_METHOD LineFromPosition(int position) const = 0;
virtual int SCI_METHOD LineStart(int line) const = 0;
virtual int SCI_METHOD GetLevel(int line) const = 0;
virtual int SCI_METHOD SetLevel(int line, int level) = 0;
virtual int SCI_METHOD GetLineState(int line) const = 0;
virtual int SCI_METHOD SetLineState(int line, int state) = 0;
virtual void SCI_METHOD StartStyling(int position, char mask) = 0;
virtual bool SCI_METHOD SetStyleFor(int length, char style) = 0;
virtual bool SCI_METHOD SetStyles(int length, const char *styles) = 0;
virtual void SCI_METHOD DecorationSetCurrentIndicator(int indicator) = 0;
virtual void SCI_METHOD DecorationFillRange(int position, int value, int fillLength) = 0;
virtual void SCI_METHOD ChangeLexerState(int start, int end) = 0;
virtual int SCI_METHOD CodePage() const = 0;
virtual bool SCI_METHOD IsDBCSLeadByte(char ch) const = 0;
virtual const char * SCI_METHOD BufferPointer() = 0;
virtual int SCI_METHOD GetLineIndentation(int line) = 0;
};
class IDocumentWithLineEnd : public IDocument {
public:
virtual int SCI_METHOD LineEnd(int line) const = 0;
virtual int SCI_METHOD GetRelativePosition(int positionStart, int characterOffset) const = 0;
virtual int SCI_METHOD GetCharacterAndWidth(int position, int *pWidth) const = 0;
};
enum { lvOriginal=0, lvSubStyles=1 };
class ILexer {
public:
virtual int SCI_METHOD Version() const = 0;
virtual void SCI_METHOD Release() = 0;
virtual const char * SCI_METHOD PropertyNames() = 0;
virtual int SCI_METHOD PropertyType(const char *name) = 0;
virtual const char * SCI_METHOD DescribeProperty(const char *name) = 0;
virtual int SCI_METHOD PropertySet(const char *key, const char *val) = 0;
virtual const char * SCI_METHOD DescribeWordListSets() = 0;
virtual int SCI_METHOD WordListSet(int n, const char *wl) = 0;
virtual void SCI_METHOD Lex(unsigned int startPos, int lengthDoc, int initStyle, IDocument *pAccess) = 0;
virtual void SCI_METHOD Fold(unsigned int startPos, int lengthDoc, int initStyle, IDocument *pAccess) = 0;
virtual void * SCI_METHOD PrivateCall(int operation, void *pointer) = 0;
};
class ILexerWithSubStyles : public ILexer {
public:
virtual int SCI_METHOD LineEndTypesSupported() = 0;
virtual int SCI_METHOD AllocateSubStyles(int styleBase, int numberStyles) = 0;
virtual int SCI_METHOD SubStylesStart(int styleBase) = 0;
virtual int SCI_METHOD SubStylesLength(int styleBase) = 0;
virtual int SCI_METHOD StyleFromSubStyle(int subStyle) = 0;
virtual int SCI_METHOD PrimaryStyleFromStyle(int style) = 0;
virtual void SCI_METHOD FreeSubStyles() = 0;
virtual void SCI_METHOD SetIdentifiers(int style, const char *identifiers) = 0;
virtual int SCI_METHOD DistanceToSecondaryStyles() = 0;
virtual const char * SCI_METHOD GetSubStyleBases() = 0;
};
class ILoader {
public:
virtual int SCI_METHOD Release() = 0;
// Returns a status code from SC_STATUS_*
virtual int SCI_METHOD AddData(char *data, int length) = 0;
virtual void * SCI_METHOD ConvertToDocument() = 0;
};
#ifdef SCI_NAMESPACE
}
#endif
#endif
+20
View File
@@ -0,0 +1,20 @@
License for Scintilla and SciTE
Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org>
All Rights Reserved
Permission to use, copy, modify, and distribute this software and its
documentation for any purpose and without fee is hereby granted,
provided that the above copyright notice appear in all copies and that
both that copyright notice and this permission notice appear in
supporting documentation.
NEIL HODGSON DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS, IN NO EVENT SHALL NEIL HODGSON BE LIABLE FOR ANY
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE
OR PERFORMANCE OF THIS SOFTWARE.
+555
View File
@@ -0,0 +1,555 @@
// Scintilla source code edit control
/** @file Platform.h
** Interface to platform facilities. Also includes some basic utilities.
** Implemented in PlatGTK.cxx for GTK+/Linux, PlatWin.cxx for Windows, and PlatWX.cxx for wxWindows.
**/
// Copyright 1998-2009 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
#ifndef PLATFORM_H
#define PLATFORM_H
// PLAT_GTK = GTK+ on Linux or Win32
// PLAT_GTK_WIN32 is defined additionally when running PLAT_GTK under Win32
// PLAT_WIN = Win32 API on Win32 OS
// PLAT_WX is wxWindows on any supported platform
// PLAT_TK = Tcl/TK on Linux or Win32
#define PLAT_GTK 0
#define PLAT_GTK_WIN32 0
#define PLAT_GTK_MACOSX 0
#define PLAT_MACOSX 0
#define PLAT_WIN 0
#define PLAT_WX 0
#define PLAT_QT 0
#define PLAT_FOX 0
#define PLAT_CURSES 0
#define PLAT_TK 0
#if defined(FOX)
#undef PLAT_FOX
#define PLAT_FOX 1
#elif defined(__WX__)
#undef PLAT_WX
#define PLAT_WX 1
#elif defined(CURSES)
#undef PLAT_CURSES
#define PLAT_CURSES 1
#elif defined(SCINTILLA_QT)
#undef PLAT_QT
#define PLAT_QT 1
#include <Qsci/qsciglobal.h>
QT_BEGIN_NAMESPACE
class QPainter;
QT_END_NAMESPACE
// This is needed to work around an HP-UX bug with Qt4.
#include <qnamespace.h>
#elif defined(TK)
#undef PLAT_TK
#define PLAT_TK 1
#elif defined(GTK)
#undef PLAT_GTK
#define PLAT_GTK 1
#if defined(__WIN32__) || defined(_MSC_VER)
#undef PLAT_GTK_WIN32
#define PLAT_GTK_WIN32 1
#endif
#if defined(__APPLE__)
#undef PLAT_GTK_MACOSX
#define PLAT_GTK_MACOSX 1
#endif
#elif defined(__APPLE__)
#undef PLAT_MACOSX
#define PLAT_MACOSX 1
#else
#undef PLAT_WIN
#define PLAT_WIN 1
#endif
#ifdef SCI_NAMESPACE
namespace Scintilla {
#endif
typedef float XYPOSITION;
typedef double XYACCUMULATOR;
inline int RoundXYPosition(XYPOSITION xyPos) {
return int(xyPos + 0.5);
}
// Underlying the implementation of the platform classes are platform specific types.
// Sometimes these need to be passed around by client code so they are defined here
typedef void *FontID;
typedef void *SurfaceID;
typedef void *WindowID;
typedef void *MenuID;
typedef void *TickerID;
typedef void *Function;
typedef void *IdlerID;
/**
* A geometric point class.
* Point is similar to the Win32 POINT and GTK+ GdkPoint types.
*/
class Point {
public:
XYPOSITION x;
XYPOSITION y;
explicit Point(XYPOSITION x_=0, XYPOSITION y_=0) : x(x_), y(y_) {
}
static Point FromInts(int x_, int y_) {
return Point(static_cast<XYPOSITION>(x_), static_cast<XYPOSITION>(y_));
}
// Other automatically defined methods (assignment, copy constructor, destructor) are fine
static Point FromLong(long lpoint);
};
/**
* A geometric rectangle class.
* PRectangle is similar to the Win32 RECT.
* PRectangles contain their top and left sides, but not their right and bottom sides.
*/
class PRectangle {
public:
XYPOSITION left;
XYPOSITION top;
XYPOSITION right;
XYPOSITION bottom;
explicit PRectangle(XYPOSITION left_=0, XYPOSITION top_=0, XYPOSITION right_=0, XYPOSITION bottom_ = 0) :
left(left_), top(top_), right(right_), bottom(bottom_) {
}
static PRectangle FromInts(int left_, int top_, int right_, int bottom_) {
return PRectangle(static_cast<XYPOSITION>(left_), static_cast<XYPOSITION>(top_),
static_cast<XYPOSITION>(right_), static_cast<XYPOSITION>(bottom_));
}
// Other automatically defined methods (assignment, copy constructor, destructor) are fine
bool operator==(PRectangle &rc) const {
return (rc.left == left) && (rc.right == right) &&
(rc.top == top) && (rc.bottom == bottom);
}
bool Contains(Point pt) const {
return (pt.x >= left) && (pt.x <= right) &&
(pt.y >= top) && (pt.y <= bottom);
}
bool ContainsWholePixel(Point pt) const {
// Does the rectangle contain all of the pixel to left/below the point
return (pt.x >= left) && ((pt.x+1) <= right) &&
(pt.y >= top) && ((pt.y+1) <= bottom);
}
bool Contains(PRectangle rc) const {
return (rc.left >= left) && (rc.right <= right) &&
(rc.top >= top) && (rc.bottom <= bottom);
}
bool Intersects(PRectangle other) const {
return (right > other.left) && (left < other.right) &&
(bottom > other.top) && (top < other.bottom);
}
void Move(XYPOSITION xDelta, XYPOSITION yDelta) {
left += xDelta;
top += yDelta;
right += xDelta;
bottom += yDelta;
}
XYPOSITION Width() const { return right - left; }
XYPOSITION Height() const { return bottom - top; }
bool Empty() const {
return (Height() <= 0) || (Width() <= 0);
}
};
/**
* Holds a desired RGB colour.
*/
class ColourDesired {
long co;
public:
ColourDesired(long lcol=0) {
co = lcol;
}
ColourDesired(unsigned int red, unsigned int green, unsigned int blue) {
Set(red, green, blue);
}
bool operator==(const ColourDesired &other) const {
return co == other.co;
}
void Set(long lcol) {
co = lcol;
}
void Set(unsigned int red, unsigned int green, unsigned int blue) {
co = red | (green << 8) | (blue << 16);
}
static inline unsigned int ValueOfHex(const char ch) {
if (ch >= '0' && ch <= '9')
return ch - '0';
else if (ch >= 'A' && ch <= 'F')
return ch - 'A' + 10;
else if (ch >= 'a' && ch <= 'f')
return ch - 'a' + 10;
else
return 0;
}
void Set(const char *val) {
if (*val == '#') {
val++;
}
unsigned int r = ValueOfHex(val[0]) * 16 + ValueOfHex(val[1]);
unsigned int g = ValueOfHex(val[2]) * 16 + ValueOfHex(val[3]);
unsigned int b = ValueOfHex(val[4]) * 16 + ValueOfHex(val[5]);
Set(r, g, b);
}
long AsLong() const {
return co;
}
unsigned int GetRed() const {
return co & 0xff;
}
unsigned int GetGreen() const {
return (co >> 8) & 0xff;
}
unsigned int GetBlue() const {
return (co >> 16) & 0xff;
}
};
/**
* Font management.
*/
struct FontParameters {
const char *faceName;
float size;
int weight;
bool italic;
int extraFontFlag;
int technology;
int characterSet;
FontParameters(
const char *faceName_,
float size_=10,
int weight_=400,
bool italic_=false,
int extraFontFlag_=0,
int technology_=0,
int characterSet_=0) :
faceName(faceName_),
size(size_),
weight(weight_),
italic(italic_),
extraFontFlag(extraFontFlag_),
technology(technology_),
characterSet(characterSet_)
{
}
};
class Font {
protected:
FontID fid;
#if PLAT_WX
int ascent;
#endif
// Private so Font objects can not be copied
Font(const Font &);
Font &operator=(const Font &);
public:
Font();
virtual ~Font();
virtual void Create(const FontParameters &fp);
virtual void Release();
FontID GetID() { return fid; }
// Alias another font - caller guarantees not to Release
void SetID(FontID fid_) { fid = fid_; }
#if PLAT_WX
void SetAscent(int ascent_) { ascent = ascent_; }
#endif
friend class Surface;
friend class SurfaceImpl;
};
/**
* A surface abstracts a place to draw.
*/
#if defined(PLAT_QT)
class XPM;
#endif
class Surface {
private:
// Private so Surface objects can not be copied
Surface(const Surface &) {}
Surface &operator=(const Surface &) { return *this; }
public:
Surface() {}
virtual ~Surface() {}
static Surface *Allocate(int technology);
virtual void Init(WindowID wid)=0;
virtual void Init(SurfaceID sid, WindowID wid)=0;
virtual void InitPixMap(int width, int height, Surface *surface_, WindowID wid)=0;
virtual void Release()=0;
virtual bool Initialised()=0;
virtual void PenColour(ColourDesired fore)=0;
virtual int LogPixelsY()=0;
virtual int DeviceHeightFont(int points)=0;
virtual void MoveTo(int x_, int y_)=0;
virtual void LineTo(int x_, int y_)=0;
virtual void Polygon(Point *pts, int npts, ColourDesired fore, ColourDesired back)=0;
virtual void RectangleDraw(PRectangle rc, ColourDesired fore, ColourDesired back)=0;
virtual void FillRectangle(PRectangle rc, ColourDesired back)=0;
virtual void FillRectangle(PRectangle rc, Surface &surfacePattern)=0;
virtual void RoundedRectangle(PRectangle rc, ColourDesired fore, ColourDesired back)=0;
virtual void AlphaRectangle(PRectangle rc, int cornerSize, ColourDesired fill, int alphaFill,
ColourDesired outline, int alphaOutline, int flags)=0;
virtual void DrawRGBAImage(PRectangle rc, int width, int height, const unsigned char *pixelsImage) = 0;
virtual void Ellipse(PRectangle rc, ColourDesired fore, ColourDesired back)=0;
virtual void Copy(PRectangle rc, Point from, Surface &surfaceSource)=0;
virtual void DrawTextNoClip(PRectangle rc, Font &font_, XYPOSITION ybase, const char *s, int len, ColourDesired fore, ColourDesired back)=0;
virtual void DrawTextClipped(PRectangle rc, Font &font_, XYPOSITION ybase, const char *s, int len, ColourDesired fore, ColourDesired back)=0;
virtual void DrawTextTransparent(PRectangle rc, Font &font_, XYPOSITION ybase, const char *s, int len, ColourDesired fore)=0;
virtual void MeasureWidths(Font &font_, const char *s, int len, XYPOSITION *positions)=0;
virtual XYPOSITION WidthText(Font &font_, const char *s, int len)=0;
virtual XYPOSITION WidthChar(Font &font_, char ch)=0;
virtual XYPOSITION Ascent(Font &font_)=0;
virtual XYPOSITION Descent(Font &font_)=0;
virtual XYPOSITION InternalLeading(Font &font_)=0;
virtual XYPOSITION ExternalLeading(Font &font_)=0;
virtual XYPOSITION Height(Font &font_)=0;
virtual XYPOSITION AverageCharWidth(Font &font_)=0;
virtual void SetClip(PRectangle rc)=0;
virtual void FlushCachedState()=0;
virtual void SetUnicodeMode(bool unicodeMode_)=0;
virtual void SetDBCSMode(int codePage)=0;
#if defined(PLAT_QT)
virtual void Init(QPainter *p)=0;
virtual void DrawXPM(PRectangle rc, const XPM *xpm)=0;
#endif
};
/**
* A simple callback action passing one piece of untyped user data.
*/
typedef void (*CallBackAction)(void*);
/**
* Class to hide the details of window manipulation.
* Does not own the window which will normally have a longer life than this object.
*/
class Window {
protected:
WindowID wid;
public:
Window() : wid(0), cursorLast(cursorInvalid) {
}
Window(const Window &source) : wid(source.wid), cursorLast(cursorInvalid) {
}
virtual ~Window();
Window &operator=(WindowID wid_) {
wid = wid_;
return *this;
}
WindowID GetID() const { return wid; }
bool Created() const { return wid != 0; }
void Destroy();
bool HasFocus();
PRectangle GetPosition();
void SetPosition(PRectangle rc);
void SetPositionRelative(PRectangle rc, Window relativeTo);
PRectangle GetClientPosition();
void Show(bool show=true);
void InvalidateAll();
void InvalidateRectangle(PRectangle rc);
virtual void SetFont(Font &font);
enum Cursor { cursorInvalid, cursorText, cursorArrow, cursorUp, cursorWait, cursorHoriz, cursorVert, cursorReverseArrow, cursorHand };
void SetCursor(Cursor curs);
void SetTitle(const char *s);
PRectangle GetMonitorRect(Point pt);
private:
Cursor cursorLast;
};
/**
* Listbox management.
*/
class ListBox : public Window {
public:
ListBox();
virtual ~ListBox();
static ListBox *Allocate();
virtual void SetFont(Font &font)=0;
virtual void Create(Window &parent, int ctrlID, Point location, int lineHeight_, bool unicodeMode_, int technology_)=0;
virtual void SetAverageCharWidth(int width)=0;
virtual void SetVisibleRows(int rows)=0;
virtual int GetVisibleRows() const=0;
virtual PRectangle GetDesiredRect()=0;
virtual int CaretFromEdge()=0;
virtual void Clear()=0;
virtual void Append(char *s, int type = -1)=0;
virtual int Length()=0;
virtual void Select(int n)=0;
virtual int GetSelection()=0;
virtual int Find(const char *prefix)=0;
virtual void GetValue(int n, char *value, int len)=0;
virtual void RegisterImage(int type, const char *xpm_data)=0;
virtual void RegisterRGBAImage(int type, int width, int height, const unsigned char *pixelsImage) = 0;
virtual void ClearRegisteredImages()=0;
virtual void SetDoubleClickAction(CallBackAction, void *)=0;
virtual void SetList(const char* list, char separator, char typesep)=0;
};
/**
* Menu management.
*/
class Menu {
MenuID mid;
public:
Menu();
MenuID GetID() { return mid; }
void CreatePopUp();
void Destroy();
void Show(Point pt, Window &w);
};
class ElapsedTime {
long bigBit;
long littleBit;
public:
ElapsedTime();
double Duration(bool reset=false);
};
/**
* Dynamic Library (DLL/SO/...) loading
*/
class DynamicLibrary {
public:
virtual ~DynamicLibrary() {}
/// @return Pointer to function "name", or NULL on failure.
virtual Function FindFunction(const char *name) = 0;
/// @return true if the library was loaded successfully.
virtual bool IsValid() = 0;
/// @return An instance of a DynamicLibrary subclass with "modulePath" loaded.
static DynamicLibrary *Load(const char *modulePath);
};
#if defined(__clang__)
# if __has_feature(attribute_analyzer_noreturn)
# define CLANG_ANALYZER_NORETURN __attribute__((analyzer_noreturn))
# else
# define CLANG_ANALYZER_NORETURN
# endif
#else
# define CLANG_ANALYZER_NORETURN
#endif
/**
* Platform class used to retrieve system wide parameters such as double click speed
* and chrome colour. Not a creatable object, more of a module with several functions.
*/
class Platform {
// Private so Platform objects can not be copied
Platform(const Platform &) {}
Platform &operator=(const Platform &) { return *this; }
public:
// Should be private because no new Platforms are ever created
// but gcc warns about this
Platform() {}
~Platform() {}
static ColourDesired Chrome();
static ColourDesired ChromeHighlight();
static const char *DefaultFont();
static int DefaultFontSize();
static unsigned int DoubleClickTime();
static bool MouseButtonBounce();
static void DebugDisplay(const char *s);
static bool IsKeyDown(int key);
static long SendScintilla(
WindowID w, unsigned int msg, unsigned long wParam=0, long lParam=0);
static long SendScintillaPointer(
WindowID w, unsigned int msg, unsigned long wParam=0, void *lParam=0);
static bool IsDBCSLeadByte(int codePage, char ch);
static int DBCSCharLength(int codePage, const char *s);
static int DBCSCharMaxLength();
// These are utility functions not really tied to a platform
static int Minimum(int a, int b);
static int Maximum(int a, int b);
// Next three assume 16 bit shorts and 32 bit longs
static long LongFromTwoShorts(short a,short b) {
return (a) | ((b) << 16);
}
static short HighShortFromLong(long x) {
return static_cast<short>(x >> 16);
}
static short LowShortFromLong(long x) {
return static_cast<short>(x & 0xffff);
}
static void DebugPrintf(const char *format, ...);
static bool ShowAssertionPopUps(bool assertionPopUps_);
static void Assert(const char *c, const char *file, int line) CLANG_ANALYZER_NORETURN;
static int Clamp(int val, int minVal, int maxVal);
};
#ifdef NDEBUG
#define PLATFORM_ASSERT(c) ((void)0)
#else
#ifdef SCI_NAMESPACE
#define PLATFORM_ASSERT(c) ((c) ? (void)(0) : Scintilla::Platform::Assert(#c, __FILE__, __LINE__))
#else
#define PLATFORM_ASSERT(c) ((c) ? (void)(0) : Platform::Assert(#c, __FILE__, __LINE__))
#endif
#endif
#ifdef SCI_NAMESPACE
}
#endif
#if defined(__GNUC__) && defined(SCINTILLA_QT)
#pragma GCC diagnostic ignored "-Wmissing-field-initializers"
#endif
#endif
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+51
View File
@@ -0,0 +1,51 @@
/* Scintilla source code edit control */
/** @file ScintillaWidget.h
** Definition of Scintilla widget for GTK+.
** Only needed by GTK+ code but is harmless on other platforms.
**/
/* Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>
* The License.txt file describes the conditions under which this software may be distributed. */
#ifndef SCINTILLAWIDGET_H
#define SCINTILLAWIDGET_H
#if defined(GTK)
#ifdef __cplusplus
extern "C" {
#endif
#define SCINTILLA(obj) G_TYPE_CHECK_INSTANCE_CAST (obj, scintilla_get_type (), ScintillaObject)
#define SCINTILLA_CLASS(klass) G_TYPE_CHECK_CLASS_CAST (klass, scintilla_get_type (), ScintillaClass)
#define IS_SCINTILLA(obj) G_TYPE_CHECK_INSTANCE_TYPE (obj, scintilla_get_type ())
typedef struct _ScintillaObject ScintillaObject;
typedef struct _ScintillaClass ScintillaClass;
struct _ScintillaObject {
GtkContainer cont;
void *pscin;
};
struct _ScintillaClass {
GtkContainerClass parent_class;
void (* command) (ScintillaObject *ttt);
void (* notify) (ScintillaObject *ttt);
};
GType scintilla_get_type (void);
GtkWidget* scintilla_new (void);
void scintilla_set_id (ScintillaObject *sci, uptr_t id);
sptr_t scintilla_send_message (ScintillaObject *sci,unsigned int iMessage, uptr_t wParam, sptr_t lParam);
void scintilla_release_resources(void);
#define SCINTILLA_NOTIFY "sci-notify"
#ifdef __cplusplus
}
#endif
#endif
#endif
+967
View File
@@ -0,0 +1,967 @@
//-*- coding: utf-8 -*-
// Scintilla source code edit control
/** @file LexSQL.cxx
** Lexer for SQL, including PL/SQL and SQL*Plus.
** Improved by Jérôme LAFORGE <jerome.laforge_AT_gmail_DOT_com> from 2010 to 2012.
**/
// Copyright 1998-2012 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <stdarg.h>
#include <assert.h>
#include <ctype.h>
#include <string>
#include <vector>
#include <map>
#include <algorithm>
#include "ILexer.h"
#include "Scintilla.h"
#include "SciLexer.h"
#include "WordList.h"
#include "LexAccessor.h"
#include "Accessor.h"
#include "StyleContext.h"
#include "CharacterSet.h"
#include "LexerModule.h"
#include "OptionSet.h"
#include "SparseState.h"
#ifdef SCI_NAMESPACE
using namespace Scintilla;
#endif
static inline bool IsAWordChar(int ch, bool sqlAllowDottedWord) {
if (!sqlAllowDottedWord)
return (ch < 0x80) && (isalnum(ch) || ch == '_');
else
return (ch < 0x80) && (isalnum(ch) || ch == '_' || ch == '.');
}
static inline bool IsAWordStart(int ch) {
return (ch < 0x80) && (isalpha(ch) || ch == '_');
}
static inline bool IsADoxygenChar(int ch) {
return (islower(ch) || ch == '$' || ch == '@' ||
ch == '\\' || ch == '&' || ch == '<' ||
ch == '>' || ch == '#' || ch == '{' ||
ch == '}' || ch == '[' || ch == ']');
}
static inline bool IsANumberChar(int ch) {
// Not exactly following number definition (several dots are seen as OK, etc.)
// but probably enough in most cases.
return (ch < 0x80) &&
(isdigit(ch) || toupper(ch) == 'E' ||
ch == '.' || ch == '-' || ch == '+');
}
typedef unsigned int sql_state_t;
class SQLStates {
public :
void Set(int lineNumber, unsigned short int sqlStatesLine) {
sqlStatement.Set(lineNumber, sqlStatesLine);
}
sql_state_t IgnoreWhen (sql_state_t sqlStatesLine, bool enable) {
if (enable)
sqlStatesLine |= MASK_IGNORE_WHEN;
else
sqlStatesLine &= ~MASK_IGNORE_WHEN;
return sqlStatesLine;
}
sql_state_t IntoCondition (sql_state_t sqlStatesLine, bool enable) {
if (enable)
sqlStatesLine |= MASK_INTO_CONDITION;
else
sqlStatesLine &= ~MASK_INTO_CONDITION;
return sqlStatesLine;
}
sql_state_t IntoExceptionBlock (sql_state_t sqlStatesLine, bool enable) {
if (enable)
sqlStatesLine |= MASK_INTO_EXCEPTION;
else
sqlStatesLine &= ~MASK_INTO_EXCEPTION;
return sqlStatesLine;
}
sql_state_t IntoDeclareBlock (sql_state_t sqlStatesLine, bool enable) {
if (enable)
sqlStatesLine |= MASK_INTO_DECLARE;
else
sqlStatesLine &= ~MASK_INTO_DECLARE;
return sqlStatesLine;
}
sql_state_t IntoMergeStatement (sql_state_t sqlStatesLine, bool enable) {
if (enable)
sqlStatesLine |= MASK_MERGE_STATEMENT;
else
sqlStatesLine &= ~MASK_MERGE_STATEMENT;
return sqlStatesLine;
}
sql_state_t CaseMergeWithoutWhenFound (sql_state_t sqlStatesLine, bool found) {
if (found)
sqlStatesLine |= MASK_CASE_MERGE_WITHOUT_WHEN_FOUND;
else
sqlStatesLine &= ~MASK_CASE_MERGE_WITHOUT_WHEN_FOUND;
return sqlStatesLine;
}
sql_state_t IntoSelectStatementOrAssignment (sql_state_t sqlStatesLine, bool found) {
if (found)
sqlStatesLine |= MASK_INTO_SELECT_STATEMENT_OR_ASSIGNEMENT;
else
sqlStatesLine &= ~MASK_INTO_SELECT_STATEMENT_OR_ASSIGNEMENT;
return sqlStatesLine;
}
sql_state_t BeginCaseBlock (sql_state_t sqlStatesLine) {
if ((sqlStatesLine & MASK_NESTED_CASES) < MASK_NESTED_CASES) {
sqlStatesLine++;
}
return sqlStatesLine;
}
sql_state_t EndCaseBlock (sql_state_t sqlStatesLine) {
if ((sqlStatesLine & MASK_NESTED_CASES) > 0) {
sqlStatesLine--;
}
return sqlStatesLine;
}
sql_state_t IntoCreateStatement (sql_state_t sqlStatesLine, bool enable) {
if (enable)
sqlStatesLine |= MASK_INTO_CREATE;
else
sqlStatesLine &= ~MASK_INTO_CREATE;
return sqlStatesLine;
}
sql_state_t IntoCreateViewStatement (sql_state_t sqlStatesLine, bool enable) {
if (enable)
sqlStatesLine |= MASK_INTO_CREATE_VIEW;
else
sqlStatesLine &= ~MASK_INTO_CREATE_VIEW;
return sqlStatesLine;
}
sql_state_t IntoCreateViewAsStatement (sql_state_t sqlStatesLine, bool enable) {
if (enable)
sqlStatesLine |= MASK_INTO_CREATE_VIEW_AS_STATEMENT;
else
sqlStatesLine &= ~MASK_INTO_CREATE_VIEW_AS_STATEMENT;
return sqlStatesLine;
}
bool IsIgnoreWhen (sql_state_t sqlStatesLine) {
return (sqlStatesLine & MASK_IGNORE_WHEN) != 0;
}
bool IsIntoCondition (sql_state_t sqlStatesLine) {
return (sqlStatesLine & MASK_INTO_CONDITION) != 0;
}
bool IsIntoCaseBlock (sql_state_t sqlStatesLine) {
return (sqlStatesLine & MASK_NESTED_CASES) != 0;
}
bool IsIntoExceptionBlock (sql_state_t sqlStatesLine) {
return (sqlStatesLine & MASK_INTO_EXCEPTION) != 0;
}
bool IsIntoSelectStatementOrAssignment (sql_state_t sqlStatesLine) {
return (sqlStatesLine & MASK_INTO_SELECT_STATEMENT_OR_ASSIGNEMENT) != 0;
}
bool IsCaseMergeWithoutWhenFound (sql_state_t sqlStatesLine) {
return (sqlStatesLine & MASK_CASE_MERGE_WITHOUT_WHEN_FOUND) != 0;
}
bool IsIntoDeclareBlock (sql_state_t sqlStatesLine) {
return (sqlStatesLine & MASK_INTO_DECLARE) != 0;
}
bool IsIntoMergeStatement (sql_state_t sqlStatesLine) {
return (sqlStatesLine & MASK_MERGE_STATEMENT) != 0;
}
bool IsIntoCreateStatement (sql_state_t sqlStatesLine) {
return (sqlStatesLine & MASK_INTO_CREATE) != 0;
}
bool IsIntoCreateViewStatement (sql_state_t sqlStatesLine) {
return (sqlStatesLine & MASK_INTO_CREATE_VIEW) != 0;
}
bool IsIntoCreateViewAsStatement (sql_state_t sqlStatesLine) {
return (sqlStatesLine & MASK_INTO_CREATE_VIEW_AS_STATEMENT) != 0;
}
sql_state_t ForLine(int lineNumber) {
return sqlStatement.ValueAt(lineNumber);
}
SQLStates() {}
private :
SparseState <sql_state_t> sqlStatement;
enum {
MASK_NESTED_CASES = 0x0001FF,
MASK_INTO_SELECT_STATEMENT_OR_ASSIGNEMENT = 0x000200,
MASK_CASE_MERGE_WITHOUT_WHEN_FOUND = 0x000400,
MASK_MERGE_STATEMENT = 0x000800,
MASK_INTO_DECLARE = 0x001000,
MASK_INTO_EXCEPTION = 0x002000,
MASK_INTO_CONDITION = 0x004000,
MASK_IGNORE_WHEN = 0x008000,
MASK_INTO_CREATE = 0x010000,
MASK_INTO_CREATE_VIEW = 0x020000,
MASK_INTO_CREATE_VIEW_AS_STATEMENT = 0x040000
};
};
// Options used for LexerSQL
struct OptionsSQL {
bool fold;
bool foldAtElse;
bool foldComment;
bool foldCompact;
bool foldOnlyBegin;
bool sqlBackticksIdentifier;
bool sqlNumbersignComment;
bool sqlBackslashEscapes;
bool sqlAllowDottedWord;
OptionsSQL() {
fold = false;
foldAtElse = false;
foldComment = false;
foldCompact = false;
foldOnlyBegin = false;
sqlBackticksIdentifier = false;
sqlNumbersignComment = false;
sqlBackslashEscapes = false;
sqlAllowDottedWord = false;
}
};
static const char * const sqlWordListDesc[] = {
"Keywords",
"Database Objects",
"PLDoc",
"SQL*Plus",
"User Keywords 1",
"User Keywords 2",
"User Keywords 3",
"User Keywords 4",
0
};
struct OptionSetSQL : public OptionSet<OptionsSQL> {
OptionSetSQL() {
DefineProperty("fold", &OptionsSQL::fold);
DefineProperty("fold.sql.at.else", &OptionsSQL::foldAtElse,
"This option enables SQL folding on a \"ELSE\" and \"ELSIF\" line of an IF statement.");
DefineProperty("fold.comment", &OptionsSQL::foldComment);
DefineProperty("fold.compact", &OptionsSQL::foldCompact);
DefineProperty("fold.sql.only.begin", &OptionsSQL::foldOnlyBegin);
DefineProperty("lexer.sql.backticks.identifier", &OptionsSQL::sqlBackticksIdentifier);
DefineProperty("lexer.sql.numbersign.comment", &OptionsSQL::sqlNumbersignComment,
"If \"lexer.sql.numbersign.comment\" property is set to 0 a line beginning with '#' will not be a comment.");
DefineProperty("sql.backslash.escapes", &OptionsSQL::sqlBackslashEscapes,
"Enables backslash as an escape character in SQL.");
DefineProperty("lexer.sql.allow.dotted.word", &OptionsSQL::sqlAllowDottedWord,
"Set to 1 to colourise recognized words with dots "
"(recommended for Oracle PL/SQL objects).");
DefineWordListSets(sqlWordListDesc);
}
};
class LexerSQL : public ILexer {
public :
LexerSQL() {}
virtual ~LexerSQL() {}
int SCI_METHOD Version () const {
return lvOriginal;
}
void SCI_METHOD Release() {
delete this;
}
const char * SCI_METHOD PropertyNames() {
return osSQL.PropertyNames();
}
int SCI_METHOD PropertyType(const char *name) {
return osSQL.PropertyType(name);
}
const char * SCI_METHOD DescribeProperty(const char *name) {
return osSQL.DescribeProperty(name);
}
int SCI_METHOD PropertySet(const char *key, const char *val) {
if (osSQL.PropertySet(&options, key, val)) {
return 0;
}
return -1;
}
const char * SCI_METHOD DescribeWordListSets() {
return osSQL.DescribeWordListSets();
}
int SCI_METHOD WordListSet(int n, const char *wl);
void SCI_METHOD Lex (unsigned int startPos, int lengthDoc, int initStyle, IDocument *pAccess);
void SCI_METHOD Fold(unsigned int startPos, int lengthDoc, int initStyle, IDocument *pAccess);
void * SCI_METHOD PrivateCall(int, void *) {
return 0;
}
static ILexer *LexerFactorySQL() {
return new LexerSQL();
}
private:
bool IsStreamCommentStyle(int style) {
return style == SCE_SQL_COMMENT ||
style == SCE_SQL_COMMENTDOC ||
style == SCE_SQL_COMMENTDOCKEYWORD ||
style == SCE_SQL_COMMENTDOCKEYWORDERROR;
}
bool IsCommentStyle (int style) {
switch (style) {
case SCE_SQL_COMMENT :
case SCE_SQL_COMMENTDOC :
case SCE_SQL_COMMENTLINE :
case SCE_SQL_COMMENTLINEDOC :
case SCE_SQL_COMMENTDOCKEYWORD :
case SCE_SQL_COMMENTDOCKEYWORDERROR :
return true;
default :
return false;
}
}
bool IsCommentLine (int line, LexAccessor &styler) {
int pos = styler.LineStart(line);
int eol_pos = styler.LineStart(line + 1) - 1;
for (int i = pos; i + 1 < eol_pos; i++) {
int style = styler.StyleAt(i);
// MySQL needs -- comments to be followed by space or control char
if (style == SCE_SQL_COMMENTLINE && styler.Match(i, "--"))
return true;
else if (!IsASpaceOrTab(styler[i]))
return false;
}
return false;
}
OptionsSQL options;
OptionSetSQL osSQL;
SQLStates sqlStates;
WordList keywords1;
WordList keywords2;
WordList kw_pldoc;
WordList kw_sqlplus;
WordList kw_user1;
WordList kw_user2;
WordList kw_user3;
WordList kw_user4;
};
int SCI_METHOD LexerSQL::WordListSet(int n, const char *wl) {
WordList *wordListN = 0;
switch (n) {
case 0:
wordListN = &keywords1;
break;
case 1:
wordListN = &keywords2;
break;
case 2:
wordListN = &kw_pldoc;
break;
case 3:
wordListN = &kw_sqlplus;
break;
case 4:
wordListN = &kw_user1;
break;
case 5:
wordListN = &kw_user2;
break;
case 6:
wordListN = &kw_user3;
break;
case 7:
wordListN = &kw_user4;
}
int firstModification = -1;
if (wordListN) {
WordList wlNew;
wlNew.Set(wl);
if (*wordListN != wlNew) {
wordListN->Set(wl);
firstModification = 0;
}
}
return firstModification;
}
void SCI_METHOD LexerSQL::Lex(unsigned int startPos, int length, int initStyle, IDocument *pAccess) {
LexAccessor styler(pAccess);
StyleContext sc(startPos, length, initStyle, styler);
int styleBeforeDCKeyword = SCE_SQL_DEFAULT;
int offset = 0;
for (; sc.More(); sc.Forward(), offset++) {
// Determine if the current state should terminate.
switch (sc.state) {
case SCE_SQL_OPERATOR:
sc.SetState(SCE_SQL_DEFAULT);
break;
case SCE_SQL_NUMBER:
// We stop the number definition on non-numerical non-dot non-eE non-sign char
if (!IsANumberChar(sc.ch)) {
sc.SetState(SCE_SQL_DEFAULT);
}
break;
case SCE_SQL_IDENTIFIER:
if (!IsAWordChar(sc.ch, options.sqlAllowDottedWord)) {
int nextState = SCE_SQL_DEFAULT;
char s[1000];
sc.GetCurrentLowered(s, sizeof(s));
if (keywords1.InList(s)) {
sc.ChangeState(SCE_SQL_WORD);
} else if (keywords2.InList(s)) {
sc.ChangeState(SCE_SQL_WORD2);
} else if (kw_sqlplus.InListAbbreviated(s, '~')) {
sc.ChangeState(SCE_SQL_SQLPLUS);
if (strncmp(s, "rem", 3) == 0) {
nextState = SCE_SQL_SQLPLUS_COMMENT;
} else if (strncmp(s, "pro", 3) == 0) {
nextState = SCE_SQL_SQLPLUS_PROMPT;
}
} else if (kw_user1.InList(s)) {
sc.ChangeState(SCE_SQL_USER1);
} else if (kw_user2.InList(s)) {
sc.ChangeState(SCE_SQL_USER2);
} else if (kw_user3.InList(s)) {
sc.ChangeState(SCE_SQL_USER3);
} else if (kw_user4.InList(s)) {
sc.ChangeState(SCE_SQL_USER4);
}
sc.SetState(nextState);
}
break;
case SCE_SQL_QUOTEDIDENTIFIER:
if (sc.ch == 0x60) {
if (sc.chNext == 0x60) {
sc.Forward(); // Ignore it
} else {
sc.ForwardSetState(SCE_SQL_DEFAULT);
}
}
break;
case SCE_SQL_COMMENT:
if (sc.Match('*', '/')) {
sc.Forward();
sc.ForwardSetState(SCE_SQL_DEFAULT);
}
break;
case SCE_SQL_COMMENTDOC:
if (sc.Match('*', '/')) {
sc.Forward();
sc.ForwardSetState(SCE_SQL_DEFAULT);
} else if (sc.ch == '@' || sc.ch == '\\') { // Doxygen support
// Verify that we have the conditions to mark a comment-doc-keyword
if ((IsASpace(sc.chPrev) || sc.chPrev == '*') && (!IsASpace(sc.chNext))) {
styleBeforeDCKeyword = SCE_SQL_COMMENTDOC;
sc.SetState(SCE_SQL_COMMENTDOCKEYWORD);
}
}
break;
case SCE_SQL_COMMENTLINE:
case SCE_SQL_COMMENTLINEDOC:
case SCE_SQL_SQLPLUS_COMMENT:
case SCE_SQL_SQLPLUS_PROMPT:
if (sc.atLineStart) {
sc.SetState(SCE_SQL_DEFAULT);
}
break;
case SCE_SQL_COMMENTDOCKEYWORD:
if ((styleBeforeDCKeyword == SCE_SQL_COMMENTDOC) && sc.Match('*', '/')) {
sc.ChangeState(SCE_SQL_COMMENTDOCKEYWORDERROR);
sc.Forward();
sc.ForwardSetState(SCE_SQL_DEFAULT);
} else if (!IsADoxygenChar(sc.ch)) {
char s[100];
sc.GetCurrentLowered(s, sizeof(s));
if (!isspace(sc.ch) || !kw_pldoc.InList(s + 1)) {
sc.ChangeState(SCE_SQL_COMMENTDOCKEYWORDERROR);
}
sc.SetState(styleBeforeDCKeyword);
}
break;
case SCE_SQL_CHARACTER:
if (options.sqlBackslashEscapes && sc.ch == '\\') {
sc.Forward();
} else if (sc.ch == '\'') {
if (sc.chNext == '\"') {
sc.Forward();
} else {
sc.ForwardSetState(SCE_SQL_DEFAULT);
}
}
break;
case SCE_SQL_STRING:
if (sc.ch == '\\') {
// Escape sequence
sc.Forward();
} else if (sc.ch == '\"') {
if (sc.chNext == '\"') {
sc.Forward();
} else {
sc.ForwardSetState(SCE_SQL_DEFAULT);
}
}
break;
case SCE_SQL_QOPERATOR:
// Locate the unique Q operator character
sc.Complete();
char qOperator = 0x00;
for (int styleStartPos = sc.currentPos; styleStartPos > 0; --styleStartPos) {
if (styler.StyleAt(styleStartPos - 1) != SCE_SQL_QOPERATOR) {
qOperator = styler.SafeGetCharAt(styleStartPos + 2);
break;
}
}
char qComplement = 0x00;
if (qOperator == '<') {
qComplement = '>';
} else if (qOperator == '(') {
qComplement = ')';
} else if (qOperator == '{') {
qComplement = '}';
} else if (qOperator == '[') {
qComplement = ']';
} else {
qComplement = qOperator;
}
if (sc.Match(qComplement, '\'')) {
sc.Forward();
sc.ForwardSetState(SCE_SQL_DEFAULT);
}
break;
}
// Determine if a new state should be entered.
if (sc.state == SCE_SQL_DEFAULT) {
if (sc.Match('q', '\'') || sc.Match('Q', '\'')) {
sc.SetState(SCE_SQL_QOPERATOR);
sc.Forward();
} else if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {
sc.SetState(SCE_SQL_NUMBER);
} else if (IsAWordStart(sc.ch)) {
sc.SetState(SCE_SQL_IDENTIFIER);
} else if (sc.ch == 0x60 && options.sqlBackticksIdentifier) {
sc.SetState(SCE_SQL_QUOTEDIDENTIFIER);
} else if (sc.Match('/', '*')) {
if (sc.Match("/**") || sc.Match("/*!")) { // Support of Doxygen doc. style
sc.SetState(SCE_SQL_COMMENTDOC);
} else {
sc.SetState(SCE_SQL_COMMENT);
}
sc.Forward(); // Eat the * so it isn't used for the end of the comment
} else if (sc.Match('-', '-')) {
// MySQL requires a space or control char after --
// http://dev.mysql.com/doc/mysql/en/ansi-diff-comments.html
// Perhaps we should enforce that with proper property:
//~ } else if (sc.Match("-- ")) {
sc.SetState(SCE_SQL_COMMENTLINE);
} else if (sc.ch == '#' && options.sqlNumbersignComment) {
sc.SetState(SCE_SQL_COMMENTLINEDOC);
} else if (sc.ch == '\'') {
sc.SetState(SCE_SQL_CHARACTER);
} else if (sc.ch == '\"') {
sc.SetState(SCE_SQL_STRING);
} else if (isoperator(static_cast<char>(sc.ch))) {
sc.SetState(SCE_SQL_OPERATOR);
}
}
}
sc.Complete();
}
void SCI_METHOD LexerSQL::Fold(unsigned int startPos, int length, int initStyle, IDocument *pAccess) {
if (!options.fold)
return;
LexAccessor styler(pAccess);
unsigned int endPos = startPos + length;
int visibleChars = 0;
int lineCurrent = styler.GetLine(startPos);
int levelCurrent = SC_FOLDLEVELBASE;
if (lineCurrent > 0) {
// Backtrack to previous line in case need to fix its fold status for folding block of single-line comments (i.e. '--').
int lastNLPos = -1;
// And keep going back until we find an operator ';' followed
// by white-space and/or comments. This will improve folding.
while (--startPos > 0) {
char ch = styler[startPos];
if (ch == '\n' || (ch == '\r' && styler[startPos + 1] != '\n')) {
lastNLPos = startPos;
} else if (ch == ';' &&
styler.StyleAt(startPos) == SCE_SQL_OPERATOR) {
bool isAllClear = true;
for (int tempPos = startPos + 1;
tempPos < lastNLPos;
++tempPos) {
int tempStyle = styler.StyleAt(tempPos);
if (!IsCommentStyle(tempStyle)
&& tempStyle != SCE_SQL_DEFAULT) {
isAllClear = false;
break;
}
}
if (isAllClear) {
startPos = lastNLPos + 1;
break;
}
}
}
lineCurrent = styler.GetLine(startPos);
if (lineCurrent > 0)
levelCurrent = styler.LevelAt(lineCurrent - 1) >> 16;
}
// And because folding ends at ';', keep going until we find one
// Otherwise if create ... view ... as is split over multiple
// lines the folding won't always update immediately.
unsigned int docLength = styler.Length();
for (; endPos < docLength; ++endPos) {
if (styler.SafeGetCharAt(endPos) == ';') {
break;
}
}
int levelNext = levelCurrent;
char chNext = styler[startPos];
int styleNext = styler.StyleAt(startPos);
int style = initStyle;
bool endFound = false;
bool isUnfoldingIgnored = false;
// this statementFound flag avoids to fold when the statement is on only one line by ignoring ELSE or ELSIF
// eg. "IF condition1 THEN ... ELSIF condition2 THEN ... ELSE ... END IF;"
bool statementFound = false;
sql_state_t sqlStatesCurrentLine = 0;
if (!options.foldOnlyBegin) {
sqlStatesCurrentLine = sqlStates.ForLine(lineCurrent);
}
for (unsigned int i = startPos; i < endPos; i++) {
char ch = chNext;
chNext = styler.SafeGetCharAt(i + 1);
int stylePrev = style;
style = styleNext;
styleNext = styler.StyleAt(i + 1);
bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
if (atEOL || (!IsCommentStyle(style) && ch == ';')) {
if (endFound) {
//Maybe this is the end of "EXCEPTION" BLOCK (eg. "BEGIN ... EXCEPTION ... END;")
sqlStatesCurrentLine = sqlStates.IntoExceptionBlock(sqlStatesCurrentLine, false);
}
// set endFound and isUnfoldingIgnored to false if EOL is reached or ';' is found
endFound = false;
isUnfoldingIgnored = false;
}
if ((!IsCommentStyle(style) && ch == ';')) {
if (sqlStates.IsIntoMergeStatement(sqlStatesCurrentLine)) {
// This is the end of "MERGE" statement.
if (!sqlStates.IsCaseMergeWithoutWhenFound(sqlStatesCurrentLine))
levelNext--;
sqlStatesCurrentLine = sqlStates.IntoMergeStatement(sqlStatesCurrentLine, false);
levelNext--;
}
if (sqlStates.IsIntoSelectStatementOrAssignment(sqlStatesCurrentLine))
sqlStatesCurrentLine = sqlStates.IntoSelectStatementOrAssignment(sqlStatesCurrentLine, false);
if (sqlStates.IsIntoCreateStatement(sqlStatesCurrentLine)) {
if (sqlStates.IsIntoCreateViewStatement(sqlStatesCurrentLine)) {
if (sqlStates.IsIntoCreateViewAsStatement(sqlStatesCurrentLine)) {
levelNext--;
sqlStatesCurrentLine = sqlStates.IntoCreateViewAsStatement(sqlStatesCurrentLine, false);
}
sqlStatesCurrentLine = sqlStates.IntoCreateViewStatement(sqlStatesCurrentLine, false);
}
sqlStatesCurrentLine = sqlStates.IntoCreateStatement(sqlStatesCurrentLine, false);
}
}
if (ch == ':' && chNext == '=' && !IsCommentStyle(style))
sqlStatesCurrentLine = sqlStates.IntoSelectStatementOrAssignment(sqlStatesCurrentLine, true);
if (options.foldComment && IsStreamCommentStyle(style)) {
if (!IsStreamCommentStyle(stylePrev)) {
levelNext++;
} else if (!IsStreamCommentStyle(styleNext) && !atEOL) {
// Comments don't end at end of line and the next character may be unstyled.
levelNext--;
}
}
if (options.foldComment && (style == SCE_SQL_COMMENTLINE)) {
// MySQL needs -- comments to be followed by space or control char
if ((ch == '-') && (chNext == '-')) {
char chNext2 = styler.SafeGetCharAt(i + 2);
char chNext3 = styler.SafeGetCharAt(i + 3);
if (chNext2 == '{' || chNext3 == '{') {
levelNext++;
} else if (chNext2 == '}' || chNext3 == '}') {
levelNext--;
}
}
}
// Fold block of single-line comments (i.e. '--').
if (options.foldComment && atEOL && IsCommentLine(lineCurrent, styler)) {
if (!IsCommentLine(lineCurrent - 1, styler) && IsCommentLine(lineCurrent + 1, styler))
levelNext++;
else if (IsCommentLine(lineCurrent - 1, styler) && !IsCommentLine(lineCurrent + 1, styler))
levelNext--;
}
if (style == SCE_SQL_OPERATOR) {
if (ch == '(') {
if (levelCurrent > levelNext)
levelCurrent--;
levelNext++;
} else if (ch == ')') {
levelNext--;
} else if ((!options.foldOnlyBegin) && ch == ';') {
sqlStatesCurrentLine = sqlStates.IgnoreWhen(sqlStatesCurrentLine, false);
}
}
// If new keyword (cannot trigger on elseif or nullif, does less tests)
if (style == SCE_SQL_WORD && stylePrev != SCE_SQL_WORD) {
const int MAX_KW_LEN = 9; // Maximum length of folding keywords
char s[MAX_KW_LEN + 2];
unsigned int j = 0;
for (; j < MAX_KW_LEN + 1; j++) {
if (!iswordchar(styler[i + j])) {
break;
}
s[j] = static_cast<char>(tolower(styler[i + j]));
}
if (j == MAX_KW_LEN + 1) {
// Keyword too long, don't test it
s[0] = '\0';
} else {
s[j] = '\0';
}
if (!options.foldOnlyBegin &&
strcmp(s, "select") == 0) {
sqlStatesCurrentLine = sqlStates.IntoSelectStatementOrAssignment(sqlStatesCurrentLine, true);
} else if (strcmp(s, "if") == 0) {
if (endFound) {
endFound = false;
if (options.foldOnlyBegin && !isUnfoldingIgnored) {
// this end isn't for begin block, but for if block ("end if;")
// so ignore previous "end" by increment levelNext.
levelNext++;
}
} else {
if (!options.foldOnlyBegin)
sqlStatesCurrentLine = sqlStates.IntoCondition(sqlStatesCurrentLine, true);
if (levelCurrent > levelNext) {
// doesn't include this line into the folding block
// because doesn't hide IF (eg "END; IF")
levelCurrent = levelNext;
}
}
} else if (!options.foldOnlyBegin &&
strcmp(s, "then") == 0 &&
sqlStates.IsIntoCondition(sqlStatesCurrentLine)) {
sqlStatesCurrentLine = sqlStates.IntoCondition(sqlStatesCurrentLine, false);
if (!options.foldOnlyBegin) {
if (levelCurrent > levelNext) {
levelCurrent = levelNext;
}
if (!statementFound)
levelNext++;
statementFound = true;
} else if (levelCurrent > levelNext) {
// doesn't include this line into the folding block
// because doesn't hide LOOP or CASE (eg "END; LOOP" or "END; CASE")
levelCurrent = levelNext;
}
} else if (strcmp(s, "loop") == 0 ||
strcmp(s, "case") == 0) {
if (endFound) {
endFound = false;
if (options.foldOnlyBegin && !isUnfoldingIgnored) {
// this end isn't for begin block, but for loop block ("end loop;") or case block ("end case;")
// so ignore previous "end" by increment levelNext.
levelNext++;
}
if ((!options.foldOnlyBegin) && strcmp(s, "case") == 0) {
sqlStatesCurrentLine = sqlStates.EndCaseBlock(sqlStatesCurrentLine);
if (!sqlStates.IsCaseMergeWithoutWhenFound(sqlStatesCurrentLine))
levelNext--; //again for the "end case;" and block when
}
} else if (!options.foldOnlyBegin) {
if (strcmp(s, "case") == 0) {
sqlStatesCurrentLine = sqlStates.BeginCaseBlock(sqlStatesCurrentLine);
sqlStatesCurrentLine = sqlStates.CaseMergeWithoutWhenFound(sqlStatesCurrentLine, true);
}
if (levelCurrent > levelNext)
levelCurrent = levelNext;
if (!statementFound)
levelNext++;
statementFound = true;
} else if (levelCurrent > levelNext) {
// doesn't include this line into the folding block
// because doesn't hide LOOP or CASE (eg "END; LOOP" or "END; CASE")
levelCurrent = levelNext;
}
} else if ((!options.foldOnlyBegin) && (
// folding for ELSE and ELSIF block only if foldAtElse is set
// and IF or CASE aren't on only one line with ELSE or ELSIF (with flag statementFound)
options.foldAtElse && !statementFound) && strcmp(s, "elsif") == 0) {
sqlStatesCurrentLine = sqlStates.IntoCondition(sqlStatesCurrentLine, true);
levelCurrent--;
levelNext--;
} else if ((!options.foldOnlyBegin) && (
// folding for ELSE and ELSIF block only if foldAtElse is set
// and IF or CASE aren't on only one line with ELSE or ELSIF (with flag statementFound)
options.foldAtElse && !statementFound) && strcmp(s, "else") == 0) {
// prevent also ELSE is on the same line (eg. "ELSE ... END IF;")
statementFound = true;
if (sqlStates.IsIntoCaseBlock(sqlStatesCurrentLine) && sqlStates.IsCaseMergeWithoutWhenFound(sqlStatesCurrentLine)) {
sqlStatesCurrentLine = sqlStates.CaseMergeWithoutWhenFound(sqlStatesCurrentLine, false);
levelNext++;
} else {
// we are in same case "} ELSE {" in C language
levelCurrent--;
}
} else if (strcmp(s, "begin") == 0) {
levelNext++;
sqlStatesCurrentLine = sqlStates.IntoDeclareBlock(sqlStatesCurrentLine, false);
} else if ((strcmp(s, "end") == 0) ||
// SQL Anywhere permits IF ... ELSE ... ENDIF
// will only be active if "endif" appears in the
// keyword list.
(strcmp(s, "endif") == 0)) {
endFound = true;
levelNext--;
if (sqlStates.IsIntoSelectStatementOrAssignment(sqlStatesCurrentLine) && !sqlStates.IsCaseMergeWithoutWhenFound(sqlStatesCurrentLine))
levelNext--;
if (levelNext < SC_FOLDLEVELBASE) {
levelNext = SC_FOLDLEVELBASE;
isUnfoldingIgnored = true;
}
} else if ((!options.foldOnlyBegin) &&
strcmp(s, "when") == 0 &&
!sqlStates.IsIgnoreWhen(sqlStatesCurrentLine) &&
!sqlStates.IsIntoExceptionBlock(sqlStatesCurrentLine) && (
sqlStates.IsIntoCaseBlock(sqlStatesCurrentLine) ||
sqlStates.IsIntoMergeStatement(sqlStatesCurrentLine)
)
) {
sqlStatesCurrentLine = sqlStates.IntoCondition(sqlStatesCurrentLine, true);
// Don't foldind when CASE and WHEN are on the same line (with flag statementFound) (eg. "CASE selector WHEN expression1 THEN sequence_of_statements1;\n")
// and same way for MERGE statement.
if (!statementFound) {
if (!sqlStates.IsCaseMergeWithoutWhenFound(sqlStatesCurrentLine)) {
levelCurrent--;
levelNext--;
}
sqlStatesCurrentLine = sqlStates.CaseMergeWithoutWhenFound(sqlStatesCurrentLine, false);
}
} else if ((!options.foldOnlyBegin) && strcmp(s, "exit") == 0) {
sqlStatesCurrentLine = sqlStates.IgnoreWhen(sqlStatesCurrentLine, true);
} else if ((!options.foldOnlyBegin) && !sqlStates.IsIntoDeclareBlock(sqlStatesCurrentLine) && strcmp(s, "exception") == 0) {
sqlStatesCurrentLine = sqlStates.IntoExceptionBlock(sqlStatesCurrentLine, true);
} else if ((!options.foldOnlyBegin) &&
(strcmp(s, "declare") == 0 ||
strcmp(s, "function") == 0 ||
strcmp(s, "procedure") == 0 ||
strcmp(s, "package") == 0)) {
sqlStatesCurrentLine = sqlStates.IntoDeclareBlock(sqlStatesCurrentLine, true);
} else if ((!options.foldOnlyBegin) &&
strcmp(s, "merge") == 0) {
sqlStatesCurrentLine = sqlStates.IntoMergeStatement(sqlStatesCurrentLine, true);
sqlStatesCurrentLine = sqlStates.CaseMergeWithoutWhenFound(sqlStatesCurrentLine, true);
levelNext++;
statementFound = true;
} else if ((!options.foldOnlyBegin) &&
strcmp(s, "create") == 0) {
sqlStatesCurrentLine = sqlStates.IntoCreateStatement(sqlStatesCurrentLine, true);
} else if ((!options.foldOnlyBegin) &&
strcmp(s, "view") == 0 &&
sqlStates.IsIntoCreateStatement(sqlStatesCurrentLine)) {
sqlStatesCurrentLine = sqlStates.IntoCreateViewStatement(sqlStatesCurrentLine, true);
} else if ((!options.foldOnlyBegin) &&
strcmp(s, "as") == 0 &&
sqlStates.IsIntoCreateViewStatement(sqlStatesCurrentLine) &&
! sqlStates.IsIntoCreateViewAsStatement(sqlStatesCurrentLine)) {
sqlStatesCurrentLine = sqlStates.IntoCreateViewAsStatement(sqlStatesCurrentLine, true);
levelNext++;
}
}
if (atEOL) {
int levelUse = levelCurrent;
int lev = levelUse | levelNext << 16;
if (visibleChars == 0 && options.foldCompact)
lev |= SC_FOLDLEVELWHITEFLAG;
if (levelUse < levelNext)
lev |= SC_FOLDLEVELHEADERFLAG;
if (lev != styler.LevelAt(lineCurrent)) {
styler.SetLevel(lineCurrent, lev);
}
lineCurrent++;
levelCurrent = levelNext;
visibleChars = 0;
statementFound = false;
if (!options.foldOnlyBegin)
sqlStates.Set(lineCurrent, sqlStatesCurrentLine);
}
if (!isspacechar(ch)) {
visibleChars++;
}
}
}
LexerModule lmSQL(SCLEX_SQL, LexerSQL::LexerFactorySQL, "sql", sqlWordListDesc);
+20
View File
@@ -0,0 +1,20 @@
License for Scintilla and SciTE
Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org>
All Rights Reserved
Permission to use, copy, modify, and distribute this software and its
documentation for any purpose and without fee is hereby granted,
provided that the above copyright notice appear in all copies and that
both that copyright notice and this permission notice appear in
supporting documentation.
NEIL HODGSON DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS, IN NO EVENT SHALL NEIL HODGSON BE LIABLE FOR ANY
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE
OR PERFORMANCE OF THIS SOFTWARE.
+79
View File
@@ -0,0 +1,79 @@
// Scintilla source code edit control
/** @file KeyWords.cxx
** Colourise for particular languages.
**/
// Copyright 1998-2002 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <stdarg.h>
#include <assert.h>
#include <ctype.h>
#include "ILexer.h"
#include "Scintilla.h"
#include "SciLexer.h"
#include "PropSetSimple.h"
#include "WordList.h"
#include "LexAccessor.h"
#include "Accessor.h"
#ifdef SCI_NAMESPACE
using namespace Scintilla;
#endif
Accessor::Accessor(IDocument *pAccess_, PropSetSimple *pprops_) : LexAccessor(pAccess_), pprops(pprops_) {
}
int Accessor::GetPropertyInt(const char *key, int defaultValue) const {
return pprops->GetInt(key, defaultValue);
}
int Accessor::IndentAmount(int line, int *flags, PFNIsCommentLeader pfnIsCommentLeader) {
int end = Length();
int spaceFlags = 0;
// Determines the indentation level of the current line and also checks for consistent
// indentation compared to the previous line.
// Indentation is judged consistent when the indentation whitespace of each line lines
// the same or the indentation of one line is a prefix of the other.
int pos = LineStart(line);
char ch = (*this)[pos];
int indent = 0;
bool inPrevPrefix = line > 0;
int posPrev = inPrevPrefix ? LineStart(line-1) : 0;
while ((ch == ' ' || ch == '\t') && (pos < end)) {
if (inPrevPrefix) {
char chPrev = (*this)[posPrev++];
if (chPrev == ' ' || chPrev == '\t') {
if (chPrev != ch)
spaceFlags |= wsInconsistent;
} else {
inPrevPrefix = false;
}
}
if (ch == ' ') {
spaceFlags |= wsSpace;
indent++;
} else { // Tab
spaceFlags |= wsTab;
if (spaceFlags & wsSpace)
spaceFlags |= wsSpaceTab;
indent = (indent / 8 + 1) * 8;
}
ch = (*this)[++pos];
}
*flags = spaceFlags;
indent += SC_FOLDLEVELBASE;
// if completely empty line or the start of a comment...
if ((LineStart(line) == Length()) || (ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r') ||
(pfnIsCommentLeader && (*pfnIsCommentLeader)(*this, pos, end-pos)))
return indent | SC_FOLDLEVELWHITEFLAG;
else
return indent;
}
+35
View File
@@ -0,0 +1,35 @@
// Scintilla source code edit control
/** @file Accessor.h
** Interfaces between Scintilla and lexers.
**/
// Copyright 1998-2010 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
#ifndef ACCESSOR_H
#define ACCESSOR_H
#ifdef SCI_NAMESPACE
namespace Scintilla {
#endif
enum { wsSpace=1, wsTab=2, wsSpaceTab=4, wsInconsistent=8 };
class Accessor;
class WordList;
class PropSetSimple;
typedef bool (*PFNIsCommentLeader)(Accessor &styler, int pos, int len);
class Accessor : public LexAccessor {
public:
PropSetSimple *pprops;
Accessor(IDocument *pAccess_, PropSetSimple *pprops_);
int GetPropertyInt(const char *, int defaultValue=0) const;
int IndentAmount(int line, int *flags, PFNIsCommentLeader pfnIsCommentLeader = 0);
};
#ifdef SCI_NAMESPACE
}
#endif
#endif
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,31 @@
// Scintilla source code edit control
/** @file CharacterCategory.h
** Returns the Unicode general category of a character.
**/
// Copyright 2013 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
#ifndef CHARACTERCATEGORY_H
#define CHARACTERCATEGORY_H
#ifdef SCI_NAMESPACE
namespace Scintilla {
#endif
enum CharacterCategory {
ccLu, ccLl, ccLt, ccLm, ccLo,
ccMn, ccMc, ccMe,
ccNd, ccNl, ccNo,
ccPc, ccPd, ccPs, ccPe, ccPi, ccPf, ccPo,
ccSm, ccSc, ccSk, ccSo,
ccZs, ccZl, ccZp,
ccCc, ccCf, ccCs, ccCo, ccCn
};
CharacterCategory CategoriseCharacter(int character);
#ifdef SCI_NAMESPACE
}
#endif
#endif
+61
View File
@@ -0,0 +1,61 @@
// Scintilla source code edit control
/** @file CharacterSet.cxx
** Simple case functions for ASCII.
** Lexer infrastructure.
**/
// Copyright 1998-2010 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <assert.h>
#include <ctype.h>
#include "CharacterSet.h"
#ifdef SCI_NAMESPACE
using namespace Scintilla;
#endif
#ifdef SCI_NAMESPACE
namespace Scintilla {
#endif
int CompareCaseInsensitive(const char *a, const char *b) {
while (*a && *b) {
if (*a != *b) {
char upperA = MakeUpperCase(*a);
char upperB = MakeUpperCase(*b);
if (upperA != upperB)
return upperA - upperB;
}
a++;
b++;
}
// Either *a or *b is nul
return *a - *b;
}
int CompareNCaseInsensitive(const char *a, const char *b, size_t len) {
while (*a && *b && len) {
if (*a != *b) {
char upperA = MakeUpperCase(*a);
char upperB = MakeUpperCase(*b);
if (upperA != upperB)
return upperA - upperB;
}
a++;
b++;
len--;
}
if (len == 0)
return 0;
else
// Either *a or *b is nul
return *a - *b;
}
#ifdef SCI_NAMESPACE
}
#endif
+178
View File
@@ -0,0 +1,178 @@
// Scintilla source code edit control
/** @file CharacterSet.h
** Encapsulates a set of characters. Used to test if a character is within a set.
**/
// Copyright 2007 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
#ifndef CHARACTERSET_H
#define CHARACTERSET_H
#ifdef SCI_NAMESPACE
namespace Scintilla {
#endif
class CharacterSet {
int size;
bool valueAfter;
bool *bset;
public:
enum setBase {
setNone=0,
setLower=1,
setUpper=2,
setDigits=4,
setAlpha=setLower|setUpper,
setAlphaNum=setAlpha|setDigits
};
CharacterSet(setBase base=setNone, const char *initialSet="", int size_=0x80, bool valueAfter_=false) {
size = size_;
valueAfter = valueAfter_;
bset = new bool[size];
for (int i=0; i < size; i++) {
bset[i] = false;
}
AddString(initialSet);
if (base & setLower)
AddString("abcdefghijklmnopqrstuvwxyz");
if (base & setUpper)
AddString("ABCDEFGHIJKLMNOPQRSTUVWXYZ");
if (base & setDigits)
AddString("0123456789");
}
CharacterSet(const CharacterSet &other) {
size = other.size;
valueAfter = other.valueAfter;
bset = new bool[size];
for (int i=0; i < size; i++) {
bset[i] = other.bset[i];
}
}
~CharacterSet() {
delete []bset;
bset = 0;
size = 0;
}
CharacterSet &operator=(const CharacterSet &other) {
if (this != &other) {
bool *bsetNew = new bool[other.size];
for (int i=0; i < other.size; i++) {
bsetNew[i] = other.bset[i];
}
delete []bset;
size = other.size;
valueAfter = other.valueAfter;
bset = bsetNew;
}
return *this;
}
void Add(int val) {
assert(val >= 0);
assert(val < size);
bset[val] = true;
}
void AddString(const char *setToAdd) {
for (const char *cp=setToAdd; *cp; cp++) {
int val = static_cast<unsigned char>(*cp);
assert(val >= 0);
assert(val < size);
bset[val] = true;
}
}
bool Contains(int val) const {
// val being -ve is valid (or there is a sign extension bug elsewhere.
//assert(val >= 0);
if (val < 0) return false;
return (val < size) ? bset[val] : valueAfter;
}
};
// Functions for classifying characters
inline bool IsASpace(int ch) {
return (ch == ' ') || ((ch >= 0x09) && (ch <= 0x0d));
}
inline bool IsASpaceOrTab(int ch) {
return (ch == ' ') || (ch == '\t');
}
inline bool IsADigit(int ch) {
return (ch >= '0') && (ch <= '9');
}
inline bool IsADigit(int ch, int base) {
if (base <= 10) {
return (ch >= '0') && (ch < '0' + base);
} else {
return ((ch >= '0') && (ch <= '9')) ||
((ch >= 'A') && (ch < 'A' + base - 10)) ||
((ch >= 'a') && (ch < 'a' + base - 10));
}
}
inline bool IsASCII(int ch) {
return (ch >= 0) && (ch < 0x80);
}
inline bool IsLowerCase(int ch) {
return (ch >= 'a') && (ch <= 'z');
}
inline bool IsUpperCase(int ch) {
return (ch >= 'A') && (ch <= 'Z');
}
inline bool IsAlphaNumeric(int ch) {
return
((ch >= '0') && (ch <= '9')) ||
((ch >= 'a') && (ch <= 'z')) ||
((ch >= 'A') && (ch <= 'Z'));
}
/**
* Check if a character is a space.
* This is ASCII specific but is safe with chars >= 0x80.
*/
inline bool isspacechar(int ch) {
return (ch == ' ') || ((ch >= 0x09) && (ch <= 0x0d));
}
inline bool iswordchar(int ch) {
return IsAlphaNumeric(ch) || ch == '.' || ch == '_';
}
inline bool iswordstart(int ch) {
return IsAlphaNumeric(ch) || ch == '_';
}
inline bool isoperator(int ch) {
if (IsAlphaNumeric(ch))
return false;
if (ch == '%' || ch == '^' || ch == '&' || ch == '*' ||
ch == '(' || ch == ')' || ch == '-' || ch == '+' ||
ch == '=' || ch == '|' || ch == '{' || ch == '}' ||
ch == '[' || ch == ']' || ch == ':' || ch == ';' ||
ch == '<' || ch == '>' || ch == ',' || ch == '/' ||
ch == '?' || ch == '!' || ch == '.' || ch == '~')
return true;
return false;
}
// Simple case functions for ASCII.
inline char MakeUpperCase(char ch) {
if (ch < 'a' || ch > 'z')
return ch;
else
return static_cast<char>(ch - 'a' + 'A');
}
int CompareCaseInsensitive(const char *a, const char *b);
int CompareNCaseInsensitive(const char *a, const char *b, size_t len);
#ifdef SCI_NAMESPACE
}
#endif
#endif
+204
View File
@@ -0,0 +1,204 @@
// Scintilla source code edit control
/** @file LexAccessor.h
** Interfaces between Scintilla and lexers.
**/
// Copyright 1998-2010 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
#ifndef LEXACCESSOR_H
#define LEXACCESSOR_H
#ifdef SCI_NAMESPACE
namespace Scintilla {
#endif
enum EncodingType { enc8bit, encUnicode, encDBCS };
class LexAccessor {
private:
IDocument *pAccess;
enum {extremePosition=0x7FFFFFFF};
/** @a bufferSize is a trade off between time taken to copy the characters
* and retrieval overhead.
* @a slopSize positions the buffer before the desired position
* in case there is some backtracking. */
enum {bufferSize=4000, slopSize=bufferSize/8};
char buf[bufferSize+1];
int startPos;
int endPos;
int codePage;
enum EncodingType encodingType;
int lenDoc;
char styleBuf[bufferSize];
int validLen;
unsigned int startSeg;
int startPosStyling;
int documentVersion;
void Fill(int position) {
startPos = position - slopSize;
if (startPos + bufferSize > lenDoc)
startPos = lenDoc - bufferSize;
if (startPos < 0)
startPos = 0;
endPos = startPos + bufferSize;
if (endPos > lenDoc)
endPos = lenDoc;
pAccess->GetCharRange(buf, startPos, endPos-startPos);
buf[endPos-startPos] = '\0';
}
public:
explicit LexAccessor(IDocument *pAccess_) :
pAccess(pAccess_), startPos(extremePosition), endPos(0),
codePage(pAccess->CodePage()),
encodingType(enc8bit),
lenDoc(pAccess->Length()),
validLen(0),
startSeg(0), startPosStyling(0),
documentVersion(pAccess->Version()) {
// Prevent warnings by static analyzers about uninitialized buf and styleBuf.
buf[0] = 0;
styleBuf[0] = 0;
switch (codePage) {
case 65001:
encodingType = encUnicode;
break;
case 932:
case 936:
case 949:
case 950:
case 1361:
encodingType = encDBCS;
}
}
char operator[](int position) {
if (position < startPos || position >= endPos) {
Fill(position);
}
return buf[position - startPos];
}
IDocumentWithLineEnd *MultiByteAccess() const {
if (documentVersion >= dvLineEnd) {
return static_cast<IDocumentWithLineEnd *>(pAccess);
}
return 0;
}
/** Safe version of operator[], returning a defined value for invalid position. */
char SafeGetCharAt(int position, char chDefault=' ') {
if (position < startPos || position >= endPos) {
Fill(position);
if (position < startPos || position >= endPos) {
// Position is outside range of document
return chDefault;
}
}
return buf[position - startPos];
}
bool IsLeadByte(char ch) const {
return pAccess->IsDBCSLeadByte(ch);
}
EncodingType Encoding() const {
return encodingType;
}
bool Match(int pos, const char *s) {
for (int i=0; *s; i++) {
if (*s != SafeGetCharAt(pos+i))
return false;
s++;
}
return true;
}
char StyleAt(int position) const {
return static_cast<char>(pAccess->StyleAt(position));
}
int GetLine(int position) const {
return pAccess->LineFromPosition(position);
}
int LineStart(int line) const {
return pAccess->LineStart(line);
}
int LineEnd(int line) {
if (documentVersion >= dvLineEnd) {
return (static_cast<IDocumentWithLineEnd *>(pAccess))->LineEnd(line);
} else {
// Old interface means only '\r', '\n' and '\r\n' line ends.
int startNext = pAccess->LineStart(line+1);
char chLineEnd = SafeGetCharAt(startNext-1);
if (chLineEnd == '\n' && (SafeGetCharAt(startNext-2) == '\r'))
return startNext - 2;
else
return startNext - 1;
}
}
int LevelAt(int line) const {
return pAccess->GetLevel(line);
}
int Length() const {
return lenDoc;
}
void Flush() {
if (validLen > 0) {
pAccess->SetStyles(validLen, styleBuf);
startPosStyling += validLen;
validLen = 0;
}
}
int GetLineState(int line) const {
return pAccess->GetLineState(line);
}
int SetLineState(int line, int state) {
return pAccess->SetLineState(line, state);
}
// Style setting
void StartAt(unsigned int start) {
pAccess->StartStyling(start, '\377');
startPosStyling = start;
}
unsigned int GetStartSegment() const {
return startSeg;
}
void StartSegment(unsigned int pos) {
startSeg = pos;
}
void ColourTo(unsigned int pos, int chAttr) {
// Only perform styling if non empty range
if (pos != startSeg - 1) {
assert(pos >= startSeg);
if (pos < startSeg) {
return;
}
if (validLen + (pos - startSeg + 1) >= bufferSize)
Flush();
if (validLen + (pos - startSeg + 1) >= bufferSize) {
// Too big for buffer so send directly
pAccess->SetStyleFor(pos - startSeg + 1, static_cast<char>(chAttr));
} else {
for (unsigned int i = startSeg; i <= pos; i++) {
assert((startPosStyling + validLen) < Length());
styleBuf[validLen++] = static_cast<char>(chAttr);
}
}
}
startSeg = pos+1;
}
void SetLevel(int line, int level) {
pAccess->SetLevel(line, level);
}
void IndicatorFill(int start, int end, int indicator, int value) {
pAccess->DecorationSetCurrentIndicator(indicator);
pAccess->DecorationFillRange(start, value, end - start);
}
void ChangeLexerState(int start, int end) {
pAccess->ChangeLexerState(start, end);
}
};
#ifdef SCI_NAMESPACE
}
#endif
#endif
+92
View File
@@ -0,0 +1,92 @@
// Scintilla source code edit control
/** @file LexerBase.cxx
** A simple lexer with no state.
**/
// Copyright 1998-2010 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <stdarg.h>
#include <assert.h>
#include <ctype.h>
#include "ILexer.h"
#include "Scintilla.h"
#include "SciLexer.h"
#include "PropSetSimple.h"
#include "WordList.h"
#include "LexAccessor.h"
#include "Accessor.h"
#include "LexerModule.h"
#include "LexerBase.h"
#ifdef SCI_NAMESPACE
using namespace Scintilla;
#endif
LexerBase::LexerBase() {
for (int wl = 0; wl < numWordLists; wl++)
keyWordLists[wl] = new WordList;
keyWordLists[numWordLists] = 0;
}
LexerBase::~LexerBase() {
for (int wl = 0; wl < numWordLists; wl++) {
delete keyWordLists[wl];
keyWordLists[wl] = 0;
}
keyWordLists[numWordLists] = 0;
}
void SCI_METHOD LexerBase::Release() {
delete this;
}
int SCI_METHOD LexerBase::Version() const {
return lvOriginal;
}
const char * SCI_METHOD LexerBase::PropertyNames() {
return "";
}
int SCI_METHOD LexerBase::PropertyType(const char *) {
return SC_TYPE_BOOLEAN;
}
const char * SCI_METHOD LexerBase::DescribeProperty(const char *) {
return "";
}
int SCI_METHOD LexerBase::PropertySet(const char *key, const char *val) {
const char *valOld = props.Get(key);
if (strcmp(val, valOld) != 0) {
props.Set(key, val);
return 0;
} else {
return -1;
}
}
const char * SCI_METHOD LexerBase::DescribeWordListSets() {
return "";
}
int SCI_METHOD LexerBase::WordListSet(int n, const char *wl) {
if (n < numWordLists) {
WordList wlNew;
wlNew.Set(wl);
if (*keyWordLists[n] != wlNew) {
keyWordLists[n]->Set(wl);
return 0;
}
}
return -1;
}
void * SCI_METHOD LexerBase::PrivateCall(int, void *) {
return 0;
}
+41
View File
@@ -0,0 +1,41 @@
// Scintilla source code edit control
/** @file LexerBase.h
** A simple lexer with no state.
**/
// Copyright 1998-2010 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
#ifndef LEXERBASE_H
#define LEXERBASE_H
#ifdef SCI_NAMESPACE
namespace Scintilla {
#endif
// A simple lexer with no state
class LexerBase : public ILexer {
protected:
PropSetSimple props;
enum {numWordLists=KEYWORDSET_MAX+1};
WordList *keyWordLists[numWordLists+1];
public:
LexerBase();
virtual ~LexerBase();
void SCI_METHOD Release();
int SCI_METHOD Version() const;
const char * SCI_METHOD PropertyNames();
int SCI_METHOD PropertyType(const char *name);
const char * SCI_METHOD DescribeProperty(const char *name);
int SCI_METHOD PropertySet(const char *key, const char *val);
const char * SCI_METHOD DescribeWordListSets();
int SCI_METHOD WordListSet(int n, const char *wl);
void SCI_METHOD Lex(unsigned int startPos, int lengthDoc, int initStyle, IDocument *pAccess) = 0;
void SCI_METHOD Fold(unsigned int startPos, int lengthDoc, int initStyle, IDocument *pAccess) = 0;
void * SCI_METHOD PrivateCall(int operation, void *pointer);
};
#ifdef SCI_NAMESPACE
}
#endif
#endif
+111
View File
@@ -0,0 +1,111 @@
// Scintilla source code edit control
/** @file LexerModule.cxx
** Colourise for particular languages.
**/
// Copyright 1998-2010 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <stdarg.h>
#include <assert.h>
#include <ctype.h>
#include <string>
#include "ILexer.h"
#include "Scintilla.h"
#include "SciLexer.h"
#include "PropSetSimple.h"
#include "WordList.h"
#include "LexAccessor.h"
#include "Accessor.h"
#include "LexerModule.h"
#include "LexerBase.h"
#include "LexerSimple.h"
#ifdef SCI_NAMESPACE
using namespace Scintilla;
#endif
LexerModule::LexerModule(int language_,
LexerFunction fnLexer_,
const char *languageName_,
LexerFunction fnFolder_,
const char *const wordListDescriptions_[]) :
language(language_),
fnLexer(fnLexer_),
fnFolder(fnFolder_),
fnFactory(0),
wordListDescriptions(wordListDescriptions_),
languageName(languageName_) {
}
LexerModule::LexerModule(int language_,
LexerFactoryFunction fnFactory_,
const char *languageName_,
const char * const wordListDescriptions_[]) :
language(language_),
fnLexer(0),
fnFolder(0),
fnFactory(fnFactory_),
wordListDescriptions(wordListDescriptions_),
languageName(languageName_) {
}
int LexerModule::GetNumWordLists() const {
if (wordListDescriptions == NULL) {
return -1;
} else {
int numWordLists = 0;
while (wordListDescriptions[numWordLists]) {
++numWordLists;
}
return numWordLists;
}
}
const char *LexerModule::GetWordListDescription(int index) const {
assert(index < GetNumWordLists());
if (!wordListDescriptions || (index >= GetNumWordLists())) {
return "";
} else {
return wordListDescriptions[index];
}
}
ILexer *LexerModule::Create() const {
if (fnFactory)
return fnFactory();
else
return new LexerSimple(this);
}
void LexerModule::Lex(unsigned int startPos, int lengthDoc, int initStyle,
WordList *keywordlists[], Accessor &styler) const {
if (fnLexer)
fnLexer(startPos, lengthDoc, initStyle, keywordlists, styler);
}
void LexerModule::Fold(unsigned int startPos, int lengthDoc, int initStyle,
WordList *keywordlists[], Accessor &styler) const {
if (fnFolder) {
int lineCurrent = styler.GetLine(startPos);
// Move back one line in case deletion wrecked current line fold state
if (lineCurrent > 0) {
lineCurrent--;
int newStartPos = styler.LineStart(lineCurrent);
lengthDoc += startPos - newStartPos;
startPos = newStartPos;
initStyle = 0;
if (startPos > 0) {
initStyle = styler.StyleAt(startPos - 1);
}
}
fnFolder(startPos, lengthDoc, initStyle, keywordlists, styler);
}
}
+82
View File
@@ -0,0 +1,82 @@
// Scintilla source code edit control
/** @file LexerModule.h
** Colourise for particular languages.
**/
// Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
#ifndef LEXERMODULE_H
#define LEXERMODULE_H
#ifdef SCI_NAMESPACE
namespace Scintilla {
#endif
class Accessor;
class WordList;
typedef void (*LexerFunction)(unsigned int startPos, int lengthDoc, int initStyle,
WordList *keywordlists[], Accessor &styler);
typedef ILexer *(*LexerFactoryFunction)();
/**
* A LexerModule is responsible for lexing and folding a particular language.
* The class maintains a list of LexerModules which can be searched to find a
* module appropriate to a particular language.
*/
class LexerModule {
protected:
int language;
LexerFunction fnLexer;
LexerFunction fnFolder;
LexerFactoryFunction fnFactory;
const char * const * wordListDescriptions;
public:
const char *languageName;
LexerModule(int language_,
LexerFunction fnLexer_,
const char *languageName_=0,
LexerFunction fnFolder_=0,
const char * const wordListDescriptions_[] = NULL);
LexerModule(int language_,
LexerFactoryFunction fnFactory_,
const char *languageName_,
const char * const wordListDescriptions_[] = NULL);
virtual ~LexerModule() {
}
int GetLanguage() const { return language; }
// -1 is returned if no WordList information is available
int GetNumWordLists() const;
const char *GetWordListDescription(int index) const;
ILexer *Create() const;
virtual void Lex(unsigned int startPos, int length, int initStyle,
WordList *keywordlists[], Accessor &styler) const;
virtual void Fold(unsigned int startPos, int length, int initStyle,
WordList *keywordlists[], Accessor &styler) const;
friend class Catalogue;
};
inline int Maximum(int a, int b) {
return (a > b) ? a : b;
}
// Shut up annoying Visual C++ warnings:
#ifdef _MSC_VER
#pragma warning(disable: 4244 4309 4456 4457)
#endif
// Turn off shadow warnings for lexers as may be maintained by others
#if defined(__GNUC__)
#pragma GCC diagnostic ignored "-Wshadow"
#endif
#ifdef SCI_NAMESPACE
}
#endif
#endif
@@ -0,0 +1,68 @@
// Scintilla source code edit control
/** @file LexerNoExceptions.cxx
** A simple lexer with no state which does not throw exceptions so can be used in an external lexer.
**/
// Copyright 1998-2010 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <stdarg.h>
#include <assert.h>
#include <ctype.h>
#include "ILexer.h"
#include "Scintilla.h"
#include "SciLexer.h"
#include "PropSetSimple.h"
#include "WordList.h"
#include "LexAccessor.h"
#include "Accessor.h"
#include "LexerModule.h"
#include "LexerBase.h"
#include "LexerNoExceptions.h"
#ifdef SCI_NAMESPACE
using namespace Scintilla;
#endif
int SCI_METHOD LexerNoExceptions::PropertySet(const char *key, const char *val) {
try {
return LexerBase::PropertySet(key, val);
} catch (...) {
// Should not throw into caller as may be compiled with different compiler or options
}
return -1;
}
int SCI_METHOD LexerNoExceptions::WordListSet(int n, const char *wl) {
try {
return LexerBase::WordListSet(n, wl);
} catch (...) {
// Should not throw into caller as may be compiled with different compiler or options
}
return -1;
}
void SCI_METHOD LexerNoExceptions::Lex(unsigned int startPos, int length, int initStyle, IDocument *pAccess) {
try {
Accessor astyler(pAccess, &props);
Lexer(startPos, length, initStyle, pAccess, astyler);
astyler.Flush();
} catch (...) {
// Should not throw into caller as may be compiled with different compiler or options
pAccess->SetErrorStatus(SC_STATUS_FAILURE);
}
}
void SCI_METHOD LexerNoExceptions::Fold(unsigned int startPos, int length, int initStyle, IDocument *pAccess) {
try {
Accessor astyler(pAccess, &props);
Folder(startPos, length, initStyle, pAccess, astyler);
astyler.Flush();
} catch (...) {
// Should not throw into caller as may be compiled with different compiler or options
pAccess->SetErrorStatus(SC_STATUS_FAILURE);
}
}
@@ -0,0 +1,32 @@
// Scintilla source code edit control
/** @file LexerNoExceptions.h
** A simple lexer with no state.
**/
// Copyright 1998-2010 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
#ifndef LEXERNOEXCEPTIONS_H
#define LEXERNOEXCEPTIONS_H
#ifdef SCI_NAMESPACE
namespace Scintilla {
#endif
// A simple lexer with no state
class LexerNoExceptions : public LexerBase {
public:
// TODO Also need to prevent exceptions in constructor and destructor
int SCI_METHOD PropertySet(const char *key, const char *val);
int SCI_METHOD WordListSet(int n, const char *wl);
void SCI_METHOD Lex(unsigned int startPos, int lengthDoc, int initStyle, IDocument *pAccess);
void SCI_METHOD Fold(unsigned int startPos, int lengthDoc, int initStyle, IDocument *);
virtual void Lexer(unsigned int startPos, int length, int initStyle, IDocument *pAccess, Accessor &styler) = 0;
virtual void Folder(unsigned int startPos, int length, int initStyle, IDocument *pAccess, Accessor &styler) = 0;
};
#ifdef SCI_NAMESPACE
}
#endif
#endif
+57
View File
@@ -0,0 +1,57 @@
// Scintilla source code edit control
/** @file LexerSimple.cxx
** A simple lexer with no state.
**/
// Copyright 1998-2010 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <stdarg.h>
#include <assert.h>
#include <ctype.h>
#include <string>
#include "ILexer.h"
#include "Scintilla.h"
#include "SciLexer.h"
#include "PropSetSimple.h"
#include "WordList.h"
#include "LexAccessor.h"
#include "Accessor.h"
#include "LexerModule.h"
#include "LexerBase.h"
#include "LexerSimple.h"
#ifdef SCI_NAMESPACE
using namespace Scintilla;
#endif
LexerSimple::LexerSimple(const LexerModule *module_) : module(module_) {
for (int wl = 0; wl < module->GetNumWordLists(); wl++) {
if (!wordLists.empty())
wordLists += "\n";
wordLists += module->GetWordListDescription(wl);
}
}
const char * SCI_METHOD LexerSimple::DescribeWordListSets() {
return wordLists.c_str();
}
void SCI_METHOD LexerSimple::Lex(unsigned int startPos, int lengthDoc, int initStyle, IDocument *pAccess) {
Accessor astyler(pAccess, &props);
module->Lex(startPos, lengthDoc, initStyle, keyWordLists, astyler);
astyler.Flush();
}
void SCI_METHOD LexerSimple::Fold(unsigned int startPos, int lengthDoc, int initStyle, IDocument *pAccess) {
if (props.GetInt("fold")) {
Accessor astyler(pAccess, &props);
module->Fold(startPos, lengthDoc, initStyle, keyWordLists, astyler);
astyler.Flush();
}
}
+30
View File
@@ -0,0 +1,30 @@
// Scintilla source code edit control
/** @file LexerSimple.h
** A simple lexer with no state.
**/
// Copyright 1998-2010 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
#ifndef LEXERSIMPLE_H
#define LEXERSIMPLE_H
#ifdef SCI_NAMESPACE
namespace Scintilla {
#endif
// A simple lexer with no state
class LexerSimple : public LexerBase {
const LexerModule *module;
std::string wordLists;
public:
explicit LexerSimple(const LexerModule *module_);
const char * SCI_METHOD DescribeWordListSets();
void SCI_METHOD Lex(unsigned int startPos, int lengthDoc, int initStyle, IDocument *pAccess);
void SCI_METHOD Fold(unsigned int startPos, int lengthDoc, int initStyle, IDocument *pAccess);
};
#ifdef SCI_NAMESPACE
}
#endif
#endif
+20
View File
@@ -0,0 +1,20 @@
License for Scintilla and SciTE
Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org>
All Rights Reserved
Permission to use, copy, modify, and distribute this software and its
documentation for any purpose and without fee is hereby granted,
provided that the above copyright notice appear in all copies and that
both that copyright notice and this permission notice appear in
supporting documentation.
NEIL HODGSON DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS, IN NO EVENT SHALL NEIL HODGSON BE LIABLE FOR ANY
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE
OR PERFORMANCE OF THIS SOFTWARE.
+142
View File
@@ -0,0 +1,142 @@
// Scintilla source code edit control
/** @file OptionSet.h
** Manage descriptive information about an options struct for a lexer.
** Hold the names, positions, and descriptions of boolean, integer and string options and
** allow setting options and retrieving metadata about the options.
**/
// Copyright 2010 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
#ifndef OPTIONSET_H
#define OPTIONSET_H
#ifdef SCI_NAMESPACE
namespace Scintilla {
#endif
template <typename T>
class OptionSet {
typedef T Target;
typedef bool T::*plcob;
typedef int T::*plcoi;
typedef std::string T::*plcos;
struct Option {
int opType;
union {
plcob pb;
plcoi pi;
plcos ps;
};
std::string description;
Option() :
opType(SC_TYPE_BOOLEAN), pb(0), description("") {
}
Option(plcob pb_, std::string description_="") :
opType(SC_TYPE_BOOLEAN), pb(pb_), description(description_) {
}
Option(plcoi pi_, std::string description_) :
opType(SC_TYPE_INTEGER), pi(pi_), description(description_) {
}
Option(plcos ps_, std::string description_) :
opType(SC_TYPE_STRING), ps(ps_), description(description_) {
}
bool Set(T *base, const char *val) const {
switch (opType) {
case SC_TYPE_BOOLEAN: {
bool option = atoi(val) != 0;
if ((*base).*pb != option) {
(*base).*pb = option;
return true;
}
break;
}
case SC_TYPE_INTEGER: {
int option = atoi(val);
if ((*base).*pi != option) {
(*base).*pi = option;
return true;
}
break;
}
case SC_TYPE_STRING: {
if ((*base).*ps != val) {
(*base).*ps = val;
return true;
}
break;
}
}
return false;
}
};
typedef std::map<std::string, Option> OptionMap;
OptionMap nameToDef;
std::string names;
std::string wordLists;
void AppendName(const char *name) {
if (!names.empty())
names += "\n";
names += name;
}
public:
virtual ~OptionSet() {
}
void DefineProperty(const char *name, plcob pb, std::string description="") {
nameToDef[name] = Option(pb, description);
AppendName(name);
}
void DefineProperty(const char *name, plcoi pi, std::string description="") {
nameToDef[name] = Option(pi, description);
AppendName(name);
}
void DefineProperty(const char *name, plcos ps, std::string description="") {
nameToDef[name] = Option(ps, description);
AppendName(name);
}
const char *PropertyNames() const {
return names.c_str();
}
int PropertyType(const char *name) {
typename OptionMap::iterator it = nameToDef.find(name);
if (it != nameToDef.end()) {
return it->second.opType;
}
return SC_TYPE_BOOLEAN;
}
const char *DescribeProperty(const char *name) {
typename OptionMap::iterator it = nameToDef.find(name);
if (it != nameToDef.end()) {
return it->second.description.c_str();
}
return "";
}
bool PropertySet(T *base, const char *name, const char *val) {
typename OptionMap::iterator it = nameToDef.find(name);
if (it != nameToDef.end()) {
return it->second.Set(base, val);
}
return false;
}
void DefineWordListSets(const char * const wordListDescriptions[]) {
if (wordListDescriptions) {
for (size_t wl = 0; wordListDescriptions[wl]; wl++) {
if (!wordLists.empty())
wordLists += "\n";
wordLists += wordListDescriptions[wl];
}
}
}
const char *DescribeWordListSets() const {
return wordLists.c_str();
}
};
#ifdef SCI_NAMESPACE
}
#endif
#endif
+156
View File
@@ -0,0 +1,156 @@
// SciTE - Scintilla based Text Editor
/** @file PropSetSimple.cxx
** A Java style properties file module.
**/
// Copyright 1998-2010 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
// Maintain a dictionary of properties
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <string>
#include <map>
#include "PropSetSimple.h"
#ifdef SCI_NAMESPACE
using namespace Scintilla;
#endif
typedef std::map<std::string, std::string> mapss;
PropSetSimple::PropSetSimple() {
mapss *props = new mapss;
impl = static_cast<void *>(props);
}
PropSetSimple::~PropSetSimple() {
mapss *props = static_cast<mapss *>(impl);
delete props;
impl = 0;
}
void PropSetSimple::Set(const char *key, const char *val, int lenKey, int lenVal) {
mapss *props = static_cast<mapss *>(impl);
if (!*key) // Empty keys are not supported
return;
if (lenKey == -1)
lenKey = static_cast<int>(strlen(key));
if (lenVal == -1)
lenVal = static_cast<int>(strlen(val));
(*props)[std::string(key, lenKey)] = std::string(val, lenVal);
}
static bool IsASpaceCharacter(unsigned int ch) {
return (ch == ' ') || ((ch >= 0x09) && (ch <= 0x0d));
}
void PropSetSimple::Set(const char *keyVal) {
while (IsASpaceCharacter(*keyVal))
keyVal++;
const char *endVal = keyVal;
while (*endVal && (*endVal != '\n'))
endVal++;
const char *eqAt = strchr(keyVal, '=');
if (eqAt) {
Set(keyVal, eqAt + 1, static_cast<int>(eqAt-keyVal),
static_cast<int>(endVal - eqAt - 1));
} else if (*keyVal) { // No '=' so assume '=1'
Set(keyVal, "1", static_cast<int>(endVal-keyVal), 1);
}
}
void PropSetSimple::SetMultiple(const char *s) {
const char *eol = strchr(s, '\n');
while (eol) {
Set(s);
s = eol + 1;
eol = strchr(s, '\n');
}
Set(s);
}
const char *PropSetSimple::Get(const char *key) const {
mapss *props = static_cast<mapss *>(impl);
mapss::const_iterator keyPos = props->find(std::string(key));
if (keyPos != props->end()) {
return keyPos->second.c_str();
} else {
return "";
}
}
// There is some inconsistency between GetExpanded("foo") and Expand("$(foo)").
// A solution is to keep a stack of variables that have been expanded, so that
// recursive expansions can be skipped. For now I'll just use the C++ stack
// for that, through a recursive function and a simple chain of pointers.
struct VarChain {
VarChain(const char *var_=NULL, const VarChain *link_=NULL): var(var_), link(link_) {}
bool contains(const char *testVar) const {
return (var && (0 == strcmp(var, testVar)))
|| (link && link->contains(testVar));
}
const char *var;
const VarChain *link;
};
static int ExpandAllInPlace(const PropSetSimple &props, std::string &withVars, int maxExpands, const VarChain &blankVars) {
size_t varStart = withVars.find("$(");
while ((varStart != std::string::npos) && (maxExpands > 0)) {
size_t varEnd = withVars.find(")", varStart+2);
if (varEnd == std::string::npos) {
break;
}
// For consistency, when we see '$(ab$(cde))', expand the inner variable first,
// regardless whether there is actually a degenerate variable named 'ab$(cde'.
size_t innerVarStart = withVars.find("$(", varStart+2);
while ((innerVarStart != std::string::npos) && (innerVarStart > varStart) && (innerVarStart < varEnd)) {
varStart = innerVarStart;
innerVarStart = withVars.find("$(", varStart+2);
}
std::string var(withVars.c_str(), varStart + 2, varEnd - varStart - 2);
std::string val = props.Get(var.c_str());
if (blankVars.contains(var.c_str())) {
val = ""; // treat blankVar as an empty string (e.g. to block self-reference)
}
if (--maxExpands >= 0) {
maxExpands = ExpandAllInPlace(props, val, maxExpands, VarChain(var.c_str(), &blankVars));
}
withVars.erase(varStart, varEnd-varStart+1);
withVars.insert(varStart, val.c_str(), val.length());
varStart = withVars.find("$(");
}
return maxExpands;
}
int PropSetSimple::GetExpanded(const char *key, char *result) const {
std::string val = Get(key);
ExpandAllInPlace(*this, val, 100, VarChain(key));
const int n = static_cast<int>(val.size());
if (result) {
memcpy(result, val.c_str(), n+1);
}
return n; // Not including NUL
}
int PropSetSimple::GetInt(const char *key, int defaultValue) const {
std::string val = Get(key);
ExpandAllInPlace(*this, val, 100, VarChain(key));
if (!val.empty()) {
return atoi(val.c_str());
}
return defaultValue;
}
+32
View File
@@ -0,0 +1,32 @@
// Scintilla source code edit control
/** @file PropSetSimple.h
** A basic string to string map.
**/
// Copyright 1998-2009 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
#ifndef PROPSETSIMPLE_H
#define PROPSETSIMPLE_H
#ifdef SCI_NAMESPACE
namespace Scintilla {
#endif
class PropSetSimple {
void *impl;
void Set(const char *keyVal);
public:
PropSetSimple();
virtual ~PropSetSimple();
void Set(const char *key, const char *val, int lenKey=-1, int lenVal=-1);
void SetMultiple(const char *);
const char *Get(const char *key) const;
int GetExpanded(const char *key, char *result) const;
int GetInt(const char *key, int defaultValue=0) const;
};
#ifdef SCI_NAMESPACE
}
#endif
#endif
+110
View File
@@ -0,0 +1,110 @@
// Scintilla source code edit control
/** @file SparseState.h
** Hold lexer state that may change rarely.
** This is often per-line state such as whether a particular type of section has been entered.
** A state continues until it is changed.
**/
// Copyright 2011 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
#ifndef SPARSESTATE_H
#define SPARSESTATE_H
#ifdef SCI_NAMESPACE
namespace Scintilla {
#endif
template <typename T>
class SparseState {
struct State {
int position;
T value;
State(int position_, T value_) : position(position_), value(value_) {
}
inline bool operator<(const State &other) const {
return position < other.position;
}
inline bool operator==(const State &other) const {
return (position == other.position) && (value == other.value);
}
};
int positionFirst;
typedef std::vector<State> stateVector;
stateVector states;
typename stateVector::iterator Find(int position) {
State searchValue(position, T());
return std::lower_bound(states.begin(), states.end(), searchValue);
}
public:
explicit SparseState(int positionFirst_=-1) {
positionFirst = positionFirst_;
}
void Set(int position, T value) {
Delete(position);
if (states.empty() || (value != states[states.size()-1].value)) {
states.push_back(State(position, value));
}
}
T ValueAt(int position) {
if (states.empty())
return T();
if (position < states[0].position)
return T();
typename stateVector::iterator low = Find(position);
if (low == states.end()) {
return states[states.size()-1].value;
} else {
if (low->position > position) {
--low;
}
return low->value;
}
}
bool Delete(int position) {
typename stateVector::iterator low = Find(position);
if (low != states.end()) {
states.erase(low, states.end());
return true;
}
return false;
}
size_t size() const {
return states.size();
}
// Returns true if Merge caused a significant change
bool Merge(const SparseState<T> &other, int ignoreAfter) {
// Changes caused beyond ignoreAfter are not significant
Delete(ignoreAfter+1);
bool different = true;
bool changed = false;
typename stateVector::iterator low = Find(other.positionFirst);
if (static_cast<size_t>(states.end() - low) == other.states.size()) {
// Same number in other as after positionFirst in this
different = !std::equal(low, states.end(), other.states.begin());
}
if (different) {
if (low != states.end()) {
states.erase(low, states.end());
changed = true;
}
typename stateVector::const_iterator startOther = other.states.begin();
if (!states.empty() && !other.states.empty() && states.back().value == startOther->value)
++startOther;
if (startOther != other.states.end()) {
states.insert(states.end(), startOther, other.states.end());
changed = true;
}
}
return changed;
}
};
#ifdef SCI_NAMESPACE
}
#endif
#endif
+36
View File
@@ -0,0 +1,36 @@
// Scintilla source code edit control
/** @file StringCopy.h
** Safe string copy function which always NUL terminates.
** ELEMENTS macro for determining array sizes.
**/
// Copyright 2013 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
#ifndef STRINGCOPY_H
#define STRINGCOPY_H
#ifdef SCI_NAMESPACE
namespace Scintilla {
#endif
// Safer version of string copy functions like strcpy, wcsncpy, etc.
// Instantiate over fixed length strings of both char and wchar_t.
// May truncate if source doesn't fit into dest with room for NUL.
template <typename T, size_t count>
void StringCopy(T (&dest)[count], const T* source) {
for (size_t i=0; i<count; i++) {
dest[i] = source[i];
if (!source[i])
break;
}
dest[count-1] = 0;
}
#define ELEMENTS(a) (sizeof(a) / sizeof(a[0]))
#ifdef SCI_NAMESPACE
}
#endif
#endif
+56
View File
@@ -0,0 +1,56 @@
// Scintilla source code edit control
/** @file StyleContext.cxx
** Lexer infrastructure.
**/
// Copyright 1998-2004 by Neil Hodgson <neilh@scintilla.org>
// This file is in the public domain.
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <assert.h>
#include <ctype.h>
#include "ILexer.h"
#include "LexAccessor.h"
#include "Accessor.h"
#include "StyleContext.h"
#ifdef SCI_NAMESPACE
using namespace Scintilla;
#endif
static void getRange(unsigned int start,
unsigned int end,
LexAccessor &styler,
char *s,
unsigned int len) {
unsigned int i = 0;
while ((i < end - start + 1) && (i < len-1)) {
s[i] = styler[start + i];
i++;
}
s[i] = '\0';
}
void StyleContext::GetCurrent(char *s, unsigned int len) {
getRange(styler.GetStartSegment(), currentPos - 1, styler, s, len);
}
static void getRangeLowered(unsigned int start,
unsigned int end,
LexAccessor &styler,
char *s,
unsigned int len) {
unsigned int i = 0;
while ((i < end - start + 1) && (i < len-1)) {
s[i] = static_cast<char>(tolower(styler[start + i]));
i++;
}
s[i] = '\0';
}
void StyleContext::GetCurrentLowered(char *s, unsigned int len) {
getRangeLowered(styler.GetStartSegment(), currentPos - 1, styler, s, len);
}
+231
View File
@@ -0,0 +1,231 @@
// Scintilla source code edit control
/** @file StyleContext.h
** Lexer infrastructure.
**/
// Copyright 1998-2004 by Neil Hodgson <neilh@scintilla.org>
// This file is in the public domain.
#ifndef STYLECONTEXT_H
#define STYLECONTEXT_H
#ifdef SCI_NAMESPACE
namespace Scintilla {
#endif
static inline int MakeLowerCase(int ch) {
if (ch < 'A' || ch > 'Z')
return ch;
else
return ch - 'A' + 'a';
}
// All languages handled so far can treat all characters >= 0x80 as one class
// which just continues the current token or starts an identifier if in default.
// DBCS treated specially as the second character can be < 0x80 and hence
// syntactically significant. UTF-8 avoids this as all trail bytes are >= 0x80
class StyleContext {
LexAccessor &styler;
IDocumentWithLineEnd *multiByteAccess;
unsigned int endPos;
unsigned int lengthDocument;
// Used for optimizing GetRelativeCharacter
unsigned int posRelative;
unsigned int currentPosLastRelative;
int offsetRelative;
StyleContext &operator=(const StyleContext &);
void GetNextChar() {
if (multiByteAccess) {
chNext = multiByteAccess->GetCharacterAndWidth(currentPos+width, &widthNext);
} else {
chNext = static_cast<unsigned char>(styler.SafeGetCharAt(currentPos+width, 0));
widthNext = 1;
}
// End of line determined from line end position, allowing CR, LF,
// CRLF and Unicode line ends as set by document.
if (currentLine < lineDocEnd)
atLineEnd = static_cast<int>(currentPos) >= (lineStartNext-1);
else // Last line
atLineEnd = static_cast<int>(currentPos) >= lineStartNext;
}
public:
unsigned int currentPos;
int currentLine;
int lineDocEnd;
int lineStartNext;
bool atLineStart;
bool atLineEnd;
int state;
int chPrev;
int ch;
int width;
int chNext;
int widthNext;
StyleContext(unsigned int startPos, unsigned int length,
int initStyle, LexAccessor &styler_, char chMask='\377') :
styler(styler_),
multiByteAccess(0),
endPos(startPos + length),
posRelative(0),
currentPosLastRelative(0x7FFFFFFF),
offsetRelative(0),
currentPos(startPos),
currentLine(-1),
lineStartNext(-1),
atLineEnd(false),
state(initStyle & chMask), // Mask off all bits which aren't in the chMask.
chPrev(0),
ch(0),
width(0),
chNext(0),
widthNext(1) {
if (styler.Encoding() != enc8bit) {
multiByteAccess = styler.MultiByteAccess();
}
styler.StartAt(startPos /*, chMask*/);
styler.StartSegment(startPos);
currentLine = styler.GetLine(startPos);
lineStartNext = styler.LineStart(currentLine+1);
lengthDocument = static_cast<unsigned int>(styler.Length());
if (endPos == lengthDocument)
endPos++;
lineDocEnd = styler.GetLine(lengthDocument);
atLineStart = static_cast<unsigned int>(styler.LineStart(currentLine)) == startPos;
// Variable width is now 0 so GetNextChar gets the char at currentPos into chNext/widthNext
width = 0;
GetNextChar();
ch = chNext;
width = widthNext;
GetNextChar();
}
void Complete() {
styler.ColourTo(currentPos - ((currentPos > lengthDocument) ? 2 : 1), state);
styler.Flush();
}
bool More() const {
return currentPos < endPos;
}
void Forward() {
if (currentPos < endPos) {
atLineStart = atLineEnd;
if (atLineStart) {
currentLine++;
lineStartNext = styler.LineStart(currentLine+1);
}
chPrev = ch;
currentPos += width;
ch = chNext;
width = widthNext;
GetNextChar();
} else {
atLineStart = false;
chPrev = ' ';
ch = ' ';
chNext = ' ';
atLineEnd = true;
}
}
void Forward(int nb) {
for (int i = 0; i < nb; i++) {
Forward();
}
}
void ForwardBytes(int nb) {
size_t forwardPos = currentPos + nb;
while (forwardPos > currentPos) {
Forward();
}
}
void ChangeState(int state_) {
state = state_;
}
void SetState(int state_) {
styler.ColourTo(currentPos - ((currentPos > lengthDocument) ? 2 : 1), state);
state = state_;
}
void ForwardSetState(int state_) {
Forward();
styler.ColourTo(currentPos - ((currentPos > lengthDocument) ? 2 : 1), state);
state = state_;
}
int LengthCurrent() const {
return currentPos - styler.GetStartSegment();
}
int GetRelative(int n) {
return static_cast<unsigned char>(styler.SafeGetCharAt(currentPos+n, 0));
}
int GetRelativeCharacter(int n) {
if (n == 0)
return ch;
if (multiByteAccess) {
if ((currentPosLastRelative != currentPos) ||
((n > 0) && ((offsetRelative < 0) || (n < offsetRelative))) ||
((n < 0) && ((offsetRelative > 0) || (n > offsetRelative)))) {
posRelative = currentPos;
offsetRelative = 0;
}
int diffRelative = n - offsetRelative;
int posNew = multiByteAccess->GetRelativePosition(posRelative, diffRelative);
int chReturn = multiByteAccess->GetCharacterAndWidth(posNew, 0);
posRelative = posNew;
currentPosLastRelative = currentPos;
offsetRelative = n;
return chReturn;
} else {
// fast version for single byte encodings
return static_cast<unsigned char>(styler.SafeGetCharAt(currentPos + n, 0));
}
}
bool Match(char ch0) const {
return ch == static_cast<unsigned char>(ch0);
}
bool Match(char ch0, char ch1) const {
return (ch == static_cast<unsigned char>(ch0)) && (chNext == static_cast<unsigned char>(ch1));
}
bool Match(const char *s) {
if (ch != static_cast<unsigned char>(*s))
return false;
s++;
if (!*s)
return true;
if (chNext != static_cast<unsigned char>(*s))
return false;
s++;
for (int n=2; *s; n++) {
if (*s != styler.SafeGetCharAt(currentPos+n, 0))
return false;
s++;
}
return true;
}
bool MatchIgnoreCase(const char *s) {
if (MakeLowerCase(ch) != static_cast<unsigned char>(*s))
return false;
s++;
if (MakeLowerCase(chNext) != static_cast<unsigned char>(*s))
return false;
s++;
for (int n=2; *s; n++) {
if (static_cast<unsigned char>(*s) !=
MakeLowerCase(static_cast<unsigned char>(styler.SafeGetCharAt(currentPos+n, 0))))
return false;
s++;
}
return true;
}
// Non-inline
void GetCurrent(char *s, unsigned int len);
void GetCurrentLowered(char *s, unsigned int len);
};
#ifdef SCI_NAMESPACE
}
#endif
#endif
+177
View File
@@ -0,0 +1,177 @@
// Scintilla source code edit control
/** @file SubStyles.h
** Manage substyles for a lexer.
**/
// Copyright 2012 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
#ifndef SUBSTYLES_H
#define SUBSTYLES_H
#ifdef SCI_NAMESPACE
namespace Scintilla {
#endif
class WordClassifier {
int baseStyle;
int firstStyle;
int lenStyles;
std::map<std::string, int> wordToStyle;
public:
explicit WordClassifier(int baseStyle_) : baseStyle(baseStyle_), firstStyle(0), lenStyles(0) {
}
void Allocate(int firstStyle_, int lenStyles_) {
firstStyle = firstStyle_;
lenStyles = lenStyles_;
wordToStyle.clear();
}
int Base() const {
return baseStyle;
}
int Start() const {
return firstStyle;
}
int Length() const {
return lenStyles;
}
void Clear() {
firstStyle = 0;
lenStyles = 0;
wordToStyle.clear();
}
int ValueFor(const std::string &s) const {
std::map<std::string, int>::const_iterator it = wordToStyle.find(s);
if (it != wordToStyle.end())
return it->second;
else
return -1;
}
bool IncludesStyle(int style) const {
return (style >= firstStyle) && (style < (firstStyle + lenStyles));
}
void SetIdentifiers(int style, const char *identifiers) {
while (*identifiers) {
const char *cpSpace = identifiers;
while (*cpSpace && !(*cpSpace == ' ' || *cpSpace == '\t' || *cpSpace == '\r' || *cpSpace == '\n'))
cpSpace++;
if (cpSpace > identifiers) {
std::string word(identifiers, cpSpace - identifiers);
wordToStyle[word] = style;
}
identifiers = cpSpace;
if (*identifiers)
identifiers++;
}
}
};
class SubStyles {
int classifications;
const char *baseStyles;
int styleFirst;
int stylesAvailable;
int secondaryDistance;
int allocated;
std::vector<WordClassifier> classifiers;
int BlockFromBaseStyle(int baseStyle) const {
for (int b=0; b < classifications; b++) {
if (baseStyle == baseStyles[b])
return b;
}
return -1;
}
int BlockFromStyle(int style) const {
int b = 0;
for (std::vector<WordClassifier>::const_iterator it=classifiers.begin(); it != classifiers.end(); ++it) {
if (it->IncludesStyle(style))
return b;
b++;
}
return -1;
}
public:
SubStyles(const char *baseStyles_, int styleFirst_, int stylesAvailable_, int secondaryDistance_) :
classifications(0),
baseStyles(baseStyles_),
styleFirst(styleFirst_),
stylesAvailable(stylesAvailable_),
secondaryDistance(secondaryDistance_),
allocated(0) {
while (baseStyles[classifications]) {
classifiers.push_back(WordClassifier(baseStyles[classifications]));
classifications++;
}
}
int Allocate(int styleBase, int numberStyles) {
int block = BlockFromBaseStyle(styleBase);
if (block >= 0) {
if ((allocated + numberStyles) > stylesAvailable)
return -1;
int startBlock = styleFirst + allocated;
allocated += numberStyles;
classifiers[block].Allocate(startBlock, numberStyles);
return startBlock;
} else {
return -1;
}
}
int Start(int styleBase) {
int block = BlockFromBaseStyle(styleBase);
return (block >= 0) ? classifiers[block].Start() : -1;
}
int Length(int styleBase) {
int block = BlockFromBaseStyle(styleBase);
return (block >= 0) ? classifiers[block].Length() : 0;
}
int BaseStyle(int subStyle) const {
int block = BlockFromStyle(subStyle);
if (block >= 0)
return classifiers[block].Base();
else
return subStyle;
}
int DistanceToSecondaryStyles() const {
return secondaryDistance;
}
void SetIdentifiers(int style, const char *identifiers) {
int block = BlockFromStyle(style);
if (block >= 0)
classifiers[block].SetIdentifiers(style, identifiers);
}
void Free() {
allocated = 0;
for (std::vector<WordClassifier>::iterator it=classifiers.begin(); it != classifiers.end(); ++it)
it->Clear();
}
const WordClassifier &Classifier(int baseStyle) const {
return classifiers[BlockFromBaseStyle(baseStyle)];
}
};
#ifdef SCI_NAMESPACE
}
#endif
#endif
+242
View File
@@ -0,0 +1,242 @@
// Scintilla source code edit control
/** @file KeyWords.cxx
** Colourise for particular languages.
**/
// Copyright 1998-2002 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <stdarg.h>
#include <ctype.h>
#include <algorithm>
#include "StringCopy.h"
#include "WordList.h"
#ifdef SCI_NAMESPACE
using namespace Scintilla;
#endif
/**
* Creates an array that points into each word in the string and puts \0 terminators
* after each word.
*/
static char **ArrayFromWordList(char *wordlist, int *len, bool onlyLineEnds = false) {
int prev = '\n';
int words = 0;
// For rapid determination of whether a character is a separator, build
// a look up table.
bool wordSeparator[256];
for (int i=0; i<256; i++) {
wordSeparator[i] = false;
}
wordSeparator[static_cast<unsigned int>('\r')] = true;
wordSeparator[static_cast<unsigned int>('\n')] = true;
if (!onlyLineEnds) {
wordSeparator[static_cast<unsigned int>(' ')] = true;
wordSeparator[static_cast<unsigned int>('\t')] = true;
}
for (int j = 0; wordlist[j]; j++) {
int curr = static_cast<unsigned char>(wordlist[j]);
if (!wordSeparator[curr] && wordSeparator[prev])
words++;
prev = curr;
}
char **keywords = new char *[words + 1];
int wordsStore = 0;
const size_t slen = strlen(wordlist);
if (words) {
prev = '\0';
for (size_t k = 0; k < slen; k++) {
if (!wordSeparator[static_cast<unsigned char>(wordlist[k])]) {
if (!prev) {
keywords[wordsStore] = &wordlist[k];
wordsStore++;
}
} else {
wordlist[k] = '\0';
}
prev = wordlist[k];
}
}
keywords[wordsStore] = &wordlist[slen];
*len = wordsStore;
return keywords;
}
WordList::WordList(bool onlyLineEnds_) :
words(0), list(0), len(0), onlyLineEnds(onlyLineEnds_) {
// Prevent warnings by static analyzers about uninitialized starts.
starts[0] = -1;
}
WordList::~WordList() {
Clear();
}
WordList::operator bool() const {
return len ? true : false;
}
bool WordList::operator!=(const WordList &other) const {
if (len != other.len)
return true;
for (int i=0; i<len; i++) {
if (strcmp(words[i], other.words[i]) != 0)
return true;
}
return false;
}
int WordList::Length() const {
return len;
}
void WordList::Clear() {
if (words) {
delete []list;
delete []words;
}
words = 0;
list = 0;
len = 0;
}
#ifdef _MSC_VER
static bool cmpWords(const char *a, const char *b) {
return strcmp(a, b) < 0;
}
#else
static int cmpWords(const void *a, const void *b) {
return strcmp(*static_cast<const char * const *>(a), *static_cast<const char * const *>(b));
}
static void SortWordList(char **words, unsigned int len) {
qsort(reinterpret_cast<void *>(words), len, sizeof(*words), cmpWords);
}
#endif
void WordList::Set(const char *s) {
Clear();
const size_t lenS = strlen(s) + 1;
list = new char[lenS];
memcpy(list, s, lenS);
words = ArrayFromWordList(list, &len, onlyLineEnds);
#ifdef _MSC_VER
std::sort(words, words + len, cmpWords);
#else
SortWordList(words, len);
#endif
for (unsigned int k = 0; k < ELEMENTS(starts); k++)
starts[k] = -1;
for (int l = len - 1; l >= 0; l--) {
unsigned char indexChar = words[l][0];
starts[indexChar] = l;
}
}
/** Check whether a string is in the list.
* List elements are either exact matches or prefixes.
* Prefix elements start with '^' and match all strings that start with the rest of the element
* so '^GTK_' matches 'GTK_X', 'GTK_MAJOR_VERSION', and 'GTK_'.
*/
bool WordList::InList(const char *s) const {
if (0 == words)
return false;
unsigned char firstChar = s[0];
int j = starts[firstChar];
if (j >= 0) {
while (static_cast<unsigned char>(words[j][0]) == firstChar) {
if (s[1] == words[j][1]) {
const char *a = words[j] + 1;
const char *b = s + 1;
while (*a && *a == *b) {
a++;
b++;
}
if (!*a && !*b)
return true;
}
j++;
}
}
j = starts[static_cast<unsigned int>('^')];
if (j >= 0) {
while (words[j][0] == '^') {
const char *a = words[j] + 1;
const char *b = s;
while (*a && *a == *b) {
a++;
b++;
}
if (!*a)
return true;
j++;
}
}
return false;
}
/** similar to InList, but word s can be a substring of keyword.
* eg. the keyword define is defined as def~ine. This means the word must start
* with def to be a keyword, but also defi, defin and define are valid.
* The marker is ~ in this case.
*/
bool WordList::InListAbbreviated(const char *s, const char marker) const {
if (0 == words)
return false;
unsigned char firstChar = s[0];
int j = starts[firstChar];
if (j >= 0) {
while (static_cast<unsigned char>(words[j][0]) == firstChar) {
bool isSubword = false;
int start = 1;
if (words[j][1] == marker) {
isSubword = true;
start++;
}
if (s[1] == words[j][start]) {
const char *a = words[j] + start;
const char *b = s + 1;
while (*a && *a == *b) {
a++;
if (*a == marker) {
isSubword = true;
a++;
}
b++;
}
if ((!*a || isSubword) && !*b)
return true;
}
j++;
}
}
j = starts[static_cast<unsigned int>('^')];
if (j >= 0) {
while (words[j][0] == '^') {
const char *a = words[j] + 1;
const char *b = s;
while (*a && *a == *b) {
a++;
b++;
}
if (!*a)
return true;
j++;
}
}
return false;
}
const char *WordList::WordAt(int n) const {
return words[n];
}
+41
View File
@@ -0,0 +1,41 @@
// Scintilla source code edit control
/** @file WordList.h
** Hold a list of words.
**/
// Copyright 1998-2010 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
#ifndef WORDLIST_H
#define WORDLIST_H
#ifdef SCI_NAMESPACE
namespace Scintilla {
#endif
/**
*/
class WordList {
// Each word contains at least one character - a empty word acts as sentinel at the end.
char **words;
char *list;
int len;
bool onlyLineEnds; ///< Delimited by any white space or only line ends
int starts[256];
public:
explicit WordList(bool onlyLineEnds_ = false);
~WordList();
operator bool() const;
bool operator!=(const WordList &other) const;
int Length() const;
void Clear();
void Set(const char *s);
bool InList(const char *s) const;
bool InListAbbreviated(const char *s, const char marker) const;
const char *WordAt(int n) const;
};
#ifdef SCI_NAMESPACE
}
#endif
#endif
+292
View File
@@ -0,0 +1,292 @@
// Scintilla source code edit control
/** @file AutoComplete.cxx
** Defines the auto completion list box.
**/
// Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <assert.h>
#include <string>
#include <vector>
#include <algorithm>
#include "Platform.h"
#include "Scintilla.h"
#include "CharacterSet.h"
#include "AutoComplete.h"
#ifdef SCI_NAMESPACE
using namespace Scintilla;
#endif
AutoComplete::AutoComplete() :
active(false),
separator(' '),
typesep('?'),
ignoreCase(false),
chooseSingle(false),
lb(0),
posStart(0),
startLen(0),
cancelAtStartPos(true),
autoHide(true),
dropRestOfWord(false),
ignoreCaseBehaviour(SC_CASEINSENSITIVEBEHAVIOUR_RESPECTCASE),
widthLBDefault(100),
heightLBDefault(100),
autoSort(SC_ORDER_PRESORTED) {
lb = ListBox::Allocate();
}
AutoComplete::~AutoComplete() {
if (lb) {
lb->Destroy();
delete lb;
lb = 0;
}
}
bool AutoComplete::Active() const {
return active;
}
void AutoComplete::Start(Window &parent, int ctrlID,
int position, Point location, int startLen_,
int lineHeight, bool unicodeMode, int technology) {
if (active) {
Cancel();
}
lb->Create(parent, ctrlID, location, lineHeight, unicodeMode, technology);
lb->Clear();
active = true;
startLen = startLen_;
posStart = position;
}
void AutoComplete::SetStopChars(const char *stopChars_) {
stopChars = stopChars_;
}
bool AutoComplete::IsStopChar(char ch) {
return ch && (stopChars.find(ch) != std::string::npos);
}
void AutoComplete::SetFillUpChars(const char *fillUpChars_) {
fillUpChars = fillUpChars_;
}
bool AutoComplete::IsFillUpChar(char ch) {
return ch && (fillUpChars.find(ch) != std::string::npos);
}
void AutoComplete::SetSeparator(char separator_) {
separator = separator_;
}
char AutoComplete::GetSeparator() const {
return separator;
}
void AutoComplete::SetTypesep(char separator_) {
typesep = separator_;
}
char AutoComplete::GetTypesep() const {
return typesep;
}
struct Sorter {
AutoComplete *ac;
const char *list;
std::vector<int> indices;
Sorter(AutoComplete *ac_, const char *list_) : ac(ac_), list(list_) {
int i = 0;
while (list[i]) {
indices.push_back(i); // word start
while (list[i] != ac->GetTypesep() && list[i] != ac->GetSeparator() && list[i])
++i;
indices.push_back(i); // word end
if (list[i] == ac->GetTypesep()) {
while (list[i] != ac->GetSeparator() && list[i])
++i;
}
if (list[i] == ac->GetSeparator()) {
++i;
// preserve trailing separator as blank entry
if (!list[i]) {
indices.push_back(i);
indices.push_back(i);
}
}
}
indices.push_back(i); // index of last position
}
bool operator()(int a, int b) {
int lenA = indices[a * 2 + 1] - indices[a * 2];
int lenB = indices[b * 2 + 1] - indices[b * 2];
int len = std::min(lenA, lenB);
int cmp;
if (ac->ignoreCase)
cmp = CompareNCaseInsensitive(list + indices[a * 2], list + indices[b * 2], len);
else
cmp = strncmp(list + indices[a * 2], list + indices[b * 2], len);
if (cmp == 0)
cmp = lenA - lenB;
return cmp < 0;
}
};
void AutoComplete::SetList(const char *list) {
if (autoSort == SC_ORDER_PRESORTED) {
lb->SetList(list, separator, typesep);
sortMatrix.clear();
for (int i = 0; i < lb->Length(); ++i)
sortMatrix.push_back(i);
return;
}
Sorter IndexSort(this, list);
sortMatrix.clear();
for (int i = 0; i < (int)IndexSort.indices.size() / 2; ++i)
sortMatrix.push_back(i);
std::sort(sortMatrix.begin(), sortMatrix.end(), IndexSort);
if (autoSort == SC_ORDER_CUSTOM || sortMatrix.size() < 2) {
lb->SetList(list, separator, typesep);
PLATFORM_ASSERT(lb->Length() == static_cast<int>(sortMatrix.size()));
return;
}
std::string sortedList;
char item[maxItemLen];
for (size_t i = 0; i < sortMatrix.size(); ++i) {
int wordLen = IndexSort.indices[sortMatrix[i] * 2 + 2] - IndexSort.indices[sortMatrix[i] * 2];
strncpy(item, list + IndexSort.indices[sortMatrix[i] * 2], wordLen);
if ((i+1) == sortMatrix.size()) {
// Last item so remove separator if present
if ((wordLen > 0) && (item[wordLen-1] == separator))
wordLen--;
} else {
// Item before last needs a separator
if ((wordLen == 0) || (item[wordLen-1] != separator)) {
item[wordLen] = separator;
wordLen++;
}
}
item[wordLen] = '\0';
sortedList += item;
}
for (int i = 0; i < (int)sortMatrix.size(); ++i)
sortMatrix[i] = i;
lb->SetList(sortedList.c_str(), separator, typesep);
}
int AutoComplete::GetSelection() const {
return lb->GetSelection();
}
std::string AutoComplete::GetValue(int item) const {
char value[maxItemLen];
lb->GetValue(item, value, sizeof(value));
return std::string(value);
}
void AutoComplete::Show(bool show) {
lb->Show(show);
if (show)
lb->Select(0);
}
void AutoComplete::Cancel() {
if (lb->Created()) {
lb->Clear();
lb->Destroy();
active = false;
}
}
void AutoComplete::Move(int delta) {
int count = lb->Length();
int current = lb->GetSelection();
current += delta;
if (current >= count)
current = count - 1;
if (current < 0)
current = 0;
lb->Select(current);
}
void AutoComplete::Select(const char *word) {
size_t lenWord = strlen(word);
int location = -1;
int start = 0; // lower bound of the api array block to search
int end = lb->Length() - 1; // upper bound of the api array block to search
while ((start <= end) && (location == -1)) { // Binary searching loop
int pivot = (start + end) / 2;
char item[maxItemLen];
lb->GetValue(sortMatrix[pivot], item, maxItemLen);
int cond;
if (ignoreCase)
cond = CompareNCaseInsensitive(word, item, lenWord);
else
cond = strncmp(word, item, lenWord);
if (!cond) {
// Find first match
while (pivot > start) {
lb->GetValue(sortMatrix[pivot-1], item, maxItemLen);
if (ignoreCase)
cond = CompareNCaseInsensitive(word, item, lenWord);
else
cond = strncmp(word, item, lenWord);
if (0 != cond)
break;
--pivot;
}
location = pivot;
if (ignoreCase
&& ignoreCaseBehaviour == SC_CASEINSENSITIVEBEHAVIOUR_RESPECTCASE) {
// Check for exact-case match
for (; pivot <= end; pivot++) {
lb->GetValue(sortMatrix[pivot], item, maxItemLen);
if (!strncmp(word, item, lenWord)) {
location = pivot;
break;
}
if (CompareNCaseInsensitive(word, item, lenWord))
break;
}
}
} else if (cond < 0) {
end = pivot - 1;
} else if (cond > 0) {
start = pivot + 1;
}
}
if (location == -1) {
if (autoHide)
Cancel();
else
lb->Select(-1);
} else {
if (autoSort == SC_ORDER_CUSTOM) {
// Check for a logically earlier match
char item[maxItemLen];
for (int i = location + 1; i <= end; ++i) {
lb->GetValue(sortMatrix[i], item, maxItemLen);
if (CompareNCaseInsensitive(word, item, lenWord))
break;
if (sortMatrix[i] < sortMatrix[location] && !strncmp(word, item, lenWord))
location = i;
}
}
lb->Select(sortMatrix[location]);
}
}
+95
View File
@@ -0,0 +1,95 @@
// Scintilla source code edit control
/** @file AutoComplete.h
** Defines the auto completion list box.
**/
// Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
#ifndef AUTOCOMPLETE_H
#define AUTOCOMPLETE_H
#ifdef SCI_NAMESPACE
namespace Scintilla {
#endif
/**
*/
class AutoComplete {
bool active;
std::string stopChars;
std::string fillUpChars;
char separator;
char typesep; // Type seperator
enum { maxItemLen=1000 };
std::vector<int> sortMatrix;
public:
bool ignoreCase;
bool chooseSingle;
ListBox *lb;
int posStart;
int startLen;
/// Should autocompletion be canceled if editor's currentPos <= startPos?
bool cancelAtStartPos;
bool autoHide;
bool dropRestOfWord;
unsigned int ignoreCaseBehaviour;
int widthLBDefault;
int heightLBDefault;
/** SC_ORDER_PRESORTED: Assume the list is presorted; selection will fail if it is not alphabetical<br />
* SC_ORDER_PERFORMSORT: Sort the list alphabetically; start up performance cost for sorting<br />
* SC_ORDER_CUSTOM: Handle non-alphabetical entries; start up performance cost for generating a sorted lookup table
*/
int autoSort;
AutoComplete();
~AutoComplete();
/// Is the auto completion list displayed?
bool Active() const;
/// Display the auto completion list positioned to be near a character position
void Start(Window &parent, int ctrlID, int position, Point location,
int startLen_, int lineHeight, bool unicodeMode, int technology);
/// The stop chars are characters which, when typed, cause the auto completion list to disappear
void SetStopChars(const char *stopChars_);
bool IsStopChar(char ch);
/// The fillup chars are characters which, when typed, fill up the selected word
void SetFillUpChars(const char *fillUpChars_);
bool IsFillUpChar(char ch);
/// The separator character is used when interpreting the list in SetList
void SetSeparator(char separator_);
char GetSeparator() const;
/// The typesep character is used for separating the word from the type
void SetTypesep(char separator_);
char GetTypesep() const;
/// The list string contains a sequence of words separated by the separator character
void SetList(const char *list);
/// Return the position of the currently selected list item
int GetSelection() const;
/// Return the value of an item in the list
std::string GetValue(int item) const;
void Show(bool show);
void Cancel();
/// Move the current list element by delta, scrolling appropriately
void Move(int delta);
/// Select a list element that starts with word as the current element
void Select(const char *word);
};
#ifdef SCI_NAMESPACE
}
#endif
#endif
+334
View File
@@ -0,0 +1,334 @@
// Scintilla source code edit control
/** @file CallTip.cxx
** Code for displaying call tips.
**/
// Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <string>
#include "Platform.h"
#include "Scintilla.h"
#include "StringCopy.h"
#include "CallTip.h"
#ifdef SCI_NAMESPACE
using namespace Scintilla;
#endif
CallTip::CallTip() {
wCallTip = 0;
inCallTipMode = false;
posStartCallTip = 0;
rectUp = PRectangle(0,0,0,0);
rectDown = PRectangle(0,0,0,0);
lineHeight = 1;
offsetMain = 0;
startHighlight = 0;
endHighlight = 0;
tabSize = 0;
above = false;
useStyleCallTip = false; // for backwards compatibility
insetX = 5;
widthArrow = 14;
borderHeight = 2; // Extra line for border and an empty line at top and bottom.
verticalOffset = 1;
#ifdef __APPLE__
// proper apple colours for the default
colourBG = ColourDesired(0xff, 0xff, 0xc6);
colourUnSel = ColourDesired(0, 0, 0);
#else
colourBG = ColourDesired(0xff, 0xff, 0xff);
colourUnSel = ColourDesired(0x80, 0x80, 0x80);
#endif
colourSel = ColourDesired(0, 0, 0x80);
colourShade = ColourDesired(0, 0, 0);
colourLight = ColourDesired(0xc0, 0xc0, 0xc0);
codePage = 0;
clickPlace = 0;
}
CallTip::~CallTip() {
font.Release();
wCallTip.Destroy();
}
// Although this test includes 0, we should never see a \0 character.
static bool IsArrowCharacter(char ch) {
return (ch == 0) || (ch == '\001') || (ch == '\002');
}
// We ignore tabs unless a tab width has been set.
bool CallTip::IsTabCharacter(char ch) const {
return (tabSize > 0) && (ch == '\t');
}
int CallTip::NextTabPos(int x) const {
if (tabSize > 0) { // paranoia... not called unless this is true
x -= insetX; // position relative to text
x = (x + tabSize) / tabSize; // tab "number"
return tabSize*x + insetX; // position of next tab
} else {
return x + 1; // arbitrary
}
}
// Draw a section of the call tip that does not include \n in one colour.
// The text may include up to numEnds tabs or arrow characters.
void CallTip::DrawChunk(Surface *surface, int &x, const char *s,
int posStart, int posEnd, int ytext, PRectangle rcClient,
bool highlight, bool draw) {
s += posStart;
int len = posEnd - posStart;
// Divide the text into sections that are all text, or that are
// single arrows or single tab characters (if tabSize > 0).
int maxEnd = 0;
const int numEnds = 10;
int ends[numEnds + 2];
for (int i=0; i<len; i++) {
if ((maxEnd < numEnds) &&
(IsArrowCharacter(s[i]) || IsTabCharacter(s[i]))) {
if (i > 0)
ends[maxEnd++] = i;
ends[maxEnd++] = i+1;
}
}
ends[maxEnd++] = len;
int startSeg = 0;
int xEnd;
for (int seg = 0; seg<maxEnd; seg++) {
int endSeg = ends[seg];
if (endSeg > startSeg) {
if (IsArrowCharacter(s[startSeg])) {
xEnd = x + widthArrow;
bool upArrow = s[startSeg] == '\001';
rcClient.left = static_cast<XYPOSITION>(x);
rcClient.right = static_cast<XYPOSITION>(xEnd);
if (draw) {
const int halfWidth = widthArrow / 2 - 3;
const int quarterWidth = halfWidth / 2;
const int centreX = x + widthArrow / 2 - 1;
const int centreY = static_cast<int>(rcClient.top + rcClient.bottom) / 2;
surface->FillRectangle(rcClient, colourBG);
PRectangle rcClientInner(rcClient.left + 1, rcClient.top + 1,
rcClient.right - 2, rcClient.bottom - 1);
surface->FillRectangle(rcClientInner, colourUnSel);
if (upArrow) { // Up arrow
Point pts[] = {
Point::FromInts(centreX - halfWidth, centreY + quarterWidth),
Point::FromInts(centreX + halfWidth, centreY + quarterWidth),
Point::FromInts(centreX, centreY - halfWidth + quarterWidth),
};
surface->Polygon(pts, ELEMENTS(pts), colourBG, colourBG);
} else { // Down arrow
Point pts[] = {
Point::FromInts(centreX - halfWidth, centreY - quarterWidth),
Point::FromInts(centreX + halfWidth, centreY - quarterWidth),
Point::FromInts(centreX, centreY + halfWidth - quarterWidth),
};
surface->Polygon(pts, ELEMENTS(pts), colourBG, colourBG);
}
}
offsetMain = xEnd;
if (upArrow) {
rectUp = rcClient;
} else {
rectDown = rcClient;
}
} else if (IsTabCharacter(s[startSeg])) {
xEnd = NextTabPos(x);
} else {
xEnd = x + RoundXYPosition(surface->WidthText(font, s + startSeg, endSeg - startSeg));
if (draw) {
rcClient.left = static_cast<XYPOSITION>(x);
rcClient.right = static_cast<XYPOSITION>(xEnd);
surface->DrawTextTransparent(rcClient, font, static_cast<XYPOSITION>(ytext),
s+startSeg, endSeg - startSeg,
highlight ? colourSel : colourUnSel);
}
}
x = xEnd;
startSeg = endSeg;
}
}
}
int CallTip::PaintContents(Surface *surfaceWindow, bool draw) {
PRectangle rcClientPos = wCallTip.GetClientPosition();
PRectangle rcClientSize(0.0f, 0.0f, rcClientPos.right - rcClientPos.left,
rcClientPos.bottom - rcClientPos.top);
PRectangle rcClient(1.0f, 1.0f, rcClientSize.right - 1, rcClientSize.bottom - 1);
// To make a nice small call tip window, it is only sized to fit most normal characters without accents
int ascent = RoundXYPosition(surfaceWindow->Ascent(font) - surfaceWindow->InternalLeading(font));
// For each line...
// Draw the definition in three parts: before highlight, highlighted, after highlight
int ytext = static_cast<int>(rcClient.top) + ascent + 1;
rcClient.bottom = ytext + surfaceWindow->Descent(font) + 1;
const char *chunkVal = val.c_str();
bool moreChunks = true;
int maxWidth = 0;
while (moreChunks) {
const char *chunkEnd = strchr(chunkVal, '\n');
if (chunkEnd == NULL) {
chunkEnd = chunkVal + strlen(chunkVal);
moreChunks = false;
}
int chunkOffset = static_cast<int>(chunkVal - val.c_str());
int chunkLength = static_cast<int>(chunkEnd - chunkVal);
int chunkEndOffset = chunkOffset + chunkLength;
int thisStartHighlight = Platform::Maximum(startHighlight, chunkOffset);
thisStartHighlight = Platform::Minimum(thisStartHighlight, chunkEndOffset);
thisStartHighlight -= chunkOffset;
int thisEndHighlight = Platform::Maximum(endHighlight, chunkOffset);
thisEndHighlight = Platform::Minimum(thisEndHighlight, chunkEndOffset);
thisEndHighlight -= chunkOffset;
rcClient.top = static_cast<XYPOSITION>(ytext - ascent - 1);
int x = insetX; // start each line at this inset
DrawChunk(surfaceWindow, x, chunkVal, 0, thisStartHighlight,
ytext, rcClient, false, draw);
DrawChunk(surfaceWindow, x, chunkVal, thisStartHighlight, thisEndHighlight,
ytext, rcClient, true, draw);
DrawChunk(surfaceWindow, x, chunkVal, thisEndHighlight, chunkLength,
ytext, rcClient, false, draw);
chunkVal = chunkEnd + 1;
ytext += lineHeight;
rcClient.bottom += lineHeight;
maxWidth = Platform::Maximum(maxWidth, x);
}
return maxWidth;
}
void CallTip::PaintCT(Surface *surfaceWindow) {
if (val.empty())
return;
PRectangle rcClientPos = wCallTip.GetClientPosition();
PRectangle rcClientSize(0.0f, 0.0f, rcClientPos.right - rcClientPos.left,
rcClientPos.bottom - rcClientPos.top);
PRectangle rcClient(1.0f, 1.0f, rcClientSize.right - 1, rcClientSize.bottom - 1);
surfaceWindow->FillRectangle(rcClient, colourBG);
offsetMain = insetX; // initial alignment assuming no arrows
PaintContents(surfaceWindow, true);
#ifndef __APPLE__
// OSX doesn't put borders on "help tags"
// Draw a raised border around the edges of the window
surfaceWindow->MoveTo(0, static_cast<int>(rcClientSize.bottom) - 1);
surfaceWindow->PenColour(colourShade);
surfaceWindow->LineTo(static_cast<int>(rcClientSize.right) - 1, static_cast<int>(rcClientSize.bottom) - 1);
surfaceWindow->LineTo(static_cast<int>(rcClientSize.right) - 1, 0);
surfaceWindow->PenColour(colourLight);
surfaceWindow->LineTo(0, 0);
surfaceWindow->LineTo(0, static_cast<int>(rcClientSize.bottom) - 1);
#endif
}
void CallTip::MouseClick(Point pt) {
clickPlace = 0;
if (rectUp.Contains(pt))
clickPlace = 1;
if (rectDown.Contains(pt))
clickPlace = 2;
}
PRectangle CallTip::CallTipStart(int pos, Point pt, int textHeight, const char *defn,
const char *faceName, int size,
int codePage_, int characterSet,
int technology, Window &wParent) {
clickPlace = 0;
val = defn;
codePage = codePage_;
Surface *surfaceMeasure = Surface::Allocate(technology);
if (!surfaceMeasure)
return PRectangle();
surfaceMeasure->Init(wParent.GetID());
surfaceMeasure->SetUnicodeMode(SC_CP_UTF8 == codePage);
surfaceMeasure->SetDBCSMode(codePage);
startHighlight = 0;
endHighlight = 0;
inCallTipMode = true;
posStartCallTip = pos;
XYPOSITION deviceHeight = static_cast<XYPOSITION>(surfaceMeasure->DeviceHeightFont(size));
FontParameters fp(faceName, deviceHeight / SC_FONT_SIZE_MULTIPLIER, SC_WEIGHT_NORMAL, false, 0, technology, characterSet);
font.Create(fp);
// Look for multiple lines in the text
// Only support \n here - simply means container must avoid \r!
int numLines = 1;
const char *newline;
const char *look = val.c_str();
rectUp = PRectangle(0,0,0,0);
rectDown = PRectangle(0,0,0,0);
offsetMain = insetX; // changed to right edge of any arrows
int width = PaintContents(surfaceMeasure, false) + insetX;
while ((newline = strchr(look, '\n')) != NULL) {
look = newline + 1;
numLines++;
}
lineHeight = RoundXYPosition(surfaceMeasure->Height(font));
// The returned
// rectangle is aligned to the right edge of the last arrow encountered in
// the tip text, else to the tip text left edge.
int height = lineHeight * numLines - static_cast<int>(surfaceMeasure->InternalLeading(font)) + borderHeight * 2;
delete surfaceMeasure;
if (above) {
return PRectangle(pt.x - offsetMain, pt.y - verticalOffset - height, pt.x + width - offsetMain, pt.y - verticalOffset);
} else {
return PRectangle(pt.x - offsetMain, pt.y + verticalOffset + textHeight, pt.x + width - offsetMain, pt.y + verticalOffset + textHeight + height);
}
}
void CallTip::CallTipCancel() {
inCallTipMode = false;
if (wCallTip.Created()) {
wCallTip.Destroy();
}
}
void CallTip::SetHighlight(int start, int end) {
// Avoid flashing by checking something has really changed
if ((start != startHighlight) || (end != endHighlight)) {
startHighlight = start;
endHighlight = (end > start) ? end : start;
if (wCallTip.Created()) {
wCallTip.InvalidateAll();
}
}
}
// Set the tab size (sizes > 0 enable the use of tabs). This also enables the
// use of the STYLE_CALLTIP.
void CallTip::SetTabSize(int tabSz) {
tabSize = tabSz;
useStyleCallTip = true;
}
// Set the calltip position, below the text by default or if above is false
// else above the text.
void CallTip::SetPosition(bool aboveText) {
above = aboveText;
}
// It might be better to have two access functions for this and to use
// them for all settings of colours.
void CallTip::SetForeBack(const ColourDesired &fore, const ColourDesired &back) {
colourBG = back;
colourUnSel = fore;
}
+93
View File
@@ -0,0 +1,93 @@
// Scintilla source code edit control
/** @file CallTip.h
** Interface to the call tip control.
**/
// Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
#ifndef CALLTIP_H
#define CALLTIP_H
#ifdef SCI_NAMESPACE
namespace Scintilla {
#endif
/**
*/
class CallTip {
int startHighlight; // character offset to start and...
int endHighlight; // ...end of highlighted text
std::string val;
Font font;
PRectangle rectUp; // rectangle of last up angle in the tip
PRectangle rectDown; // rectangle of last down arrow in the tip
int lineHeight; // vertical line spacing
int offsetMain; // The alignment point of the call tip
int tabSize; // Tab size in pixels, <=0 no TAB expand
bool useStyleCallTip; // if true, STYLE_CALLTIP should be used
bool above; // if true, display calltip above text
// Private so CallTip objects can not be copied
CallTip(const CallTip &);
CallTip &operator=(const CallTip &);
void DrawChunk(Surface *surface, int &x, const char *s,
int posStart, int posEnd, int ytext, PRectangle rcClient,
bool highlight, bool draw);
int PaintContents(Surface *surfaceWindow, bool draw);
bool IsTabCharacter(char c) const;
int NextTabPos(int x) const;
public:
Window wCallTip;
Window wDraw;
bool inCallTipMode;
int posStartCallTip;
ColourDesired colourBG;
ColourDesired colourUnSel;
ColourDesired colourSel;
ColourDesired colourShade;
ColourDesired colourLight;
int codePage;
int clickPlace;
int insetX; // text inset in x from calltip border
int widthArrow;
int borderHeight;
int verticalOffset; // pixel offset up or down of the calltip with respect to the line
CallTip();
~CallTip();
void PaintCT(Surface *surfaceWindow);
void MouseClick(Point pt);
/// Setup the calltip and return a rectangle of the area required.
PRectangle CallTipStart(int pos, Point pt, int textHeight, const char *defn,
const char *faceName, int size, int codePage_,
int characterSet, int technology, Window &wParent);
void CallTipCancel();
/// Set a range of characters to be displayed in a highlight style.
/// Commonly used to highlight the current parameter.
void SetHighlight(int start, int end);
/// Set the tab size in pixels for the call tip. 0 or -ve means no tab expand.
void SetTabSize(int tabSz);
/// Set calltip position.
void SetPosition(bool aboveText);
/// Used to determine which STYLE_xxxx to use for call tip information
bool UseStyleCallTip() const { return useStyleCallTip;}
// Modify foreground and background colours
void SetForeBack(const ColourDesired &fore, const ColourDesired &back);
};
#ifdef SCI_NAMESPACE
}
#endif
#endif
+634
View File
@@ -0,0 +1,634 @@
// Scintilla source code edit control
// Encoding: UTF-8
/** @file CaseConvert.cxx
** Case fold characters and convert them to upper or lower case.
** Tables automatically regenerated by scripts/GenerateCaseConvert.py
** Should only be rarely regenerated for new versions of Unicode.
**/
// Copyright 2013 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
#include <cstring>
#include <vector>
#include <algorithm>
#include "StringCopy.h"
#include "CaseConvert.h"
#include "UniConversion.h"
#include "UnicodeFromUTF8.h"
#ifdef SCI_NAMESPACE
using namespace Scintilla;
#endif
namespace {
// Use an unnamed namespace to protect the declarations from name conflicts
// Unicode code points are ordered by groups and follow patterns.
// Most characters (pitch==1) are in ranges for a particular alphabet and their
// upper case forms are a fixed distance away.
// Another pattern (pitch==2) is where each lower case letter is preceded by
// the upper case form. These are also grouped into ranges.
int symmetricCaseConversionRanges[] = {
//lower, upper, range length, range pitch
//++Autogenerated -- start of section automatically generated
//**\(\*\n\)
97,65,26,1,
224,192,23,1,
248,216,7,1,
257,256,24,2,
314,313,8,2,
331,330,23,2,
462,461,8,2,
479,478,9,2,
505,504,20,2,
547,546,9,2,
583,582,5,2,
945,913,17,1,
963,931,9,1,
985,984,12,2,
1072,1040,32,1,
1104,1024,16,1,
1121,1120,17,2,
1163,1162,27,2,
1218,1217,7,2,
1233,1232,44,2,
1377,1329,38,1,
7681,7680,75,2,
7841,7840,48,2,
7936,7944,8,1,
7952,7960,6,1,
7968,7976,8,1,
7984,7992,8,1,
8000,8008,6,1,
8032,8040,8,1,
8560,8544,16,1,
9424,9398,26,1,
11312,11264,47,1,
11393,11392,50,2,
11520,4256,38,1,
42561,42560,23,2,
42625,42624,12,2,
42787,42786,7,2,
42803,42802,31,2,
42879,42878,5,2,
42913,42912,5,2,
65345,65313,26,1,
66600,66560,40,1,
//--Autogenerated -- end of section automatically generated
};
// Code points that are symmetric but don't fit into a range of similar characters
// are listed here.
int symmetricCaseConversions[] = {
//lower, upper
//++Autogenerated -- start of section automatically generated
//**1 \(\*\n\)
255,376,
307,306,
309,308,
311,310,
378,377,
380,379,
382,381,
384,579,
387,386,
389,388,
392,391,
396,395,
402,401,
405,502,
409,408,
410,573,
414,544,
417,416,
419,418,
421,420,
424,423,
429,428,
432,431,
436,435,
438,437,
441,440,
445,444,
447,503,
454,452,
457,455,
460,458,
477,398,
499,497,
501,500,
572,571,
575,11390,
576,11391,
578,577,
592,11375,
593,11373,
594,11376,
595,385,
596,390,
598,393,
599,394,
601,399,
603,400,
608,403,
611,404,
613,42893,
614,42922,
616,407,
617,406,
619,11362,
623,412,
625,11374,
626,413,
629,415,
637,11364,
640,422,
643,425,
648,430,
649,580,
650,433,
651,434,
652,581,
658,439,
881,880,
883,882,
887,886,
891,1021,
892,1022,
893,1023,
940,902,
941,904,
942,905,
943,906,
972,908,
973,910,
974,911,
983,975,
1010,1017,
1016,1015,
1019,1018,
1231,1216,
7545,42877,
7549,11363,
8017,8025,
8019,8027,
8021,8029,
8023,8031,
8048,8122,
8049,8123,
8050,8136,
8051,8137,
8052,8138,
8053,8139,
8054,8154,
8055,8155,
8056,8184,
8057,8185,
8058,8170,
8059,8171,
8060,8186,
8061,8187,
8112,8120,
8113,8121,
8144,8152,
8145,8153,
8160,8168,
8161,8169,
8165,8172,
8526,8498,
8580,8579,
11361,11360,
11365,570,
11366,574,
11368,11367,
11370,11369,
11372,11371,
11379,11378,
11382,11381,
11500,11499,
11502,11501,
11507,11506,
11559,4295,
11565,4301,
42874,42873,
42876,42875,
42892,42891,
42897,42896,
42899,42898,
//--Autogenerated -- end of section automatically generated
};
// Characters that have complex case conversions are listed here.
// This includes cases where more than one character is needed for a conversion,
// folding is different to lowering, or (as appropriate) upper(lower(x)) != x or
// lower(upper(x)) != x.
const char *complexCaseConversions =
// Original | Folded | Upper | Lower |
//++Autogenerated -- start of section automatically generated
//**2 \(\*\n\)
"\xc2\xb5|\xce\xbc|\xce\x9c||"
"\xc3\x9f|ss|SS||"
"\xc4\xb0|i\xcc\x87||i\xcc\x87|"
"\xc4\xb1||I||"
"\xc5\x89|\xca\xbcn|\xca\xbcN||"
"\xc5\xbf|s|S||"
"\xc7\x85|\xc7\x86|\xc7\x84|\xc7\x86|"
"\xc7\x88|\xc7\x89|\xc7\x87|\xc7\x89|"
"\xc7\x8b|\xc7\x8c|\xc7\x8a|\xc7\x8c|"
"\xc7\xb0|j\xcc\x8c|J\xcc\x8c||"
"\xc7\xb2|\xc7\xb3|\xc7\xb1|\xc7\xb3|"
"\xcd\x85|\xce\xb9|\xce\x99||"
"\xce\x90|\xce\xb9\xcc\x88\xcc\x81|\xce\x99\xcc\x88\xcc\x81||"
"\xce\xb0|\xcf\x85\xcc\x88\xcc\x81|\xce\xa5\xcc\x88\xcc\x81||"
"\xcf\x82|\xcf\x83|\xce\xa3||"
"\xcf\x90|\xce\xb2|\xce\x92||"
"\xcf\x91|\xce\xb8|\xce\x98||"
"\xcf\x95|\xcf\x86|\xce\xa6||"
"\xcf\x96|\xcf\x80|\xce\xa0||"
"\xcf\xb0|\xce\xba|\xce\x9a||"
"\xcf\xb1|\xcf\x81|\xce\xa1||"
"\xcf\xb4|\xce\xb8||\xce\xb8|"
"\xcf\xb5|\xce\xb5|\xce\x95||"
"\xd6\x87|\xd5\xa5\xd6\x82|\xd4\xb5\xd5\x92||"
"\xe1\xba\x96|h\xcc\xb1|H\xcc\xb1||"
"\xe1\xba\x97|t\xcc\x88|T\xcc\x88||"
"\xe1\xba\x98|w\xcc\x8a|W\xcc\x8a||"
"\xe1\xba\x99|y\xcc\x8a|Y\xcc\x8a||"
"\xe1\xba\x9a|a\xca\xbe|A\xca\xbe||"
"\xe1\xba\x9b|\xe1\xb9\xa1|\xe1\xb9\xa0||"
"\xe1\xba\x9e|ss||\xc3\x9f|"
"\xe1\xbd\x90|\xcf\x85\xcc\x93|\xce\xa5\xcc\x93||"
"\xe1\xbd\x92|\xcf\x85\xcc\x93\xcc\x80|\xce\xa5\xcc\x93\xcc\x80||"
"\xe1\xbd\x94|\xcf\x85\xcc\x93\xcc\x81|\xce\xa5\xcc\x93\xcc\x81||"
"\xe1\xbd\x96|\xcf\x85\xcc\x93\xcd\x82|\xce\xa5\xcc\x93\xcd\x82||"
"\xe1\xbe\x80|\xe1\xbc\x80\xce\xb9|\xe1\xbc\x88\xce\x99||"
"\xe1\xbe\x81|\xe1\xbc\x81\xce\xb9|\xe1\xbc\x89\xce\x99||"
"\xe1\xbe\x82|\xe1\xbc\x82\xce\xb9|\xe1\xbc\x8a\xce\x99||"
"\xe1\xbe\x83|\xe1\xbc\x83\xce\xb9|\xe1\xbc\x8b\xce\x99||"
"\xe1\xbe\x84|\xe1\xbc\x84\xce\xb9|\xe1\xbc\x8c\xce\x99||"
"\xe1\xbe\x85|\xe1\xbc\x85\xce\xb9|\xe1\xbc\x8d\xce\x99||"
"\xe1\xbe\x86|\xe1\xbc\x86\xce\xb9|\xe1\xbc\x8e\xce\x99||"
"\xe1\xbe\x87|\xe1\xbc\x87\xce\xb9|\xe1\xbc\x8f\xce\x99||"
"\xe1\xbe\x88|\xe1\xbc\x80\xce\xb9|\xe1\xbc\x88\xce\x99|\xe1\xbe\x80|"
"\xe1\xbe\x89|\xe1\xbc\x81\xce\xb9|\xe1\xbc\x89\xce\x99|\xe1\xbe\x81|"
"\xe1\xbe\x8a|\xe1\xbc\x82\xce\xb9|\xe1\xbc\x8a\xce\x99|\xe1\xbe\x82|"
"\xe1\xbe\x8b|\xe1\xbc\x83\xce\xb9|\xe1\xbc\x8b\xce\x99|\xe1\xbe\x83|"
"\xe1\xbe\x8c|\xe1\xbc\x84\xce\xb9|\xe1\xbc\x8c\xce\x99|\xe1\xbe\x84|"
"\xe1\xbe\x8d|\xe1\xbc\x85\xce\xb9|\xe1\xbc\x8d\xce\x99|\xe1\xbe\x85|"
"\xe1\xbe\x8e|\xe1\xbc\x86\xce\xb9|\xe1\xbc\x8e\xce\x99|\xe1\xbe\x86|"
"\xe1\xbe\x8f|\xe1\xbc\x87\xce\xb9|\xe1\xbc\x8f\xce\x99|\xe1\xbe\x87|"
"\xe1\xbe\x90|\xe1\xbc\xa0\xce\xb9|\xe1\xbc\xa8\xce\x99||"
"\xe1\xbe\x91|\xe1\xbc\xa1\xce\xb9|\xe1\xbc\xa9\xce\x99||"
"\xe1\xbe\x92|\xe1\xbc\xa2\xce\xb9|\xe1\xbc\xaa\xce\x99||"
"\xe1\xbe\x93|\xe1\xbc\xa3\xce\xb9|\xe1\xbc\xab\xce\x99||"
"\xe1\xbe\x94|\xe1\xbc\xa4\xce\xb9|\xe1\xbc\xac\xce\x99||"
"\xe1\xbe\x95|\xe1\xbc\xa5\xce\xb9|\xe1\xbc\xad\xce\x99||"
"\xe1\xbe\x96|\xe1\xbc\xa6\xce\xb9|\xe1\xbc\xae\xce\x99||"
"\xe1\xbe\x97|\xe1\xbc\xa7\xce\xb9|\xe1\xbc\xaf\xce\x99||"
"\xe1\xbe\x98|\xe1\xbc\xa0\xce\xb9|\xe1\xbc\xa8\xce\x99|\xe1\xbe\x90|"
"\xe1\xbe\x99|\xe1\xbc\xa1\xce\xb9|\xe1\xbc\xa9\xce\x99|\xe1\xbe\x91|"
"\xe1\xbe\x9a|\xe1\xbc\xa2\xce\xb9|\xe1\xbc\xaa\xce\x99|\xe1\xbe\x92|"
"\xe1\xbe\x9b|\xe1\xbc\xa3\xce\xb9|\xe1\xbc\xab\xce\x99|\xe1\xbe\x93|"
"\xe1\xbe\x9c|\xe1\xbc\xa4\xce\xb9|\xe1\xbc\xac\xce\x99|\xe1\xbe\x94|"
"\xe1\xbe\x9d|\xe1\xbc\xa5\xce\xb9|\xe1\xbc\xad\xce\x99|\xe1\xbe\x95|"
"\xe1\xbe\x9e|\xe1\xbc\xa6\xce\xb9|\xe1\xbc\xae\xce\x99|\xe1\xbe\x96|"
"\xe1\xbe\x9f|\xe1\xbc\xa7\xce\xb9|\xe1\xbc\xaf\xce\x99|\xe1\xbe\x97|"
"\xe1\xbe\xa0|\xe1\xbd\xa0\xce\xb9|\xe1\xbd\xa8\xce\x99||"
"\xe1\xbe\xa1|\xe1\xbd\xa1\xce\xb9|\xe1\xbd\xa9\xce\x99||"
"\xe1\xbe\xa2|\xe1\xbd\xa2\xce\xb9|\xe1\xbd\xaa\xce\x99||"
"\xe1\xbe\xa3|\xe1\xbd\xa3\xce\xb9|\xe1\xbd\xab\xce\x99||"
"\xe1\xbe\xa4|\xe1\xbd\xa4\xce\xb9|\xe1\xbd\xac\xce\x99||"
"\xe1\xbe\xa5|\xe1\xbd\xa5\xce\xb9|\xe1\xbd\xad\xce\x99||"
"\xe1\xbe\xa6|\xe1\xbd\xa6\xce\xb9|\xe1\xbd\xae\xce\x99||"
"\xe1\xbe\xa7|\xe1\xbd\xa7\xce\xb9|\xe1\xbd\xaf\xce\x99||"
"\xe1\xbe\xa8|\xe1\xbd\xa0\xce\xb9|\xe1\xbd\xa8\xce\x99|\xe1\xbe\xa0|"
"\xe1\xbe\xa9|\xe1\xbd\xa1\xce\xb9|\xe1\xbd\xa9\xce\x99|\xe1\xbe\xa1|"
"\xe1\xbe\xaa|\xe1\xbd\xa2\xce\xb9|\xe1\xbd\xaa\xce\x99|\xe1\xbe\xa2|"
"\xe1\xbe\xab|\xe1\xbd\xa3\xce\xb9|\xe1\xbd\xab\xce\x99|\xe1\xbe\xa3|"
"\xe1\xbe\xac|\xe1\xbd\xa4\xce\xb9|\xe1\xbd\xac\xce\x99|\xe1\xbe\xa4|"
"\xe1\xbe\xad|\xe1\xbd\xa5\xce\xb9|\xe1\xbd\xad\xce\x99|\xe1\xbe\xa5|"
"\xe1\xbe\xae|\xe1\xbd\xa6\xce\xb9|\xe1\xbd\xae\xce\x99|\xe1\xbe\xa6|"
"\xe1\xbe\xaf|\xe1\xbd\xa7\xce\xb9|\xe1\xbd\xaf\xce\x99|\xe1\xbe\xa7|"
"\xe1\xbe\xb2|\xe1\xbd\xb0\xce\xb9|\xe1\xbe\xba\xce\x99||"
"\xe1\xbe\xb3|\xce\xb1\xce\xb9|\xce\x91\xce\x99||"
"\xe1\xbe\xb4|\xce\xac\xce\xb9|\xce\x86\xce\x99||"
"\xe1\xbe\xb6|\xce\xb1\xcd\x82|\xce\x91\xcd\x82||"
"\xe1\xbe\xb7|\xce\xb1\xcd\x82\xce\xb9|\xce\x91\xcd\x82\xce\x99||"
"\xe1\xbe\xbc|\xce\xb1\xce\xb9|\xce\x91\xce\x99|\xe1\xbe\xb3|"
"\xe1\xbe\xbe|\xce\xb9|\xce\x99||"
"\xe1\xbf\x82|\xe1\xbd\xb4\xce\xb9|\xe1\xbf\x8a\xce\x99||"
"\xe1\xbf\x83|\xce\xb7\xce\xb9|\xce\x97\xce\x99||"
"\xe1\xbf\x84|\xce\xae\xce\xb9|\xce\x89\xce\x99||"
"\xe1\xbf\x86|\xce\xb7\xcd\x82|\xce\x97\xcd\x82||"
"\xe1\xbf\x87|\xce\xb7\xcd\x82\xce\xb9|\xce\x97\xcd\x82\xce\x99||"
"\xe1\xbf\x8c|\xce\xb7\xce\xb9|\xce\x97\xce\x99|\xe1\xbf\x83|"
"\xe1\xbf\x92|\xce\xb9\xcc\x88\xcc\x80|\xce\x99\xcc\x88\xcc\x80||"
"\xe1\xbf\x93|\xce\xb9\xcc\x88\xcc\x81|\xce\x99\xcc\x88\xcc\x81||"
"\xe1\xbf\x96|\xce\xb9\xcd\x82|\xce\x99\xcd\x82||"
"\xe1\xbf\x97|\xce\xb9\xcc\x88\xcd\x82|\xce\x99\xcc\x88\xcd\x82||"
"\xe1\xbf\xa2|\xcf\x85\xcc\x88\xcc\x80|\xce\xa5\xcc\x88\xcc\x80||"
"\xe1\xbf\xa3|\xcf\x85\xcc\x88\xcc\x81|\xce\xa5\xcc\x88\xcc\x81||"
"\xe1\xbf\xa4|\xcf\x81\xcc\x93|\xce\xa1\xcc\x93||"
"\xe1\xbf\xa6|\xcf\x85\xcd\x82|\xce\xa5\xcd\x82||"
"\xe1\xbf\xa7|\xcf\x85\xcc\x88\xcd\x82|\xce\xa5\xcc\x88\xcd\x82||"
"\xe1\xbf\xb2|\xe1\xbd\xbc\xce\xb9|\xe1\xbf\xba\xce\x99||"
"\xe1\xbf\xb3|\xcf\x89\xce\xb9|\xce\xa9\xce\x99||"
"\xe1\xbf\xb4|\xcf\x8e\xce\xb9|\xce\x8f\xce\x99||"
"\xe1\xbf\xb6|\xcf\x89\xcd\x82|\xce\xa9\xcd\x82||"
"\xe1\xbf\xb7|\xcf\x89\xcd\x82\xce\xb9|\xce\xa9\xcd\x82\xce\x99||"
"\xe1\xbf\xbc|\xcf\x89\xce\xb9|\xce\xa9\xce\x99|\xe1\xbf\xb3|"
"\xe2\x84\xa6|\xcf\x89||\xcf\x89|"
"\xe2\x84\xaa|k||k|"
"\xe2\x84\xab|\xc3\xa5||\xc3\xa5|"
"\xef\xac\x80|ff|FF||"
"\xef\xac\x81|fi|FI||"
"\xef\xac\x82|fl|FL||"
"\xef\xac\x83|ffi|FFI||"
"\xef\xac\x84|ffl|FFL||"
"\xef\xac\x85|st|ST||"
"\xef\xac\x86|st|ST||"
"\xef\xac\x93|\xd5\xb4\xd5\xb6|\xd5\x84\xd5\x86||"
"\xef\xac\x94|\xd5\xb4\xd5\xa5|\xd5\x84\xd4\xb5||"
"\xef\xac\x95|\xd5\xb4\xd5\xab|\xd5\x84\xd4\xbb||"
"\xef\xac\x96|\xd5\xbe\xd5\xb6|\xd5\x8e\xd5\x86||"
"\xef\xac\x97|\xd5\xb4\xd5\xad|\xd5\x84\xd4\xbd||"
//--Autogenerated -- end of section automatically generated
;
class CaseConverter : public ICaseConverter {
// Maximum length of a case conversion result is 6 bytes in UTF-8
enum { maxConversionLength=6 };
struct ConversionString {
char conversion[maxConversionLength+1];
ConversionString() {
conversion[0] = '\0';
}
};
// Conversions are initially store in a vector of structs but then decomposed into
// parallel arrays as that is about 10% faster to search.
struct CharacterConversion {
int character;
ConversionString conversion;
CharacterConversion(int character_=0, const char *conversion_="") : character(character_) {
StringCopy(conversion.conversion, conversion_);
}
bool operator<(const CharacterConversion &other) const {
return character < other.character;
}
};
typedef std::vector<CharacterConversion> CharacterToConversion;
CharacterToConversion characterToConversion;
// The parallel arrays
std::vector<int> characters;
std::vector<ConversionString> conversions;
public:
CaseConverter() {
}
bool Initialised() const {
return characters.size() > 0;
}
void Add(int character, const char *conversion) {
characterToConversion.push_back(CharacterConversion(character, conversion));
}
const char *Find(int character) {
const std::vector<int>::iterator it = std::lower_bound(characters.begin(), characters.end(), character);
if (it == characters.end())
return 0;
else if (*it == character)
return conversions[it - characters.begin()].conversion;
else
return 0;
}
size_t CaseConvertString(char *converted, size_t sizeConverted, const char *mixed, size_t lenMixed) {
size_t lenConverted = 0;
size_t mixedPos = 0;
unsigned char bytes[UTF8MaxBytes + 1];
while (mixedPos < lenMixed) {
const unsigned char leadByte = static_cast<unsigned char>(mixed[mixedPos]);
const char *caseConverted = 0;
size_t lenMixedChar = 1;
if (UTF8IsAscii(leadByte)) {
caseConverted = Find(leadByte);
} else {
bytes[0] = leadByte;
const int widthCharBytes = UTF8BytesOfLead[leadByte];
for (int b=1; b<widthCharBytes; b++) {
bytes[b] = (mixedPos+b < lenMixed) ? mixed[mixedPos+b] : 0;
}
int classified = UTF8Classify(bytes, widthCharBytes);
if (!(classified & UTF8MaskInvalid)) {
// valid UTF-8
lenMixedChar = classified & UTF8MaskWidth;
int character = UnicodeFromUTF8(bytes);
caseConverted = Find(character);
}
}
if (caseConverted) {
// Character has a conversion so copy that conversion in
while (*caseConverted) {
converted[lenConverted++] = *caseConverted++;
if (lenConverted >= sizeConverted)
return 0;
}
} else {
// Character has no conversion so copy the input to output
for (size_t i=0; i<lenMixedChar; i++) {
converted[lenConverted++] = mixed[mixedPos+i];
if (lenConverted >= sizeConverted)
return 0;
}
}
mixedPos += lenMixedChar;
}
return lenConverted;
}
void FinishedAdding() {
std::sort(characterToConversion.begin(), characterToConversion.end());
characters.reserve(characterToConversion.size());
conversions.reserve(characterToConversion.size());
for (CharacterToConversion::iterator it = characterToConversion.begin(); it != characterToConversion.end(); ++it) {
characters.push_back(it->character);
conversions.push_back(it->conversion);
}
// Empty the original calculated data completely
CharacterToConversion().swap(characterToConversion);
}
};
CaseConverter caseConvFold;
CaseConverter caseConvUp;
CaseConverter caseConvLow;
void UTF8FromUTF32Character(int uch, char *putf) {
size_t k = 0;
if (uch < 0x80) {
putf[k++] = static_cast<char>(uch);
} else if (uch < 0x800) {
putf[k++] = static_cast<char>(0xC0 | (uch >> 6));
putf[k++] = static_cast<char>(0x80 | (uch & 0x3f));
} else if (uch < 0x10000) {
putf[k++] = static_cast<char>(0xE0 | (uch >> 12));
putf[k++] = static_cast<char>(0x80 | ((uch >> 6) & 0x3f));
putf[k++] = static_cast<char>(0x80 | (uch & 0x3f));
} else {
putf[k++] = static_cast<char>(0xF0 | (uch >> 18));
putf[k++] = static_cast<char>(0x80 | ((uch >> 12) & 0x3f));
putf[k++] = static_cast<char>(0x80 | ((uch >> 6) & 0x3f));
putf[k++] = static_cast<char>(0x80 | (uch & 0x3f));
}
putf[k] = 0;
}
void AddSymmetric(enum CaseConversion conversion, int lower,int upper) {
char lowerUTF8[UTF8MaxBytes+1];
UTF8FromUTF32Character(lower, lowerUTF8);
char upperUTF8[UTF8MaxBytes+1];
UTF8FromUTF32Character(upper, upperUTF8);
switch (conversion) {
case CaseConversionFold:
caseConvFold.Add(upper, lowerUTF8);
break;
case CaseConversionUpper:
caseConvUp.Add(lower, upperUTF8);
break;
case CaseConversionLower:
caseConvLow.Add(upper, lowerUTF8);
break;
}
}
void SetupConversions(enum CaseConversion conversion) {
// First initialize for the symmetric ranges
for (size_t i=0; i<ELEMENTS(symmetricCaseConversionRanges);) {
int lower = symmetricCaseConversionRanges[i++];
int upper = symmetricCaseConversionRanges[i++];
int length = symmetricCaseConversionRanges[i++];
int pitch = symmetricCaseConversionRanges[i++];
for (int j=0; j<length*pitch; j+=pitch) {
AddSymmetric(conversion, lower+j, upper+j);
}
}
// Add the symmetric singletons
for (size_t i=0; i<ELEMENTS(symmetricCaseConversions);) {
int lower = symmetricCaseConversions[i++];
int upper = symmetricCaseConversions[i++];
AddSymmetric(conversion, lower, upper);
}
// Add the complex cases
const char *sComplex = complexCaseConversions;
while (*sComplex) {
// Longest ligature is 3 character so 5 for safety
const size_t lenUTF8 = 5*UTF8MaxBytes+1;
char originUTF8[lenUTF8];
char foldedUTF8[lenUTF8];
char lowerUTF8[lenUTF8];
char upperUTF8[lenUTF8];
size_t i = 0;
while (*sComplex && *sComplex != '|') {
originUTF8[i++] = *sComplex;
sComplex++;
}
sComplex++;
originUTF8[i] = 0;
i = 0;
while (*sComplex && *sComplex != '|') {
foldedUTF8[i++] = *sComplex;
sComplex++;
}
sComplex++;
foldedUTF8[i] = 0;
i = 0;
while (*sComplex && *sComplex != '|') {
upperUTF8[i++] = *sComplex;
sComplex++;
}
sComplex++;
upperUTF8[i] = 0;
i = 0;
while (*sComplex && *sComplex != '|') {
lowerUTF8[i++] = *sComplex;
sComplex++;
}
sComplex++;
lowerUTF8[i] = 0;
int character = UnicodeFromUTF8(reinterpret_cast<unsigned char *>(originUTF8));
if (conversion == CaseConversionFold && foldedUTF8[0]) {
caseConvFold.Add(character, foldedUTF8);
}
if (conversion == CaseConversionUpper && upperUTF8[0]) {
caseConvUp.Add(character, upperUTF8);
}
if (conversion == CaseConversionLower && lowerUTF8[0]) {
caseConvLow.Add(character, lowerUTF8);
}
}
switch (conversion) {
case CaseConversionFold:
caseConvFold.FinishedAdding();
break;
case CaseConversionUpper:
caseConvUp.FinishedAdding();
break;
case CaseConversionLower:
caseConvLow.FinishedAdding();
break;
}
}
CaseConverter *ConverterForConversion(enum CaseConversion conversion) {
switch (conversion) {
case CaseConversionFold:
return &caseConvFold;
case CaseConversionUpper:
return &caseConvUp;
case CaseConversionLower:
return &caseConvLow;
}
return 0;
}
}
#ifdef SCI_NAMESPACE
namespace Scintilla {
#endif
ICaseConverter *ConverterFor(enum CaseConversion conversion) {
CaseConverter *pCaseConv = ConverterForConversion(conversion);
if (!pCaseConv->Initialised())
SetupConversions(conversion);
return pCaseConv;
}
const char *CaseConvert(int character, enum CaseConversion conversion) {
CaseConverter *pCaseConv = ConverterForConversion(conversion);
if (!pCaseConv->Initialised())
SetupConversions(conversion);
return pCaseConv->Find(character);
}
size_t CaseConvertString(char *converted, size_t sizeConverted, const char *mixed, size_t lenMixed, enum CaseConversion conversion) {
CaseConverter *pCaseConv = ConverterForConversion(conversion);
if (!pCaseConv->Initialised())
SetupConversions(conversion);
return pCaseConv->CaseConvertString(converted, sizeConverted, mixed, lenMixed);
}
#ifdef SCI_NAMESPACE
}
#endif
+47
View File
@@ -0,0 +1,47 @@
// Scintilla source code edit control
// Encoding: UTF-8
/** @file CaseConvert.h
** Performs Unicode case conversions.
** Does not handle locale-sensitive case conversion.
**/
// Copyright 2013 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
#ifndef CASECONVERT_H
#define CASECONVERT_H
#ifdef SCI_NAMESPACE
namespace Scintilla {
#endif
enum CaseConversion {
CaseConversionFold,
CaseConversionUpper,
CaseConversionLower
};
class ICaseConverter {
public:
virtual size_t CaseConvertString(char *converted, size_t sizeConverted, const char *mixed, size_t lenMixed) = 0;
};
ICaseConverter *ConverterFor(enum CaseConversion conversion);
// Returns a UTF-8 string. Empty when no conversion
const char *CaseConvert(int character, enum CaseConversion conversion);
// When performing CaseConvertString, the converted value may be up to 3 times longer than the input.
// Ligatures are often decomposed into multiple characters and long cases include:
// ΐ "\xce\x90" folds to ΐ "\xce\xb9\xcc\x88\xcc\x81"
const int maxExpansionCaseConversion=3;
// Converts a mixed case string using a particular conversion.
// Result may be a different length to input and the length is the return value.
// If there is not enough space then 0 is returned.
size_t CaseConvertString(char *converted, size_t sizeConverted, const char *mixed, size_t lenMixed, enum CaseConversion conversion);
#ifdef SCI_NAMESPACE
}
#endif
#endif
+68
View File
@@ -0,0 +1,68 @@
// Scintilla source code edit control
/** @file CaseFolder.cxx
** Classes for case folding.
**/
// Copyright 1998-2013 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
#include <vector>
#include <algorithm>
#include "CaseFolder.h"
#include "CaseConvert.h"
#include "UniConversion.h"
#ifdef SCI_NAMESPACE
using namespace Scintilla;
#endif
CaseFolder::~CaseFolder() {
}
CaseFolderTable::CaseFolderTable() {
for (size_t iChar=0; iChar<sizeof(mapping); iChar++) {
mapping[iChar] = static_cast<char>(iChar);
}
}
CaseFolderTable::~CaseFolderTable() {
}
size_t CaseFolderTable::Fold(char *folded, size_t sizeFolded, const char *mixed, size_t lenMixed) {
if (lenMixed > sizeFolded) {
return 0;
} else {
for (size_t i=0; i<lenMixed; i++) {
folded[i] = mapping[static_cast<unsigned char>(mixed[i])];
}
return lenMixed;
}
}
void CaseFolderTable::SetTranslation(char ch, char chTranslation) {
mapping[static_cast<unsigned char>(ch)] = chTranslation;
}
void CaseFolderTable::StandardASCII() {
for (size_t iChar=0; iChar<sizeof(mapping); iChar++) {
if (iChar >= 'A' && iChar <= 'Z') {
mapping[iChar] = static_cast<char>(iChar - 'A' + 'a');
} else {
mapping[iChar] = static_cast<char>(iChar);
}
}
}
CaseFolderUnicode::CaseFolderUnicode() {
StandardASCII();
converter = ConverterFor(CaseConversionFold);
}
size_t CaseFolderUnicode::Fold(char *folded, size_t sizeFolded, const char *mixed, size_t lenMixed) {
if ((lenMixed == 1) && (sizeFolded > 0)) {
folded[0] = mapping[static_cast<unsigned char>(mixed[0])];
return 1;
} else {
return converter->CaseConvertString(folded, sizeFolded, mixed, lenMixed);
}
}
+45
View File
@@ -0,0 +1,45 @@
// Scintilla source code edit control
/** @file CaseFolder.h
** Classes for case folding.
**/
// Copyright 1998-2013 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
#ifndef CASEFOLDER_H
#define CASEFOLDER_H
#ifdef SCI_NAMESPACE
namespace Scintilla {
#endif
class CaseFolder {
public:
virtual ~CaseFolder();
virtual size_t Fold(char *folded, size_t sizeFolded, const char *mixed, size_t lenMixed) = 0;
};
class CaseFolderTable : public CaseFolder {
protected:
char mapping[256];
public:
CaseFolderTable();
virtual ~CaseFolderTable();
virtual size_t Fold(char *folded, size_t sizeFolded, const char *mixed, size_t lenMixed);
void SetTranslation(char ch, char chTranslation);
void StandardASCII();
};
class ICaseConverter;
class CaseFolderUnicode : public CaseFolderTable {
ICaseConverter *converter;
public:
CaseFolderUnicode();
virtual size_t Fold(char *folded, size_t sizeFolded, const char *mixed, size_t lenMixed);
};
#ifdef SCI_NAMESPACE
}
#endif
#endif
+84
View File
@@ -0,0 +1,84 @@
// Scintilla source code edit control
/** @file Catalogue.cxx
** Colourise for particular languages.
**/
// Copyright 1998-2002 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <stdarg.h>
#include <assert.h>
#include <ctype.h>
#include <vector>
#include "ILexer.h"
#include "Scintilla.h"
#include "SciLexer.h"
#include "LexerModule.h"
#include "Catalogue.h"
#ifdef SCI_NAMESPACE
using namespace Scintilla;
#endif
static std::vector<LexerModule *> lexerCatalogue;
static int nextLanguage = SCLEX_AUTOMATIC+1;
const LexerModule *Catalogue::Find(int language) {
Scintilla_LinkLexers();
for (std::vector<LexerModule *>::iterator it=lexerCatalogue.begin();
it != lexerCatalogue.end(); ++it) {
if ((*it)->GetLanguage() == language) {
return *it;
}
}
return 0;
}
const LexerModule *Catalogue::Find(const char *languageName) {
Scintilla_LinkLexers();
if (languageName) {
for (std::vector<LexerModule *>::iterator it=lexerCatalogue.begin();
it != lexerCatalogue.end(); ++it) {
if ((*it)->languageName && (0 == strcmp((*it)->languageName, languageName))) {
return *it;
}
}
}
return 0;
}
void Catalogue::AddLexerModule(LexerModule *plm) {
if (plm->GetLanguage() == SCLEX_AUTOMATIC) {
plm->language = nextLanguage;
nextLanguage++;
}
lexerCatalogue.push_back(plm);
}
// To add or remove a lexer, add or remove its file and run LexGen.py.
// Force a reference to all of the Scintilla lexers so that the linker will
// not remove the code of the lexers.
int Scintilla_LinkLexers() {
static int initialised = 0;
if (initialised)
return 0;
initialised = 1;
// Shorten the code that declares a lexer and ensures it is linked in by calling a method.
#define LINK_LEXER(lexer) extern LexerModule lexer; Catalogue::AddLexerModule(&lexer);
//++Autogenerated -- run scripts/LexGen.py to regenerate
//**\(\tLINK_LEXER(\*);\n\)
LINK_LEXER(lmSQL);
//--Autogenerated -- end of automatically generated section
return 1;
}

Some files were not shown because too many files have changed in this diff Show More