diff --git a/CMakeLists.txt b/CMakeLists.txt index 16e8f4b..eb10c64 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,7 +1,7 @@ cmake_minimum_required(VERSION 3.16) project(BareCode - VERSION 1.0.0 + VERSION 1.1.0 DESCRIPTION "A modular code editor built with Qt6" LANGUAGES CXX ) diff --git a/README.md b/README.md index 8b0ac51..f6e99d6 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # BareCode -Ein modularer Code-Editor, entwickelt mit **C++17**, **Qt6** und **CMake** -von **Dany Thinnes** | [Projekt Hirnfrei](https://www.projekt-hirnfrei.de) +**BareCode – Schlanker Code-Editor für Web-Entwickler** +Version 1.1.0 Kompiliert sauber auf **Linux**, **Windows** und **Haiku**. diff --git a/main.cpp b/main.cpp index c24c0bc..babe9b5 100644 --- a/main.cpp +++ b/main.cpp @@ -7,7 +7,7 @@ int main(int argc, char *argv[]) QApplication app(argc, argv); app.setApplicationName("BareCode"); - app.setApplicationVersion("1.0.0"); + app.setApplicationVersion("1.1.0"); app.setOrganizationName("BareCode"); // Icon in allen verfügbaren Größen setzen diff --git a/resources/php_functions.json b/resources/php_functions.json new file mode 100644 index 0000000..1e81c97 --- /dev/null +++ b/resources/php_functions.json @@ -0,0 +1,1197 @@ +[ + { + "name": "abs", + "signature": "abs(int|float $num): int|float", + "desc": "Absolutwert" + }, + { + "name": "addslashes", + "signature": "addslashes(string $string): string", + "desc": "Sonderzeichen mit Backslash escapen" + }, + { + "name": "array_chunk", + "signature": "array_chunk(array $array, int $length, bool $preserve_keys = false): array", + "desc": "Array in Stücke aufteilen" + }, + { + "name": "array_column", + "signature": "array_column(array $array, int|string|null $column_key, int|string|null $index_key = null): array", + "desc": "Spalte aus mehrdimensionalem Array" + }, + { + "name": "array_combine", + "signature": "array_combine(array $keys, array $values): array", + "desc": "Array aus Schlüsseln und Werten erstellen" + }, + { + "name": "array_diff", + "signature": "array_diff(array $array, array ...$arrays): array", + "desc": "Differenz zweier Arrays" + }, + { + "name": "array_fill", + "signature": "array_fill(int $start_index, int $count, mixed $value): array", + "desc": "Array mit Werten füllen" + }, + { + "name": "array_fill_keys", + "signature": "array_fill_keys(array $keys, mixed $value): array", + "desc": "Array mit Schlüsseln und Wert füllen" + }, + { + "name": "array_filter", + "signature": "array_filter(array $array, callable $callback = null, int $mode = 0): array", + "desc": "Array filtern" + }, + { + "name": "array_flip", + "signature": "array_flip(array $array): array", + "desc": "Schlüssel und Werte tauschen" + }, + { + "name": "array_intersect", + "signature": "array_intersect(array $array, array ...$arrays): array", + "desc": "Schnittmenge zweier Arrays" + }, + { + "name": "array_key_exists", + "signature": "array_key_exists(string|int $key, array $array): bool", + "desc": "Prüft ob Schlüssel existiert" + }, + { + "name": "array_key_first", + "signature": "array_key_first(array $array): int|string|null", + "desc": "Ersten Schlüssel eines Arrays" + }, + { + "name": "array_key_last", + "signature": "array_key_last(array $array): int|string|null", + "desc": "Letzten Schlüssel eines Arrays" + }, + { + "name": "array_keys", + "signature": "array_keys(array $array, mixed $filter_value = null, bool $strict = false): array", + "desc": "Alle Schlüssel zurückgeben" + }, + { + "name": "array_map", + "signature": "array_map(callable|null $callback, array $array, array ...$arrays): array", + "desc": "Funktion auf alle Elemente anwenden" + }, + { + "name": "array_merge", + "signature": "array_merge(array ...$arrays): array", + "desc": "Arrays zusammenführen" + }, + { + "name": "array_merge_recursive", + "signature": "array_merge_recursive(array ...$arrays): array", + "desc": "Arrays rekursiv zusammenführen" + }, + { + "name": "array_pop", + "signature": "array_pop(array &$array): mixed", + "desc": "Letztes Element entfernen und zurückgeben" + }, + { + "name": "array_push", + "signature": "array_push(array &$array, mixed ...$values): int", + "desc": "Elemente ans Ende anhängen" + }, + { + "name": "array_reduce", + "signature": "array_reduce(array $array, callable $callback, mixed $initial = null): mixed", + "desc": "Array auf einen Wert reduzieren" + }, + { + "name": "array_reverse", + "signature": "array_reverse(array $array, bool $preserve_keys = false): array", + "desc": "Array umkehren" + }, + { + "name": "array_search", + "signature": "array_search(mixed $needle, array $haystack, bool $strict = false): int|string|false", + "desc": "Wert im Array suchen" + }, + { + "name": "array_shift", + "signature": "array_shift(array &$array): mixed", + "desc": "Erstes Element entfernen und zurückgeben" + }, + { + "name": "array_slice", + "signature": "array_slice(array $array, int $offset, int $length = null, bool $preserve_keys = false): array", + "desc": "Teilarray zurückgeben" + }, + { + "name": "array_splice", + "signature": "array_splice(array &$array, int $offset, int $length = null, mixed $replacement = []): array", + "desc": "Array-Elemente entfernen und ersetzen" + }, + { + "name": "array_unique", + "signature": "array_unique(array $array, int $flags = SORT_STRING): array", + "desc": "Doppelte Werte entfernen" + }, + { + "name": "array_unshift", + "signature": "array_unshift(array &$array, mixed ...$values): int", + "desc": "Elemente am Anfang einfügen" + }, + { + "name": "array_values", + "signature": "array_values(array $array): array", + "desc": "Alle Werte neu indiziert zurückgeben" + }, + { + "name": "array_walk", + "signature": "array_walk(array|object &$array, callable $callback, mixed $arg = null): bool", + "desc": "Funktion auf jedes Element anwenden" + }, + { + "name": "arsort", + "signature": "arsort(array &$array, int $flags = SORT_REGULAR): bool", + "desc": "Array absteigend sortieren, Schlüssel beibehalten" + }, + { + "name": "asort", + "signature": "asort(array &$array, int $flags = SORT_REGULAR): bool", + "desc": "Array aufsteigend sortieren, Schlüssel beibehalten" + }, + { + "name": "base64_decode", + "signature": "base64_decode(string $string, bool $strict = false): string|false", + "desc": "Base64 dekodieren" + }, + { + "name": "base64_encode", + "signature": "base64_encode(string $string): string", + "desc": "Base64 kodieren" + }, + { + "name": "basename", + "signature": "basename(string $path, string $suffix = ''): string", + "desc": "Dateinamen aus Pfad" + }, + { + "name": "boolval", + "signature": "boolval(mixed $value): bool", + "desc": "In Boolean umwandeln" + }, + { + "name": "call_user_func", + "signature": "call_user_func(callable $callback, mixed ...$args): mixed", + "desc": "Funktion aufrufen" + }, + { + "name": "call_user_func_array", + "signature": "call_user_func_array(callable $callback, array $args): mixed", + "desc": "Funktion mit Array-Parametern aufrufen" + }, + { + "name": "ceil", + "signature": "ceil(int|float $num): float", + "desc": "Aufrunden" + }, + { + "name": "checkdate", + "signature": "checkdate(int $month, int $day, int $year): bool", + "desc": "Datum auf Gültigkeit prüfen" + }, + { + "name": "chunk_split", + "signature": "chunk_split(string $string, int $length = 76, string $separator = \"\\r\\n\"): string", + "desc": "String in Stücke aufteilen" + }, + { + "name": "class_exists", + "signature": "class_exists(string $class, bool $autoload = true): bool", + "desc": "Prüft ob Klasse existiert" + }, + { + "name": "compact", + "signature": "compact(array|string $var_names, mixed ...$vars): array", + "desc": "Array aus Variablen erstellen" + }, + { + "name": "constant", + "signature": "constant(string $name): mixed", + "desc": "Wert einer Konstante" + }, + { + "name": "copy", + "signature": "copy(string $from, string $to, resource $context = null): bool", + "desc": "Datei kopieren" + }, + { + "name": "count", + "signature": "count(Countable|array $array, int $mode = COUNT_NORMAL): int", + "desc": "Anzahl der Elemente" + }, + { + "name": "date", + "signature": "date(string $format, int $timestamp = time()): string", + "desc": "Datum formatieren" + }, + { + "name": "date_add", + "signature": "date_add(DateTime $object, DateInterval $interval): DateTime|false", + "desc": "Interval zu Datum addieren" + }, + { + "name": "date_create", + "signature": "date_create(string $datetime = 'now', DateTimeZone $timezone = null): DateTime|false", + "desc": "DateTime-Objekt erstellen" + }, + { + "name": "date_diff", + "signature": "date_diff(DateTimeInterface $baseObject, DateTimeInterface $targetObject, bool $absolute = false): DateInterval", + "desc": "Differenz zweier Datumswerte" + }, + { + "name": "date_format", + "signature": "date_format(DateTimeInterface $object, string $format): string", + "desc": "DateTime formatieren" + }, + { + "name": "date_sub", + "signature": "date_sub(DateTime $object, DateInterval $interval): DateTime|false", + "desc": "Interval von Datum subtrahieren" + }, + { + "name": "define", + "signature": "define(string $constant_name, mixed $value, bool $case_insensitive = false): bool", + "desc": "Konstante definieren" + }, + { + "name": "defined", + "signature": "defined(string $constant_name): bool", + "desc": "Prüft ob Konstante definiert ist" + }, + { + "name": "die", + "signature": "die(int|string $status = 0): never", + "desc": "Skript beenden (Alias exit)" + }, + { + "name": "dirname", + "signature": "dirname(string $path, int $levels = 1): string", + "desc": "Verzeichnisteil eines Pfades" + }, + { + "name": "echo", + "signature": "echo(string ...$expressions): void", + "desc": "Strings ausgeben" + }, + { + "name": "empty", + "signature": "empty(mixed $var): bool", + "desc": "Prüft ob Variable leer ist" + }, + { + "name": "error_reporting", + "signature": "error_reporting(int $error_level = null): int", + "desc": "Fehler-Reporting-Level setzen" + }, + { + "name": "exit", + "signature": "exit(int|string $status = 0): never", + "desc": "Skript beenden" + }, + { + "name": "exp", + "signature": "exp(float $num): float", + "desc": "e hoch x" + }, + { + "name": "explode", + "signature": "explode(string $separator, string $string, int $limit = PHP_INT_MAX): array", + "desc": "String aufteilen" + }, + { + "name": "extract", + "signature": "extract(array &$array, int $flags = EXTR_OVERWRITE, string $prefix = ''): int", + "desc": "Variablen aus Array importieren" + }, + { + "name": "fclose", + "signature": "fclose(resource $handle): bool", + "desc": "Datei schließen" + }, + { + "name": "feof", + "signature": "feof(resource $handle): bool", + "desc": "Prüft ob Dateiende erreicht" + }, + { + "name": "fgets", + "signature": "fgets(resource $handle, int $length = null): string|false", + "desc": "Zeile aus Datei lesen" + }, + { + "name": "file", + "signature": "file(string $filename, int $flags = 0, resource $context = null): array|false", + "desc": "Datei als Array von Zeilen" + }, + { + "name": "file_exists", + "signature": "file_exists(string $filename): bool", + "desc": "Prüft ob Datei existiert" + }, + { + "name": "file_get_contents", + "signature": "file_get_contents(string $filename, bool $use_include_path = false, resource $context = null, int $offset = 0, int $length = null): string|false", + "desc": "Dateiinhalt als String" + }, + { + "name": "file_put_contents", + "signature": "file_put_contents(string $filename, mixed $data, int $flags = 0, resource $context = null): int|false", + "desc": "String in Datei schreiben" + }, + { + "name": "filectime", + "signature": "filectime(string $filename): int|false", + "desc": "Zeitpunkt der letzten Statusänderung" + }, + { + "name": "filemtime", + "signature": "filemtime(string $filename): int|false", + "desc": "Zeitpunkt der letzten Änderung" + }, + { + "name": "filesize", + "signature": "filesize(string $filename): int|false", + "desc": "Dateigröße in Bytes" + }, + { + "name": "floatval", + "signature": "floatval(mixed $value): float", + "desc": "In Float umwandeln" + }, + { + "name": "floor", + "signature": "floor(int|float $num): float", + "desc": "Abrunden" + }, + { + "name": "fmod", + "signature": "fmod(float $num1, float $num2): float", + "desc": "Modulo für Floats" + }, + { + "name": "fopen", + "signature": "fopen(string $filename, string $mode, bool $use_include_path = false, resource $context = null): resource|false", + "desc": "Datei öffnen" + }, + { + "name": "fread", + "signature": "fread(resource $handle, int $length): string|false", + "desc": "Aus Datei lesen" + }, + { + "name": "fseek", + "signature": "fseek(resource $handle, int $offset, int $whence = SEEK_SET): int", + "desc": "Dateizeiger setzen" + }, + { + "name": "ftell", + "signature": "ftell(resource $handle): int|false", + "desc": "Aktuelle Position des Dateizeigers" + }, + { + "name": "function_exists", + "signature": "function_exists(string $function): bool", + "desc": "Prüft ob Funktion existiert" + }, + { + "name": "fwrite", + "signature": "fwrite(resource $handle, string $string, int $length = null): int|false", + "desc": "In Datei schreiben" + }, + { + "name": "get_class", + "signature": "get_class(object $object = null): string|false", + "desc": "Klassenname eines Objekts" + }, + { + "name": "get_parent_class", + "signature": "get_parent_class(object|string $object_or_class): string|false", + "desc": "Elternklasse ermitteln" + }, + { + "name": "gettype", + "signature": "gettype(mixed $value): string", + "desc": "Typ einer Variable" + }, + { + "name": "glob", + "signature": "glob(string $pattern, int $flags = 0): array|false", + "desc": "Dateien per Muster suchen" + }, + { + "name": "hash", + "signature": "hash(string $algo, string $data, bool $binary = false, array $options = []): string", + "desc": "Hash mit beliebigem Algorithmus" + }, + { + "name": "header", + "signature": "header(string $header, bool $replace = true, int $response_code = 0): void", + "desc": "HTTP-Header senden" + }, + { + "name": "headers_sent", + "signature": "headers_sent(string &$filename = null, int &$line = null): bool", + "desc": "Prüft ob Header bereits gesendet" + }, + { + "name": "htmlentities", + "signature": "htmlentities(string $string, int $flags = ENT_QUOTES|ENT_SUBSTITUTE, string $encoding = 'UTF-8', bool $double_encode = true): string", + "desc": "Alle Sonderzeichen in HTML-Entities" + }, + { + "name": "htmlspecialchars", + "signature": "htmlspecialchars(string $string, int $flags = ENT_QUOTES|ENT_SUBSTITUTE, string $encoding = 'UTF-8', bool $double_encode = true): string", + "desc": "Sonderzeichen in HTML-Entities umwandeln" + }, + { + "name": "htmlspecialchars_decode", + "signature": "htmlspecialchars_decode(string $string, int $flags = ENT_QUOTES|ENT_SUBSTITUTE): string", + "desc": "HTML-Entities zurückumwandeln" + }, + { + "name": "http_build_query", + "signature": "http_build_query(array|object $data, string $numeric_prefix = '', string $arg_separator = null, int $encoding_type = PHP_QUERY_RFC1738): string", + "desc": "Query-String aufbauen" + }, + { + "name": "implode", + "signature": "implode(string $separator, array $array): string", + "desc": "Array zu String verbinden" + }, + { + "name": "in_array", + "signature": "in_array(mixed $needle, array $haystack, bool $strict = false): bool", + "desc": "Prüft ob Wert im Array vorhanden" + }, + { + "name": "include", + "signature": "include(string $filename): mixed", + "desc": "Datei einbinden" + }, + { + "name": "include_once", + "signature": "include_once(string $filename): mixed", + "desc": "Datei einmalig einbinden" + }, + { + "name": "ini_get", + "signature": "ini_get(string $option): string|false", + "desc": "PHP-Konfigurationswert holen" + }, + { + "name": "ini_set", + "signature": "ini_set(string $option, string $value): string|false", + "desc": "PHP-Konfigurationswert setzen" + }, + { + "name": "instanceof", + "signature": "instanceof", + "desc": "Prüft ob Objekt eine Instanz ist" + }, + { + "name": "intdiv", + "signature": "intdiv(int $num1, int $num2): int", + "desc": "Ganzzahlige Division" + }, + { + "name": "intval", + "signature": "intval(mixed $value, int $base = 10): int", + "desc": "In Integer umwandeln" + }, + { + "name": "is_array", + "signature": "is_array(mixed $value): bool", + "desc": "Prüft ob Array" + }, + { + "name": "is_bool", + "signature": "is_bool(mixed $value): bool", + "desc": "Prüft ob Boolean" + }, + { + "name": "is_callable", + "signature": "is_callable(mixed $value, bool $syntax_only = false, string &$callable_name = null): bool", + "desc": "Prüft ob aufrufbar" + }, + { + "name": "is_dir", + "signature": "is_dir(string $filename): bool", + "desc": "Prüft ob Pfad ein Verzeichnis ist" + }, + { + "name": "is_file", + "signature": "is_file(string $filename): bool", + "desc": "Prüft ob Pfad eine Datei ist" + }, + { + "name": "is_float", + "signature": "is_float(mixed $value): bool", + "desc": "Prüft ob Float" + }, + { + "name": "is_int", + "signature": "is_int(mixed $value): bool", + "desc": "Prüft ob Integer" + }, + { + "name": "is_null", + "signature": "is_null(mixed $value): bool", + "desc": "Prüft ob Wert null ist" + }, + { + "name": "is_numeric", + "signature": "is_numeric(mixed $value): bool", + "desc": "Prüft ob numerisch" + }, + { + "name": "is_object", + "signature": "is_object(mixed $value): bool", + "desc": "Prüft ob Objekt" + }, + { + "name": "is_readable", + "signature": "is_readable(string $filename): bool", + "desc": "Prüft ob Datei lesbar ist" + }, + { + "name": "is_string", + "signature": "is_string(mixed $value): bool", + "desc": "Prüft ob String" + }, + { + "name": "is_writable", + "signature": "is_writable(string $filename): bool", + "desc": "Prüft ob Datei schreibbar ist" + }, + { + "name": "isset", + "signature": "isset(mixed $var, mixed ...$vars): bool", + "desc": "Prüft ob Variable gesetzt und nicht null" + }, + { + "name": "join", + "signature": "join(string $separator, array $array): string", + "desc": "Array zu String verbinden (Alias implode)" + }, + { + "name": "json_decode", + "signature": "json_decode(string $json, bool $associative = null, int $depth = 512, int $flags = 0): mixed", + "desc": "JSON parsen" + }, + { + "name": "json_encode", + "signature": "json_encode(mixed $value, int $flags = 0, int $depth = 512): string|false", + "desc": "In JSON umwandeln" + }, + { + "name": "json_last_error", + "signature": "json_last_error(): int", + "desc": "Letzten JSON-Fehler abrufen" + }, + { + "name": "json_last_error_msg", + "signature": "json_last_error_msg(): string", + "desc": "Letzten JSON-Fehler als Text" + }, + { + "name": "krsort", + "signature": "krsort(array &$array, int $flags = SORT_REGULAR): bool", + "desc": "Array nach Schlüsseln absteigend sortieren" + }, + { + "name": "ksort", + "signature": "ksort(array &$array, int $flags = SORT_REGULAR): bool", + "desc": "Array nach Schlüsseln sortieren" + }, + { + "name": "lcfirst", + "signature": "lcfirst(string $string): string", + "desc": "Ersten Buchstaben klein" + }, + { + "name": "list", + "signature": "list(mixed ...$vars): array", + "desc": "Variablen wie ein Array zuweisen" + }, + { + "name": "log", + "signature": "log(float $num, float $base = M_E): float", + "desc": "Logarithmus" + }, + { + "name": "ltrim", + "signature": "ltrim(string $string, string $characters = \" \\n\\r\\t\\v\\0\"): string", + "desc": "Leerzeichen links entfernen" + }, + { + "name": "max", + "signature": "max(mixed $value, mixed ...$values): mixed", + "desc": "Größten Wert ermitteln" + }, + { + "name": "md5", + "signature": "md5(string $string, bool $binary = false): string", + "desc": "MD5-Hash berechnen" + }, + { + "name": "method_exists", + "signature": "method_exists(object|string $object_or_class, string $method): bool", + "desc": "Prüft ob Methode existiert" + }, + { + "name": "microtime", + "signature": "microtime(bool $as_float = false): string|float", + "desc": "Aktuellen Timestamp mit Mikrosekunden" + }, + { + "name": "min", + "signature": "min(mixed $value, mixed ...$values): mixed", + "desc": "Kleinsten Wert ermitteln" + }, + { + "name": "mkdir", + "signature": "mkdir(string $directory, int $permissions = 0777, bool $recursive = false, resource $context = null): bool", + "desc": "Verzeichnis erstellen" + }, + { + "name": "mktime", + "signature": "mktime(int $hour, int $minute = null, int $second = null, int $month = null, int $day = null, int $year = null): int|false", + "desc": "Unix-Timestamp erstellen" + }, + { + "name": "mt_rand", + "signature": "mt_rand(int $min = 0, int $max = MT_RAND_MAX): int", + "desc": "Bessere Zufallszahl" + }, + { + "name": "nl2br", + "signature": "nl2br(string $string, bool $use_xhtml = true): string", + "desc": "Zeilenumbrüche in
umwandeln" + }, + { + "name": "number_format", + "signature": "number_format(float $num, int $decimals = 0, string $decimal_separator = '.', string $thousands_separator = ','): string", + "desc": "Zahl formatieren" + }, + { + "name": "ob_end_clean", + "signature": "ob_end_clean(): bool", + "desc": "Buffer leeren und beenden" + }, + { + "name": "ob_get_clean", + "signature": "ob_get_clean(): string|false", + "desc": "Buffer-Inhalt holen und beenden" + }, + { + "name": "ob_get_contents", + "signature": "ob_get_contents(): string|false", + "desc": "Buffer-Inhalt holen" + }, + { + "name": "ob_start", + "signature": "ob_start(callable $callback = null, int $chunk_size = 0, int $flags = PHP_OUTPUT_HANDLER_STDFLAGS): bool", + "desc": "Output-Buffering starten" + }, + { + "name": "parse_str", + "signature": "parse_str(string $string, array &$result): void", + "desc": "Query-String parsen" + }, + { + "name": "pathinfo", + "signature": "pathinfo(string $path, int $options = PATHINFO_ALL): array|string", + "desc": "Informationen über einen Pfad" + }, + { + "name": "PDO::__construct", + "signature": "PDO::__construct(string $dsn, string $username = null, string $password = null, array $options = null)", + "desc": "PDO-Verbindung herstellen" + }, + { + "name": "PDO::beginTransaction", + "signature": "PDO::beginTransaction(): bool", + "desc": "Transaktion starten" + }, + { + "name": "PDO::commit", + "signature": "PDO::commit(): bool", + "desc": "Transaktion bestätigen" + }, + { + "name": "PDO::exec", + "signature": "PDO::exec(string $statement): int|false", + "desc": "SQL ausführen, Anzahl betroffener Zeilen" + }, + { + "name": "PDO::lastInsertId", + "signature": "PDO::lastInsertId(string $name = null): string|false", + "desc": "Letzte eingefügte ID" + }, + { + "name": "PDO::prepare", + "signature": "PDO::prepare(string $query, array $options = []): PDOStatement|false", + "desc": "SQL-Statement vorbereiten" + }, + { + "name": "PDO::query", + "signature": "PDO::query(string $query, int $fetchMode = null, mixed ...$fetchModeArgs): PDOStatement|false", + "desc": "SQL direkt ausführen" + }, + { + "name": "PDO::rollBack", + "signature": "PDO::rollBack(): bool", + "desc": "Transaktion zurückrollen" + }, + { + "name": "PDOStatement::bindParam", + "signature": "PDOStatement::bindParam(string|int $param, mixed &$var, int $type = PDO::PARAM_STR, int $maxLength = 0, mixed $driverOptions = null): bool", + "desc": "Parameter binden" + }, + { + "name": "PDOStatement::bindValue", + "signature": "PDOStatement::bindValue(string|int $param, mixed $value, int $type = PDO::PARAM_STR): bool", + "desc": "Wert binden" + }, + { + "name": "PDOStatement::execute", + "signature": "PDOStatement::execute(array $params = null): bool", + "desc": "Vorbereitetes Statement ausführen" + }, + { + "name": "PDOStatement::fetch", + "signature": "PDOStatement::fetch(int $mode = PDO::FETCH_DEFAULT, int $cursorOrientation = PDO::FETCH_ORI_NEXT, int $cursorOffset = 0): mixed", + "desc": "Nächste Zeile holen" + }, + { + "name": "PDOStatement::fetchAll", + "signature": "PDOStatement::fetchAll(int $mode = PDO::FETCH_DEFAULT, mixed ...$args): array", + "desc": "Alle Zeilen holen" + }, + { + "name": "PDOStatement::fetchColumn", + "signature": "PDOStatement::fetchColumn(int $column = 0): mixed", + "desc": "Einzelne Spalte holen" + }, + { + "name": "PDOStatement::rowCount", + "signature": "PDOStatement::rowCount(): int", + "desc": "Anzahl betroffener Zeilen" + }, + { + "name": "php_uname", + "signature": "php_uname(string $mode = 'a'): string", + "desc": "Systeminformationen" + }, + { + "name": "phpinfo", + "signature": "phpinfo(int $flags = INFO_ALL): bool", + "desc": "PHP-Konfiguration ausgeben" + }, + { + "name": "phpversion", + "signature": "phpversion(string $extension = null): string|false", + "desc": "PHP-Version" + }, + { + "name": "pi", + "signature": "pi(): float", + "desc": "Wert von Pi" + }, + { + "name": "pow", + "signature": "pow(mixed $base, mixed $exp): int|float", + "desc": "Potenz berechnen" + }, + { + "name": "preg_match", + "signature": "preg_match(string $pattern, string $subject, array &$matches = null, int $flags = 0, int $offset = 0): int|false", + "desc": "Regulären Ausdruck prüfen" + }, + { + "name": "preg_match_all", + "signature": "preg_match_all(string $pattern, string $subject, array &$matches = null, int $flags = PREG_PATTERN_ORDER, int $offset = 0): int|false", + "desc": "Alle Treffer eines Regex finden" + }, + { + "name": "preg_quote", + "signature": "preg_quote(string $string, string $delimiter = null): string", + "desc": "Regex-Sonderzeichen escapen" + }, + { + "name": "preg_replace", + "signature": "preg_replace(string|array $pattern, string|array $replacement, string|array $subject, int $limit = -1, int &$count = null): string|array|null", + "desc": "Regex-Suchen und -Ersetzen" + }, + { + "name": "preg_split", + "signature": "preg_split(string $pattern, string $subject, int $limit = -1, int $flags = 0): array|false", + "desc": "String per Regex aufteilen" + }, + { + "name": "print", + "signature": "print(string $expression): int", + "desc": "String ausgeben" + }, + { + "name": "print_r", + "signature": "print_r(mixed $value, bool $return = false): string|bool", + "desc": "Variable lesbar ausgeben" + }, + { + "name": "printf", + "signature": "printf(string $format, mixed ...$values): int", + "desc": "Formatierten String ausgeben" + }, + { + "name": "property_exists", + "signature": "property_exists(object|string $object_or_class, string $property): bool", + "desc": "Prüft ob Eigenschaft existiert" + }, + { + "name": "rand", + "signature": "rand(int $min = 0, int $max = getrandmax()): int", + "desc": "Zufallszahl" + }, + { + "name": "random_int", + "signature": "random_int(int $min, int $max): int", + "desc": "Kryptografisch sichere Zufallszahl" + }, + { + "name": "range", + "signature": "range(string|int|float $start, string|int|float $end, int|float $step = 1): array", + "desc": "Array mit Wertebereich erstellen" + }, + { + "name": "rawurldecode", + "signature": "rawurldecode(string $string): string", + "desc": "URL-dekodieren nach RFC 3986" + }, + { + "name": "rawurlencode", + "signature": "rawurlencode(string $string): string", + "desc": "URL-kodieren nach RFC 3986" + }, + { + "name": "realpath", + "signature": "realpath(string $path): string|false", + "desc": "Absoluten Pfad auflösen" + }, + { + "name": "rename", + "signature": "rename(string $from, string $to, resource $context = null): bool", + "desc": "Datei umbenennen oder verschieben" + }, + { + "name": "require", + "signature": "require(string $filename): mixed", + "desc": "Datei einbinden (Fehler bei Misserfolg)" + }, + { + "name": "require_once", + "signature": "require_once(string $filename): mixed", + "desc": "Datei einmalig einbinden (Fehler bei Misserfolg)" + }, + { + "name": "restore_error_handler", + "signature": "restore_error_handler(): bool", + "desc": "Fehler-Handler zurücksetzen" + }, + { + "name": "rewind", + "signature": "rewind(resource $handle): bool", + "desc": "Dateizeiger zurücksetzen" + }, + { + "name": "rmdir", + "signature": "rmdir(string $directory, resource $context = null): bool", + "desc": "Verzeichnis löschen" + }, + { + "name": "round", + "signature": "round(int|float $num, int $precision = 0, int $mode = PHP_ROUND_HALF_UP): float", + "desc": "Runden" + }, + { + "name": "rsort", + "signature": "rsort(array &$array, int $flags = SORT_REGULAR): bool", + "desc": "Array absteigend sortieren" + }, + { + "name": "rtrim", + "signature": "rtrim(string $string, string $characters = \" \\n\\r\\t\\v\\0\"): string", + "desc": "Leerzeichen rechts entfernen" + }, + { + "name": "scandir", + "signature": "scandir(string $directory, int $sorting_order = SCANDIR_SORT_ASCENDING, resource $context = null): array|false", + "desc": "Verzeichnisinhalt auflisten" + }, + { + "name": "session_destroy", + "signature": "session_destroy(): bool", + "desc": "Session beenden" + }, + { + "name": "session_id", + "signature": "session_id(string $id = null): string|false", + "desc": "Session-ID holen oder setzen" + }, + { + "name": "session_regenerate_id", + "signature": "session_regenerate_id(bool $delete_old_session = false): bool", + "desc": "Session-ID erneuern" + }, + { + "name": "session_start", + "signature": "session_start(array $options = []): bool", + "desc": "Session starten" + }, + { + "name": "set_error_handler", + "signature": "set_error_handler(callable|null $callback, int $error_levels = E_ALL): callable|null", + "desc": "Eigenen Fehler-Handler setzen" + }, + { + "name": "set_exception_handler", + "signature": "set_exception_handler(callable|null $callback): callable|null", + "desc": "Eigenen Exception-Handler setzen" + }, + { + "name": "setcookie", + "signature": "setcookie(string $name, string $value = '', int $expires_or_options = 0, string $path = '', string $domain = '', bool $secure = false, bool $httponly = false): bool", + "desc": "Cookie setzen" + }, + { + "name": "settype", + "signature": "settype(mixed &$var, string $type): bool", + "desc": "Typ einer Variable setzen" + }, + { + "name": "sha1", + "signature": "sha1(string $string, bool $binary = false): string", + "desc": "SHA1-Hash berechnen" + }, + { + "name": "shuffle", + "signature": "shuffle(array &$array): bool", + "desc": "Array zufällig mischen" + }, + { + "name": "sleep", + "signature": "sleep(int $seconds): int|false", + "desc": "Ausführung anhalten" + }, + { + "name": "sort", + "signature": "sort(array &$array, int $flags = SORT_REGULAR): bool", + "desc": "Array aufsteigend sortieren" + }, + { + "name": "sprintf", + "signature": "sprintf(string $format, mixed ...$values): string", + "desc": "Formatierten String zurückgeben" + }, + { + "name": "sqrt", + "signature": "sqrt(float $num): float", + "desc": "Quadratwurzel" + }, + { + "name": "str_contains", + "signature": "str_contains(string $haystack, string $needle): bool", + "desc": "Prüft ob String enthalten ist" + }, + { + "name": "str_ends_with", + "signature": "str_ends_with(string $haystack, string $needle): bool", + "desc": "Prüft ob String mit needle endet" + }, + { + "name": "str_pad", + "signature": "str_pad(string $input, int $length, string $pad_string = ' ', int $pad_type = STR_PAD_RIGHT): string", + "desc": "String auf Länge auffüllen" + }, + { + "name": "str_repeat", + "signature": "str_repeat(string $string, int $times): string", + "desc": "String wiederholen" + }, + { + "name": "str_replace", + "signature": "str_replace(array|string $search, array|string $replace, string|array $subject, int &$count = null): string|array", + "desc": "Suchen und Ersetzen in einem String" + }, + { + "name": "str_split", + "signature": "str_split(string $string, int $length = 1): array", + "desc": "String in Array aufteilen" + }, + { + "name": "str_starts_with", + "signature": "str_starts_with(string $haystack, string $needle): bool", + "desc": "Prüft ob String mit needle beginnt" + }, + { + "name": "str_word_count", + "signature": "str_word_count(string $string, int $format = 0, string $characters = null): array|int", + "desc": "Wörter zählen" + }, + { + "name": "strcasecmp", + "signature": "strcasecmp(string $string1, string $string2): int", + "desc": "Strings ohne Groß-/Kleinschreibung vergleichen" + }, + { + "name": "strcmp", + "signature": "strcmp(string $string1, string $string2): int", + "desc": "Strings vergleichen" + }, + { + "name": "strip_tags", + "signature": "strip_tags(string $string, array|string $allowed_tags = null): string", + "desc": "HTML-Tags entfernen" + }, + { + "name": "stripslashes", + "signature": "stripslashes(string $string): string", + "desc": "Backslashes entfernen" + }, + { + "name": "strlen", + "signature": "strlen(string $string): int", + "desc": "Länge eines Strings" + }, + { + "name": "strpos", + "signature": "strpos(string $haystack, string $needle, int $offset = 0): int|false", + "desc": "Position des ersten Vorkommens" + }, + { + "name": "strrpos", + "signature": "strrpos(string $haystack, string $needle, int $offset = 0): int|false", + "desc": "Position des letzten Vorkommens" + }, + { + "name": "strtolower", + "signature": "strtolower(string $string): string", + "desc": "In Kleinbuchstaben umwandeln" + }, + { + "name": "strtotime", + "signature": "strtotime(string $datetime, int $baseTimestamp = time()): int|false", + "desc": "Datum-String in Timestamp umwandeln" + }, + { + "name": "strtoupper", + "signature": "strtoupper(string $string): string", + "desc": "In Großbuchstaben umwandeln" + }, + { + "name": "strval", + "signature": "strval(mixed $value): string", + "desc": "In String umwandeln" + }, + { + "name": "substr", + "signature": "substr(string $string, int $offset, int $length = null): string", + "desc": "Teilstring zurückgeben" + }, + { + "name": "sys_get_temp_dir", + "signature": "sys_get_temp_dir(): string", + "desc": "Temp-Verzeichnis des Systems" + }, + { + "name": "tempnam", + "signature": "tempnam(string $directory, string $prefix): string|false", + "desc": "Temporäre Datei erstellen" + }, + { + "name": "time", + "signature": "time(): int", + "desc": "Aktuellen Unix-Timestamp" + }, + { + "name": "trigger_error", + "signature": "trigger_error(string $message, int $error_level = E_USER_NOTICE): bool", + "desc": "Fehler auslösen" + }, + { + "name": "trim", + "signature": "trim(string $string, string $characters = \" \\n\\r\\t\\v\\0\"): string", + "desc": "Leerzeichen am Rand entfernen" + }, + { + "name": "uasort", + "signature": "uasort(array &$array, callable $callback): bool", + "desc": "Array mit eigener Funktion sortieren, Schlüssel beibehalten" + }, + { + "name": "ucfirst", + "signature": "ucfirst(string $string): string", + "desc": "Ersten Buchstaben groß" + }, + { + "name": "ucwords", + "signature": "ucwords(string $string, string $separators = \" \\t\\r\\n\\f\\v\"): string", + "desc": "Jeden Wortanfang groß" + }, + { + "name": "uksort", + "signature": "uksort(array &$array, callable $callback): bool", + "desc": "Array nach Schlüsseln mit eigener Funktion sortieren" + }, + { + "name": "unlink", + "signature": "unlink(string $filename, resource $context = null): bool", + "desc": "Datei löschen" + }, + { + "name": "urldecode", + "signature": "urldecode(string $string): string", + "desc": "URL-dekodieren" + }, + { + "name": "urlencode", + "signature": "urlencode(string $string): string", + "desc": "URL-kodieren" + }, + { + "name": "usleep", + "signature": "usleep(int $microseconds): void", + "desc": "Ausführung in Mikrosekunden anhalten" + }, + { + "name": "usort", + "signature": "usort(array &$array, callable $callback): bool", + "desc": "Array mit eigener Funktion sortieren" + }, + { + "name": "var_dump", + "signature": "var_dump(mixed $value, mixed ...$values): void", + "desc": "Variable ausgeben mit Typ-Info" + }, + { + "name": "var_export", + "signature": "var_export(mixed $value, bool $return = false): string|null", + "desc": "Variable als PHP-Code ausgeben" + }, + { + "name": "wordwrap", + "signature": "wordwrap(string $string, int $width = 75, string $break = \"\\n\", bool $cut_long_words = false): string", + "desc": "String umbrechen" + } +] \ No newline at end of file diff --git a/resources/resources.qrc b/resources/resources.qrc index 38da93d..f3b588a 100644 --- a/resources/resources.qrc +++ b/resources/resources.qrc @@ -7,5 +7,6 @@ icon_48.png icon_32.png icon_16.png + php_functions.json diff --git a/src/core/AboutDialog.cpp b/src/core/AboutDialog.cpp index bc0ebd9..9feeca1 100644 --- a/src/core/AboutDialog.cpp +++ b/src/core/AboutDialog.cpp @@ -74,7 +74,7 @@ AboutDialog::AboutDialog(QWidget *parent) info->addLayout(row); }; - makeRow(tr("Version"), "1.0.0"); + makeRow(tr("Version"), "1.1.0"); makeRow(tr("Entwickler"), "Dany Thinnes"); makeRow(tr("Projekt"), "Projekt Hirnfrei"); makeRow(tr("Framework"), QString("Qt %1").arg(qVersion())); diff --git a/src/editor/CMakeLists.txt b/src/editor/CMakeLists.txt index 63e8322..fe64f27 100644 --- a/src/editor/CMakeLists.txt +++ b/src/editor/CMakeLists.txt @@ -13,6 +13,10 @@ set(EDITOR_SOURCES FileSearchPanel.h ColorIndicator.cpp ColorIndicator.h + SignatureHelper.cpp + SignatureHelper.h + SignatureTooltip.cpp + SignatureTooltip.h ) add_library(BareCode_Editor STATIC ${EDITOR_SOURCES}) diff --git a/src/editor/CodeEditor.cpp b/src/editor/CodeEditor.cpp index 0579409..f6aca9b 100644 --- a/src/editor/CodeEditor.cpp +++ b/src/editor/CodeEditor.cpp @@ -1,6 +1,7 @@ #include "CodeEditor.h" #include "LineNumberArea.h" #include "ColorIndicator.h" +#include "SignatureHelper.h" #include "core/Settings.h" #include "highlighter/HighlighterFactory.h" @@ -24,6 +25,7 @@ CodeEditor::CodeEditor(Settings *settings, QWidget *parent) { m_lineNumberArea = new LineNumberArea(this); m_colorIndicator = new ColorIndicator(this); + m_signatureHelper = new SignatureHelper(this); setupEditor(); connect(this, &CodeEditor::blockCountChanged, diff --git a/src/editor/CodeEditor.h b/src/editor/CodeEditor.h index 9ca7837..21581fe 100644 --- a/src/editor/CodeEditor.h +++ b/src/editor/CodeEditor.h @@ -9,6 +9,7 @@ class LineNumberArea; class Settings; class SyntaxHighlighter; class ColorIndicator; +class SignatureHelper; // --------------------------------------------------------------------------- // CodeEditor – Core editing widget. @@ -70,5 +71,6 @@ private: LineNumberArea *m_lineNumberArea = nullptr; SyntaxHighlighter *m_highlighter = nullptr; ColorIndicator *m_colorIndicator = nullptr; + SignatureHelper *m_signatureHelper = nullptr; QString m_filePath; }; diff --git a/src/editor/SignatureHelper.cpp b/src/editor/SignatureHelper.cpp new file mode 100644 index 0000000..c84f723 --- /dev/null +++ b/src/editor/SignatureHelper.cpp @@ -0,0 +1,222 @@ +#include "SignatureHelper.h" +#include "SignatureTooltip.h" +#include "CodeEditor.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +SignatureHelper::SignatureHelper(CodeEditor *editor) + : QObject(editor) + , m_editor(editor) +{ + // Tooltip als Kind des Viewports — bleibt im Fenster + m_tooltip = new SignatureTooltip(editor->window()); + + loadDatabase(); + + connect(m_editor, &CodeEditor::cursorPositionChanged, + this, &SignatureHelper::onCursorPositionChanged); +} + +// --------------------------------------------------------------------------- +// Datenbank laden +// --------------------------------------------------------------------------- +void SignatureHelper::loadDatabase() +{ + QFile f(":/php_functions.json"); + if (!f.open(QIODevice::ReadOnly)) + { + return; + } + + const QJsonDocument doc = QJsonDocument::fromJson(f.readAll()); + if (!doc.isArray()) + { + return; + } + + for (const QJsonValue &val : doc.array()) + { + const QJsonObject obj = val.toObject(); + const QString name = obj["name"].toString(); + if (name.isEmpty()) + { + continue; + } + + FunctionInfo info; + info.signature = obj["signature"].toString(); + info.description = obj["desc"].toString(); + m_functions.insert(name.toLower(), info); + } +} + +// --------------------------------------------------------------------------- +// Cursor-Bewegung auswerten +// --------------------------------------------------------------------------- +void SignatureHelper::onCursorPositionChanged() +{ + const QTextCursor cursor = m_editor->textCursor(); + const QString block = cursor.block().text(); + const int col = cursor.columnNumber(); + const QString leftText = block.left(col); + + const QString funcName = extractFunctionName(leftText); + + if (funcName.isEmpty()) + { + m_tooltip->hide(); + return; + } + + // Klammern zählen — wenn alle geschlossen, Tooltip ausblenden + if (countOpenParens(leftText) <= 0) + { + m_tooltip->hide(); + return; + } + + const QString key = funcName.toLower(); + if (!m_functions.contains(key)) + { + m_tooltip->hide(); + return; + } + + const FunctionInfo &info = m_functions[key]; + + // Position unter dem Cursor berechnen + const QRect cursorRect = m_editor->cursorRect(cursor); + const QPoint globalPos = m_editor->viewport()->mapToGlobal( + QPoint(cursorRect.left(), cursorRect.bottom() + 4) + ); + + m_tooltip->showSignature(info.signature, info.description, globalPos); +} + +// --------------------------------------------------------------------------- +// Funktionsnamen links vor der öffnenden Klammer extrahieren +// --------------------------------------------------------------------------- +QString SignatureHelper::extractFunctionName(const QString &text) const +{ + // Wir suchen das letzte '(' das zu einem Funktionsnamen gehört. + // Dabei müssen wir verschachtelte Klammern korrekt behandeln. + int depth = 0; + int openPos = -1; + + for (int i = text.length() - 1; i >= 0; --i) + { + const QChar ch = text[i]; + if (ch == ')') + { + ++depth; + } + else if (ch == '(') + { + if (depth == 0) + { + openPos = i; + break; + } + --depth; + } + } + + if (openPos <= 0) + { + return QString(); + } + + // Funktionsnamen direkt links von '(' lesen + int end = openPos - 1; + + // Leerzeichen überspringen + while (end >= 0 && text[end].isSpace()) + { + --end; + } + + if (end < 0) + { + return QString(); + } + + // Bezeichner-Zeichen sammeln (Buchstaben, Ziffern, _, :, \) + int start = end; + while (start > 0 && + (text[start - 1].isLetterOrNumber() || + text[start - 1] == '_' || + text[start - 1] == ':' || + text[start - 1] == '\\')) + { + --start; + } + + const QString name = text.mid(start, end - start + 1); + + // Schlüsselwörter und leere Namen ausschließen + static const QStringList keywords = { + "if", "else", "elseif", "while", "for", "foreach", + "switch", "match", "catch", "function", "fn" + }; + + if (name.isEmpty() || keywords.contains(name.toLower())) + { + return QString(); + } + + // Nur den letzten Teil nach :: oder -> nehmen + const int colonPos = name.lastIndexOf("::"); + const int arrowPos = name.lastIndexOf("->"); + const int backslashPos = name.lastIndexOf("\\"); + const int splitPos = qMax(backslashPos, qMax(colonPos, arrowPos)); + + if (splitPos >= 0) + { + return name.mid(splitPos + (name[splitPos] == ':' ? 2 : (name[splitPos] == '\\' ? 1 : 2))); + } + + return name; +} + +// --------------------------------------------------------------------------- +// Offene Klammern zählen +// --------------------------------------------------------------------------- +int SignatureHelper::countOpenParens(const QString &text) const +{ + int depth = 0; + bool inString = false; + QChar stringChar; + + for (int i = 0; i < text.length(); ++i) + { + const QChar ch = text[i]; + + // Einfache String-Erkennung (kein vollständiger PHP-Parser) + if (!inString && (ch == '\'' || ch == '"')) + { + inString = true; + stringChar = ch; + continue; + } + if (inString) + { + if (ch == stringChar && (i == 0 || text[i - 1] != '\\')) + { + inString = false; + } + continue; + } + + if (ch == '(') { ++depth; } + else if (ch == ')') { --depth; } + } + + return depth; +} diff --git a/src/editor/SignatureHelper.h b/src/editor/SignatureHelper.h new file mode 100644 index 0000000..9b1ec89 --- /dev/null +++ b/src/editor/SignatureHelper.h @@ -0,0 +1,51 @@ +#pragma once + +#include +#include +#include + +class CodeEditor; +class SignatureTooltip; + +// --------------------------------------------------------------------------- +// SignatureHelper – Lädt die PHP-Funktionsdatenbank und zeigt beim Tippen +// automatisch die passende Funktionssignatur als Tooltip. +// +// Logik: +// • Bei jedem Tastendruck: Text links vom Cursor analysieren +// • Wenn "funktionsname(" erkannt wird → Tooltip anzeigen +// • Wenn ")" die öffnende Klammer schließt → Tooltip verstecken +// • Wenn Cursor sich weg bewegt → Tooltip verstecken +// --------------------------------------------------------------------------- +class SignatureHelper : public QObject +{ + Q_OBJECT + +public: + explicit SignatureHelper(CodeEditor *editor); + +private slots: + void onCursorPositionChanged(); + +private: + struct FunctionInfo + { + QString signature; + QString description; + }; + + void loadDatabase(); + void loadProjectFunctions(); + + // Extrahiert den Funktionsnamen direkt links vor dem letzten '(' + // Gibt leeren String zurück wenn kein Kontext gefunden + QString extractFunctionName(const QString &textUpToCursor) const; + + // Zählt offene Klammern — bei 0 ist der Aufruf abgeschlossen + int countOpenParens(const QString &textUpToCursor) const; + + CodeEditor *m_editor = nullptr; + SignatureTooltip *m_tooltip = nullptr; + + QHash m_functions; // name → info +}; diff --git a/src/editor/SignatureTooltip.cpp b/src/editor/SignatureTooltip.cpp new file mode 100644 index 0000000..3ac4099 --- /dev/null +++ b/src/editor/SignatureTooltip.cpp @@ -0,0 +1,91 @@ +#include "SignatureTooltip.h" + +#include +#include + +SignatureTooltip::SignatureTooltip(QWidget *parent) + : QFrame(parent, Qt::ToolTip | Qt::FramelessWindowHint) +{ + setFrameShape(QFrame::StyledPanel); + setFrameShadow(QFrame::Raised); + setAttribute(Qt::WA_ShowWithoutActivating); + + // Dezentes Styling passend zu Hell- und Dunkeltheme + setStyleSheet( + "SignatureTooltip {" + " background: palette(toolTipBase);" + " border: 1px solid palette(mid);" + " border-radius: 4px;" + " padding: 4px;" + "}" + ); + + m_layout = new QVBoxLayout(this); + m_layout->setContentsMargins(8, 6, 8, 6); + m_layout->setSpacing(3); + + // Signatur — Monospace, deutlich hervorgehoben + m_sigLabel = new QLabel(this); + m_sigLabel->setTextFormat(Qt::PlainText); + m_sigLabel->setWordWrap(false); + QFont sigFont = m_sigLabel->font(); + sigFont.setFamily("Monospace"); + sigFont.setStyleHint(QFont::Monospace); + sigFont.setPointSize(sigFont.pointSize()); + m_sigLabel->setFont(sigFont); + m_sigLabel->setStyleSheet("color: palette(toolTipText); font-weight: bold;"); + m_layout->addWidget(m_sigLabel); + + // Beschreibung — kleiner, gedimmt + m_descLabel = new QLabel(this); + m_descLabel->setTextFormat(Qt::PlainText); + m_descLabel->setWordWrap(false); + m_descLabel->setStyleSheet("color: palette(mid);"); + QFont descFont = m_descLabel->font(); + descFont.setPointSize(qMax(descFont.pointSize() - 1, 8)); + m_descLabel->setFont(descFont); + m_layout->addWidget(m_descLabel); + + hide(); +} + +void SignatureTooltip::showSignature(const QString &signature, + const QString &description, + const QPoint &globalPos) +{ + m_sigLabel->setText(signature); + + if (description.isEmpty()) + { + m_descLabel->hide(); + } + else + { + m_descLabel->setText(description); + m_descLabel->show(); + } + + adjustSize(); + + // Position so wählen dass das Popup nicht aus dem Bildschirm ragt + QPoint pos = globalPos; + const QRect screen = QApplication::primaryScreen()->availableGeometry(); + + if (pos.x() + width() > screen.right()) + { + pos.setX(screen.right() - width() - 4); + } + if (pos.y() + height() > screen.bottom()) + { + pos.setY(globalPos.y() - height() - 24); + } + + move(pos); + show(); + raise(); +} + +void SignatureTooltip::hide() +{ + QFrame::hide(); +} diff --git a/src/editor/SignatureTooltip.h b/src/editor/SignatureTooltip.h new file mode 100644 index 0000000..110062f --- /dev/null +++ b/src/editor/SignatureTooltip.h @@ -0,0 +1,29 @@ +#pragma once + +#include +#include +#include +#include + +// --------------------------------------------------------------------------- +// SignatureTooltip – Schwebendes Popup das die Signatur einer Funktion zeigt. +// Erscheint unter dem Cursor, verschwindet automatisch wenn der Nutzer +// die Klammer schließt oder den Kontext verlässt. +// --------------------------------------------------------------------------- +class SignatureTooltip : public QFrame +{ + Q_OBJECT + +public: + explicit SignatureTooltip(QWidget *parent = nullptr); + + void showSignature(const QString &signature, + const QString &description, + const QPoint &globalPos); + void hide(); + +private: + QVBoxLayout *m_layout = nullptr; + QLabel *m_sigLabel = nullptr; + QLabel *m_descLabel = nullptr; +};