diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000000000000000000000000000000000000..1ce8223982923e68f47be72ef7bff1927db81e38 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,16 @@ +root = true + +[*] +charset = utf-8 +end_of_line = lf + +[*.[ch]] +indent_size = 8 +indent_style = tab +insert_final_newline = true +max_line_length = 80 +tab_width = 8 + +[meson.build] +indent_size = 2 +indent_style = space diff --git a/HACKING b/HACKING index a481180726b75cbf3ea853ed4d61aae0bacd0f9d..f499c9228edcd1eb5c62794fa770db1f5f2b2adc 100644 --- a/HACKING +++ b/HACKING @@ -25,13 +25,11 @@ C code conventions You may encounter old code that doesn't follow all the following code conventions, but for new code it is better to follow them, for consistency. -In the scripts/ directory there is an uncrustify config file with a script to -apply the coding style to a certain *.c file. The script has not (yet) been run -on all the GtkSourceView source code, but it can serve as a guideline. - - Avoid trailing whitespace. - Indent the C code with tabulations with a width of eight characters. + However, alignment after matching the current scope should be done + with spaces. - All blocks should be surrounded by curly braces, even one-line blocks. The curly braces must be placed on their own lines. Like this: @@ -49,9 +47,12 @@ on all the GtkSourceView source code, but it can serve as a guideline. modifying a block of code, if it switches between one and two lines, we don't need to add/remove the curly braces all the time. - - Follow the C89 standard. In particular, no "//"-style comments. + - Follow the C99 standard but without "//"-style comments. Some restrictions + apply but relatively should match GTK and GLib. - - The files should have a modeline for the indentation style. + - The files should not have modelines included. A .editorconfig file is + provided for configuration indentation and many editors have support for + using them. - Do not be cheap about blank lines, spacing the code vertically helps readability. However never use two consecutive blank lines, there is really @@ -61,9 +62,10 @@ on all the GtkSourceView source code, but it can serve as a guideline. code. See also: -https://developer.gnome.org/programming-guidelines/stable/ -https://wiki.gnome.org/Projects/GTK%2B/BestPractices -https://wiki.gnome.org/Projects/GLib/CompilerRequirements + + - https://developer.gnome.org/programming-guidelines/stable/ + - https://wiki.gnome.org/Projects/GTK%2B/BestPractices + - https://wiki.gnome.org/Projects/GLib/CompilerRequirements Programming best-practices -------------------------- @@ -75,9 +77,9 @@ old. So when editing the code, we should try to make it better, not worse. Here are some general advices: - Simplicity: the simpler code the better. Any trick that seem smart when you - write it is going to bite your ass later when reading the code. In fact, a + write it is going to bite you later when reading the code. In fact, the code is read far more often than it is written: for fixing a bug, adding a - feature, or simply see how it is implemented. So making the code harder to + feature, or simply see how it is implemented. Making the code harder to read is a net loss. - Avoid code duplication, make an effort to refactor common code into utility @@ -132,6 +134,17 @@ Here are some general advices: writing hacks or heuristics to work around a bug or a lack of feature in an underlying library. + - Public API should have precondition guards using g_return_if_fail() or + g_return_val_if_fail(). Optionally, you may do this before returnin values + from the function to help catch bugs earlier in the development cycle. + + Private functions (such as those with static) should use g_assert() to + validate invariants. These are used in debug builds but can be compiled + out of production/release builds. + + - When transfering ownership of an object or struct, use g_steal_pointer() + to make it clear when reading that ownership was transfered. + See also: https://blogs.gnome.org/swilmet/2012/08/01/about-code-quality-and-maintainability/ diff --git a/README.md b/README.md index ba6edee82b0d01bdb7f254253b8ffbf5f549e1f4..b6d0213989829d9b16ec6903d7b6f7b41cb649a3 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,8 @@ GtkSourceView ============= +This is a development branch progressing towards GTK 4 support. + GtkSourceView is a GNOME library that extends GtkTextView, the standard GTK+ widget for multiline text editing. GtkSourceView adds support for syntax highlighting, undo/redo, file loading and saving, search and replace, a @@ -14,8 +16,8 @@ The official web site is https://wiki.gnome.org/Projects/GtkSourceView. Dependencies ------------ -* GLib >= 2.48 -* GTK+ >= 3.24 +* GLib >= 2.62 +* GTK+ >= 3.96 * libxml2 >= 2.6 * freebidi >= 0.19.7 diff --git a/data/fonts/BuilderBlocks.ttf b/data/fonts/BuilderBlocks.ttf new file mode 100644 index 0000000000000000000000000000000000000000..8fe8942068f15a7f415be980c68e614c3f7c5ff8 Binary files /dev/null and b/data/fonts/BuilderBlocks.ttf differ diff --git a/data/fonts/BuilderBlocks.ttx b/data/fonts/BuilderBlocks.ttx new file mode 100644 index 0000000000000000000000000000000000000000..23c47c402538a233c102a006cd2b544e1902b8a1 --- /dev/null +++ b/data/fonts/BuilderBlocks.ttx @@ -0,0 +1,137 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + BuilderBlocks + + + + + + + 0000 0001 + 0003 000A + 0000000C + 000D 0000 + 00000040 + 00000000 + 00000004 + 00000001 + 00000020 + 00000002 + 00000021 + 00000060 + 00000001 + 00000061 + 0000007A + 00000003 + 0000007B + 0010FFFE + 00000001 + + + + diff --git a/data/glade/gtksourceview.xml.in b/data/glade/gtksourceview.xml.in deleted file mode 100644 index 4b2c298454e1514794f1ca4db28a2839629b9883..0000000000000000000000000000000000000000 --- a/data/glade/gtksourceview.xml.in +++ /dev/null @@ -1,44 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/data/glade/meson.build b/data/glade/meson.build deleted file mode 100644 index 3148632b4c96aaedab06d34867a9bd101d3d170b..0000000000000000000000000000000000000000 --- a/data/glade/meson.build +++ /dev/null @@ -1,37 +0,0 @@ -# Note that we do not install in the detected GLADE_CATALOG_DIR -# since we may not have permissions to do it, for instance if -# compiling with a prefix while glade is installed in /usr. -# We use the variable only to find the dtd file. -# If you install gtksourceview and glade in different prefixes -# and want to use the catalog in glade, you will need to set -# the GLADE_CATALOG_SEARCH_PATH environment variable. - -catalog_in = configuration_data() -catalog_in.set('GSV_API_VERSION', api_version) - -catalog_xml = configure_file( - input: 'gtksourceview.xml.in', - output: 'gtksourceview.xml', - configuration: catalog_in, - install_dir: join_paths(datadir, 'glade', 'catalogs') -) - -# Currently DTD validation does not work with glade's DTD. -# This does not appear to be limited to GtkSourceView. -#if xmllint_prg.found() -# catalog_dtd = join_paths( -# gladeui_dep.get_pkgconfig_variable('catalogdir'), -# 'glade-catalog.dtd' -# ) -# -# test( -# 'Validate Glade catalogue', -# xmllint_prg, -# args: [ -# '--dtdvalid', -# catalog_dtd, -# catalog_xml, -# '--noout', -# ] -# ) -#endif diff --git a/data/icons/COPYING b/data/icons/COPYING new file mode 100644 index 0000000000000000000000000000000000000000..2f789c3b148d9ba3e5c4e9af0e9912b477b3cfd4 --- /dev/null +++ b/data/icons/COPYING @@ -0,0 +1,6 @@ +The icons here are licensed under the CC-by-SA 3. You can find the full text of +the license at: + + http://creativecommons.org/licenses/by-sa/3.0/ + +See git commit's for authors and contributors to individual icons. diff --git a/data/icons/hicolor/scalable/actions/completion-snippet-symbolic.svg b/data/icons/hicolor/scalable/actions/completion-snippet-symbolic.svg new file mode 100644 index 0000000000000000000000000000000000000000..4ddad984fb695581032e329f4620ba25856d1423 --- /dev/null +++ b/data/icons/hicolor/scalable/actions/completion-snippet-symbolic.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/data/icons/hicolor/scalable/actions/completion-word-symbolic.svg b/data/icons/hicolor/scalable/actions/completion-word-symbolic.svg new file mode 100644 index 0000000000000000000000000000000000000000..140a4e4b9f278d76fdb9e23cea14f6b759efdee1 --- /dev/null +++ b/data/icons/hicolor/scalable/actions/completion-word-symbolic.svg @@ -0,0 +1,3 @@ + + + diff --git a/data/icons/hicolor/scalable/actions/lang-class-symbolic.svg b/data/icons/hicolor/scalable/actions/lang-class-symbolic.svg new file mode 100644 index 0000000000000000000000000000000000000000..337e29f1aa08bee5889e46bfb6e606d65c589dd0 --- /dev/null +++ b/data/icons/hicolor/scalable/actions/lang-class-symbolic.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/data/icons/hicolor/scalable/actions/lang-define-symbolic.svg b/data/icons/hicolor/scalable/actions/lang-define-symbolic.svg new file mode 100644 index 0000000000000000000000000000000000000000..1caef0f445ce35f09c81616e533e4b4c1f52e369 --- /dev/null +++ b/data/icons/hicolor/scalable/actions/lang-define-symbolic.svg @@ -0,0 +1,3 @@ + + + diff --git a/data/icons/hicolor/scalable/actions/lang-enum-symbolic.svg b/data/icons/hicolor/scalable/actions/lang-enum-symbolic.svg new file mode 100644 index 0000000000000000000000000000000000000000..cb0b2917154cc6c068cc230901130ca212e86783 --- /dev/null +++ b/data/icons/hicolor/scalable/actions/lang-enum-symbolic.svg @@ -0,0 +1,3 @@ + + + diff --git a/data/icons/hicolor/scalable/actions/lang-enum-value-symbolic.svg b/data/icons/hicolor/scalable/actions/lang-enum-value-symbolic.svg new file mode 100644 index 0000000000000000000000000000000000000000..8e47e29a478adea64c7f01e9f9d50e353a7bfb12 --- /dev/null +++ b/data/icons/hicolor/scalable/actions/lang-enum-value-symbolic.svg @@ -0,0 +1,3 @@ + + + diff --git a/data/icons/hicolor/scalable/actions/lang-function-symbolic.svg b/data/icons/hicolor/scalable/actions/lang-function-symbolic.svg new file mode 100644 index 0000000000000000000000000000000000000000..e29109e4f59ceaccc5f6592584a33c2a6eff55a1 --- /dev/null +++ b/data/icons/hicolor/scalable/actions/lang-function-symbolic.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/data/icons/hicolor/scalable/actions/lang-include-symbolic.svg b/data/icons/hicolor/scalable/actions/lang-include-symbolic.svg new file mode 100644 index 0000000000000000000000000000000000000000..73b4d0f78c71779627c19d4787446f1fea11c3aa --- /dev/null +++ b/data/icons/hicolor/scalable/actions/lang-include-symbolic.svg @@ -0,0 +1,3 @@ + + + diff --git a/data/icons/hicolor/scalable/actions/lang-method-symbolic.svg b/data/icons/hicolor/scalable/actions/lang-method-symbolic.svg new file mode 100644 index 0000000000000000000000000000000000000000..f8b16afa63d56407fa146097067e374f91e68557 --- /dev/null +++ b/data/icons/hicolor/scalable/actions/lang-method-symbolic.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/data/icons/hicolor/scalable/actions/lang-namespace-symbolic.svg b/data/icons/hicolor/scalable/actions/lang-namespace-symbolic.svg new file mode 100644 index 0000000000000000000000000000000000000000..241c78e02fe9e0f155d2546252aff595c37ab497 --- /dev/null +++ b/data/icons/hicolor/scalable/actions/lang-namespace-symbolic.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/data/icons/hicolor/scalable/actions/lang-struct-field-symbolic.svg b/data/icons/hicolor/scalable/actions/lang-struct-field-symbolic.svg new file mode 100644 index 0000000000000000000000000000000000000000..7729007129dbd90c25c3e0f0750147d0ca359768 --- /dev/null +++ b/data/icons/hicolor/scalable/actions/lang-struct-field-symbolic.svg @@ -0,0 +1,3 @@ + + + diff --git a/data/icons/hicolor/scalable/actions/lang-struct-symbolic.svg b/data/icons/hicolor/scalable/actions/lang-struct-symbolic.svg new file mode 100644 index 0000000000000000000000000000000000000000..b2daa4fbe59f990dc71e24968627ac0faf9d83ce --- /dev/null +++ b/data/icons/hicolor/scalable/actions/lang-struct-symbolic.svg @@ -0,0 +1,3 @@ + + + diff --git a/data/icons/hicolor/scalable/actions/lang-typedef-symbolic.svg b/data/icons/hicolor/scalable/actions/lang-typedef-symbolic.svg new file mode 100644 index 0000000000000000000000000000000000000000..e5174b2d81b74093a5a1b863b5446aa1ca048bac --- /dev/null +++ b/data/icons/hicolor/scalable/actions/lang-typedef-symbolic.svg @@ -0,0 +1,3 @@ + + + diff --git a/data/icons/hicolor/scalable/actions/lang-union-symbolic.svg b/data/icons/hicolor/scalable/actions/lang-union-symbolic.svg new file mode 100644 index 0000000000000000000000000000000000000000..1db71e0cd8984e5f016fb3a6e6d4595629c001f1 --- /dev/null +++ b/data/icons/hicolor/scalable/actions/lang-union-symbolic.svg @@ -0,0 +1,3 @@ + + + diff --git a/data/icons/hicolor/scalable/actions/lang-variable-symbolic.svg b/data/icons/hicolor/scalable/actions/lang-variable-symbolic.svg new file mode 100644 index 0000000000000000000000000000000000000000..e74c0b153a675d79fc0b4793d135d2883e9fc4af --- /dev/null +++ b/data/icons/hicolor/scalable/actions/lang-variable-symbolic.svg @@ -0,0 +1,3 @@ + + + diff --git a/data/icons/meson.build b/data/icons/meson.build new file mode 100644 index 0000000000000000000000000000000000000000..b7a96d967c01a7663dd048db4ae31d274a78fdb6 --- /dev/null +++ b/data/icons/meson.build @@ -0,0 +1,3 @@ +iconsdir = join_paths(get_option('datadir'), 'icons') + +install_subdir('hicolor', install_dir: iconsdir) diff --git a/data/meson.build b/data/meson.build index 2ca97a5f4ba82fbe86970bcb6fa3ac0b0bdfcc4d..e92067b9afbdd1f17a35f2a7a89e9fb18b9c0d49 100644 --- a/data/meson.build +++ b/data/meson.build @@ -1,7 +1,3 @@ -if install_glade_catalog - subdir('glade') -endif - install_subdir('language-specs', install_dir: pkgdatadir, exclude_files: [ 'Makefile.am', @@ -23,3 +19,15 @@ install_subdir('styles', 'testdark.xml', 'update-pot.sh' ] ) + +install_subdir('fonts', + install_dir: pkgdatadir, + exclude_files: [ 'BuilderBlocks.ttx' ] +) + +install_subdir('snippets', + install_dir: pkgdatadir, + exclude_files: [], +) + +subdir('icons') diff --git a/data/snippets/licenses.snippets b/data/snippets/licenses.snippets new file mode 100644 index 0000000000000000000000000000000000000000..d764c68f7c15fee44be542fae1b0768d1b872b9a --- /dev/null +++ b/data/snippets/licenses.snippets @@ -0,0 +1,357 @@ + + + + + + + + +# +# 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 . +# +# SPDX-License-Identifier: GPL-3.0-or-later +$0]]> + + * + * 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 . + * + * SPDX-License-Identifier: GPL-3.0-or-later + */ +$0]]> + +// +// 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 . +// +// SPDX-License-Identifier: GPL-3.0-or-later +$0]]> + + + + + + +# +# This file is free software; you can redistribute it and/or modify it +# under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation; either version 3 of the License, or (at +# your option) any later version. +# +# This file 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 Lesser General Public +# License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program. If not, see . +# +# SPDX-License-Identifier: LGPL-3.0-or-later +$0]]> + + * + * This file is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This file 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 Lesser General Public + * License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + * + * SPDX-License-Identifier: LGPL-3.0-or-later + */ +$0]]> + +// +// This file is free software; you can redistribute it and/or modify it +// under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation; either version 3 of the License, or (at +// your option) any later version. +// +// This file 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 Lesser General Public +// License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this program. If not, see . +// +// SPDX-License-Identifier: LGPL-3.0-or-later +$0]]> + + + + + + +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 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 +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this library; if not, see . +# +# SPDX-License-Identifier: LGPL-2.1-or-later +$0]]> + + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, see . + * + * SPDX-License-Identifier: LGPL-2.1-or-later + */ +$0]]> + +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 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 +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this library; if not, see . +// +// SPDX-License-Identifier: LGPL-2.1-or-later +$0]]> + + + + + + +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# SPDX-License-Identifier: Apache-2.0 +$0]]> + + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +$0]]> + +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// SPDX-License-Identifier: Apache-2.0 +$0]]> + + + + + + +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to +# deal in the Software without restriction, including without limitation the +# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +# sell copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +# IN THE SOFTWARE. +# +# SPDX-License-Identifier: MIT +$0]]> + + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * SPDX-License-Identifier: MIT + */ +$0]]> + +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +// +// SPDX-License-Identifier: MIT +$0]]> + + diff --git a/data/snippets/snippets.rng b/data/snippets/snippets.rng new file mode 100644 index 0000000000000000000000000000000000000000..fff388edf1470a2853ef3da80d5c9a272d008a16 --- /dev/null +++ b/data/snippets/snippets.rng @@ -0,0 +1,64 @@ + + + + + + + + + + + 1.0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/data/styles/classic.xml b/data/styles/classic.xml index 183f5881e28dbfa7d2ea91910bd151c8b22970ac..ad75bbcc037c2015463eae841bda247dc5cb9793 100644 --- a/data/styles/classic.xml +++ b/data/styles/classic.xml @@ -47,6 +47,7 @@ + + + comment + true + baseline + + + + + horizontal + top + baseline + + + 6 + 6 + baseline + + + + + false + _Details + true + end + start + + + + + + + + + + + diff --git a/gtksourceview/gtksourcecompletionlistbox-private.h b/gtksourceview/gtksourcecompletionlistbox-private.h new file mode 100644 index 0000000000000000000000000000000000000000..5f4537053644970fa685c2d3ba3c03d160651669 --- /dev/null +++ b/gtksourceview/gtksourcecompletionlistbox-private.h @@ -0,0 +1,58 @@ +/* + * This file is part of GtkSourceView + * + * Copyright 2020 Christian Hergert + * + * GtkSourceView is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * GtkSourceView 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, see . + * + * SPDX-License-Identifier: LGPL-2.1-or-later + */ + +#pragma once + +#include + +#include "gtksourcetypes-private.h" + +G_BEGIN_DECLS + +#define GTK_SOURCE_TYPE_COMPLETION_LIST_BOX (gtk_source_completion_list_box_get_type()) + +G_DECLARE_FINAL_TYPE (GtkSourceCompletionListBox, gtk_source_completion_list_box, GTK_SOURCE, COMPLETION_LIST_BOX, GtkWidget) + +GtkWidget *_gtk_source_completion_list_box_new (void); +GtkSourceCompletionContext *_gtk_source_completion_list_box_get_context (GtkSourceCompletionListBox *self); +void _gtk_source_completion_list_box_set_context (GtkSourceCompletionListBox *self, + GtkSourceCompletionContext *context); +guint _gtk_source_completion_list_box_get_n_rows (GtkSourceCompletionListBox *self); +void _gtk_source_completion_list_box_set_n_rows (GtkSourceCompletionListBox *self, + guint n_rows); +GtkSourceCompletionProposal *_gtk_source_completion_list_box_get_proposal (GtkSourceCompletionListBox *self); +gboolean _gtk_source_completion_list_box_get_selected (GtkSourceCompletionListBox *self, + GtkSourceCompletionProvider **provider, + GtkSourceCompletionProposal **proposal); +void _gtk_source_completion_list_box_move_cursor (GtkSourceCompletionListBox *self, + GtkMovementStep step, + gint direction); +void _gtk_source_completion_list_box_set_font_desc (GtkSourceCompletionListBox *self, + const PangoFontDescription *font_desc); +GtkSourceCompletionListBoxRow *_gtk_source_completion_list_box_get_first (GtkSourceCompletionListBox *self); +gboolean _gtk_source_completion_list_box_key_activates (GtkSourceCompletionListBox *self, + const GdkKeyEvent *key); +int _gtk_source_completion_list_box_get_alternate (GtkSourceCompletionListBox *self); +guint _gtk_source_completion_list_box_get_n_alternates (GtkSourceCompletionListBox *self); +void _gtk_source_completion_list_box_set_show_icons (GtkSourceCompletionListBox *self, + gboolean show_icons); + +G_END_DECLS diff --git a/gtksourceview/gtksourcecompletionlistbox.c b/gtksourceview/gtksourcecompletionlistbox.c new file mode 100644 index 0000000000000000000000000000000000000000..f831ed45d9c98afe161b081629a0cf6d47af30ea --- /dev/null +++ b/gtksourceview/gtksourcecompletionlistbox.c @@ -0,0 +1,1273 @@ +/* + * This file is part of GtkSourceView + * + * Copyright 2020 Christian Hergert + * + * GtkSourceView is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * GtkSourceView 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, see . + * + * SPDX-License-Identifier: LGPL-2.1-or-later + */ + +#include "config.h" + +#include "gtksourcecompletion-private.h" +#include "gtksourcecompletioncontext-private.h" +#include "gtksourcecompletionlistbox-private.h" +#include "gtksourcecompletionlistboxrow-private.h" +#include "gtksourcecompletionproposal.h" +#include "gtksourcecompletionprovider.h" + +struct _GtkSourceCompletionListBox +{ + GtkWidget parent_instance; + + /* The box containing the rows. */ + GtkBox *box; + + /* Font styling for rows */ + PangoAttrList *font_attrs; + + /* The completion context that is being displayed. */ + GtkSourceCompletionContext *context; + + /* The handler for GtkSourceCompletionContext::items-chaged which should + * be disconnected when no longer needed. + */ + gulong items_changed_handler; + + /* The number of rows we expect to have visible to the user. */ + guint n_rows; + + /* The currently selected index within the result set. Signed to + * ensure our math in various places allows going negative to catch + * lower edge. + */ + int selected; + + /* The alternate proposal for the current selection. This references + * something from GtkSourceCompletionProvider.list_alternates(). + */ + GPtrArray *alternates; + int alternate; + + /* This is set whenever we make a change that requires updating the + * row content. We delay the update until the next frame callback so + * that we only update once right before we draw the frame. This helps + * reduce duplicate work when reacting to ::items-changed in the model. + */ + guint queued_update; + + /* These size groups are used to keep each portion of the proposal row + * aligned with each other. Since we only have a fixed number of visible + * rows, the overhead here is negligible by introducing the size cycle. + */ + GtkSizeGroup *before_size_group; + GtkSizeGroup *typed_text_size_group; + GtkSizeGroup *after_size_group; + + /* The adjustments for scrolling the GtkScrollable. */ + GtkAdjustment *hadjustment; + GtkAdjustment *vadjustment; + + /* Gesture to handle button press/touch events. */ + GtkGesture *click_gesture; + + /* If icons are visible */ + guint show_icons : 1; +}; + +typedef struct +{ + GtkSourceCompletionListBox *self; + GtkSourceCompletionContext *context; + guint n_items; + guint position; + int selected; +} UpdateState; + +enum { + PROP_0, + PROP_ALTERNATE, + PROP_CONTEXT, + PROP_PROPOSAL, + PROP_N_ROWS, + PROP_HADJUSTMENT, + PROP_HSCROLL_POLICY, + PROP_N_ALTERNATES, + PROP_VADJUSTMENT, + PROP_VSCROLL_POLICY, + N_PROPS +}; + +enum { + REPOSITION, + N_SIGNALS +}; + +static void gtk_source_completion_list_box_queue_update (GtkSourceCompletionListBox *self); +static gboolean gtk_source_completion_list_box_update_cb (GtkWidget *widget, + GdkFrameClock *frame_clock, + gpointer user_data); +static void gtk_source_completion_list_box_do_update (GtkSourceCompletionListBox *self, + gboolean update_selection); + +G_DEFINE_TYPE_WITH_CODE (GtkSourceCompletionListBox, gtk_source_completion_list_box, GTK_TYPE_WIDGET, + G_IMPLEMENT_INTERFACE (GTK_TYPE_SCROLLABLE, NULL)) + +static GParamSpec *properties [N_PROPS]; +static guint signals [N_SIGNALS]; + +static void +gtk_source_completion_list_box_set_selected (GtkSourceCompletionListBox *self, + int selected) +{ + GtkSourceCompletionProposal *proposal = NULL; + GtkSourceCompletionProvider *provider = NULL; + + g_assert (GTK_SOURCE_IS_COMPLETION_LIST_BOX (self)); + + if (selected == -1 && self->context != NULL) + { + GtkSourceCompletion *completion; + gboolean select_on_show; + + completion = gtk_source_completion_context_get_completion (self->context); + select_on_show = _gtk_source_completion_get_select_on_show (completion); + + if (select_on_show) + { + selected = 0; + } + } + + self->selected = selected; + self->alternate = -1; + g_clear_pointer (&self->alternates, g_ptr_array_unref); + + if (_gtk_source_completion_list_box_get_selected (self, &provider, &proposal)) + { + self->alternates = gtk_source_completion_provider_list_alternates (provider, self->context, proposal); + + if (self->alternates != NULL) + { + g_ptr_array_set_free_func (self->alternates, g_object_unref); + } + } + + gtk_source_completion_list_box_queue_update (self); + + g_clear_object (&proposal); + g_clear_object (&provider); +} + +static gboolean +move_next_alternate (GtkWidget *widget, + GVariant *param, + gpointer user_data) +{ + GtkSourceCompletionListBox *self = (GtkSourceCompletionListBox *)widget; + + g_assert (GTK_SOURCE_IS_COMPLETION_LIST_BOX (self)); + + if (self->alternates == NULL || self->alternates->len == 0) + { + return FALSE; + } + + if ((guint)(self->alternate + 1) < self->alternates->len) + { + self->alternate++; + } + else + { + self->alternate = -1; + } + + gtk_source_completion_list_box_do_update (self, FALSE); + + return TRUE; +} + +static void +move_next_alternate_action (GtkWidget *widget, + const char *action_name, + GVariant *param) +{ + g_assert (GTK_SOURCE_IS_COMPLETION_LIST_BOX (widget)); + + move_next_alternate (widget, param, NULL); +} + +static gboolean +move_previous_alternate (GtkWidget *widget, + GVariant *param, + gpointer user_data) +{ + GtkSourceCompletionListBox *self = (GtkSourceCompletionListBox *)widget; + + g_assert (GTK_SOURCE_IS_COMPLETION_LIST_BOX (self)); + + if (self->alternates == NULL || self->alternates->len == 0) + { + return FALSE; + } + + if (self->alternate < 0) + { + self->alternate = self->alternates->len - 1; + } + else + { + self->alternate--; + } + + gtk_source_completion_list_box_do_update (self, FALSE); + + return TRUE; +} + +static void +move_previous_alternate_action (GtkWidget *widget, + const char *action_name, + GVariant *param) +{ + g_assert (GTK_SOURCE_IS_COMPLETION_LIST_BOX (widget)); + + move_previous_alternate (widget, param, NULL); +} + +static guint +gtk_source_completion_list_box_get_offset (GtkSourceCompletionListBox *self) +{ + g_assert (GTK_SOURCE_IS_COMPLETION_LIST_BOX (self)); + + return gtk_adjustment_get_value (self->vadjustment); +} + +static void +gtk_source_completion_list_box_set_offset (GtkSourceCompletionListBox *self, + guint offset) +{ + double value = offset; + double page_size; + double upper; + double lower; + + g_assert (GTK_SOURCE_IS_COMPLETION_LIST_BOX (self)); + + lower = gtk_adjustment_get_lower (self->vadjustment); + upper = gtk_adjustment_get_upper (self->vadjustment); + page_size = gtk_adjustment_get_page_size (self->vadjustment); + + if (value > (upper - page_size)) + { + value = upper - page_size; + } + + if (value < lower) + { + value = lower; + } + + gtk_adjustment_set_value (self->vadjustment, value); +} + +static void +gtk_source_completion_list_box_value_changed (GtkSourceCompletionListBox *self, + GtkAdjustment *vadj) +{ + g_assert (GTK_SOURCE_IS_COMPLETION_LIST_BOX (self)); + g_assert (GTK_IS_ADJUSTMENT (vadj)); + + gtk_source_completion_list_box_queue_update (self); +} + +static void +gtk_source_completion_list_box_set_hadjustment (GtkSourceCompletionListBox *self, + GtkAdjustment *hadjustment) +{ + g_assert (GTK_SOURCE_IS_COMPLETION_LIST_BOX (self)); + g_assert (!hadjustment || GTK_IS_ADJUSTMENT (hadjustment)); + + if (g_set_object (&self->hadjustment, hadjustment)) + { + gtk_source_completion_list_box_queue_update (self); + } +} + +static void +gtk_source_completion_list_box_set_vadjustment (GtkSourceCompletionListBox *self, + GtkAdjustment *vadjustment) +{ + g_assert (GTK_SOURCE_IS_COMPLETION_LIST_BOX (self)); + g_assert (!vadjustment || GTK_IS_ADJUSTMENT (vadjustment)); + + if (self->vadjustment == vadjustment) + return; + + if (self->vadjustment) + { + g_signal_handlers_disconnect_by_func (self->vadjustment, + G_CALLBACK (gtk_source_completion_list_box_value_changed), + self); + g_clear_object (&self->vadjustment); + } + + if (vadjustment) + { + self->vadjustment = g_object_ref (vadjustment); + + gtk_adjustment_set_lower (self->vadjustment, 0); + gtk_adjustment_set_upper (self->vadjustment, 0); + gtk_adjustment_set_value (self->vadjustment, 0); + gtk_adjustment_set_step_increment (self->vadjustment, 1); + gtk_adjustment_set_page_size (self->vadjustment, self->n_rows); + gtk_adjustment_set_page_increment (self->vadjustment, self->n_rows); + + g_signal_connect_object (self->vadjustment, + "value-changed", + G_CALLBACK (gtk_source_completion_list_box_value_changed), + self, + G_CONNECT_SWAPPED); + } + + gtk_source_completion_list_box_queue_update (self); +} + +static guint +get_row_at_y (GtkSourceCompletionListBox *self, + double y) +{ + GtkAllocation alloc; + guint offset; + guint n_items; + + g_assert (GTK_SOURCE_IS_COMPLETION_LIST_BOX (self)); + g_assert (G_IS_LIST_MODEL (self->context)); + + gtk_widget_get_allocation (GTK_WIDGET (self), &alloc); + + offset = gtk_source_completion_list_box_get_offset (self); + + n_items = g_list_model_get_n_items (G_LIST_MODEL (self->context)); + n_items = MAX (1, MIN (self->n_rows, n_items)); + + return offset + (y / (alloc.height / n_items)); +} + +static void +click_gesture_pressed (GtkGestureClick *gesture, + guint n_press, + double x, + double y, + GtkSourceCompletionListBox *self) +{ + int selected; + + g_assert (GTK_IS_GESTURE_CLICK (gesture)); + g_assert (GTK_SOURCE_IS_COMPLETION_LIST_BOX (self)); + + if (self->context == NULL) + { + return; + } + + selected = get_row_at_y (self, y); + + if (selected != self->selected) + { + gtk_source_completion_list_box_set_selected (self, selected); + } + else + { + GtkSourceCompletionProvider *provider = NULL; + GtkSourceCompletionProposal *proposal = NULL; + + if (self->selected >= 0 && + self->selected < (int)g_list_model_get_n_items (G_LIST_MODEL (self->context)) && + _gtk_source_completion_context_get_item_full (self->context, self->selected, &provider, &proposal)) + { + _gtk_source_completion_activate (gtk_source_completion_context_get_completion (self->context), + self->context, provider, proposal); + g_clear_object (&provider); + g_clear_object (&proposal); + } + } +} + +static gboolean +move_binding_cb (GtkWidget *widget, + GVariant *param, + gpointer user_data) +{ + GtkSourceCompletionListBox *self = (GtkSourceCompletionListBox *)widget; + int direction = 0; + + g_assert (GTK_SOURCE_IS_COMPLETION_LIST_BOX (self)); + + g_variant_get (param, "(i)", &direction); + + if (ABS (direction) == 1) + { + _gtk_source_completion_list_box_move_cursor (self, GTK_MOVEMENT_DISPLAY_LINES, direction); + } + else + { + _gtk_source_completion_list_box_move_cursor (self, GTK_MOVEMENT_PAGES, direction > 0 ? 1 : -1); + } + + return TRUE; +} + +static gboolean +activate_nth_cb (GtkWidget *widget, + GVariant *param, + gpointer user_data) +{ + GtkSourceCompletionListBox *self = (GtkSourceCompletionListBox *)widget; + GtkSourceCompletionProvider *provider = NULL; + GtkSourceCompletionProposal *proposal = NULL; + int nth = 0; + + g_assert (GTK_SOURCE_IS_COMPLETION_LIST_BOX (self)); + + if (self->context == NULL) + { + return FALSE; + } + + g_variant_get (param, "(i)", &nth); + + if (nth == 0 && self->selected >= 0) + { + nth = self->selected; + } + else + { + nth--; + } + + if (nth < 0 || (guint)nth >= g_list_model_get_n_items (G_LIST_MODEL (self->context))) + { + return FALSE; + } + + if (!_gtk_source_completion_context_get_item_full (self->context, nth, &provider, &proposal)) + { + return FALSE; + } + + g_assert (GTK_SOURCE_IS_COMPLETION_PROVIDER (provider)); + g_assert (GTK_SOURCE_IS_COMPLETION_PROPOSAL (proposal)); + + _gtk_source_completion_activate (gtk_source_completion_context_get_completion (self->context), + self->context, + provider, + proposal); + + g_clear_object (&proposal); + g_clear_object (&provider); + + return TRUE; +} + +static gboolean +_gtk_source_completion_list_box_key_pressed_cb (GtkSourceCompletionListBox *self, + guint keyval, + guint keycode, + GdkModifierType state, + GtkEventControllerKey *key) +{ + GtkSourceCompletionProvider *provider = NULL; + GtkSourceCompletionProposal *proposal = NULL; + gboolean ret = FALSE; + + g_assert (GTK_SOURCE_IS_COMPLETION_LIST_BOX (self)); + g_assert (GTK_IS_EVENT_CONTROLLER_KEY (key)); + + if (self->context == NULL) + { + return FALSE; + } + + if (_gtk_source_completion_list_box_get_selected (self, &provider, &proposal)) + { + if (gtk_source_completion_provider_key_activates (provider, self->context, proposal, keyval, state)) + { + _gtk_source_completion_activate (gtk_source_completion_context_get_completion (self->context), + self->context, + provider, + proposal); + ret = TRUE; + } + } + + g_clear_object (&proposal); + g_clear_object (&provider); + + return ret; +} + +static void +gtk_source_completion_list_box_constructed (GObject *object) +{ + GtkSourceCompletionListBox *self = (GtkSourceCompletionListBox *)object; + + G_OBJECT_CLASS (gtk_source_completion_list_box_parent_class)->constructed (object); + + if (self->hadjustment == NULL) + { + self->hadjustment = gtk_adjustment_new (0, 0, 0, 0, 0, 0); + } + + if (self->vadjustment == NULL) + { + self->vadjustment = gtk_adjustment_new (0, 0, 0, 0, 0, 0); + } + + gtk_adjustment_set_lower (self->hadjustment, 0); + gtk_adjustment_set_upper (self->hadjustment, 0); + gtk_adjustment_set_value (self->hadjustment, 0); + + gtk_source_completion_list_box_queue_update (self); +} + +static void +gtk_source_completion_list_box_dispose (GObject *object) +{ + GtkSourceCompletionListBox *self = (GtkSourceCompletionListBox *)object; + + if (self->box != NULL) + { + gtk_widget_unparent (GTK_WIDGET (self->box)); + self->box = NULL; + } + + g_clear_object (&self->before_size_group); + g_clear_object (&self->typed_text_size_group); + g_clear_object (&self->after_size_group); + g_clear_object (&self->hadjustment); + g_clear_object (&self->vadjustment); + g_clear_pointer (&self->font_attrs, pango_attr_list_unref); + + G_OBJECT_CLASS (gtk_source_completion_list_box_parent_class)->dispose (object); +} + +static void +gtk_source_completion_list_box_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + GtkSourceCompletionListBox *self = GTK_SOURCE_COMPLETION_LIST_BOX (object); + + switch (prop_id) + { + case PROP_N_ALTERNATES: + g_value_set_int (value, self->alternates ? self->alternates->len : 0); + break; + + case PROP_ALTERNATE: + g_value_set_int (value, self->alternate); + break; + + case PROP_CONTEXT: + g_value_set_object (value, _gtk_source_completion_list_box_get_context (self)); + break; + + case PROP_PROPOSAL: + g_value_take_object (value, _gtk_source_completion_list_box_get_proposal (self)); + break; + + case PROP_N_ROWS: + g_value_set_uint (value, _gtk_source_completion_list_box_get_n_rows (self)); + break; + + case PROP_HADJUSTMENT: + g_value_set_object (value, self->hadjustment); + break; + + case PROP_VADJUSTMENT: + g_value_set_object (value, self->vadjustment); + break; + + case PROP_HSCROLL_POLICY: + g_value_set_enum (value, GTK_SCROLL_NATURAL); + break; + + case PROP_VSCROLL_POLICY: + g_value_set_enum (value, GTK_SCROLL_NATURAL); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static void +gtk_source_completion_list_box_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + GtkSourceCompletionListBox *self = GTK_SOURCE_COMPLETION_LIST_BOX (object); + + switch (prop_id) + { + case PROP_CONTEXT: + _gtk_source_completion_list_box_set_context (self, g_value_get_object (value)); + break; + + case PROP_N_ROWS: + _gtk_source_completion_list_box_set_n_rows (self, g_value_get_uint (value)); + break; + + case PROP_HADJUSTMENT: + gtk_source_completion_list_box_set_hadjustment (self, g_value_get_object (value)); + break; + + case PROP_VADJUSTMENT: + gtk_source_completion_list_box_set_vadjustment (self, g_value_get_object (value)); + break; + + case PROP_HSCROLL_POLICY: + /* Do nothing */ + break; + + case PROP_VSCROLL_POLICY: + /* Do nothing */ + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static void +gtk_source_completion_list_box_class_init (GtkSourceCompletionListBoxClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); + + object_class->constructed = gtk_source_completion_list_box_constructed; + object_class->dispose = gtk_source_completion_list_box_dispose; + object_class->get_property = gtk_source_completion_list_box_get_property; + object_class->set_property = gtk_source_completion_list_box_set_property; + + properties [PROP_ALTERNATE] = + g_param_spec_int ("alternate", + "Alternate", + "The alternate to choose", + -1, G_MAXINT, -1, + (G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); + + properties [PROP_N_ALTERNATES] = + g_param_spec_int ("n-alternates", + "N Alternates", + "The number of alternates", + 0, G_MAXINT, 0, + (G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); + + properties [PROP_CONTEXT] = + g_param_spec_object ("context", + "Context", + "The context being displayed", + GTK_SOURCE_TYPE_COMPLETION_CONTEXT, + (G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS)); + + properties [PROP_HADJUSTMENT] = + g_param_spec_object ("hadjustment", NULL, NULL, + GTK_TYPE_ADJUSTMENT, + (G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS)); + + properties [PROP_HSCROLL_POLICY] = + g_param_spec_enum ("hscroll-policy", NULL, NULL, + GTK_TYPE_SCROLLABLE_POLICY, + GTK_SCROLL_NATURAL, + (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + properties [PROP_VADJUSTMENT] = + g_param_spec_object ("vadjustment", NULL, NULL, + GTK_TYPE_ADJUSTMENT, + (G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS)); + + properties [PROP_VSCROLL_POLICY] = + g_param_spec_enum ("vscroll-policy", NULL, NULL, + GTK_TYPE_SCROLLABLE_POLICY, + GTK_SCROLL_NATURAL, + (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + properties [PROP_PROPOSAL] = + g_param_spec_object ("proposal", + "Proposal", + "The proposal that is currently selected", + GTK_SOURCE_TYPE_COMPLETION_PROPOSAL, + (G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); + + properties [PROP_N_ROWS] = + g_param_spec_uint ("n-rows", + "N Rows", + "The number of visible rows", + 1, 32, 5, + (G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS)); + + g_object_class_install_properties (object_class, N_PROPS, properties); + + signals [REPOSITION] = + g_signal_new_class_handler ("reposition", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + NULL, NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); + g_signal_set_va_marshaller (signals [REPOSITION], + G_TYPE_FROM_CLASS (klass), + g_cclosure_marshal_VOID__VOIDv); + + gtk_widget_class_set_layout_manager_type (widget_class, GTK_TYPE_BIN_LAYOUT); + gtk_widget_class_set_css_name (widget_class, "list"); + + gtk_widget_class_install_action (widget_class, "proposal.move-next-alternate", NULL, move_next_alternate_action); + gtk_widget_class_install_action (widget_class, "proposal.move-previous-alternate", NULL, move_previous_alternate_action); + + gtk_widget_class_add_binding (widget_class, GDK_KEY_Down, 0, move_binding_cb, "(i)", 1); + gtk_widget_class_add_binding (widget_class, GDK_KEY_Up, 0, move_binding_cb, "(i)", -1); + gtk_widget_class_add_binding (widget_class, GDK_KEY_Page_Up, 0, move_binding_cb, "(i)", -2); + gtk_widget_class_add_binding (widget_class, GDK_KEY_Page_Down, 0, move_binding_cb, "(i)", 2); + gtk_widget_class_add_binding (widget_class, GDK_KEY_1, GDK_ALT_MASK, activate_nth_cb, "(i)", 1); + gtk_widget_class_add_binding (widget_class, GDK_KEY_2, GDK_ALT_MASK, activate_nth_cb, "(i)", 2); + gtk_widget_class_add_binding (widget_class, GDK_KEY_3, GDK_ALT_MASK, activate_nth_cb, "(i)", 3); + gtk_widget_class_add_binding (widget_class, GDK_KEY_4, GDK_ALT_MASK, activate_nth_cb, "(i)", 4); + gtk_widget_class_add_binding (widget_class, GDK_KEY_5, GDK_ALT_MASK, activate_nth_cb, "(i)", 5); + gtk_widget_class_add_binding (widget_class, GDK_KEY_6, GDK_ALT_MASK, activate_nth_cb, "(i)", 6); + gtk_widget_class_add_binding (widget_class, GDK_KEY_7, GDK_ALT_MASK, activate_nth_cb, "(i)", 7); + gtk_widget_class_add_binding (widget_class, GDK_KEY_8, GDK_ALT_MASK, activate_nth_cb, "(i)", 8); + gtk_widget_class_add_binding (widget_class, GDK_KEY_9, GDK_ALT_MASK, activate_nth_cb, "(i)", 9); + gtk_widget_class_add_binding (widget_class, GDK_KEY_Return, 0, activate_nth_cb, "(i)", 0); + gtk_widget_class_add_binding (widget_class, GDK_KEY_KP_Enter, 0, activate_nth_cb, "(i)", 0); + gtk_widget_class_add_binding (widget_class, GDK_KEY_Tab, 0, activate_nth_cb, "(i)", 0); + gtk_widget_class_add_binding (widget_class, GDK_KEY_Right, 0, move_next_alternate, NULL); + gtk_widget_class_add_binding (widget_class, GDK_KEY_Left, 0, move_previous_alternate, NULL); + gtk_widget_class_add_binding_action (widget_class, GDK_KEY_Escape, 0, "assistant.hide", NULL); + + g_type_ensure (GTK_SOURCE_TYPE_COMPLETION_LIST_BOX_ROW); +} + +static void +gtk_source_completion_list_box_init (GtkSourceCompletionListBox *self) +{ + GtkEventController *key; + + key = gtk_event_controller_key_new (); + g_signal_connect_swapped (key, + "key-pressed", + G_CALLBACK (_gtk_source_completion_list_box_key_pressed_cb), + self); + gtk_widget_add_controller (GTK_WIDGET (self), key); + + self->box = g_object_new (GTK_TYPE_BOX, + "orientation", GTK_ORIENTATION_VERTICAL, + "visible", TRUE, + NULL); + gtk_widget_set_parent (GTK_WIDGET (self->box), GTK_WIDGET (self)); + + self->selected = -1; + self->alternate = -1; + self->before_size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL); + self->typed_text_size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL); + self->after_size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL); + + self->click_gesture = gtk_gesture_click_new (); + gtk_event_controller_set_propagation_phase (GTK_EVENT_CONTROLLER (self->click_gesture), GTK_PHASE_BUBBLE); + gtk_gesture_single_set_touch_only (GTK_GESTURE_SINGLE (self->click_gesture), FALSE); + gtk_gesture_single_set_button (GTK_GESTURE_SINGLE (self->click_gesture), GDK_BUTTON_PRIMARY); + g_signal_connect_object (self->click_gesture, "pressed", + G_CALLBACK (click_gesture_pressed), self, 0); + gtk_widget_add_controller (GTK_WIDGET (self), GTK_EVENT_CONTROLLER (self->click_gesture)); +} + +static void +gtk_source_completion_list_box_do_update (GtkSourceCompletionListBox *self, + gboolean update_selection) +{ + UpdateState state = {0}; + + g_assert (GTK_SOURCE_IS_COMPLETION_LIST_BOX (self)); + + state.self = self; + state.context = self->context; + state.position = gtk_source_completion_list_box_get_offset (self); + state.selected = self->selected; + + if (self->context != NULL) + { + state.n_items = g_list_model_get_n_items (G_LIST_MODEL (self->context)); + } + + state.position = MIN (state.position, MAX (state.n_items, self->n_rows) - self->n_rows); + state.selected = MIN (self->selected, state.n_items ? (int)state.n_items - 1 : 0); + + if (gtk_adjustment_get_upper (self->vadjustment) != state.n_items) + { + gtk_adjustment_set_upper (self->vadjustment, state.n_items); + } + + for (GtkWidget *iter = gtk_widget_get_first_child (GTK_WIDGET (self->box)); + iter != NULL; + iter = gtk_widget_get_next_sibling (iter)) + { + GtkSourceCompletionProposal *proposal = NULL; + GtkSourceCompletionProvider *provider = NULL; + gboolean has_alternates = FALSE; + + g_assert (GTK_SOURCE_IS_COMPLETION_LIST_BOX_ROW (iter)); + + if (state.selected >= 0 && state.position == (guint)state.selected) + { + gtk_widget_set_state_flags (iter, GTK_STATE_FLAG_SELECTED, FALSE); + } + else + { + gtk_widget_unset_state_flags (iter, GTK_STATE_FLAG_SELECTED); + } + + if (state.context != NULL && state.position < state.n_items) + { + _gtk_source_completion_context_get_item_full (state.context, + state.position, + &provider, + &proposal); + + if (state.selected == (int)state.position) + { + if (self->alternate >= 0 && self->alternate < (int)self->alternates->len) + { + g_clear_object (&proposal); + proposal = g_object_ref (g_ptr_array_index (self->alternates, self->alternate)); + } + + has_alternates = self->alternates != NULL && self->alternates->len > 0; + } + + _gtk_source_completion_list_box_row_display (GTK_SOURCE_COMPLETION_LIST_BOX_ROW (iter), + state.context, + provider, + proposal, + self->show_icons, + has_alternates); + + gtk_widget_show (iter); + } + else + { + _gtk_source_completion_list_box_row_display (GTK_SOURCE_COMPLETION_LIST_BOX_ROW (iter), + NULL, NULL, NULL, self->show_icons, FALSE); + gtk_widget_hide (GTK_WIDGET (iter)); + } + + state.position++; + + g_clear_object (&proposal); + g_clear_object (&provider); + } + + if (update_selection) + { + gtk_source_completion_list_box_set_selected (self, state.selected); + } + + g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_PROPOSAL]); + g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_N_ALTERNATES]); + g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_ALTERNATE]); + + g_signal_emit (self, signals [REPOSITION], 0); +} + +static gboolean +gtk_source_completion_list_box_update_cb (GtkWidget *widget, + GdkFrameClock *frame_clock, + gpointer user_data) +{ + GtkSourceCompletionListBox *self = (GtkSourceCompletionListBox *)widget; + + g_assert (GTK_SOURCE_IS_COMPLETION_LIST_BOX (self)); + + gtk_source_completion_list_box_do_update (self, TRUE); + self->queued_update = 0; + return G_SOURCE_REMOVE; +} + +static void +gtk_source_completion_list_box_queue_update (GtkSourceCompletionListBox *self) +{ + g_assert (GTK_SOURCE_IS_COMPLETION_LIST_BOX (self)); + + /* See gtk_source_completion_list_box_set_selected() for while this needs + * to be set here to avoid re-entrancy. + */ + if (self->queued_update == 0) + { + self->queued_update = gtk_widget_add_tick_callback (GTK_WIDGET (self), + gtk_source_completion_list_box_update_cb, + NULL, NULL); + } +} + +GtkWidget * +_gtk_source_completion_list_box_new (void) +{ + return g_object_new (GTK_SOURCE_TYPE_COMPLETION_LIST_BOX, NULL); +} + +guint +_gtk_source_completion_list_box_get_n_rows (GtkSourceCompletionListBox *self) +{ + g_return_val_if_fail (GTK_SOURCE_IS_COMPLETION_LIST_BOX (self), 0); + + return self->n_rows; +} + +void +_gtk_source_completion_list_box_set_n_rows (GtkSourceCompletionListBox *self, + guint n_rows) +{ + g_return_if_fail (GTK_SOURCE_IS_COMPLETION_LIST_BOX (self)); + g_return_if_fail (n_rows > 0); + g_return_if_fail (n_rows <= 32); + + if (n_rows != self->n_rows) + { + GtkWidget *tmp; + + while ((tmp = gtk_widget_get_first_child (GTK_WIDGET (self->box)))) + { + gtk_box_remove (self->box, tmp); + } + + self->n_rows = n_rows; + + if (self->vadjustment != NULL) + { + gtk_adjustment_set_page_size (self->vadjustment, n_rows); + } + + for (guint i = 0; i < n_rows; i++) + { + GtkWidget *row; + + row = _gtk_source_completion_list_box_row_new (); + gtk_widget_set_can_focus (GTK_WIDGET (row), FALSE); + _gtk_source_completion_list_box_row_attach (GTK_SOURCE_COMPLETION_LIST_BOX_ROW (row), + self->before_size_group, + self->typed_text_size_group, + self->after_size_group); + _gtk_source_completion_list_box_row_set_attrs (GTK_SOURCE_COMPLETION_LIST_BOX_ROW (row), + self->font_attrs); + gtk_box_append (self->box, row); + } + + gtk_source_completion_list_box_queue_update (self); + + g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_N_ROWS]); + } +} + +/** + * gtk_source_completion_list_box_get_proposal: + * @self: a #GtkSourceCompletionListBox + * + * Gets the currently selected proposal, or %NULL if no proposal is selected + * + * Returns: (nullable) (transfer full): a #GtkSourceCompletionProposal or %NULL + * + * Since: 5.0 + */ +GtkSourceCompletionProposal * +_gtk_source_completion_list_box_get_proposal (GtkSourceCompletionListBox *self) +{ + GtkSourceCompletionProposal *ret = NULL; + + g_return_val_if_fail (GTK_SOURCE_IS_COMPLETION_LIST_BOX (self), NULL); + + if (self->context != NULL && + self->selected < (int)g_list_model_get_n_items (G_LIST_MODEL (self->context))) + ret = g_list_model_get_item (G_LIST_MODEL (self->context), self->selected); + + g_return_val_if_fail (!ret || GTK_SOURCE_IS_COMPLETION_PROPOSAL (ret), NULL); + + return ret; +} + +/** + * _gtk_source_completion_list_box_get_selected: + * @self: an #GtkSourceCompletionListBox + * @provider: (out) (transfer full) (optional): a location for the provider + * @proposal: (out) (transfer full) (optional): a location for the proposal + * + * Gets the selected item if there is any. + * + * If there is a selection, %TRUE is returned and @provider and @proposal + * are set to the selected provider/proposal. + * + * Returns: %TRUE if there is a selection + * + * Since: 5.0 + */ +gboolean +_gtk_source_completion_list_box_get_selected (GtkSourceCompletionListBox *self, + GtkSourceCompletionProvider **provider, + GtkSourceCompletionProposal **proposal) +{ + g_return_val_if_fail (GTK_SOURCE_IS_COMPLETION_LIST_BOX (self), FALSE); + + if (self->context != NULL) + { + guint n_items = g_list_model_get_n_items (G_LIST_MODEL (self->context)); + + if (n_items > 0) + { + if (self->selected >= 0) + { + gint selected = MIN (self->selected, (int)n_items - 1); + _gtk_source_completion_context_get_item_full (self->context, selected, provider, proposal); + return TRUE; + } + } + } + + return FALSE; +} + +/** + * gtk_source_completion_list_box_get_context: + * @self: a #GtkSourceCompletionListBox + * + * Gets the context that is being displayed in the list box. + * + * Returns: (transfer none) (nullable): an #GtkSourceCompletionContext or %NULL + * + * Since: 5.0 + */ +GtkSourceCompletionContext * +_gtk_source_completion_list_box_get_context (GtkSourceCompletionListBox *self) +{ + g_return_val_if_fail (GTK_SOURCE_IS_COMPLETION_LIST_BOX (self), NULL); + + return self->context; +} + +static void +gtk_source_completion_list_box_items_changed_cb (GtkSourceCompletionListBox *self, + guint position, + guint removed, + guint added, + GListModel *model) +{ + guint offset; + + g_assert (GTK_SOURCE_IS_COMPLETION_LIST_BOX (self)); + g_assert (G_IS_LIST_MODEL (model)); + + offset = gtk_source_completion_list_box_get_offset (self); + + /* Skip widget resize if results are after visible area */ + if (position >= offset + self->n_rows) + return; + + gtk_source_completion_list_box_queue_update (self); +} + +/** + * gtk_source_completion_list_box_set_context: + * @self: a #GtkSourceCompletionListBox + * @context: the #GtkSourceCompletionContext + * + * Sets the context to be displayed. + * + * Since: 5.0 + */ +void +_gtk_source_completion_list_box_set_context (GtkSourceCompletionListBox *self, + GtkSourceCompletionContext *context) +{ + g_return_if_fail (GTK_SOURCE_IS_COMPLETION_LIST_BOX (self)); + g_return_if_fail (!context || GTK_SOURCE_IS_COMPLETION_CONTEXT (context)); + + if (self->context == context) + return; + + if (self->context != NULL && self->items_changed_handler != 0) + { + g_signal_handler_disconnect (self->context, self->items_changed_handler); + self->items_changed_handler = 0; + } + + g_set_object (&self->context, context); + + if (self->context != NULL) + { + self->items_changed_handler = + g_signal_connect_object (self->context, + "items-changed", + G_CALLBACK (gtk_source_completion_list_box_items_changed_cb), + self, + G_CONNECT_SWAPPED); + } + + gtk_source_completion_list_box_set_selected (self, -1); + gtk_adjustment_set_value (self->vadjustment, 0); + + g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_CONTEXT]); +} + +GtkSourceCompletionListBoxRow * +_gtk_source_completion_list_box_get_first (GtkSourceCompletionListBox *self) +{ + g_return_val_if_fail (GTK_SOURCE_IS_COMPLETION_LIST_BOX (self), NULL); + + return GTK_SOURCE_COMPLETION_LIST_BOX_ROW (gtk_widget_get_first_child (GTK_WIDGET (self->box))); +} + +void +_gtk_source_completion_list_box_move_cursor (GtkSourceCompletionListBox *self, + GtkMovementStep step, + int direction) +{ + int n_items; + int offset; + + g_return_if_fail (GTK_SOURCE_IS_COMPLETION_LIST_BOX (self)); + + if (self->context == NULL || direction == 0) + return; + + if (!(n_items = g_list_model_get_n_items (G_LIST_MODEL (self->context)))) + return; + + /* n_items is signed so that we can do negative comparison */ + if (n_items < 0) + return; + + if (step == GTK_MOVEMENT_BUFFER_ENDS) + { + if (direction > 0) + { + gtk_source_completion_list_box_set_offset (self, n_items); + gtk_source_completion_list_box_set_selected (self, n_items - 1); + } + else + { + gtk_source_completion_list_box_set_offset (self, 0); + gtk_source_completion_list_box_set_selected (self, -1); + } + + gtk_source_completion_list_box_queue_update (self); + + return; + } + + if ((direction < 0 && self->selected == 0) || + (direction > 0 && self->selected == n_items - 1)) + { + return; + } + + if (step == GTK_MOVEMENT_PAGES) + { + direction *= self->n_rows; + } + + if ((self->selected + direction) > n_items) + { + gtk_source_completion_list_box_set_selected (self, n_items - 1); + } + else if ((self->selected + direction) < 0) + { + gtk_source_completion_list_box_set_selected (self, 0); + } + else + { + gtk_source_completion_list_box_set_selected (self, self->selected + direction); + } + + offset = gtk_source_completion_list_box_get_offset (self); + + if (self->selected < offset) + { + gtk_source_completion_list_box_set_offset (self, self->selected); + } + else if (self->selected >= (int)(offset + self->n_rows)) + { + gtk_source_completion_list_box_set_offset (self, self->selected - self->n_rows + 1); + } + + gtk_source_completion_list_box_queue_update (self); +} + +void +_gtk_source_completion_list_box_set_font_desc (GtkSourceCompletionListBox *self, + const PangoFontDescription *font_desc) +{ + GtkWidget *iter; + + g_return_if_fail (GTK_SOURCE_IS_COMPLETION_LIST_BOX (self)); + + g_clear_pointer (&self->font_attrs, pango_attr_list_unref); + + if (font_desc) + { + self->font_attrs = pango_attr_list_new (); + + if (font_desc != NULL) + { + pango_attr_list_insert (self->font_attrs, pango_attr_font_desc_new (font_desc)); + pango_attr_list_insert (self->font_attrs, pango_attr_font_features_new ("tnum")); + } + } + + for ((iter = gtk_widget_get_first_child (GTK_WIDGET (self->box))); + iter != NULL; + iter = gtk_widget_get_next_sibling (iter)) + { + _gtk_source_completion_list_box_row_set_attrs (GTK_SOURCE_COMPLETION_LIST_BOX_ROW (iter), + self->font_attrs); + } +} + +int +_gtk_source_completion_list_box_get_alternate (GtkSourceCompletionListBox *self) +{ + g_return_val_if_fail (GTK_SOURCE_IS_COMPLETION_LIST_BOX (self), 0); + + return self->alternate + 1; +} + +guint +_gtk_source_completion_list_box_get_n_alternates (GtkSourceCompletionListBox *self) +{ + g_return_val_if_fail (GTK_SOURCE_IS_COMPLETION_LIST_BOX (self), 0); + + return self->alternates ? self->alternates->len : 0; +} + +void +_gtk_source_completion_list_box_set_show_icons (GtkSourceCompletionListBox *self, + gboolean show_icons) +{ + g_return_if_fail (GTK_SOURCE_IS_COMPLETION_LIST_BOX (self)); + + self->show_icons = !!show_icons; + + gtk_source_completion_list_box_queue_update (self); +} diff --git a/gtksourceview/gtksourcecompletionlistboxrow-private.h b/gtksourceview/gtksourcecompletionlistboxrow-private.h new file mode 100644 index 0000000000000000000000000000000000000000..ab3fa8c059302f71c7e8c477ba703c1cbdbe7eb3 --- /dev/null +++ b/gtksourceview/gtksourcecompletionlistboxrow-private.h @@ -0,0 +1,50 @@ +/* + * This file is part of GtkSourceView + * + * Copyright 2020 Christian Hergert + * + * GtkSourceView is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * GtkSourceView 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, see . + * + * SPDX-License-Identifier: LGPL-2.1-or-later + */ + +#pragma once + +#include + +#include "gtksourcetypes.h" + +G_BEGIN_DECLS + +#define GTK_SOURCE_TYPE_COMPLETION_LIST_BOX_ROW (gtk_source_completion_list_box_row_get_type()) + +G_DECLARE_FINAL_TYPE (GtkSourceCompletionListBoxRow, gtk_source_completion_list_box_row, GTK_SOURCE, COMPLETION_LIST_BOX_ROW, GtkListBoxRow) + +GtkWidget *_gtk_source_completion_list_box_row_new (void); +void _gtk_source_completion_list_box_row_display (GtkSourceCompletionListBoxRow *self, + GtkSourceCompletionContext *context, + GtkSourceCompletionProvider *provider, + GtkSourceCompletionProposal *proposal, + gboolean show_icons, + gboolean has_alternates); +gint _gtk_source_completion_list_box_row_get_x_offset (GtkSourceCompletionListBoxRow *self, + GtkWidget *toplevel); +void _gtk_source_completion_list_box_row_set_attrs (GtkSourceCompletionListBoxRow *self, + PangoAttrList *attrs); +void _gtk_source_completion_list_box_row_attach (GtkSourceCompletionListBoxRow *self, + GtkSizeGroup *before, + GtkSizeGroup *typed_text, + GtkSizeGroup *after); + +G_END_DECLS diff --git a/gtksourceview/gtksourcecompletionlistboxrow.c b/gtksourceview/gtksourcecompletionlistboxrow.c new file mode 100644 index 0000000000000000000000000000000000000000..c64e358b5ce7d28a75599376171ca26b16536ea4 --- /dev/null +++ b/gtksourceview/gtksourcecompletionlistboxrow.c @@ -0,0 +1,197 @@ +/* + * This file is part of GtkSourceView + * + * Copyright 2020 Christian Hergert + * + * GtkSourceView is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * GtkSourceView 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, see . + * + * SPDX-License-Identifier: LGPL-2.1-or-later + */ + +#include "config.h" + +#include "gtksourcecompletioncell-private.h" +#include "gtksourcecompletioncontext-private.h" +#include "gtksourcecompletionlistboxrow-private.h" +#include "gtksourcecompletionproposal.h" +#include "gtksourcecompletionprovider.h" + +struct _GtkSourceCompletionListBoxRow +{ + GtkListBoxRow parent_instance; + + GtkSourceCompletionProposal *proposal; + PangoAttrList *attrs; + + GtkBox *box; + GtkBox *more; + GtkSourceCompletionCell *icon; + GtkSourceCompletionCell *before; + GtkSourceCompletionCell *typed_text; + GtkSourceCompletionCell *after; +}; + +G_DEFINE_TYPE (GtkSourceCompletionListBoxRow, gtk_source_completion_list_box_row, GTK_TYPE_LIST_BOX_ROW) + +static void +gtk_source_completion_list_box_row_finalize (GObject *object) +{ + GtkSourceCompletionListBoxRow *self = (GtkSourceCompletionListBoxRow *)object; + + g_clear_pointer (&self->attrs, pango_attr_list_unref); + + G_OBJECT_CLASS (gtk_source_completion_list_box_row_parent_class)->finalize (object); +} + +static void +gtk_source_completion_list_box_row_class_init (GtkSourceCompletionListBoxRowClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); + + object_class->finalize = gtk_source_completion_list_box_row_finalize; + + gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/gtksourceview/ui/gtksourcecompletionlistboxrow.ui"); + gtk_widget_class_bind_template_child (widget_class, GtkSourceCompletionListBoxRow, box); + gtk_widget_class_bind_template_child (widget_class, GtkSourceCompletionListBoxRow, icon); + gtk_widget_class_bind_template_child (widget_class, GtkSourceCompletionListBoxRow, before); + gtk_widget_class_bind_template_child (widget_class, GtkSourceCompletionListBoxRow, typed_text); + gtk_widget_class_bind_template_child (widget_class, GtkSourceCompletionListBoxRow, after); + gtk_widget_class_bind_template_child (widget_class, GtkSourceCompletionListBoxRow, more); + + g_type_ensure (GTK_SOURCE_TYPE_COMPLETION_CELL); +} + +static void +gtk_source_completion_list_box_row_init (GtkSourceCompletionListBoxRow *self) +{ + gtk_widget_init_template (GTK_WIDGET (self)); +} + +GtkWidget * +_gtk_source_completion_list_box_row_new (void) +{ + return g_object_new (GTK_SOURCE_TYPE_COMPLETION_LIST_BOX_ROW, NULL); +} + +void +_gtk_source_completion_list_box_row_display (GtkSourceCompletionListBoxRow *self, + GtkSourceCompletionContext *context, + GtkSourceCompletionProvider *provider, + GtkSourceCompletionProposal *proposal, + gboolean show_icons, + gboolean has_alternates) +{ + g_return_if_fail (GTK_SOURCE_IS_COMPLETION_LIST_BOX_ROW (self)); + g_return_if_fail (!context || GTK_SOURCE_IS_COMPLETION_CONTEXT (context)); + g_return_if_fail (!provider || GTK_SOURCE_IS_COMPLETION_PROVIDER (provider)); + g_return_if_fail (!proposal || GTK_SOURCE_IS_COMPLETION_PROPOSAL (proposal)); + + if (proposal == NULL) + { + gtk_source_completion_cell_set_widget (self->icon, NULL); + gtk_source_completion_cell_set_widget (self->before, NULL); + gtk_source_completion_cell_set_widget (self->typed_text, NULL); + gtk_source_completion_cell_set_widget (self->after, NULL); + } + else + { + gtk_source_completion_provider_display (provider, context, proposal, self->icon); + gtk_source_completion_provider_display (provider, context, proposal, self->before); + gtk_source_completion_provider_display (provider, context, proposal, self->typed_text); + gtk_source_completion_provider_display (provider, context, proposal, self->after); + } + + gtk_widget_set_visible (GTK_WIDGET (self->icon), show_icons); + gtk_widget_set_visible (GTK_WIDGET (self->more), has_alternates); +} + +void +_gtk_source_completion_list_box_row_attach (GtkSourceCompletionListBoxRow *self, + GtkSizeGroup *before, + GtkSizeGroup *typed_text, + GtkSizeGroup *after) +{ + g_return_if_fail (GTK_SOURCE_IS_COMPLETION_LIST_BOX_ROW (self)); + g_return_if_fail (GTK_IS_SIZE_GROUP (before)); + g_return_if_fail (GTK_IS_SIZE_GROUP (typed_text)); + g_return_if_fail (GTK_IS_SIZE_GROUP (after)); + + gtk_size_group_add_widget (before, GTK_WIDGET (self->before)); + gtk_size_group_add_widget (typed_text, GTK_WIDGET (self->typed_text)); + gtk_size_group_add_widget (after, GTK_WIDGET (self->after)); +} + +static void +get_margin_and_border (GtkWidget *widget, + GtkBorder *margin, + GtkBorder *border) +{ + GtkStyleContext *style_context = gtk_widget_get_style_context (widget); + gtk_style_context_get_margin (style_context, margin); + gtk_style_context_get_border (style_context, border); +} + +gint +_gtk_source_completion_list_box_row_get_x_offset (GtkSourceCompletionListBoxRow *self, + GtkWidget *toplevel) +{ + GtkRequisition min; + GtkRequisition nat; + GtkBorder margin; + GtkBorder border; + double x = 0; + + g_return_val_if_fail (GTK_SOURCE_IS_COMPLETION_LIST_BOX_ROW (self), 0); + g_return_val_if_fail (GTK_IS_WIDGET (toplevel), 0); + + for (GtkWidget *iter = GTK_WIDGET (self->box); + iter != NULL; + iter = gtk_widget_get_parent (iter)) + { + get_margin_and_border (iter, &margin, &border); + x += margin.left + border.left; + + if (iter == toplevel) + { + break; + } + } + + get_margin_and_border (GTK_WIDGET (self->icon), &margin, &border); + gtk_widget_get_preferred_size (GTK_WIDGET (self->icon), &min, &nat); + x += margin.left + border.left + nat.width + margin.right + border.right; + + get_margin_and_border (GTK_WIDGET (self->before), &margin, &border); + gtk_widget_get_preferred_size (GTK_WIDGET (self->before), &min, &nat); + x += margin.left + border.left + nat.width + border.right + margin.right; + + get_margin_and_border (GTK_WIDGET (self->typed_text), &margin, &border); + gtk_widget_get_preferred_size (GTK_WIDGET (self->typed_text), &min, &nat); + x += margin.left + border.left; + + return -x; +} + +void +_gtk_source_completion_list_box_row_set_attrs (GtkSourceCompletionListBoxRow *self, + PangoAttrList *attrs) +{ + g_assert (GTK_SOURCE_IS_COMPLETION_LIST_BOX_ROW (self)); + + _gtk_source_completion_cell_set_attrs (self->icon, attrs); + _gtk_source_completion_cell_set_attrs (self->before, attrs); + _gtk_source_completion_cell_set_attrs (self->typed_text, attrs); + _gtk_source_completion_cell_set_attrs (self->after, attrs); +} diff --git a/gtksourceview/gtksourcecompletionlistboxrow.ui b/gtksourceview/gtksourcecompletionlistboxrow.ui new file mode 100644 index 0000000000000000000000000000000000000000..671fce2fb82ecdf97c6727cc018d162f524694cf --- /dev/null +++ b/gtksourceview/gtksourcecompletionlistboxrow.ui @@ -0,0 +1,65 @@ + + + + diff --git a/gtksourceview/gtksourcecompletionmodel.c b/gtksourceview/gtksourcecompletionmodel.c deleted file mode 100644 index 73facc7789dd789f43f7be09c69ad65348270626..0000000000000000000000000000000000000000 --- a/gtksourceview/gtksourcecompletionmodel.c +++ /dev/null @@ -1,1243 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8; coding: utf-8 -*- * - * - * This file is part of GtkSourceView - * - * Copyright (C) 2009 - Jesse van den Kieboom - * Copyright (C) 2013 - Sébastien Wilmet - * - * GtkSourceView is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * GtkSourceView 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this library; if not, see . - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include "gtksourcecompletionmodel.h" -#include -#include "gtksourcecompletionprovider.h" -#include "gtksourcecompletionproposal.h" - -typedef struct -{ - GtkSourceCompletionModel *model; - GtkSourceCompletionProvider *completion_provider; - - /* List of ProposalInfo. If the header is visible, it is included. */ - GQueue *proposals; - - /* By default, all providers are visible. But with Ctrl+{left, right}, - * the user can switch between providers. In this case, only one - * provider is visible, and the others are hidden. */ - guint visible : 1; -} ProviderInfo; - -typedef struct -{ - /* Node from model->priv->providers */ - GList *provider_node; - - /* For the header, the completion proposal is NULL. */ - GtkSourceCompletionProposal *completion_proposal; - - /* For the "changed" signal emitted by the proposal. - * When the node is freed, the signal is disconnected. */ - gulong changed_id; -} ProposalInfo; - -struct _GtkSourceCompletionModelPrivate -{ - GType column_types[GTK_SOURCE_COMPLETION_MODEL_N_COLUMNS]; - - /* List of ProviderInfo sorted by priority in descending order. */ - GList *providers; - - /* List of GtkSourceCompletionProvider. If NULL, all providers are - * visible. */ - GList *visible_providers; - - guint show_headers : 1; -}; - -static void tree_model_iface_init (gpointer g_iface, gpointer iface_data); - -G_DEFINE_TYPE_WITH_CODE (GtkSourceCompletionModel, - gtk_source_completion_model, - G_TYPE_OBJECT, - G_ADD_PRIVATE (GtkSourceCompletionModel) - G_IMPLEMENT_INTERFACE (GTK_TYPE_TREE_MODEL, - tree_model_iface_init)) - -/* Utility functions */ - -static gboolean -is_header (ProposalInfo *info) -{ - g_assert (info != NULL); - - return info->completion_proposal == NULL; -} - -static gboolean -is_provider_visible (GtkSourceCompletionModel *model, - GtkSourceCompletionProvider *provider) -{ - if (model->priv->visible_providers == NULL) - { - return TRUE; - } - - return g_list_find (model->priv->visible_providers, provider) != NULL; -} - -static gboolean -get_iter_from_index (GtkSourceCompletionModel *model, - GtkTreeIter *iter, - gint idx) -{ - gint provider_index = 0; - GList *l; - ProviderInfo *info; - - if (idx < 0) - { - return FALSE; - } - - /* Find the provider */ - for (l = model->priv->providers; l != NULL; l = l->next) - { - gint new_index; - info = l->data; - - if (!info->visible) - { - continue; - } - - new_index = provider_index + info->proposals->length; - - if (idx < new_index) - { - break; - } - - provider_index = new_index; - } - - if (l == NULL) - { - return FALSE; - } - - /* Find the node inside the provider */ - iter->user_data = g_queue_peek_nth_link (info->proposals, idx - provider_index); - - return iter->user_data != NULL; -} - -static gint -get_provider_start_index (GtkSourceCompletionModel *model, - ProviderInfo *info) -{ - gint start_index = 0; - GList *l; - - g_assert (info != NULL); - - for (l = model->priv->providers; l != NULL; l = l->next) - { - ProviderInfo *cur_info = l->data; - - if (cur_info == info) - { - break; - } - - if (cur_info->visible) - { - start_index += cur_info->proposals->length; - } - } - - /* The provider must be in the list. */ - g_assert (l != NULL); - - return start_index; -} - -static GtkTreePath * -get_proposal_path (GtkSourceCompletionModel *model, - GList *proposal_node) -{ - ProposalInfo *proposal_info; - ProviderInfo *provider_info; - gint idx; - - if (proposal_node == NULL) - { - return NULL; - } - - proposal_info = proposal_node->data; - provider_info = proposal_info->provider_node->data; - - idx = get_provider_start_index (model, provider_info); - idx += g_queue_link_index (provider_info->proposals, proposal_node); - - return gtk_tree_path_new_from_indices (idx, -1); -} - -/* Returns the first visible provider after @provider. It can be @provider - * itself. Returns NULL if not found. */ -static GList * -find_next_visible_provider (GList *provider) -{ - GList *l; - - for (l = provider; l != NULL; l = l->next) - { - ProviderInfo *info = l->data; - - if (info->visible) - { - return l; - } - } - - return NULL; -} - -/* Returns the first visible provider before @provider. It can be @provider - * itself. Returns NULL if not found. */ -static GList * -find_previous_visible_provider (GList *provider) -{ - GList *l; - - for (l = provider; l != NULL; l = l->prev) - { - ProviderInfo *info = l->data; - - if (info->visible) - { - return l; - } - } - - return NULL; -} - -static GList * -get_provider_node (GtkSourceCompletionModel *model, - GtkSourceCompletionProvider *provider) -{ - GList *l; - - for (l = model->priv->providers; l != NULL; l = l->next) - { - ProviderInfo *provider_info = l->data; - - if (provider_info->completion_provider == provider) - { - return l; - } - } - - return NULL; -} - -static gboolean -get_last_iter (GtkSourceCompletionModel *model, - GtkTreeIter *iter) -{ - GList *last_provider; - ProviderInfo *provider_info; - - g_return_val_if_fail (GTK_SOURCE_IS_COMPLETION_MODEL (model), FALSE); - g_return_val_if_fail (iter != NULL, FALSE); - - last_provider = g_list_last (model->priv->providers); - - if (last_provider == NULL) - { - return FALSE; - } - - provider_info = last_provider->data; - - iter->user_data = provider_info->proposals->tail; - g_assert (iter->user_data != NULL); - - if (!provider_info->visible) - { - return gtk_source_completion_model_iter_previous (model, iter); - } - - return TRUE; -} - -static void -proposal_info_free (gpointer data) -{ - ProposalInfo *info = data; - - if (data == NULL) - { - return; - } - - if (info->completion_proposal != NULL) - { - if (info->changed_id != 0) - { - g_signal_handler_disconnect (info->completion_proposal, - info->changed_id); - } - - g_object_unref (info->completion_proposal); - } - - g_slice_free (ProposalInfo, data); -} - -static void -provider_info_free (gpointer data) -{ - ProviderInfo *info = data; - - if (data == NULL) - { - return; - } - - g_object_unref (info->completion_provider); - g_queue_free_full (info->proposals, (GDestroyNotify)proposal_info_free); - g_slice_free (ProviderInfo, data); -} - -static void -add_header (GList *provider_node) -{ - ProviderInfo *provider_info = provider_node->data; - ProposalInfo *header = g_slice_new0 (ProposalInfo); - - header->provider_node = provider_node; - - g_queue_push_head (provider_info->proposals, header); -} - -/* Add the header, and emit the "row-inserted" signal. */ -static void -show_header (GtkSourceCompletionModel *model, - GList *provider_node) -{ - ProviderInfo *provider_info = provider_node->data; - - add_header (provider_node); - - if (provider_info->visible) - { - GtkTreePath *path = get_proposal_path (model, provider_info->proposals->head); - GtkTreeIter iter; - - iter.user_data = provider_info->proposals->head; - gtk_tree_model_row_inserted (GTK_TREE_MODEL (model), path, &iter); - - gtk_tree_path_free (path); - } -} - -/* Remove the header, and emit the "row-deleted" signal. */ -static void -hide_header (GtkSourceCompletionModel *model, - GList *provider_node) -{ - ProviderInfo *provider_info = provider_node->data; - ProposalInfo *proposal_info = g_queue_pop_head (provider_info->proposals); - - g_assert (provider_info->proposals->length > 0); - g_assert (is_header (proposal_info)); - - proposal_info_free (proposal_info); - - if (provider_info->visible) - { - GtkTreePath *path = get_proposal_path (model, provider_info->proposals->head); - gtk_tree_model_row_deleted (GTK_TREE_MODEL (model), path); - gtk_tree_path_free (path); - } -} - -/* Interface implementation */ - -static GtkTreeModelFlags -tree_model_get_flags (GtkTreeModel *tree_model) -{ - g_return_val_if_fail (GTK_SOURCE_IS_COMPLETION_MODEL (tree_model), 0); - - return GTK_TREE_MODEL_LIST_ONLY | GTK_TREE_MODEL_ITERS_PERSIST; -} - -static gint -tree_model_get_n_columns (GtkTreeModel *tree_model) -{ - g_return_val_if_fail (GTK_SOURCE_IS_COMPLETION_MODEL (tree_model), 0); - - return GTK_SOURCE_COMPLETION_MODEL_N_COLUMNS; -} - -static GType -tree_model_get_column_type (GtkTreeModel *tree_model, - gint idx) -{ - g_return_val_if_fail (GTK_SOURCE_IS_COMPLETION_MODEL (tree_model), G_TYPE_INVALID); - g_return_val_if_fail (0 <= idx && idx < GTK_SOURCE_COMPLETION_MODEL_N_COLUMNS, G_TYPE_INVALID); - - return GTK_SOURCE_COMPLETION_MODEL (tree_model)->priv->column_types[idx]; -} - -static gboolean -tree_model_get_iter (GtkTreeModel *tree_model, - GtkTreeIter *iter, - GtkTreePath *path) -{ - GtkSourceCompletionModel *model; - gint *indices; - - g_return_val_if_fail (GTK_SOURCE_IS_COMPLETION_MODEL (tree_model), FALSE); - g_return_val_if_fail (iter != NULL, FALSE); - g_return_val_if_fail (path != NULL, FALSE); - - model = GTK_SOURCE_COMPLETION_MODEL (tree_model); - indices = gtk_tree_path_get_indices (path); - - return get_iter_from_index (model, iter, indices[0]); -} - -static GtkTreePath * -tree_model_get_path (GtkTreeModel *tree_model, - GtkTreeIter *iter) -{ - GtkSourceCompletionModel *model; - - g_return_val_if_fail (GTK_SOURCE_IS_COMPLETION_MODEL (tree_model), NULL); - g_return_val_if_fail (iter != NULL, NULL); - g_return_val_if_fail (iter->user_data != NULL, NULL); - - model = GTK_SOURCE_COMPLETION_MODEL (tree_model); - - return get_proposal_path (model, iter->user_data); -} - -static void -tree_model_get_value (GtkTreeModel *tree_model, - GtkTreeIter *iter, - gint column, - GValue *value) -{ - GList *proposal_node; - ProposalInfo *proposal_info; - ProviderInfo *provider_info; - GtkSourceCompletionProposal *completion_proposal; - GtkSourceCompletionProvider *completion_provider; - - g_return_if_fail (GTK_SOURCE_IS_COMPLETION_MODEL (tree_model)); - g_return_if_fail (iter != NULL); - g_return_if_fail (iter->user_data != NULL); - g_return_if_fail (0 <= column && column < GTK_SOURCE_COMPLETION_MODEL_N_COLUMNS); - - proposal_node = iter->user_data; - proposal_info = proposal_node->data; - provider_info = proposal_info->provider_node->data; - completion_proposal = proposal_info->completion_proposal; - completion_provider = provider_info->completion_provider; - - g_value_init (value, GTK_SOURCE_COMPLETION_MODEL (tree_model)->priv->column_types[column]); - - switch (column) - { - case GTK_SOURCE_COMPLETION_MODEL_COLUMN_PROVIDER: - g_value_set_object (value, completion_provider); - break; - - case GTK_SOURCE_COMPLETION_MODEL_COLUMN_PROPOSAL: - g_value_set_object (value, completion_proposal); - break; - - case GTK_SOURCE_COMPLETION_MODEL_COLUMN_MARKUP: - if (is_header (proposal_info)) - { - gchar *name = gtk_source_completion_provider_get_name (completion_provider); - - if (name != NULL) - { - gchar *escaped = g_markup_escape_text (name, -1); - gchar *markup = g_strdup_printf ("%s", escaped); - g_value_take_string (value, markup); - - g_free (name); - g_free (escaped); - } - else - { - gchar *markup = g_strdup_printf ("%s", _("Provider")); - g_value_take_string (value, markup); - } - } - else - { - gchar *markup = gtk_source_completion_proposal_get_markup (completion_proposal); - - if (markup == NULL) - { - gchar *label = gtk_source_completion_proposal_get_label (completion_proposal); - markup = g_markup_escape_text (label != NULL ? label : "", -1); - g_free (label); - } - - g_value_take_string (value, markup); - } - break; - - case GTK_SOURCE_COMPLETION_MODEL_COLUMN_ICON: - if (is_header (proposal_info)) - { - GdkPixbuf *icon = gtk_source_completion_provider_get_icon (completion_provider); - g_value_set_object (value, (gpointer)icon); - } - else - { - GdkPixbuf *icon = gtk_source_completion_proposal_get_icon (completion_proposal); - g_value_set_object (value, (gpointer)icon); - } - break; - - case GTK_SOURCE_COMPLETION_MODEL_COLUMN_ICON_NAME: - if (is_header (proposal_info)) - { - const gchar *icon_name = gtk_source_completion_provider_get_icon_name (completion_provider); - g_value_set_string (value, (gpointer)icon_name); - } - else - { - const gchar *icon_name = gtk_source_completion_proposal_get_icon_name (completion_proposal); - g_value_set_string (value, (gpointer)icon_name); - } - break; - - case GTK_SOURCE_COMPLETION_MODEL_COLUMN_GICON: - if (is_header (proposal_info)) - { - GIcon *icon = gtk_source_completion_provider_get_gicon (completion_provider); - g_value_set_object (value, (gpointer)icon); - } - else - { - GIcon *icon = gtk_source_completion_proposal_get_gicon (completion_proposal); - g_value_set_object (value, (gpointer)icon); - } - break; - - case GTK_SOURCE_COMPLETION_MODEL_COLUMN_IS_HEADER: - g_value_set_boolean (value, is_header (proposal_info)); - break; - - default: - g_assert_not_reached (); - } -} - -static gboolean -tree_model_iter_next (GtkTreeModel *tree_model, - GtkTreeIter *iter) -{ - ProposalInfo *proposal_info; - GList *proposal_node; - GList *cur_provider; - - g_return_val_if_fail (GTK_SOURCE_IS_COMPLETION_MODEL (tree_model), FALSE); - g_return_val_if_fail (iter != NULL, FALSE); - g_return_val_if_fail (iter->user_data != NULL, FALSE); - - proposal_node = iter->user_data; - proposal_info = proposal_node->data; - - /* Find the right provider, which must be visible */ - - cur_provider = proposal_info->provider_node; - - if (proposal_node->next == NULL) - { - cur_provider = g_list_next (cur_provider); - } - - cur_provider = find_next_visible_provider (cur_provider); - - if (cur_provider == NULL) - { - return FALSE; - } - - /* Find the proposal inside the provider */ - - if (cur_provider == proposal_info->provider_node) - { - iter->user_data = g_list_next (proposal_node); - } - else - { - ProviderInfo *info = cur_provider->data; - iter->user_data = info->proposals->head; - } - - g_assert (iter->user_data != NULL); - - return TRUE; -} - -static gboolean -tree_model_iter_children (GtkTreeModel *tree_model, - GtkTreeIter *iter, - GtkTreeIter *parent) -{ - g_return_val_if_fail (GTK_SOURCE_IS_COMPLETION_MODEL (tree_model), FALSE); - g_return_val_if_fail (iter != NULL, FALSE); - g_return_val_if_fail (parent == NULL || parent->user_data != NULL, FALSE); - - if (parent != NULL) - { - return FALSE; - } - else - { - return get_iter_from_index (GTK_SOURCE_COMPLETION_MODEL (tree_model), iter, 0); - } -} - -static gboolean -tree_model_iter_has_child (GtkTreeModel *tree_model, - GtkTreeIter *iter) -{ - g_return_val_if_fail (GTK_SOURCE_IS_COMPLETION_MODEL (tree_model), FALSE); - g_return_val_if_fail (iter != NULL, FALSE); - g_return_val_if_fail (iter->user_data != NULL, FALSE); - - return FALSE; -} - -static gint -tree_model_iter_n_children (GtkTreeModel *tree_model, - GtkTreeIter *iter) -{ - GtkSourceCompletionModel *model; - GList *l; - gint num_nodes = 0; - - g_return_val_if_fail (GTK_SOURCE_IS_COMPLETION_MODEL (tree_model), 0); - g_return_val_if_fail (iter == NULL || iter->user_data != NULL, 0); - - if (iter != NULL) - { - return 0; - } - - model = GTK_SOURCE_COMPLETION_MODEL (tree_model); - - for (l = model->priv->providers; l != NULL; l = l->next) - { - ProviderInfo *info = l->data; - - if (info->visible) - { - num_nodes += info->proposals->length; - } - } - - return num_nodes; -} - -static gboolean -tree_model_iter_nth_child (GtkTreeModel *tree_model, - GtkTreeIter *iter, - GtkTreeIter *parent, - gint child_num) -{ - g_return_val_if_fail (GTK_SOURCE_IS_COMPLETION_MODEL (tree_model), FALSE); - g_return_val_if_fail (iter != NULL, FALSE); - g_return_val_if_fail (parent == NULL || parent->user_data != NULL, FALSE); - - if (parent != NULL) - { - return FALSE; - } - else - { - return get_iter_from_index (GTK_SOURCE_COMPLETION_MODEL (tree_model), - iter, - child_num); - } -} - -static gboolean -tree_model_iter_parent (GtkTreeModel *tree_model, - GtkTreeIter *iter, - GtkTreeIter *child) -{ - g_return_val_if_fail (GTK_SOURCE_IS_COMPLETION_MODEL (tree_model), FALSE); - g_return_val_if_fail (iter != NULL, FALSE); - g_return_val_if_fail (child != NULL, FALSE); - - iter->user_data = NULL; - return FALSE; -} - -static void -tree_model_iface_init (gpointer g_iface, - gpointer iface_data) -{ - GtkTreeModelIface *iface = g_iface; - - iface->get_flags = tree_model_get_flags; - iface->get_n_columns = tree_model_get_n_columns; - iface->get_column_type = tree_model_get_column_type; - iface->get_iter = tree_model_get_iter; - iface->get_path = tree_model_get_path; - iface->get_value = tree_model_get_value; - iface->iter_next = tree_model_iter_next; - iface->iter_children = tree_model_iter_children; - iface->iter_has_child = tree_model_iter_has_child; - iface->iter_n_children = tree_model_iter_n_children; - iface->iter_nth_child = tree_model_iter_nth_child; - iface->iter_parent = tree_model_iter_parent; -} - -/* Construction and destruction */ - -static void -gtk_source_completion_model_dispose (GObject *object) -{ - GtkSourceCompletionModel *model = GTK_SOURCE_COMPLETION_MODEL (object); - - g_list_free_full (model->priv->providers, (GDestroyNotify)provider_info_free); - model->priv->providers = NULL; - - g_list_free_full (model->priv->visible_providers, g_object_unref); - model->priv->visible_providers = NULL; - - G_OBJECT_CLASS (gtk_source_completion_model_parent_class)->dispose (object); -} - -static void -gtk_source_completion_model_class_init (GtkSourceCompletionModelClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - object_class->dispose = gtk_source_completion_model_dispose; -} - -static void -gtk_source_completion_model_init (GtkSourceCompletionModel *self) -{ - self->priv = gtk_source_completion_model_get_instance_private (self); - - self->priv->column_types[GTK_SOURCE_COMPLETION_MODEL_COLUMN_MARKUP] = G_TYPE_STRING; - self->priv->column_types[GTK_SOURCE_COMPLETION_MODEL_COLUMN_ICON] = GDK_TYPE_PIXBUF; - self->priv->column_types[GTK_SOURCE_COMPLETION_MODEL_COLUMN_ICON_NAME] = G_TYPE_STRING; - self->priv->column_types[GTK_SOURCE_COMPLETION_MODEL_COLUMN_GICON] = G_TYPE_ICON; - self->priv->column_types[GTK_SOURCE_COMPLETION_MODEL_COLUMN_PROPOSAL] = G_TYPE_OBJECT; - self->priv->column_types[GTK_SOURCE_COMPLETION_MODEL_COLUMN_PROVIDER] = G_TYPE_OBJECT; - self->priv->column_types[GTK_SOURCE_COMPLETION_MODEL_COLUMN_IS_HEADER] = G_TYPE_BOOLEAN; - - self->priv->show_headers = 1; - self->priv->providers = NULL; - self->priv->visible_providers = NULL; -} - -/* Population: add proposals */ - -/* Returns the newly-created provider node */ -static GList * -create_provider_info (GtkSourceCompletionModel *model, - GtkSourceCompletionProvider *provider) -{ - ProviderInfo *info; - gint priority; - GList *l; - GList *provider_node; - - /* Create the structure */ - - info = g_slice_new0 (ProviderInfo); - info->model = model; - info->completion_provider = g_object_ref (provider); - info->proposals = g_queue_new (); - info->visible = is_provider_visible (model, provider); - - /* Insert the ProviderInfo in the list */ - - priority = gtk_source_completion_provider_get_priority (provider); - - for (l = model->priv->providers; l != NULL; l = l->next) - { - ProviderInfo *cur_info = l->data; - gint cur_priority = gtk_source_completion_provider_get_priority (cur_info->completion_provider); - - if (cur_priority < priority) - { - break; - } - } - - model->priv->providers = g_list_insert_before (model->priv->providers, l, info); - - provider_node = g_list_find (model->priv->providers, info); - - /* Insert the header if needed */ - - if (model->priv->show_headers) - { - add_header (provider_node); - } - - return provider_node; -} - -static void -on_proposal_changed (GtkSourceCompletionProposal *proposal, - GList *proposal_node) -{ - ProposalInfo *proposal_info = proposal_node->data; - ProviderInfo *provider_info = proposal_info->provider_node->data; - - if (provider_info->visible) - { - GtkTreeIter iter; - GtkTreePath *path; - - iter.user_data = proposal_node; - path = get_proposal_path (provider_info->model, proposal_node); - - gtk_tree_model_row_changed (GTK_TREE_MODEL (provider_info->model), - path, - &iter); - - gtk_tree_path_free (path); - } -} - -static void -add_proposal (GtkSourceCompletionProposal *proposal, - GList *provider_node) -{ - ProviderInfo *provider_info = provider_node->data; - ProposalInfo *proposal_info = g_slice_new0 (ProposalInfo); - - proposal_info->provider_node = provider_node; - proposal_info->completion_proposal = g_object_ref (proposal); - - g_queue_push_tail (provider_info->proposals, proposal_info); - - proposal_info->changed_id = g_signal_connect (proposal, - "changed", - G_CALLBACK (on_proposal_changed), - provider_info->proposals->tail); -} - -void -gtk_source_completion_model_add_proposals (GtkSourceCompletionModel *model, - GtkSourceCompletionProvider *provider, - GList *proposals) -{ - GList *provider_node = NULL; - - g_return_if_fail (GTK_SOURCE_IS_COMPLETION_MODEL (model)); - g_return_if_fail (GTK_SOURCE_IS_COMPLETION_PROVIDER (provider)); - - if (proposals == NULL) - { - return; - } - - provider_node = get_provider_node (model, provider); - - if (provider_node == NULL) - { - provider_node = create_provider_info (model, provider); - } - - g_list_foreach (proposals, (GFunc)add_proposal, provider_node); -} - -/* Other public functions */ - -static gpointer -provider_copy_func (gconstpointer src, - gpointer data) -{ - return g_object_ref ((gpointer) src); -} - -void -gtk_source_completion_model_set_visible_providers (GtkSourceCompletionModel *model, - GList *providers) -{ - GList *l; - - g_return_if_fail (GTK_SOURCE_IS_COMPLETION_MODEL (model)); - - for (l = providers; l != NULL; l = l->next) - { - g_return_if_fail (GTK_SOURCE_IS_COMPLETION_PROVIDER (l->data)); - } - - g_list_free_full (model->priv->visible_providers, g_object_unref); - - model->priv->visible_providers = g_list_copy_deep (providers, - provider_copy_func, - NULL); - - for (l = model->priv->providers; l != NULL; l = l->next) - { - ProviderInfo *provider_info = l->data; - provider_info->visible = is_provider_visible (model, provider_info->completion_provider); - } -} - -GList * -gtk_source_completion_model_get_visible_providers (GtkSourceCompletionModel *model) -{ - g_return_val_if_fail (GTK_SOURCE_IS_COMPLETION_MODEL (model), NULL); - - return model->priv->visible_providers; -} - -/* If @only_visible is %TRUE, only the visible providers are taken into account. */ -gboolean -gtk_source_completion_model_is_empty (GtkSourceCompletionModel *model, - gboolean only_visible) -{ - GList *l; - - g_return_val_if_fail (GTK_SOURCE_IS_COMPLETION_MODEL (model), TRUE); - - for (l = model->priv->providers; l != NULL; l = l->next) - { - ProviderInfo *info = l->data; - - if (only_visible && !info->visible) - { - continue; - } - - /* A provider can not be empty */ - return FALSE; - } - - return TRUE; -} - -void -gtk_source_completion_model_set_show_headers (GtkSourceCompletionModel *model, - gboolean show_headers) -{ - GList *l; - - g_return_if_fail (GTK_SOURCE_IS_COMPLETION_MODEL (model)); - - if (model->priv->show_headers == show_headers) - { - return; - } - - model->priv->show_headers = show_headers; - - for (l = model->priv->providers; l != NULL; l = l->next) - { - if (show_headers) - { - show_header (model, l); - } - else - { - hide_header (model, l); - } - } -} - -gboolean -gtk_source_completion_model_iter_is_header (GtkSourceCompletionModel *model, - GtkTreeIter *iter) -{ - GList *proposal_node; - ProposalInfo *proposal_info; - - g_return_val_if_fail (GTK_SOURCE_IS_COMPLETION_MODEL (model), FALSE); - g_return_val_if_fail (iter != NULL, FALSE); - g_return_val_if_fail (iter->user_data != NULL, FALSE); - - proposal_node = iter->user_data; - proposal_info = proposal_node->data; - - return is_header (proposal_info); -} - -gboolean -gtk_source_completion_model_iter_previous (GtkSourceCompletionModel *model, - GtkTreeIter *iter) -{ - /* This function is the symmetry of tree_model_iter_next(). */ - - ProposalInfo *proposal_info; - GList *proposal_node; - GList *cur_provider; - - g_return_val_if_fail (GTK_SOURCE_IS_COMPLETION_MODEL (model), FALSE); - g_return_val_if_fail (iter != NULL, FALSE); - g_return_val_if_fail (iter->user_data != NULL, FALSE); - - proposal_node = iter->user_data; - proposal_info = proposal_node->data; - - /* Find the right provider, which must be visible */ - - cur_provider = proposal_info->provider_node; - - if (proposal_node->prev == NULL) - { - cur_provider = g_list_previous (cur_provider); - } - - cur_provider = find_previous_visible_provider (cur_provider); - - if (cur_provider == NULL) - { - return FALSE; - } - - /* Find the proposal inside the provider */ - - if (cur_provider == proposal_info->provider_node) - { - iter->user_data = g_list_previous (proposal_node); - } - else - { - ProviderInfo *info = cur_provider->data; - iter->user_data = info->proposals->tail; - } - - g_assert (iter->user_data != NULL); - - return TRUE; -} - -/* Get all the providers (visible and hidden), sorted by priority in descending - * order (the highest priority first). - * Free the return value with g_list_free(). - */ -GList * -gtk_source_completion_model_get_providers (GtkSourceCompletionModel *model) -{ - GList *l; - GList *ret = NULL; - - g_return_val_if_fail (GTK_SOURCE_IS_COMPLETION_MODEL (model), NULL); - - for (l = model->priv->providers; l != NULL; l = l->next) - { - ProviderInfo *info = l->data; - ret = g_list_prepend (ret, info->completion_provider); - } - - return g_list_reverse (ret); -} - -/* Get the first proposal. Headers are skipped. - * Returns TRUE on success. - */ -gboolean -gtk_source_completion_model_first_proposal (GtkSourceCompletionModel *model, - GtkTreeIter *iter) -{ - g_return_val_if_fail (GTK_SOURCE_IS_COMPLETION_MODEL (model), FALSE); - g_return_val_if_fail (iter != NULL, FALSE); - - if (!gtk_tree_model_get_iter_first (GTK_TREE_MODEL (model), iter)) - { - return FALSE; - } - - while (gtk_source_completion_model_iter_is_header (model, iter)) - { - if (!gtk_tree_model_iter_next (GTK_TREE_MODEL (model), iter)) - { - return FALSE; - } - } - - return TRUE; -} - -/* Get the last proposal. Headers are skipped. - * Returns TRUE on success. - */ -gboolean -gtk_source_completion_model_last_proposal (GtkSourceCompletionModel *model, - GtkTreeIter *iter) -{ - g_return_val_if_fail (GTK_SOURCE_IS_COMPLETION_MODEL (model), FALSE); - g_return_val_if_fail (iter != NULL, FALSE); - - if (!get_last_iter (model, iter)) - { - return FALSE; - } - - while (gtk_source_completion_model_iter_is_header (model, iter)) - { - if (!gtk_source_completion_model_iter_previous (model, iter)) - { - return FALSE; - } - } - - return TRUE; -} - -/* Get the next proposal. Headers are skipped. - * Returns TRUE on success. - */ -gboolean -gtk_source_completion_model_next_proposal (GtkSourceCompletionModel *model, - GtkTreeIter *iter) -{ - g_return_val_if_fail (GTK_SOURCE_IS_COMPLETION_MODEL (model), FALSE); - g_return_val_if_fail (iter != NULL && iter->user_data != NULL, FALSE); - - do - { - if (!gtk_tree_model_iter_next (GTK_TREE_MODEL (model), iter)) - { - return FALSE; - } - } while (gtk_source_completion_model_iter_is_header (model, iter)); - - return TRUE; -} - -/* Get the previous proposal. Headers are skipped. - * Returns TRUE on success. - */ -gboolean -gtk_source_completion_model_previous_proposal (GtkSourceCompletionModel *model, - GtkTreeIter *iter) -{ - g_return_val_if_fail (GTK_SOURCE_IS_COMPLETION_MODEL (model), FALSE); - g_return_val_if_fail (iter != NULL && iter->user_data != NULL, FALSE); - - do - { - if (!gtk_source_completion_model_iter_previous (model, iter)) - { - return FALSE; - } - } while (gtk_source_completion_model_iter_is_header (model, iter)); - - return TRUE; -} - -static gboolean -proposal_has_info (GtkSourceCompletionProvider *provider, - GtkSourceCompletionProposal *proposal) -{ - gchar *info; - - if (gtk_source_completion_provider_get_info_widget (provider, proposal) != NULL) - { - return TRUE; - } - - info = gtk_source_completion_proposal_get_info (proposal); - - if (info != NULL) - { - g_free (info); - return TRUE; - } - - return FALSE; -} - -static gboolean -provider_has_info (ProviderInfo *provider_info) -{ - GList *l; - - for (l = provider_info->proposals->head; l != NULL; l = l->next) - { - ProposalInfo *proposal_info = l->data; - - if (proposal_info->completion_proposal == NULL) - { - continue; - } - - if (proposal_has_info (provider_info->completion_provider, - proposal_info->completion_proposal)) - { - return TRUE; - } - } - - return FALSE; -} - -/* Returns whether the model contains one or more proposal with extra - * information. If the function returns %FALSE, the "Details" button is useless. - */ -gboolean -gtk_source_completion_model_has_info (GtkSourceCompletionModel *model) -{ - GList *l; - - for (l = model->priv->providers; l != NULL; l = l->next) - { - ProviderInfo *provider_info = l->data; - - if (provider_has_info (provider_info)) - { - return TRUE; - } - } - - return FALSE; -} - -gboolean -gtk_source_completion_model_iter_equal (GtkSourceCompletionModel *model, - GtkTreeIter *iter1, - GtkTreeIter *iter2) -{ - g_return_val_if_fail (GTK_SOURCE_IS_COMPLETION_MODEL (model), FALSE); - g_return_val_if_fail (iter1 != NULL, FALSE); - g_return_val_if_fail (iter2 != NULL, FALSE); - - return iter1->user_data == iter2->user_data; -} - -GtkSourceCompletionModel* -gtk_source_completion_model_new (void) -{ - return g_object_new (GTK_SOURCE_TYPE_COMPLETION_MODEL, NULL); -} diff --git a/gtksourceview/gtksourcecompletionmodel.h b/gtksourceview/gtksourcecompletionmodel.h deleted file mode 100644 index 85004f00dba5c7e8eacd446cf6d49f4ccefcc936..0000000000000000000000000000000000000000 --- a/gtksourceview/gtksourcecompletionmodel.h +++ /dev/null @@ -1,129 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8; coding: utf-8 -*- - * - * This file is part of GtkSourceView - * - * Copyright (C) 2009 - Jesse van den Kieboom - * - * GtkSourceView is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * GtkSourceView 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this library; if not, see . - */ - -#ifndef GTK_SOURCE_COMPLETION_MODEL_H -#define GTK_SOURCE_COMPLETION_MODEL_H - -#include -#include "gtksourcetypes.h" -#include "gtksourcetypes-private.h" - -G_BEGIN_DECLS - -#define GTK_SOURCE_TYPE_COMPLETION_MODEL (gtk_source_completion_model_get_type ()) -#define GTK_SOURCE_COMPLETION_MODEL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_SOURCE_TYPE_COMPLETION_MODEL, GtkSourceCompletionModel)) -#define GTK_SOURCE_COMPLETION_MODEL_CONST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_SOURCE_TYPE_COMPLETION_MODEL, GtkSourceCompletionModel const)) -#define GTK_SOURCE_COMPLETION_MODEL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_SOURCE_TYPE_COMPLETION_MODEL, GtkSourceCompletionModelClass)) -#define GTK_SOURCE_IS_COMPLETION_MODEL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_SOURCE_TYPE_COMPLETION_MODEL)) -#define GTK_SOURCE_IS_COMPLETION_MODEL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_SOURCE_TYPE_COMPLETION_MODEL)) -#define GTK_SOURCE_COMPLETION_MODEL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_SOURCE_TYPE_COMPLETION_MODEL, GtkSourceCompletionModelClass)) - -typedef struct _GtkSourceCompletionModelClass GtkSourceCompletionModelClass; -typedef struct _GtkSourceCompletionModelPrivate GtkSourceCompletionModelPrivate; - -struct _GtkSourceCompletionModel { - GObject parent; - - GtkSourceCompletionModelPrivate *priv; -}; - -struct _GtkSourceCompletionModelClass { - GObjectClass parent_class; - - void (*providers_changed) (GtkSourceCompletionModel *model); -}; - -enum -{ - GTK_SOURCE_COMPLETION_MODEL_COLUMN_MARKUP, - GTK_SOURCE_COMPLETION_MODEL_COLUMN_ICON, - GTK_SOURCE_COMPLETION_MODEL_COLUMN_ICON_NAME, - GTK_SOURCE_COMPLETION_MODEL_COLUMN_GICON, - GTK_SOURCE_COMPLETION_MODEL_COLUMN_PROPOSAL, - GTK_SOURCE_COMPLETION_MODEL_COLUMN_PROVIDER, - GTK_SOURCE_COMPLETION_MODEL_COLUMN_IS_HEADER, - GTK_SOURCE_COMPLETION_MODEL_N_COLUMNS -}; - -GTK_SOURCE_INTERNAL -GType gtk_source_completion_model_get_type (void) G_GNUC_CONST; - -GTK_SOURCE_INTERNAL -GtkSourceCompletionModel * - gtk_source_completion_model_new (void); - -GTK_SOURCE_INTERNAL -void gtk_source_completion_model_add_proposals (GtkSourceCompletionModel *model, - GtkSourceCompletionProvider *provider, - GList *proposals); - -GTK_SOURCE_INTERNAL -gboolean gtk_source_completion_model_is_empty (GtkSourceCompletionModel *model, - gboolean only_visible); - -GTK_SOURCE_INTERNAL -void gtk_source_completion_model_set_visible_providers (GtkSourceCompletionModel *model, - GList *providers); - -GTK_SOURCE_INTERNAL -GList *gtk_source_completion_model_get_visible_providers (GtkSourceCompletionModel *model); - -GTK_SOURCE_INTERNAL -GList *gtk_source_completion_model_get_providers (GtkSourceCompletionModel *model); - -GTK_SOURCE_INTERNAL -void gtk_source_completion_model_set_show_headers (GtkSourceCompletionModel *model, - gboolean show_headers); - -GTK_SOURCE_INTERNAL -gboolean gtk_source_completion_model_iter_is_header (GtkSourceCompletionModel *model, - GtkTreeIter *iter); - -GTK_SOURCE_INTERNAL -gboolean gtk_source_completion_model_iter_previous (GtkSourceCompletionModel *model, - GtkTreeIter *iter); - -GTK_SOURCE_INTERNAL -gboolean gtk_source_completion_model_first_proposal (GtkSourceCompletionModel *model, - GtkTreeIter *iter); - -GTK_SOURCE_INTERNAL -gboolean gtk_source_completion_model_last_proposal (GtkSourceCompletionModel *model, - GtkTreeIter *iter); - -GTK_SOURCE_INTERNAL -gboolean gtk_source_completion_model_next_proposal (GtkSourceCompletionModel *model, - GtkTreeIter *iter); - -GTK_SOURCE_INTERNAL -gboolean gtk_source_completion_model_previous_proposal (GtkSourceCompletionModel *model, - GtkTreeIter *iter); - -GTK_SOURCE_INTERNAL -gboolean gtk_source_completion_model_has_info (GtkSourceCompletionModel *model); - -GTK_SOURCE_INTERNAL -gboolean gtk_source_completion_model_iter_equal (GtkSourceCompletionModel *model, - GtkTreeIter *iter1, - GtkTreeIter *iter2); - -G_END_DECLS - -#endif /* GTK_SOURCE_COMPLETION_MODEL_H */ diff --git a/gtksourceview/gtksourcecompletionproposal.c b/gtksourceview/gtksourcecompletionproposal.c index 54417c7b02ce34c7994cefbeb02ebda84a272fa6..b66e2f83d74df763d01c41bcc0b772f78a19a50d 100644 --- a/gtksourceview/gtksourcecompletionproposal.c +++ b/gtksourceview/gtksourcecompletionproposal.c @@ -1,9 +1,7 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8; coding: utf-8 -*- */ /* * This file is part of GtkSourceView * - * Copyright (C) 2007 - 2009 Jesús Barbero Rodríguez - * Copyright (C) 2009 - Jesse van den Kieboom + * Copyright 2020 Christian Hergert * * GtkSourceView is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -17,323 +15,19 @@ * * You should have received a copy of the GNU Lesser General Public License * along with this library; if not, see . - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include "gtksourcecompletionproposal.h" - -/** - * SECTION:completionproposal - * @title: GtkSourceCompletionProposal - * @short_description: Completion proposal interface - * - * The proposal interface represents a completion item in the completion window. - * It provides information on how to display the completion item and what action - * should be taken when the completion item is activated. * - * The proposal is displayed in the completion window with a label and - * optionally an icon. - * The label may be specified using plain text or markup by implementing - * the corresponding get function. Only one of those get functions - * should return a value different from %NULL. - * The icon may be specified as a #GdkPixbuf, as an icon name or as a #GIcon by - * implementing the corresponding get function. At most one of those get functions - * should return a value different from %NULL, if they all return %NULL no icon - * will be used. + * SPDX-License-Identifier: LGPL-2.1-or-later */ -enum -{ - CHANGED, - N_SIGNALS -}; - -static guint signals[N_SIGNALS]; - -typedef GtkSourceCompletionProposalIface GtkSourceCompletionProposalInterface; - -G_DEFINE_INTERFACE (GtkSourceCompletionProposal, gtk_source_completion_proposal, G_TYPE_OBJECT) - -static gchar * -gtk_source_completion_proposal_get_label_default (GtkSourceCompletionProposal *proposal) -{ - return NULL; -} - -static gchar * -gtk_source_completion_proposal_get_markup_default (GtkSourceCompletionProposal *proposal) -{ - return NULL; -} - -static gchar * -gtk_source_completion_proposal_get_text_default (GtkSourceCompletionProposal *proposal) -{ - return NULL; -} - -static GdkPixbuf * -gtk_source_completion_proposal_get_icon_default (GtkSourceCompletionProposal *proposal) -{ - return NULL; -} -static const gchar * -gtk_source_completion_proposal_get_icon_name_default (GtkSourceCompletionProposal *proposal) -{ - return NULL; -} -static GIcon * -gtk_source_completion_proposal_get_gicon_default (GtkSourceCompletionProposal *proposal) -{ - return NULL; -} +#include "config.h" -static gchar * -gtk_source_completion_proposal_get_info_default (GtkSourceCompletionProposal *proposal) -{ - return NULL; -} - -static guint -gtk_source_completion_proposal_hash_default (GtkSourceCompletionProposal *proposal) -{ - return g_direct_hash (proposal); -} +#include "gtksourcecompletionproposal.h" -static gboolean -gtk_source_completion_proposal_equal_default (GtkSourceCompletionProposal *proposal, - GtkSourceCompletionProposal *other) -{ - return g_direct_equal (proposal, other); -} +G_DEFINE_INTERFACE (GtkSourceCompletionProposal, gtk_source_completion_proposal, G_TYPE_OBJECT) static void -gtk_source_completion_proposal_default_init (GtkSourceCompletionProposalIface *iface) -{ - static gboolean initialized = FALSE; - - iface->get_label = gtk_source_completion_proposal_get_label_default; - iface->get_markup = gtk_source_completion_proposal_get_markup_default; - iface->get_text = gtk_source_completion_proposal_get_text_default; - iface->get_icon = gtk_source_completion_proposal_get_icon_default; - iface->get_icon_name = gtk_source_completion_proposal_get_icon_name_default; - iface->get_gicon = gtk_source_completion_proposal_get_gicon_default; - iface->get_info = gtk_source_completion_proposal_get_info_default; - iface->hash = gtk_source_completion_proposal_hash_default; - iface->equal = gtk_source_completion_proposal_equal_default; - - if (!initialized) - { - /** - * GtkSourceCompletionProposal::changed: - * @proposal: The #GtkSourceCompletionProposal - * - * Emitted when the proposal has changed. The completion popup - * will react to this by updating the shown information. - * - */ - signals[CHANGED] = - g_signal_new ("changed", - G_TYPE_FROM_INTERFACE (iface), - G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, - G_STRUCT_OFFSET (GtkSourceCompletionProposalIface, changed), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - g_signal_set_va_marshaller (signals[CHANGED], - G_TYPE_FROM_INTERFACE (iface), - g_cclosure_marshal_VOID__VOIDv); - - initialized = TRUE; - } -} - -/** - * gtk_source_completion_proposal_get_label: - * @proposal: a #GtkSourceCompletionProposal. - * - * Gets the label of @proposal. The label is shown in the list of proposals as - * plain text. If you need any markup (such as bold or italic text), you have - * to implement gtk_source_completion_proposal_get_markup(). The returned string - * must be freed with g_free(). - * - * Returns: a new string containing the label of @proposal. - */ -gchar * -gtk_source_completion_proposal_get_label (GtkSourceCompletionProposal *proposal) -{ - g_return_val_if_fail (GTK_SOURCE_IS_COMPLETION_PROPOSAL (proposal), NULL); - - return GTK_SOURCE_COMPLETION_PROPOSAL_GET_INTERFACE (proposal)->get_label (proposal); -} - -/** - * gtk_source_completion_proposal_get_markup: - * @proposal: a #GtkSourceCompletionProposal. - * - * Gets the label of @proposal with markup. The label is shown in the list of - * proposals and may contain markup. This will be used instead of - * gtk_source_completion_proposal_get_label() if implemented. The returned string - * must be freed with g_free(). - * - * Returns: a new string containing the label of @proposal with markup. - */ -gchar * -gtk_source_completion_proposal_get_markup (GtkSourceCompletionProposal *proposal) -{ - g_return_val_if_fail (GTK_SOURCE_IS_COMPLETION_PROPOSAL (proposal), NULL); - - return GTK_SOURCE_COMPLETION_PROPOSAL_GET_INTERFACE (proposal)->get_markup (proposal); -} - -/** - * gtk_source_completion_proposal_get_text: - * @proposal: a #GtkSourceCompletionProposal. - * - * Gets the text of @proposal. The text that is inserted into - * the text buffer when the proposal is activated by the default activation. - * You are free to implement a custom activation handler in the provider and - * not implement this function. For more information, see - * gtk_source_completion_provider_activate_proposal(). The returned string must - * be freed with g_free(). - * - * Returns: a new string containing the text of @proposal. - */ -gchar * -gtk_source_completion_proposal_get_text (GtkSourceCompletionProposal *proposal) -{ - g_return_val_if_fail (GTK_SOURCE_IS_COMPLETION_PROPOSAL (proposal), NULL); - - return GTK_SOURCE_COMPLETION_PROPOSAL_GET_INTERFACE (proposal)->get_text (proposal); -} - -/** - * gtk_source_completion_proposal_get_icon: - * @proposal: a #GtkSourceCompletionProposal. - * - * Gets the #GdkPixbuf for the icon of @proposal. - * - * Returns: (nullable) (transfer none): A #GdkPixbuf with the icon of @proposal. - */ -GdkPixbuf * -gtk_source_completion_proposal_get_icon (GtkSourceCompletionProposal *proposal) -{ - g_return_val_if_fail (GTK_SOURCE_IS_COMPLETION_PROPOSAL (proposal), NULL); - - return GTK_SOURCE_COMPLETION_PROPOSAL_GET_INTERFACE (proposal)->get_icon (proposal); -} - -/** - * gtk_source_completion_proposal_get_icon_name: - * @proposal: a #GtkSourceCompletionProposal. - * - * Gets the icon name of @proposal. - * - * Returns: (nullable) (transfer none): The icon name of @proposal. - * - * Since: 3.18 - */ -const gchar * -gtk_source_completion_proposal_get_icon_name (GtkSourceCompletionProposal *proposal) -{ - g_return_val_if_fail (GTK_SOURCE_IS_COMPLETION_PROPOSAL (proposal), NULL); - - return GTK_SOURCE_COMPLETION_PROPOSAL_GET_INTERFACE (proposal)->get_icon_name (proposal); -} - -/** - * gtk_source_completion_proposal_get_gicon: - * @proposal: a #GtkSourceCompletionProposal. - * - * Gets the #GIcon for the icon of @proposal. - * - * Returns: (nullable) (transfer none): A #GIcon with the icon of @proposal. - * - * Since: 3.18 - */ -GIcon * -gtk_source_completion_proposal_get_gicon (GtkSourceCompletionProposal *proposal) -{ - g_return_val_if_fail (GTK_SOURCE_IS_COMPLETION_PROPOSAL (proposal), NULL); - - return GTK_SOURCE_COMPLETION_PROPOSAL_GET_INTERFACE (proposal)->get_gicon (proposal); -} - -/** - * gtk_source_completion_proposal_get_info: - * @proposal: a #GtkSourceCompletionProposal. - * - * Gets extra information associated to the proposal. This information will be - * used to present the user with extra, detailed information about the - * selected proposal. The returned string must be freed with g_free(). - * - * Returns: (nullable) (transfer full): a newly-allocated string containing - * extra information of @proposal or %NULL if no extra information is associated - * to @proposal. - */ -gchar * -gtk_source_completion_proposal_get_info (GtkSourceCompletionProposal *proposal) -{ - g_return_val_if_fail (GTK_SOURCE_IS_COMPLETION_PROPOSAL (proposal), NULL); - - return GTK_SOURCE_COMPLETION_PROPOSAL_GET_INTERFACE (proposal)->get_info (proposal); -} - -/** - * gtk_source_completion_proposal_hash: - * @proposal: a #GtkSourceCompletionProposal. - * - * Get the hash value of @proposal. This is used to (together with - * gtk_source_completion_proposal_equal()) to match proposals in the completion - * model. By default, it uses a direct hash (g_direct_hash()). - * - * Returns: The hash value of @proposal. - */ -guint -gtk_source_completion_proposal_hash (GtkSourceCompletionProposal *proposal) -{ - g_return_val_if_fail (GTK_SOURCE_IS_COMPLETION_PROPOSAL (proposal), 0); - - return GTK_SOURCE_COMPLETION_PROPOSAL_GET_INTERFACE (proposal)->hash (proposal); -} - -/** - * gtk_source_completion_proposal_equal: - * @proposal: a #GtkSourceCompletionProposal. - * @other: a #GtkSourceCompletionProposal. - * - * Get whether two proposal objects are the same. This is used to (together - * with gtk_source_completion_proposal_hash()) to match proposals in the - * completion model. By default, it uses direct equality (g_direct_equal()). - * - * Returns: %TRUE if @proposal and @object are the same proposal - */ -gboolean -gtk_source_completion_proposal_equal (GtkSourceCompletionProposal *proposal, - GtkSourceCompletionProposal *other) -{ - g_return_val_if_fail (GTK_SOURCE_IS_COMPLETION_PROPOSAL (proposal), FALSE); - g_return_val_if_fail (GTK_SOURCE_IS_COMPLETION_PROPOSAL (other), FALSE); - - return GTK_SOURCE_COMPLETION_PROPOSAL_GET_INTERFACE (proposal)->equal (proposal, other); -} - -/** - * gtk_source_completion_proposal_changed: - * @proposal: a #GtkSourceCompletionProposal. - * - * Emits the "changed" signal on @proposal. This should be called by - * implementations whenever the name, icon or info of the proposal has - * changed. - */ -void -gtk_source_completion_proposal_changed (GtkSourceCompletionProposal *proposal) +gtk_source_completion_proposal_default_init (GtkSourceCompletionProposalInterface *iface) { - g_return_if_fail (GTK_SOURCE_IS_COMPLETION_PROPOSAL (proposal)); - g_signal_emit (proposal, signals[CHANGED], 0); } diff --git a/gtksourceview/gtksourcecompletionproposal.h b/gtksourceview/gtksourcecompletionproposal.h index 82858798d9480724f692557459ac0b88fcd7fa34..723f80120eb80cff0858ba9facd5a908051faf98 100644 --- a/gtksourceview/gtksourcecompletionproposal.h +++ b/gtksourceview/gtksourcecompletionproposal.h @@ -1,9 +1,7 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8; coding: utf-8 -*- - * +/* * This file is part of GtkSourceView * - * Copyright (C) 2007 - 2009 Jesús Barbero Rodríguez - * Copyright (C) 2009 - Jesse van den Kieboom + * Copyright 2020 Christian Hergert * * GtkSourceView is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -17,110 +15,26 @@ * * You should have received a copy of the GNU Lesser General Public License * along with this library; if not, see . + * + * SPDX-License-Identifier: LGPL-2.1-or-later */ -#ifndef GTK_SOURCE_COMPLETION_PROPOSAL_H -#define GTK_SOURCE_COMPLETION_PROPOSAL_H - -#if !defined (GTK_SOURCE_H_INSIDE) && !defined (GTK_SOURCE_COMPILATION) -#error "Only can be included directly." -#endif +#pragma once #include -#include -#include + +#include "gtksourcetypes.h" G_BEGIN_DECLS -#define GTK_SOURCE_TYPE_COMPLETION_PROPOSAL (gtk_source_completion_proposal_get_type ()) -#define GTK_SOURCE_COMPLETION_PROPOSAL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_SOURCE_TYPE_COMPLETION_PROPOSAL, GtkSourceCompletionProposal)) -#define GTK_SOURCE_IS_COMPLETION_PROPOSAL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_SOURCE_TYPE_COMPLETION_PROPOSAL)) -#define GTK_SOURCE_COMPLETION_PROPOSAL_GET_INTERFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), GTK_SOURCE_TYPE_COMPLETION_PROPOSAL, GtkSourceCompletionProposalIface)) +#define GTK_SOURCE_TYPE_COMPLETION_PROPOSAL (gtk_source_completion_proposal_get_type()) -typedef struct _GtkSourceCompletionProposalIface GtkSourceCompletionProposalIface; +GTK_SOURCE_AVAILABLE_IN_5_0 +G_DECLARE_INTERFACE (GtkSourceCompletionProposal, gtk_source_completion_proposal, GTK_SOURCE, COMPLETION_PROPOSAL, GObject) -/** - * GtkSourceCompletionProposalIface: - * @parent: The parent interface. - * @get_label: The virtual function pointer for gtk_source_completion_proposal_get_label(). - * By default, %NULL is returned. - * @get_markup: The virtual function pointer for gtk_source_completion_proposal_get_markup(). - * By default, %NULL is returned. - * @get_text: The virtual function pointer for gtk_source_completion_proposal_get_text(). - * By default, %NULL is returned. - * @get_icon: The virtual function pointer for gtk_source_completion_proposal_get_icon(). - * By default, %NULL is returned. - * @get_icon_name: The virtual function pointer for gtk_source_completion_proposal_get_icon_name(). - * By default, %NULL is returned. - * @get_gicon: The virtual function pointer for gtk_source_completion_proposal_get_gicon(). - * By default, %NULL is returned. - * @get_info: The virtual function pointer for gtk_source_completion_proposal_get_info(). - * By default, %NULL is returned. - * @hash: The virtual function pointer for gtk_source_completion_proposal_hash(). - * By default, it uses a direct hash (g_direct_hash()). - * @equal: The virtual function pointer for gtk_source_completion_proposal_equal(). - * By default, it uses direct equality (g_direct_equal()). - * @changed: The function pointer for the #GtkSourceCompletionProposal::changed signal. - * - * The virtual function table for #GtkSourceCompletionProposal. - */ -struct _GtkSourceCompletionProposalIface +struct _GtkSourceCompletionProposalInterface { - GTypeInterface parent; - - /* Interface functions */ - gchar *(*get_label) (GtkSourceCompletionProposal *proposal); - gchar *(*get_markup) (GtkSourceCompletionProposal *proposal); - gchar *(*get_text) (GtkSourceCompletionProposal *proposal); - - GdkPixbuf *(*get_icon) (GtkSourceCompletionProposal *proposal); - const gchar *(*get_icon_name) (GtkSourceCompletionProposal *proposal); - GIcon *(*get_gicon) (GtkSourceCompletionProposal *proposal); - - gchar *(*get_info) (GtkSourceCompletionProposal *proposal); - - guint (*hash) (GtkSourceCompletionProposal *proposal); - gboolean (*equal) (GtkSourceCompletionProposal *proposal, - GtkSourceCompletionProposal *other); - - /* Signals */ - void (*changed) (GtkSourceCompletionProposal *proposal); + GTypeInterface parent_iface; }; -GTK_SOURCE_AVAILABLE_IN_ALL -GType gtk_source_completion_proposal_get_type (void) G_GNUC_CONST; - -GTK_SOURCE_AVAILABLE_IN_ALL -gchar *gtk_source_completion_proposal_get_label (GtkSourceCompletionProposal *proposal); - -GTK_SOURCE_AVAILABLE_IN_ALL -gchar *gtk_source_completion_proposal_get_markup (GtkSourceCompletionProposal *proposal); - -GTK_SOURCE_AVAILABLE_IN_ALL -gchar *gtk_source_completion_proposal_get_text (GtkSourceCompletionProposal *proposal); - -GTK_SOURCE_AVAILABLE_IN_ALL -GdkPixbuf *gtk_source_completion_proposal_get_icon (GtkSourceCompletionProposal *proposal); - -GTK_SOURCE_AVAILABLE_IN_3_18 -const gchar *gtk_source_completion_proposal_get_icon_name (GtkSourceCompletionProposal *proposal); - -GTK_SOURCE_AVAILABLE_IN_3_18 -GIcon *gtk_source_completion_proposal_get_gicon (GtkSourceCompletionProposal *proposal); - -GTK_SOURCE_AVAILABLE_IN_ALL -gchar *gtk_source_completion_proposal_get_info (GtkSourceCompletionProposal *proposal); - -GTK_SOURCE_AVAILABLE_IN_ALL -void gtk_source_completion_proposal_changed (GtkSourceCompletionProposal *proposal); - -GTK_SOURCE_AVAILABLE_IN_ALL -guint gtk_source_completion_proposal_hash (GtkSourceCompletionProposal *proposal); - -GTK_SOURCE_AVAILABLE_IN_ALL -gboolean gtk_source_completion_proposal_equal (GtkSourceCompletionProposal *proposal, - GtkSourceCompletionProposal *other); - G_END_DECLS - -#endif /* GTK_SOURCE_COMPLETION_PROPOSAL_H */ diff --git a/gtksourceview/gtksourcecompletionprovider.c b/gtksourceview/gtksourcecompletionprovider.c index 4dfcdba5f6652ace376d564e551c41926e03141b..35a5cd6e361621b8fb577c0d50fd4c3edafd43ca 100644 --- a/gtksourceview/gtksourcecompletionprovider.c +++ b/gtksourceview/gtksourcecompletionprovider.c @@ -1,9 +1,7 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8; coding: utf-8 -*- */ /* * This file is part of GtkSourceView * - * Copyright (C) 2007 - 2009 Jesús Barbero Rodríguez - * Copyright (C) 2009 - Jesse van den Kieboom + * Copyright 2020 Christian Hergert * * GtkSourceView is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -17,441 +15,262 @@ * * You should have received a copy of the GNU Lesser General Public License * along with this library; if not, see . - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include "gtksourcecompletionprovider.h" -#include "gtksourcecompletionproposal.h" -#include "gtksourcecompletioninfo.h" - -/** - * SECTION:completionprovider - * @title: GtkSourceCompletionProvider - * @short_description: Completion provider interface - * - * You must implement this interface to provide proposals to #GtkSourceCompletion * - * The provider may be displayed in the completion window as a header row, showing - * its name and optionally an icon. - * The icon may be specified as a #GdkPixbuf, as an icon name or as a #GIcon by - * implementing the corresponding get function. At most one of those get functions - * should return a value different from %NULL, if they all return %NULL no icon - * will be used. + * SPDX-License-Identifier: LGPL-2.1-or-later */ -typedef GtkSourceCompletionProviderIface GtkSourceCompletionProviderInterface; -G_DEFINE_INTERFACE(GtkSourceCompletionProvider, gtk_source_completion_provider, G_TYPE_OBJECT) -/* Default implementations */ -static gchar * -gtk_source_completion_provider_get_name_default (GtkSourceCompletionProvider *provider) -{ - g_return_val_if_reached (NULL); -} - -static GdkPixbuf * -gtk_source_completion_provider_get_icon_default (GtkSourceCompletionProvider *provider) -{ - return NULL; -} +#include "config.h" -static const gchar * -gtk_source_completion_provider_get_icon_name_default (GtkSourceCompletionProvider *provider) -{ - return NULL; -} +#include "gtksourcecompletioncontext.h" +#include "gtksourcecompletioncell.h" +#include "gtksourcecompletionproposal.h" +#include "gtksourcecompletionprovider.h" -static GIcon * -gtk_source_completion_provider_get_gicon_default (GtkSourceCompletionProvider *provider) -{ - return NULL; -} +G_DEFINE_INTERFACE (GtkSourceCompletionProvider, gtk_source_completion_provider, G_TYPE_OBJECT) static void -gtk_source_completion_provider_populate_default (GtkSourceCompletionProvider *provider, - GtkSourceCompletionContext *context) -{ - gtk_source_completion_context_add_proposals (context, provider, NULL, TRUE); -} - -static GtkSourceCompletionActivation -gtk_source_completion_provider_get_activation_default (GtkSourceCompletionProvider *provider) +fallback_populate_async (GtkSourceCompletionProvider *provider, + GtkSourceCompletionContext *context, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) { - return GTK_SOURCE_COMPLETION_ACTIVATION_INTERACTIVE | - GTK_SOURCE_COMPLETION_ACTIVATION_USER_REQUESTED; + GListModel *ret; + GError *error = NULL; + GTask *task; + + task = g_task_new (provider, cancellable, callback, user_data); + g_task_set_source_tag (task, fallback_populate_async); + + ret = GTK_SOURCE_COMPLETION_PROVIDER_GET_IFACE (provider)->populate (provider, context, &error); + + if (ret == NULL) + { + if (error != NULL) + { + g_task_return_error (task, g_steal_pointer (&error)); + } + else + { + g_task_return_new_error (task, + G_IO_ERROR, + G_IO_ERROR_NOT_SUPPORTED, + "No results"); + } + } + else + { + g_task_return_pointer (task, g_steal_pointer (&ret), g_object_unref); + } + + g_clear_object (&task); } -static gboolean -gtk_source_completion_provider_match_default (GtkSourceCompletionProvider *provider, - GtkSourceCompletionContext *context) +static GListModel * +fallback_populate_finish (GtkSourceCompletionProvider *provider, + GAsyncResult *result, + GError **error) { - return TRUE; + return g_task_propagate_pointer (G_TASK (result), error); } -static GtkWidget * -gtk_source_completion_provider_get_info_widget_default (GtkSourceCompletionProvider *provider, - GtkSourceCompletionProposal *proposal) +static GListModel * +fallback_populate (GtkSourceCompletionProvider *provider, + GtkSourceCompletionContext *context, + GError **error) { + g_set_error (error, + G_IO_ERROR, + G_IO_ERROR_NOT_SUPPORTED, + "Not supported"); return NULL; } static void -gtk_source_completion_provider_update_info_default (GtkSourceCompletionProvider *provider, - GtkSourceCompletionProposal *proposal, - GtkSourceCompletionInfo *info) +fallback_refilter (GtkSourceCompletionProvider *provider, + GtkSourceCompletionContext *context, + GListModel *model) { } -static gboolean -gtk_source_completion_provider_get_start_iter_default (GtkSourceCompletionProvider *provider, - GtkSourceCompletionContext *context, - GtkSourceCompletionProposal *proposal, - GtkTextIter *iter) +static void +fallback_activate (GtkSourceCompletionProvider *provider, + GtkSourceCompletionContext *context, + GtkSourceCompletionProposal *proposal) { - return FALSE; } -static gboolean -gtk_source_completion_provider_activate_proposal_default (GtkSourceCompletionProvider *provider, - GtkSourceCompletionProposal *proposal, - GtkTextIter *iter) +static void +gtk_source_completion_provider_default_init (GtkSourceCompletionProviderInterface *iface) { - return FALSE; + iface->populate_async = fallback_populate_async; + iface->populate_finish = fallback_populate_finish; + iface->populate = fallback_populate; + iface->refilter = fallback_refilter; + iface->activate = fallback_activate; } -static gint -gtk_source_completion_provider_get_interactive_delay_default (GtkSourceCompletionProvider *provider) +char * +gtk_source_completion_provider_get_title (GtkSourceCompletionProvider *self) { - /* -1 means the default value in the completion object */ - return -1; -} + g_return_val_if_fail (GTK_SOURCE_IS_COMPLETION_PROVIDER (self), NULL); -static gint -gtk_source_completion_provider_get_priority_default (GtkSourceCompletionProvider *provider) -{ - return 0; + if (GTK_SOURCE_COMPLETION_PROVIDER_GET_IFACE (self)->get_title) + return GTK_SOURCE_COMPLETION_PROVIDER_GET_IFACE (self)->get_title (self); + + return NULL; } -static void -gtk_source_completion_provider_default_init (GtkSourceCompletionProviderIface *iface) +int +gtk_source_completion_provider_get_priority (GtkSourceCompletionProvider *self, + GtkSourceCompletionContext *context) { - iface->get_name = gtk_source_completion_provider_get_name_default; - - iface->get_icon = gtk_source_completion_provider_get_icon_default; - iface->get_icon_name = gtk_source_completion_provider_get_icon_name_default; - iface->get_gicon = gtk_source_completion_provider_get_gicon_default; + g_return_val_if_fail (GTK_SOURCE_IS_COMPLETION_PROVIDER (self), 0); + g_return_val_if_fail (GTK_SOURCE_IS_COMPLETION_CONTEXT (context), 0); - iface->populate = gtk_source_completion_provider_populate_default; + if (GTK_SOURCE_COMPLETION_PROVIDER_GET_IFACE (self)->get_priority) + return GTK_SOURCE_COMPLETION_PROVIDER_GET_IFACE (self)->get_priority (self, context); - iface->match = gtk_source_completion_provider_match_default; - iface->get_activation = gtk_source_completion_provider_get_activation_default; - - iface->get_info_widget = gtk_source_completion_provider_get_info_widget_default; - iface->update_info = gtk_source_completion_provider_update_info_default; - - iface->get_start_iter = gtk_source_completion_provider_get_start_iter_default; - iface->activate_proposal = gtk_source_completion_provider_activate_proposal_default; - - iface->get_interactive_delay = gtk_source_completion_provider_get_interactive_delay_default; - iface->get_priority = gtk_source_completion_provider_get_priority_default; + return 0; } -/** - * gtk_source_completion_provider_get_name: - * @provider: a #GtkSourceCompletionProvider. - * - * Get the name of the provider. This should be a translatable name for - * display to the user. For example: _("Document word completion provider"). The - * returned string must be freed with g_free(). - * - * Returns: a new string containing the name of the provider. - */ -gchar * -gtk_source_completion_provider_get_name (GtkSourceCompletionProvider *provider) +gboolean +gtk_source_completion_provider_is_trigger (GtkSourceCompletionProvider *self, + const GtkTextIter *iter, + gunichar ch) { - g_return_val_if_fail (GTK_SOURCE_IS_COMPLETION_PROVIDER (provider), NULL); + g_return_val_if_fail (GTK_SOURCE_IS_COMPLETION_PROVIDER (self), FALSE); + g_return_val_if_fail (iter != NULL, FALSE); - return GTK_SOURCE_COMPLETION_PROVIDER_GET_INTERFACE (provider)->get_name (provider); -} + if (GTK_SOURCE_COMPLETION_PROVIDER_GET_IFACE (self)->is_trigger) + return GTK_SOURCE_COMPLETION_PROVIDER_GET_IFACE (self)->is_trigger (self, iter, ch); -/** - * gtk_source_completion_provider_get_icon: - * @provider: The #GtkSourceCompletionProvider - * - * Get the #GdkPixbuf for the icon of the @provider. - * - * Returns: (nullable) (transfer none): The icon to be used for the provider, - * or %NULL if the provider does not have a special icon. - */ -GdkPixbuf * -gtk_source_completion_provider_get_icon (GtkSourceCompletionProvider *provider) -{ - g_return_val_if_fail (GTK_SOURCE_IS_COMPLETION_PROVIDER (provider), NULL); - - return GTK_SOURCE_COMPLETION_PROVIDER_GET_INTERFACE (provider)->get_icon (provider); + return FALSE; } -/** - * gtk_source_completion_provider_get_icon_name: - * @provider: The #GtkSourceCompletionProvider - * - * Gets the icon name of @provider. - * - * Returns: (nullable) (transfer none): The icon name to be used for the provider, - * or %NULL if the provider does not have a special icon. - * - * Since: 3.18 - */ -const gchar * -gtk_source_completion_provider_get_icon_name (GtkSourceCompletionProvider *provider) +gboolean +gtk_source_completion_provider_key_activates (GtkSourceCompletionProvider *self, + GtkSourceCompletionContext *context, + GtkSourceCompletionProposal *proposal, + guint keyval, + GdkModifierType state) { - g_return_val_if_fail (GTK_SOURCE_IS_COMPLETION_PROVIDER (provider), NULL); - - return GTK_SOURCE_COMPLETION_PROVIDER_GET_INTERFACE (provider)->get_icon_name (provider); -} + g_return_val_if_fail (GTK_SOURCE_IS_COMPLETION_PROVIDER (self), FALSE); + g_return_val_if_fail (GTK_SOURCE_IS_COMPLETION_CONTEXT (context), FALSE); + g_return_val_if_fail (GTK_SOURCE_IS_COMPLETION_PROPOSAL (proposal), FALSE); -/** - * gtk_source_completion_provider_get_gicon: - * @provider: The #GtkSourceCompletionProvider - * - * Gets the #GIcon for the icon of @provider. - * - * Returns: (nullable) (transfer none): The icon to be used for the provider, - * or %NULL if the provider does not have a special icon. - * - * Since: 3.18 - */ -GIcon * -gtk_source_completion_provider_get_gicon (GtkSourceCompletionProvider *provider) -{ - g_return_val_if_fail (GTK_SOURCE_IS_COMPLETION_PROVIDER (provider), NULL); + if (GTK_SOURCE_COMPLETION_PROVIDER_GET_IFACE (self)->key_activates) + return GTK_SOURCE_COMPLETION_PROVIDER_GET_IFACE (self)->key_activates (self, context, proposal, keyval, state); - return GTK_SOURCE_COMPLETION_PROVIDER_GET_INTERFACE (provider)->get_gicon (provider); + return FALSE; } -/** - * gtk_source_completion_provider_populate: - * @provider: a #GtkSourceCompletionProvider. - * @context: a #GtkSourceCompletionContext. - * - * Populate @context with proposals from @provider added with the - * gtk_source_completion_context_add_proposals() function. - */ void -gtk_source_completion_provider_populate (GtkSourceCompletionProvider *provider, - GtkSourceCompletionContext *context) +gtk_source_completion_provider_populate_async (GtkSourceCompletionProvider *self, + GtkSourceCompletionContext *context, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) { - g_return_if_fail (GTK_SOURCE_IS_COMPLETION_PROVIDER (provider)); + g_return_if_fail (GTK_SOURCE_IS_COMPLETION_PROVIDER (self)); + g_return_if_fail (GTK_SOURCE_IS_COMPLETION_CONTEXT (context)); + g_return_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable)); - GTK_SOURCE_COMPLETION_PROVIDER_GET_INTERFACE (provider)->populate (provider, context); + GTK_SOURCE_COMPLETION_PROVIDER_GET_IFACE (self)->populate_async (self, context, cancellable, callback, user_data); } /** - * gtk_source_completion_provider_get_activation: - * @provider: a #GtkSourceCompletionProvider. + * gtk_source_completion_provider_populate_finish: + * @self: a #GtkSourceCompletionProvider + * @result: a #GAsyncResult provided to callback + * @error: a location for a #GError, or %NULL * - * Get with what kind of activation the provider should be activated. - * - * Returns: a combination of #GtkSourceCompletionActivation. - **/ -GtkSourceCompletionActivation -gtk_source_completion_provider_get_activation (GtkSourceCompletionProvider *provider) -{ - g_return_val_if_fail (GTK_SOURCE_IS_COMPLETION_PROVIDER (provider), GTK_SOURCE_COMPLETION_ACTIVATION_NONE); - - return GTK_SOURCE_COMPLETION_PROVIDER_GET_INTERFACE (provider)->get_activation (provider); -} - -/** - * gtk_source_completion_provider_match: - * @provider: a #GtkSourceCompletionProvider. - * @context: a #GtkSourceCompletionContext. + * Completes an asynchronous operation to populate a completion provider. * - * Get whether the provider match the context of completion detailed in - * @context. + * Returns: (transfer full): a #GListModel of #GtkSourceCompletionProposal * - * Returns: %TRUE if @provider matches the completion context, %FALSE otherwise. + * Since: 5.0 */ -gboolean -gtk_source_completion_provider_match (GtkSourceCompletionProvider *provider, - GtkSourceCompletionContext *context) +GListModel * +gtk_source_completion_provider_populate_finish (GtkSourceCompletionProvider *self, + GAsyncResult *result, + GError **error) { - g_return_val_if_fail (GTK_SOURCE_IS_COMPLETION_PROVIDER (provider), TRUE); + g_return_val_if_fail (GTK_SOURCE_IS_COMPLETION_PROVIDER (self), NULL); - return GTK_SOURCE_COMPLETION_PROVIDER_GET_INTERFACE (provider)->match (provider, - context); + return GTK_SOURCE_COMPLETION_PROVIDER_GET_IFACE (self)->populate_finish (self, result, error); } -/** - * gtk_source_completion_provider_get_info_widget: - * @provider: a #GtkSourceCompletionProvider. - * @proposal: a currently selected #GtkSourceCompletionProposal. - * - * Get a customized info widget to show extra information of a proposal. - * This allows for customized widgets on a proposal basis, although in general - * providers will have the same custom widget for all their proposals and - * @proposal can be ignored. The implementation of this function is optional. - * - * If this function is not implemented, the default widget is a #GtkLabel. The - * return value of gtk_source_completion_proposal_get_info() is used as the - * content of the #GtkLabel. - * - * - * - * If implemented, gtk_source_completion_provider_update_info() - * must also be implemented. - * - * - * - * Returns: (nullable) (transfer none): a custom #GtkWidget to show extra - * information about @proposal, or %NULL if the provider does not have a special - * info widget. - */ -GtkWidget * -gtk_source_completion_provider_get_info_widget (GtkSourceCompletionProvider *provider, - GtkSourceCompletionProposal *proposal) +void +gtk_source_completion_provider_refilter (GtkSourceCompletionProvider *self, + GtkSourceCompletionContext *context, + GListModel *model) { - g_return_val_if_fail (GTK_SOURCE_IS_COMPLETION_PROVIDER (provider), NULL); - g_return_val_if_fail (GTK_SOURCE_IS_COMPLETION_PROPOSAL (proposal), NULL); + g_return_if_fail (GTK_SOURCE_IS_COMPLETION_PROVIDER (self)); + g_return_if_fail (GTK_SOURCE_IS_COMPLETION_CONTEXT (context)); + g_return_if_fail (G_IS_LIST_MODEL (model)); - return GTK_SOURCE_COMPLETION_PROVIDER_GET_INTERFACE (provider)->get_info_widget (provider, proposal); + if (GTK_SOURCE_COMPLETION_PROVIDER_GET_IFACE (self)->refilter) + GTK_SOURCE_COMPLETION_PROVIDER_GET_IFACE (self)->refilter (self, context, model); } -/** - * gtk_source_completion_provider_update_info: - * @provider: a #GtkSourceCompletionProvider. - * @proposal: a #GtkSourceCompletionProposal. - * @info: a #GtkSourceCompletionInfo. - * - * Update extra information shown in @info for @proposal. - * - * - * - * This function must be implemented when - * gtk_source_completion_provider_get_info_widget() is implemented. - * - * - */ void -gtk_source_completion_provider_update_info (GtkSourceCompletionProvider *provider, - GtkSourceCompletionProposal *proposal, - GtkSourceCompletionInfo *info) +gtk_source_completion_provider_display (GtkSourceCompletionProvider *self, + GtkSourceCompletionContext *context, + GtkSourceCompletionProposal *proposal, + GtkSourceCompletionCell *cell) { - g_return_if_fail (GTK_SOURCE_IS_COMPLETION_PROVIDER (provider)); + g_return_if_fail (GTK_SOURCE_IS_COMPLETION_PROVIDER (self)); + g_return_if_fail (GTK_SOURCE_IS_COMPLETION_CONTEXT (context)); g_return_if_fail (GTK_SOURCE_IS_COMPLETION_PROPOSAL (proposal)); - g_return_if_fail (GTK_SOURCE_IS_COMPLETION_INFO (info)); + g_return_if_fail (GTK_SOURCE_IS_COMPLETION_CELL (cell)); - GTK_SOURCE_COMPLETION_PROVIDER_GET_INTERFACE (provider)->update_info (provider, proposal, info); + if (GTK_SOURCE_COMPLETION_PROVIDER_GET_IFACE (self)->display) + GTK_SOURCE_COMPLETION_PROVIDER_GET_IFACE (self)->display (self, context, proposal, cell); } -/** - * gtk_source_completion_provider_get_start_iter: - * @provider: a #GtkSourceCompletionProvider. - * @proposal: a #GtkSourceCompletionProposal. - * @context: a #GtkSourceCompletionContext. - * @iter: (out): a #GtkTextIter. - * - * Get the #GtkTextIter at which the completion for @proposal starts. When - * implemented, this information is used to position the completion window - * accordingly when a proposal is selected in the completion window. The - * @proposal text inside the completion window is aligned on @iter. - * - * If this function is not implemented, the word boundary is taken to position - * the completion window. See gtk_source_completion_provider_activate_proposal() - * for an explanation on the word boundaries. - * - * When the @proposal is activated, the default handler uses @iter as the start - * of the word to replace. See - * gtk_source_completion_provider_activate_proposal() for more information. - * - * Returns: %TRUE if @iter was set for @proposal, %FALSE otherwise. - */ -gboolean -gtk_source_completion_provider_get_start_iter (GtkSourceCompletionProvider *provider, - GtkSourceCompletionContext *context, - GtkSourceCompletionProposal *proposal, - GtkTextIter *iter) +void +gtk_source_completion_provider_activate (GtkSourceCompletionProvider *self, + GtkSourceCompletionContext *context, + GtkSourceCompletionProposal *proposal) { - g_return_val_if_fail (GTK_SOURCE_IS_COMPLETION_PROVIDER (provider), FALSE); - g_return_val_if_fail (GTK_SOURCE_IS_COMPLETION_CONTEXT (context), FALSE); - g_return_val_if_fail (GTK_SOURCE_IS_COMPLETION_PROPOSAL (proposal), FALSE); - g_return_val_if_fail (iter != NULL, FALSE); + g_return_if_fail (GTK_SOURCE_IS_COMPLETION_PROVIDER (self)); + g_return_if_fail (GTK_SOURCE_IS_COMPLETION_CONTEXT (context)); + g_return_if_fail (GTK_SOURCE_IS_COMPLETION_PROPOSAL (proposal)); - return GTK_SOURCE_COMPLETION_PROVIDER_GET_INTERFACE (provider)->get_start_iter (provider, - context, - proposal, - iter); + if (GTK_SOURCE_COMPLETION_PROVIDER_GET_IFACE (self)->activate) + GTK_SOURCE_COMPLETION_PROVIDER_GET_IFACE (self)->activate (self, context, proposal); } /** - * gtk_source_completion_provider_activate_proposal: - * @provider: a #GtkSourceCompletionProvider. - * @proposal: a #GtkSourceCompletionProposal. - * @iter: a #GtkTextIter. + * gtk_source_completion_provider_list_alternates: + * @self: a #GtkSourceCompletionProvider + * @context: a #GtkSourceCompletionContext + * @proposal: a #GtkSourceCompletionProposal * - * Activate @proposal at @iter. When this functions returns %FALSE, the default - * activation of @proposal will take place which replaces the word at @iter - * with the text of @proposal (see gtk_source_completion_proposal_get_text()). + * Providers should return a list of alternates to @proposal or %NULL if + * there are no alternates available. This can be used by the completion + * view to allow the user to move laterally through similar proposals, such + * as overrides of methods by the same name. * - * Here is how the default activation selects the boundaries of the word to - * replace. The end of the word is @iter. For the start of the word, it depends - * on whether a start iter is defined for @proposal (see - * gtk_source_completion_provider_get_start_iter()). If a start iter is defined, - * the start of the word is the start iter. Else, the word (as long as possible) - * will contain only alphanumerical and the "_" characters. + * Returns: (nullable) (transfer full) (element-type GtkSourceCompletionProposal): + * a #GPtrArray of #GtkSourceCompletionProposal or %NULL. * - * Returns: %TRUE to indicate that the proposal activation has been handled, - * %FALSE otherwise. + * Since: 5.0 */ -gboolean -gtk_source_completion_provider_activate_proposal (GtkSourceCompletionProvider *provider, - GtkSourceCompletionProposal *proposal, - GtkTextIter *iter) -{ - g_return_val_if_fail (GTK_SOURCE_IS_COMPLETION_PROVIDER (provider), FALSE); - g_return_val_if_fail (GTK_SOURCE_IS_COMPLETION_PROPOSAL (proposal), FALSE); - - return GTK_SOURCE_COMPLETION_PROVIDER_GET_INTERFACE (provider)->activate_proposal (provider, - proposal, - iter); -} - -/** - * gtk_source_completion_provider_get_interactive_delay: - * @provider: a #GtkSourceCompletionProvider. - * - * Get the delay in milliseconds before starting interactive completion for - * this provider. A value of -1 indicates to use the default value as set - * by the #GtkSourceCompletion:auto-complete-delay property. - * - * Returns: the interactive delay in milliseconds. - **/ -gint -gtk_source_completion_provider_get_interactive_delay (GtkSourceCompletionProvider *provider) +GPtrArray * +gtk_source_completion_provider_list_alternates (GtkSourceCompletionProvider *self, + GtkSourceCompletionContext *context, + GtkSourceCompletionProposal *proposal) { - g_return_val_if_fail (GTK_SOURCE_IS_COMPLETION_PROVIDER (provider), -1); - - return GTK_SOURCE_COMPLETION_PROVIDER_GET_INTERFACE (provider)->get_interactive_delay (provider); -} + g_return_val_if_fail (GTK_SOURCE_IS_COMPLETION_PROVIDER (self), NULL); + g_return_val_if_fail (GTK_SOURCE_IS_COMPLETION_CONTEXT (context), NULL); + g_return_val_if_fail (GTK_SOURCE_IS_COMPLETION_PROPOSAL (proposal), NULL); -/** - * gtk_source_completion_provider_get_priority: - * @provider: a #GtkSourceCompletionProvider. - * - * Get the provider priority. The priority determines the order in which - * proposals appear in the completion popup. Higher priorities are sorted - * before lower priorities. The default priority is 0. - * - * Returns: the provider priority. - **/ -gint -gtk_source_completion_provider_get_priority (GtkSourceCompletionProvider *provider) -{ - g_return_val_if_fail (GTK_SOURCE_IS_COMPLETION_PROVIDER (provider), 0); + if (GTK_SOURCE_COMPLETION_PROVIDER_GET_IFACE (self)->list_alternates) + return GTK_SOURCE_COMPLETION_PROVIDER_GET_IFACE (self)->list_alternates (self, context, proposal); - return GTK_SOURCE_COMPLETION_PROVIDER_GET_INTERFACE (provider)->get_priority (provider); + return NULL; } diff --git a/gtksourceview/gtksourcecompletionprovider.h b/gtksourceview/gtksourcecompletionprovider.h index 0560e7203a50d67cae0a757715bc5f3c30702596..62f60baae0cf2673257b4b9f3cb1b982e8093aca 100644 --- a/gtksourceview/gtksourcecompletionprovider.h +++ b/gtksourceview/gtksourcecompletionprovider.h @@ -1,9 +1,7 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8; coding: utf-8 -*- - * +/* * This file is part of GtkSourceView * - * Copyright (C) 2007 - 2009 Jesús Barbero Rodríguez - * Copyright (C) 2009 - Jesse van den Kieboom + * Copyright 2020 Christian Hergert * * GtkSourceView is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -17,150 +15,103 @@ * * You should have received a copy of the GNU Lesser General Public License * along with this library; if not, see . + * + * SPDX-License-Identifier: LGPL-2.1-or-later */ -#ifndef GTK_SOURCE_COMPLETION_PROVIDER_H -#define GTK_SOURCE_COMPLETION_PROVIDER_H +#pragma once -#if !defined (GTK_SOURCE_H_INSIDE) && !defined (GTK_SOURCE_COMPILATION) -#error "Only can be included directly." -#endif - -#include -#include -#include +#include "gtksourcetypes.h" G_BEGIN_DECLS -#define GTK_SOURCE_TYPE_COMPLETION_PROVIDER (gtk_source_completion_provider_get_type ()) -#define GTK_SOURCE_COMPLETION_PROVIDER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_SOURCE_TYPE_COMPLETION_PROVIDER, GtkSourceCompletionProvider)) -#define GTK_SOURCE_IS_COMPLETION_PROVIDER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_SOURCE_TYPE_COMPLETION_PROVIDER)) -#define GTK_SOURCE_COMPLETION_PROVIDER_GET_INTERFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), GTK_SOURCE_TYPE_COMPLETION_PROVIDER, GtkSourceCompletionProviderIface)) +#define GTK_SOURCE_TYPE_COMPLETION_PROVIDER (gtk_source_completion_provider_get_type()) -typedef struct _GtkSourceCompletionProviderIface GtkSourceCompletionProviderIface; +GTK_SOURCE_AVAILABLE_IN_5_0 +G_DECLARE_INTERFACE (GtkSourceCompletionProvider, gtk_source_completion_provider, GTK_SOURCE, COMPLETION_PROVIDER, GObject) -/** - * GtkSourceCompletionProviderIface: - * @g_iface: The parent interface. - * @get_name: The virtual function pointer for gtk_source_completion_provider_get_name(). - * Must be implemented. - * @get_icon: The virtual function pointer for gtk_source_completion_provider_get_icon(). - * By default, %NULL is returned. - * @get_icon_name: The virtual function pointer for gtk_source_completion_provider_get_icon_name(). - * By default, %NULL is returned. - * @get_gicon: The virtual function pointer for gtk_source_completion_provider_get_gicon(). - * By default, %NULL is returned. - * @populate: The virtual function pointer for gtk_source_completion_provider_populate(). - * Add no proposals by default. - * @match: The virtual function pointer for gtk_source_completion_provider_match(). - * By default, %TRUE is returned. - * @get_activation: The virtual function pointer for gtk_source_completion_provider_get_activation(). - * The combination of all #GtkSourceCompletionActivation is returned by default. - * @get_info_widget: The virtual function pointer for gtk_source_completion_provider_get_info_widget(). - * By default, %NULL is returned. - * @update_info: The virtual function pointer for gtk_source_completion_provider_update_info(). - * Does nothing by default. - * @get_start_iter: The virtual function pointer for gtk_source_completion_provider_get_start_iter(). - * By default, %FALSE is returned. - * @activate_proposal: The virtual function pointer for gtk_source_completion_provider_activate_proposal(). - * By default, %FALSE is returned. - * @get_interactive_delay: The virtual function pointer for gtk_source_completion_provider_get_interactive_delay(). - * By default, -1 is returned. - * @get_priority: The virtual function pointer for gtk_source_completion_provider_get_priority(). - * By default, 0 is returned. - * - * The virtual function table for #GtkSourceCompletionProvider. - */ -struct _GtkSourceCompletionProviderIface +struct _GtkSourceCompletionProviderInterface { - GTypeInterface g_iface; - - gchar *(*get_name) (GtkSourceCompletionProvider *provider); - - GdkPixbuf *(*get_icon) (GtkSourceCompletionProvider *provider); - const gchar *(*get_icon_name) (GtkSourceCompletionProvider *provider); - GIcon *(*get_gicon) (GtkSourceCompletionProvider *provider); - - void (*populate) (GtkSourceCompletionProvider *provider, - GtkSourceCompletionContext *context); - - gboolean (*match) (GtkSourceCompletionProvider *provider, - GtkSourceCompletionContext *context); - - GtkSourceCompletionActivation - (*get_activation) (GtkSourceCompletionProvider *provider); - - GtkWidget *(*get_info_widget) (GtkSourceCompletionProvider *provider, - GtkSourceCompletionProposal *proposal); - void (*update_info) (GtkSourceCompletionProvider *provider, - GtkSourceCompletionProposal *proposal, - GtkSourceCompletionInfo *info); - - gboolean (*get_start_iter) (GtkSourceCompletionProvider *provider, - GtkSourceCompletionContext *context, - GtkSourceCompletionProposal *proposal, - GtkTextIter *iter); - gboolean (*activate_proposal) (GtkSourceCompletionProvider *provider, - GtkSourceCompletionProposal *proposal, - GtkTextIter *iter); - - gint (*get_interactive_delay) (GtkSourceCompletionProvider *provider); - gint (*get_priority) (GtkSourceCompletionProvider *provider); + GTypeInterface parent_iface; + + char *(*get_title) (GtkSourceCompletionProvider *self); + int (*get_priority) (GtkSourceCompletionProvider *self, + GtkSourceCompletionContext *context); + gboolean (*is_trigger) (GtkSourceCompletionProvider *self, + const GtkTextIter *iter, + gunichar ch); + gboolean (*key_activates) (GtkSourceCompletionProvider *self, + GtkSourceCompletionContext *context, + GtkSourceCompletionProposal *proposal, + guint keyval, + GdkModifierType state); + GListModel *(*populate) (GtkSourceCompletionProvider *self, + GtkSourceCompletionContext *context, + GError **error); + void (*populate_async) (GtkSourceCompletionProvider *self, + GtkSourceCompletionContext *context, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); + GListModel *(*populate_finish) (GtkSourceCompletionProvider *self, + GAsyncResult *result, + GError **error); + void (*refilter) (GtkSourceCompletionProvider *self, + GtkSourceCompletionContext *context, + GListModel *model); + void (*display) (GtkSourceCompletionProvider *self, + GtkSourceCompletionContext *context, + GtkSourceCompletionProposal *proposal, + GtkSourceCompletionCell *cell); + void (*activate) (GtkSourceCompletionProvider *self, + GtkSourceCompletionContext *context, + GtkSourceCompletionProposal *proposal); + GPtrArray *(*list_alternates) (GtkSourceCompletionProvider *self, + GtkSourceCompletionContext *context, + GtkSourceCompletionProposal *proposal); }; -GTK_SOURCE_AVAILABLE_IN_ALL -GType gtk_source_completion_provider_get_type (void); - -GTK_SOURCE_AVAILABLE_IN_ALL -gchar *gtk_source_completion_provider_get_name (GtkSourceCompletionProvider *provider); - -GTK_SOURCE_AVAILABLE_IN_ALL -GdkPixbuf *gtk_source_completion_provider_get_icon (GtkSourceCompletionProvider *provider); - -GTK_SOURCE_AVAILABLE_IN_3_18 -const gchar *gtk_source_completion_provider_get_icon_name (GtkSourceCompletionProvider *provider); - -GTK_SOURCE_AVAILABLE_IN_3_18 -GIcon *gtk_source_completion_provider_get_gicon (GtkSourceCompletionProvider *provider); - -GTK_SOURCE_AVAILABLE_IN_ALL -void gtk_source_completion_provider_populate (GtkSourceCompletionProvider *provider, - GtkSourceCompletionContext *context); - -GTK_SOURCE_AVAILABLE_IN_ALL -GtkSourceCompletionActivation - gtk_source_completion_provider_get_activation (GtkSourceCompletionProvider *provider); - -GTK_SOURCE_AVAILABLE_IN_ALL -gboolean gtk_source_completion_provider_match (GtkSourceCompletionProvider *provider, - GtkSourceCompletionContext *context); - -GTK_SOURCE_AVAILABLE_IN_ALL -GtkWidget *gtk_source_completion_provider_get_info_widget (GtkSourceCompletionProvider *provider, - GtkSourceCompletionProposal *proposal); - -GTK_SOURCE_AVAILABLE_IN_ALL -void gtk_source_completion_provider_update_info (GtkSourceCompletionProvider *provider, - GtkSourceCompletionProposal *proposal, - GtkSourceCompletionInfo *info); - -GTK_SOURCE_AVAILABLE_IN_ALL -gboolean gtk_source_completion_provider_get_start_iter (GtkSourceCompletionProvider *provider, - GtkSourceCompletionContext *context, - GtkSourceCompletionProposal *proposal, - GtkTextIter *iter); - -GTK_SOURCE_AVAILABLE_IN_ALL -gboolean gtk_source_completion_provider_activate_proposal (GtkSourceCompletionProvider *provider, - GtkSourceCompletionProposal *proposal, - GtkTextIter *iter); - -GTK_SOURCE_AVAILABLE_IN_ALL -gint gtk_source_completion_provider_get_interactive_delay (GtkSourceCompletionProvider *provider); - -GTK_SOURCE_AVAILABLE_IN_ALL -gint gtk_source_completion_provider_get_priority (GtkSourceCompletionProvider *provider); +GTK_SOURCE_AVAILABLE_IN_5_0 +char *gtk_source_completion_provider_get_title (GtkSourceCompletionProvider *self); +GTK_SOURCE_AVAILABLE_IN_5_0 +int gtk_source_completion_provider_get_priority (GtkSourceCompletionProvider *self, + GtkSourceCompletionContext *context); +GTK_SOURCE_AVAILABLE_IN_5_0 +gboolean gtk_source_completion_provider_is_trigger (GtkSourceCompletionProvider *self, + const GtkTextIter *iter, + gunichar ch); +GTK_SOURCE_AVAILABLE_IN_5_0 +gboolean gtk_source_completion_provider_key_activates (GtkSourceCompletionProvider *self, + GtkSourceCompletionContext *context, + GtkSourceCompletionProposal *proposal, + guint keyval, + GdkModifierType state); +GTK_SOURCE_AVAILABLE_IN_5_0 +void gtk_source_completion_provider_populate_async (GtkSourceCompletionProvider *self, + GtkSourceCompletionContext *context, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +GTK_SOURCE_AVAILABLE_IN_5_0 +GListModel *gtk_source_completion_provider_populate_finish (GtkSourceCompletionProvider *self, + GAsyncResult *result, + GError **error); +GTK_SOURCE_AVAILABLE_IN_5_0 +void gtk_source_completion_provider_refilter (GtkSourceCompletionProvider *self, + GtkSourceCompletionContext *context, + GListModel *model); +GTK_SOURCE_AVAILABLE_IN_5_0 +void gtk_source_completion_provider_display (GtkSourceCompletionProvider *self, + GtkSourceCompletionContext *context, + GtkSourceCompletionProposal *proposal, + GtkSourceCompletionCell *cell); +GTK_SOURCE_AVAILABLE_IN_5_0 +void gtk_source_completion_provider_activate (GtkSourceCompletionProvider *self, + GtkSourceCompletionContext *context, + GtkSourceCompletionProposal *proposal); +GTK_SOURCE_AVAILABLE_IN_5_0 +GPtrArray *gtk_source_completion_provider_list_alternates (GtkSourceCompletionProvider *self, + GtkSourceCompletionContext *context, + GtkSourceCompletionProposal *proposal); G_END_DECLS - -#endif /* GTK_SOURCE_COMPLETION_PROVIDER_H */ diff --git a/gtksourceview/gtksourcecontextengine-private.h b/gtksourceview/gtksourcecontextengine-private.h new file mode 100644 index 0000000000000000000000000000000000000000..7ba72c555f367efc46a178214d1fc7fdb412718c --- /dev/null +++ b/gtksourceview/gtksourcecontextengine-private.h @@ -0,0 +1,108 @@ +/* + * This file is part of GtkSourceView + * + * Copyright 2003 - Gustavo Giráldez + * Copyright 2005 - Marco Barisione, Emanuele Aina + * + * GtkSourceView is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * GtkSourceView 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, see . + */ + +#pragma once + +#include "gtksourceengine-private.h" +#include "gtksourcetypes.h" +#include "gtksourcetypes-private.h" + +G_BEGIN_DECLS + +#define GTK_SOURCE_TYPE_CONTEXT_ENGINE (_gtk_source_context_engine_get_type()) + +typedef struct _GtkSourceContextData GtkSourceContextData; +typedef struct _GtkSourceContextReplace GtkSourceContextReplace; +typedef struct _GtkSourceContextClass GtkSourceContextClass; + +typedef enum _GtkSourceContextFlags { + GTK_SOURCE_CONTEXT_EXTEND_PARENT = 1 << 0, + GTK_SOURCE_CONTEXT_END_PARENT = 1 << 1, + GTK_SOURCE_CONTEXT_END_AT_LINE_END = 1 << 2, + GTK_SOURCE_CONTEXT_FIRST_LINE_ONLY = 1 << 3, + GTK_SOURCE_CONTEXT_ONCE_ONLY = 1 << 4, + GTK_SOURCE_CONTEXT_STYLE_INSIDE = 1 << 5 +} GtkSourceContextFlags; + +typedef enum _GtkSourceContextRefOptions { + GTK_SOURCE_CONTEXT_IGNORE_STYLE = 1 << 0, + GTK_SOURCE_CONTEXT_OVERRIDE_STYLE = 1 << 1, + GTK_SOURCE_CONTEXT_REF_ORIGINAL = 1 << 2 +} GtkSourceContextRefOptions; + +G_GNUC_INTERNAL +G_DECLARE_FINAL_TYPE (GtkSourceContextEngine, _gtk_source_context_engine, GTK_SOURCE, CONTEXT_ENGINE, GObject) + +G_GNUC_INTERNAL +GtkSourceContextData *_gtk_source_context_data_new (GtkSourceLanguage *lang); +G_GNUC_INTERNAL +GtkSourceContextData *_gtk_source_context_data_ref (GtkSourceContextData *data); +G_GNUC_INTERNAL +void _gtk_source_context_data_unref (GtkSourceContextData *data); +G_GNUC_INTERNAL +GtkSourceContextClass *gtk_source_context_class_new (gchar const *name, + gboolean enabled); +G_GNUC_INTERNAL +void gtk_source_context_class_free (GtkSourceContextClass *cclass); +G_GNUC_INTERNAL +GtkSourceContextEngine *_gtk_source_context_engine_new (GtkSourceContextData *data); +G_GNUC_INTERNAL +gboolean _gtk_source_context_data_define_context (GtkSourceContextData *data, + const gchar *id, + const gchar *parent_id, + const gchar *match_regex, + const gchar *start_regex, + const gchar *end_regex, + const gchar *style, + GSList *context_classes, + GtkSourceContextFlags flags, + GError **error); +G_GNUC_INTERNAL +gboolean _gtk_source_context_data_add_sub_pattern (GtkSourceContextData *data, + const gchar *id, + const gchar *parent_id, + const gchar *name, + const gchar *where, + const gchar *style, + GSList *context_classes, + GError **error); +G_GNUC_INTERNAL +gboolean _gtk_source_context_data_add_ref (GtkSourceContextData *data, + const gchar *parent_id, + const gchar *ref_id, + GtkSourceContextRefOptions options, + const gchar *style, + gboolean all, + GError **error); +G_GNUC_INTERNAL +GtkSourceContextReplace *_gtk_source_context_replace_new (const gchar *to_replace_id, + const gchar *replace_with_id); +G_GNUC_INTERNAL +void _gtk_source_context_replace_free (GtkSourceContextReplace *repl); +G_GNUC_INTERNAL +gboolean _gtk_source_context_data_finish_parse (GtkSourceContextData *data, + GList *overrides, + GError **error); +/* Only for lang files version 1, do not use it */ +G_GNUC_INTERNAL +void _gtk_source_context_data_set_escape_char (GtkSourceContextData *data, + gunichar esc_char); + +G_END_DECLS diff --git a/gtksourceview/gtksourcecontextengine.c b/gtksourceview/gtksourcecontextengine.c index 13554f8fe306ba3bb42ffac6f7eeafebe391430b..364270a95ad0507d390737c21e6f57865a4f349a 100644 --- a/gtksourceview/gtksourcecontextengine.c +++ b/gtksourceview/gtksourcecontextengine.c @@ -2,8 +2,8 @@ * * This file is part of GtkSourceView * - * Copyright (C) 2003 - Gustavo Giráldez - * Copyright (C) 2005, 2006 - Marco Barisione, Emanuele Aina + * Copyright 2003 - Gustavo Giráldez + * Copyright 2005, 2006 - Marco Barisione, Emanuele Aina * * GtkSourceView is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -19,19 +19,18 @@ * along with this library; if not, see . */ -#ifdef HAVE_CONFIG_H -#include -#endif +#include "config.h" -#include "gtksourcecontextengine.h" #include #include #include + +#include "gtksourcecontextengine-private.h" #include "gtksourceregion.h" #include "gtksourcelanguage.h" #include "gtksourcelanguage-private.h" #include "gtksourcebuffer.h" -#include "gtksourceregex.h" +#include "gtksourceregex-private.h" #include "gtksourcestyle.h" #include "gtksourcestylescheme.h" #include "gtksourceutils-private.h" @@ -413,8 +412,10 @@ struct _GtkSourceContextData GHashTable *definitions; }; -struct _GtkSourceContextEnginePrivate +struct _GtkSourceContextEngine { + GObject parent_instance; + GtkSourceContextData *ctx_data; GtkTextBuffer *buffer; @@ -455,9 +456,9 @@ struct _GtkSourceContextEnginePrivate }; #ifdef ENABLE_CHECK_TREE -static void check_tree (GtkSourceContextEngine *ce); -static void check_segment_list (Segment *segment); -static void check_segment_children (Segment *segment); +static void check_tree (GtkSourceContextEngine *ce); +static void check_segment_list (Segment *segment); +static void check_segment_children (Segment *segment); #define CHECK_TREE check_tree #define CHECK_SEGMENT_LIST check_segment_list #define CHECK_SEGMENT_CHILDREN check_segment_children @@ -467,66 +468,62 @@ static void check_segment_children (Segment *segment); #define CHECK_SEGMENT_CHILDREN(s) #endif -static GQuark gtk_source_context_engine_error_quark (void) G_GNUC_CONST; - -static Segment *create_segment (GtkSourceContextEngine *ce, - Segment *parent, - Context *context, - gint start_at, - gint end_at, - gboolean is_start, - Segment *hint); -static Segment *segment_new (GtkSourceContextEngine *ce, - Segment *parent, - Context *context, - gint start_at, - gint end_at, - gboolean is_start); -static Context *context_new (Context *parent, - ContextDefinition *definition, - const gchar *line_text, - const gchar *style, - gboolean ignore_children_style); -static void context_unref (Context *context); -static void context_freeze (Context *context); -static void context_thaw (Context *context); -static void erase_segments (GtkSourceContextEngine *ce, - gint start, - gint end, - Segment *hint); -static void segment_remove (GtkSourceContextEngine *ce, - Segment *segment); - -static void find_insertion_place (Segment *segment, - gint offset, - Segment **parent, - Segment **prev, - Segment **next, - Segment *hint); -static void segment_destroy (GtkSourceContextEngine *ce, - Segment *segment); -static ContextDefinition *context_definition_ref(ContextDefinition *definition); -static void context_definition_unref(ContextDefinition *definition); - -static void segment_extend (Segment *state, - gint end_at); -static Context *ancestor_context_ends_here (Context *state, - LineInfo *line, - gint pos); -static void definition_iter_init (DefinitionsIter *iter, - ContextDefinition *definition); -static DefinitionChild *definition_iter_next (DefinitionsIter *iter); -static void definition_iter_destroy (DefinitionsIter *iter); - -static void update_syntax (GtkSourceContextEngine *ce, - const GtkTextIter *end, - gint time); -static void install_idle_worker (GtkSourceContextEngine *ce); -static void install_first_update (GtkSourceContextEngine *ce); +static GQuark gtk_source_context_engine_error_quark (void) G_GNUC_CONST; +static Segment *create_segment (GtkSourceContextEngine *ce, + Segment *parent, + Context *context, + gint start_at, + gint end_at, + gboolean is_start, + Segment *hint); +static Segment *segment_new (GtkSourceContextEngine *ce, + Segment *parent, + Context *context, + gint start_at, + gint end_at, + gboolean is_start); +static Context *context_new (Context *parent, + ContextDefinition *definition, + const gchar *line_text, + const gchar *style, + gboolean ignore_children_style); +static void context_unref (Context *context); +static void context_freeze (Context *context); +static void context_thaw (Context *context); +static void erase_segments (GtkSourceContextEngine *ce, + gint start, + gint end, + Segment *hint); +static void segment_remove (GtkSourceContextEngine *ce, + Segment *segment); +static void find_insertion_place (Segment *segment, + gint offset, + Segment **parent, + Segment **prev, + Segment **next, + Segment *hint); +static void segment_destroy (GtkSourceContextEngine *ce, + Segment *segment); +static ContextDefinition *context_definition_ref (ContextDefinition *definition); +static void context_definition_unref (ContextDefinition *definition); +static void segment_extend (Segment *state, + gint end_at); +static Context *ancestor_context_ends_here (Context *state, + LineInfo *line, + gint pos); +static void definition_iter_init (DefinitionsIter *iter, + ContextDefinition *definition); +static DefinitionChild *definition_iter_next (DefinitionsIter *iter); +static void definition_iter_destroy (DefinitionsIter *iter); +static void update_syntax (GtkSourceContextEngine *ce, + const GtkTextIter *end, + gint time); +static void install_idle_worker (GtkSourceContextEngine *ce); +static void install_first_update (GtkSourceContextEngine *ce); static ContextDefinition * gtk_source_context_data_lookup (GtkSourceContextData *ctx_data, - const gchar *id) + const gchar *id) { return g_hash_table_lookup (ctx_data->definitions, id); } @@ -575,7 +572,7 @@ gtk_source_context_class_free (GtkSourceContextClass *cclass) static ContextClassTag * context_class_tag_new (GtkTextTag *tag, - gboolean enabled) + gboolean enabled) { ContextClassTag *attrtag = g_slice_new (ContextClassTag); @@ -598,8 +595,8 @@ struct BufAndIters { static void unhighlight_region_cb (G_GNUC_UNUSED gpointer style, - GSList *tags, - gpointer user_data) + GSList *tags, + gpointer user_data) { struct BufAndIters *data = user_data; @@ -615,27 +612,27 @@ unhighlight_region_cb (G_GNUC_UNUSED gpointer style, static void unhighlight_region (GtkSourceContextEngine *ce, - const GtkTextIter *start, - const GtkTextIter *end) + const GtkTextIter *start, + const GtkTextIter *end) { struct BufAndIters data; - data.buffer = ce->priv->buffer; + data.buffer = ce->buffer; data.start = start; data.end = end; if (gtk_text_iter_equal (start, end)) return; - g_hash_table_foreach (ce->priv->tags, (GHFunc) unhighlight_region_cb, &data); + g_hash_table_foreach (ce->tags, (GHFunc) unhighlight_region_cb, &data); } #define MAX_STYLE_DEPENDENCY_DEPTH 50 static void set_tag_style (GtkSourceContextEngine *ce, - GtkTextTag *tag, - const gchar *style_id) + GtkTextTag *tag, + const gchar *style_id) { GtkSourceStyle *style; const char *map_to; @@ -646,11 +643,11 @@ set_tag_style (GtkSourceContextEngine *ce, gtk_source_style_apply (NULL, tag); - if (ce->priv->style_scheme == NULL) + if (ce->style_scheme == NULL) return; map_to = style_id; - style = gtk_source_style_scheme_get_style (ce->priv->style_scheme, style_id); + style = gtk_source_style_scheme_get_style (ce->style_scheme, style_id); while (style == NULL) { @@ -664,11 +661,11 @@ set_tag_style (GtkSourceContextEngine *ce, /* FIXME Style references really must be fixed, both parser for * sane use in lang files, and engine for safe use. */ - map_to = gtk_source_language_get_style_fallback (ce->priv->ctx_data->lang, map_to); + map_to = gtk_source_language_get_style_fallback (ce->ctx_data->lang, map_to); if (map_to == NULL) break; - style = gtk_source_style_scheme_get_style (ce->priv->style_scheme, map_to); + style = gtk_source_style_scheme_get_style (ce->style_scheme, map_to); } /* not having style is fine, since parser checks validity of every style reference, @@ -679,18 +676,18 @@ set_tag_style (GtkSourceContextEngine *ce, static GtkTextTag * create_tag (GtkSourceContextEngine *ce, - const gchar *style_id) + const gchar *style_id) { GtkTextTag *new_tag; g_assert (style_id != NULL); - new_tag = gtk_text_buffer_create_tag (ce->priv->buffer, NULL, NULL); + new_tag = gtk_text_buffer_create_tag (ce->buffer, NULL, NULL); /* It must have priority lower than user tags but still * higher than highlighting tags created before */ - gtk_text_tag_set_priority (new_tag, ce->priv->n_tags); + gtk_text_tag_set_priority (new_tag, ce->n_tags); set_tag_style (ce, new_tag, style_id); - ce->priv->n_tags += 1; + ce->n_tags += 1; return new_tag; } @@ -698,7 +695,7 @@ create_tag (GtkSourceContextEngine *ce, /* Find tag which has to be overridden. */ static GtkTextTag * get_parent_tag (Context *context, - const char *style) + const char *style) { while (context != NULL) { @@ -719,8 +716,8 @@ get_parent_tag (Context *context, static GtkTextTag * get_tag_for_parent (GtkSourceContextEngine *ce, - const char *style, - Context *parent) + const char *style, + Context *parent) { GSList *tags; GtkTextTag *parent_tag = NULL; @@ -729,7 +726,7 @@ get_tag_for_parent (GtkSourceContextEngine *ce, g_return_val_if_fail (style != NULL, NULL); parent_tag = get_parent_tag (parent, style); - tags = g_hash_table_lookup (ce->priv->tags, style); + tags = g_hash_table_lookup (ce->tags, style); if (tags && (!parent_tag || gtk_text_tag_get_priority (tags->data) > gtk_text_tag_get_priority (parent_tag))) @@ -753,7 +750,7 @@ get_tag_for_parent (GtkSourceContextEngine *ce, tag = create_tag (ce, style); tags = g_slist_prepend (tags, g_object_ref (tag)); - g_hash_table_insert (ce->priv->tags, g_strdup (style), tags); + g_hash_table_insert (ce->tags, g_strdup (style), tags); #ifdef ENABLE_DEBUG { @@ -772,7 +769,7 @@ get_tag_for_parent (GtkSourceContextEngine *ce, parent = parent->parent; } - tags = g_hash_table_lookup (ce->priv->tags, style); + tags = g_hash_table_lookup (ce->tags, style); n = g_slist_length (tags); g_print ("created %d tag for style %s: %s\n", n, style, style_path->str); g_string_free (style_path, TRUE); @@ -785,8 +782,8 @@ get_tag_for_parent (GtkSourceContextEngine *ce, static GtkTextTag * get_subpattern_tag (GtkSourceContextEngine *ce, - Context *context, - SubPatternDefinition *sp_def) + Context *context, + SubPatternDefinition *sp_def) { if (sp_def->style == NULL) return NULL; @@ -805,7 +802,7 @@ get_subpattern_tag (GtkSourceContextEngine *ce, static GtkTextTag * get_context_tag (GtkSourceContextEngine *ce, - Context *context) + Context *context) { if (context->style != NULL && context->tag == NULL) context->tag = get_tag_for_parent (ce, @@ -816,13 +813,13 @@ get_context_tag (GtkSourceContextEngine *ce, static void apply_tags (GtkSourceContextEngine *ce, - Segment *segment, - gint start_offset, - gint end_offset) + Segment *segment, + gint start_offset, + gint end_offset) { GtkTextTag *tag; GtkTextIter start_iter, end_iter; - GtkTextBuffer *buffer = ce->priv->buffer; + GtkTextBuffer *buffer = ce->buffer; SubPattern *sp; Segment *child; @@ -861,7 +858,7 @@ apply_tags (GtkSourceContextEngine *ce, gtk_text_buffer_get_iter_at_offset (buffer, &start_iter, style_start_at); end_iter = start_iter; gtk_text_iter_forward_chars (&end_iter, style_end_at - style_start_at); - gtk_text_buffer_apply_tag (ce->priv->buffer, tag, &start_iter, &end_iter); + gtk_text_buffer_apply_tag (ce->buffer, tag, &start_iter, &end_iter); } } @@ -879,7 +876,7 @@ apply_tags (GtkSourceContextEngine *ce, gtk_text_buffer_get_iter_at_offset (buffer, &start_iter, start); end_iter = start_iter; gtk_text_iter_forward_chars (&end_iter, end - start); - gtk_text_buffer_apply_tag (ce->priv->buffer, tag, &start_iter, &end_iter); + gtk_text_buffer_apply_tag (ce->buffer, tag, &start_iter, &end_iter); } } } @@ -895,8 +892,8 @@ apply_tags (GtkSourceContextEngine *ce, static void highlight_region (GtkSourceContextEngine *ce, - GtkTextIter *start, - GtkTextIter *end) + GtkTextIter *start, + GtkTextIter *end) { #ifdef ENABLE_PROFILE GTimer *timer; @@ -914,7 +911,7 @@ highlight_region (GtkSourceContextEngine *ce, /* First we need to delete tags in the regions. */ unhighlight_region (ce, start, end); - apply_tags (ce, ce->priv->root_segment, + apply_tags (ce, ce->root_segment, gtk_text_iter_get_offset (start), gtk_text_iter_get_offset (end)); @@ -941,14 +938,14 @@ highlight_region (GtkSourceContextEngine *ce, */ static void ensure_highlighted (GtkSourceContextEngine *ce, - const GtkTextIter *start, - const GtkTextIter *end) + const GtkTextIter *start, + const GtkTextIter *end) { GtkSourceRegion *region; GtkSourceRegionIter reg_iter; /* Get the subregions not yet highlighted. */ - region = gtk_source_region_intersect_subregion (ce->priv->refresh_region, start, end); + region = gtk_source_region_intersect_subregion (ce->refresh_region, start, end); if (region == NULL) return; @@ -968,12 +965,12 @@ ensure_highlighted (GtkSourceContextEngine *ce, g_clear_object (®ion); /* Remove the just highlighted region. */ - gtk_source_region_subtract_subregion (ce->priv->refresh_region, start, end); + gtk_source_region_subtract_subregion (ce->refresh_region, start, end); } static GtkTextTag * get_context_class_tag (GtkSourceContextEngine *ce, - gchar const *name) + gchar const *name) { gchar *tag_name; GtkTextTagTable *tag_table; @@ -981,15 +978,15 @@ get_context_class_tag (GtkSourceContextEngine *ce, tag_name = g_strdup_printf ("gtksourceview:context-classes:%s", name); - tag_table = gtk_text_buffer_get_tag_table (ce->priv->buffer); + tag_table = gtk_text_buffer_get_tag_table (ce->buffer); tag = gtk_text_tag_table_lookup (tag_table, tag_name); if (tag == NULL) { - tag = gtk_text_buffer_create_tag (ce->priv->buffer, tag_name, NULL); + tag = gtk_text_buffer_create_tag (ce->buffer, tag_name, NULL); g_return_val_if_fail (tag != NULL, NULL); - ce->priv->context_classes = g_slist_prepend (ce->priv->context_classes, + ce->context_classes = g_slist_prepend (ce->context_classes, g_object_ref (tag)); } @@ -999,7 +996,7 @@ get_context_class_tag (GtkSourceContextEngine *ce, static GSList * extend_context_classes (GtkSourceContextEngine *ce, - GSList *definitions) + GSList *definitions) { GSList *item; GSList *ret = NULL; @@ -1018,8 +1015,8 @@ extend_context_classes (GtkSourceContextEngine *ce, static GSList * get_subpattern_context_classes (GtkSourceContextEngine *ce, - Context *context, - SubPatternDefinition *sp_def) + Context *context, + SubPatternDefinition *sp_def) { g_assert (sp_def->index < context->definition->n_sub_patterns); @@ -1038,7 +1035,7 @@ get_subpattern_context_classes (GtkSourceContextEngine *ce, static GSList * get_context_classes (GtkSourceContextEngine *ce, - Context *context) + Context *context) { if (context->context_classes == NULL) { @@ -1052,15 +1049,15 @@ get_context_classes (GtkSourceContextEngine *ce, static void apply_context_classes (GtkSourceContextEngine *ce, - GSList *context_classes, - gint start, - gint end) + GSList *context_classes, + gint start, + gint end) { GtkTextIter start_iter; GtkTextIter end_iter; GSList *item; - gtk_text_buffer_get_iter_at_offset (ce->priv->buffer, &start_iter, start); + gtk_text_buffer_get_iter_at_offset (ce->buffer, &start_iter, start); end_iter = start_iter; gtk_text_iter_forward_chars (&end_iter, end - start); @@ -1070,14 +1067,14 @@ apply_context_classes (GtkSourceContextEngine *ce, if (attrtag->enabled) { - gtk_text_buffer_apply_tag (ce->priv->buffer, + gtk_text_buffer_apply_tag (ce->buffer, attrtag->tag, &start_iter, &end_iter); } else { - gtk_text_buffer_remove_tag (ce->priv->buffer, + gtk_text_buffer_remove_tag (ce->buffer, attrtag->tag, &start_iter, &end_iter); @@ -1087,9 +1084,9 @@ apply_context_classes (GtkSourceContextEngine *ce, static void add_region_context_classes (GtkSourceContextEngine *ce, - Segment *segment, - gint start_offset, - gint end_offset) + Segment *segment, + gint start_offset, + gint end_offset) { SubPattern *sp; Segment *child; @@ -1154,8 +1151,8 @@ add_region_context_classes (GtkSourceContextEngine *ce, static void remove_region_context_classes (GtkSourceContextEngine *ce, - const GtkTextIter *start, - const GtkTextIter *end) + const GtkTextIter *start, + const GtkTextIter *end) { GSList *l; @@ -1164,18 +1161,18 @@ remove_region_context_classes (GtkSourceContextEngine *ce, return; } - for (l = ce->priv->context_classes; l != NULL; l = l->next) + for (l = ce->context_classes; l != NULL; l = l->next) { GtkTextTag *tag = l->data; - gtk_text_buffer_remove_tag (ce->priv->buffer, tag, start, end); + gtk_text_buffer_remove_tag (ce->buffer, tag, start, end); } } static void refresh_context_classes (GtkSourceContextEngine *ce, - const GtkTextIter *start, - const GtkTextIter *end) + const GtkTextIter *start, + const GtkTextIter *end) { #ifdef ENABLE_PROFILE GTimer *timer; @@ -1200,7 +1197,7 @@ refresh_context_classes (GtkSourceContextEngine *ce, remove_region_context_classes (ce, start, &realend); add_region_context_classes (ce, - ce->priv->root_segment, + ce->root_segment, gtk_text_iter_get_offset (start), gtk_text_iter_get_offset (&realend)); @@ -1225,8 +1222,8 @@ refresh_context_classes (GtkSourceContextEngine *ce, */ static void refresh_range (GtkSourceContextEngine *ce, - const GtkTextIter *start, - const GtkTextIter *end) + const GtkTextIter *start, + const GtkTextIter *end) { GtkTextIter real_end; @@ -1245,7 +1242,7 @@ refresh_range (GtkSourceContextEngine *ce, gtk_text_iter_backward_cursor_position (&real_end); } - g_signal_emit_by_name (ce->priv->buffer, + g_signal_emit_by_name (ce->buffer, "highlight-updated", start, &real_end); @@ -1265,7 +1262,7 @@ refresh_range (GtkSourceContextEngine *ce, */ static gint segment_cmp (Segment *s1, - Segment *s2) + Segment *s2) { if (s1->start_at < s2->start_at) return -1; @@ -1293,18 +1290,18 @@ segment_cmp (Segment *s1, */ static void add_invalid (GtkSourceContextEngine *ce, - Segment *segment) + Segment *segment) { #ifdef ENABLE_CHECK_TREE - g_assert (!g_slist_find (ce->priv->invalid, segment)); + g_assert (!g_slist_find (ce->invalid, segment)); #endif g_return_if_fail (SEGMENT_IS_INVALID (segment)); - ce->priv->invalid = g_slist_insert_sorted (ce->priv->invalid, + ce->invalid = g_slist_insert_sorted (ce->invalid, segment, (GCompareFunc) segment_cmp); - DEBUG (g_print ("%d invalid\n", g_slist_length (ce->priv->invalid))); + DEBUG (g_print ("%d invalid\n", g_slist_length (ce->invalid))); } /** @@ -1318,12 +1315,12 @@ add_invalid (GtkSourceContextEngine *ce, */ static void remove_invalid (GtkSourceContextEngine *ce, - Segment *segment) + Segment *segment) { #ifdef ENABLE_CHECK_TREE - g_assert (g_slist_find (ce->priv->invalid, segment) != NULL); + g_assert (g_slist_find (ce->invalid, segment) != NULL); #endif - ce->priv->invalid = g_slist_remove (ce->priv->invalid, segment); + ce->invalid = g_slist_remove (ce->invalid, segment); } /** @@ -1337,8 +1334,8 @@ remove_invalid (GtkSourceContextEngine *ce, */ static void fix_offsets_insert_ (Segment *segment, - gint start, - gint delta) + gint start, + gint delta) { Segment *child; SubPattern *sp; @@ -1375,11 +1372,11 @@ fix_offsets_insert_ (Segment *segment, */ static void find_insertion_place_forward_ (Segment *segment, - gint offset, - Segment *start, - Segment **parent, - Segment **prev, - Segment **next) + gint offset, + Segment *start, + Segment **parent, + Segment **prev, + Segment **next) { Segment *child; @@ -1443,11 +1440,11 @@ find_insertion_place_forward_ (Segment *segment, */ static void find_insertion_place_backward_ (Segment *segment, - gint offset, - Segment *start, - Segment **parent, - Segment **prev, - Segment **next) + gint offset, + Segment *start, + Segment **parent, + Segment **prev, + Segment **next) { Segment *child; @@ -1517,11 +1514,11 @@ find_insertion_place_backward_ (Segment *segment, */ static void find_insertion_place (Segment *segment, - gint offset, - Segment **parent, - Segment **prev, - Segment **next, - Segment *hint) + gint offset, + Segment **parent, + Segment **prev, + Segment **next, + Segment *hint) { g_assert (segment->start_at <= offset && segment->end_at >= offset); @@ -1573,9 +1570,9 @@ find_insertion_place (Segment *segment, */ static Segment * get_invalid_at (GtkSourceContextEngine *ce, - gint offset) + gint offset) { - GSList *link = ce->priv->invalid; + GSList *link = ce->invalid; while (link != NULL) { @@ -1604,7 +1601,7 @@ get_invalid_at (GtkSourceContextEngine *ce, */ static void segment_add_subpattern (Segment *state, - SubPattern *sp) + SubPattern *sp) { sp->next = state->sub_patterns; state->sub_patterns = sp; @@ -1624,9 +1621,9 @@ segment_add_subpattern (Segment *state, */ static SubPattern * sub_pattern_new (Segment *segment, - gint start_at, - gint end_at, - SubPatternDefinition *sp_def) + gint start_at, + gint end_at, + SubPatternDefinition *sp_def) { SubPattern *sp; @@ -1665,7 +1662,7 @@ sub_pattern_free (SubPattern *sp) */ static void segment_make_invalid_ (GtkSourceContextEngine *ce, - Segment *segment) + Segment *segment) { Context *ctx; SubPattern *sp; @@ -1705,8 +1702,8 @@ segment_make_invalid_ (GtkSourceContextEngine *ce, */ static Segment * simple_segment_split_ (GtkSourceContextEngine *ce, - Segment *segment, - gint offset) + Segment *segment, + gint offset) { SubPattern *sp; Segment *new_segment, *invalid; @@ -1766,11 +1763,11 @@ simple_segment_split_ (GtkSourceContextEngine *ce, */ static void invalidate_region (GtkSourceContextEngine *ce, - gint offset, - gint length) + gint offset, + gint length) { - InvalidRegion *region = &ce->priv->invalid_region; - GtkTextBuffer *buffer = ce->priv->buffer; + InvalidRegion *region = &ce->invalid_region; + GtkTextBuffer *buffer = ce->buffer; GtkTextIter iter; gint end_offset; @@ -1838,8 +1835,8 @@ invalidate_region (GtkSourceContextEngine *ce, */ static void insert_range (GtkSourceContextEngine *ce, - gint offset, - gint length) + gint offset, + gint length) { Segment *parent, *prev = NULL, *next = NULL, *new_segment; Segment *segment; @@ -1851,9 +1848,9 @@ insert_range (GtkSourceContextEngine *ce, parent = get_invalid_at (ce, offset); if (parent == NULL) - find_insertion_place (ce->priv->root_segment, offset, + find_insertion_place (ce->root_segment, offset, &parent, &prev, &next, - ce->priv->hint); + ce->hint); g_assert (parent->start_at <= offset); g_assert (parent->end_at >= offset); @@ -1950,13 +1947,13 @@ insert_range (GtkSourceContextEngine *ce, */ static void gtk_source_context_engine_text_inserted (GtkSourceEngine *engine, - gint start_offset, - gint end_offset) + gint start_offset, + gint end_offset) { GtkTextIter iter; GtkSourceContextEngine *ce = GTK_SOURCE_CONTEXT_ENGINE (engine); - if (!ce->priv->disabled) + if (!ce->disabled) { g_return_if_fail (start_offset < end_offset); @@ -1967,7 +1964,7 @@ gtk_source_context_engine_text_inserted (GtkSourceEngine *engine, * highlighted because the engine analyzes the previous line, end * context there is none, start context at this line is none too, * and the engine stops. */ - gtk_text_buffer_get_iter_at_offset (ce->priv->buffer, &iter, end_offset); + gtk_text_buffer_get_iter_at_offset (ce->buffer, &iter, end_offset); if (gtk_text_iter_starts_line (&iter) && !gtk_text_iter_ends_line (&iter)) { gtk_text_iter_forward_to_line_end (&iter); @@ -1988,8 +1985,8 @@ gtk_source_context_engine_text_inserted (GtkSourceEngine *engine, */ static inline gint fix_offset_delete_one_ (gint offset, - gint start, - gint length) + gint start, + gint length) { if (offset > start) { @@ -2014,9 +2011,9 @@ fix_offset_delete_one_ (gint offset, */ static void fix_offsets_delete_ (Segment *segment, - gint offset, - gint length, - Segment *hint) + gint offset, + gint length, + Segment *hint) { Segment *child; SubPattern *sp; @@ -2066,14 +2063,14 @@ fix_offsets_delete_ (Segment *segment, */ static void delete_range_ (GtkSourceContextEngine *ce, - gint start, - gint end) + gint start, + gint end) { g_return_if_fail (start < end); /* FIXME adjacent invalid segments? */ erase_segments (ce, start, end, NULL); - fix_offsets_delete_ (ce->priv->root_segment, start, end - start, ce->priv->hint); + fix_offsets_delete_ (ce->root_segment, start, end - start, ce->hint); /* no need to invalidate at start, update_tree will do it */ @@ -2090,14 +2087,14 @@ delete_range_ (GtkSourceContextEngine *ce, */ static void gtk_source_context_engine_text_deleted (GtkSourceEngine *engine, - gint offset, - gint length) + gint offset, + gint length) { GtkSourceContextEngine *ce = GTK_SOURCE_CONTEXT_ENGINE (engine); g_return_if_fail (length > 0); - if (!ce->priv->disabled) + if (!ce->disabled) { invalidate_region (ce, offset, - length); } @@ -2112,8 +2109,8 @@ gtk_source_context_engine_text_deleted (GtkSourceEngine *engine, static Segment * get_invalid_segment (GtkSourceContextEngine *ce) { - g_return_val_if_fail (ce->priv->invalid_region.empty, NULL); - return ce->priv->invalid ? ce->priv->invalid->data : NULL; + g_return_val_if_fail (ce->invalid_region.empty, NULL); + return ce->invalid ? ce->invalid->data : NULL; } /** @@ -2128,26 +2125,26 @@ get_invalid_line (GtkSourceContextEngine *ce) GtkTextIter iter; gint offset = G_MAXINT; - if (!ce->priv->invalid_region.empty) + if (!ce->invalid_region.empty) { gint tmp; - gtk_text_buffer_get_iter_at_mark (ce->priv->buffer, + gtk_text_buffer_get_iter_at_mark (ce->buffer, &iter, - ce->priv->invalid_region.start); + ce->invalid_region.start); tmp = gtk_text_iter_get_offset (&iter); offset = MIN (offset, tmp); } - if (ce->priv->invalid) + if (ce->invalid) { - Segment *segment = ce->priv->invalid->data; + Segment *segment = ce->invalid->data; offset = MIN (offset, segment->start_at); } if (offset == G_MAXINT) return -1; - gtk_text_buffer_get_iter_at_offset (ce->priv->buffer, &iter, offset); + gtk_text_buffer_get_iter_at_offset (ce->buffer, &iter, offset); return gtk_text_iter_get_line (&iter); } @@ -2160,7 +2157,7 @@ get_invalid_line (GtkSourceContextEngine *ce) static void update_tree (GtkSourceContextEngine *ce) { - InvalidRegion *region = &ce->priv->invalid_region; + InvalidRegion *region = &ce->invalid_region; gint start, end, delta; gint erase_start, erase_end; GtkTextIter iter; @@ -2168,9 +2165,9 @@ update_tree (GtkSourceContextEngine *ce) if (region->empty) return; - gtk_text_buffer_get_iter_at_mark (ce->priv->buffer, &iter, region->start); + gtk_text_buffer_get_iter_at_mark (ce->buffer, &iter, region->start); start = gtk_text_iter_get_offset (&iter); - gtk_text_buffer_get_iter_at_mark (ce->priv->buffer, &iter, region->end); + gtk_text_buffer_get_iter_at_mark (ce->buffer, &iter, region->end); end = gtk_text_iter_get_offset (&iter); delta = region->delta; @@ -2202,7 +2199,7 @@ update_tree (GtkSourceContextEngine *ce) if (erase_start < erase_end) { erase_segments (ce, erase_start, erase_end, NULL); - create_segment (ce, ce->priv->root_segment, NULL, erase_start, erase_end, FALSE, NULL); + create_segment (ce, ce->root_segment, NULL, erase_start, erase_end, FALSE, NULL); } else if (get_invalid_at (ce, start) == NULL) { @@ -2232,15 +2229,15 @@ update_tree (GtkSourceContextEngine *ce) */ static void gtk_source_context_engine_update_highlight (GtkSourceEngine *engine, - const GtkTextIter *start, - const GtkTextIter *end, - gboolean synchronous) + const GtkTextIter *start, + const GtkTextIter *end, + gboolean synchronous) { gint invalid_line; gint end_line; GtkSourceContextEngine *ce = GTK_SOURCE_CONTEXT_ENGINE (engine); - if (!ce->priv->highlight || ce->priv->disabled) + if (!ce->highlight || ce->disabled) return; invalid_line = get_invalid_line (ce); @@ -2284,20 +2281,20 @@ gtk_source_context_engine_update_highlight (GtkSourceEngine *engine, */ static void enable_highlight (GtkSourceContextEngine *ce, - gboolean enable) + gboolean enable) { GtkTextIter start, end; - if (!enable == !ce->priv->highlight) + if (!enable == !ce->highlight) return; - ce->priv->highlight = enable != 0; - gtk_text_buffer_get_bounds (GTK_TEXT_BUFFER (ce->priv->buffer), + ce->highlight = enable != 0; + gtk_text_buffer_get_bounds (GTK_TEXT_BUFFER (ce->buffer), &start, &end); if (enable) { - gtk_source_region_add_subregion (ce->priv->refresh_region, &start, &end); + gtk_source_region_add_subregion (ce->refresh_region, &start, &end); refresh_range (ce, &start, &end); } @@ -2312,7 +2309,7 @@ buffer_notify_highlight_syntax_cb (GtkSourceContextEngine *ce) { gboolean highlight; - g_object_get (ce->priv->buffer, "highlight-syntax", &highlight, NULL); + g_object_get (ce->buffer, "highlight-syntax", &highlight, NULL); enable_highlight (ce, highlight); } @@ -2328,7 +2325,7 @@ buffer_notify_highlight_syntax_cb (GtkSourceContextEngine *ce) static gboolean all_analyzed (GtkSourceContextEngine *ce) { - return ce->priv->invalid == NULL && ce->priv->invalid_region.empty; + return ce->invalid == NULL && ce->invalid_region.empty; } /** @@ -2343,7 +2340,7 @@ idle_worker (GtkSourceContextEngine *ce) { gboolean retval = G_SOURCE_CONTINUE; - g_return_val_if_fail (ce->priv->buffer != NULL, G_SOURCE_REMOVE); + g_return_val_if_fail (ce->buffer != NULL, G_SOURCE_REMOVE); /* analyze batch of text */ update_syntax (ce, NULL, INCREMENTAL_UPDATE_TIME_SLICE); @@ -2351,7 +2348,7 @@ idle_worker (GtkSourceContextEngine *ce) if (all_analyzed (ce)) { - ce->priv->incremental_update = 0; + ce->incremental_update = 0; retval = G_SOURCE_REMOVE; } @@ -2368,13 +2365,13 @@ idle_worker (GtkSourceContextEngine *ce) static gboolean first_update_callback (GtkSourceContextEngine *ce) { - g_return_val_if_fail (ce->priv->buffer != NULL, G_SOURCE_REMOVE); + g_return_val_if_fail (ce->buffer != NULL, G_SOURCE_REMOVE); /* analyze batch of text */ update_syntax (ce, NULL, FIRST_UPDATE_TIME_SLICE); CHECK_TREE (ce); - ce->priv->first_update = 0; + ce->first_update = 0; if (!all_analyzed (ce)) install_idle_worker (ce); @@ -2392,10 +2389,11 @@ first_update_callback (GtkSourceContextEngine *ce) static void install_idle_worker (GtkSourceContextEngine *ce) { - if (ce->priv->first_update == 0 && ce->priv->incremental_update == 0) - ce->priv->incremental_update = - gdk_threads_add_idle_full (INCREMENTAL_UPDATE_PRIORITY, - (GSourceFunc) idle_worker, ce, NULL); + if (ce->first_update == 0 && ce->incremental_update == 0) + ce->incremental_update = + g_idle_add_full (INCREMENTAL_UPDATE_PRIORITY, + (GSourceFunc) idle_worker, + ce, NULL); } /** @@ -2408,18 +2406,18 @@ install_idle_worker (GtkSourceContextEngine *ce) static void install_first_update (GtkSourceContextEngine *ce) { - if (ce->priv->first_update == 0) + if (ce->first_update == 0) { - if (ce->priv->incremental_update != 0) + if (ce->incremental_update != 0) { - g_source_remove (ce->priv->incremental_update); - ce->priv->incremental_update = 0; + g_source_remove (ce->incremental_update); + ce->incremental_update = 0; } - ce->priv->first_update = - gdk_threads_add_idle_full (FIRST_UPDATE_PRIORITY, - (GSourceFunc) first_update_callback, - ce, NULL); + ce->first_update = + g_idle_add_full (FIRST_UPDATE_PRIORITY, + (GSourceFunc) first_update_callback, + ce, NULL); } } @@ -2428,11 +2426,10 @@ install_first_update (GtkSourceContextEngine *ce) static void _gtk_source_engine_interface_init (GtkSourceEngineInterface *iface); G_DEFINE_TYPE_WITH_CODE (GtkSourceContextEngine, - _gtk_source_context_engine, - G_TYPE_OBJECT, - G_ADD_PRIVATE (GtkSourceContextEngine) - G_IMPLEMENT_INTERFACE (GTK_SOURCE_TYPE_ENGINE, - _gtk_source_engine_interface_init)) + _gtk_source_context_engine, + G_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE (GTK_SOURCE_TYPE_ENGINE, + _gtk_source_engine_interface_init)) static GQuark gtk_source_context_engine_error_quark (void) @@ -2445,8 +2442,8 @@ gtk_source_context_engine_error_quark (void) static void remove_tags_hash_cb (G_GNUC_UNUSED gpointer style, - GSList *tags, - GtkTextTagTable *table) + GSList *tags, + GtkTextTagTable *table) { GSList *l = tags; @@ -2469,10 +2466,10 @@ remove_tags_hash_cb (G_GNUC_UNUSED gpointer style, static void destroy_tags_hash (GtkSourceContextEngine *ce) { - g_hash_table_foreach (ce->priv->tags, (GHFunc) remove_tags_hash_cb, - gtk_text_buffer_get_tag_table (ce->priv->buffer)); - g_hash_table_destroy (ce->priv->tags); - ce->priv->tags = NULL; + g_hash_table_foreach (ce->tags, (GHFunc) remove_tags_hash_cb, + gtk_text_buffer_get_tag_table (ce->buffer)); + g_hash_table_destroy (ce->tags); + ce->tags = NULL; } static void @@ -2481,9 +2478,9 @@ destroy_context_classes_list (GtkSourceContextEngine *ce) GtkTextTagTable *table; GSList *l; - table = gtk_text_buffer_get_tag_table (ce->priv->buffer); + table = gtk_text_buffer_get_tag_table (ce->buffer); - for (l = ce->priv->context_classes; l != NULL; l = l->next) + for (l = ce->context_classes; l != NULL; l = l->next) { GtkTextTag *tag = l->data; @@ -2491,8 +2488,8 @@ destroy_context_classes_list (GtkSourceContextEngine *ce) g_object_unref (tag); } - g_slist_free (ce->priv->context_classes); - ce->priv->context_classes = NULL; + g_slist_free (ce->context_classes); + ce->context_classes = NULL; } /** @@ -2505,47 +2502,47 @@ destroy_context_classes_list (GtkSourceContextEngine *ce) */ static void gtk_source_context_engine_attach_buffer (GtkSourceEngine *engine, - GtkTextBuffer *buffer) + GtkTextBuffer *buffer) { GtkSourceContextEngine *ce = GTK_SOURCE_CONTEXT_ENGINE (engine); g_return_if_fail (!buffer || GTK_IS_TEXT_BUFFER (buffer)); - if (ce->priv->buffer == buffer) + if (ce->buffer == buffer) return; /* Detach previous buffer if there is one. */ - if (ce->priv->buffer != NULL) + if (ce->buffer != NULL) { - g_signal_handlers_disconnect_by_func (ce->priv->buffer, + g_signal_handlers_disconnect_by_func (ce->buffer, (gpointer) buffer_notify_highlight_syntax_cb, ce); - if (ce->priv->first_update != 0) - g_source_remove (ce->priv->first_update); - if (ce->priv->incremental_update != 0) - g_source_remove (ce->priv->incremental_update); - ce->priv->first_update = 0; - ce->priv->incremental_update = 0; - - if (ce->priv->root_segment != NULL) - segment_destroy (ce, ce->priv->root_segment); - if (ce->priv->root_context != NULL) - context_unref (ce->priv->root_context); - g_assert (!ce->priv->invalid); - g_slist_free (ce->priv->invalid); - ce->priv->root_segment = NULL; - ce->priv->root_context = NULL; - ce->priv->invalid = NULL; - - if (ce->priv->invalid_region.start != NULL) - gtk_text_buffer_delete_mark (ce->priv->buffer, - ce->priv->invalid_region.start); - if (ce->priv->invalid_region.end != NULL) - gtk_text_buffer_delete_mark (ce->priv->buffer, - ce->priv->invalid_region.end); - ce->priv->invalid_region.start = NULL; - ce->priv->invalid_region.end = NULL; + if (ce->first_update != 0) + g_source_remove (ce->first_update); + if (ce->incremental_update != 0) + g_source_remove (ce->incremental_update); + ce->first_update = 0; + ce->incremental_update = 0; + + if (ce->root_segment != NULL) + segment_destroy (ce, ce->root_segment); + if (ce->root_context != NULL) + context_unref (ce->root_context); + g_assert (!ce->invalid); + g_slist_free (ce->invalid); + ce->root_segment = NULL; + ce->root_context = NULL; + ce->invalid = NULL; + + if (ce->invalid_region.start != NULL) + gtk_text_buffer_delete_mark (ce->buffer, + ce->invalid_region.start); + if (ce->invalid_region.end != NULL) + gtk_text_buffer_delete_mark (ce->buffer, + ce->invalid_region.end); + ce->invalid_region.start = NULL; + ce->invalid_region.end = NULL; /* this deletes tags from the tag table, therefore there is no need * in removing tags from the text (it may be very slow). @@ -2554,51 +2551,51 @@ gtk_source_context_engine_attach_buffer (GtkSourceEngine *engine, * nothing. Caveat: if tag table is shared with other buffer, we do * need to remove tags. */ destroy_tags_hash (ce); - ce->priv->n_tags = 0; + ce->n_tags = 0; destroy_context_classes_list (ce); - g_clear_object (&ce->priv->refresh_region); + g_clear_object (&ce->refresh_region); } - ce->priv->buffer = buffer; + ce->buffer = buffer; if (buffer != NULL) { ContextDefinition *main_definition; GtkTextIter start, end; - main_definition = gtk_source_context_data_lookup_root (ce->priv->ctx_data); + main_definition = gtk_source_context_data_lookup_root (ce->ctx_data); /* If we don't abort here, we will crash later (#485661). But it should * never happen, _gtk_source_context_data_finish_parse checks main context. */ g_assert (main_definition != NULL); - ce->priv->root_context = context_new (NULL, main_definition, NULL, NULL, FALSE); - ce->priv->root_segment = create_segment (ce, NULL, ce->priv->root_context, 0, 0, TRUE, NULL); + ce->root_context = context_new (NULL, main_definition, NULL, NULL, FALSE); + ce->root_segment = create_segment (ce, NULL, ce->root_context, 0, 0, TRUE, NULL); - ce->priv->tags = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); - ce->priv->context_classes = NULL; + ce->tags = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); + ce->context_classes = NULL; gtk_text_buffer_get_bounds (buffer, &start, &end); - ce->priv->invalid_region.start = gtk_text_buffer_create_mark (buffer, NULL, + ce->invalid_region.start = gtk_text_buffer_create_mark (buffer, NULL, &start, TRUE); - ce->priv->invalid_region.end = gtk_text_buffer_create_mark (buffer, NULL, + ce->invalid_region.end = gtk_text_buffer_create_mark (buffer, NULL, &end, FALSE); if (gtk_text_buffer_get_char_count (buffer) != 0) { - ce->priv->invalid_region.empty = FALSE; - ce->priv->invalid_region.delta = gtk_text_buffer_get_char_count (buffer); + ce->invalid_region.empty = FALSE; + ce->invalid_region.delta = gtk_text_buffer_get_char_count (buffer); } else { - ce->priv->invalid_region.empty = TRUE; - ce->priv->invalid_region.delta = 0; + ce->invalid_region.empty = TRUE; + ce->invalid_region.delta = 0; } - g_object_get (buffer, "highlight-syntax", &ce->priv->highlight, NULL); - ce->priv->refresh_region = gtk_source_region_new (buffer); + g_object_get (buffer, "highlight-syntax", &ce->highlight, NULL); + ce->refresh_region = gtk_source_region_new (buffer); g_signal_connect_swapped (buffer, "notify::highlight-syntax", @@ -2620,9 +2617,9 @@ gtk_source_context_engine_attach_buffer (GtkSourceEngine *engine, static void disable_syntax_analysis (GtkSourceContextEngine *ce) { - if (!ce->priv->disabled) + if (!ce->disabled) { - ce->priv->disabled = TRUE; + ce->disabled = TRUE; gtk_source_context_engine_attach_buffer (GTK_SOURCE_ENGINE (ce), NULL); /* FIXME maybe emit some signal here? */ } @@ -2630,8 +2627,8 @@ disable_syntax_analysis (GtkSourceContextEngine *ce) static void set_tag_style_hash_cb (const char *style, - GSList *tags, - GtkSourceContextEngine *ce) + GSList *tags, + GtkSourceContextEngine *ce) { while (tags != NULL) { @@ -2650,7 +2647,7 @@ set_tag_style_hash_cb (const char *style, */ static void gtk_source_context_engine_set_style_scheme (GtkSourceEngine *engine, - GtkSourceStyleScheme *scheme) + GtkSourceStyleScheme *scheme) { GtkSourceContextEngine *ce; @@ -2659,9 +2656,9 @@ gtk_source_context_engine_set_style_scheme (GtkSourceEngine *engine, ce = GTK_SOURCE_CONTEXT_ENGINE (engine); - if (g_set_object (&ce->priv->style_scheme, scheme)) + if (g_set_object (&ce->style_scheme, scheme)) { - g_hash_table_foreach (ce->priv->tags, (GHFunc) set_tag_style_hash_cb, ce); + g_hash_table_foreach (ce->tags, (GHFunc) set_tag_style_hash_cb, ce); } } @@ -2670,7 +2667,7 @@ gtk_source_context_engine_finalize (GObject *object) { GtkSourceContextEngine *ce = GTK_SOURCE_CONTEXT_ENGINE (object); - if (ce->priv->buffer != NULL) + if (ce->buffer != NULL) { g_critical ("finalizing engine with attached buffer"); /* Disconnect the buffer (if there is one), which destroys almost @@ -2678,26 +2675,26 @@ gtk_source_context_engine_finalize (GObject *object) gtk_source_context_engine_attach_buffer (GTK_SOURCE_ENGINE (ce), NULL); } - g_assert (!ce->priv->tags); - g_assert (!ce->priv->root_context); - g_assert (!ce->priv->root_segment); + g_assert (!ce->tags); + g_assert (!ce->root_context); + g_assert (!ce->root_segment); - if (ce->priv->first_update != 0) + if (ce->first_update != 0) { - g_source_remove (ce->priv->first_update); - ce->priv->first_update = 0; + g_source_remove (ce->first_update); + ce->first_update = 0; } - if (ce->priv->incremental_update != 0) + if (ce->incremental_update != 0) { - g_source_remove (ce->priv->incremental_update); - ce->priv->incremental_update = 0; + g_source_remove (ce->incremental_update); + ce->incremental_update = 0; } - _gtk_source_context_data_unref (ce->priv->ctx_data); + _gtk_source_context_data_unref (ce->ctx_data); - if (ce->priv->style_scheme != NULL) - g_object_unref (ce->priv->style_scheme); + if (ce->style_scheme != NULL) + g_object_unref (ce->style_scheme); G_OBJECT_CLASS (_gtk_source_context_engine_parent_class)->finalize (object); } @@ -2723,7 +2720,7 @@ _gtk_source_context_engine_class_init (GtkSourceContextEngineClass *klass) static void _gtk_source_context_engine_init (GtkSourceContextEngine *ce) { - ce->priv = _gtk_source_context_engine_get_instance_private (ce); + ce = _gtk_source_context_engine_get_instance_private (ce); } GtkSourceContextEngine * @@ -2735,7 +2732,7 @@ _gtk_source_context_engine_new (GtkSourceContextData *ctx_data) g_return_val_if_fail (ctx_data->lang != NULL, NULL); ce = g_object_new (GTK_SOURCE_TYPE_CONTEXT_ENGINE, NULL); - ce->priv->ctx_data = _gtk_source_context_data_ref (ctx_data); + ce->ctx_data = _gtk_source_context_data_ref (ctx_data); return ce; } @@ -2744,7 +2741,7 @@ _gtk_source_context_engine_new (GtkSourceContextData *ctx_data) * _gtk_source_context_data_new: * @lang: #GtkSourceLanguage. * - * Creates new context definition set. It does not set lang->priv->ctx_data, + * Creates new context definition set. It does not set lang->ctx_data, * that's lang business. */ GtkSourceContextData * @@ -2776,7 +2773,7 @@ _gtk_source_context_data_ref (GtkSourceContextData *ctx_data) * @ctx_data: #GtkSourceContextData. * * Decreases reference count in ctx_data. When reference count - * drops to zero, ctx_data is freed, and ctx_data->lang->priv->ctx_data + * drops to zero, ctx_data is freed, and ctx_data->lang->ctx_data * is unset. */ void @@ -2786,9 +2783,8 @@ _gtk_source_context_data_unref (GtkSourceContextData *ctx_data) if (--ctx_data->ref_count == 0) { - if (ctx_data->lang != NULL && ctx_data->lang->priv != NULL && - ctx_data->lang->priv->ctx_data == ctx_data) - ctx_data->lang->priv->ctx_data = NULL; + if (ctx_data->lang != NULL) + _gtk_source_language_clear_ctx_data (ctx_data->lang, ctx_data); g_hash_table_destroy (ctx_data->definitions); g_slice_free (GtkSourceContextData, ctx_data); } @@ -2810,9 +2806,9 @@ _gtk_source_context_data_unref (GtkSourceContextData *ctx_data) */ static void apply_sub_patterns (Segment *state, - LineInfo *line, - GtkSourceRegex *regex, - SubPatternWhere where) + LineInfo *line, + GtkSourceRegex *regex, + SubPatternWhere where) { GSList *sub_pattern_list = state->context->definition->sub_patterns; @@ -2897,10 +2893,10 @@ apply_sub_patterns (Segment *state, */ static gboolean can_apply_match (Context *state, - LineInfo *line, - gint match_start, - gint *match_end, - GtkSourceRegex *regex) + LineInfo *line, + gint match_start, + gint *match_end, + GtkSourceRegex *regex) { gint end_match_pos; gboolean ancestor_ends; @@ -2958,7 +2954,7 @@ can_apply_match (Context *state, static gint line_pos_to_offset (LineInfo *line, - gint pos) + gint pos) { if (line->char_length != line->byte_length) pos = g_utf8_pointer_to_offset (line->text, line->text + pos); @@ -2985,10 +2981,10 @@ line_pos_to_offset (LineInfo *line, */ static gboolean apply_match (Segment *state, - LineInfo *line, - gint *line_pos, - GtkSourceRegex *regex, - SubPatternWhere where) + LineInfo *line, + gint *line_pos, + GtkSourceRegex *regex, + SubPatternWhere where) { gint match_end; @@ -3023,7 +3019,7 @@ apply_match (Segment *state, */ static GtkSourceRegex * create_reg_all (Context *context, - ContextDefinition *definition) + ContextDefinition *definition) { DefinitionsIter iter; DefinitionChild *child_def; @@ -3158,10 +3154,10 @@ context_ref (Context *context) /* does not copy style */ static Context * context_new (Context *parent, - ContextDefinition *definition, - const gchar *line_text, - const gchar *style, - gboolean ignore_children_style) + ContextDefinition *definition, + const gchar *line_text, + const gchar *style, + gboolean ignore_children_style) { Context *context; @@ -3229,8 +3225,8 @@ context_new (Context *parent, static void context_unref_hash_cb (gpointer text, - Context *context, - gpointer user_data) + Context *context, + gpointer user_data) { context->parent = NULL; context_unref (context); @@ -3238,15 +3234,15 @@ context_unref_hash_cb (gpointer text, static gboolean remove_context_cb (G_GNUC_UNUSED gpointer text, - Context *context, - Context *target) + Context *context, + Context *target) { return context == target; } static void context_remove_child (Context *parent, - Context *context) + Context *context) { ContextPtr *ptr, *prev = NULL; gboolean delete = TRUE; @@ -3362,8 +3358,8 @@ context_unref (Context *context) static void context_freeze_hash_cb (gpointer text, - Context *context, - gpointer user_data) + Context *context, + gpointer user_data) { context_freeze (context); } @@ -3412,15 +3408,15 @@ context_freeze (Context *ctx) static void get_child_contexts_hash_cb (G_GNUC_UNUSED gpointer text, - Context *context, - GSList **list) + Context *context, + GSList **list) { *list = g_slist_prepend (*list, context); } static void -context_thaw_cb (Context *ctx, - gpointer user_data) +context_thaw_cb (Context *ctx, + gpointer user_data) { context_thaw (ctx); } @@ -3469,8 +3465,8 @@ context_thaw (Context *ctx) static Context * create_child_context (Context *parent, - DefinitionChild *child_def, - const gchar *line_text) + DefinitionChild *child_def, + const gchar *line_text) { Context *context; ContextPtr *ptr; @@ -3551,11 +3547,11 @@ create_child_context (Context *parent, */ static Segment * segment_new (GtkSourceContextEngine *ce, - Segment *parent, - Context *context, - gint start_at, - gint end_at, - gboolean is_start) + Segment *parent, + Context *context, + gint start_at, + gint end_at, + gboolean is_start) { Segment *segment; @@ -3578,10 +3574,10 @@ segment_new (GtkSourceContextEngine *ce, static void find_segment_position_forward_ (Segment *segment, - gint start_at, - gint end_at, - Segment **prev, - Segment **next) + gint start_at, + gint end_at, + Segment **prev, + Segment **next) { g_assert (segment->start_at <= start_at); @@ -3620,10 +3616,10 @@ find_segment_position_forward_ (Segment *segment, static void find_segment_position_backward_ (Segment *segment, - gint start_at, - gint end_at, - Segment **prev, - Segment **next) + gint start_at, + gint end_at, + Segment **prev, + Segment **next) { g_assert (start_at < segment->end_at); @@ -3657,11 +3653,11 @@ find_segment_position_backward_ (Segment *segment, */ static void find_segment_position (Segment *parent, - Segment *hint, - gint start_at, - gint end_at, - Segment **prev, - Segment **next) + Segment *hint, + gint start_at, + gint end_at, + Segment **prev, + Segment **next) { Segment *tmp; @@ -3710,12 +3706,12 @@ find_segment_position (Segment *parent, */ static Segment * create_segment (GtkSourceContextEngine *ce, - Segment *parent, - Context *context, - gint start_at, - gint end_at, - gboolean is_start, - Segment *hint) + Segment *parent, + Context *context, + gint start_at, + gint end_at, + gboolean is_start, + Segment *hint) { Segment *segment; @@ -3729,7 +3725,7 @@ create_segment (GtkSourceContextEngine *ce, if (hint == NULL) { - hint = ce->priv->hint; + hint = ce->hint; while (hint != NULL && hint->parent != parent) hint = hint->parent; } @@ -3772,7 +3768,7 @@ create_segment (GtkSourceContextEngine *ce, */ static void segment_extend (Segment *state, - gint end_at) + gint end_at) { while (state != NULL && state->end_at < end_at) { @@ -3784,7 +3780,7 @@ segment_extend (Segment *state, static void segment_destroy_children (GtkSourceContextEngine *ce, - Segment *segment) + Segment *segment) { Segment *child; SubPattern *sp; @@ -3825,7 +3821,7 @@ segment_destroy_children (GtkSourceContextEngine *ce, */ static void segment_destroy (GtkSourceContextEngine *ce, - Segment *segment) + Segment *segment) { g_return_if_fail (segment != NULL); @@ -3833,10 +3829,10 @@ segment_destroy (GtkSourceContextEngine *ce, /* segment neighbours and parent may be invalid here, * so we only can unset the hint */ - if (ce->priv->hint == segment) - ce->priv->hint = NULL; - if (ce->priv->hint2 == segment) - ce->priv->hint2 = NULL; + if (ce->hint == segment) + ce->hint = NULL; + if (ce->hint2 == segment) + ce->hint2 = NULL; if (SEGMENT_IS_INVALID (segment)) remove_invalid (ce, segment); @@ -3844,7 +3840,7 @@ segment_destroy (GtkSourceContextEngine *ce, context_unref (segment->context); #ifdef ENABLE_DEBUG - g_assert (!g_slist_find (ce->priv->invalid, segment)); + g_assert (!g_slist_find (ce->invalid, segment)); memset (segment, 1, sizeof (Segment)); #else g_slice_free (Segment, segment); @@ -3858,11 +3854,11 @@ segment_destroy (GtkSourceContextEngine *ce, */ static gboolean container_context_starts_here (GtkSourceContextEngine *ce, - Segment *state, - DefinitionChild *child_def, - LineInfo *line, - gint *line_pos, /* bytes */ - Segment **new_state) + Segment *state, + DefinitionChild *child_def, + LineInfo *line, + gint *line_pos, /* bytes */ + Segment **new_state) { Context *new_context; Segment *new_segment; @@ -3899,7 +3895,7 @@ container_context_starts_here (GtkSourceContextEngine *ce, line_pos_to_offset (line, *line_pos), line_pos_to_offset (line, match_end), TRUE, - ce->priv->hint2); + ce->hint2); /* This new context could end at the same position (i.e. have zero length), * and then we get an infinite loop. We can't possibly know about it at this point @@ -3922,7 +3918,7 @@ container_context_starts_here (GtkSourceContextEngine *ce, SUB_PATTERN_WHERE_START); *line_pos = match_end; *new_state = new_segment; - ce->priv->hint2 = NULL; + ce->hint2 = NULL; context_unref (new_context); return TRUE; } @@ -3933,12 +3929,12 @@ container_context_starts_here (GtkSourceContextEngine *ce, * See child_starts_here(). */ static gboolean -simple_context_starts_here (GtkSourceContextEngine *ce, - Segment *state, - DefinitionChild *child_def, - LineInfo *line, - gint *line_pos, /* bytes */ - Segment **new_state) +simple_context_starts_here (GtkSourceContextEngine *ce, + Segment *state, + DefinitionChild *child_def, + LineInfo *line, + gint *line_pos, /* bytes */ + Segment **new_state) { gint match_end; Context *new_context; @@ -3990,9 +3986,9 @@ simple_context_starts_here (GtkSourceContextEngine *ce, line_pos_to_offset (line, *line_pos), line_pos_to_offset (line, match_end), TRUE, - ce->priv->hint2); + ce->hint2); apply_sub_patterns (new_segment, line, definition->u.match, SUB_PATTERN_WHERE_DEFAULT); - ce->priv->hint2 = new_segment; + ce->hint2 = new_segment; } /* Terminate parent if needed */ @@ -4000,7 +3996,7 @@ simple_context_starts_here (GtkSourceContextEngine *ce, { do { - ce->priv->hint2 = state; + ce->hint2 = state; state = state->parent; } while (SEGMENT_ENDS_PARENT (state)); @@ -4029,11 +4025,11 @@ simple_context_starts_here (GtkSourceContextEngine *ce, */ static gboolean child_starts_here (GtkSourceContextEngine *ce, - Segment *state, - DefinitionChild *child_def, - LineInfo *line, - gint *line_pos, - Segment **new_state) + Segment *state, + DefinitionChild *child_def, + LineInfo *line, + gint *line_pos, + Segment **new_state) { g_return_val_if_fail (child_def->resolved, FALSE); @@ -4070,8 +4066,8 @@ child_starts_here (GtkSourceContextEngine *ce, */ static gboolean segment_ends_here (Segment *state, - LineInfo *line, - gint pos) + LineInfo *line, + gint pos) { g_assert (SEGMENT_IS_CONTAINER (state)); @@ -4096,8 +4092,8 @@ segment_ends_here (Segment *state, */ static Context * ancestor_context_ends_here (Context *state, - LineInfo *line, - gint line_pos) + LineInfo *line, + gint line_pos) { Context *current_context; GSList *current_context_list; @@ -4159,9 +4155,9 @@ ancestor_context_ends_here (Context *state, */ static gboolean ancestor_ends_here (Segment *state, - LineInfo *line, - gint line_pos, - Segment **new_state) + LineInfo *line, + gint line_pos, + Segment **new_state) { Context *terminating_context; @@ -4200,14 +4196,14 @@ ancestor_ends_here (Segment *state, */ static gboolean next_segment (GtkSourceContextEngine *ce, - Segment *state, - LineInfo *line, - gint *line_pos, - Segment **new_state) + Segment *state, + LineInfo *line, + gint *line_pos, + Segment **new_state) { gint pos = *line_pos; - g_assert (!ce->priv->hint2 || ce->priv->hint2->parent == state); + g_assert (!ce->hint2 || ce->hint2->parent == state); g_assert (pos <= line->byte_length); while (pos <= line->byte_length) @@ -4310,7 +4306,7 @@ next_segment (GtkSourceContextEngine *ce, state = state->parent; *new_state = state->parent; - ce->priv->hint2 = state; + ce->hint2 = state; *line_pos = pos; return TRUE; } @@ -4335,12 +4331,12 @@ next_segment (GtkSourceContextEngine *ce, */ static Segment * check_line_end (GtkSourceContextEngine *ce, - Segment *state) + Segment *state) { Segment *current_segment; Segment *terminating_segment; - g_assert (!ce->priv->hint2 || ce->priv->hint2->parent == state); + g_assert (!ce->hint2 || ce->hint2->parent == state); /* A context can be terminated by the parent if extend_parent is * FALSE, so we need to verify the end of all the parents of @@ -4359,7 +4355,7 @@ check_line_end (GtkSourceContextEngine *ce, if (terminating_segment != NULL) { - ce->priv->hint2 = terminating_segment; + ce->hint2 = terminating_segment; return terminating_segment->parent; } else @@ -4370,7 +4366,7 @@ check_line_end (GtkSourceContextEngine *ce, static void delete_zero_length_segments (GtkSourceContextEngine *ce, - GList *list) + GList *list) { while (list != NULL) { @@ -4403,9 +4399,9 @@ delete_zero_length_segments (GtkSourceContextEngine *ce, l = next; } - if (ce->priv->hint2 != NULL) + if (ce->hint2 != NULL) { - Segment *s2 = ce->priv->hint2; + Segment *s2 = ce->hint2; gboolean child = FALSE; while (s2 != NULL) @@ -4420,7 +4416,7 @@ delete_zero_length_segments (GtkSourceContextEngine *ce, } if (child) - ce->priv->hint2 = s->parent; + ce->hint2 = s->parent; } segment_remove (ce, s); @@ -4443,8 +4439,8 @@ delete_zero_length_segments (GtkSourceContextEngine *ce, */ static Segment * analyze_line (GtkSourceContextEngine *ce, - Segment *state, - LineInfo *line) + Segment *state, + LineInfo *line) { gint line_pos = 0; GList *end_segments = NULL; @@ -4452,9 +4448,9 @@ analyze_line (GtkSourceContextEngine *ce, g_assert (SEGMENT_IS_CONTAINER (state)); - if (ce->priv->hint2 == NULL || ce->priv->hint2->parent != state) - ce->priv->hint2 = state->last_child; - g_assert (!ce->priv->hint2 || ce->priv->hint2->parent == state); + if (ce->hint2 == NULL || ce->hint2->parent != state) + ce->hint2 = state->last_child; + g_assert (!ce->hint2 || ce->hint2->parent == state); timer = g_timer_new (); @@ -4480,9 +4476,9 @@ analyze_line (GtkSourceContextEngine *ce, state = new_state; - if (ce->priv->hint2 == NULL || ce->priv->hint2->parent != state) - ce->priv->hint2 = state->last_child; - g_assert (!ce->priv->hint2 || ce->priv->hint2->parent == state); + if (ce->hint2 == NULL || ce->hint2->parent != state) + ce->hint2 = state->last_child; + g_assert (!ce->hint2 || ce->hint2->parent == state); /* XXX this a temporary workaround for zero-length segments in the end * of line. there are no zero-length segments in the middle because it goes @@ -4494,7 +4490,7 @@ analyze_line (GtkSourceContextEngine *ce, } g_timer_destroy (timer); - if (ce->priv->disabled) + if (ce->disabled) return NULL; /* Extend current state to the end of line. */ @@ -4537,9 +4533,9 @@ analyze_line (GtkSourceContextEngine *ce, */ static void get_line_info (GtkTextBuffer *buffer, - const GtkTextIter *line_start, - const GtkTextIter *line_end, - LineInfo *line) + const GtkTextIter *line_start, + const GtkTextIter *line_end, + LineInfo *line) { g_assert (!gtk_text_iter_equal (line_start, line_end)); @@ -4594,7 +4590,7 @@ line_info_destroy (LineInfo *line) static void segment_tree_zero_len (GtkSourceContextEngine *ce) { - Segment *root = ce->priv->root_segment; + Segment *root = ce->root_segment; segment_destroy_children (ce, root); root->start_at = root->end_at = 0; CHECK_TREE (ce); @@ -4603,7 +4599,7 @@ segment_tree_zero_len (GtkSourceContextEngine *ce) #ifdef ENABLE_CHECK_TREE static Segment * get_segment_at_offset_slow_ (Segment *segment, - gint offset) + gint offset) { Segment *child; @@ -4673,7 +4669,7 @@ start: #define SEGMENT_DISTANCE(s,o) (MIN (ABS ((s)->start_at - (o)), ABS ((s)->end_at - (o)))) static Segment * get_segment_in_ (Segment *segment, - gint offset) + gint offset) { Segment *child; @@ -4735,7 +4731,7 @@ get_segment_in_ (Segment *segment, /* assumes zero-length segments can't have children */ static Segment * get_segment_ (Segment *segment, - gint offset) + gint offset) { if (segment->parent != NULL) { @@ -4827,26 +4823,26 @@ get_segment_ (Segment *segment, */ static Segment * get_segment_at_offset (GtkSourceContextEngine *ce, - Segment *hint, - gint offset) + Segment *hint, + gint offset) { Segment *result; - if (offset == ce->priv->root_segment->end_at) - return ce->priv->root_segment; + if (offset == ce->root_segment->end_at) + return ce->root_segment; #ifdef ENABLE_DEBUG /* if you see this message (often), then something is * wrong with the hints business, i.e. optimizations * do not work quite like they should */ - if (hint == NULL || hint == ce->priv->root_segment) + if (hint == NULL || hint == ce->root_segment) { static int c; g_print ("searching from root %d\n", ++c); } #endif - result = get_segment_ (hint ? hint : ce->priv->root_segment, offset); + result = get_segment_ (hint ? hint : ce->root_segment, offset); #ifdef ENABLE_CHECK_TREE g_assert (result == get_segment_at_offset_slow_ (hint, offset)); @@ -4867,7 +4863,7 @@ get_segment_at_offset (GtkSourceContextEngine *ce, */ static void segment_remove (GtkSourceContextEngine *ce, - Segment *segment) + Segment *segment) { if (segment->next != NULL) segment->next->prev = segment->prev; @@ -4879,28 +4875,28 @@ segment_remove (GtkSourceContextEngine *ce, else segment->parent->children = segment->next; - /* if ce->priv->hint is being deleted, set it to some + /* if ce->hint is being deleted, set it to some * neighbour segment */ - if (ce->priv->hint == segment) + if (ce->hint == segment) { if (segment->next != NULL) - ce->priv->hint = segment->next; + ce->hint = segment->next; else if (segment->prev != NULL) - ce->priv->hint = segment->prev; + ce->hint = segment->prev; else - ce->priv->hint = segment->parent; + ce->hint = segment->parent; } - /* if ce->priv->hint2 is being deleted, set it to some + /* if ce->hint2 is being deleted, set it to some * neighbour segment */ - if (ce->priv->hint2 == segment) + if (ce->hint2 == segment) { if (segment->next != NULL) - ce->priv->hint2 = segment->next; + ce->hint2 = segment->next; else if (segment->prev != NULL) - ce->priv->hint2 = segment->prev; + ce->hint2 = segment->prev; else - ce->priv->hint2 = segment->parent; + ce->hint2 = segment->parent; } segment_destroy (ce, segment); @@ -4908,9 +4904,9 @@ segment_remove (GtkSourceContextEngine *ce, static void segment_erase_middle_ (GtkSourceContextEngine *ce, - Segment *segment, - gint start, - gint end) + Segment *segment, + gint start, + gint end) { Segment *new_segment, *child; SubPattern *sp; @@ -5018,9 +5014,9 @@ segment_erase_middle_ (GtkSourceContextEngine *ce, */ static void segment_erase_range_ (GtkSourceContextEngine *ce, - Segment *segment, - gint start, - gint end) + Segment *segment, + gint start, + gint end) { g_assert (start < end); @@ -5134,8 +5130,8 @@ segment_erase_range_ (GtkSourceContextEngine *ce, */ static void segment_merge (GtkSourceContextEngine *ce, - Segment *first, - Segment *second) + Segment *first, + Segment *second) { Segment *parent; @@ -5218,26 +5214,26 @@ segment_merge (GtkSourceContextEngine *ce, * * Erases all non-toplevel segments in the interval * [@start, @end]. Its action on the tree is roughly - * equivalent to segment_erase_range_(ce->priv->root_segment, start, end) + * equivalent to segment_erase_range_(ce->root_segment, start, end) * (but that does not accept toplevel segment). */ static void erase_segments (GtkSourceContextEngine *ce, - gint start, - gint end, - Segment *hint) + gint start, + gint end, + Segment *hint) { - Segment *root = ce->priv->root_segment; + Segment *root = ce->root_segment; Segment *child, *hint_prev; if (root->children == NULL) return; if (hint == NULL) - hint = ce->priv->hint; + hint = ce->hint; if (hint != NULL) - while (hint != NULL && hint->parent != ce->priv->root_segment) + while (hint != NULL && hint->parent != ce->root_segment) hint = hint->parent; if (hint == NULL) @@ -5255,14 +5251,14 @@ erase_segments (GtkSourceContextEngine *ce, child = next; if (next != NULL) - ce->priv->hint = next; + ce->hint = next; continue; } if (child->start_at > end) { - ce->priv->hint = child; + ce->hint = child; break; } @@ -5275,8 +5271,8 @@ erase_segments (GtkSourceContextEngine *ce, { Segment *prev = child->prev; - if (ce->priv->hint == NULL) - ce->priv->hint = child; + if (ce->hint == NULL) + ce->hint = child; if (child->start_at > end) { @@ -5316,8 +5312,8 @@ erase_segments (GtkSourceContextEngine *ce, /* TODO it must be refactored. */ static void update_syntax (GtkSourceContextEngine *ce, - const GtkTextIter *end, - gint time) + const GtkTextIter *end, + gint time) { GtkTextBuffer *buffer; GtkTextIter start_iter, end_iter; @@ -5330,10 +5326,10 @@ update_syntax (GtkSourceContextEngine *ce, gboolean first_line = FALSE; GTimer *timer; - buffer = ce->priv->buffer; - state = ce->priv->root_segment; + buffer = ce->buffer; + state = ce->root_segment; - context_freeze (ce->priv->root_context); + context_freeze (ce->root_context); update_tree (ce); if (!gtk_text_buffer_get_char_count (buffer)) @@ -5398,7 +5394,7 @@ update_syntax (GtkSourceContextEngine *ce, if (start_offset == end_offset) { g_assert (end_offset == gtk_text_buffer_get_char_count (buffer)); - g_assert (g_slist_length (ce->priv->invalid) == 1); + g_assert (g_slist_length (ce->invalid) == 1); segment_remove (ce, invalid); CHECK_TREE (ce); goto out; @@ -5430,7 +5426,7 @@ update_syntax (GtkSourceContextEngine *ce, } /* Analyze the line */ - erase_segments (ce, line_start_offset, line_end_offset, ce->priv->hint); + erase_segments (ce, line_start_offset, line_end_offset, ce->hint); get_line_info (buffer, &line_start, &line_end, &line); #ifdef ENABLE_CHECK_TREE @@ -5442,26 +5438,26 @@ update_syntax (GtkSourceContextEngine *ce, if (first_line) { - state = ce->priv->root_segment; + state = ce->root_segment; } else { state = get_segment_at_offset (ce, - ce->priv->hint ? ce->priv->hint : state, + ce->hint ? ce->hint : state, line_start_offset - 1); } g_assert (state->context != NULL); - ce->priv->hint2 = ce->priv->hint; + ce->hint2 = ce->hint; - if (ce->priv->hint2 != NULL && ce->priv->hint2->parent != state) - ce->priv->hint2 = NULL; + if (ce->hint2 != NULL && ce->hint2->parent != state) + ce->hint2 = NULL; state = analyze_line (ce, state, &line); /* At this point analyze_line() could have disabled highlighting */ - if (ce->priv->disabled) + if (ce->disabled) return; #ifdef ENABLE_CHECK_TREE @@ -5474,14 +5470,14 @@ update_syntax (GtkSourceContextEngine *ce, /* XXX this is wrong */ /* I don't know anymore why it's wrong, I guess it means * "may be inefficient" */ - if (ce->priv->hint2 != NULL) - ce->priv->hint = ce->priv->hint2; + if (ce->hint2 != NULL) + ce->hint = ce->hint2; else - ce->priv->hint = state; + ce->hint = state; line_info_destroy (&line); - gtk_source_region_add_subregion (ce->priv->refresh_region, &line_start, &line_end); + gtk_source_region_add_subregion (ce->refresh_region, &line_start, &line_end); analyzed_end = line_end_offset; invalid = get_invalid_segment (ce); @@ -5500,7 +5496,7 @@ update_syntax (GtkSourceContextEngine *ce, { Segment *old_state, *hint; - hint = ce->priv->hint ? ce->priv->hint : state; + hint = ce->hint ? ce->hint : state; old_state = get_segment_at_offset (ce, hint, line_end_offset); /* We can merge old and new stuff if: contexts are the same, @@ -5550,9 +5546,9 @@ update_syntax (GtkSourceContextEngine *ce, if (analyzed_end == gtk_text_buffer_get_char_count (buffer)) { - g_assert (g_slist_length (ce->priv->invalid) <= 1); + g_assert (g_slist_length (ce->invalid) <= 1); - if (ce->priv->invalid != NULL) + if (ce->invalid != NULL) { invalid = get_invalid_segment (ce); segment_remove (ce, invalid); @@ -5575,7 +5571,7 @@ update_syntax (GtkSourceContextEngine *ce, out: /* must call context_thaw, so this is the only return point */ - context_thaw (ce->priv->root_context); + context_thaw (ce->root_context); } @@ -5583,11 +5579,11 @@ out: static DefinitionChild * definition_child_new (ContextDefinition *definition, - const gchar *child_id, - const gchar *style, - gboolean override_style, - gboolean is_ref_all, - gboolean original_ref) + const gchar *child_id, + const gchar *style, + gboolean override_style, + gboolean is_ref_all, + gboolean original_ref) { DefinitionChild *ch; @@ -5641,14 +5637,14 @@ copy_context_classes (GSList *context_classes) static ContextDefinition * context_definition_new (const gchar *id, - ContextType type, - const gchar *match, - const gchar *start, - const gchar *end, - const gchar *style, - GSList *context_classes, - GtkSourceContextFlags flags, - GError **error) + ContextType type, + const gchar *match, + const gchar *start, + const gchar *end, + const gchar *style, + GSList *context_classes, + GtkSourceContextFlags flags, + GError **error) { ContextDefinition *definition; gboolean regex_error = FALSE; @@ -5805,7 +5801,7 @@ context_definition_unref (ContextDefinition *definition) static void definition_iter_init (DefinitionsIter *iter, - ContextDefinition *definition) + ContextDefinition *definition) { iter->children_stack = g_slist_prepend (NULL, definition->children); } @@ -5856,15 +5852,15 @@ definition_iter_next (DefinitionsIter *iter) gboolean _gtk_source_context_data_define_context (GtkSourceContextData *ctx_data, - const gchar *id, - const gchar *parent_id, - const gchar *match_regex, - const gchar *start_regex, - const gchar *end_regex, - const gchar *style, - GSList *context_classes, - GtkSourceContextFlags flags, - GError **error) + const gchar *id, + const gchar *parent_id, + const gchar *match_regex, + const gchar *start_regex, + const gchar *end_regex, + const gchar *style, + GSList *context_classes, + GtkSourceContextFlags flags, + GError **error) { ContextDefinition *definition, *parent = NULL; ContextType type; @@ -5946,13 +5942,13 @@ _gtk_source_context_data_define_context (GtkSourceContextData *ctx_data, gboolean _gtk_source_context_data_add_sub_pattern (GtkSourceContextData *ctx_data, - const gchar *id, - const gchar *parent_id, - const gchar *name, - const gchar *where, - const gchar *style, - GSList *context_classes, - GError **error) + const gchar *id, + const gchar *parent_id, + const gchar *name, + const gchar *where, + const gchar *style, + GSList *context_classes, + GError **error) { ContextDefinition *parent; SubPatternDefinition *sp_def; @@ -6049,12 +6045,12 @@ context_is_pure_container (ContextDefinition *def) gboolean _gtk_source_context_data_add_ref (GtkSourceContextData *ctx_data, - const gchar *parent_id, - const gchar *ref_id, - GtkSourceContextRefOptions options, - const gchar *style, - gboolean all, - GError **error) + const gchar *parent_id, + const gchar *ref_id, + GtkSourceContextRefOptions options, + const gchar *style, + gboolean all, + GError **error) { ContextDefinition *parent; ContextDefinition *ref; @@ -6088,7 +6084,7 @@ _gtk_source_context_data_add_ref (GtkSourceContextData *ctx_data, GTK_SOURCE_CONTEXT_ENGINE_ERROR_INVALID_STYLE, _("style override used with wildcard context reference" " in language “%s” in ref “%s”"), - ctx_data->lang->priv->id, ref_id); + gtk_source_language_get_id (ctx_data->lang), ref_id); return FALSE; } @@ -6114,8 +6110,8 @@ struct ResolveRefData { static void resolve_reference (G_GNUC_UNUSED const gchar *id, - ContextDefinition *definition, - gpointer user_data) + ContextDefinition *definition, + gpointer user_data) { GSList *l; @@ -6148,7 +6144,7 @@ resolve_reference (G_GNUC_UNUSED const gchar *id, GTK_SOURCE_CONTEXT_ENGINE_ERROR_INVALID_STYLE, _("style override used with wildcard context reference" " in language “%s” in ref “%s”"), - data->ctx_data->lang->priv->id, ref->id); + gtk_source_language_get_id (data->ctx_data->lang), ref->id); } else { @@ -6167,9 +6163,9 @@ resolve_reference (G_GNUC_UNUSED const gchar *id, static gboolean process_replace (GtkSourceContextData *ctx_data, - const gchar *id, - const gchar *replace_with, - GError **error) + const gchar *id, + const gchar *replace_with, + GError **error) { ContextDefinition *to_replace, *new; @@ -6199,8 +6195,8 @@ process_replace (GtkSourceContextData *ctx_data, } GtkSourceContextReplace * -_gtk_source_context_replace_new (const gchar *to_replace_id, - const gchar *replace_with_id) +_gtk_source_context_replace_new (const gchar *to_replace_id, + const gchar *replace_with_id) { GtkSourceContextReplace *repl; @@ -6245,8 +6241,8 @@ _gtk_source_context_replace_free (GtkSourceContextReplace *repl) */ gboolean _gtk_source_context_data_finish_parse (GtkSourceContextData *ctx_data, - GList *overrides, - GError **error) + GList *overrides, + GError **error) { struct ResolveRefData data; gchar *root_id; @@ -6280,7 +6276,9 @@ _gtk_source_context_data_finish_parse (GtkSourceContextData *ctx_data, } /* Sanity check: user may have screwed up the files by now (#485661) */ - root_id = g_strdup_printf ("%s:%s", ctx_data->lang->priv->id, ctx_data->lang->priv->id); + root_id = g_strdup_printf ("%s:%s", + gtk_source_language_get_id (ctx_data->lang), + gtk_source_language_get_id (ctx_data->lang)); main_definition = gtk_source_context_data_lookup (ctx_data, root_id); g_free (root_id); @@ -6288,9 +6286,8 @@ _gtk_source_context_data_finish_parse (GtkSourceContextData *ctx_data, { g_set_error (error, GTK_SOURCE_CONTEXT_ENGINE_ERROR, GTK_SOURCE_CONTEXT_ENGINE_ERROR_BAD_FILE, - _("Missing main language " - "definition (id = \"%s\".)"), - ctx_data->lang->priv->id); + _("Missing main language definition (id = “%s”.)"), + gtk_source_language_get_id (ctx_data->lang)); return FALSE; } @@ -6299,7 +6296,7 @@ _gtk_source_context_data_finish_parse (GtkSourceContextData *ctx_data, static void add_escape_ref (ContextDefinition *definition, - GtkSourceContextData *ctx_data) + GtkSourceContextData *ctx_data) { GError *error = NULL; @@ -6327,8 +6324,8 @@ out: static void prepend_definition (G_GNUC_UNUSED gchar *id, - ContextDefinition *definition, - GSList **list) + ContextDefinition *definition, + GSList **list) { *list = g_slist_prepend (*list, definition); } @@ -6342,7 +6339,7 @@ prepend_definition (G_GNUC_UNUSED gchar *id, next line. */ void _gtk_source_context_data_set_escape_char (GtkSourceContextData *ctx_data, - gunichar escape_char) + gunichar escape_char) { GError *error = NULL; char buf[10]; @@ -6397,7 +6394,7 @@ out: #ifdef ENABLE_CHECK_TREE static void check_segment (GtkSourceContextEngine *ce, - Segment *segment) + Segment *segment) { Segment *child; @@ -6406,9 +6403,9 @@ check_segment (GtkSourceContextEngine *ce, g_assert (!segment->next || segment->next->start_at >= segment->end_at); if (SEGMENT_IS_INVALID (segment)) - g_assert (g_slist_find (ce->priv->invalid, segment) != NULL); + g_assert (g_slist_find (ce->invalid, segment) != NULL); else - g_assert (g_slist_find (ce->priv->invalid, segment) == NULL); + g_assert (g_slist_find (ce->invalid, segment) == NULL); if (segment->children != NULL) g_assert (!SEGMENT_IS_INVALID (segment) && SEGMENT_IS_CONTAINER (segment)); @@ -6431,8 +6428,8 @@ struct CheckContextData { static void check_context_hash_cb (const char *text, - Context *context, - gpointer user_data) + Context *context, + gpointer user_data) { struct CheckContextData *data = user_data; @@ -6470,21 +6467,21 @@ check_context (Context *context) static void check_tree (GtkSourceContextEngine *ce) { - Segment *root = ce->priv->root_segment; + Segment *root = ce->root_segment; check_regex (); g_assert (root->start_at == 0); - if (ce->priv->invalid_region.empty) - g_assert (root->end_at == gtk_text_buffer_get_char_count (ce->priv->buffer)); + if (ce->invalid_region.empty) + g_assert (root->end_at == gtk_text_buffer_get_char_count (ce->buffer)); g_assert (!root->parent); check_segment (ce, root); - g_assert (!ce->priv->root_context->parent); - g_assert (root->context == ce->priv->root_context); - check_context (ce->priv->root_context); + g_assert (!ce->root_context->parent); + g_assert (root->context == ce->root_context); + check_context (ce->root_context); } static void diff --git a/gtksourceview/gtksourcecontextengine.h b/gtksourceview/gtksourcecontextengine.h deleted file mode 100644 index 147e2ba3ef28dcef14debeb6139c8a13fa5d86a2..0000000000000000000000000000000000000000 --- a/gtksourceview/gtksourcecontextengine.h +++ /dev/null @@ -1,144 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8; coding: utf-8 -*- - * - * This file is part of GtkSourceView - * - * Copyright (C) 2003 - Gustavo Giráldez - * Copyright (C) 2005 - Marco Barisione, Emanuele Aina - * - * GtkSourceView is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * GtkSourceView 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this library; if not, see . - */ - -#ifndef GTK_SOURCE_CONTEXT_ENGINE_H -#define GTK_SOURCE_CONTEXT_ENGINE_H - -#include "gtksourceengine.h" -#include "gtksourcetypes.h" -#include "gtksourcetypes-private.h" - -G_BEGIN_DECLS - -#define GTK_SOURCE_TYPE_CONTEXT_ENGINE (_gtk_source_context_engine_get_type ()) -#define GTK_SOURCE_CONTEXT_ENGINE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_SOURCE_TYPE_CONTEXT_ENGINE, GtkSourceContextEngine)) -#define GTK_SOURCE_CONTEXT_ENGINE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_SOURCE_TYPE_CONTEXT_ENGINE, GtkSourceContextEngineClass)) -#define GTK_SOURCE_IS_CONTEXT_ENGINE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_SOURCE_TYPE_CONTEXT_ENGINE)) -#define GTK_SOURCE_IS_CONTEXT_ENGINE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_SOURCE_TYPE_CONTEXT_ENGINE)) -#define GTK_SOURCE_CONTEXT_ENGINE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_SOURCE_TYPE_CONTEXT_ENGINE, GtkSourceContextEngineClass)) - -typedef struct _GtkSourceContextData GtkSourceContextData; -typedef struct _GtkSourceContextReplace GtkSourceContextReplace; -typedef struct _GtkSourceContextClass GtkSourceContextClass; -typedef struct _GtkSourceContextEngineClass GtkSourceContextEngineClass; -typedef struct _GtkSourceContextEnginePrivate GtkSourceContextEnginePrivate; - -struct _GtkSourceContextEngine -{ - GObject parent_instance; - - /*< private >*/ - GtkSourceContextEnginePrivate *priv; -}; - -struct _GtkSourceContextEngineClass -{ - GObjectClass parent_class; -}; - -typedef enum _GtkSourceContextFlags { - GTK_SOURCE_CONTEXT_EXTEND_PARENT = 1 << 0, - GTK_SOURCE_CONTEXT_END_PARENT = 1 << 1, - GTK_SOURCE_CONTEXT_END_AT_LINE_END = 1 << 2, - GTK_SOURCE_CONTEXT_FIRST_LINE_ONLY = 1 << 3, - GTK_SOURCE_CONTEXT_ONCE_ONLY = 1 << 4, - GTK_SOURCE_CONTEXT_STYLE_INSIDE = 1 << 5 -} GtkSourceContextFlags; - -typedef enum _GtkSourceContextRefOptions { - GTK_SOURCE_CONTEXT_IGNORE_STYLE = 1 << 0, - GTK_SOURCE_CONTEXT_OVERRIDE_STYLE = 1 << 1, - GTK_SOURCE_CONTEXT_REF_ORIGINAL = 1 << 2 -} GtkSourceContextRefOptions; - -G_GNUC_INTERNAL -GType _gtk_source_context_engine_get_type (void) G_GNUC_CONST; - -G_GNUC_INTERNAL -GtkSourceContextData *_gtk_source_context_data_new (GtkSourceLanguage *lang); - -G_GNUC_INTERNAL -GtkSourceContextData *_gtk_source_context_data_ref (GtkSourceContextData *data); - -G_GNUC_INTERNAL -void _gtk_source_context_data_unref (GtkSourceContextData *data); - -G_GNUC_INTERNAL -GtkSourceContextClass *gtk_source_context_class_new (gchar const *name, - gboolean enabled); - -G_GNUC_INTERNAL -void gtk_source_context_class_free (GtkSourceContextClass *cclass); - -G_GNUC_INTERNAL -GtkSourceContextEngine *_gtk_source_context_engine_new (GtkSourceContextData *data); - -G_GNUC_INTERNAL -gboolean _gtk_source_context_data_define_context (GtkSourceContextData *data, - const gchar *id, - const gchar *parent_id, - const gchar *match_regex, - const gchar *start_regex, - const gchar *end_regex, - const gchar *style, - GSList *context_classes, - GtkSourceContextFlags flags, - GError **error); - -G_GNUC_INTERNAL -gboolean _gtk_source_context_data_add_sub_pattern (GtkSourceContextData *data, - const gchar *id, - const gchar *parent_id, - const gchar *name, - const gchar *where, - const gchar *style, - GSList *context_classes, - GError **error); - -G_GNUC_INTERNAL -gboolean _gtk_source_context_data_add_ref (GtkSourceContextData *data, - const gchar *parent_id, - const gchar *ref_id, - GtkSourceContextRefOptions options, - const gchar *style, - gboolean all, - GError **error); - -G_GNUC_INTERNAL -GtkSourceContextReplace *_gtk_source_context_replace_new (const gchar *to_replace_id, - const gchar *replace_with_id); - -G_GNUC_INTERNAL -void _gtk_source_context_replace_free (GtkSourceContextReplace *repl); - -G_GNUC_INTERNAL -gboolean _gtk_source_context_data_finish_parse (GtkSourceContextData *data, - GList *overrides, - GError **error); - -/* Only for lang files version 1, do not use it */ -G_GNUC_INTERNAL -void _gtk_source_context_data_set_escape_char (GtkSourceContextData *data, - gunichar esc_char); - -G_END_DECLS - -#endif /* GTK_SOURCE_CONTEXT_ENGINE_H */ diff --git a/gtksourceview/gtksourceencoding-private.h b/gtksourceview/gtksourceencoding-private.h index cd9e73dbfd5efe45f4a5a62c6a6edcf3ffce8de1..b99d4e14f75c52777c68b50811799e6b01aded27 100644 --- a/gtksourceview/gtksourceencoding-private.h +++ b/gtksourceview/gtksourceencoding-private.h @@ -1,8 +1,7 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8; coding: utf-8 -*- */ /* * This file is part of GtkSourceView * - * Copyright (C) 2014 - Sébastien Wilmet + * Copyright 2014 - Sébastien Wilmet * * GtkSourceView is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -18,8 +17,7 @@ * along with this library; if not, see . */ -#ifndef GTK_SOURCE_ENCODING_PRIVATE_H -#define GTK_SOURCE_ENCODING_PRIVATE_H +#pragma once #include #include "gtksourcetypes-private.h" @@ -43,9 +41,7 @@ typedef enum _GtkSourceEncodingDuplicates } GtkSourceEncodingDuplicates; GTK_SOURCE_INTERNAL -GSList * _gtk_source_encoding_remove_duplicates (GSList *encodings, - GtkSourceEncodingDuplicates removal_type); +GSList *_gtk_source_encoding_remove_duplicates (GSList *encodings, + GtkSourceEncodingDuplicates removal_type); G_END_DECLS - -#endif /* GTK_SOURCE_ENCODING_PRIVATE_H */ diff --git a/gtksourceview/gtksourceencoding.c b/gtksourceview/gtksourceencoding.c index 5e5cdeb3b7d4248b23815bffafb65d0dbe2601dd..30eda3c0d356681d9ce9ecb821abd4c6702db423 100644 --- a/gtksourceview/gtksourceencoding.c +++ b/gtksourceview/gtksourceencoding.c @@ -1,9 +1,8 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8; coding: utf-8 -*- */ /* * This file is part of GtkSourceView * - * Copyright (C) 2002-2005 - Paolo Maggi - * Copyright (C) 2014, 2015 - Sébastien Wilmet + * Copyright 2002-2005 - Paolo Maggi + * Copyright 2014, 2015 - Sébastien Wilmet * * GtkSourceView is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -19,9 +18,7 @@ * along with this library; if not, see . */ -#ifdef HAVE_CONFIG_H -#include -#endif +#include "config.h" #include "gtksourceencoding.h" #include "gtksourceencoding-private.h" @@ -58,7 +55,7 @@ G_DEFINE_BOXED_TYPE (GtkSourceEncoding, gtk_source_encoding, /* * The original versions of the following tables are taken from profterm * - * Copyright (C) 2002 Red Hat, Inc. + * Copyright 2002 Red Hat, Inc. */ typedef enum _GtkSourceEncodingIndex diff --git a/gtksourceview/gtksourceencoding.h b/gtksourceview/gtksourceencoding.h index 25fb93713a675ce5c11b0868e0bc8fab7e3cf668..e09e050d0ff7de0817b1c1146e61ee7233bf5f3b 100644 --- a/gtksourceview/gtksourceencoding.h +++ b/gtksourceview/gtksourceencoding.h @@ -1,9 +1,8 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8; coding: utf-8 -*- */ /* * This file is part of GtkSourceView * - * Copyright (C) 2002-2005 - Paolo Maggi - * Copyright (C) 2014, 2015 - Sébastien Wilmet + * Copyright 2002-2005 - Paolo Maggi + * Copyright 2014, 2015 - Sébastien Wilmet * * GtkSourceView is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -19,8 +18,7 @@ * along with this library; if not, see . */ -#ifndef GTK_SOURCE_ENCODING_H -#define GTK_SOURCE_ENCODING_H +#pragma once #if !defined (GTK_SOURCE_H_INSIDE) && !defined (GTK_SOURCE_COMPILATION) #error "Only can be included directly." @@ -28,47 +26,36 @@ #include #include -#include + +#include "gtksourcetypes.h" G_BEGIN_DECLS #define GTK_SOURCE_TYPE_ENCODING (gtk_source_encoding_get_type ()) GTK_SOURCE_AVAILABLE_IN_3_14 -GType gtk_source_encoding_get_type (void) G_GNUC_CONST; - +GType gtk_source_encoding_get_type (void) G_GNUC_CONST; GTK_SOURCE_AVAILABLE_IN_3_14 -const GtkSourceEncoding *gtk_source_encoding_get_from_charset (const gchar *charset); - +const GtkSourceEncoding *gtk_source_encoding_get_from_charset (const gchar *charset); GTK_SOURCE_AVAILABLE_IN_3_14 -gchar *gtk_source_encoding_to_string (const GtkSourceEncoding *enc); - +gchar *gtk_source_encoding_to_string (const GtkSourceEncoding *enc); GTK_SOURCE_AVAILABLE_IN_3_14 -const gchar *gtk_source_encoding_get_name (const GtkSourceEncoding *enc); - +const gchar *gtk_source_encoding_get_name (const GtkSourceEncoding *enc); GTK_SOURCE_AVAILABLE_IN_3_14 -const gchar *gtk_source_encoding_get_charset (const GtkSourceEncoding *enc); - +const gchar *gtk_source_encoding_get_charset (const GtkSourceEncoding *enc); GTK_SOURCE_AVAILABLE_IN_3_14 -const GtkSourceEncoding *gtk_source_encoding_get_utf8 (void); - +const GtkSourceEncoding *gtk_source_encoding_get_utf8 (void); GTK_SOURCE_AVAILABLE_IN_3_14 -const GtkSourceEncoding *gtk_source_encoding_get_current (void); - +const GtkSourceEncoding *gtk_source_encoding_get_current (void); GTK_SOURCE_AVAILABLE_IN_3_14 -GSList *gtk_source_encoding_get_all (void); - +GSList *gtk_source_encoding_get_all (void); GTK_SOURCE_AVAILABLE_IN_3_18 -GSList *gtk_source_encoding_get_default_candidates (void); +GSList *gtk_source_encoding_get_default_candidates (void); /* These should not be used, they are just to make python bindings happy */ - GTK_SOURCE_AVAILABLE_IN_3_14 -GtkSourceEncoding *gtk_source_encoding_copy (const GtkSourceEncoding *enc); - +GtkSourceEncoding *gtk_source_encoding_copy (const GtkSourceEncoding *enc); GTK_SOURCE_AVAILABLE_IN_3_14 -void gtk_source_encoding_free (GtkSourceEncoding *enc); +void gtk_source_encoding_free (GtkSourceEncoding *enc); G_END_DECLS - -#endif /* GTK_SOURCE_ENCODING_H */ diff --git a/gtksourceview/gtksourceengine-private.h b/gtksourceview/gtksourceengine-private.h new file mode 100644 index 0000000000000000000000000000000000000000..2de6439925fdea2e6e7712ef54843e0f86ed0e9f --- /dev/null +++ b/gtksourceview/gtksourceengine-private.h @@ -0,0 +1,73 @@ +/* + * This file is part of GtkSourceView + * + * Copyright 2003 - Gustavo Giráldez + * + * GtkSourceView is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * GtkSourceView 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, see . + */ + +#pragma once + +#include +#include "gtksourcetypes.h" +#include "gtksourcetypes-private.h" + +G_BEGIN_DECLS + +#define GTK_SOURCE_TYPE_ENGINE (_gtk_source_engine_get_type()) + +G_GNUC_INTERNAL +G_DECLARE_INTERFACE (GtkSourceEngine, _gtk_source_engine, GTK_SOURCE, ENGINE, GObject) + +struct _GtkSourceEngineInterface +{ + GTypeInterface parent_interface; + + void (* attach_buffer) (GtkSourceEngine *engine, + GtkTextBuffer *buffer); + void (* text_inserted) (GtkSourceEngine *engine, + gint start_offset, + gint end_offset); + void (* text_deleted) (GtkSourceEngine *engine, + gint offset, + gint length); + void (* update_highlight) (GtkSourceEngine *engine, + const GtkTextIter *start, + const GtkTextIter *end, + gboolean synchronous); + void (* set_style_scheme) (GtkSourceEngine *engine, + GtkSourceStyleScheme *scheme); +}; + +G_GNUC_INTERNAL +void _gtk_source_engine_attach_buffer (GtkSourceEngine *engine, + GtkTextBuffer *buffer); +G_GNUC_INTERNAL +void _gtk_source_engine_text_inserted (GtkSourceEngine *engine, + gint start_offset, + gint end_offset); +G_GNUC_INTERNAL +void _gtk_source_engine_text_deleted (GtkSourceEngine *engine, + gint offset, + gint length); +G_GNUC_INTERNAL +void _gtk_source_engine_update_highlight (GtkSourceEngine *engine, + const GtkTextIter *start, + const GtkTextIter *end, + gboolean synchronous); +G_GNUC_INTERNAL +void _gtk_source_engine_set_style_scheme (GtkSourceEngine *engine, + GtkSourceStyleScheme *scheme); + +G_END_DECLS diff --git a/gtksourceview/gtksourceengine.c b/gtksourceview/gtksourceengine.c index 94ff2224651e386e1991c4e60f5698639d4666b0..201dbf5352fc89f39ce1c3954773610b087b608f 100644 --- a/gtksourceview/gtksourceengine.c +++ b/gtksourceview/gtksourceengine.c @@ -1,8 +1,7 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8; coding: utf-8 -*- - * +/* * This file is part of GtkSourceView * - * Copyright (C) 2003 - Gustavo Giráldez + * Copyright 2003 - Gustavo Giráldez * * GtkSourceView is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,11 +19,9 @@ /* Interface for syntax highlighting engines. */ -#ifdef HAVE_CONFIG_H -#include -#endif +#include "config.h" -#include "gtksourceengine.h" +#include "gtksourceengine-private.h" #include "gtksourcestylescheme.h" G_DEFINE_INTERFACE (GtkSourceEngine, _gtk_source_engine, G_TYPE_OBJECT) @@ -36,51 +33,51 @@ _gtk_source_engine_default_init (GtkSourceEngineInterface *interface) void _gtk_source_engine_attach_buffer (GtkSourceEngine *engine, - GtkTextBuffer *buffer) + GtkTextBuffer *buffer) { g_return_if_fail (GTK_SOURCE_IS_ENGINE (engine)); - g_return_if_fail (GTK_SOURCE_ENGINE_GET_INTERFACE (engine)->attach_buffer != NULL); + g_return_if_fail (GTK_SOURCE_ENGINE_GET_IFACE (engine)->attach_buffer != NULL); - GTK_SOURCE_ENGINE_GET_INTERFACE (engine)->attach_buffer (engine, buffer); + GTK_SOURCE_ENGINE_GET_IFACE (engine)->attach_buffer (engine, buffer); } void _gtk_source_engine_text_inserted (GtkSourceEngine *engine, - gint start_offset, - gint end_offset) + gint start_offset, + gint end_offset) { g_return_if_fail (GTK_SOURCE_IS_ENGINE (engine)); - g_return_if_fail (GTK_SOURCE_ENGINE_GET_INTERFACE (engine)->text_inserted != NULL); + g_return_if_fail (GTK_SOURCE_ENGINE_GET_IFACE (engine)->text_inserted != NULL); - GTK_SOURCE_ENGINE_GET_INTERFACE (engine)->text_inserted (engine, + GTK_SOURCE_ENGINE_GET_IFACE (engine)->text_inserted (engine, start_offset, end_offset); } void _gtk_source_engine_text_deleted (GtkSourceEngine *engine, - gint offset, - gint length) + gint offset, + gint length) { g_return_if_fail (GTK_SOURCE_IS_ENGINE (engine)); - g_return_if_fail (GTK_SOURCE_ENGINE_GET_INTERFACE (engine)->text_deleted != NULL); + g_return_if_fail (GTK_SOURCE_ENGINE_GET_IFACE (engine)->text_deleted != NULL); - GTK_SOURCE_ENGINE_GET_INTERFACE (engine)->text_deleted (engine, + GTK_SOURCE_ENGINE_GET_IFACE (engine)->text_deleted (engine, offset, length); } void _gtk_source_engine_update_highlight (GtkSourceEngine *engine, - const GtkTextIter *start, - const GtkTextIter *end, - gboolean synchronous) + const GtkTextIter *start, + const GtkTextIter *end, + gboolean synchronous) { g_return_if_fail (GTK_SOURCE_IS_ENGINE (engine)); g_return_if_fail (start != NULL && end != NULL); - g_return_if_fail (GTK_SOURCE_ENGINE_GET_INTERFACE (engine)->update_highlight != NULL); + g_return_if_fail (GTK_SOURCE_ENGINE_GET_IFACE (engine)->update_highlight != NULL); - GTK_SOURCE_ENGINE_GET_INTERFACE (engine)->update_highlight (engine, + GTK_SOURCE_ENGINE_GET_IFACE (engine)->update_highlight (engine, start, end, synchronous); @@ -88,11 +85,11 @@ _gtk_source_engine_update_highlight (GtkSourceEngine *engine, void _gtk_source_engine_set_style_scheme (GtkSourceEngine *engine, - GtkSourceStyleScheme *scheme) + GtkSourceStyleScheme *scheme) { g_return_if_fail (GTK_SOURCE_IS_ENGINE (engine)); g_return_if_fail (GTK_SOURCE_IS_STYLE_SCHEME (scheme) || scheme == NULL); - g_return_if_fail (GTK_SOURCE_ENGINE_GET_INTERFACE (engine)->set_style_scheme != NULL); + g_return_if_fail (GTK_SOURCE_ENGINE_GET_IFACE (engine)->set_style_scheme != NULL); - GTK_SOURCE_ENGINE_GET_INTERFACE (engine)->set_style_scheme (engine, scheme); + GTK_SOURCE_ENGINE_GET_IFACE (engine)->set_style_scheme (engine, scheme); } diff --git a/gtksourceview/gtksourceengine.h b/gtksourceview/gtksourceengine.h deleted file mode 100644 index c6ecb850fb5a061be1c0717a1728bbd0b0d8ae05..0000000000000000000000000000000000000000 --- a/gtksourceview/gtksourceengine.h +++ /dev/null @@ -1,89 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8; coding: utf-8 -*- - * - * This file is part of GtkSourceView - * - * Copyright (C) 2003 - Gustavo Giráldez - * - * GtkSourceView is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * GtkSourceView 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this library; if not, see . - */ - -#ifndef GTK_SOURCE_ENGINE_H -#define GTK_SOURCE_ENGINE_H - -#include -#include "gtksourcetypes.h" -#include "gtksourcetypes-private.h" - -G_BEGIN_DECLS - -#define GTK_SOURCE_TYPE_ENGINE (_gtk_source_engine_get_type ()) -#define GTK_SOURCE_ENGINE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_SOURCE_TYPE_ENGINE, GtkSourceEngine)) -#define GTK_SOURCE_IS_ENGINE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_SOURCE_TYPE_ENGINE)) -#define GTK_SOURCE_ENGINE_GET_INTERFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), GTK_SOURCE_TYPE_ENGINE, GtkSourceEngineInterface)) - -typedef struct _GtkSourceEngineInterface GtkSourceEngineInterface; - -struct _GtkSourceEngineInterface -{ - GTypeInterface parent_interface; - - void (* attach_buffer) (GtkSourceEngine *engine, - GtkTextBuffer *buffer); - - void (* text_inserted) (GtkSourceEngine *engine, - gint start_offset, - gint end_offset); - void (* text_deleted) (GtkSourceEngine *engine, - gint offset, - gint length); - - void (* update_highlight) (GtkSourceEngine *engine, - const GtkTextIter *start, - const GtkTextIter *end, - gboolean synchronous); - - void (* set_style_scheme) (GtkSourceEngine *engine, - GtkSourceStyleScheme *scheme); -}; - -G_GNUC_INTERNAL -GType _gtk_source_engine_get_type (void) G_GNUC_CONST; - -G_GNUC_INTERNAL -void _gtk_source_engine_attach_buffer (GtkSourceEngine *engine, - GtkTextBuffer *buffer); - -G_GNUC_INTERNAL -void _gtk_source_engine_text_inserted (GtkSourceEngine *engine, - gint start_offset, - gint end_offset); - -G_GNUC_INTERNAL -void _gtk_source_engine_text_deleted (GtkSourceEngine *engine, - gint offset, - gint length); - -G_GNUC_INTERNAL -void _gtk_source_engine_update_highlight (GtkSourceEngine *engine, - const GtkTextIter *start, - const GtkTextIter *end, - gboolean synchronous); - -G_GNUC_INTERNAL -void _gtk_source_engine_set_style_scheme (GtkSourceEngine *engine, - GtkSourceStyleScheme *scheme); - -G_END_DECLS - -#endif /* GTK_SOURCE_ENGINE_H */ diff --git a/gtksourceview/gtksourcefile-private.h b/gtksourceview/gtksourcefile-private.h new file mode 100644 index 0000000000000000000000000000000000000000..921e38d6f01d25309d7bc2978a0bb89e70632ffc --- /dev/null +++ b/gtksourceview/gtksourcefile-private.h @@ -0,0 +1,53 @@ +/* + * This file is part of GtkSourceView + * + * Copyright 2014, 2015 - Sébastien Wilmet + * + * GtkSourceView is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * GtkSourceView 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, see . + */ + +#pragma once + +#include "gtksourcefile.h" + +G_BEGIN_DECLS + +G_GNUC_INTERNAL +void _gtk_source_file_set_encoding (GtkSourceFile *file, + const GtkSourceEncoding *encoding); +G_GNUC_INTERNAL +void _gtk_source_file_set_newline_type (GtkSourceFile *file, + GtkSourceNewlineType newline_type); +G_GNUC_INTERNAL +void _gtk_source_file_set_compression_type (GtkSourceFile *file, + GtkSourceCompressionType compression_type); +G_GNUC_INTERNAL +GMountOperation *_gtk_source_file_create_mount_operation (GtkSourceFile *file); +G_GNUC_INTERNAL +gboolean _gtk_source_file_get_modification_time (GtkSourceFile *file, + gint64 *modification_time); +G_GNUC_INTERNAL +void _gtk_source_file_set_modification_time (GtkSourceFile *file, + gint64 modification_time); +G_GNUC_INTERNAL +void _gtk_source_file_set_externally_modified (GtkSourceFile *file, + gboolean externally_modified); +G_GNUC_INTERNAL +void _gtk_source_file_set_deleted (GtkSourceFile *file, + gboolean deleted); +G_GNUC_INTERNAL +void _gtk_source_file_set_readonly (GtkSourceFile *file, + gboolean readonly); + +G_END_DECLS diff --git a/gtksourceview/gtksourcefile.c b/gtksourceview/gtksourcefile.c index 16d60965104d90636918b78cae7e7ccaae55feb6..33343509dea66bc821cebfa4bfa4d8fd4f73f8b2 100644 --- a/gtksourceview/gtksourcefile.c +++ b/gtksourceview/gtksourcefile.c @@ -1,8 +1,7 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8; coding: utf-8 -*- */ /* * This file is part of GtkSourceView * - * Copyright (C) 2014, 2015 - Sébastien Wilmet + * Copyright 2014, 2015 - Sébastien Wilmet * * GtkSourceView is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -18,11 +17,9 @@ * along with this library; if not, see . */ -#ifdef HAVE_CONFIG_H -#include -#endif +#include "config.h" -#include "gtksourcefile.h" +#include "gtksourcefile-private.h" #include "gtksourceencoding.h" #include "gtksource-enumtypes.h" @@ -54,10 +51,11 @@ enum PROP_ENCODING, PROP_NEWLINE_TYPE, PROP_COMPRESSION_TYPE, - PROP_READ_ONLY + PROP_READ_ONLY, + N_PROPS }; -struct _GtkSourceFilePrivate +typedef struct { GFile *location; const GtkSourceEncoding *encoding; @@ -71,78 +69,73 @@ struct _GtkSourceFilePrivate /* Last known modification time of 'location'. The value is updated on a * file loading or file saving. */ - GTimeVal modification_time; + gint64 modification_time; guint modification_time_set : 1; guint externally_modified : 1; guint deleted : 1; guint readonly : 1; -}; +} GtkSourceFilePrivate; G_DEFINE_TYPE_WITH_PRIVATE (GtkSourceFile, gtk_source_file, G_TYPE_OBJECT) +static GParamSpec *properties[N_PROPS]; + static void gtk_source_file_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) + guint prop_id, + GValue *value, + GParamSpec *pspec) { - GtkSourceFile *file; - - g_return_if_fail (GTK_SOURCE_IS_FILE (object)); - - file = GTK_SOURCE_FILE (object); + GtkSourceFile *file = GTK_SOURCE_FILE (object); + GtkSourceFilePrivate *priv = gtk_source_file_get_instance_private (file); switch (prop_id) { - case PROP_LOCATION: - g_value_set_object (value, file->priv->location); - break; + case PROP_LOCATION: + g_value_set_object (value, priv->location); + break; - case PROP_ENCODING: - g_value_set_boxed (value, file->priv->encoding); - break; + case PROP_ENCODING: + g_value_set_boxed (value, priv->encoding); + break; - case PROP_NEWLINE_TYPE: - g_value_set_enum (value, file->priv->newline_type); - break; + case PROP_NEWLINE_TYPE: + g_value_set_enum (value, priv->newline_type); + break; - case PROP_COMPRESSION_TYPE: - g_value_set_enum (value, file->priv->compression_type); - break; + case PROP_COMPRESSION_TYPE: + g_value_set_enum (value, priv->compression_type); + break; - case PROP_READ_ONLY: - g_value_set_boolean (value, file->priv->readonly); - break; + case PROP_READ_ONLY: + g_value_set_boolean (value, priv->readonly); + break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; } } static void gtk_source_file_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) + guint prop_id, + const GValue *value, + GParamSpec *pspec) { - GtkSourceFile *file; - - g_return_if_fail (GTK_SOURCE_IS_FILE (object)); - - file = GTK_SOURCE_FILE (object); + GtkSourceFile *file = GTK_SOURCE_FILE (object); switch (prop_id) { - case PROP_LOCATION: - gtk_source_file_set_location (file, g_value_get_object (value)); - break; + case PROP_LOCATION: + gtk_source_file_set_location (file, g_value_get_object (value)); + break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; } } @@ -150,13 +143,14 @@ static void gtk_source_file_dispose (GObject *object) { GtkSourceFile *file = GTK_SOURCE_FILE (object); + GtkSourceFilePrivate *priv = gtk_source_file_get_instance_private (file); - g_clear_object (&file->priv->location); + g_clear_object (&priv->location); - if (file->priv->mount_operation_notify != NULL) + if (priv->mount_operation_notify != NULL) { - file->priv->mount_operation_notify (file->priv->mount_operation_userdata); - file->priv->mount_operation_notify = NULL; + priv->mount_operation_notify (priv->mount_operation_userdata); + priv->mount_operation_notify = NULL; } G_OBJECT_CLASS (gtk_source_file_parent_class)->dispose (object); @@ -178,15 +172,14 @@ gtk_source_file_class_init (GtkSourceFileClass *klass) * * Since: 3.14 */ - g_object_class_install_property (object_class, - PROP_LOCATION, - g_param_spec_object ("location", - "Location", - "", - G_TYPE_FILE, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT | - G_PARAM_STATIC_STRINGS)); + properties [PROP_LOCATION] = + g_param_spec_object ("location", + "Location", + "", + G_TYPE_FILE, + (G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + G_PARAM_STATIC_STRINGS)); /** * GtkSourceFile:encoding: @@ -196,14 +189,13 @@ gtk_source_file_class_init (GtkSourceFileClass *klass) * * Since: 3.14 */ - g_object_class_install_property (object_class, - PROP_ENCODING, - g_param_spec_boxed ("encoding", - "Encoding", - "", - GTK_SOURCE_TYPE_ENCODING, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS)); + properties[PROP_ENCODING] = + g_param_spec_boxed ("encoding", + "Encoding", + "", + GTK_SOURCE_TYPE_ENCODING, + (G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); /** * GtkSourceFile:newline-type: @@ -212,15 +204,14 @@ gtk_source_file_class_init (GtkSourceFileClass *klass) * * Since: 3.14 */ - g_object_class_install_property (object_class, - PROP_NEWLINE_TYPE, - g_param_spec_enum ("newline-type", - "Newline type", - "", - GTK_SOURCE_TYPE_NEWLINE_TYPE, - GTK_SOURCE_NEWLINE_TYPE_LF, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS)); + properties[PROP_NEWLINE_TYPE] = + g_param_spec_enum ("newline-type", + "Newline type", + "", + GTK_SOURCE_TYPE_NEWLINE_TYPE, + GTK_SOURCE_NEWLINE_TYPE_LF, + (G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); /** * GtkSourceFile:compression-type: @@ -229,15 +220,14 @@ gtk_source_file_class_init (GtkSourceFileClass *klass) * * Since: 3.14 */ - g_object_class_install_property (object_class, - PROP_COMPRESSION_TYPE, - g_param_spec_enum ("compression-type", - "Compression type", - "", - GTK_SOURCE_TYPE_COMPRESSION_TYPE, - GTK_SOURCE_COMPRESSION_TYPE_NONE, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS)); + properties [PROP_COMPRESSION_TYPE] = + g_param_spec_enum ("compression-type", + "Compression type", + "", + GTK_SOURCE_TYPE_COMPRESSION_TYPE, + GTK_SOURCE_COMPRESSION_TYPE_NONE, + (G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); /** * GtkSourceFile:read-only: @@ -247,24 +237,25 @@ gtk_source_file_class_init (GtkSourceFileClass *klass) * * Since: 3.18 */ - g_object_class_install_property (object_class, - PROP_READ_ONLY, - g_param_spec_boolean ("read-only", - "Read Only", - "", - FALSE, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS)); + properties [PROP_READ_ONLY] = + g_param_spec_boolean ("read-only", + "Read Only", + "", + FALSE, + (G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + g_object_class_install_properties (object_class, N_PROPS, properties); } static void gtk_source_file_init (GtkSourceFile *file) { - file->priv = gtk_source_file_get_instance_private (file); + GtkSourceFilePrivate *priv = gtk_source_file_get_instance_private (file); - file->priv->encoding = NULL; - file->priv->newline_type = GTK_SOURCE_NEWLINE_TYPE_LF; - file->priv->compression_type = GTK_SOURCE_COMPRESSION_TYPE_NONE; + priv->encoding = NULL; + priv->newline_type = GTK_SOURCE_NEWLINE_TYPE_LF; + priv->compression_type = GTK_SOURCE_COMPRESSION_TYPE_NONE; } /** @@ -290,20 +281,22 @@ gtk_source_file_new (void) */ void gtk_source_file_set_location (GtkSourceFile *file, - GFile *location) + GFile *location) { + GtkSourceFilePrivate *priv = gtk_source_file_get_instance_private (file); + g_return_if_fail (GTK_SOURCE_IS_FILE (file)); g_return_if_fail (location == NULL || G_IS_FILE (location)); - if (g_set_object (&file->priv->location, location)) + if (g_set_object (&priv->location, location)) { - g_object_notify (G_OBJECT (file), "location"); + g_object_notify_by_pspec (G_OBJECT (file), properties[PROP_LOCATION]); /* The modification_time is for the old location. */ - file->priv->modification_time_set = FALSE; + priv->modification_time_set = FALSE; - file->priv->externally_modified = FALSE; - file->priv->deleted = FALSE; + priv->externally_modified = FALSE; + priv->deleted = FALSE; } } @@ -317,21 +310,25 @@ gtk_source_file_set_location (GtkSourceFile *file, GFile * gtk_source_file_get_location (GtkSourceFile *file) { + GtkSourceFilePrivate *priv = gtk_source_file_get_instance_private (file); + g_return_val_if_fail (GTK_SOURCE_IS_FILE (file), NULL); - return file->priv->location; + return priv->location; } void _gtk_source_file_set_encoding (GtkSourceFile *file, - const GtkSourceEncoding *encoding) + const GtkSourceEncoding *encoding) { + GtkSourceFilePrivate *priv = gtk_source_file_get_instance_private (file); + g_return_if_fail (GTK_SOURCE_IS_FILE (file)); - if (file->priv->encoding != encoding) + if (priv->encoding != encoding) { - file->priv->encoding = encoding; - g_object_notify (G_OBJECT (file), "encoding"); + priv->encoding = encoding; + g_object_notify_by_pspec (G_OBJECT (file), properties[PROP_ENCODING]); } } @@ -348,21 +345,25 @@ _gtk_source_file_set_encoding (GtkSourceFile *file, const GtkSourceEncoding * gtk_source_file_get_encoding (GtkSourceFile *file) { + GtkSourceFilePrivate *priv = gtk_source_file_get_instance_private (file); + g_return_val_if_fail (GTK_SOURCE_IS_FILE (file), NULL); - return file->priv->encoding; + return priv->encoding; } void _gtk_source_file_set_newline_type (GtkSourceFile *file, - GtkSourceNewlineType newline_type) + GtkSourceNewlineType newline_type) { + GtkSourceFilePrivate *priv = gtk_source_file_get_instance_private (file); + g_return_if_fail (GTK_SOURCE_IS_FILE (file)); - if (file->priv->newline_type != newline_type) + if (priv->newline_type != newline_type) { - file->priv->newline_type = newline_type; - g_object_notify (G_OBJECT (file), "newline-type"); + priv->newline_type = newline_type; + g_object_notify_by_pspec (G_OBJECT (file), properties[PROP_NEWLINE_TYPE]); } } @@ -376,21 +377,25 @@ _gtk_source_file_set_newline_type (GtkSourceFile *file, GtkSourceNewlineType gtk_source_file_get_newline_type (GtkSourceFile *file) { + GtkSourceFilePrivate *priv = gtk_source_file_get_instance_private (file); + g_return_val_if_fail (GTK_SOURCE_IS_FILE (file), GTK_SOURCE_NEWLINE_TYPE_DEFAULT); - return file->priv->newline_type; + return priv->newline_type; } void _gtk_source_file_set_compression_type (GtkSourceFile *file, - GtkSourceCompressionType compression_type) + GtkSourceCompressionType compression_type) { + GtkSourceFilePrivate *priv = gtk_source_file_get_instance_private (file); + g_return_if_fail (GTK_SOURCE_IS_FILE (file)); - if (file->priv->compression_type != compression_type) + if (priv->compression_type != compression_type) { - file->priv->compression_type = compression_type; - g_object_notify (G_OBJECT (file), "compression-type"); + priv->compression_type = compression_type; + g_object_notify_by_pspec (G_OBJECT (file), properties[PROP_COMPRESSION_TYPE]); } } @@ -404,9 +409,11 @@ _gtk_source_file_set_compression_type (GtkSourceFile *file, GtkSourceCompressionType gtk_source_file_get_compression_type (GtkSourceFile *file) { + GtkSourceFilePrivate *priv = gtk_source_file_get_instance_private (file); + g_return_val_if_fail (GTK_SOURCE_IS_FILE (file), GTK_SOURCE_COMPRESSION_TYPE_NONE); - return file->priv->compression_type; + return priv->compression_type; } /** @@ -429,34 +436,40 @@ gtk_source_file_get_compression_type (GtkSourceFile *file) */ void gtk_source_file_set_mount_operation_factory (GtkSourceFile *file, - GtkSourceMountOperationFactory callback, - gpointer user_data, - GDestroyNotify notify) + GtkSourceMountOperationFactory callback, + gpointer user_data, + GDestroyNotify notify) { + GtkSourceFilePrivate *priv = gtk_source_file_get_instance_private (file); + g_return_if_fail (GTK_SOURCE_IS_FILE (file)); - if (file->priv->mount_operation_notify != NULL) + if (priv->mount_operation_notify != NULL) { - file->priv->mount_operation_notify (file->priv->mount_operation_userdata); + priv->mount_operation_notify (priv->mount_operation_userdata); } - file->priv->mount_operation_factory = callback; - file->priv->mount_operation_userdata = user_data; - file->priv->mount_operation_notify = notify; + priv->mount_operation_factory = callback; + priv->mount_operation_userdata = user_data; + priv->mount_operation_notify = notify; } GMountOperation * _gtk_source_file_create_mount_operation (GtkSourceFile *file) { - return (file != NULL && file->priv->mount_operation_factory != NULL) ? - file->priv->mount_operation_factory (file, file->priv->mount_operation_userdata) : + GtkSourceFilePrivate *priv = gtk_source_file_get_instance_private (file); + + return (file != NULL && priv->mount_operation_factory != NULL) ? + priv->mount_operation_factory (file, priv->mount_operation_userdata) : g_mount_operation_new (); } gboolean _gtk_source_file_get_modification_time (GtkSourceFile *file, - GTimeVal *modification_time) + gint64 *modification_time) { + GtkSourceFilePrivate *priv = gtk_source_file_get_instance_private (file); + g_assert (modification_time != NULL); if (file == NULL) @@ -466,24 +479,26 @@ _gtk_source_file_get_modification_time (GtkSourceFile *file, g_return_val_if_fail (GTK_SOURCE_IS_FILE (file), FALSE); - if (file->priv->modification_time_set) + if (priv->modification_time_set) { - *modification_time = file->priv->modification_time; + *modification_time = priv->modification_time; } - return file->priv->modification_time_set; + return priv->modification_time_set; } void _gtk_source_file_set_modification_time (GtkSourceFile *file, - GTimeVal modification_time) + gint64 modification_time) { + GtkSourceFilePrivate *priv = gtk_source_file_get_instance_private (file); + if (file != NULL) { g_return_if_fail (GTK_SOURCE_IS_FILE (file)); - file->priv->modification_time = modification_time; - file->priv->modification_time_set = TRUE; + priv->modification_time = modification_time; + priv->modification_time_set = TRUE; } } @@ -500,14 +515,16 @@ _gtk_source_file_set_modification_time (GtkSourceFile *file, gboolean gtk_source_file_is_local (GtkSourceFile *file) { + GtkSourceFilePrivate *priv = gtk_source_file_get_instance_private (file); + g_return_val_if_fail (GTK_SOURCE_IS_FILE (file), FALSE); - if (file->priv->location == NULL) + if (priv->location == NULL) { return FALSE; } - return g_file_has_uri_scheme (file->priv->location, "file"); + return g_file_has_uri_scheme (priv->location, "file"); } /** @@ -529,14 +546,15 @@ gtk_source_file_is_local (GtkSourceFile *file) void gtk_source_file_check_file_on_disk (GtkSourceFile *file) { + GtkSourceFilePrivate *priv = gtk_source_file_get_instance_private (file); GFileInfo *info; - if (file->priv->location == NULL) + if (priv->location == NULL) { return; } - info = g_file_query_info (file->priv->location, + info = g_file_query_info (priv->location, G_FILE_ATTRIBUTE_TIME_MODIFIED "," G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE, G_FILE_QUERY_INFO_NONE, @@ -545,25 +563,28 @@ gtk_source_file_check_file_on_disk (GtkSourceFile *file) if (info == NULL) { - file->priv->deleted = TRUE; + priv->deleted = TRUE; return; } if (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_TIME_MODIFIED) && - file->priv->modification_time_set) + priv->modification_time_set) { - GTimeVal timeval; + GDateTime *dt; + gint64 mtime; - g_file_info_get_modification_time (info, &timeval); + dt = g_file_info_get_modification_date_time (info); + mtime = g_date_time_to_unix (dt); /* Note that the modification time can even go backwards if the * user is copying over an old file. */ - if (timeval.tv_sec != file->priv->modification_time.tv_sec || - timeval.tv_usec != file->priv->modification_time.tv_usec) + if (mtime != priv->modification_time) { - file->priv->externally_modified = TRUE; + priv->externally_modified = TRUE; } + + g_date_time_unref (dt); } if (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE)) @@ -580,11 +601,13 @@ gtk_source_file_check_file_on_disk (GtkSourceFile *file) void _gtk_source_file_set_externally_modified (GtkSourceFile *file, - gboolean externally_modified) + gboolean externally_modified) { + GtkSourceFilePrivate *priv = gtk_source_file_get_instance_private (file); + g_return_if_fail (GTK_SOURCE_IS_FILE (file)); - file->priv->externally_modified = externally_modified != FALSE; + priv->externally_modified = externally_modified != FALSE; } /** @@ -603,18 +626,22 @@ _gtk_source_file_set_externally_modified (GtkSourceFile *file, gboolean gtk_source_file_is_externally_modified (GtkSourceFile *file) { + GtkSourceFilePrivate *priv = gtk_source_file_get_instance_private (file); + g_return_val_if_fail (GTK_SOURCE_IS_FILE (file), FALSE); - return file->priv->externally_modified; + return priv->externally_modified; } void _gtk_source_file_set_deleted (GtkSourceFile *file, - gboolean deleted) + gboolean deleted) { + GtkSourceFilePrivate *priv = gtk_source_file_get_instance_private (file); + g_return_if_fail (GTK_SOURCE_IS_FILE (file)); - file->priv->deleted = deleted != FALSE; + priv->deleted = deleted != FALSE; } /** @@ -633,23 +660,27 @@ _gtk_source_file_set_deleted (GtkSourceFile *file, gboolean gtk_source_file_is_deleted (GtkSourceFile *file) { + GtkSourceFilePrivate *priv = gtk_source_file_get_instance_private (file); + g_return_val_if_fail (GTK_SOURCE_IS_FILE (file), FALSE); - return file->priv->deleted; + return priv->deleted; } void _gtk_source_file_set_readonly (GtkSourceFile *file, - gboolean readonly) + gboolean readonly) { + GtkSourceFilePrivate *priv = gtk_source_file_get_instance_private (file); + g_return_if_fail (GTK_SOURCE_IS_FILE (file)); readonly = readonly != FALSE; - if (file->priv->readonly != readonly) + if (priv->readonly != readonly) { - file->priv->readonly = readonly; - g_object_notify (G_OBJECT (file), "read-only"); + priv->readonly = readonly; + g_object_notify_by_pspec (G_OBJECT (file), properties[PROP_READ_ONLY]); } } @@ -669,7 +700,9 @@ _gtk_source_file_set_readonly (GtkSourceFile *file, gboolean gtk_source_file_is_readonly (GtkSourceFile *file) { + GtkSourceFilePrivate *priv = gtk_source_file_get_instance_private (file); + g_return_val_if_fail (GTK_SOURCE_IS_FILE (file), FALSE); - return file->priv->readonly; + return priv->readonly; } diff --git a/gtksourceview/gtksourcefile.h b/gtksourceview/gtksourcefile.h index 0e6b0163d8bfafd57f9eee371dd0f23c0359649b..baf95cafaabc26568b4fca1932b3aa9eca2be738 100644 --- a/gtksourceview/gtksourcefile.h +++ b/gtksourceview/gtksourcefile.h @@ -1,8 +1,7 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8; coding: utf-8 -*- */ /* * This file is part of GtkSourceView * - * Copyright (C) 2014, 2015 - Sébastien Wilmet + * Copyright 2014, 2015 - Sébastien Wilmet * * GtkSourceView is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -18,27 +17,19 @@ * along with this library; if not, see . */ -#ifndef GTK_SOURCE_FILE_H -#define GTK_SOURCE_FILE_H +#pragma once #if !defined (GTK_SOURCE_H_INSIDE) && !defined (GTK_SOURCE_COMPILATION) #error "Only can be included directly." #endif #include -#include -G_BEGIN_DECLS +#include "gtksourcetypes.h" -#define GTK_SOURCE_TYPE_FILE (gtk_source_file_get_type ()) -#define GTK_SOURCE_FILE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_SOURCE_TYPE_FILE, GtkSourceFile)) -#define GTK_SOURCE_FILE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_SOURCE_TYPE_FILE, GtkSourceFileClass)) -#define GTK_SOURCE_IS_FILE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_SOURCE_TYPE_FILE)) -#define GTK_SOURCE_IS_FILE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_SOURCE_TYPE_FILE)) -#define GTK_SOURCE_FILE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_SOURCE_TYPE_FILE, GtkSourceFileClass)) +G_BEGIN_DECLS -typedef struct _GtkSourceFileClass GtkSourceFileClass; -typedef struct _GtkSourceFilePrivate GtkSourceFilePrivate; +#define GTK_SOURCE_TYPE_FILE (gtk_source_file_get_type()) /** * GtkSourceNewlineType: @@ -93,105 +84,47 @@ typedef enum _GtkSourceCompressionType * Since: 3.14 */ typedef GMountOperation *(*GtkSourceMountOperationFactory) (GtkSourceFile *file, - gpointer userdata); - -struct _GtkSourceFile -{ - GObject parent; + gpointer userdata); - GtkSourceFilePrivate *priv; -}; +GTK_SOURCE_AVAILABLE_IN_3_14 +G_DECLARE_DERIVABLE_TYPE (GtkSourceFile, gtk_source_file, GTK_SOURCE, FILE, GObject) struct _GtkSourceFileClass { GObjectClass parent_class; - gpointer padding[10]; + /*< private >*/ + gpointer _reserved[10]; }; -GTK_SOURCE_AVAILABLE_IN_3_14 -GType gtk_source_file_get_type (void) G_GNUC_CONST; GTK_SOURCE_AVAILABLE_IN_3_14 -GtkSourceFile *gtk_source_file_new (void); - +GtkSourceFile *gtk_source_file_new (void); GTK_SOURCE_AVAILABLE_IN_3_14 -GFile *gtk_source_file_get_location (GtkSourceFile *file); - +GFile *gtk_source_file_get_location (GtkSourceFile *file); GTK_SOURCE_AVAILABLE_IN_3_14 -void gtk_source_file_set_location (GtkSourceFile *file, - GFile *location); - +void gtk_source_file_set_location (GtkSourceFile *file, + GFile *location); GTK_SOURCE_AVAILABLE_IN_3_14 -const GtkSourceEncoding * - gtk_source_file_get_encoding (GtkSourceFile *file); - +const GtkSourceEncoding *gtk_source_file_get_encoding (GtkSourceFile *file); GTK_SOURCE_AVAILABLE_IN_3_14 -GtkSourceNewlineType - gtk_source_file_get_newline_type (GtkSourceFile *file); - +GtkSourceNewlineType gtk_source_file_get_newline_type (GtkSourceFile *file); GTK_SOURCE_AVAILABLE_IN_3_14 -GtkSourceCompressionType - gtk_source_file_get_compression_type (GtkSourceFile *file); - +GtkSourceCompressionType gtk_source_file_get_compression_type (GtkSourceFile *file); GTK_SOURCE_AVAILABLE_IN_3_14 -void gtk_source_file_set_mount_operation_factory (GtkSourceFile *file, - GtkSourceMountOperationFactory callback, - gpointer user_data, - GDestroyNotify notify); - +void gtk_source_file_set_mount_operation_factory (GtkSourceFile *file, + GtkSourceMountOperationFactory callback, + gpointer user_data, + GDestroyNotify notify); GTK_SOURCE_AVAILABLE_IN_3_18 -void gtk_source_file_check_file_on_disk (GtkSourceFile *file); - +void gtk_source_file_check_file_on_disk (GtkSourceFile *file); GTK_SOURCE_AVAILABLE_IN_3_18 -gboolean gtk_source_file_is_local (GtkSourceFile *file); - +gboolean gtk_source_file_is_local (GtkSourceFile *file); GTK_SOURCE_AVAILABLE_IN_3_18 -gboolean gtk_source_file_is_externally_modified (GtkSourceFile *file); - +gboolean gtk_source_file_is_externally_modified (GtkSourceFile *file); GTK_SOURCE_AVAILABLE_IN_3_18 -gboolean gtk_source_file_is_deleted (GtkSourceFile *file); - +gboolean gtk_source_file_is_deleted (GtkSourceFile *file); GTK_SOURCE_AVAILABLE_IN_3_18 -gboolean gtk_source_file_is_readonly (GtkSourceFile *file); - -G_GNUC_INTERNAL -void _gtk_source_file_set_encoding (GtkSourceFile *file, - const GtkSourceEncoding *encoding); - -G_GNUC_INTERNAL -void _gtk_source_file_set_newline_type (GtkSourceFile *file, - GtkSourceNewlineType newline_type); - -G_GNUC_INTERNAL -void _gtk_source_file_set_compression_type (GtkSourceFile *file, - GtkSourceCompressionType compression_type); - -G_GNUC_INTERNAL -GMountOperation *_gtk_source_file_create_mount_operation (GtkSourceFile *file); - -G_GNUC_BEGIN_IGNORE_DEPRECATIONS -G_GNUC_INTERNAL -gboolean _gtk_source_file_get_modification_time (GtkSourceFile *file, - GTimeVal *modification_time); - -G_GNUC_INTERNAL -void _gtk_source_file_set_modification_time (GtkSourceFile *file, - GTimeVal modification_time); -G_GNUC_END_IGNORE_DEPRECATIONS - -G_GNUC_INTERNAL -void _gtk_source_file_set_externally_modified (GtkSourceFile *file, - gboolean externally_modified); - -G_GNUC_INTERNAL -void _gtk_source_file_set_deleted (GtkSourceFile *file, - gboolean deleted); - -G_GNUC_INTERNAL -void _gtk_source_file_set_readonly (GtkSourceFile *file, - gboolean readonly); +gboolean gtk_source_file_is_readonly (GtkSourceFile *file); G_END_DECLS - -#endif /* GTK_SOURCE_FILE_H */ diff --git a/gtksourceview/gtksourcefileloader.c b/gtksourceview/gtksourcefileloader.c index 381caec30a6715ca64443c441ed57da5e577ea49..ff02ab09187cd4f82bdbfe41ef833044c5908f6f 100644 --- a/gtksourceview/gtksourcefileloader.c +++ b/gtksourceview/gtksourcefileloader.c @@ -1,11 +1,10 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8; coding: utf-8 -*- */ /* * This file is part of GtkSourceView * - * Copyright (C) 2005 - Paolo Maggi - * Copyright (C) 2007 - Paolo Maggi, Steve Frécinaux - * Copyright (C) 2008 - Jesse van den Kieboom - * Copyright (C) 2014, 2016 - Sébastien Wilmet + * Copyright 2005 - Paolo Maggi + * Copyright 2007 - Paolo Maggi, Steve Frécinaux + * Copyright 2008 - Jesse van den Kieboom + * Copyright 2014, 2016 - Sébastien Wilmet * * GtkSourceView is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -21,15 +20,14 @@ * along with this library; if not, see . */ -#ifdef HAVE_CONFIG_H -#include -#endif +#include "config.h" -#include "gtksourcefileloader.h" #include + +#include "gtksourcefileloader.h" #include "gtksourcebuffer.h" -#include "gtksourcefile.h" -#include "gtksourcebufferoutputstream.h" +#include "gtksourcefile-private.h" +#include "gtksourcebufferoutputstream-private.h" #include "gtksourceencoding.h" #include "gtksourceencoding-private.h" #include "gtksource-enumtypes.h" @@ -89,8 +87,10 @@ enum G_FILE_ATTRIBUTE_STANDARD_SIZE "," \ G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE -struct _GtkSourceFileLoaderPrivate +struct _GtkSourceFileLoader { + GObject parent_instance; + /* Weak ref to the GtkSourceBuffer. A strong ref could create a * reference cycle in an application. For example a subclass of * GtkSourceBuffer can have a strong ref to the FileLoader. @@ -119,8 +119,7 @@ struct _GtkSourceFileLoaderPrivate GTask *task; }; -typedef struct _TaskData TaskData; -struct _TaskData +typedef struct { /* The two streams cannot be spliced directly, because: * (1) We need to call the progress callback. @@ -144,11 +143,11 @@ struct _TaskData guint guess_content_type_from_content : 1; guint tried_mount : 1; -}; +} TaskData; -G_DEFINE_TYPE_WITH_PRIVATE (GtkSourceFileLoader, gtk_source_file_loader, G_TYPE_OBJECT) +G_DEFINE_TYPE (GtkSourceFileLoader, gtk_source_file_loader, G_TYPE_OBJECT) -static void open_file (GTask *task); +static void open_file (GTask *task); static void read_file_chunk (GTask *task); static TaskData * @@ -197,36 +196,36 @@ get_compression_type_from_content_type (const gchar *content_type) static void gtk_source_file_loader_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) + guint prop_id, + const GValue *value, + GParamSpec *pspec) { GtkSourceFileLoader *loader = GTK_SOURCE_FILE_LOADER (object); switch (prop_id) { case PROP_BUFFER: - g_assert (loader->priv->source_buffer == NULL); - loader->priv->source_buffer = g_value_get_object (value); - g_object_add_weak_pointer (G_OBJECT (loader->priv->source_buffer), - (gpointer *)&loader->priv->source_buffer); + g_assert (loader->source_buffer == NULL); + loader->source_buffer = g_value_get_object (value); + g_object_add_weak_pointer (G_OBJECT (loader->source_buffer), + (gpointer *)&loader->source_buffer); break; case PROP_FILE: - g_assert (loader->priv->file == NULL); - loader->priv->file = g_value_get_object (value); - g_object_add_weak_pointer (G_OBJECT (loader->priv->file), - (gpointer *)&loader->priv->file); + g_assert (loader->file == NULL); + loader->file = g_value_get_object (value); + g_object_add_weak_pointer (G_OBJECT (loader->file), + (gpointer *)&loader->file); break; case PROP_LOCATION: - g_assert (loader->priv->location == NULL); - loader->priv->location = g_value_dup_object (value); + g_assert (loader->location == NULL); + loader->location = g_value_dup_object (value); break; case PROP_INPUT_STREAM: - g_assert (loader->priv->input_stream_property == NULL); - loader->priv->input_stream_property = g_value_dup_object (value); + g_assert (loader->input_stream_property == NULL); + loader->input_stream_property = g_value_dup_object (value); break; default: @@ -237,28 +236,28 @@ gtk_source_file_loader_set_property (GObject *object, static void gtk_source_file_loader_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) + guint prop_id, + GValue *value, + GParamSpec *pspec) { GtkSourceFileLoader *loader = GTK_SOURCE_FILE_LOADER (object); switch (prop_id) { case PROP_BUFFER: - g_value_set_object (value, loader->priv->source_buffer); + g_value_set_object (value, loader->source_buffer); break; case PROP_FILE: - g_value_set_object (value, loader->priv->file); + g_value_set_object (value, loader->file); break; case PROP_LOCATION: - g_value_set_object (value, loader->priv->location); + g_value_set_object (value, loader->location); break; case PROP_INPUT_STREAM: - g_value_set_object (value, loader->priv->input_stream_property); + g_value_set_object (value, loader->input_stream_property); break; default: @@ -272,28 +271,28 @@ gtk_source_file_loader_dispose (GObject *object) { GtkSourceFileLoader *loader = GTK_SOURCE_FILE_LOADER (object); - if (loader->priv->source_buffer != NULL) + if (loader->source_buffer != NULL) { - g_object_remove_weak_pointer (G_OBJECT (loader->priv->source_buffer), - (gpointer *)&loader->priv->source_buffer); + g_object_remove_weak_pointer (G_OBJECT (loader->source_buffer), + (gpointer *)&loader->source_buffer); - loader->priv->source_buffer = NULL; + loader->source_buffer = NULL; } - if (loader->priv->file != NULL) + if (loader->file != NULL) { - g_object_remove_weak_pointer (G_OBJECT (loader->priv->file), - (gpointer *)&loader->priv->file); + g_object_remove_weak_pointer (G_OBJECT (loader->file), + (gpointer *)&loader->file); - loader->priv->file = NULL; + loader->file = NULL; } - g_clear_object (&loader->priv->location); - g_clear_object (&loader->priv->input_stream_property); - g_clear_object (&loader->priv->task); + g_clear_object (&loader->location); + g_clear_object (&loader->input_stream_property); + g_clear_object (&loader->task); - g_slist_free (loader->priv->candidate_encodings); - loader->priv->candidate_encodings = NULL; + g_slist_free (loader->candidate_encodings); + loader->candidate_encodings = NULL; G_OBJECT_CLASS (gtk_source_file_loader_parent_class)->dispose (object); } @@ -311,12 +310,12 @@ set_default_candidate_encodings (GtkSourceFileLoader *loader) */ list = gtk_source_encoding_get_default_candidates (); - if (loader->priv->file == NULL) + if (loader->file == NULL) { goto end; } - file_encoding = gtk_source_file_get_encoding (loader->priv->file); + file_encoding = gtk_source_file_get_encoding (loader->file); if (file_encoding == NULL) { @@ -342,8 +341,8 @@ set_default_candidate_encodings (GtkSourceFileLoader *loader) list = g_slist_prepend (list, (gpointer) file_encoding); end: - g_slist_free (loader->priv->candidate_encodings); - loader->priv->candidate_encodings = list; + g_slist_free (loader->candidate_encodings); + loader->candidate_encodings = list; } static void @@ -351,18 +350,18 @@ gtk_source_file_loader_constructed (GObject *object) { GtkSourceFileLoader *loader = GTK_SOURCE_FILE_LOADER (object); - if (loader->priv->file != NULL) + if (loader->file != NULL) { set_default_candidate_encodings (loader); - if (loader->priv->location == NULL && - loader->priv->input_stream_property == NULL) + if (loader->location == NULL && + loader->input_stream_property == NULL) { - loader->priv->location = gtk_source_file_get_location (loader->priv->file); + loader->location = gtk_source_file_get_location (loader->file); - if (loader->priv->location != NULL) + if (loader->location != NULL) { - g_object_ref (loader->priv->location); + g_object_ref (loader->location); } else { @@ -453,26 +452,18 @@ gtk_source_file_loader_class_init (GtkSourceFileLoaderClass *klass) G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS)); - - /* Due to potential deadlocks when registering types, we need to - * ensure the dependent private class GtkSourceBufferOutputStream - * has been registered up front. - * - * See https://bugzilla.gnome.org/show_bug.cgi?id=780216 - */ - g_type_ensure (GTK_SOURCE_TYPE_BUFFER_OUTPUT_STREAM); } static void gtk_source_file_loader_init (GtkSourceFileLoader *loader) { - loader->priv = gtk_source_file_loader_get_instance_private (loader); + loader = gtk_source_file_loader_get_instance_private (loader); } static void close_input_stream_cb (GObject *source_object, - GAsyncResult *result, - gpointer user_data) + GAsyncResult *result, + gpointer user_data) { GInputStream *input_stream = G_INPUT_STREAM (source_object); GTask *task = G_TASK (user_data); @@ -596,8 +587,8 @@ write_file_chunk (GTask *task) static void read_cb (GObject *source_object, - GAsyncResult *result, - gpointer user_data) + GAsyncResult *result, + gpointer user_data) { GInputStream *input_stream = G_INPUT_STREAM (source_object); GTask *task = G_TASK (user_data); @@ -657,10 +648,10 @@ read_cb (GObject *source_object, /* Flush the stream to ensure proper line ending detection. */ g_output_stream_flush (G_OUTPUT_STREAM (task_data->output_stream), NULL, NULL); - loader->priv->auto_detected_encoding = + loader->auto_detected_encoding = gtk_source_buffer_output_stream_get_guessed (task_data->output_stream); - loader->priv->auto_detected_newline_type = + loader->auto_detected_newline_type = gtk_source_buffer_output_stream_detect_newline_type (task_data->output_stream); write_complete (task); @@ -717,11 +708,11 @@ create_input_stream (GTask *task) loader = g_task_get_source_object (task); task_data = g_task_get_task_data (task); - loader->priv->auto_detected_compression_type = GTK_SOURCE_COMPRESSION_TYPE_NONE; + loader->auto_detected_compression_type = GTK_SOURCE_COMPRESSION_TYPE_NONE; - if (loader->priv->input_stream_property != NULL) + if (loader->input_stream_property != NULL) { - task_data->input_stream = g_object_ref (loader->priv->input_stream_property); + task_data->input_stream = g_object_ref (loader->input_stream_property); } else if (g_file_info_has_attribute (task_data->info, G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE)) { @@ -731,7 +722,7 @@ create_input_stream (GTask *task) { case GTK_SOURCE_COMPRESSION_TYPE_GZIP: add_gzip_decompressor_stream (task); - loader->priv->auto_detected_compression_type = GTK_SOURCE_COMPRESSION_TYPE_GZIP; + loader->auto_detected_compression_type = GTK_SOURCE_COMPRESSION_TYPE_GZIP; break; case GTK_SOURCE_COMPRESSION_TYPE_NONE: @@ -751,8 +742,8 @@ create_input_stream (GTask *task) static void query_info_cb (GObject *source_object, - GAsyncResult *result, - gpointer user_data) + GAsyncResult *result, + gpointer user_data) { GFile *location = G_FILE (source_object); GTask *task = G_TASK (user_data); @@ -795,8 +786,8 @@ query_info_cb (GObject *source_object, static void mount_cb (GObject *source_object, - GAsyncResult *result, - gpointer user_data) + GAsyncResult *result, + gpointer user_data) { GFile *location = G_FILE (source_object); GTask *task = G_TASK (user_data); @@ -829,7 +820,7 @@ recover_not_mounted (GTask *task) loader = g_task_get_source_object (task); task_data = g_task_get_task_data (task); - mount_operation = _gtk_source_file_create_mount_operation (loader->priv->file); + mount_operation = _gtk_source_file_create_mount_operation (loader->file); DEBUG ({ g_print ("%s\n", G_STRFUNC); @@ -837,7 +828,7 @@ recover_not_mounted (GTask *task) task_data->tried_mount = TRUE; - g_file_mount_enclosing_volume (loader->priv->location, + g_file_mount_enclosing_volume (loader->location, G_MOUNT_MOUNT_NONE, mount_operation, g_task_get_cancellable (task), @@ -849,8 +840,8 @@ recover_not_mounted (GTask *task) static void open_file_cb (GObject *source_object, - GAsyncResult *result, - gpointer user_data) + GAsyncResult *result, + gpointer user_data) { GFile *location = G_FILE (source_object); GTask *task = G_TASK (user_data); @@ -902,7 +893,7 @@ open_file (GTask *task) loader = g_task_get_source_object (task); - g_file_read_async (loader->priv->location, + g_file_read_async (loader->location, g_task_get_priority (task), g_task_get_cancellable (task), open_file_cb, @@ -938,7 +929,7 @@ gtk_source_file_loader_error_quark (void) */ GtkSourceFileLoader * gtk_source_file_loader_new (GtkSourceBuffer *buffer, - GtkSourceFile *file) + GtkSourceFile *file) { g_return_val_if_fail (GTK_SOURCE_IS_BUFFER (buffer), NULL); g_return_val_if_fail (GTK_SOURCE_IS_FILE (file), NULL); @@ -962,8 +953,8 @@ gtk_source_file_loader_new (GtkSourceBuffer *buffer, */ GtkSourceFileLoader * gtk_source_file_loader_new_from_stream (GtkSourceBuffer *buffer, - GtkSourceFile *file, - GInputStream *stream) + GtkSourceFile *file, + GInputStream *stream) { g_return_val_if_fail (GTK_SOURCE_IS_BUFFER (buffer), NULL); g_return_val_if_fail (GTK_SOURCE_IS_FILE (file), NULL); @@ -998,18 +989,18 @@ gtk_source_file_loader_new_from_stream (GtkSourceBuffer *buffer, */ void gtk_source_file_loader_set_candidate_encodings (GtkSourceFileLoader *loader, - GSList *candidate_encodings) + GSList *candidate_encodings) { GSList *list; g_return_if_fail (GTK_SOURCE_IS_FILE_LOADER (loader)); - g_return_if_fail (loader->priv->task == NULL); + g_return_if_fail (loader->task == NULL); list = g_slist_copy (candidate_encodings); list = _gtk_source_encoding_remove_duplicates (list, GTK_SOURCE_ENCODING_DUPLICATES_KEEP_FIRST); - g_slist_free (loader->priv->candidate_encodings); - loader->priv->candidate_encodings = list; + g_slist_free (loader->candidate_encodings); + loader->candidate_encodings = list; } /** @@ -1024,7 +1015,7 @@ gtk_source_file_loader_get_buffer (GtkSourceFileLoader *loader) { g_return_val_if_fail (GTK_SOURCE_IS_FILE_LOADER (loader), NULL); - return loader->priv->source_buffer; + return loader->source_buffer; } /** @@ -1039,7 +1030,7 @@ gtk_source_file_loader_get_file (GtkSourceFileLoader *loader) { g_return_val_if_fail (GTK_SOURCE_IS_FILE_LOADER (loader), NULL); - return loader->priv->file; + return loader->file; } /** @@ -1055,7 +1046,7 @@ gtk_source_file_loader_get_location (GtkSourceFileLoader *loader) { g_return_val_if_fail (GTK_SOURCE_IS_FILE_LOADER (loader), NULL); - return loader->priv->location; + return loader->location; } /** @@ -1071,7 +1062,7 @@ gtk_source_file_loader_get_input_stream (GtkSourceFileLoader *loader) { g_return_val_if_fail (GTK_SOURCE_IS_FILE_LOADER (loader), NULL); - return loader->priv->input_stream_property; + return loader->input_stream_property; } /** @@ -1102,36 +1093,39 @@ gtk_source_file_loader_get_input_stream (GtkSourceFileLoader *loader) */ void gtk_source_file_loader_load_async (GtkSourceFileLoader *loader, - gint io_priority, - GCancellable *cancellable, - GFileProgressCallback progress_callback, - gpointer progress_callback_data, - GDestroyNotify progress_callback_notify, - GAsyncReadyCallback callback, - gpointer user_data) + gint io_priority, + GCancellable *cancellable, + GFileProgressCallback progress_callback, + gpointer progress_callback_data, + GDestroyNotify progress_callback_notify, + GAsyncReadyCallback callback, + gpointer user_data) { TaskData *task_data; gboolean implicit_trailing_newline; g_return_if_fail (GTK_SOURCE_IS_FILE_LOADER (loader)); g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable)); - g_return_if_fail (loader->priv->task == NULL); + g_return_if_fail (loader->task == NULL); - loader->priv->task = g_task_new (loader, cancellable, callback, user_data); - g_task_set_priority (loader->priv->task, io_priority); + loader->task = g_task_new (loader, cancellable, callback, user_data); + g_task_set_priority (loader->task, io_priority); task_data = task_data_new (); - g_task_set_task_data (loader->priv->task, task_data, task_data_free); + g_task_set_task_data (loader->task, task_data, task_data_free); task_data->progress_cb = progress_callback; task_data->progress_cb_data = progress_callback_data; task_data->progress_cb_notify = progress_callback_notify; - if (loader->priv->source_buffer == NULL || - loader->priv->file == NULL || - (loader->priv->location == NULL && loader->priv->input_stream_property == NULL)) + if (loader->source_buffer == NULL || + loader->file == NULL || + (loader->location == NULL && loader->input_stream_property == NULL)) { - g_task_return_boolean (loader->priv->task, FALSE); + g_task_return_new_error (loader->task, + G_IO_ERROR, + G_IO_ERROR_INVALID_ARGUMENT, + "Invalid argument"); return; } @@ -1146,36 +1140,36 @@ gtk_source_file_loader_load_async (GtkSourceFileLoader *loader, * location is directly needed (for example to display the filename in a * tab or an info bar with the progress information). */ - if (loader->priv->input_stream_property != NULL) + if (loader->input_stream_property != NULL) { - gtk_source_file_set_location (loader->priv->file, NULL); + gtk_source_file_set_location (loader->file, NULL); } else { - gtk_source_file_set_location (loader->priv->file, - loader->priv->location); + gtk_source_file_set_location (loader->file, + loader->location); } - implicit_trailing_newline = gtk_source_buffer_get_implicit_trailing_newline (loader->priv->source_buffer); + implicit_trailing_newline = gtk_source_buffer_get_implicit_trailing_newline (loader->source_buffer); /* The BufferOutputStream has a strong reference to the buffer. * We create the BufferOutputStream here so we are sure that the * buffer will not be destroyed during the file loading. */ - task_data->output_stream = gtk_source_buffer_output_stream_new (loader->priv->source_buffer, - loader->priv->candidate_encodings, + task_data->output_stream = gtk_source_buffer_output_stream_new (loader->source_buffer, + loader->candidate_encodings, implicit_trailing_newline); - if (loader->priv->input_stream_property != NULL) + if (loader->input_stream_property != NULL) { task_data->guess_content_type_from_content = TRUE; task_data->info = g_file_info_new (); - create_input_stream (loader->priv->task); + create_input_stream (loader->task); } else { - open_file (loader->priv->task); + open_file (loader->task); } } @@ -1196,8 +1190,8 @@ gtk_source_file_loader_load_async (GtkSourceFileLoader *loader, */ gboolean gtk_source_file_loader_load_finish (GtkSourceFileLoader *loader, - GAsyncResult *result, - GError **error) + GAsyncResult *result, + GError **error) { gboolean ok; gboolean update_file_properties; @@ -1226,7 +1220,7 @@ gtk_source_file_loader_load_finish (GtkSourceFileLoader *loader, real_error->domain == GTK_SOURCE_FILE_LOADER_ERROR && real_error->code == GTK_SOURCE_FILE_LOADER_ERROR_CONVERSION_FALLBACK); - if (update_file_properties && loader->priv->file != NULL) + if (update_file_properties && loader->file != NULL) { TaskData *task_data; @@ -1236,24 +1230,32 @@ gtk_source_file_loader_load_finish (GtkSourceFileLoader *loader, * operation. */ - _gtk_source_file_set_encoding (loader->priv->file, - loader->priv->auto_detected_encoding); + _gtk_source_file_set_encoding (loader->file, + loader->auto_detected_encoding); - _gtk_source_file_set_newline_type (loader->priv->file, - loader->priv->auto_detected_newline_type); + _gtk_source_file_set_newline_type (loader->file, + loader->auto_detected_newline_type); - _gtk_source_file_set_compression_type (loader->priv->file, - loader->priv->auto_detected_compression_type); + _gtk_source_file_set_compression_type (loader->file, + loader->auto_detected_compression_type); - _gtk_source_file_set_externally_modified (loader->priv->file, FALSE); - _gtk_source_file_set_deleted (loader->priv->file, FALSE); + _gtk_source_file_set_externally_modified (loader->file, FALSE); + _gtk_source_file_set_deleted (loader->file, FALSE); if (g_file_info_has_attribute (task_data->info, G_FILE_ATTRIBUTE_TIME_MODIFIED)) { - GTimeVal modification_time; + GDateTime *dt; + gint64 mtime = 0; + + dt = g_file_info_get_modification_date_time (task_data->info); + + if (dt != NULL) + { + mtime = g_date_time_to_unix (dt); + g_date_time_unref (dt); + } - g_file_info_get_modification_time (task_data->info, &modification_time); - _gtk_source_file_set_modification_time (loader->priv->file, modification_time); + _gtk_source_file_set_modification_time (loader->file, mtime); } if (g_file_info_has_attribute (task_data->info, G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE)) @@ -1263,15 +1265,15 @@ gtk_source_file_loader_load_finish (GtkSourceFileLoader *loader, readonly = !g_file_info_get_attribute_boolean (task_data->info, G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE); - _gtk_source_file_set_readonly (loader->priv->file, readonly); + _gtk_source_file_set_readonly (loader->file, readonly); } else { - _gtk_source_file_set_readonly (loader->priv->file, FALSE); + _gtk_source_file_set_readonly (loader->file, FALSE); } } - g_clear_object (&loader->priv->task); + g_clear_object (&loader->task); if (real_error != NULL) { @@ -1293,7 +1295,7 @@ gtk_source_file_loader_get_encoding (GtkSourceFileLoader *loader) { g_return_val_if_fail (GTK_SOURCE_IS_FILE_LOADER (loader), NULL); - return loader->priv->auto_detected_encoding; + return loader->auto_detected_encoding; } /** @@ -1309,7 +1311,7 @@ gtk_source_file_loader_get_newline_type (GtkSourceFileLoader *loader) g_return_val_if_fail (GTK_SOURCE_IS_FILE_LOADER (loader), GTK_SOURCE_NEWLINE_TYPE_LF); - return loader->priv->auto_detected_newline_type; + return loader->auto_detected_newline_type; } /** @@ -1325,5 +1327,5 @@ gtk_source_file_loader_get_compression_type (GtkSourceFileLoader *loader) g_return_val_if_fail (GTK_SOURCE_IS_FILE_LOADER (loader), GTK_SOURCE_COMPRESSION_TYPE_NONE); - return loader->priv->auto_detected_compression_type; + return loader->auto_detected_compression_type; } diff --git a/gtksourceview/gtksourcefileloader.h b/gtksourceview/gtksourcefileloader.h index 70fff263735186cbc8bc563dc9d9a03b676e6d20..3514056dfc604111d17ca2c10b1bafcb28819d39 100644 --- a/gtksourceview/gtksourcefileloader.h +++ b/gtksourceview/gtksourcefileloader.h @@ -1,11 +1,10 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8; coding: utf-8 -*- */ /* * This file is part of GtkSourceView * - * Copyright (C) 2005 - Paolo Maggi - * Copyright (C) 2007 - Paolo Maggi, Steve Frécinaux - * Copyright (C) 2008 - Jesse van den Kieboom - * Copyright (C) 2014 - Sébastien Wilmet + * Copyright 2005 - Paolo Maggi + * Copyright 2007 - Paolo Maggi, Steve Frécinaux + * Copyright 2008 - Jesse van den Kieboom + * Copyright 2014 - Sébastien Wilmet * * GtkSourceView is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -21,30 +20,21 @@ * along with this library; if not, see . */ -#ifndef GTK_SOURCE_FILE_LOADER_H -#define GTK_SOURCE_FILE_LOADER_H +#pragma once #if !defined (GTK_SOURCE_H_INSIDE) && !defined (GTK_SOURCE_COMPILATION) #error "Only can be included directly." #endif #include -#include -#include -G_BEGIN_DECLS - -#define GTK_SOURCE_TYPE_FILE_LOADER (gtk_source_file_loader_get_type()) -#define GTK_SOURCE_FILE_LOADER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GTK_SOURCE_TYPE_FILE_LOADER, GtkSourceFileLoader)) -#define GTK_SOURCE_FILE_LOADER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), GTK_SOURCE_TYPE_FILE_LOADER, GtkSourceFileLoaderClass)) -#define GTK_SOURCE_IS_FILE_LOADER(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), GTK_SOURCE_TYPE_FILE_LOADER)) -#define GTK_SOURCE_IS_FILE_LOADER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_SOURCE_TYPE_FILE_LOADER)) -#define GTK_SOURCE_FILE_LOADER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GTK_SOURCE_TYPE_FILE_LOADER, GtkSourceFileLoaderClass)) +#include "gtksourcetypes.h" +#include "gtksourcefile.h" -typedef struct _GtkSourceFileLoaderClass GtkSourceFileLoaderClass; -typedef struct _GtkSourceFileLoaderPrivate GtkSourceFileLoaderPrivate; +G_BEGIN_DECLS -#define GTK_SOURCE_FILE_LOADER_ERROR gtk_source_file_loader_error_quark () +#define GTK_SOURCE_TYPE_FILE_LOADER (gtk_source_file_loader_get_type()) +#define GTK_SOURCE_FILE_LOADER_ERROR (gtk_source_file_loader_error_quark()) /** * GtkSourceFileLoaderError: @@ -63,78 +53,47 @@ typedef enum _GtkSourceFileLoaderError GTK_SOURCE_FILE_LOADER_ERROR_CONVERSION_FALLBACK } GtkSourceFileLoaderError; -struct _GtkSourceFileLoader -{ - GObject parent; - - GtkSourceFileLoaderPrivate *priv; -}; - -struct _GtkSourceFileLoaderClass -{ - GObjectClass parent_class; - - gpointer padding[10]; -}; - GTK_SOURCE_AVAILABLE_IN_3_14 -GType gtk_source_file_loader_get_type (void) G_GNUC_CONST; +G_DECLARE_FINAL_TYPE (GtkSourceFileLoader, gtk_source_file_loader, GTK_SOURCE, FILE_LOADER, GObject) GTK_SOURCE_AVAILABLE_IN_3_14 -GQuark gtk_source_file_loader_error_quark (void); - +GQuark gtk_source_file_loader_error_quark (vo