diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml new file mode 100644 index 000000000..47ee72242 --- /dev/null +++ b/.github/workflows/docs.yml @@ -0,0 +1,29 @@ +name: Documentation +on: + push: + branches: + - master + - main +permissions: + contents: read + pages: write + id-token: write +jobs: + deploy: + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + runs-on: ubuntu-latest + steps: + - uses: actions/configure-pages@v6 + - uses: actions/checkout@v6 + - uses: actions/setup-python@v6 + with: + python-version: 3.x + - run: pip install zensical + - run: zensical build --clean + - uses: actions/upload-pages-artifact@v5 + with: + path: site + - uses: actions/deploy-pages@v5 + id: deployment diff --git a/.gitignore b/.gitignore index f1621826f..4242603bc 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ +site/ /build/ build-* /distr/ diff --git a/README.md b/README.md index d80b24c8a..b93cd81a9 100644 --- a/README.md +++ b/README.md @@ -18,6 +18,8 @@ Features added are: * bookmarking all predecsessors or successors of a given node (for later analysis) * **custom commands** (to perform any user-defined action on nodes/edges, e.g., open a terminal at a given path, open a web page, etc.) + + ## Usage We strongly recommend using the provided Docker image to run NumbatUI, as @@ -67,6 +69,35 @@ one needs to forward the X11/Wayland display to the container. ``` +## Supported Languages + +### C + +C support is powered by [Clang](https://clang.llvm.org/), with **LLVM/Clang 19** +as the hard minimum (matching Debian trixie's default toolchain). For issues +loading C code, have a look at [Clang language compatibility](https://clang.llvm.org/compatibility.html) +or report a bug in our [issue tracker](https://github.com/quarkslab/NumbatUI/issues). + +### C++ + +C++ support is powered by [Clang](https://clang.llvm.org/), with **LLVM/Clang 19** +as the hard minimum. For more information please visit +[Clang C++ Status](https://clang.llvm.org/cxx_status.html). For issues loading +C++ code, have a look at [Clang language compatibility](https://clang.llvm.org/compatibility.html) +or report a bug in our [issue tracker](https://github.com/quarkslab/NumbatUI/issues). + +> [!NOTE] +> C/C++ indexing is built only when `-DBUILD_CXX_LANGUAGE_PACKAGE=ON` is passed +> to CMake. It is **off by default** in the current builds while it is being +> stabilized, so the prebuilt Docker image and `.deb` ship without it for now. + +### Python + +Python indexing (inherited from Sourcetrail's `SourcetrailPythonIndexer`) is +currently **disabled by design** and is not built. Support may be revisited in +a future release. + + ## Manual Installation As this fork is currently a WIP, the application should be compiled by the user. Build instructions are provided for Linux and macOS. @@ -129,8 +160,11 @@ The compiled binary is available in `build/app/NumbatUI` on Unix The binary is a native arm64 (or x86_64) Mach-O on macOS — no X11 / XQuartz forwarding required, unlike the Docker image documented above. -Note: This build purposely disables C++, Python language indexation features. -They shall be re-enabled in future releases. +Note: this command disables both the C/C++ and Python indexing features. C/C++ +indexing has been ported to LLVM/Clang 19 and can be re-enabled by passing +`-DBUILD_CXX_LANGUAGE_PACKAGE=ON` (which then requires the LLVM 19 packages +listed above); it is kept off in the default build while it is stabilized. +Python indexing remains disabled by design. ### Debian package (.deb) diff --git a/debian/changelog b/debian/changelog index 0c8e22a47..0fbb7448f 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,16 @@ +numbatui (0.0.0+git20260618) unstable; urgency=medium + + * Enable the C/C++ language indexing back-end + (-DBUILD_CXX_LANGUAGE_PACKAGE=ON), built against LLVM/Clang 19. + * Add llvm-19-dev, libclang-19-dev, libclang-cpp19-dev and clang-19 to + Build-Depends; pin Clang_DIR/LLVM_DIR to the LLVM 19 toolchain. + * Ship Clang's builtin compiler headers under the indexer data directory + and add the corresponding lintian overrides. + * Update the package description to reflect that C/C++ indexing is now + available (Python indexing remains disabled). + + -- Quarkslab Thu, 18 Jun 2026 07:41:39 +0000 + numbatui (0.0.0+git20260604) unstable; urgency=medium * Initial Debian packaging. diff --git a/debian/control b/debian/control index d95ea656b..f4cc05ddf 100644 --- a/debian/control +++ b/debian/control @@ -15,6 +15,10 @@ Build-Depends: libboost-program-options-dev, libboost-system-dev, libboost-date-time-dev, + llvm-19-dev, + libclang-19-dev, + libclang-cpp19-dev, + clang-19, imagemagick, Standards-Version: 4.6.2 Homepage: https://github.com/quarkslab/NumbatUI @@ -30,6 +34,7 @@ Description: source code and graph explorer (Quarkslab fork of Sourcetrail) you navigate code through linked graph and code views. It is designed to explore graph-based data generated by Numbat. . - This package ships the GUI application and its indexer. The C/C++ and Python - language indexing back-ends are disabled in this build and will be enabled in - a future release. + This package ships the GUI application and its indexer, including the C/C++ + language indexing back-end (built against LLVM/Clang 19). The Python language + indexing back-end is disabled in this build and will be enabled in a future + release. diff --git a/debian/numbatui.lintian-overrides b/debian/numbatui.lintian-overrides index 7d509521f..c2276003a 100644 --- a/debian/numbatui.lintian-overrides +++ b/debian/numbatui.lintian-overrides @@ -10,3 +10,13 @@ numbatui: embedded-library # fonts-roboto-* packages; replacing the bundled copies with symlinks plus a # dependency is left for a future change. numbatui: duplicate-font-file + +# The C/C++ indexer requires Clang's builtin compiler headers (stddef.h, +# stdarg.h, intrinsics, ...) at the fixed runtime path +# /data/cxx/include. These are copied from the build-time +# LLVM/Clang 19 resource directory into the package, as inherited from upstream +# Sourcetrail. They duplicate files from libclang-common-19-dev, but the indexer +# resolves them relative to its own data dir and cannot rely on a system path, +# so the copy is intentional and known. +numbatui: package-installs-something-onto-an-existing-symlink +numbatui: file-references-package-build-path diff --git a/debian/rules b/debian/rules index 57d307130..eb86139ee 100755 --- a/debian/rules +++ b/debian/rules @@ -11,10 +11,12 @@ export DH_VERBOSE = 1 override_dh_auto_configure: dh_auto_configure -- \ -DCMAKE_BUILD_TYPE=Release \ - -DBUILD_CXX_LANGUAGE_PACKAGE=OFF \ + -DBUILD_CXX_LANGUAGE_PACKAGE=ON \ -DBUILD_PYTHON_LANGUAGE_PACKAGE=OFF \ -DTREAT_WARNINGS_AS_ERRORS=OFF \ - -DCMAKE_SKIP_INSTALL_RPATH=ON + -DCMAKE_SKIP_INSTALL_RPATH=ON \ + -DClang_DIR=/usr/lib/llvm-19/lib/cmake/clang \ + -DLLVM_DIR=/usr/lib/llvm-19/lib/cmake/llvm # Build the GUI and the indexer explicitly. This avoids building the (test) # targets, which are not packaged, and does not rely on the GUI target's diff --git a/docs/getting_started.md b/docs/getting_started.md new file mode 100644 index 000000000..8e2da12f5 --- /dev/null +++ b/docs/getting_started.md @@ -0,0 +1,177 @@ +--- +icon: lucide/badge-info +--- +# Getting Started + +This short introduction will briefly guide you through the project setup and the user interface of NumbatUI. The bullet point lists will provide you with the next steps to take: + +## Starting Up NumbatUI + +![Start Windows](documentation/start_window.png){ width="400", align="right" } + +Once you've installed NumbatUI successfully you are ready to run the application. For assistance with installation, visit the [installation](!installation) section. + +!!! example "Tasks" + * Launch NumbatUI. + +After launching NumbatUI you will see the [Start Window](!interface#start-window). From here you can create your own project or choose a pre-indexed one. + +!!! example "Tasks" + * Click **New Project** to create a new project. + * or select one from the **Recent Projects** _(ex: TicTacToe)_ and continue with the [UI Intro](!interface#ui-intro) + + + +## Creating a New Project + +When creating a new NumbatUI project you will use the [Project Setup Wizard](!interface#project-setup-wizard). This wizard splits the setup process into several subsequent steps. Depending on your project's structure and the used build system, there are different types for project setup. Choosing the correct setup method is important and can make the setup process a lot easier. + +!!! example "Tasks" + * Give your project a **Name** and select a **Location** for your NumbatUI project to live. + * Click **Add Source Group** to add source files to the project. + +Project Setup Wizard Start + +### Add Source Group + +NumbatUI projects consist of multiple *Source Groups*. Each Source Group uses a certain language, a set of files, and all configurations to index these files. There are different types of Source Groups for each supported programming language. In addition, creating a single Source Group is sufficient for most projects. + +Scroll past the image for detailed instructions on setting this up. + +!!! example "Tasks" + * Select your chosen **Source Group** setup type and come back here as soon as the project is created. + +Project Setup Wizard Source Group Type + +=== "Source Group Setup for C/C++" + + The Source Group setup types for C & C++ are the same. + + **Are you using CMake, Make or Qt Creator?** + + If you are using [CMake](https://cmake.org/) or [Make](https://www.gnu.org/software/make/) as build environment you can export a [clang JSON Compilation Database](https://clang.llvm.org/docs/JSONCompilationDatabase.html) as `compile_commands.json` file. A Compilation Database holds all information necessary for building the project, such as source files, include paths and compiler flags. Having a Compilation Database makes project setup within NumbatUI a lot easier. We recommend using this approach if possible. + + Exporting a Compilation Database: + + * From **CMake** by defining the `CMAKE_EXPORT_COMPILE_COMMANDS` flag. (not supported on for Visual Studio CMake generators) + * For **Make** projects use [Bear](https://github.com/rizsotto/Bear). Bear generates a `compile_commands.json` file during a simulated build process. Bear has been tested on FreeBSD, GNU/Linux and OS X. + * From **Qt Creator since version 4.8** by selecting the "Generate Compilation Database" from the "Build" menu. + + If you managed to export a `compile_commands.json` file, then please continue at [Create a Source Group from Compilation Database](!interface#create-a-project-from-compilation-database) and come back after you finished creating the project. + + Project Setup Wizard Start CDB + + + + **Create Empty** + + If neither of the above options apply to your project, please continue at [create an empty C/C++ Source Group](!interface#create-an-empty-cxx-project) and return here once the project is created. + + Project Setup Wizard Source Group Type + +=== "Source Group Setup for Python" + + **Create empty** + + If you want to browse your Python source code with NumbatUI, please continue at [Create an Empty Python Source Group](!interface#create-an-empty-python-project) and come back here as soon as the project is created. + + Project Setup Wizard Start Python Empty + +### Source Indexing + +After the project is created, NumbatUI will ask you whether you want to start indexing. Click **Start** and wait for the indexing to complete. This may take a bit of time. The [Indexing Dialog](!interface#indexing-dialogs) and the [Status Bar](!interface#status-bar) will give you information about the progress. Otherwise the UI will be empty. NumbatUI indexes all named symbols and their relationships throughout the provided source files. + +!!! example "Tasks" + * Click **Start** when asked whether to start indexing. + * Wait until the indexing of your source files has finished. + * or Click **Stop** or press ESC to stop indexing (NumbatUI will provide all information gathered so far and the indexing can be continued later by [refreshing](!interface#refresh)). + +!["Indexing"](documentation/indexing.png "Indexing") + +After indexing is completed, NumbatUI will show an overview of all indexed symbols in the [graph view](!interface#graph-view) and some statistics in the [code view](!interface#code-view). + +### Troubleshooting Errors + +If the indexing yields errors, the status view will be shown with a list of errors. You can click on the errors label on the right side of the status bar or on one of the errors in the table to see their location. + +!!! example "Tasks" + * Fix your errors and [refresh](!interface#refresh) to re-index the files with errors (Open Issue: As long as there was no change in the specific file, NumbatUI won't reindex it, use the **Force Refresh** option from the [Edit Menu](!interface#edit)). + * or ignore them and continue with an incomplete index. + +!["Error View"](documentation/error_view.png "Error View") + +## User Interface + +As mentioned earlier, NumbatUI's user interface is split into three main views. Their arrangement can be adjusted as preferred and can also be detached from the main window and split into different screens (see [Window Widgets](!interface#widget-windows)). + +All three views display information about the currently selected symbol: + +!["Main Screen"](documentation/main_screen.png "Main Screen") + +### 1. Search Field + +The [Search Field](!interface#search-bar) allows for easy access to all indexed symbols. Use it to find all classes and functions you wish to investigate. In addition, it also holds the UI buttons for navigating [back & forward](!interface#back-&-forward) as well as [refreshing](!interface#refresh). + +Search View + +When entering a search query, the [autocompletion popup](!interface#autocompletion-popup) will provide you with a concise list of all matching symbols. Note that NumbatUI uses a fuzzy matching algorithm, that allows you to skip characters while entering a query. + +Search View Completion + +### 2. Graph Visualization + +The [graph visualization](!interface#graph-view) displays the currently selected symbol in an active state and all the other symbols it shares a relationship with. The visualization is made up of nodes and edges. + +* **Nodes:** All named symbols in your source code will be displayed as different [nodes](!interface#nodes), such as `functions`, `classes` or `files`. Nodes with members (like `classes`) can be expanded to show all their contents, the number at the expansion arrow shows how many members are hidden. Clicking a node will activate it and update all the views to the new selection. Dragging a node can be used to change its position. +* **Edges:** The relationships between the symbols are displayed as different [edges](!interface#edges), such as `type use`, `function call` or `file include`. Sometimes edges get bundled together and are displayed as `bundled edges` that show a number of how many edges are contained. Clicking an edge will highlight its source location in the code view. + +!["Graph View Graph"](documentation/graph_view_graph.png "Graph View Graph") + +* **Colors:** The different node and edge types are also displayed using different colors. The default color scheme uses this convention: + + | Color | Node | Edge + | --- | --- | --- + | gray | types and classes | type use + | yellow | functions and methods | calls + | blue | variables and fields | variable access + +* **Hatching:** Nodes displayed with a striped hatching, are nodes that were used within your indexed source files, but were not defined. Clicking them shows all locations where they are used, without providing their declaration. + + !["Node Non Indexed"](documentation/node_non_indexed.png "Node Non Indexed") + +* **Legend:** For a full list on all existing nodes and edges take a look at the integrated [Graph Legend](!interface#graph-legend) by clicking the `?`-button in the bottom right corner of the [Graph View](!interface#graph-view). + +### 3. Code View + +The [code view](!interface#code-view) displays all locations of the currently active symbol within the indexed source files. It does not allow for editing the source code. Syntax highlighting is used to increase readability. Source locations that are surrounded by a box when hovered can be clicked to activate the respective symbol. Active source locations are highlighted. + +Code View + +The source locations are displayed as code snippets, containing the line of interest and extra lines added to the top and bottom to give information about its context. Code snippets are then bundled together into files. + +**Note:** A file can be selected as active symbol by clicking its name in the title bar. By clicking the title bar or the icon on the right hand side of the title bar, the file can switch between 3 different states: + +* **Minimized:** The file does not show any content + +Snippet Minimized + +* **Snippets:** The file displays the snippets containing active locations separated by lines. + +Snippet Snippets + +* **Maximized:** The [code view](!interface#code-view) switches to [single file mode](!interface#single-file-mode) and the whole content of the file is visible. + +Code View Single + +For more information, please visit the [Code View Files](!interface#files) section. + +## Start Exploring! + +At this point, you should have an understanding of the basics of NumbatUI's user interface and can begin exploring your codebase. NumbatUI will allow you to see your source code from a whole new perspective, by giving you a concise overview of its parts and a faster way of drilling down to its internals, while always maintaining the connection to the implementation details of the actual source code. + +Please take look at the much more extensive instruction manual below for detailed information. + +The NumbatUI team wishes you a good start with our product, lots of saved time, increased productivity and much cleaner code. + +!!! example "Tasks" + * Start exploring and have fun! diff --git a/docs/index.md b/docs/index.md new file mode 100644 index 000000000..0527d5e61 --- /dev/null +++ b/docs/index.md @@ -0,0 +1,4 @@ +--- +icon: lucide/rocket +--- +--8<-- "README.md" \ No newline at end of file diff --git a/docs/installation.md b/docs/installation.md new file mode 100644 index 000000000..dd31a63f5 --- /dev/null +++ b/docs/installation.md @@ -0,0 +1,240 @@ +--- +icon: lucide/file-terminal +--- +# Installation + +!!! warning + NumbatUI is in active development and still unstable. We recommend waiting + for our first releases before relying on it for production work. + +NumbatUI does not yet ship prebuilt installers. There are three supported ways +to get it running, in increasing order of integration with your system: + +* the **Docker image**, which bundles every dependency and is the recommended + way to try NumbatUI; +* a **manual build** from source on Linux or macOS; +* a native **Debian package** (`.deb`) on Debian/Ubuntu. + +## Docker (recommended) + +The Docker image contains all required dependencies. Either build it locally: + +```bash +cd docker +docker build -t numbatui . +``` + +or pull it from the GitHub Container Registry: + +```bash +docker pull ghcr.io/quarkslab/numbatui:main +``` + +NumbatUI is a Qt GUI application, so the container needs access to your display +server. Open a `*.srctrlprj` database by mounting its directory and forwarding +X11 or Wayland. + +=== "X11" + + You may need to allow `docker` to use your Xserver first: + + ```bash + xhost +local:docker + ``` + + ```bash + docker run -it --rm \ + --env DISPLAY=$DISPLAY \ + --env QT_X11_NO_MITSHM=1 \ + --volume /tmp/.X11-unix:/tmp/.X11-unix \ + --volume /path/to/:/data/ \ + numbatui:latest /data/my_database.srctrlprj + ``` + + After usage you can revoke the authorization with `xhost -local:docker`. + +=== "Wayland" + + ```bash + docker run -it --rm \ + --env QT_QPA_PLATFORM=wayland \ + --env XDG_RUNTIME_DIR=$XDG_RUNTIME_DIR \ + --env WAYLAND_DISPLAY=$WAYLAND_DISPLAY \ + --volume /run/user/1000/$WAYLAND_DISPLAY:/run/user/1000/$WAYLAND_DISPLAY \ + --volume /usr/share/wayland-sessions:/usr/share/wayland-sessions \ + --volume /path/to/:/data/ \ + numbatui:latest /data/my_database.srctrlprj + ``` + +!!! note "Docker on macOS" + The image is Linux-only and talks to X11/Wayland, neither of which is + native on macOS. Running it there requires installing + [XQuartz](https://www.xquartz.org/) and forwarding the display over TCP — + workable but slow. On macOS, prefer the native build below. + +## Manual build + +Build instructions are provided for Linux and macOS. + +### Requirements + +=== "Linux (Ubuntu/Debian)" + + * base tooling: `build-essential`, `cmake`, `git`, `unzip`, `wget` + * LLVM/Clang 19: `clang-19`, `llvm-19-dev`, `libclang-19-dev`, + `liblld-19-dev`, `libc++-19-dev` + * Boost: `libboost-filesystem-dev`, `libboost-program-options-dev`, + `libboost-system-dev`, `libboost-date-time-dev` + * Qt6: `qt6-base-dev`, `qt6-svg-dev`, `qt6-5compat-dev` + +=== "macOS (Homebrew)" + + Tested on Apple Silicon (arm64) with macOS 26 / Tahoe and Homebrew Qt 6.11. + + ```bash + brew install cmake boost qt@6 + # Only needed if you re-enable BUILD_CXX_LANGUAGE_PACKAGE: + # brew install llvm@19 + ``` + +### Compilation + +=== "Linux" + + ```bash + git clone --recurse-submodules https://github.com/quarkslab/NumbatUI.git + cd NumbatUI + + cmake -B build \ + -DCMAKE_BUILD_TYPE="Release" \ + -DBUILD_CXX_LANGUAGE_PACKAGE=OFF \ + -DBUILD_PYTHON_LANGUAGE_PACKAGE=OFF + + cmake --build build --target NumbatUI -j $(nproc) + ``` + +=== "macOS" + + Point CMake at the Homebrew Qt6 install and use `sysctl` for the parallel + job count: + + ```bash + git clone --recurse-submodules https://github.com/quarkslab/NumbatUI.git + cd NumbatUI + + cmake -B build \ + -DCMAKE_BUILD_TYPE="Release" \ + -DBUILD_CXX_LANGUAGE_PACKAGE=OFF \ + -DBUILD_PYTHON_LANGUAGE_PACKAGE=OFF \ + -DCMAKE_PREFIX_PATH=$(brew --prefix qt@6) + + cmake --build build --target NumbatUI -j $(sysctl -n hw.logicalcpu) + ``` + +The compiled binary is available at `build/app/NumbatUI` on Unix (or +`build/Release/app/` on Windows). Launch it directly: + +```bash +./build/app/NumbatUI # macOS / Linux +./build/app/NumbatUI /path/to/my_database.srctrlprj # open a project +``` + +On macOS the binary is a native arm64 (or x86_64) Mach-O — no X11 / XQuartz +forwarding required, unlike the Docker image. + +!!! note + This build purposely disables the C++ and Python language indexing + features. C++ indexing is being re-enabled (see + [Supported Languages](!index#supported-languages)); when built with + `-DBUILD_CXX_LANGUAGE_PACKAGE=ON` it targets LLVM/Clang 19 as a hard + minimum. + +## Debian package (.deb) + +On Debian/Ubuntu, NumbatUI can be installed as a native `.deb` package. This +installs the GUI and indexer to `/usr/bin`, the runtime data to +`/usr/share/numbatui`, and registers the desktop entry, MIME association +(`*.srctrlprj`) and application icons. + +### Install a prebuilt package + +Every push to the `main` and `dev` branches builds a `.deb` in CI. Download it +from the **Actions** tab: open the latest *Build Debian package* run and grab +the `numbatui-deb--` artifact (tagged `v*` releases also attach the +`.deb` to the GitHub release). Then: + +```bash +sudo apt install ./numbatui_*_amd64.deb +``` + +`apt` pulls in the required Qt 6 and Boost runtime libraries automatically. + +### Build the package yourself + +From a checkout of the repository: + +```bash +# one-off: install the build dependencies declared in debian/control +sudo apt build-dep . +# or, without a deb-src entry: +# sudo apt install devscripts equivs && sudo mk-build-deps -i debian/control + +# build the binary package (the .deb is written to the parent directory) +dpkg-buildpackage -us -uc -b +ls ../numbatui_*_amd64.deb +``` + +The packaging lives in `debian/` and drives the same CMake build as the manual +build through `debhelper`. See +[`debian/README.source`](https://github.com/quarkslab/NumbatUI/blob/dev/debian/README.source) +for the packaging design and how to bump the package version. + +## Data folder + +On first launch NumbatUI creates a configuration folder holding settings and a +copy of its user templates. After installation the data folder is located here: + +| Platform | Location +| --- | --- +| Linux | `~/.config/numbatui` +| macOS | `~/Library/Application Support/numbatui` + +A `.deb` install additionally ships the static runtime data under +`/usr/share/numbatui` and the per-user template tree that is copied into +`~/.config/numbatui` on first launch. + +## Finding System Header Locations + +When indexing C/C++ projects without a compilation database, NumbatUI needs to +know where your compiler's system headers live. + +### macOS + +Run this command in your terminal: +`gcc -x c++ -v -E /dev/null` +You will find the header search paths your compiler uses in the output between +these two lines: + +``` +#include <...> search starts here: +. +. +. +End of search list. +``` + +### Linux + +`gcc -x c++ -v -E /dev/null` +or +`clang -x c++ -v -E /dev/null` +You will find the header search paths your compiler uses in the output between +these two lines: + +``` +#include <...> search starts here: +. +. +. +End of search list. +``` diff --git a/docs/interface.md b/docs/interface.md new file mode 100644 index 000000000..b7bf9bce2 --- /dev/null +++ b/docs/interface.md @@ -0,0 +1,794 @@ +--- +icon: lucide/app-window +--- +# Interface +## Main Window + +### Subwindows + +NumbatUI's three views are organized into subwindows, which can be freely arranged within the Main Window or detached from it. Each subwindow has a title bar displaying its name and 2 buttons for closing the subwindow and for detaching it from the Main Window. + +!["Main Window"](documentation/main_window.png "Main Window") + +!!! abstract "Interactions" + * Drag the subwindow at the title bar to rearrange it within the Main Window, detach it or attach it again. + * Press the "x" icon to close the subwindow. They can be reopened from the [View Menu](#view). + * Press the "□" icon to detach the subwindow from the Main Window. + +### Tab Bar + +The Tab Bar is located at the top of the [Main Window](#main-window) and is used to open multiple symbols in parallel. + +!["Tab Bar"](documentation/tab_bar.png "Tab Bar") + +!!! abstract "Interactions" + * Click on the `+` icon to open a new tab or use the [New Tab Shortcut](#shortcuts). + * Click on a tab to activate it and show it's content or use the [Next/Previous Tab Shortcuts](#shortcuts). + * Click on the `x` icon on the right of each tab to close it or use the [Close Tab Shortcut](#shortcuts). + * Click and drag a tab to change it's position. + +### Status Bar + +The Status Bar is located on the bottom of the [Main Window](#main-window) and is used to convey information about NumbatUI's status and currently running processes to the user + +It displays: + +* The most recent status message. +* Error Count if the currently loaded project has errors. +* Indexing progress bar while indexing. + +!["Status Bar"](documentation/status_bar.png "Status Bar") + +!!! abstract "Interactions" + * Click on the status message count to display the (Status Tab](#status-tab). + * Click on the error count to display the error locations in the [Code View](#code-view). + * Click on the indexing progress bar to display the [Indexing Dialogs](#indexing-dialogs) if they were hidden. + +### On-Screen Search Bar + +The On-Screen Search Bar is used to search visible contents of the [Graph View](#graph-view) and [Code View](#code-view). It gets displayed at the bottom of the [Main Window](#main-window) when using the [Find On-Screen](#shortcuts) action. + +!["Onscreen Search Bar"](documentation/onscreen_search_bar.png "Onscreen Search Bar") + +!!! abstract "Interactions" + * Enter a search query to search in contents of the [Graph View](#graph-view) and [Code View](#code-view). + * Click the arrow buttons next to the search field to iterate the matched locations. + * Use the checkboxes right of the search field to define which view contents will be matched. + * Click the `x` icon on the right to close the On-Screen Search Bar or press `ESC`. + +## Windows + +### Start Window + +On every start of NumbatUI you are shown the start window. It allows for creating new projects or opening existing ones. + +Start Window + +!!! abstract "Interactions" + * Clicking `New Project` will lead you to [Project Setup](#project-setup-wizard). + * Clicking `Open Project` will let you open an existing NumbatUI project by choosing from a file dialog. + * Clicking on one of the `Recent Projects` will open this project. The list shows a maximum of 7 items ordered by recent first. + * Pressing `ESC` will close the window. + * Click `Check for new version` to connect to [https://sourcetrail.com](https://sourcetrail.com) and check if a new version is available. + + +### Path List Box + +The Path List Box is a user interface element that is used within the [Preferences Window](#preferences-window) and the [Project Setup Wizard](#project-setup-wizard). It allows for entering a list of file and directory paths. +If you want to use environment variables you can use either of the following notations. +`${VARIABLE_NAME}` or `%VARIABLE_NAME%` + +Path List Box + +!!! abstract "Interactions" + * Click the "+" icon to add a new path line. + * Click the "-" icon to remove a selected path line. + * Click a path line to select it. + * Enter the path by typing on your keyboard + * Click "..." within the path line to open a file dialog for choosing a file or directory path. + * Directly add multiple paths into the box by dropping elements from your filesystem. + * Click the pen icon in the bottom right corner to edit the list as plain text. + +#### Plain Text Editing + +By pressing the pen icon in the bottom right corner you can open the plain text edition dialog. It allows you to edit the whole list within a text field. Each line will be one list item. + +Path List Box Edit + +!!! abstract "Interactions" + * Add and remove list items through keyboard interaction. + * Click `Cancel` to cancel plain text editing. + * Click `Save` to save your changes to the list. + +### Preferences Window + +The Preferences window lets you define settings for all projects. You can open the Preferences from the menu via [Edit/Preferences](#edit). + +Preferences Screen + +| Setting | Description +| --- | --- +| Font Face | Define the font face used throughout the UI +| Font Size | Set the font size used throughout the UI. It can also be changed with the actions in the [View Menu](#view) +| Tab Width | Define the space width of tabs in the code view. +| Text Encoding | Define the Text Encoding used for displaying your source code. +| Color scheme | Choose which color scheme NumbatUI should display. The color schemes are located in [data](!installation#datafolder)/color_schemes/ +| Animations | Define if animations are used within the user interface. +| Built-In Types | Define whether built-in types such as int or bool are shown when referenced in the graph view. +| Directory in File Title | Enable display of the parent directory of a code file relative to the project file. +| Auto Scaling to DPI | **(Linux only)** Define if automatic scaling to screen DPI resolution is active. This setting manipulates the environment flag `QT_AUTO_SCREEN_SCALE_FACTOR` of the Qt framework. Choose 'system' to stick to the setting of your current environment. +| Scale Factor | **(Linux only)** Define a screen scale factor for the user interface of the application. This setting manipulates the environment flag `QT_SCALE_FACTOR` of the Qt framework. Choose 'system' to stick to the setting of your current environment. +| Scroll Speed | Define a multiplyer for the default scroll speed. Values smaller than 1 slow down scrolling while values greater than 1 increase the scroll speed. +| Graph Zoom | Switch the default mouse wheel behavior in the graph between scrolling and zooming. +| Logging | Ticking this box enables logging to console and to a log file. This option is disabled by default to speed up NumbatUI. If you encounter problems while running NumbatUI, we recommend to enable this option so you have somewhere to start looking for a cause. +| Indexer Logging | When enabled NumbatUI will log detailed information during indexing. This log data can help us fix issues. +| Automatic Update Check | Check to automatically check whether a new version of NumbatUI is available once every day. +| NumbatUI Port | Port number that NumbatUI uses to listen for incoming messages from plugins. +| Plugin Port | Port number that NumbatUI sends outgoing messages to. +| Indexer threads | Define how many parallel threads are used during indexing. Setting this value to `default` will cause NumbatUI to detect the ideal number of threads based on the CPU and use as many threads for indexing. +| Multi process C/C++ indexing | Enable C/C++ indexer threads to run in a different process. This prevents the application from crashing due to unforeseen exceptions while indexing. +| Post Processing | Enable a post processing step to solve unsolved references after the indexing is done. These references will be marked "ambiguous" to indicate that some of these edges may never be encountered during runtime of the indexed code because the post processing only relies on symbol names and types. +| Global Include Paths | Set header search paths that are used for **all** of your projects (e.g. std headers). An option for automatic detection of these paths is available for Clang, GCC and the Visual Studio compiler. For instructions on how to add paths manually see [Path List Box](#path-list-box). For instructions on how to find the system header paths see [Finding System Header Locations](!installation#finding-system-header-locations). +| Global Framework Search Paths | **(macOS only)** Define the search paths for `.framework` files for all of your projects. An option for automatic detection of these paths is available for Clang and GCC.
For instructions on how to add paths see [Path List Box](#path-list-box). + +### Project Setup Wizard +The Project Setup Wizard lets you create a new NumbatUI project. It allows for defining name and location of your project NumbatUI and adding several **Source Groups**, that define which source files will be indexed. There are several ways to create Source Groups. It is sufficient to add only one Source Group for most projects. + +For detailed information continue at [PROJECT SETUP](!project-setup). + +Project Setup Wizard Start + +### Indexing Dialogs + +These dialogs will be used while NumbatUI indexes your project. The whole user interface will be frozen as long as these dialogs are visible. + +#### Start Indexing Dialog + +This dialog displays the number of files for indexing and clearing before indexing starts. There are different refresh modes: + + +* **Updated files:** Reindexes all files that were modified since the last indexing, all files depending on those and new files. +* **Incomplete & updated files:** Reindexes all files that had errors during last indexing, all files depending on those and all updated files. +* **All files:** Deletes the previous index and reindexes all files. + + +**Shallow Python Indexing** + +For Python projects a checkbox **Shallow Python Indexing** is additionally displayed. When checked, references within your code base (calls, usages, etc.) are resolved by name, which is imprecise but much faster than in-depth indexing. Use this option for a quick first indexing pass and start browsing the code base while running a second pass for in-depth indexing. + +Start Indexing Dialog + +!!! abstract "Interactions" + * Switch indexing mode by clicking a different option. + * Clicking `Cancel` will abort indexing. + * Clicking `Start` will start the file clearing and indexing. + +#### Progress Dialog + +This dialog shows that NumbatUI is currently doing processing that can't be interrupted. + +Progress Dialog + +!!! abstract "Interactions" + * Clicking `Hide` will hide the dialog. You can display it again by clicking on the indexing progress bar in the [status bar](#status-bar) or [refreshing](#refresh). + +#### Indexing Dialogs + +This dialog shows the indexing progress of your project, by displaying the number of already indexed files, the last file that was started indexing, the number of errors and a progress estimate in percent. + +Indexing Dialog + +!!! abstract "Interactions" + * Clicking `Stop` or pressing ESC will interrupt indexing. NumbatUI will still wait for the already running indexer threads to finish. You can continue indexing later by [refreshing](#refresh). + * Clicking `Hide` will hide the dialog. You can display it again by clicking on the indexing progress bar in the [status bar](#status-bar) or [refreshing](#refresh). + +#### Finished Indexing Dialog + +This dialog is shown after indexing finished, giving you information about indexed files, duration and errors. + +Finished Indexing Dialog + +#### Interrupted Indexing Dialog + +This dialog is shown after indexing was stopped, giving you information about indexed files, duration and errors. You can choose to either use the new index or continue using the old one. + +Interrupted Indexing Dialog + +!!! abstract "Interactions" + * Clicking `Discard` will discard the new index. + * Clicking `Keep` will switch your project to the new index and discard the old one. + +## Menu + +### Project + +* **New Project** + * Shortcut: [New Project](#shortcuts) + * Opens the [New Project](#project-setup-wizard) Dialog to define a new project and loads it after creation. +* **Open Project** + * Shortcut: [Open Project](#shortcuts) + * Opens a file dialog to choose an existing NumbatUI project file from your system's hard drive. +* **Recent Projects** + * Opens a submenu to choose recent opened NumbatUI projects. +* **Edit Project** + * Opens the [Edit Project Dialog](#project-setup-wizard) prefilled with your project settings and allows for changing them. +* **Exit** + * Quits NumbatUI. + +### Edit + +* **Refresh** + * Shortcut: [Refresh](#shortcuts) + * Refresh will check all indexed source files for updates and reindex the ones that changed and their depending ones. +* **Full Refresh** + * Shortcut: [Full Refresh](#shortcuts) + * Full Refresh will reindex the whole project. +* **Find Symbol** + * Shortcut: [Find Symbol](#shortcuts) + * This option will put the focus into the search field, so you can start typing your search query. Alternatively you can click the search field. +* **Find Text** + * Shortcut: [Find Text](#shortcuts) + * This option will put the focus into the search field and start a new full text search query +* **Find On-Screen** + * Shortcut: [Find On-Screen](#shortcuts) + * Display the [On-Screen Search Bar](#on-screen-search-bar) to search visible contents of the [Graph View](#graph-view) and [Code View](#code-view) +* **Next Reference** + * Shortcut: [Next Reference](#shortcuts) + * Use this option to iterate to the next source location of the active symbol in the code view. +* **Previous Reference** + * Shortcut: [Previous Reference](#shortcuts) + * Use this option to iterate to the previous source location of the active symbol in the code view. +* **Next Local Reference** + * Shortcut: [Next Local Reference](#shortcuts) + * Use this option to iterate to the next source location of the active local symbol or edge in the code view. +* **Previous Local Reference** + * Shortcut: [Previous Local Reference](#shortcuts) + * Use this option to iterate to the previous source location of the active local symbol or edge in the code view. +* **To overview** + * Shortcut: [To overview](#shortcuts) + * This option will display the overview of the project. +* **Preferences** + * Shortcut: [Preferences](#shortcuts) + * Opens the [Preferences Window](#preferences-window). + +### View + +* **New Tab** + * Opens a new tab. +* **Close Tab** + * Closes the current tab. +* **Select Next Tab** + * Switch to the tab to the right of the current tab. +* **Select Previous Tab** + * Switch to the tab to the left of the current tab. +* **Show Start Window** + * Shows the [Start Window](#start-window). +* **Show Title Bars** + * Toggle the visibility of the bars above each [Window Widget](!interface#widget-windows). +* **Reset window layout** + * Resets all the dock widgets to their original layout. +* **Search Window** + * Toggle the visibility of the Search Window. This can also be done by closing the Search Window on clicking the "x" icon in it's title bar. (See [Window Widgets](!interface#widget-windows)) +* **Graph Window** + * Toggle the visibility of the Graph Window. This can also be done by closing the Graph Window on clicking the "x" icon in it's title bar. (See [Window Widgets](!interface#widget-windows)) +* **Code Window** + * Toggle the visibility of the Code Window. This can also be done by closing the Code Window on clicking the "x" icon in it's title bar. (See [Window Widgets](!interface#widget-windows)) +* **Status Window** + * Toggle the visibility of the Status Window. This can also be done by closing the Status Window on clicking the "x" icon in it's title bar. (See [Window Widgets](!interface#widget-windows)) +* **Larger Font** + * Shortcut: [Larger Font](#shortcuts) + * Increase the font size within the Main Window's user interface. +* **Smaller Font** + * Shortcut: [Smaller Font](#shortcuts) + * Decrease the font size within the Main Window's user interface. +* **Reset font size** + * Shortcut: [Reset font size](#shortcuts) + * Resets the font size to the original size. + +### History + +* **Back** + * Shortcut: [Back](#shortcuts) + * Undoes the last navigation action. +* **Forward** + * Shortcut: [Forward](#shortcuts) + * Redoes an undone navigation action. +* **Recently Active Symbols** + * List the history of active symbols in chronologic order. + +### Bookmarks + +* **Bookmark Active Symbol** + * Shortcut: Bookmark Active Symbol](#shortcuts) + * Opens the [Bookmark Creator](#bookmark-creator) dialog create a new bookmark. +* **Bookmark Manager** + * Shortcut: Bookmark Manager](#shortcuts) + * Opens the [Bookmark Manager](#bookmark-manager) dialog for viewing all bookmarks. +* **Recent Bookmarks** + * List of recently added bookmarks for quick activation. + +### Help + +* **About** + * Shows copyright information about NumbatUI. +* **Keyboard Shortcuts** + * Shows table of keyboard shortcuts for NumbatUI. +* **Documentation** + * Opens this documentation of NumbatUI in your web browser by URL. +* **Changelog** + * Opens the [changelog](https://github.com/CoatiSoftware/NumbatUIBugTracker#changelog) of NumbatUI in your web browser by URL. +* **Bug Tracker** + * Opens NumbatUI's bug tracker in your web browser by URL. +* **License** + * Opens a window containing the NumbatUI license and all 3rd party licenses. +* **Show Data Folder** + * Opens the file explorer showing the [data folder](!installation#datafolder). +* **Show Log Folder** + * Opens the file explorer in the directory [data](!installation#datafolder)/logs where all log files are saved to. You can enable file logging in the [Preferences Window](#preferences-window). + + +### Shortcuts + +#### General + +| Shortcut | Windows | macOS | Linux +| --- | --- | --- | --- +| Switch Focus Between Graph/Code Views | `Tab` | `Tab` | `Tab` +| Preferences | `Ctrl + ,` | `Cmd + ,` | `Ctrl + ,` +| New Project | `Ctrl + N` | `Cmd + N` | `Ctrl + N` +| Open Project | `Ctrl + O` | `Cmd + O` | `Ctrl + O` +| Close Window | `Alt + F4` | `Cmd + W` | `Ctrl + W` +| Hide Window | | `Cmd + H` | +| Refresh | `F5` | `Cmd + R` | `F5` +| Full Refresh | `Shift + F5` | `Cmd + Shift + R` | `Shift + F5` +| Back | `Z` / `Alt + Left` / `Backspace` | `Z` / `Cmd + [` / `Backspace` | `Z` / `Alt + Left` / `Backspace` +| Forward | `Shift + Z` / `Alt + Right` | `Shift + Z` / `Cmd + ]` | `Shift + Z` / `Alt + Right` +| Find Symbol | `Ctrl + F` | `Cmd + F` | `Ctrl + F` +| Find Text | `Ctrl + Shift + F` | `Cmd + Shift + F` | `Ctrl + Shift + F` +| Find On-Screen | `Ctrl + D` | `Cmd + D` | `Ctrl + D` +| To overview | `Ctrl + Home` | `Cmd + Home` / `Cmd + Up` | `Ctrl + Home` +| New Tab | `Ctrl + T` | `Cmd + T` | `Ctrl + T` +| Close Tab | `Ctrl + W` | `Cmd + W` | `Ctrl + W` +| Select Next Tab | `Ctrl + Tab` | `Ctrl + Tab` | `Ctrl + Tab` +| Select Previous Tab | `Ctrl + Shift + Tab` | `Ctrl + Shift + Tab` | `Ctrl + Shift + Tab` +| Larger Font | `Ctrl + +` | `Cmd + +` | `Ctrl + +` +| Smaller Font | `Ctrl + -` | `Cmd + -` | `Ctrl + -` +| Reset Font Size | `Ctrl + 0` | `Cmd + 0` | `Ctrl + 0` +| Bookmark Active Symbol | `Ctrl + S` | `Cmd + S` | `Ctrl + S` +| Bookmark Manager | `Ctrl + B` | `Cmd + B` | `Ctrl + B` + +#### Graph View + +| Shortcut | Windows | macOS | Linux +| --- | --- | --- | --- +| Move Focus Within Nodes | `WASD` / `HJKL` / `Arrows` | `WASD` / `HJKL` / `Arrows` | `WASD` / `HJKL` / `Arrows` +| Move Focus Within Edges | `Shift + WASD` / `Shift + HJKL` / `Shift + Arrows` | `Shift + WASD` / `Shift + HJKL` / `Shift + Arrows` | `Shift + WASD` / `Shift + HJKL` / `Shift + Arrows` +| Activate Node/Edge | `Enter` / `E` | `Enter` / `E` | `Enter` / `E` +| Activate Node in New Tab | `Ctrl + Shift + Enter` / `Ctrl + Shift + E` | `Cmd + Shift + Enter` / `Cmd + Shift + E` | `Ctrl + Shift + Enter` / `Ctrl + Shift + E` +| Expand/Collapse Node | `Shift + Enter` / `Shift + E` | `Shift + Enter` / `Shift + E` | `Shift + Enter` / `Shift + E` +| Pan | `Ctrl + Arrows` | `Cmd + Arrows` | `Ctrl + Arrows` +| Zoom In | `Ctrl + Shift + Up` / `Ctrl + Mouse Wheel Up` | `Cmd + Shift + Up` / `Cmd + Mouse Wheel Up` | `Ctrl + Shift + Up` / `Ctrl + Mouse Wheel Up` +| Zoom Out | `Ctrl + Shift + Down` / `Ctrl + Mouse Wheel Down` | `Cmd + Shift + Down` / `Cmd + Mouse Wheel Down` | `Ctrl + Shift + Down` / `Ctrl + Mouse Wheel Down` +| Reset Zoom | `0` | `0` | `0` +| Open Custom Trail Dialog | `Ctrl + U` | `Cmd + U` | `Ctrl + U` + +#### Code View + +| Shortcut | Windows | macOS | Linux +| --- | --- | --- | --- +| Next Reference | `Ctrl + G` | `Cmd + G` | `Ctrl + G` +| Previous Reference | `Ctrl + Shift + G` | `Cmd + Shift + G` | `Ctrl + Shift + G` +| Next Local Reference | `Ctrl + T` | `Cmd + T` | `Ctrl + T` +| Previous Local Reference | `Ctrl + Shift + T` | `Cmd + Shift + T` | `Ctrl + Shift + T` +| Move Focus Within Code | `WASD` / `HJKL` / `Arrows` | `WASD` / `HJKL` / `Arrows` | `WASD` / `HJKL` / `Arrows` +| Move Focus to Closest Reference | `Shift + WASD` / `Shift + HJKL` / `Shift + Arrows` | `Shift + WASD` / `Shift + HJKL` / `Shift + Arrows` | `Shift + WASD` / `Shift + HJKL` / `Shift + Arrows` +| Activate Location | `Enter` / `E` | `Enter` / `E` | `Enter` / `E` +| Activate Location in New Tab | `Ctrl + Shift + Enter` / `Ctrl + Shift + E` | `Cmd + Shift + Enter` / `Cmd + Shift + E` | `Ctrl + Shift + Enter` / `Ctrl + Shift + E` +| Scroll | `Ctrl + Arrows` | `Cmd + Arrows` | `Ctrl + Arrows` + +## Graph View +The graph view visualizes the currently selected symbol and all its relationships to other symbols as an interactive graph visualization. You can also display whole call graphs, inheritance chains or include trees by using the toolbar in the top left. Read more about that at [Custom Trail](#custom-trail). + +Graph View + +#### Interactions: + +**Buttons:** + +* Use the trail navigation in the top left to create [Custom Trails](#custom-trail). +* Use the grouping buttons in the top left to enable [Node Grouping](#node-grouping) by namespace/package or file. +* Press the `+` and `-` buttons in the lower left corner to change the zoom level. +* Press the `?` button in the bottom right corner to show the [Graph Legend](#graph-legend). + +**Panning:** + +* Drag the background area with the mouse. +* Scroll left-right and up-down on the mouse pad. +* Use the keys `W` `A` `S` `D`. + + +**Zooming:** + +* Hold `Ctrl/Cmd` and scroll with mouse wheel or mouse pad. +* Press `Shift + W` or `Shift + S`. +* Press `0` to reset zoom. + + +**Context Menu:** + +* **Open in New Tab:** Opens a new Tab with the node under the mouse cursor as active symbol. +* **Back:** Go back in history. +* **Forward:** Go forward in history. +* **Show Definition:** Show the definition of the node under the mouse cursor in the [Code View](#code-view). +* **Expand Node:** Expand node under mouse cursor. +* **Collapse Node:** Collapse node under mouse cursor. +* **Hide Node:** Hide node under mouse cursor. +* **Hide Edge:** Hide edge under mouse cursor. +* **Bookmark Node:** Create a bookmark for node under mouse cursor. +* **Save As Image:** Export current graph as image file. Possible formats are `PNG`, `JPEG`, `BMP` and `SVG`. +* **Save To Clipboard:** Save current graph as `PNG` image to clipboard. +* **Copy Name:** Copy name for node under mouse cursor to clipboard. +* **Copy Full Path:** Copy file path for file node under mouse cursor to clipboard. +* **Open Containing Folder:** Show the file in your file explorer for file node under mouse cursor. + + +### Nodes +Colors are corresponding to the default color scheme. + +| Node Type | Image +| --- | --- +| **File**: Non-indexed files are files that are not part of any source group and therefore have not been indexed by NumbatUI's indexer. Incomplete files produced errors during indexing or where part of an indexer run with errors. | !["Node File"](documentation/node_file.png "Node File") +| **Macro** | !["Node Macro"](documentation/node_macro.png "Node Macro") +| **Namespace, Package & Module** | !["Node Namespace"](documentation/node_namespace.png "Node Namespace") +| **Class & Struct**: Display their members nested, and separated by access type: public, protected, private. By default only members with edges are shown. The arrow icon allows to expand and collapse them. The number tells how many nodes are hidden. | !["Node Class"](documentation/node_class.png "Node Class") +| **Type** | !["Node Type"](documentation/node_type.png "Node Type") +| **Typedef** | !["Node Typedef"](documentation/node_typedef.png "Node Typedef") +| **Variable & Field** | !["Node Variable"](documentation/node_variable.png "Node Variable") +| **Function & Method** | !["Node Function"](documentation/node_function.png "Node Function") +| **Enum & Enum Constant** | !["Node Enum"](documentation/node_enum.png "Node Enum") +| **Bundle**: A bundle node combines multiple nodes to reduce the size of the graph visualization. The name describes what kind of nodes are bundled. The number tells how many nodes are bundled. | !["Node Bundle"](documentation/node_bundle.png "Node Bundle") +| **Group: A group node shows that all contained nodes share something in common e.g. same file or namespace. | !["Node Group"](documentation/node_group.png "Node Group") + +!!! abstract "Interactions" + * Click a node to activate it. + * Drag a node to change its position. + * Click the arrow icon in class nodes to expand and collapse it. + * Click a bundle node to expand it. + * Hover a node to see a tooltip that displays the node’s type. + +### Edges +Colors are corresponding to the default color scheme. + +| Edge Type | Image +| --- | --- +| **File Include** | !["Edge Include"](documentation/edge_include.png "Edge Include") +| **Type Use** | !["Edge Use"](documentation/edge_type_usage.png "Edge Use") +| **Variable Use** | !["Edge Variable Use"](documentation/edge_variable_use.png "Edge Variable Use") +| **Function Call** | !["Edge Call"](documentation/edge_call.png "Edge Call") +| **Inheritance** | !["Edge Inheritance"](documentation/edge_inheritance.png "Edge Inheritance") +| **Method Override** | !["Edge Override"](documentation/edge_override.png "Edge Override") +| **Template Specialization & Template Argument Use** | !["Edge Template Param"](documentation/edge_template_param.png "Edge Template Param") +| **Template Member Specialization** | !["Edget Template Member Specialization"](documentation/edge_template_member_specialization.png "Edget Template Member Specialization") +| **Bundled Edges**: Bundles multiple edges between the child nodes of the 2 nodes. The thickness gives an impression of how many edges are bundled. Hover the edge to get the number of bundled edges. | !["Edge Bunled Edges"](documentation/edge_bundled_edges.png "Edge Bunled Edges") + +!!! abstract "Interactions" + * Click an edge to see its location in the [Code View](#code-view). + * Click a bundled edges to activate all its corresponding edges. + * Hover an edge to see a tooltip that displays the edge’s type. + +### Custom Trail +Using the toolbar in the top left you can display whole call graphs, inheritance chains or include trees for the currently active symbol if the right symbol type is currently active. Or you can use the Custom Trail Dialog to display graphs based on custom criteria. + +!["Call Graph"](documentation/call_graph.png "Call Graph") + +!!! abstract "Interactions" + * Click the arrow button to expand/collapse the `Custom Trail` controls. + * Click the `Custom Trail Dialog` button to show the `Custom Trail Dialog`. + * Click the `Predefined Custom Trail` buttons to show a graph of depending/dependent nodes based on the currently active symbol. + * Change the slider position to change the maximum depth of the graph. Moving it to the top will use infinite depth. + * Click on a node to activate it. + * Click on an edge to show it's source location in the [Code View](#code-view). + + +#### Custom Trail Dialog +The Custom Trail Dialog can be accessed within the trail controls in the top left of the graph view. It allows to display Custom Trails based on certain criteria. + +Custom Trail + +Every Custom Trail has a specific Start Symbol, then 1 of 3 different modes can be chosen: + +| Mode | Description +| --- | --- +| **To Target Symbol** | Specify another target symbol. The graph will only contain paths from the origin to the target symbol. +| **All Referenced** | The graph will only contain nodes that are referenced by the origin symbol. +| **All Referencing** | The graph will only contain nodes that depend on the origin symbol. + +Additional options allow defining which information should be shown: + +| Setting | Description +| --- | --- +| **Maximum Depth** | Define the depth of the resulting graph. When searching paths from origin to target, all paths that are beyond this depth will not be found. +| **Layout Direction** | Define if the graph should be displayed vertically or horizontally. +| **Node Filters** | Define which node types will be part of the resulting graph. Only node types present in the loaded project are displayed. This setting is ignored for the origin and target nodes. +| **Edge Filters** | Define which edge types will be part of the resulting graph. Only node types present in the loaded project are displayed. The special edge "member" defines whether parent-child relations are considered as edge. + +!!! abstract "Interactions" + * Search for start and target symbols using a search field. The interactions are the same as in the main [Search Field](#search-bar). + * Drag the Max Depth slider to change the maximum depth of the resulting graph. + * Click the **Check All** and **Uncheck All** buttons to check all available node or edge filters. + * Click on Cancel to close the dialog. + * Click on Search to search for a Custom Trail using the selected options. + +### Node Grouping + +Using grouping buttons in the top left you can specify if nodes in the graph shall be grouped by either namespace/package or defining file. + +!["Grouping Buttons"](documentation/grouping_buttons.png "Grouping Buttons") + +#### Namespace/Package Grouping + +All nodes that belong to the same namespace or package are grouped together in a separate group node. + +Grouping Namespace + +#### File Grouping + +All nodes defined in the same source or header file are grouped together in a separate group node. + +Grouping File + +!!! abstract "Interactions" + * Click on the group name to activate the corresponding namespace/package or file node. + + +### Graph Legend + +Click the `?` button in the bottom right corner of the graph view or enter the keyword `legend` in the [search field](#search-bar) to show the graph legend. It gives you an overview on the different node and edge types and provides examples of graph layouts. + +!["Graph Legend"](documentation/graph_legend.png "Graph Legend") + +## Code View + +The code view displays the corresponding source code of the currently selected symbols. The code view has two modes. In list mode it contains a list of one or more files. In single file mode it shows one full source file at a time. + +Code View + +!!! abstract "Interactions" + * Iterate the references of the currently active symbol with the `reference` navigation in the upper left corner. + * Iterate local references of the currently selected local variable or multiple references of a symbol within a local scope with the `local reference` navigation in center. + * Switch between Snippet List and Single File mode with the `mode selection` in the upper right corner. + * Scroll up and down to see the different source files. + +Code View Show Errors + +If a viewed file had errors during indexing, its file icon will contain an `x` and there is a `Show Errors`-button visible in the files title bar. Clicking one `Show Errors` will show you only the errors that cause this specific file to be incomplete in the [Errors Tab](#errors-tab). + +### Snippet List Mode + +In this mode the Code View will provide all references of the currently active symbol at once. The top most snippet will show the definition of the symbol if available. + +#### Files + +Each file has a title bar with the file's name. Clicking the title bar will change the display state. There are 2 different states: + +* **Minimized:** The file does not show its content. + +Snippet Minimized + +* **Snippets:** The file displays the snippets containing active locations separated by lines. + +Snippet Snippets + +!!! abstract "Interactions" + * Hover the title to see the full file path. + * Click the title to activate the file's corresponding node and switch to full file view. + * Click the title bar to minimize the file or show its snippets. + * Click the snippet button to switch to snippet or full file view, depending on the file node + * Click the maximize button to switch to [Single File Mode](#single-file-mode). + +#### Snippets + +A code snippet contains the lines of interest for the currently active symbol surrounded by some more lines to provide some context. Other symbols that were indexed by NumbatUI are framed by a box when hovered. Here NumbatUI distinguishes between local symbols and symbols that can be related to any other part of the code base. In case the snippet is part of a class, function or namespace, an additional line at the top of the snippet provides information about the snippet’s context (e.g. the surrounding scope). + +Code View Snippet + +!!! abstract "Interactions" + * Click the top line to show the whole scope around the snippet. + * Click a boxed symbol to activate it. + * Click a boxed local symbol to highlight all its usages in the visible code. + +### Single File Mode + +In single file mode you will only every have one file visible at a time. The first file shown is usually the file containing the definition of the active snippet if available. Other than that the user interface is the same as in [Snippet List Mode](#snippet-list-mode). + +Code View Single + +!!! abstract "Interactions" + * Hover the title to see the full file path. + * Click the title to activate the file's corresponding node. + * Click the snippet button to switch to [Snippet List Mode](#snippet-list-mode). + +## Search View + +The Search View contains the search field and some other related user interface elements. + +Search View + +### Back, Forward and History + +The left `Backward` button lets you undo your last navigation actions (see [Back](#view)) and the right `Forward` button lets you redo your undone navigation actions again (see [Forward](#view)). Both buttons are only enabled when the respective actions are available at the moment. + +The middle button shows a list of the recently active symbol stack. Select a symbol to activate it. + +!["Undo Redo View"](documentation/undo_redo_buttons.png "Undo Redo View") + +!["History List"](documentation/history_list.png "History List") + +!!! abstract "Interactions" + * Hover the buttons to see a tool tip. + * Press the buttons to execute the respective action. + * Press the history button to show the active symbol stack and click on an item to activate it. + +### Refresh + +The refresh button allows you to refresh the current project and reindex all updated, added and removed files. To reindex the whole project choose the **Force Refresh** option from the [Edit Menu](#edit). + +!["Refresh Button"](documentation/refresh_button.png "Refresh Button") + +!!! abstract "Interactions" + * Hover the buttons to see a tooltip. + * Press the refresh button to refresh the project. + +### Overview Button + +Show the overview screen, which gives a summary of the loaded project. The overview screen is shown after the project was loaded. Alternatively use the shortcut [To overview](#shortcuts). + +!["Overview Button"](documentation/overview_button.png "Overview Button") + +!!! abstract "Interactions" + * Press the overview button to show the project overview. + +### Search Bar + +The search bar allows you to enter search requests to find one of NumbatUI's indexed symbols. It doesn't allow for full text searching across all files so far. The search field allows for most text editing interactions common to text fields. When typing your request the [Autocompletion Popup](#autocompletion-popup) will show you search results matching to your entered string. + +!["Search Bar"](documentation/search_bar.png "Search Bar") + +!!! abstract "Interactions" + * Focus the search field by clicking it or using the [Find Symbol](#edit) action. + * Enter your search request by typing on your keyboard. + * By pressing enter or clicking on the search icon on the right you send your request. + * The search field allows for most interactions known from other text fields such as moving the cursor, copy&paste and text selection. + + +### Autocompletion Popup + +The Autocompletion Popup displays all [Nodes](#nodes) matching your search request within all indexed symbols. The match results are determined by a fuzzy matching algorithm, that allows you to skip characters. The popup shows which characters in the words are matching and displays their corresponding node color. The node type is displayed on the right. + +Search View Completion + +!!! abstract "Interactions" + * Use the up and down arrow keys to switch between search results. + * Pressing tab or clicking on the search result will insert it into the search field. + * Pressing enter will select the search result and send the search request. + +### Keywords + +Additionally the search view provides specific keywords that select a certain group of symbols. + +| keyword | effect +| --- | --- +| **overview** | Shows an overview of all indexed symbols in the [graph view](#graph-view) and some statistics in the [code view](#code-view). +| **error** | Shows all errors in the [code view](). + +### Full text search + +Search for a certain string in all indexed files by putting `?` at the front of your search query. The default full text search is case-insensitive, use `??` to search case-sensitive. + +!["Search View Fulltext"](documentation/search_view_fulltext.png "Search View Fulltext") + +!!! abstract "Interactions" + * Start a query with `?` or use the [Find Text](#edit) action to do a case-insensitive full text search. + * Start a query with `??` to do a case-sensitive full text search. + +### Bookmarking Buttons + +The `Bookmark Active Symbol` button on the left opens the [Bookmark Creator](#bookmark-creator) to create a new bookmark. The `Bookmark Manager` button on the right is used to display the [Bookmark Manager](#bookmark-manager) for activating and editing your bookmarks. + +!["Bookmark Buttons"](documentation/bookmark_buttons.png "Bookmark Buttons") + +!!! abstract "Interactions" + * Hover the buttons to see a tool tip. + * Press the buttons to execute the respective action. + +### Bookmark Creator + +Use the `Bookmark Creator` to create or edit bookmarks. + +Bookmark Creator + +| Setting | Description +| --- | --- +| **Name** | The name of the bookmark. Initially the name of the node or edge is used. +| **Comment** | Add an optional comment to the bookmark. +| **Category** | Add the bookmark to a certain category. Bookmarks with the same category are grouped together in the [Bookmark Manager](#bookmark-manager). + +!!! abstract "Interactions" + * Press `Cancel` to close without changes. + * Press `Create/Save` to save the bookmark or apply the changes. + +### Bookmark Manager + +Use the `Bookmark Manager` to view and activate your bookmarks. Bookmarks are displayed as lines below their respective category. If a bookmark does not have a category it will be placed within the `default` category. The buttons for removing/editing categories or bookmarks are only visible when hovering the respective line. Bookmark information is stored within a separate `.srctrlbm` file next to your `.srctrlprj` project file. + +Bookmark Manager + +!!! abstract "Interactions" + * Activate bookmarks by clicking on the name. + * Open/Collapse the bookmark comment by clicking within the bookmark line. + * Click the `Edit` button to change the contents of the bookmark. + * Click the `Delete` button at a bookmark to remove the bookmark. + * Open/Collapse categories by clicking in their line. + * Click the `Delete` button at a category to remove the category and all bookmarks within. + * Change the `Show` filter to switch between display of nodes and/or edges. + * Change the `Sorting` to change the order of bookmarks within their categories. + +## Status View + +This view provides different tabs with information about your project. This +view is hidden by default. + +!!! abstract "!!! abstract "Interactions"" + * Click on the titles on top to switch between tabs. + * Click on the `x`-button in the top right corner to close the Status View. + +### Status Tab + +This table gives some information about status updates while running NumbatUI. It can be helpful to figure out why something does not the way it's expected to. + +!["Status View Status"](documentation/status_view_status.png "Status View Status") + +!!! abstract "Interactions" + * Double click on a table cell to select the text for copy&paste. + * Use the checkboxes below to filter the shown messages by type. + * Click on `Clear Table` to remove all rows from the table. + +### Errors Tab + +This list shows errors occurred during indexing. + +!["Status View Error"](documentation/status_view_error.png "Status View Error") + +The following information is provided: + +* **Type:** ERROR or FATAL. A FATAL error causes lots of missing information since the indexer had to stop at this error. +* **Error message** +* **File** +* **Line number** +* **Indexed:** Whether the file is within the indexed files. +* **Translation Unit:** The source file that produced this error while being indexed. + +!!! abstract "Interactions" + * Click on a error line to see the location of the error in the [Code View](#code-view). + * Click on the column headers to sort the error rows ascending or descending by this data. + * Double click on a table cell to select the text for copy&paste. + * Use the checkboxes below to filter the shown errors by certain criteria. + * Click on `Edit Project` to open the [Edit Project Dialog](#project-setup-wizard). + +## Tooltips + +Show information about hovered symbols in the [Graph View](#graph-view) and [Code View](#code-view) + +Tooltip + +**The following information is provided:** + +* Symbol type +* Visibility (e.g. public or private) +* Reference count +* Symbol name +* Clickable type name for global variables and fields. +* Full signatures with clickable return type name and parameter types names for functions and methods. + +!!! abstract "Interactions" + * Click on symbol names to activate them. diff --git a/docs/logo/numbatui_1024.png b/docs/logo/numbatui_1024.png new file mode 120000 index 000000000..f40e0a4b4 --- /dev/null +++ b/docs/logo/numbatui_1024.png @@ -0,0 +1 @@ +../../logo/numbatui_1024.png \ No newline at end of file diff --git a/docs/logo/numbatui_192.png b/docs/logo/numbatui_192.png new file mode 120000 index 000000000..fe045305d --- /dev/null +++ b/docs/logo/numbatui_192.png @@ -0,0 +1 @@ +../../logo/numbatui_192.png \ No newline at end of file diff --git a/docs/project_setup.md b/docs/project_setup.md new file mode 100644 index 000000000..5f1417f95 --- /dev/null +++ b/docs/project_setup.md @@ -0,0 +1,131 @@ +--- +icon: lucide/sliders-horizontal +--- +# Project Setup + +Project Setup in NumbatUI is done via the [Project Setup Wizard](!interface#project-setup-wizard), which can be accessed on the [Start Window](!interface#start-window) by clicking `New Project` or from the [Project Menu](!interface#project) with the `New Project` action. + +The Project Setup Wizard lets you create a new NumbatUI project. It allows for defining name and location of your NumbatUI project and adding several **Source Groups**, that define which source files will be indexed. There are several ways to create Source Groups. It is sufficient to add only one Source Group for most projects. + +After you added Source Groups to your project this dialog allows you to edit their configurations, as well as removing or duplicating them. + +Project Setup Wizard Start + +| Setting | Description +| --- | --- +| NumbatUI Project Name | The name of the project. This will also be the name of the `.srctrlprj` file generated by NumbatUI. +| NumbatUI Project Location | Choose the location of the project file from the dialog. + +!!! abstract "Interactions" + * Clicking `Cancel` or pressing `ESC` will close the window and abort the setup process. + * Clicking `Add Source Group` will take you to the creation of a new Source Group. + * Clicking `General` will take you to the name and location setting of the project. + * Clicking a `Source Group` will let you edit it's configuration and change it's name. + * Clicking `+` beneath the Source Group list will take you to the creation of a new Source Group. + * Clicking `-` beneath the Source Group list will delete the currently selected Source Group. + * Clicking `☐` beneath the Source Group list will duplicate the currently selected Source Group. + * Clicking `Create` will close this window and create the new project. + +This window is also used when editing the project. You can select a Source Group from the list on the left and edit it's contents then. Additionally you can also set the `active` flag of certain Source Groups to false, so they won't get indexed when refreshing the project. + +Project Setup Wizard Edit + +!!! abstract "Interactions" + * Change the name of the Source Group. + * Activate/Deactivate the Source Group for indexing. + * Change any settings defined during Source Group setup. + +## Choose a Source Group Type + +When creating a new Source Group you can choose between different methods of setup depending on your project language. Please have a look at our [QUICK START GUIDE](!getting-started) section for help on choosing the right Source Group type. + +Project Setup Wizard Source Group Type + +!!! abstract "Interactions" + * Select the language used in code project. + * Selecting a Source Group type will determine how you enter all the required information. + * Clicking `Cancel` or pressing `ESC` will close the window. + * Clicking `Next` will take you to the next step of the setup process. + +## Empty C/C++ Source Group + +Empty C/C++ Source Groups have the following configuration options: + +| Setting | Description +| --- | --- +| Standard | Select the language standard that should be used for indexing your project. Usually the most recent language standard is preselected here. (See [Language Support](!markdown#supported-languages)) +| Cross-compilation | Check **Use specific target** and then use the dropdown boxes to specify a certain target platform. Please have a look at the clang compiler documentation on [cross-compilation](https://clang.llvm.org/docs/CrossCompilation.html) for more information. +| Files & Directories to Index | These paths define the files and directories that will be indexed by NumbatUI. Provide a directory to recursively add all contained source and header files. If your project's source code resides in one location, but generated source files are kept at a different location, you will also need to add that directory. You can make use of environment variables with `${ENV_VAR}`.

For instructions on how to add paths see [Path List Box](!interface#path-list-box). +| Excluded Files & Directories | These paths define the files and directories that will be left out from indexing.
Hints:
  • You can use the wildcard `*` which represents characters except `\` or `/` (e.g. `src/*/test.h` matches `src/app/test.h` but does not match `src/app/widget/test.h` or `src/test.h`)
  • You can use the wildcard `**` which represents arbitrary characters (e.g. `src**test.h` matches `src/app/test.h` as well as `src/app/widget/test.h` or `src/test.h`)
  • You can make use of environment variables with `${ENV_VAR}`

    For instructions on how to add paths see [Path List Box](!interface#path-list-box).
+| Source File Extensions | Define the valid extensions for source files including the dot e.g. `.cpp`. NumbatUI will only try to index files that match one of these extensions. +| Include Paths | Include Paths are used for resolving #include directives in the indexed source and header files. These paths are usually passed to the compiler with the `-I` or `-iquote` flags. Add all paths #include directives throughout your project are relative to. If all #include directives are specified relative to the project's root directory, please add that root directory here. If your project also includes files from external libraries (e.g. boost), please add these directories as well (e.g. add `path/to/boost_home/include`). You can make use of environment variables with `${ENV_VAR}`.

For instructions on how to add paths see [Path List Box](!interface#path-list-box). +| Global Include Paths | The Global Include Paths will be used in all your projects in addition to the project specific Include Paths. These paths are usually passed to the compiler with the '-isystem' flag. Use them to add system header paths (See [Finding System Header Locations](!interface#finding-system-header-locations) or use the auto detection below).

For instructions on how to add paths see [Path List Box](!interface#path-list-box). +| Framework Search Paths (macOS only) | These paths are used to find `.framework` files used by your project. (
For instructions on how to add paths see [Path List Box](!interface#path-list-box).) +| Global Framework Search Paths (macOS only) | These Framework Search Paths will be used in all your projects. (
For instructions on how to add paths see [Path List Box](!interface#path-list-box). For instructions on how to find the system header paths see [Finding System Header Locations](!interface#finding-system-header-locations)) +| Compiler Flags | Define additional compiler flags used during indexing including the dash (e.g. use `-DRELEASE` to add a `#define` for `RELEASE`).

For instructions on how to add paths see [Path List Box](!interface#path-list-box). +| Precompiled Header File | Select the path to the header file that should be used to generate a Precompiled Header File. The Precompiled Header File will be generated as pre-indexing step. If no path is supplied, no Precompiled Header File will be generated. +| Precompiled Header Flags | Define if the already supplied compiler flags should be used for Precompiled Header File generation and define additional flags for Precompiled Header File generation only.

For instructions on how to add paths see [Path List Box](!interface#path-list-box). + +## C/C++ Source Group from Compilation Database + +If you are using [CMake](https://cmake.org/) you can export compile commands by defining the `CMAKE_EXPORT_COMPILE_COMMANDS` flag and then use the exported `.json` file for NumbatUI project setup. +For non-CMake projects you can use [Bear](https://github.com/rizsotto/Bear). Bear generates a `.json` file during the simulated build process. Bear has been tested on FreeBSD, GNU/Linux and OS X. +C/C++ Source Groups from Compilation Database offer the following configuration options: + +| Setting | Description +| --- | --- +| Compilation Database | Select the compilation database file for the project. NumbatUI will index your project based on the compile commands this file contains using all include paths and compiler flags of these compile commands. The project will stay up to date with changes in the compilation database on every refresh. You can make use of environment variables with ${ENV_VAR}. +| Header Files & Directories to Index | Your Compilation Database already specifies which source files are part of your project. But NumbatUI still needs to know which header files to index as part of your project and which to skip. Choosing to skip indexing your system headers or external frameworks will significantly improve the overall indexing performance. Use this list to define which header files should be indexed by NumbatUI. Provide a directory to recursively add all contained files. You can make use of environment variables with ${ENV_VAR}.
**Hint**: Just enter the root path of your project if you want NumbatUI to index all contained headers it encounters.

For instructions on how to add paths see [Path List Box](!interface#path-list-box). +| Excluded Files & Directories | These paths define the files and directories that will be left out from indexing.
Hints:
  • You can use the wildcard `*` which represents characters except `\` or `/` (e.g. `src/*/test.h` matches `src/app/test.h` but does not match `src/app/widget/test.h` or `src/test.h`)
  • You can use the wildcard `**` which represents arbitrary characters (e.g. `src**test.h` matches `src/app/test.h` as well as `src/app/widget/test.h` or `src/test.h`)
  • You can make use of environment variables with `${ENV_VAR}`

    For instructions on how to add paths see [Path List Box](!interface#path-list-box).
+| Additional Include Paths | Include Paths are used for resolving #include directives in the indexed source and header files. These paths are usually passed to the compiler with the '-I' or '-iquote' flags. Add all paths #include directives throughout your project are relative to. If all #include directives are specified relative to the project's root directory, please add that root directory here. If your project also includes files from external libraries (e.g. boost), please add these directories as well (e.g. add 'path/to/boost_home/include'). You can make use of environment variables with ${ENV_VAR}.

For instructions on how to add paths see [Path List Box](!interface#path-list-box). +| Global Include Paths | The Global Include Paths will be used in all your projects in addition to the project specific Include Paths. These paths are usually passed to the compiler with the '-isystem' flag. Use them to add system header paths (See [Finding System Header Locations](!interface#finding-system-header-locations) or use the auto detection below).

For instructions on how to add paths see [Path List Box](!interface#path-list-box). +| Framework Search Paths (macOS only) | These paths are used to find `.framework` files used by your project. (
For instructions on how to add paths see [Path List Box](!interface#path-list-box).) +| Global Framework Search Paths (macOS only) | These Framework Search Paths will be used in all your projects. (
For instructions on how to add paths see [Path List Box](!interface#path-list-box). For instructions on how to find the system header paths see [Finding System Header Locations](!interface#finding-system-header-locations)) +| Additional Compiler Flags | Define additional compiler flags used during indexing including the dash (e.g. use `-DRELEASE` to add a `#define` for `RELEASE`).

For instructions on how to add paths see [Path List Box](!interface#path-list-box). +| Precompiled Header File | Select the path to the header file that should be used to generate a Precompiled Header File. The Precompiled Header File will be generated as pre-indexing step. If no path is supplied, no Precompiled Header File will be generated. +| Precompiled Header Flags | Define if the already supplied compiler flags should be used for Precompiled Header File generation and define additional flags for Precompiled Header File generation only.

For instructions on how to add paths see [Path List Box](!interface#path-list-box). + +## C/C++ Source Group from Code::Blocks + +If you already have a working Code::Blocks project (`.cbp`) for your source code you can use it to create a project with NumbatUI. Note that a `.cbp` file will be generated by the **QtCreator** if a CMakeLists file is imported. +C/C++ Source Groups from Code::Blocks offer the following configuration options: + +| Setting | Description +| --- | --- +| C++ Standard | Select the language standard that should be used for indexing your project's C++ files. Usually the most recent language standard is preselected here. (See [Language Support](!markdown#supported-languages)) +| C Standard | Select the language standard that should be used for indexing your project's C files. Usually the most recent language standard is preselected here. (See [Language Support](!markdown#supported-languages)) +| Code::Blocks Project | Select the `.cbp` file for the project. NumbatUI will index your project based on the settings specified by the Code::Blocks project file. Your NumbatUI project will stay up to date with changes in the Code::Blocks project file on every refresh. You can make use of environment variables with ${ENV_VAR}. +| Header Files & Directories to Index | Your Code::Blocks project already specifies which source files are part of your project. But NumbatUI still needs to know which header files to index as part of your project and which to skip. Choosing to skip indexing your system headers or external frameworks will significantly improve the overall indexing performance. Use this list to define which header files should be indexed by NumbatUI. Provide a directory to recursively add all contained files. You can make use of environment variables with ${ENV_VAR}.
**Hint**: Just enter the root path of your project if you want NumbatUI to index all contained headers it encounters.

For instructions on how to add paths see [Path List Box](!interface#path-list-box). +| Excluded Files & Directories | These paths define the files and directories that will be left out from indexing.
Hints:
  • You can use the wildcard `*` which represents characters except `\` or `/` (e.g. `src/*/test.h` matches `src/app/test.h` but does not match `src/app/widget/test.h` or `src/test.h`)
  • You can use the wildcard `**` which represents arbitrary characters (e.g. `src**test.h` matches `src/app/test.h` as well as `src/app/widget/test.h` or `src/test.h`)
  • You can make use of environment variables with `${ENV_VAR}`

    For instructions on how to add paths see [Path List Box](!interface#path-list-box).
+| Source File Extensions | Define the valid extensions for source files including the dot e.g. `.cpp`. NumbatUI will only try to index files that match one of these extensions. +| Additional Include Paths | Include Paths are used for resolving #include directives in the indexed source and header files. These paths are usually passed to the compiler with the '-I' or '-iquote' flags. Add all paths #include directives throughout your project are relative to. If all #include directives are specified relative to the project's root directory, please add that root directory here. If your project also includes files from external libraries (e.g. boost), please add these directories as well (e.g. add 'path/to/boost_home/include'). You can make use of environment variables with ${ENV_VAR}.

For instructions on how to add paths see [Path List Box](!interface#path-list-box). +| Global Include Paths | The Global Include Paths will be used in all your projects in addition to the project specific Include Paths. These paths are usually passed to the compiler with the '-isystem' flag. Use them to add system header paths (See [Finding System Header Locations](!interface#finding-system-header-locations) or use the auto detection below).

For instructions on how to add paths see [Path List Box](!interface#path-list-box). +| Framework Search Paths (macOS only) | These paths are used to find `.framework` files used by your project. (
For instructions on how to add paths see [Path List Box](!interface#path-list-box).) +| Global Framework Search Paths (macOS only) | These Framework Search Paths will be used in all your projects. (
For instructions on how to add paths see [Path List Box](!interface#path-list-box). For instructions on how to find the system header paths see [Finding System Header Locations](!interface#finding-system-header-locations)) +| Additional Compiler Flags | Define additional compiler flags used during indexing including the dash (e.g. use `-DRELEASE` to add a `#define` for `RELEASE`).

For instructions on how to add paths see [Path List Box](!interface#path-list-box). + +## Empty Python Source Group + +Choose this option if you want to index Python files using NumbatUI. +Empty Python Source Groups offer the following configuration options: + +| Setting | Description +| --- | --- +| Python Environment | Here you can specify the path to the directory or to the executable of the (virtual) Python environment that should be used to resolve dependencies within the indexed source code.
If you would run:
`$ cd c:\dev\python\envs`
`$ virtualenv py37`
you would set it to `C:\dev\python\envs\py37` or `C:\dev\python\envs\py37\Scripts\python.exe`.
Leave blank to use the default Python environment. You can make use of environment variables with `${ENV_VAR}`. +| Files & Directories to Index | These paths define the files and directories that will be indexed by NumbatUI. Provide a directory to recursively add all contained source and header files. If your project's source code resides in one location, but generated source files are kept at a different location, you will also need to add that directory. You can make use of environment variables with ${ENV_VAR}.

For instructions on how to add paths see [Path List Box](!interface#path-list-box). +| Excluded Files & Directories | These paths define the files and directories that will be left out from indexing.
Hints:
  • You can use the wildcard `*` which represents characters except `\` or `/` (e.g. `src/*/test.h` matches `src/app/test.h` but does not match `src/app/widget/test.h` or `src/test.h`)
  • You can use the wildcard `**` which represents arbitrary characters (e.g. `src**test.h` matches `src/app/test.h` as well as `src/app/widget/test.h` or `src/test.h`)
  • You can make use of environment variables with `${ENV_VAR}`

    For instructions on how to add paths see [Path List Box](!interface#path-list-box).
+| Source File Extensions | Define the valid extensions for source files including the dot e.g. `.py`. NumbatUI will only try to index files that match one of these extensions. + +## Custom Command Source Group + +In a Custom Command Source Group you can define a set of files and a command line call used to index each of these files. This Source Group type was introduced to integrate custom indexers written with [NumbatUIDB](https://github.com/CoatiSoftware/NumbatUIDB). + +Custom Command Source Groups offer the following configuration options: + +| Setting | Description +| --- | --- +| Custom Command | The command line call executed for each source file. You can pass different pre-defined parameters:
  • **%{SOURCE_FILE_PATH}**: The path to each source file in the source group (mandatory)
  • **%{DATABASE_FILE_PATH}**: The path to the database of the project
  • **%{DATABASE_VERSION}**: The database version of the used NumbatUI instance
  • **%{PROJECT_FILE_PATH}**: The path to the project file
+| Run in Parallel | Whether files should be processed in parallel. +| Files & Directories to Index | These paths define the files and directories that will be indexed by NumbatUI. Provide a directory to recursively add all contained source and header files. If your project's source code resides in one location, but generated source files are kept at a different location, you will also need to add that directory. You can make use of environment variables with ${ENV_VAR}.

For instructions on how to add paths see [Path List Box](!interface#path-list-box). +| Excluded Files & Directories | These paths define the files and directories that will be left out from indexing.
Hints:
  • You can use the wildcard `*` which represents characters except `\` or `/` (e.g. `src/*/test.h` matches `src/app/test.h` but does not match `src/app/widget/test.h` or `src/test.h`)
  • You can use the wildcard `**` which represents arbitrary characters (e.g. `src**test.h` matches `src/app/test.h` as well as `src/app/widget/test.h` or `src/test.h`)
  • You can make use of environment variables with `${ENV_VAR}`

    For instructions on how to add paths see [Path List Box](!interface#path-list-box).
+| Source File Extensions | Define the valid extensions for source files including the dot e.g. `.ext`. NumbatUI will only try to index files that match one of these extensions. If no extension is defined, any file extension is valid. diff --git a/docs/requirements.txt b/docs/requirements.txt new file mode 100644 index 000000000..6fae69468 --- /dev/null +++ b/docs/requirements.txt @@ -0,0 +1,2 @@ +mike @ git+https://github.com/squidfunk/mike.git +zensical \ No newline at end of file diff --git a/src/external/catch/catch.hpp b/src/external/catch/catch.hpp index 099119d41..129aeb0a5 100644 --- a/src/external/catch/catch.hpp +++ b/src/external/catch/catch.hpp @@ -8161,7 +8161,7 @@ namespace Catch { // 32kb for the alternate stack seems to be sufficient. However, this value // is experimentally determined, so that's not guaranteed. - constexpr static std::size_t sigStackSize = 32768 >= MINSIGSTKSZ ? 32768 : MINSIGSTKSZ; + static std::size_t sigStackSize = 32768 >= static_cast(MINSIGSTKSZ) ? 32768 : static_cast(MINSIGSTKSZ); static SignalDefs signalDefs[] = { { SIGINT, "SIGINT - Terminal interrupt signal" }, @@ -8220,7 +8220,7 @@ namespace Catch { bool FatalConditionHandler::isSet = false; struct sigaction FatalConditionHandler::oldSigActions[sizeof(signalDefs)/sizeof(SignalDefs)] = {}; stack_t FatalConditionHandler::oldSigStack = {}; - char FatalConditionHandler::altStackMem[sigStackSize] = {}; + char FatalConditionHandler::altStackMem[32768] = {}; } // namespace Catch diff --git a/src/lib/component/controller/GraphController.cpp b/src/lib/component/controller/GraphController.cpp index 1252e3fe5..15fb6e522 100644 --- a/src/lib/component/controller/GraphController.cpp +++ b/src/lib/component/controller/GraphController.cpp @@ -76,8 +76,19 @@ void GraphController::handleMessage(MessageActivateOverview* message) } else { - createDummyGraphAndSetActiveAndVisibility( - std::vector(), m_storageAccess->getGraphForAll(), false); + std::shared_ptr graph = m_storageAccess->getGraphForAll(); + + const size_t maxNodes = static_cast( + ApplicationSettings::getInstance()->getGraphMaxCreatedNodes()); + if (graph && graph->getNodeCount() > maxNodes) + { + LOG_WARNING( + "Overview graph has " + std::to_string(graph->getNodeCount()) + + " nodes, exceeding the limit of " + std::to_string(maxNodes) + + ". Showing a bundled overview only; refine the view to expand nodes."); + } + + createDummyGraphAndSetActiveAndVisibility(std::vector(), graph, false); bundleNodesByType(); diff --git a/src/lib/settings/ApplicationSettings.cpp b/src/lib/settings/ApplicationSettings.cpp index 3233ab1ae..47fe96320 100644 --- a/src/lib/settings/ApplicationSettings.cpp +++ b/src/lib/settings/ApplicationSettings.cpp @@ -549,6 +549,16 @@ void ApplicationSettings::setGraphZoomLevel(float zoomLevel) setValue("user/graph_zoom_level", zoomLevel); } +int ApplicationSettings::getGraphMaxCreatedNodes() const +{ + return getValue("application/graph_max_created_nodes", 10000); +} + +void ApplicationSettings::setGraphMaxCreatedNodes(int maxNodes) +{ + setValue("application/graph_max_created_nodes", maxNodes); +} + int ApplicationSettings::getPluginPort() const { return getValue("network/plugin_port", 6666); diff --git a/src/lib/settings/ApplicationSettings.h b/src/lib/settings/ApplicationSettings.h index d3e9afba1..52d4cca26 100644 --- a/src/lib/settings/ApplicationSettings.h +++ b/src/lib/settings/ApplicationSettings.h @@ -141,6 +141,12 @@ class ApplicationSettings: public Settings float getGraphZoomLevel() const; void setGraphZoomLevel(float zoomLevel); + // Maximum number of nodes that may be materialized into the scene at once. + // Above this, the graph view falls back to aggressive bundling / a placeholder + // instead of building tens of thousands of QGraphicsItems (which lags/crashes). + int getGraphMaxCreatedNodes() const; + void setGraphMaxCreatedNodes(int maxNodes); + // network int getPluginPort() const; void setPluginPort(const int pluginPort); diff --git a/src/lib_cxx/data/parser/cxx/CanonicalFilePathCache.cpp b/src/lib_cxx/data/parser/cxx/CanonicalFilePathCache.cpp index feb20669a..abebfc4ad 100644 --- a/src/lib_cxx/data/parser/cxx/CanonicalFilePathCache.cpp +++ b/src/lib_cxx/data/parser/cxx/CanonicalFilePathCache.cpp @@ -31,17 +31,16 @@ FilePath CanonicalFilePathCache::getCanonicalFilePath( FilePath filePath; - const clang::FileEntry* fileEntry = sourceManager.getFileEntryForID(fileId); - if (fileEntry != nullptr) + if (auto fileEntryRef = sourceManager.getFileEntryRefForID(fileId)) { - filePath = getCanonicalFilePath(fileEntry); + filePath = getCanonicalFilePath(*fileEntryRef); m_fileIdMap.emplace(fileId, filePath); } return filePath; } -FilePath CanonicalFilePathCache::getCanonicalFilePath(const clang::FileEntry* entry) +FilePath CanonicalFilePathCache::getCanonicalFilePath(clang::FileEntryRef entry) { return getCanonicalFilePath(utility::getFileNameOfFileEntry(entry)); } @@ -103,7 +102,7 @@ Id CanonicalFilePathCache::getFileSymbolId(const clang::FileID& fileId) return 0; } -Id CanonicalFilePathCache::getFileSymbolId(const clang::FileEntry* entry) +Id CanonicalFilePathCache::getFileSymbolId(clang::FileEntryRef entry) { return getFileSymbolId(utility::getFileNameOfFileEntry(entry)); } @@ -125,8 +124,7 @@ FilePath CanonicalFilePathCache::getDeclarationFilePath(const clang::Decl* decla { const clang::SourceManager& sourceManager = declaration->getASTContext().getSourceManager(); const clang::FileID fileId = sourceManager.getFileID(declaration->getBeginLoc()); - const clang::FileEntry* fileEntry = sourceManager.getFileEntryForID(fileId); - if (fileEntry != nullptr) + if (sourceManager.getFileEntryRefForID(fileId)) { return getCanonicalFilePath(fileId, sourceManager); } diff --git a/src/lib_cxx/data/parser/cxx/CanonicalFilePathCache.h b/src/lib_cxx/data/parser/cxx/CanonicalFilePathCache.h index 733b74d94..406614183 100644 --- a/src/lib_cxx/data/parser/cxx/CanonicalFilePathCache.h +++ b/src/lib_cxx/data/parser/cxx/CanonicalFilePathCache.h @@ -20,13 +20,13 @@ class CanonicalFilePathCache std::shared_ptr getFileRegister() const; FilePath getCanonicalFilePath(const clang::FileID& fileId, const clang::SourceManager& sourceManager); - FilePath getCanonicalFilePath(const clang::FileEntry* entry); + FilePath getCanonicalFilePath(clang::FileEntryRef entry); FilePath getCanonicalFilePath(const std::wstring& path); FilePath getCanonicalFilePath(const Id symbolId); void addFileSymbolId(const clang::FileID& fileId, const FilePath& path, Id symbolId); Id getFileSymbolId(const clang::FileID& fileId); - Id getFileSymbolId(const clang::FileEntry* entry); + Id getFileSymbolId(clang::FileEntryRef entry); Id getFileSymbolId(const std::wstring& path); FilePath getDeclarationFilePath(const clang::Decl* declaration); diff --git a/src/lib_cxx/data/parser/cxx/ClangInvocationInfo.cpp b/src/lib_cxx/data/parser/cxx/ClangInvocationInfo.cpp index 61b73fe3b..cfe6d062f 100644 --- a/src/lib_cxx/data/parser/cxx/ClangInvocationInfo.cpp +++ b/src/lib_cxx/data/parser/cxx/ClangInvocationInfo.cpp @@ -8,7 +8,7 @@ #include #include #include -#include +#include #include "CxxCompilationDatabaseSingle.h" #include "CxxDiagnosticConsumer.h" diff --git a/src/lib_cxx/data/parser/cxx/CxxAstVisitor.cpp b/src/lib_cxx/data/parser/cxx/CxxAstVisitor.cpp index 93e1259fd..585665f38 100644 --- a/src/lib_cxx/data/parser/cxx/CxxAstVisitor.cpp +++ b/src/lib_cxx/data/parser/cxx/CxxAstVisitor.cpp @@ -270,7 +270,10 @@ bool CxxAstVisitor::TraverseTemplateTypeParmDecl(clang::TemplateTypeParmDecl* d) if (d->hasDefaultArgument() && !d->defaultArgumentWasInherited()) { FOREACH_COMPONENT(beginTraverseTemplateDefaultArgumentLoc()); - TraverseTypeLoc(d->getDefaultArgumentInfo()->getTypeLoc()); + if (clang::TypeSourceInfo* defaultArgTSI = d->getDefaultArgument().getTypeSourceInfo()) + { + TraverseTypeLoc(defaultArgTSI->getTypeLoc()); + } FOREACH_COMPONENT(endTraverseTemplateDefaultArgumentLoc()); } @@ -396,24 +399,34 @@ bool CxxAstVisitor::TraverseClassTemplateSpecializationDecl(clang::ClassTemplate if (ReturnValue) { - if (clang::TypeSourceInfo* TSI = D->getTypeAsWritten()) + if (const clang::ASTTemplateArgumentListInfo* argsAsWritten = D->getTemplateArgsAsWritten()) { - clang::TypeLoc::TypeLocClass ccccc = TSI->getTypeLoc().getTypeLocClass(); - const clang::TemplateSpecializationTypeLoc tstl = - TSI->getTypeLoc().getAs(); - if (!tstl.isNull()) + for (const clang::TemplateArgumentLoc& argLoc: argsAsWritten->arguments()) { - for (unsigned I = 0, E = tstl.getNumArgs(); I != E; ++I) + if (!TraverseTemplateArgumentLoc(argLoc)) { - if (!TraverseTemplateArgumentLoc(tstl.getArgLoc(I))) - { - ReturnValue = false; - } + ReturnValue = false; } } } } + // Traverse the base specifiers of the specialization so that the inheritance + // edge of an (implicit) instantiation is recorded with its substituted + // template arguments, e.g. "VectorBase" rather than the generic + // "VectorBase" carried by the primary template. The base type sugar is + // only available on the specialization decl, not the primary template. + if (ReturnValue && D->hasDefinition()) + { + for (const clang::CXXBaseSpecifier& base: D->bases()) + { + if (!traverseCXXBaseSpecifier(base)) + { + ReturnValue = false; + } + } + } + if (ReturnValue) { if (!TraverseNestedNameSpecifierLoc(D->getQualifierLoc())) diff --git a/src/lib_cxx/data/parser/cxx/CxxDiagnosticConsumer.cpp b/src/lib_cxx/data/parser/cxx/CxxDiagnosticConsumer.cpp index 3823f714f..f9fb597f7 100644 --- a/src/lib_cxx/data/parser/cxx/CxxDiagnosticConsumer.cpp +++ b/src/lib_cxx/data/parser/cxx/CxxDiagnosticConsumer.cpp @@ -81,9 +81,9 @@ void CxxDiagnosticConsumer::HandleDiagnostic( } clang::FileID clangFileId = sourceManager.getFileID(loc); - const clang::FileEntry* fileEntry = sourceManager.getFileEntryForID(clangFileId); + clang::OptionalFileEntryRef fileEntry = sourceManager.getFileEntryRefForID(clangFileId); - if (fileEntry != nullptr) + if (fileEntry) { ParseLocation location = utility::getParseLocation( loc, sourceManager, nullptr, m_canonicalFilePathCache); @@ -94,10 +94,10 @@ void CxxDiagnosticConsumer::HandleDiagnostic( } else { - fileEntry = sourceManager.getFileEntryForID(sourceManager.getMainFileID()); - if (fileEntry != nullptr) + fileEntry = sourceManager.getFileEntryRefForID(sourceManager.getMainFileID()); + if (fileEntry) { - filePath = m_canonicalFilePathCache->getCanonicalFilePath(fileEntry); + filePath = m_canonicalFilePathCache->getCanonicalFilePath(*fileEntry); fileId = m_client->recordFile( filePath, false /*keeps the "indexed" state if the file already exists*/); lineNumber = 1; diff --git a/src/lib_cxx/data/parser/cxx/PreprocessorCallbacks.cpp b/src/lib_cxx/data/parser/cxx/PreprocessorCallbacks.cpp index 74df94cdc..77db13428 100644 --- a/src/lib_cxx/data/parser/cxx/PreprocessorCallbacks.cpp +++ b/src/lib_cxx/data/parser/cxx/PreprocessorCallbacks.cpp @@ -58,15 +58,16 @@ void PreprocessorCallbacks::InclusionDirective( llvm::StringRef fileName, bool isAngled, clang::CharSourceRange fileNameRange, - const clang::FileEntry* fileEntry, + clang::OptionalFileEntryRef fileEntry, llvm::StringRef searchPath, llvm::StringRef relativePath, - const clang::Module* imported, + const clang::Module* suggestedModule, + bool moduleImported, clang::SrcMgr::CharacteristicKind fileType) { if (m_currentFileSymbolId && fileEntry) { - const FilePath includedFilePath = m_canonicalFilePathCache->getCanonicalFilePath(fileEntry); + const FilePath includedFilePath = m_canonicalFilePathCache->getCanonicalFilePath(*fileEntry); const NameHierarchy includedFileNameHierarchy(includedFilePath.wstr(), NAME_DELIMITER_FILE); Id includedFileSymbolId = m_client->recordSymbol(includedFileNameHierarchy); diff --git a/src/lib_cxx/data/parser/cxx/PreprocessorCallbacks.h b/src/lib_cxx/data/parser/cxx/PreprocessorCallbacks.h index 6cd57823d..803a59d97 100644 --- a/src/lib_cxx/data/parser/cxx/PreprocessorCallbacks.h +++ b/src/lib_cxx/data/parser/cxx/PreprocessorCallbacks.h @@ -37,10 +37,11 @@ class PreprocessorCallbacks: public clang::PPCallbacks llvm::StringRef fileName, bool isAngled, clang::CharSourceRange fileNameRange, - const clang::FileEntry* fileEntry, + clang::OptionalFileEntryRef fileEntry, llvm::StringRef searchPath, llvm::StringRef relativePath, - const clang::Module* imported, + const clang::Module* suggestedModule, + bool moduleImported, clang::SrcMgr::CharacteristicKind fileType); void MacroDefined( diff --git a/src/lib_cxx/data/parser/cxx/name_resolver/CxxDeclNameResolver.cpp b/src/lib_cxx/data/parser/cxx/name_resolver/CxxDeclNameResolver.cpp index 8ff7e6303..b848974e9 100644 --- a/src/lib_cxx/data/parser/cxx/name_resolver/CxxDeclNameResolver.cpp +++ b/src/lib_cxx/data/parser/cxx/name_resolver/CxxDeclNameResolver.cpp @@ -314,7 +314,7 @@ std::unique_ptr CxxDeclNameResolver::getDeclName(const clang::Named clang::isa(declaration) && clang::dyn_cast(declaration)->isAnonymousNamespace()) { - declaration = clang::dyn_cast(declaration)->getOriginalNamespace(); + declaration = clang::dyn_cast(declaration)->getCanonicalDecl(); return std::make_unique(getNameForAnonymousSymbol(L"namespace", declaration)); } else if (clang::isa(declaration) && declNameString.empty()) diff --git a/src/lib_cxx/data/parser/cxx/utilityClang.cpp b/src/lib_cxx/data/parser/cxx/utilityClang.cpp index 47cf0c2e8..d57cfeed1 100644 --- a/src/lib_cxx/data/parser/cxx/utilityClang.cpp +++ b/src/lib_cxx/data/parser/cxx/utilityClang.cpp @@ -78,15 +78,15 @@ SymbolKind utility::convertTagKind(const clang::TagTypeKind tagKind) { switch (tagKind) { - case clang::TTK_Struct: + case clang::TagTypeKind::Struct: return SYMBOL_STRUCT; - case clang::TTK_Union: + case clang::TagTypeKind::Union: return SYMBOL_UNION; - case clang::TTK_Class: + case clang::TagTypeKind::Class: return SYMBOL_CLASS; - case clang::TTK_Enum: + case clang::TagTypeKind::Enum: return SYMBOL_ENUM; - case clang::TTK_Interface: + case clang::TagTypeKind::Interface: return SYMBOL_KIND_MAX; default: return SYMBOL_KIND_MAX; @@ -126,23 +126,19 @@ SymbolKind utility::getSymbolKind(const clang::VarDecl* d) return symbolKind; } -std::wstring utility::getFileNameOfFileEntry(const clang::FileEntry* entry) +std::wstring utility::getFileNameOfFileEntry(clang::FileEntryRef entry) { - std::wstring fileName = L""; - if (entry != nullptr) + std::wstring fileName = utility::decodeFromUtf8(entry.getFileEntry().tryGetRealPathName().str()); + if (fileName.empty()) { - fileName = utility::decodeFromUtf8(entry->tryGetRealPathName().str()); - if (fileName.empty()) - { - fileName = utility::decodeFromUtf8(entry->getName().str()); - } - else - { - fileName = FilePath(utility::decodeFromUtf8(entry->getName().str())) - .getParentDirectory() - .concatenate(FilePath(fileName).fileName()) - .wstr(); - } + fileName = utility::decodeFromUtf8(entry.getName().str()); + } + else + { + fileName = FilePath(utility::decodeFromUtf8(entry.getName().str())) + .getParentDirectory() + .concatenate(FilePath(fileName).fileName()) + .wstr(); } return fileName; } diff --git a/src/lib_cxx/data/parser/cxx/utilityClang.h b/src/lib_cxx/data/parser/cxx/utilityClang.h index 4371aa9f9..b1f2bce58 100644 --- a/src/lib_cxx/data/parser/cxx/utilityClang.h +++ b/src/lib_cxx/data/parser/cxx/utilityClang.h @@ -2,6 +2,7 @@ #define UTILITY_CLANG_H #include +#include #include "AccessKind.h" #include "SymbolKind.h" @@ -28,7 +29,7 @@ SymbolKind convertTagKind(const clang::TagTypeKind tagKind); bool isLocalVariable(const clang::ValueDecl* d); bool isParameter(const clang::ValueDecl* d); SymbolKind getSymbolKind(const clang::VarDecl* d); -std::wstring getFileNameOfFileEntry(const clang::FileEntry* entry); +std::wstring getFileNameOfFileEntry(clang::FileEntryRef entry); ParseLocation getParseLocation( const clang::SourceLocation& sourceLocation, diff --git a/src/lib_gui/qt/graphics/QtGraphicsView.cpp b/src/lib_gui/qt/graphics/QtGraphicsView.cpp index e231e2e17..f83dcd702 100644 --- a/src/lib_gui/qt/graphics/QtGraphicsView.cpp +++ b/src/lib_gui/qt/graphics/QtGraphicsView.cpp @@ -50,6 +50,17 @@ QtGraphicsView::QtGraphicsView(GraphFocusHandler* focusHandler, QWidget* parent) setTransformationAnchor(QGraphicsView::AnchorUnderMouse); + // Performance tuning for large scenes: + // - Only repaint the regions that actually changed rather than the whole + // viewport on every scene update. + // - Don't save/restore the full painter state per item; nodes manage their + // own pen/brush, so this is safe and cheaper. + // - Skip adjusting paint rects for antialiasing seams (negligible visually, + // measurably cheaper with thousands of items). + setViewportUpdateMode(QGraphicsView::SmartViewportUpdate); + setOptimizationFlags( + QGraphicsView::DontSavePainterState | QGraphicsView::DontAdjustForAntialiasing); + m_timer = std::make_shared(this); connect(m_timer.get(), &QTimer::timeout, this, &QtGraphicsView::updateTimer); diff --git a/src/lib_gui/qt/graphics/graph/QtGraphNode.cpp b/src/lib_gui/qt/graphics/graph/QtGraphNode.cpp index e7a2fd18c..b4987a7be 100644 --- a/src/lib_gui/qt/graphics/graph/QtGraphNode.cpp +++ b/src/lib_gui/qt/graphics/graph/QtGraphNode.cpp @@ -5,7 +5,9 @@ #include #include #include +#include #include +#include #include "GraphFocusHandler.h" #include "MessageCodeShowDefinition.h" @@ -64,6 +66,13 @@ QtGraphNode::QtGraphNode(GraphFocusHandler* focusHandler): m_focusHandler(focusH this->setPen(QPen(Qt::transparent)); this->setCursor(Qt::PointingHandCursor); + // Rasterize each node's subtree once and reuse it while panning/zooming + // instead of repainting text + rounded rects every frame. Major win on + // large overviews where thousands of nodes are visible at once. + this->setCacheMode(QGraphicsItem::DeviceCoordinateCache); + // Ensures levelOfDetailFromTransform() is populated in paint(). + this->setFlag(QGraphicsItem::ItemUsesExtendedStyleOption, true); + m_text = new QGraphicsSimpleTextItem(this); m_rect = new QtRoundedRectItem(this); m_undefinedRect = new QtRoundedRectItem(this); @@ -72,6 +81,28 @@ QtGraphNode::QtGraphNode(GraphFocusHandler* focusHandler): m_focusHandler(focusH QtGraphNode::~QtGraphNode() {} +void QtGraphNode::paint( + QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget) +{ + // Level of detail: how many device pixels one logical unit maps to. + const qreal lod = option->levelOfDetailFromTransform(painter->worldTransform()); + + // Below this, glyphs are sub-pixel and just burn paint time. Hiding the + // text child (the most expensive part to render) keeps zoomed-out overviews + // of large graphs interactive. The node rectangle still draws. + constexpr qreal kTextLodThreshold = 0.4; + if (m_text != nullptr) + { + const bool textShouldBeVisible = lod >= kTextLodThreshold; + if (m_text->isVisible() != textShouldBeVisible && !m_text->text().isEmpty()) + { + m_text->setVisible(textShouldBeVisible); + } + } + + QGraphicsRectItem::paint(painter, option, widget); +} + QtGraphNode* QtGraphNode::getParent() const { return m_parentNode; diff --git a/src/lib_gui/qt/graphics/graph/QtGraphNode.h b/src/lib_gui/qt/graphics/graph/QtGraphNode.h index 9b6e51cc3..664d6d271 100644 --- a/src/lib_gui/qt/graphics/graph/QtGraphNode.h +++ b/src/lib_gui/qt/graphics/graph/QtGraphNode.h @@ -114,6 +114,10 @@ public slots: virtual void updateStyle() = 0; + // Level-of-detail aware painting: hides expensive text rendering when the + // node is drawn too small to be legible (e.g. zoomed-out overview). + void paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget) override; + protected: virtual void mousePressEvent(QGraphicsSceneMouseEvent* event); virtual void mouseMoveEvent(QGraphicsSceneMouseEvent* event); diff --git a/src/lib_gui/qt/view/QtGraphView.cpp b/src/lib_gui/qt/view/QtGraphView.cpp index 81c72ac86..e3fdf3315 100644 --- a/src/lib_gui/qt/view/QtGraphView.cpp +++ b/src/lib_gui/qt/view/QtGraphView.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #include #include #include @@ -347,6 +348,78 @@ void QtGraphView::rebuildGraph( activeNodeCount += nodes[i]->getActiveSubNodeCount(); } + // Safety net: count how many nodes would actually be materialized into + // the scene. Every code path that reaches the view goes through here, so + // this catches the overview AND expanding a bundle with a huge fan-out. + // Above the limit we refuse to build the scene (which would lag/crash) + // and show a short message instead. + { + const size_t maxNodes = static_cast( + ApplicationSettings::getInstance()->getGraphMaxCreatedNodes()); + size_t visibleNodeCount = 0; + for (const std::shared_ptr& n: nodes) + { + n->forEachDummyNodeRecursive([&visibleNodeCount](DummyNode* d) { + if (d->visible) + { + ++visibleNodeCount; + } + }); + } + + if (visibleNodeCount > maxNodes) + { + LOG_WARNING( + "Refusing to render " + std::to_string(visibleNodeCount) + + " nodes (limit " + std::to_string(maxNodes) + + "). Showing placeholder; refine the view or raise " + "application/graph_max_created_nodes."); + + // Tear down the existing graph the same way clear() does before + // bailing out. scene()->clear() synchronously deletes every + // QGraphicsItem, so any member still pointing at those items + // (the focus handler, the old node/edge lists, the active node) + // would dangle and crash on the next event. Mirror clear()'s + // ordering exactly, but inline: we are already running inside an + // m_onQtThread lambda here, and calling clear() would nest a + // second dispatch and run this teardown out of order. + m_focusHandler.clear(); + + m_oldActiveNode = nullptr; + m_activeNodes.clear(); + + for (QtGraphNode* node: m_oldNodes) + { + node->deleteLater(); + } + for (QtGraphEdge* edge: m_oldEdges) + { + edge->deleteLater(); + } + + m_nodes.clear(); + m_edges.clear(); + m_oldNodes.clear(); + m_oldEdges.clear(); + + m_graph.reset(); + m_oldGraph.reset(); + + m_matchedNodes.clear(); + + getView()->scene()->clear(); + + QGraphicsTextItem* msg = getView()->scene()->addText( + QStringLiteral( + "This view contains %1 nodes, which is too many to display.\n" + "Refine your selection, or raise the node limit in settings.") + .arg(visibleNodeCount)); + msg->setDefaultTextColor(Qt::gray); + getView()->setSceneRect(msg->boundingRect()); + return; + } + } + Id oldActiveTokenId = m_oldActiveNode ? m_oldActiveNode->getTokenId() : 0; m_nodes.clear(); m_activeNodes.clear(); @@ -428,8 +501,16 @@ void QtGraphView::rebuildGraph( m_scrollToTop = params.scrollToTop; m_isIndexedList = params.isIndexedList; - if (params.animatedTransition && ApplicationSettings::getInstance()->getUseAnimations() && - view->isVisible()) + // Animated transitions keep both the old and new node sets alive + // simultaneously and animate every item; on large graphs this is the + // most common cause of freezes. Skip straight to the new data above a + // threshold, regardless of the global animation setting. + const bool tooManyForAnimation = + (m_nodes.size() + m_oldNodes.size()) > + static_cast(ApplicationSettings::getInstance()->getGraphMaxCreatedNodes()); + + if (params.animatedTransition && !tooManyForAnimation && + ApplicationSettings::getInstance()->getUseAnimations() && view->isVisible()) { createTransition(); } diff --git a/src/test/CxxParserTestSuite.cpp b/src/test/CxxParserTestSuite.cpp index 0c57ec1e7..45c671530 100644 --- a/src/test/CxxParserTestSuite.cpp +++ b/src/test/CxxParserTestSuite.cpp @@ -1006,6 +1006,25 @@ TEST_CASE("cxx parser finds explicit partial variable template specialization") client->globalVariables, L"int t <5:5 5:5>")); } +TEST_CASE("cxx parser finds type used as argument in explicit class template specialization") +{ + std::shared_ptr client = parseCode( + "struct S\n" + "{\n" + "};\n" + "template \n" + "class A\n" + "{\n" + "};\n" + "template <>\n" + "class A\n" + "{\n" + "};\n"); + + REQUIRE(utility::containsElement(client->classes, L"A <8:1 <9:7 9:7> 11:1>")); + REQUIRE(utility::containsElement(client->typeUses, L"A -> S <9:9 9:9>")); +} + TEST_CASE("cxx parser finds correct field member name of template class in declaration") { std::shared_ptr client = parseCode( @@ -3422,8 +3441,10 @@ TEST_CASE("record base class of implicit template class specialization") "\n" "Vec2f v; \n"); + // Note: since LLVM/Clang 19 the unsigned non-type template argument 2 is + // pretty-printed canonically as "2U" (reflecting its unsigned int type). REQUIRE(utility::containsElement( - client->inheritances, L"Vector2 -> VectorBase <5:24 5:33>")); + client->inheritances, L"Vector2 -> VectorBase <5:24 5:33>")); } TEST_CASE("cxx parser finds template class specialization with template argument") diff --git a/zensical.toml b/zensical.toml new file mode 100644 index 000000000..6cae5c40d --- /dev/null +++ b/zensical.toml @@ -0,0 +1,326 @@ +[project] +site_name = "NumbatUI Documentation" +site_description = "Quarkslab fork of Sourcetrail - free and open-source interactive source explorer " +site_author = "Quarkslab" +site_url = "https://quarkslab.github.io/numbatui/" +repo_name = "quarkslab/NumbatUI" +repo_url = "https://github.com/quarkslab/numbatui" +copyright = """ +Copyright © 2024-2026 Quarkslab +""" + +# Zensical supports both implicit navigation and explicitly defined navigation. +# If you decide not to define a navigation here then Zensical will simply +# derive the navigation structure from the directory structure of your +# "docs_dir". The definition below demonstrates how a navigation structure +# can be defined using TOML syntax. +# +# Read more: https://zensical.org/docs/setup/navigation/ +nav = [ + { "Home" = "index.md" }, + { "Installation" = "installation.md" }, + { "Getting Started" = "getting_started.md" }, + { "Project Setup" = "project_setup.md" }, + { "Interface" = "interface.md" }, + +] + +# With the "extra_css" option you can add your own CSS styling to customize +# your Zensical project according to your needs. You can add any number of +# CSS files. +# +# The path provided should be relative to the "docs_dir". +# +# Read more: https://zensical.org/docs/customization/#additional-css +# +#extra_css = ["stylesheets/extra.css"] + +# With the `extra_javascript` option you can add your own JavaScript to your +# project to customize the behavior according to your needs. +# +# The path provided should be relative to the "docs_dir". +# +# Read more: https://zensical.org/docs/customization/#additional-javascript +#extra_javascript = ["javascripts/extra.js"] + +# ---------------------------------------------------------------------------- +# Section for configuring theme options +# ---------------------------------------------------------------------------- +[project.theme] + +# change this to "classic" to use the traditional Material for MkDocs look. +#variant = "classic" + +# Zensical allows you to override specific blocks, partials, or whole +# templates as well as to define your own templates. To do this, uncomment +# the custom_dir setting below and set it to a directory in which you +# keep your template overrides. +# +# Read more: +# - https://zensical.org/docs/customization/#extending-the-theme +# +#custom_dir = "overrides" + +# With the "favicon" option you can set your own image to use as the icon +# browsers will use in the browser title bar or tab bar. The path provided +# must be relative to the "docs_dir". +# +# Read more: +# - https://zensical.org/docs/setup/logo-and-icons/#favicon +# - https://developer.mozilla.org/en-US/docs/Glossary/Favicon +# +favicon = "logo/numbatui_192.png" + +# Zensical supports more than 60 different languages. This means that the +# labels and tooltips that Zensical's templates produce are translated. +# The "language" option allows you to set the language used. This language +# is also indicated in the HTML head element to help with accessibility +# and guide search engines and translation tools. +# +# The default language is "en" (English). It is possible to create +# sites with multiple languages and configure a language selector. See +# the documentation for details. +# +# Read more: +# - https://zensical.org/docs/setup/language/ +# +language = "en" + +# Zensical provides a number of feature toggles that change the behavior +# of the documentation site. +features = [ + # Zensical includes an announcement bar. This feature allows users to + # dismiss it when they have read the announcement. + # https://zensical.org/docs/setup/header/#announcement-bar + "announce.dismiss", + + # If you have a repository configured and turn on this feature, Zensical + # will generate an edit button for the page. This works for common + # repository hosting services. + # https://zensical.org/docs/setup/repository/#content-actions + #"content.action.edit", + + # If you have a repository configured and turn on this feature, Zensical + # will generate a button that allows the user to view the Markdown + # code for the current page. + # https://zensical.org/docs/setup/repository/#content-actions + #"content.action.view", + + # Code annotations allow you to add an icon with a tooltip to your + # code blocks to provide explanations at crucial points. + # https://zensical.org/docs/authoring/code-blocks/#code-annotations + "content.code.annotate", + + # This feature turns on a button in code blocks that allow users to + # copy the content to their clipboard without first selecting it. + # https://zensical.org/docs/authoring/code-blocks/#code-copy-button + "content.code.copy", + + # Code blocks can include a button to allow for the selection of line + # ranges by the user. + # https://zensical.org/docs/authoring/code-blocks/#code-selection-button + "content.code.select", + + # Zensical can render footnotes as inline tooltips, so the user can read + # the footnote without leaving the context of the document. + # https://zensical.org/docs/authoring/footnotes/#footnote-tooltips + "content.footnote.tooltips", + + # If you have many content tabs that have the same titles (e.g., "Python", + # "JavaScript", "Cobol"), this feature causes all of them to switch to + # at the same time when the user chooses their language in one. + # https://zensical.org/docs/authoring/content-tabs/#linked-content-tabs + "content.tabs.link", + + # With this feature enabled users can add tooltips to links that will be + # displayed when the mouse pointer hovers the link. + # https://zensical.org/docs/authoring/tooltips/#improved-tooltips + "content.tooltips", + + # With this feature enabled, Zensical will automatically hide parts + # of the header when the user scrolls past a certain point. + # https://zensical.org/docs/setup/header/#automatic-hiding + # "header.autohide", + + # Turn on this feature to expand all collapsible sections in the + # navigation sidebar by default. + # https://zensical.org/docs/setup/navigation/#navigation-expansion + # "navigation.expand", + + # This feature turns on navigation elements in the footer that allow the + # user to navigate to a next or previous page. + # https://zensical.org/docs/setup/footer/#navigation + "navigation.footer", + + # When section index pages are enabled, documents can be directly attached + # to sections, which is particularly useful for providing overview pages. + # https://zensical.org/docs/setup/navigation/#section-index-pages + "navigation.indexes", + + # When instant navigation is enabled, clicks on all internal links will be + # intercepted and dispatched via XHR without fully reloading the page. + # https://zensical.org/docs/setup/navigation/#instant-navigation + "navigation.instant", + + # With instant prefetching, your site will start to fetch a page once the + # user hovers over a link. This will reduce the perceived loading time + # for the user. + # https://zensical.org/docs/setup/navigation/#instant-prefetching + "navigation.instant.prefetch", + + # In order to provide a better user experience on slow connections when + # using instant navigation, a progress indicator can be enabled. + # https://zensical.org/docs/setup/navigation/#progress-indicator + #"navigation.instant.progress", + + # When navigation paths are activated, a breadcrumb navigation is rendered + # above the title of each page + # https://zensical.org/docs/setup/navigation/#navigation-path + #"navigation.path", + + # When pruning is enabled, only the visible navigation items are included + # in the rendered HTML, reducing the size of the built site by 33% or more. + # https://zensical.org/docs/setup/navigation/#navigation-pruning + #"navigation.prune", + + # When sections are enabled, top-level sections are rendered as groups in + # the sidebar for viewports above 1220px, but remain as-is on mobile. + # https://zensical.org/docs/setup/navigation/#navigation-sections + "navigation.sections", + + # When tabs are enabled, top-level sections are rendered in a menu layer + # below the header for viewports above 1220px, but remain as-is on mobile. + # https://zensical.org/docs/setup/navigation/#navigation-tabs + #"navigation.tabs", + + # When sticky tabs are enabled, navigation tabs will lock below the header + # and always remain visible when scrolling down. + # https://zensical.org/docs/setup/navigation/#sticky-navigation-tabs + #"navigation.tabs.sticky", + + # A back-to-top button can be shown when the user, after scrolling down, + # starts to scroll up again. + # https://zensical.org/docs/setup/navigation/#back-to-top-button + "navigation.top", + + # When anchor tracking is enabled, the URL in the address bar is + # automatically updated with the active anchor as highlighted in the table + # of contents. + # https://zensical.org/docs/setup/navigation/#anchor-tracking + "navigation.tracking", + + # When search highlighting is enabled and a user clicks on a search result, + # Zensical will highlight all occurrences after following the link. + # https://zensical.org/docs/setup/search/#search-highlighting + "search.highlight", + + # When anchor following for the table of contents is enabled, the sidebar + # is automatically scrolled so that the active anchor is always visible. + # https://zensical.org/docs/setup/navigation/#anchor-following + "toc.follow", + + # When navigation integration for the table of contents is enabled, it is + # always rendered as part of the navigation sidebar on the left. + # https://zensical.org/docs/setup/navigation/#navigation-integration + "toc.integrate", +] + +# ---------------------------------------------------------------------------- +# You can configure your own logo to be shown in the header using the "logo" +# option in the "theme" subsection. The logo must be a relative path to a file +# in your "docs_dir", e.g., to use `docs/assets/logo.png` you would set: +# ---------------------------------------------------------------------------- +logo = "logo/numbatui_192.png" + +# ---------------------------------------------------------------------------- +# If you don't have a dedicated project logo, you can use a built-in icon from +# the icon sets shipped in Zensical. Please note that the setting lives in a +# different subsection, and that the above take precedence over the icon. +# +# Read more: +# - https://zensical.org/docs/setup/logo-and-icons +# - https://github.com/zensical/ui/tree/master/dist/.icons +# ---------------------------------------------------------------------------- +#[project.theme.icon] +#logo = "lucide/smile" + +# ---------------------------------------------------------------------------- +# In the "font" subsection you can configure the fonts used. By default, fonts +# are loaded from Google Fonts, giving you a wide range of choices from a set +# of suitably licensed fonts. There are options for a normal text font and for +# a monospaced font used in code blocks. +# ---------------------------------------------------------------------------- +#[project.theme.font] +#text = "Inter" +#code = "Jetbrains Mono" + +# ---------------------------------------------------------------------------- +# In the "palette" subsection you can configure options for the color scheme. +# You can configure different color schemes, e.g., to turn on dark mode, +# that the user can switch between. Each color scheme can be further +# customized. +# +# Read more: +# - https://zensical.org/docs/setup/colors/ +# ---------------------------------------------------------------------------- +[[project.theme.palette]] +scheme = "default" +toggle.icon = "lucide/sun" +toggle.name = "Switch to dark mode" + +[[project.theme.palette]] +scheme = "slate" +toggle.icon = "lucide/moon" +toggle.name = "Switch to light mode" + +# ---------------------------------------------------------------------------- +# The "extra" section contains miscellaneous settings. +# ---------------------------------------------------------------------------- +[[project.extra.social]] +icon = "fontawesome/brands/github" +link = "https://github.com/quarkslab/numbatui" + +# ---------------------------------------------------------------------------- +# In this section you can configure the Markdown extensions that are used when +# rendering your documentation. We enable the most useful extensions by default, +# but you can customize this list to your needs. +# +# Read more: +# - https://zensical.org/docs/setup/extensions/ +# ---------------------------------------------------------------------------- +[project.markdown_extensions.abbr] +[project.markdown_extensions.admonition] +[project.markdown_extensions.attr_list] +[project.markdown_extensions.def_list] +[project.markdown_extensions.footnotes] +[project.markdown_extensions.md_in_html] +[project.markdown_extensions.toc] +permalink = true +[project.markdown_extensions.pymdownx.arithmatex] +generic = true +[project.markdown_extensions.pymdownx.betterem] +[project.markdown_extensions.pymdownx.caret] +[project.markdown_extensions.pymdownx.details] +[project.markdown_extensions.pymdownx.emoji] +emoji_generator = "zensical.extensions.emoji.to_svg" +emoji_index = "zensical.extensions.emoji.twemoji" +[project.markdown_extensions.pymdownx.highlight] +anchor_linenums = true +line_spans = "__span" +pygments_lang_class = true +[project.markdown_extensions.pymdownx.inlinehilite] +[project.markdown_extensions.pymdownx.keys] +[project.markdown_extensions.pymdownx.magiclink] +[project.markdown_extensions.pymdownx.mark] +[project.markdown_extensions.pymdownx.smartsymbols] +[project.markdown_extensions.pymdownx.snippets] +[project.markdown_extensions.pymdownx.superfences] +custom_fences = [ + { name = "mermaid", class = "mermaid", format = "pymdownx.superfences.fence_code_format" }, +] +[project.markdown_extensions.pymdownx.tabbed] +alternate_style = true +combine_header_slug = true +[project.markdown_extensions.pymdownx.tasklist] +custom_checkbox = true +[project.markdown_extensions.pymdownx.tilde]