├── .clang-format ├── .gitignore ├── Dockerfile.el7 ├── Dockerfile.f40 ├── Dockerfile.qt5 ├── Dockerfile.qt6 ├── LICENSE ├── QSourceHighlite ├── QSourceHighlite.pri ├── languagedata.cpp ├── languagedata.h ├── qsourcehighliter.cpp ├── qsourcehighliter.h ├── qsourcehighliterthemes.cpp └── qsourcehighliterthemes.h ├── QVNCClient ├── QVNCClient.pri ├── qvncclientwidget.cpp └── qvncclientwidget.h ├── QrwEmoticons ├── LICENSE.txt ├── QrwEmoticons.pri ├── README.md ├── include │ └── QrwEmoticons │ │ ├── Global.h │ │ ├── QrwEmoticons │ │ ├── QrwEmoticons.h │ │ ├── QrwEmoticonsPlugin.h │ │ └── TextEdit.h ├── lib │ ├── lib.pro │ └── src │ │ ├── QrwEmoticons.cpp │ │ ├── QrwEmoticonsTextObjectInterface.cpp │ │ ├── QrwEmoticonsTextObjectInterface_p.h │ │ ├── QrwEmoticons_data.cpp │ │ ├── QrwEmoticons_p.cpp │ │ ├── QrwEmoticons_p.h │ │ └── TextEdit.cpp ├── plugin-openmoji │ ├── emoticons_openmoji.qrc │ ├── openmoji │ │ ├── LICENSE.txt │ │ ├── README.md │ │ ├── color │ │ │ ├── 72x72 │ │ │ │ ├── 1F535.png │ │ │ │ ├── 1F7E2.png │ │ │ │ ├── 26A0.png │ │ │ │ └── 2B50.png │ │ │ └── svg │ │ │ │ ├── 1F535.svg │ │ │ │ ├── 1F7E2.svg │ │ │ │ ├── 26A0.svg │ │ │ │ └── 2B50.svg │ │ └── src │ │ │ ├── symbols │ │ │ ├── geometric │ │ │ │ ├── 1F535.svg │ │ │ │ └── 1F7E2.svg │ │ │ └── warning │ │ │ │ └── 26A0.svg │ │ │ └── travel-places │ │ │ └── sky-weather │ │ │ └── 2B50.svg │ ├── plugin-openmoji.pro │ ├── plugin.json │ └── src │ │ ├── plugin.cpp │ │ └── plugin.h └── shared │ └── src │ ├── QrwEmoticonsHelper.cpp │ └── QrwEmoticonsHelper.h ├── README.md ├── assets ├── lima-gui-quick-start.dark.png ├── lima-gui-quick-start.light.png ├── screenshot1.png ├── screenshot2.png └── screenshot3.png ├── contrib ├── README.md ├── cool-retro-term-lima.jpg └── cool-retro-term-lima.json ├── icons ├── 16x16 │ └── tux.png ├── 256x256 │ └── tux.png ├── 32x32 │ └── tux.png ├── 48x48 │ └── tux.png └── tux.icns ├── images ├── add.png ├── advanced.png ├── desktopshare.png ├── help.png ├── info.png ├── player_start.png ├── player_stop.png ├── quick.png ├── reload.png ├── remove.png ├── search.png ├── terminal.png └── tux.png ├── instance.cpp ├── instance.h ├── lima-gui.desktop ├── lima.cpp ├── lima.h ├── logos ├── README ├── almalinux.png ├── alpine.png ├── apptainer.png ├── archlinux.png ├── buildroot.png ├── centos.png ├── coreos.png ├── debian.png ├── fedora.png ├── flatcar.png ├── k3s.png ├── k8s.png ├── leap.png ├── nerd-face.png ├── nomad.png ├── openfaas.png ├── opensuse.png ├── podman.png ├── rocky.png ├── singularity.png ├── stream.png ├── tinycore.png ├── tumbleweed.png ├── ubuntu.png └── whale.png ├── main.cpp ├── systray.pro ├── systray.qrc ├── templates.cpp ├── templates.h ├── window.cpp └── window.h /.clang-format: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2016 Olivier Goffart 2 | # 3 | # You may use this file under the terms of the 3-clause BSD license. 4 | # See the file LICENSE from this package for details. 5 | 6 | # This is the clang-format configuration style to be used by Qt, 7 | # based on the rules from https://wiki.qt.io/Qt_Coding_Style and 8 | # https://wiki.qt.io/Coding_Conventions 9 | 10 | --- 11 | # Webkit style was loosely based on the Qt style 12 | BasedOnStyle: WebKit 13 | 14 | Standard: Cpp11 15 | 16 | # Column width is limited to 100 in accordance with Qt Coding Style. 17 | # https://wiki.qt.io/Qt_Coding_Style 18 | # Note that this may be changed at some point in the future. 19 | ColumnLimit: 100 20 | # How much weight do extra characters after the line length limit have. 21 | # PenaltyExcessCharacter: 4 22 | 23 | # Disable reflow of qdoc comments: indentation rules are different. 24 | # Translation comments are also excluded. 25 | CommentPragmas: "^!|^:" 26 | 27 | # We want a space between the type and the star for pointer types. 28 | PointerBindsToType: false 29 | 30 | # We use template< without space. 31 | SpaceAfterTemplateKeyword: false 32 | 33 | # We want to break before the operators, but not before a '='. 34 | BreakBeforeBinaryOperators: NonAssignment 35 | 36 | # Braces are usually attached, but not after functions or class declarations. 37 | BreakBeforeBraces: Custom 38 | BraceWrapping: 39 | AfterClass: true 40 | AfterControlStatement: false 41 | AfterEnum: false 42 | AfterFunction: true 43 | AfterNamespace: false 44 | AfterObjCDeclaration: false 45 | AfterStruct: true 46 | AfterUnion: false 47 | BeforeCatch: false 48 | BeforeElse: false 49 | IndentBraces: false 50 | 51 | # When constructor initializers do not fit on one line, put them each on a new line. 52 | ConstructorInitializerAllOnOneLineOrOnePerLine: true 53 | # Indent initializers by 4 spaces 54 | ConstructorInitializerIndentWidth: 4 55 | 56 | # Indent width for line continuations. 57 | ContinuationIndentWidth: 8 58 | 59 | # No indentation for namespaces. 60 | NamespaceIndentation: None 61 | 62 | # Allow indentation for preprocessing directives (if/ifdef/endif). https://reviews.llvm.org/rL312125 63 | #IndentPPDirectives: AfterHash 64 | # AfterHash is broken, since it indents every single include statement not following after an ifdef 65 | IndentPPDirectives: None 66 | 67 | # Horizontally align arguments after an open bracket. 68 | # The coding style does not specify the following, but this is what gives 69 | # results closest to the existing code. 70 | AlignAfterOpenBracket: true 71 | AlwaysBreakTemplateDeclarations: true 72 | 73 | # Ideally we should also allow less short function in a single line, but 74 | # clang-format does not handle that. 75 | AllowShortFunctionsOnASingleLine: Inline 76 | 77 | # The coding style specifies some include order categories, but also tells to 78 | # separate categories with an empty line. It does not specify the order within 79 | # the categories. Since the SortInclude feature of clang-format does not 80 | # re-order includes separated by empty lines, the feature is not used. 81 | SortIncludes: false 82 | 83 | # macros for which the opening brace stays attached. 84 | ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH, forever, Q_FOREVER, QBENCHMARK, QBENCHMARK_ONCE ] 85 | 86 | # Break constructor initializers before the colon and after the commas. 87 | BreakConstructorInitializers: BeforeColon 88 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | build-*-Desktop-Debug/ 2 | build-*-Desktop-Release/ 3 | build-*-Desktop-Profile/ 4 | systray 5 | lima-gui 6 | systray.pro.user 7 | # qmake 8 | .qmake.stash 9 | Makefile 10 | moc_predefs.h 11 | moc_*.cpp 12 | qrc_*.cpp 13 | *_plugin_resources.cpp 14 | *.o 15 | lib*.so 16 | lib*.a 17 | lima-gui.app 18 | -------------------------------------------------------------------------------- /Dockerfile.el7: -------------------------------------------------------------------------------- 1 | # docker build -f Dockerfile.el7 -t el7-build . 2 | 3 | FROM docker.io/centos:7 4 | #RUN yum install -y epel-release && && yum clean all && yum-config-manager --disable epel 5 | 6 | RUN yum install -y qt5-qtbase-devel gcc-c++ make && yum clean all 7 | 8 | RUN yum install -y pkgconfig qt5-qtsvg-devel && yum clean all 9 | #RUN yum install --enablerepo=epel -y pkgconfig qtermwidget-devel qt5-qtsvg-devel && yum clean all 10 | 11 | # docker run --rm -v $PWD:/build el7-build 12 | 13 | VOLUME /build 14 | 15 | WORKDIR /build 16 | 17 | CMD qmake-qt5 && make CXX="g++ -std=c++11" 18 | -------------------------------------------------------------------------------- /Dockerfile.f40: -------------------------------------------------------------------------------- 1 | # docker build -f Dockerfile.f40 -t f40-build . 2 | 3 | FROM docker.io/fedora:40 4 | 5 | RUN yum install -y qt6-qtbase-devel gcc-c++ make && yum clean all 6 | 7 | RUN yum install -y pkgconfig qt6-qtsvg-devel && yum clean all 8 | #RUN yum install -y pkgconfig qtermwidget-devel qt6-qtsvg-devel && yum clean all 9 | 10 | # docker run --rm -v $PWD:/build f40-build 11 | 12 | VOLUME /build 13 | 14 | WORKDIR /build 15 | 16 | CMD qmake && make CXX="g++ -std=c++17" 17 | -------------------------------------------------------------------------------- /Dockerfile.qt5: -------------------------------------------------------------------------------- 1 | # docker build -f Dockerfile.qt5 -t qt5-build . 2 | 3 | FROM docker.io/ubuntu:20.04 4 | 5 | RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y qtbase5-dev qtchooser qt5-qmake qtbase5-dev-tools g++ make && rm -rf /var/lib/apt/lists/* 6 | 7 | RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y pkg-config libqtermwidget5-0-dev libutf8proc-dev libqt5svg5-dev && rm -rf /var/lib/apt/lists/* 8 | 9 | RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y qt5-default && rm -rf /var/lib/apt/lists/* && qtchooser -l 10 | 11 | # docker run --rm -v $PWD:/build qt5-build 12 | 13 | VOLUME /build 14 | 15 | WORKDIR /build 16 | 17 | CMD qmake && make 18 | -------------------------------------------------------------------------------- /Dockerfile.qt6: -------------------------------------------------------------------------------- 1 | # docker build -f Dockerfile.qt6 -t qt6-build . 2 | 3 | FROM docker.io/ubuntu:22.04 4 | 5 | RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y qt6-base-dev qtchooser qmake6 qt6-base-dev-tools g++ make && rm -rf /var/lib/apt/lists/* 6 | 7 | RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y pkg-config libgl-dev libqt6svg6-dev && rm -rf /var/lib/apt/lists/* 8 | 9 | RUN ARCH=$(uname -m); printf "/usr/lib/qt6/bin\n/usr/lib/${ARCH}-linux-gnu\n" | tee /usr/lib/${ARCH}-linux-gnu/qtchooser/qt6-${ARCH}-linux-gnu.conf && for alias in 6 default qt6; do ln -s qt6-${ARCH}-linux-gnu.conf /usr/lib/${ARCH}-linux-gnu/qtchooser/$alias.conf; done && qtchooser -l # 10 | 11 | # docker run --rm -v $PWD:/build qt6-build 12 | 13 | VOLUME /build 14 | 15 | WORKDIR /build 16 | 17 | CMD qmake && make 18 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (C) 2021 Anders F Björklund 2 | Copyright (C) 2016 The Qt Company Ltd. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are 6 | met: 7 | * Redistributions of source code must retain the above copyright 8 | notice, this list of conditions and the following disclaimer. 9 | * Redistributions in binary form must reproduce the above copyright 10 | notice, this list of conditions and the following disclaimer in 11 | the documentation and/or other materials provided with the 12 | distribution. 13 | * Neither the name of the copyright holder nor the names of its 14 | contributors may be used to endorse or promote products derived 15 | from this software without specific prior written permission. 16 | 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | -------------------------------------------------------------------------------- /QSourceHighlite/QSourceHighlite.pri: -------------------------------------------------------------------------------- 1 | QT += gui 2 | 3 | INCLUDEPATH += $$PWD 4 | 5 | # Removed all languages but bash and yaml 6 | 7 | HEADERS += $$PWD/qsourcehighliter.h \ 8 | $$PWD/qsourcehighliterthemes.h \ 9 | $$PWD/languagedata.h 10 | 11 | SOURCES += $$PWD/qsourcehighliter.cpp \ 12 | $$PWD/languagedata.cpp \ 13 | $$PWD/qsourcehighliterthemes.cpp 14 | -------------------------------------------------------------------------------- /QSourceHighlite/languagedata.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019-2020 Waqar Ahmed -- 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included in all 12 | * copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | * SOFTWARE. 21 | * 22 | */ 23 | 24 | #include 25 | #include 26 | #include "languagedata.h" 27 | /* ------------------------ 28 | * TEMPLATE FOR LANG DATA 29 | * ------------------------- 30 | * 31 | * loadXXXData, where XXX is the language 32 | * keywords are the language keywords e.g, const 33 | * types are built-in types i.e, int, char, var 34 | * literals are words like, true false 35 | * builtin are the library functions 36 | * other can contain any other thing, for e.g, in cpp it contains the preprocessor 37 | 38 | xxx_keywords = { 39 | }; 40 | 41 | xxx_types = { 42 | }; 43 | 44 | xxx_literals = { 45 | }; 46 | 47 | xxx_builtin = { 48 | }; 49 | 50 | xxx_other = { 51 | }; 52 | 53 | */ 54 | 55 | namespace QSourceHighlite { 56 | 57 | /**********************************************************/ 58 | /* Shell Data *********************************************/ 59 | /**********************************************************/ 60 | 61 | static bool shellDataInitialized = false; 62 | static LanguageData shell_keywords; 63 | static LanguageData shell_types; 64 | static LanguageData shell_literals; 65 | static LanguageData shell_builtin; 66 | static LanguageData shell_other; 67 | void initShellData() { 68 | shell_keywords = { 69 | {('i'), QLatin1String("if")}, 70 | {('t'), QLatin1String("then")}, 71 | {('e'), QLatin1String("else")}, 72 | {('e'), QLatin1String("elif")}, 73 | {('f'), QLatin1String("fi")}, 74 | {('f'), QLatin1String("for")}, 75 | {('w'), QLatin1String("while")}, 76 | {('i'), QLatin1String("in")}, 77 | {('d'), QLatin1String("do")}, 78 | {('d'), QLatin1String("done")}, 79 | {('c'), QLatin1String("case")}, 80 | {('e'), QLatin1String("esac")}, 81 | {('f'), QLatin1String("function")} 82 | }; 83 | 84 | shell_types = {}; 85 | 86 | shell_literals = { 87 | {('f'), QLatin1String("false")}, 88 | {('t'), QLatin1String("true")} 89 | }; 90 | 91 | shell_builtin = { 92 | {('b'), QLatin1String("break")}, 93 | {('c'), QLatin1String("cd")}, 94 | {('c'), QLatin1String("continue")}, 95 | {('e'), QLatin1String("eval")}, 96 | {('e'), QLatin1String("exec")}, 97 | {('e'), QLatin1String("exit")}, 98 | {('e'), QLatin1String("export")}, 99 | {('g'), QLatin1String("getopts")}, 100 | {('h'), QLatin1String("hash")}, 101 | {('p'), QLatin1String("pwd")}, 102 | {('r'), QLatin1String("readonly")}, 103 | {('r'), QLatin1String("return")}, 104 | {('s'), QLatin1String("shift")}, 105 | {('t'), QLatin1String("test")}, 106 | {('t'), QLatin1String("timestrap")}, 107 | {('u'), QLatin1String("umask")}, 108 | {('u'), QLatin1String("unset")}, 109 | {('B'), QLatin1String("Bash")}, 110 | {('a'), QLatin1String("alias")}, 111 | {('b'), QLatin1String("bind")}, 112 | {('b'), QLatin1String("builtin")}, 113 | {('c'), QLatin1String("caller")}, 114 | {('c'), QLatin1String("command")}, 115 | {('d'), QLatin1String("declare")}, 116 | {('e'), QLatin1String("echo")}, 117 | {('e'), QLatin1String("enable")}, 118 | {('h'), QLatin1String("help")}, 119 | {('l'), QLatin1String("let")}, 120 | {('l'), QLatin1String("local")}, 121 | {('l'), QLatin1String("logout")}, 122 | {('m'), QLatin1String("mapfile")}, 123 | {('p'), QLatin1String("printfread")}, 124 | {('r'), QLatin1String("readarray")}, 125 | {('s'), QLatin1String("source")}, 126 | {('t'), QLatin1String("type")}, 127 | {('t'), QLatin1String("typeset")}, 128 | {('u'), QLatin1String("ulimit")}, 129 | {('u'), QLatin1String("unalias")}, 130 | {('m'), QLatin1String("modifiers")}, 131 | {('s'), QLatin1String("set")}, 132 | {('s'), QLatin1String("shopt")}, 133 | {('a'), QLatin1String("autoload")}, 134 | {('b'), QLatin1String("bg")}, 135 | {('b'), QLatin1String("bindkey")}, 136 | {('b'), QLatin1String("bye")}, 137 | {('c'), QLatin1String("cap")}, 138 | {('c'), QLatin1String("chdir")}, 139 | {('c'), QLatin1String("clone")}, 140 | {('c'), QLatin1String("comparguments")}, 141 | {('c'), QLatin1String("compcall")}, 142 | {('c'), QLatin1String("compctl")}, 143 | {('c'), QLatin1String("compdescribe")}, 144 | {('c'), QLatin1String("compfilescompgroups")}, 145 | {('c'), QLatin1String("compquote")}, 146 | {('c'), QLatin1String("comptags")}, 147 | {('c'), QLatin1String("comptry")}, 148 | {('c'), QLatin1String("compvalues")}, 149 | {('d'), QLatin1String("dirs")}, 150 | {('d'), QLatin1String("disable")}, 151 | {('d'), QLatin1String("disown")}, 152 | {('e'), QLatin1String("echotc")}, 153 | {('e'), QLatin1String("echoti")}, 154 | {('e'), QLatin1String("emulatefc")}, 155 | {('f'), QLatin1String("fg")}, 156 | {('f'), QLatin1String("float")}, 157 | {('f'), QLatin1String("functions")}, 158 | {('g'), QLatin1String("getcap")}, 159 | {('g'), QLatin1String("getln")}, 160 | {('h'), QLatin1String("history")}, 161 | {('i'), QLatin1String("integer")}, 162 | {('j'), QLatin1String("jobs")}, 163 | {('k'), QLatin1String("kill")}, 164 | {('l'), QLatin1String("limit")}, 165 | {('l'), QLatin1String("log")}, 166 | {('n'), QLatin1String("noglob")}, 167 | {('p'), QLatin1String("popd")}, 168 | {('p'), QLatin1String("printpushd")}, 169 | {('p'), QLatin1String("pushln")}, 170 | {('r'), QLatin1String("rehash")}, 171 | {('s'), QLatin1String("sched")}, 172 | {('s'), QLatin1String("setcap")}, 173 | {('s'), QLatin1String("setopt")}, 174 | {('s'), QLatin1String("stat")}, 175 | {('s'), QLatin1String("suspend")}, 176 | {('t'), QLatin1String("ttyctl")}, 177 | {('u'), QLatin1String("unfunction")}, 178 | {('u'), QLatin1String("unhash")}, 179 | {('u'), QLatin1String("unlimitunsetopt")}, 180 | {('v'), QLatin1String("vared")}, 181 | {('w'), QLatin1String("wait")}, 182 | {('w'), QLatin1String("whence")}, 183 | {('w'), QLatin1String("where")}, 184 | {('w'), QLatin1String("which")}, 185 | {('z'), QLatin1String("zcompile")}, 186 | {('z'), QLatin1String("zformat")}, 187 | {('z'), QLatin1String("zftp")}, 188 | {('z'), QLatin1String("zle")}, 189 | {('z'), QLatin1String("zmodload")}, 190 | {('z'), QLatin1String("zparseopts")}, 191 | {('z'), QLatin1String("zprof")}, 192 | {('z'), QLatin1String("zpty")}, 193 | {('z'), QLatin1String("zregexparse")}, 194 | {('z'), QLatin1String("zsocket")}, 195 | {('z'), QLatin1String("zstyle")}, 196 | {('z'), QLatin1String("ztcp")}, 197 | {('g'), QLatin1String("git")}, 198 | {('r'), QLatin1String("rm")}, 199 | {('s'), QLatin1String("sudo")}, 200 | {('f'), QLatin1String("fdisk")}, 201 | {('a'), QLatin1String("apt")}, 202 | {('s'), QLatin1String("snap")}, 203 | {('f'), QLatin1String("flatpak")}, 204 | {('s'), QLatin1String("snapcraft")}, 205 | {('y'), QLatin1String("yaourt")}, 206 | {('n'), QLatin1String("nmcli")}, 207 | {('p'), QLatin1String("pacman")}, 208 | {('p'), QLatin1String("pamac")}, 209 | {('f'), QLatin1String("fsck")}, 210 | {('m'), QLatin1String("mount")}, 211 | {('m'), QLatin1String("mkdir")}, 212 | {('m'), QLatin1String("mkswap")}, 213 | {('s'), QLatin1String("sleep")}, 214 | {('l'), QLatin1String("ls")}, 215 | {('w'), QLatin1String("wget")}, 216 | {('k'), QLatin1String("kill")}, 217 | {('k'), QLatin1String("killall")}, 218 | {('g'), QLatin1String("gdb")}, 219 | {('Q'), QLatin1String("QOwnNotes")}, 220 | {('q'), QLatin1String("qownnotes")}, 221 | {('d'), QLatin1String("docker")}, 222 | {('o'), QLatin1String("openssl")}, 223 | {('p'), QLatin1String("php")}, 224 | {('p'), QLatin1String("python")}, 225 | {('p'), QLatin1String("perl")}, 226 | {('g'), QLatin1String("go")}, 227 | {('c'), QLatin1String("curl")} 228 | }; 229 | 230 | shell_other = {}; 231 | } 232 | 233 | void loadShellData(LanguageData &types, 234 | LanguageData &keywords, 235 | LanguageData &builtin, 236 | LanguageData &literals, 237 | LanguageData &other) { 238 | if (!shellDataInitialized) { 239 | initShellData(); 240 | shellDataInitialized = true; 241 | } 242 | types = shell_types; 243 | keywords = shell_keywords; 244 | builtin = shell_builtin; 245 | literals = shell_literals; 246 | other = shell_other; 247 | 248 | } 249 | 250 | /********************************************************/ 251 | /*** YAML DATA ***************************************/ 252 | /********************************************************/ 253 | static bool YAMLDataInitialized = false; 254 | static LanguageData YAML_keywords; 255 | static LanguageData YAML_types; 256 | static LanguageData YAML_literals; 257 | static LanguageData YAML_builtin; 258 | static LanguageData YAML_other; 259 | void initYAMLData() { 260 | YAML_keywords = {}; 261 | YAML_types = {}; 262 | YAML_literals = { 263 | {('f'), QLatin1String("false")}, 264 | {('t'), QLatin1String("true")}, 265 | {('n'), QLatin1String("null")}, 266 | }; 267 | 268 | YAML_builtin = {}; 269 | YAML_other = {}; 270 | } 271 | void loadYAMLData(LanguageData &types, 272 | LanguageData &keywords, 273 | LanguageData &builtin, 274 | LanguageData &literals, 275 | LanguageData &other) { 276 | if (!YAMLDataInitialized) { 277 | initYAMLData(); 278 | YAMLDataInitialized = true; 279 | } 280 | types = YAML_types; 281 | keywords = YAML_keywords; 282 | builtin = YAML_builtin; 283 | literals = YAML_literals; 284 | other = YAML_other; 285 | } 286 | 287 | } 288 | -------------------------------------------------------------------------------- /QSourceHighlite/languagedata.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019-2020 Waqar Ahmed -- 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included in all 12 | * copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | * SOFTWARE. 21 | * 22 | */ 23 | 24 | #ifndef QOWNLANGUAGEDATA_H 25 | #define QOWNLANGUAGEDATA_H 26 | 27 | template 28 | class QMultiHash; 29 | 30 | class QLatin1String; 31 | 32 | namespace QSourceHighlite { 33 | 34 | using LanguageData = QMultiHash; 35 | 36 | /**********************************************************/ 37 | /* Shell Data *********************************************/ 38 | /**********************************************************/ 39 | void loadShellData(LanguageData &types, 40 | LanguageData &keywords, 41 | LanguageData &builtin, 42 | LanguageData &literals, 43 | LanguageData &other); 44 | 45 | /********************************************************/ 46 | /*** YAML DATA ***************************************/ 47 | /********************************************************/ 48 | void loadYAMLData(LanguageData &types, 49 | LanguageData &keywords, 50 | LanguageData &builtin, 51 | LanguageData &literals, 52 | LanguageData &other); 53 | } 54 | #endif 55 | -------------------------------------------------------------------------------- /QSourceHighlite/qsourcehighliter.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019-2020 Waqar Ahmed -- 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included in all 12 | * copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | * SOFTWARE. 21 | * 22 | */ 23 | 24 | #include "qsourcehighliter.h" 25 | #include "languagedata.h" 26 | #include "qsourcehighliterthemes.h" 27 | 28 | #include 29 | #include 30 | #include 31 | 32 | namespace QSourceHighlite { 33 | 34 | QSourceHighliter::QSourceHighliter(QTextDocument *doc) 35 | : QSyntaxHighlighter(doc), 36 | _language(CodeC) 37 | { 38 | initFormats(); 39 | } 40 | 41 | QSourceHighliter::QSourceHighliter(QTextDocument *doc, QSourceHighliter::Themes theme) 42 | : QSyntaxHighlighter(doc), 43 | _language(CodeC) 44 | { 45 | setTheme(theme); 46 | } 47 | 48 | void QSourceHighliter::initFormats() { 49 | /**************************************** 50 | * Formats for syntax highlighting 51 | ***************************************/ 52 | 53 | QTextCharFormat format = QTextCharFormat(); 54 | 55 | _formats[Token::CodeBlock] = format; 56 | format = QTextCharFormat(); 57 | 58 | format.setForeground(QColor("#F92672")); 59 | _formats[Token::CodeKeyWord] = format; 60 | format = QTextCharFormat(); 61 | 62 | format.setForeground(QColor("#a39b4e")); 63 | _formats[Token::CodeString] = format; 64 | format = QTextCharFormat(); 65 | 66 | format.setForeground(QColor("#75715E")); 67 | _formats[Token::CodeComment] = format; 68 | format = QTextCharFormat(); 69 | 70 | format.setForeground(QColor("#54aebf")); 71 | _formats[Token::CodeType] = format; 72 | 73 | format = QTextCharFormat(); 74 | format.setForeground(QColor("#db8744")); 75 | _formats[Token::CodeOther] = format; 76 | 77 | format = QTextCharFormat(); 78 | format.setForeground(QColor("#AE81FF")); 79 | _formats[Token::CodeNumLiteral] = format; 80 | 81 | format = QTextCharFormat(); 82 | format.setForeground(QColor("#018a0f")); 83 | _formats[Token::CodeBuiltIn] = format; 84 | } 85 | 86 | void QSourceHighliter::setCurrentLanguage(Language language) { 87 | if (language != _language) 88 | _language = language; 89 | } 90 | 91 | QSourceHighliter::Language QSourceHighliter::currentLanguage() { 92 | return _language; 93 | } 94 | 95 | void QSourceHighliter::setTheme(QSourceHighliter::Themes theme) 96 | { 97 | _formats = QSourceHighliterTheme::theme(theme); 98 | rehighlight(); 99 | } 100 | 101 | void QSourceHighliter::highlightBlock(const QString &text) 102 | { 103 | if (currentBlock() == document()->firstBlock()) { 104 | setCurrentBlockState(_language); 105 | } else { 106 | previousBlockState() == _language ? 107 | setCurrentBlockState(_language) : 108 | setCurrentBlockState(_language + 1); 109 | } 110 | 111 | highlightSyntax(text); 112 | } 113 | 114 | /** 115 | * @brief Does the code syntax highlighting 116 | * @param text 117 | */ 118 | void QSourceHighliter::highlightSyntax(const QString &text) 119 | { 120 | if (text.isEmpty()) return; 121 | 122 | const auto textLen = text.length(); 123 | 124 | QChar comment; 125 | bool isCSS = false; 126 | bool isYAML = false; 127 | bool isMake = false; 128 | bool isAsm = false; 129 | bool isSQL = false; 130 | 131 | LanguageData keywords{}, 132 | others{}, 133 | types{}, 134 | builtin{}, 135 | literals{}; 136 | 137 | switch (currentBlockState()) { 138 | case CodeBash : 139 | loadShellData(types, keywords, builtin, literals, others); 140 | comment = QLatin1Char('#'); 141 | break; 142 | case CodeYAML: 143 | isYAML = true; 144 | loadYAMLData(types, keywords, builtin, literals, others); 145 | comment = QLatin1Char('#'); 146 | break; 147 | default: 148 | break; 149 | } 150 | 151 | // keep the default code block format 152 | // this statement is very slow 153 | // TODO: do this formatting when necessary instead of 154 | // applying it to the whole block in the beginning 155 | setFormat(0, textLen, _formats[CodeBlock]); 156 | 157 | auto applyCodeFormat = 158 | [this](int i, const LanguageData &data, 159 | const QString &text, const QTextCharFormat &fmt) -> int { 160 | // check if we are at the beginning OR if this is the start of a word 161 | if (i == 0 || (!text.at(i - 1).isLetterOrNumber() && 162 | text.at(i-1) != QLatin1Char('_'))) { 163 | const auto wordList = data.values(text.at(i).toLatin1()); 164 | for (const QLatin1String &word : wordList) { 165 | // we have a word match check 166 | // 1. if we are at the end 167 | // 2. if we have a complete word 168 | if (word == strMidRef(text, i, word.size()) && 169 | (i + word.size() == text.length() || 170 | (!text.at(i + word.size()).isLetterOrNumber() && 171 | text.at(i + word.size()) != QLatin1Char('_')))) { 172 | setFormat(i, word.size(), fmt); 173 | i += word.size(); 174 | } 175 | } 176 | } 177 | return i; 178 | }; 179 | 180 | const QTextCharFormat &formatType = _formats[CodeType]; 181 | const QTextCharFormat &formatKeyword = _formats[CodeKeyWord]; 182 | const QTextCharFormat &formatComment = _formats[CodeComment]; 183 | const QTextCharFormat &formatNumLit = _formats[CodeNumLiteral]; 184 | const QTextCharFormat &formatBuiltIn = _formats[CodeBuiltIn]; 185 | const QTextCharFormat &formatOther = _formats[CodeOther]; 186 | 187 | for (int i = 0; i < textLen; ++i) { 188 | 189 | if (currentBlockState() % 2 != 0) goto Comment; 190 | 191 | while (i < textLen && !text[i].isLetter()) { 192 | if (text[i].isSpace()) { 193 | ++i; 194 | //make sure we don't cross the bound 195 | if (i == textLen) return; 196 | if (text[i].isLetter()) break; 197 | else continue; 198 | } 199 | //inline comment 200 | if (comment.isNull() && text[i] == QLatin1Char('/')) { 201 | if((i+1) < textLen){ 202 | if(text[i+1] == QLatin1Char('/')) { 203 | setFormat(i, textLen, formatComment); 204 | return; 205 | } else if(text[i+1] == QLatin1Char('*')) { 206 | Comment: 207 | int next = text.indexOf(QLatin1String("*/")); 208 | if (next == -1) { 209 | //we didn't find a comment end. 210 | //Check if we are already in a comment block 211 | if (currentBlockState() % 2 == 0) 212 | setCurrentBlockState(currentBlockState() + 1); 213 | setFormat(i, textLen, formatComment); 214 | return; 215 | } else { 216 | //we found a comment end 217 | //mark this block as code if it was previously comment 218 | //first check if the comment ended on the same line 219 | //if modulo 2 is not equal to zero, it means we are in a comment 220 | //-1 will set this block's state as language 221 | if (currentBlockState() % 2 != 0) { 222 | setCurrentBlockState(currentBlockState() - 1); 223 | } 224 | next += 2; 225 | setFormat(i, next - i, formatComment); 226 | i = next; 227 | if (i >= textLen) return; 228 | } 229 | } 230 | } 231 | } else if (isSQL && comment.isNull() && text[i] == QLatin1Char('-')) { 232 | if((i+1) < textLen){ 233 | if(text[i+1] == QLatin1Char('-')) { 234 | setFormat(i, textLen, formatComment); 235 | return; 236 | } 237 | } 238 | } else if (text[i] == comment) { 239 | setFormat(i, textLen, formatComment); 240 | i = textLen; 241 | //integer literal 242 | } else if (text[i].isNumber()) { 243 | i = highlightNumericLiterals(text, i); 244 | //string literals 245 | } else if (text[i] == QLatin1Char('\"')) { 246 | i = highlightStringLiterals('\"', text, i); 247 | } else if (text[i] == QLatin1Char('\'')) { 248 | i = highlightStringLiterals('\'', text, i); 249 | } 250 | if (i >= textLen) { 251 | break; 252 | } 253 | ++i; 254 | } 255 | 256 | const int pos = i; 257 | 258 | if (i == textLen || !text[i].isLetter()) continue; 259 | 260 | /* Highlight Types */ 261 | i = applyCodeFormat(i, types, text, formatType); 262 | /************************************************ 263 | next letter is usually a space, in that case 264 | going forward is useless, so continue; 265 | We can ++i here and go to the beginning of the next word 266 | so that the next formatter can check for formatting but this will 267 | cause problems in case the next word is also of 'Type' or the current 268 | type(keyword/builtin). We can work around it and reset the value of i 269 | in the beginning of the loop to the word's first letter but I am not 270 | sure about its efficiency yet. 271 | ************************************************/ 272 | if (i == textLen || !text[i].isLetter()) continue; 273 | 274 | /* Highlight Keywords */ 275 | i = applyCodeFormat(i, keywords, text, formatKeyword); 276 | if (i == textLen || !text[i].isLetter()) continue; 277 | 278 | /* Highlight Literals (true/false/NULL,nullptr) */ 279 | i = applyCodeFormat(i, literals, text, formatNumLit); 280 | if (i == textLen || !text[i].isLetter()) continue; 281 | 282 | /* Highlight Builtin library stuff */ 283 | i = applyCodeFormat(i, builtin, text, formatBuiltIn); 284 | if (i == textLen || !text[i].isLetter()) continue; 285 | 286 | /* Highlight other stuff (preprocessor etc.) */ 287 | if (( i == 0 || !text.at(i-1).isLetter()) && others.contains(text[i].toLatin1())) { 288 | const QList wordList = others.values(text[i].toLatin1()); 289 | for(const QLatin1String &word : wordList) { 290 | if (word == strMidRef(text, i, word.size()) // we have a word match 291 | && 292 | (i + word.size() == text.length() // check if we are at the end 293 | || 294 | !text.at(i + word.size()).isLetter()) //OR if we have a complete word 295 | ) { 296 | currentBlockState() == CodeCpp ? 297 | setFormat(i - 1, word.size() + 1, formatOther) : 298 | setFormat(i, word.size(), formatOther); 299 | i += word.size(); 300 | } 301 | } 302 | } 303 | 304 | //we were unable to find any match, lets skip this word 305 | if (pos == i) { 306 | int count = i; 307 | while (count < textLen) { 308 | if (!text[count].isLetter()) break; 309 | ++count; 310 | } 311 | i = count; 312 | } 313 | } 314 | 315 | if (isCSS) cssHighlighter(text); 316 | if (isYAML) ymlHighlighter(text); 317 | if (isMake) makeHighlighter(text); 318 | if (isAsm) asmHighlighter(text); 319 | } 320 | 321 | /** 322 | * @brief Highlight string literals in code 323 | * @param strType str type i.e., ' or " 324 | * @param text the text being scanned 325 | * @param i pos of i in loop 326 | * @return pos of i after the string 327 | */ 328 | int QSourceHighliter::highlightStringLiterals(const QChar strType, const QString &text, int i) { 329 | setFormat(i, 1, _formats[CodeString]); 330 | ++i; 331 | 332 | while (i < text.length()) { 333 | //look for string end 334 | //make sure it's not an escape seq 335 | if (text.at(i) == strType && text.at(i-1) != QLatin1Char('\\')) { 336 | setFormat(i, 1, _formats[CodeString]); 337 | ++i; 338 | break; 339 | } 340 | //look for escape sequence 341 | if (text.at(i) == QLatin1Char('\\') && (i+1) < text.length()) { 342 | int len = 0; 343 | switch(text.at(i+1).toLatin1()) { 344 | case 'a': 345 | case 'b': 346 | case 'e': 347 | case 'f': 348 | case 'n': 349 | case 'r': 350 | case 't': 351 | case 'v': 352 | case '\'': 353 | case '"': 354 | case '\\': 355 | case '\?': 356 | //2 because we have to highlight \ as well as the following char 357 | len = 2; 358 | break; 359 | //octal esc sequence \123 360 | case '0': 361 | case '1': 362 | case '2': 363 | case '3': 364 | case '4': 365 | case '5': 366 | case '6': 367 | case '7': 368 | { 369 | if (i + 4 <= text.length()) { 370 | bool isCurrentOctal = true; 371 | if (!isOctal(text.at(i+2).toLatin1())) { 372 | isCurrentOctal = false; 373 | break; 374 | } 375 | if (!isOctal(text.at(i+3).toLatin1())) { 376 | isCurrentOctal = false; 377 | break; 378 | } 379 | len = isCurrentOctal ? 4 : 0; 380 | } 381 | break; 382 | } 383 | //hex numbers \xFA 384 | case 'x': 385 | { 386 | if (i + 3 <= text.length()) { 387 | bool isCurrentHex = true; 388 | if (!isHex(text.at(i+2).toLatin1())) { 389 | isCurrentHex = false; 390 | break; 391 | } 392 | if (!isHex(text.at(i+3).toLatin1())) { 393 | isCurrentHex = false; 394 | break; 395 | } 396 | len = isCurrentHex ? 4 : 0; 397 | } 398 | break; 399 | } 400 | //TODO: implement unicode code point escaping 401 | default: 402 | break; 403 | } 404 | 405 | //if len is zero, that means this wasn't an esc seq 406 | //increment i so that we skip this backslash 407 | if (len == 0) { 408 | setFormat(i, 1, _formats[CodeString]); 409 | ++i; 410 | continue; 411 | } 412 | 413 | setFormat(i, len, _formats[CodeNumLiteral]); 414 | i += len; 415 | continue; 416 | } 417 | setFormat(i, 1, _formats[CodeString]); 418 | ++i; 419 | } 420 | return i; 421 | } 422 | 423 | /** 424 | * @brief Highlight number literals in code 425 | * @param text the text being scanned 426 | * @param i pos of i in loop 427 | * @return pos of i after the number 428 | */ 429 | int QSourceHighliter::highlightNumericLiterals(const QString &text, int i) 430 | { 431 | bool isPreAllowed = false; 432 | if (i == 0) isPreAllowed = true; 433 | else { 434 | //these values are allowed before a number 435 | switch(text.at(i - 1).toLatin1()) { 436 | //css number 437 | case ':': 438 | if (currentBlockState() == CodeCSS) 439 | isPreAllowed = true; 440 | break; 441 | case '$': 442 | if (currentBlockState() == CodeAsm) 443 | isPreAllowed = true; 444 | break; 445 | case '[': 446 | case '(': 447 | case '{': 448 | case ' ': 449 | case ',': 450 | case '=': 451 | case '+': 452 | case '-': 453 | case '*': 454 | case '/': 455 | case '%': 456 | case '<': 457 | case '>': 458 | isPreAllowed = true; 459 | break; 460 | } 461 | } 462 | 463 | if (!isPreAllowed) return i; 464 | 465 | const int start = i; 466 | 467 | if ((i+1) >= text.length()) { 468 | setFormat(i, 1, _formats[CodeNumLiteral]); 469 | return ++i; 470 | } 471 | 472 | ++i; 473 | //hex numbers highlighting (only if there's a preceding zero) 474 | if (text.at(i) == QChar('x') && text.at(i - 1) == QChar('0')) 475 | ++i; 476 | 477 | while (i < text.length()) { 478 | if (!text.at(i).isNumber() && text.at(i) != QChar('.') && 479 | text.at(i) != QChar('e')) //exponent 480 | break; 481 | ++i; 482 | } 483 | 484 | bool isPostAllowed = false; 485 | if (i == text.length()) { 486 | //cant have e at the end 487 | if (text.at(i - 1) != QChar('e')) 488 | isPostAllowed = true; 489 | } else { 490 | //these values are allowed after a number 491 | switch(text.at(i).toLatin1()) { 492 | case ']': 493 | case ')': 494 | case '}': 495 | case ' ': 496 | case ',': 497 | case '=': 498 | case '+': 499 | case '-': 500 | case '*': 501 | case '/': 502 | case '%': 503 | case '>': 504 | case '<': 505 | case ';': 506 | isPostAllowed = true; 507 | break; 508 | // for 100u, 1.0F 509 | case 'p': 510 | if (currentBlockState() == CodeCSS) 511 | if (i + 1 < text.length() && text.at(i+1) == QChar('x')) { 512 | if (i + 2 == text.length() || !text.at(i+2).isLetterOrNumber()) 513 | isPostAllowed = true; 514 | } 515 | break; 516 | case 'e': 517 | if (currentBlockState() == CodeCSS) 518 | if (i + 1 < text.length() && text.at(i+1) == QChar('m')) { 519 | if (i + 2 == text.length() || !text.at(i+2).isLetterOrNumber()) 520 | isPostAllowed = true; 521 | } 522 | break; 523 | case 'u': 524 | case 'l': 525 | case 'f': 526 | case 'U': 527 | case 'L': 528 | case 'F': 529 | if (i + 1 == text.length() || !text.at(i+1).isLetterOrNumber()) { 530 | isPostAllowed = true; 531 | ++i; 532 | } 533 | break; 534 | } 535 | } 536 | if (isPostAllowed) { 537 | int end = i; 538 | setFormat(start, end - start, _formats[CodeNumLiteral]); 539 | } 540 | //decrement so that the index is at the last number, not after it 541 | return --i; 542 | } 543 | 544 | /** 545 | * @brief The YAML highlighter 546 | * @param text 547 | * @details This function post processes a line after the main syntax 548 | * highlighter has run for additional highlighting. It does these things 549 | * 550 | * If the current line is a comment, skip it 551 | * 552 | * Highlight all the words that have a colon after them as 'keyword' except: 553 | * If the word is a string, skip it. 554 | * If the colon is in between a path, skip it (C:\) 555 | * 556 | * Once the colon is found, the function will skip every character except 'h' 557 | * 558 | * If an h letter is found, check the next 4/5 letters for http/https and 559 | * highlight them as a link (underlined) 560 | */ 561 | void QSourceHighliter::ymlHighlighter(const QString &text) { 562 | if (text.isEmpty()) return; 563 | const auto textLen = text.length(); 564 | bool colonNotFound = false; 565 | 566 | //if this is a comment don't do anything and just return 567 | if (text.trimmed().at(0) == QLatin1Char('#')) 568 | return; 569 | 570 | for (int i = 0; i < textLen; ++i) { 571 | if (!text.at(i).isLetter()) continue; 572 | 573 | if (colonNotFound && text.at(i) != QLatin1Char('h')) continue; 574 | 575 | //we found a string literal, skip it 576 | if (i != 0 && (text.at(i-1) == QLatin1Char('"') || text.at(i-1) == QLatin1Char('\''))) { 577 | const int next = text.indexOf(text.at(i-1), i); 578 | if (next == -1) break; 579 | i = next; 580 | continue; 581 | } 582 | 583 | const int colon = text.indexOf(QLatin1Char(':'), i); 584 | 585 | //if colon isn't found, we set this true 586 | if (colon == -1) colonNotFound = true; 587 | 588 | if (!colonNotFound) { 589 | //if the line ends here, format and return 590 | if (colon+1 == textLen) { 591 | setFormat(i, colon - i, _formats[CodeKeyWord]); 592 | return; 593 | } else { 594 | //colon is found, check if it isn't some path or something else 595 | if (!(text.at(colon+1) == QLatin1Char('\\') && text.at(colon+1) == QLatin1Char('/'))) { 596 | setFormat(i, colon - i, _formats[CodeKeyWord]); 597 | } 598 | } 599 | } 600 | 601 | //underlined links 602 | if (text.at(i) == QLatin1Char('h')) { 603 | if (strMidRef(text, i, 5) == QLatin1String("https") || 604 | strMidRef(text, i, 4) == QLatin1String("http")) { 605 | int space = text.indexOf(QChar(' '), i); 606 | if (space == -1) space = textLen; 607 | QTextCharFormat f = _formats[CodeString]; 608 | f.setUnderlineStyle(QTextCharFormat::SingleUnderline); 609 | setFormat(i, space - i, f); 610 | i = space; 611 | } 612 | } else if (text.at(i) == QLatin1Char('t')) { 613 | if (strMidRef(text, i, 8) == QLatin1String("template")) { 614 | int space = text.indexOf(QChar(' '), i); 615 | if (space == -1) space = textLen; 616 | QTextCharFormat f = _formats[CodeString]; 617 | f.setUnderlineStyle(QTextCharFormat::SingleUnderline); 618 | setFormat(i, space - i, f); 619 | i = space; 620 | } 621 | } 622 | } 623 | } 624 | 625 | void QSourceHighliter::cssHighlighter(const QString &text) 626 | { 627 | if (text.isEmpty()) return; 628 | const auto textLen = text.length(); 629 | for (int i = 0; i= textLen) return; 632 | if (text[i + 1].isSpace() || text[i+1].isNumber()) continue; 633 | int space = text.indexOf(QLatin1Char(' '), i); 634 | if (space < 0) { 635 | space = text.indexOf('{'); 636 | if (space < 0) { 637 | space = textLen; 638 | } 639 | } 640 | setFormat(i, space - i, _formats[CodeKeyWord]); 641 | i = space; 642 | } else if (text[i] == QLatin1Char('c')) { 643 | if (strMidRef(text, i, 5) == QLatin1String("color")) { 644 | i += 5; 645 | int colon = text.indexOf(QLatin1Char(':'), i); 646 | if (colon < 0) continue; 647 | i = colon; 648 | i++; 649 | while(i < textLen) { 650 | if (!text[i].isSpace()) break; 651 | i++; 652 | } 653 | int semicolon = text.indexOf(QLatin1Char(';')); 654 | if (semicolon < 0) semicolon = textLen; 655 | const QString color = text.mid(i, semicolon-i); 656 | QTextCharFormat f = _formats[CodeBlock]; 657 | QColor c(color); 658 | if (color.startsWith(QLatin1String("rgb"))) { 659 | int t = text.indexOf(QLatin1Char('('), i); 660 | int rPos = text.indexOf(QLatin1Char(','), t); 661 | int gPos = text.indexOf(QLatin1Char(','), rPos+1); 662 | int bPos = text.indexOf(QLatin1Char(')'), gPos); 663 | if (rPos > -1 && gPos > -1 && bPos > -1) { 664 | const auto r = strMidRef(text, t+1, rPos - (t+1)); 665 | const auto g = strMidRef(text, rPos+1, gPos - (rPos + 1)); 666 | const auto b = strMidRef(text, gPos+1, bPos - (gPos+1)); 667 | c.setRgb(r.toInt(), g.toInt(), b.toInt()); 668 | } else { 669 | c = _formats[CodeBlock].background().color(); 670 | } 671 | } 672 | 673 | if (!c.isValid()) { 674 | continue; 675 | } 676 | 677 | int lightness{}; 678 | QColor foreground; 679 | //really dark 680 | if (c.lightness() <= 20) { 681 | foreground = Qt::white; 682 | } else if (c.lightness() > 20 && c.lightness() <= 51){ 683 | foreground = QColor("#ccc"); 684 | } else if (c.lightness() > 51 && c.lightness() <= 78){ 685 | foreground = QColor("#bbb"); 686 | } else if (c.lightness() > 78 && c.lightness() <= 110){ 687 | foreground = QColor("#bbb"); 688 | } else if (c.lightness() > 127) { 689 | lightness = c.lightness() + 100; 690 | foreground = c.darker(lightness); 691 | } 692 | else { 693 | lightness = c.lightness() + 100; 694 | foreground = c.lighter(lightness); 695 | } 696 | 697 | f.setBackground(c); 698 | f.setForeground(foreground); 699 | setFormat(i, semicolon - i, QTextCharFormat()); //clear prev format 700 | setFormat(i, semicolon - i, f); 701 | i = semicolon; 702 | } 703 | } 704 | } 705 | } 706 | 707 | 708 | void QSourceHighliter::xmlHighlighter(const QString &text) { 709 | if (text.isEmpty()) return; 710 | const auto textLen = text.length(); 711 | 712 | setFormat(0, textLen, _formats[CodeBlock]); 713 | 714 | for (int i = 0; i < textLen; ++i) { 715 | if (text[i] == QLatin1Char('<') && text[i+1] != QLatin1Char('!')) { 716 | 717 | const int found = text.indexOf(QLatin1Char('>'), i); 718 | if (found > 0) { 719 | ++i; 720 | if (text[i] == QLatin1Char('/')) ++i; 721 | setFormat(i, found - i, _formats[CodeKeyWord]); 722 | } 723 | } 724 | 725 | if (text[i] == QLatin1Char('=')) { 726 | int lastSpace = text.lastIndexOf(QLatin1Char(' '), i); 727 | if (lastSpace == i-1) lastSpace = text.lastIndexOf(QLatin1Char(' '), i-2); 728 | if (lastSpace > 0) { 729 | setFormat(lastSpace, i - lastSpace, _formats[CodeBuiltIn]); 730 | } 731 | } 732 | 733 | if (text[i] == QLatin1Char('\"')) { 734 | const int pos = i; 735 | int cnt = 1; 736 | ++i; 737 | //bound check 738 | if ( (i+1) >= textLen) return; 739 | while (i < textLen) { 740 | if (text[i] == QLatin1Char('\"')) { 741 | ++cnt; 742 | ++i; 743 | break; 744 | } 745 | ++i; ++cnt; 746 | //bound check 747 | if ( (i+1) >= textLen) { 748 | ++cnt; 749 | break; 750 | } 751 | } 752 | setFormat(pos, cnt, _formats[CodeString]); 753 | } 754 | } 755 | } 756 | 757 | void QSourceHighliter::makeHighlighter(const QString &text) 758 | { 759 | int colonPos = text.indexOf(QLatin1Char(':')); 760 | if (colonPos == -1) 761 | return; 762 | setFormat(0, colonPos, _formats[Token::CodeBuiltIn]); 763 | } 764 | 765 | /** 766 | * @brief highlight inline labels such as 'func()' in "call func()" 767 | * @param text 768 | */ 769 | void QSourceHighliter::highlightInlineAsmLabels(const QString &text) 770 | { 771 | #define Q(s) QStringLiteral(s) 772 | static const QString jumps[27] = { 773 | //0 - 19 774 | Q("jmp"), Q("je"), Q("jne"), Q("jz"), Q("jnz"), Q("ja"), Q("jb"), Q("jg"), Q("jge"), Q("jae"), Q("jl"), Q("jle"), 775 | Q("jbe"), Q("jo"), Q("jno"), Q("js"), Q("jns"), Q("jcxz"), Q("jecxz"), Q("jrcxz"), 776 | //20 - 24 777 | Q("loop"), Q("loope"), Q("loopne"), Q("loopz"), Q("loopnz"), 778 | //25 - 26 779 | Q("call"), Q("callq") 780 | }; 781 | #undef Q 782 | 783 | auto format = _formats[Token::CodeBuiltIn]; 784 | format.setFontUnderline(true); 785 | 786 | const QString trimmed = text.trimmed(); 787 | int start = -1; 788 | int end = -1; 789 | char c{}; 790 | if (!trimmed.isEmpty()) 791 | c = trimmed.at(0).toLatin1(); 792 | if (c == 'j') { 793 | start = 0; end = 20; 794 | } else if (c == 'c') { 795 | start = 25; end = 27; 796 | } else if (c == 'l') { 797 | start = 20; end = 25; 798 | } else { 799 | return; 800 | } 801 | 802 | auto skipSpaces = [&text](int& j){ 803 | while (text.at(j).isSpace()) j++; 804 | return j; 805 | }; 806 | 807 | for (int i = start; i < end; ++i) { 808 | if (trimmed.startsWith(jumps[i])) { 809 | int j = 0; 810 | skipSpaces(j); 811 | j = j + jumps[i].length() + 1; 812 | skipSpaces(j); 813 | int len = text.length() - j; 814 | setFormat(j, len, format); 815 | } 816 | } 817 | } 818 | 819 | void QSourceHighliter::asmHighlighter(const QString& text) 820 | { 821 | highlightInlineAsmLabels(text); 822 | //label highlighting 823 | //examples: 824 | //L1: 825 | //LFB1: # local func begin 826 | // 827 | //following e.gs are not a label 828 | //mov %eax, Count::count(%rip) 829 | //.string ": #%s" 830 | 831 | //look for the last occurence of a colon 832 | int colonPos = text.lastIndexOf(QLatin1Char(':')); 833 | if (colonPos == -1) 834 | return; 835 | //check if this colon is in a comment maybe? 836 | bool isComment = text.lastIndexOf('#', colonPos) != -1; 837 | if (isComment) { 838 | int commentPos = text.lastIndexOf('#', colonPos); 839 | colonPos = text.lastIndexOf(':', commentPos); 840 | } 841 | 842 | auto format = _formats[Token::CodeBuiltIn]; 843 | format.setFontUnderline(true); 844 | 845 | if (colonPos >= text.length() - 1) { 846 | setFormat(0, colonPos, format); 847 | } 848 | 849 | int i = 0; 850 | bool isLabel = true; 851 | for (i = colonPos + 1; i < text.length(); ++i) { 852 | if (!text.at(i).isSpace()) { 853 | isLabel = false; 854 | break; 855 | } 856 | } 857 | 858 | if (!isLabel && i < text.length() && text.at(i) == QLatin1Char('#')) 859 | setFormat(0, colonPos, format); 860 | } 861 | } 862 | -------------------------------------------------------------------------------- /QSourceHighlite/qsourcehighliter.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019-2020 Waqar Ahmed -- 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included in all 12 | * copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | * SOFTWARE. 21 | * 22 | */ 23 | 24 | #ifndef QSOURCEHIGHLITER_H 25 | #define QSOURCEHIGHLITER_H 26 | 27 | #include 28 | 29 | #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) 30 | #include 31 | #endif 32 | 33 | namespace QSourceHighlite { 34 | 35 | class QSourceHighliter : public QSyntaxHighlighter 36 | { 37 | public: 38 | enum Themes { 39 | Monokai = 1 40 | }; 41 | 42 | explicit QSourceHighliter(QTextDocument *doc); 43 | QSourceHighliter(QTextDocument *doc, Themes theme); 44 | 45 | //languages 46 | /********* 47 | * When adding a language make sure that its value is a multiple of 2 48 | * This is because we use the next number as comment for that language 49 | * In case the language doesn't support multiline comments in the traditional C++ 50 | * sense, leave the next value empty. Otherwise mark the next value as comment for 51 | * that language. 52 | * e.g 53 | * CodeCpp = 200 54 | * CodeCppComment = 201 55 | */ 56 | enum Language { 57 | //languages 58 | CodeCpp = 200, 59 | CodeCppComment = 201, 60 | CodeJs = 202, 61 | CodeJsComment = 203, 62 | CodeC = 204, 63 | CodeCComment = 205, 64 | CodeBash = 206, 65 | CodePHP = 208, 66 | CodePHPComment = 209, 67 | CodeQML = 210, 68 | CodeQMLComment = 211, 69 | CodePython = 212, 70 | CodeRust = 214, 71 | CodeRustComment = 215, 72 | CodeJava = 216, 73 | CodeJavaComment = 217, 74 | CodeCSharp = 218, 75 | CodeCSharpComment = 219, 76 | CodeGo = 220, 77 | CodeGoComment = 221, 78 | CodeV = 222, 79 | CodeVComment = 223, 80 | CodeSQL = 224, 81 | CodeJSON = 226, 82 | CodeXML = 228, 83 | CodeCSS = 230, 84 | CodeCSSComment = 231, 85 | CodeTypeScript = 232, 86 | CodeTypeScriptComment = 233, 87 | CodeYAML = 234, 88 | CodeINI = 236, 89 | CodeVex = 238, 90 | CodeVexComment = 239, 91 | CodeCMake = 240, 92 | CodeMake = 242, 93 | CodeAsm = 244, 94 | CodeLua = 246, 95 | CodeLuaComment = 247 96 | }; 97 | Q_ENUM(Language) 98 | 99 | enum Token { 100 | CodeBlock, 101 | CodeKeyWord, 102 | CodeString, 103 | CodeComment, 104 | CodeType, 105 | CodeOther, 106 | CodeNumLiteral, 107 | CodeBuiltIn, 108 | }; 109 | Q_ENUM(Token) 110 | 111 | void setCurrentLanguage(Language language); 112 | Q_REQUIRED_RESULT Language currentLanguage(); 113 | void setTheme(Themes theme); 114 | 115 | protected: 116 | void highlightBlock(const QString &text) override; 117 | 118 | private: 119 | void highlightSyntax(const QString &text); 120 | Q_REQUIRED_RESULT int highlightNumericLiterals(const QString &text, int i); 121 | Q_REQUIRED_RESULT int highlightStringLiterals(const QChar strType, const QString &text, int i); 122 | 123 | /** 124 | * @brief returns true if c is octal 125 | * @param c the char being checked 126 | * @returns true if the number is octal, false otherwise 127 | */ 128 | Q_REQUIRED_RESULT static constexpr inline bool isOctal(const char c) { 129 | return (c >= '0' && c <= '7'); 130 | } 131 | 132 | /** 133 | * @brief returns true if c is hex 134 | * @param c the char being checked 135 | * @returns true if the number is hex, false otherwise 136 | */ 137 | Q_REQUIRED_RESULT static constexpr inline bool isHex(const char c) { 138 | return ( 139 | (c >= '0' && c <= '9') || 140 | (c >= 'a' && c <= 'f') || 141 | (c >= 'A' && c <= 'F') 142 | ); 143 | } 144 | 145 | void cssHighlighter(const QString &text); 146 | void ymlHighlighter(const QString &text); 147 | void xmlHighlighter(const QString &text); 148 | void makeHighlighter(const QString &text); 149 | void highlightInlineAsmLabels(const QString& text); 150 | void asmHighlighter(const QString& text); 151 | void initFormats(); 152 | 153 | #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) 154 | static inline QStringView strMidRef(const QString& str, qsizetype position, qsizetype n = -1) 155 | { 156 | return QStringView(str).mid(position, n); 157 | } 158 | #else 159 | static inline QStringRef strMidRef(const QString& str, int position, int n = -1) 160 | { 161 | return str.midRef(position, n); 162 | } 163 | #endif 164 | 165 | QHash _formats; 166 | Language _language; 167 | }; 168 | } 169 | #endif // QSOURCEHIGHLITER_H 170 | -------------------------------------------------------------------------------- /QSourceHighlite/qsourcehighliterthemes.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019-2020 Waqar Ahmed -- 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included in all 12 | * copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | * SOFTWARE. 21 | * 22 | */ 23 | 24 | #include "qsourcehighliterthemes.h" 25 | 26 | namespace QSourceHighlite { 27 | 28 | static QHash formats() 29 | { 30 | QHash _formats; 31 | 32 | QTextCharFormat defaultFormat = QTextCharFormat(); 33 | 34 | _formats[QSourceHighliter::Token::CodeBlock] = defaultFormat; 35 | _formats[QSourceHighliter::Token::CodeKeyWord] = defaultFormat; 36 | _formats[QSourceHighliter::Token::CodeString] = defaultFormat; 37 | _formats[QSourceHighliter::Token::CodeComment] = defaultFormat; 38 | _formats[QSourceHighliter::Token::CodeType] = defaultFormat; 39 | _formats[QSourceHighliter::Token::CodeOther] = defaultFormat; 40 | _formats[QSourceHighliter::Token::CodeNumLiteral] = defaultFormat; 41 | _formats[QSourceHighliter::Token::CodeBuiltIn] = defaultFormat; 42 | 43 | return _formats; 44 | } 45 | 46 | static QHash monokai() 47 | { 48 | QHash _formats = formats(); 49 | 50 | _formats[QSourceHighliter::Token::CodeBlock].setForeground(QColor(227, 226, 214)); 51 | _formats[QSourceHighliter::Token::CodeKeyWord].setForeground(QColor(249, 38, 114)); 52 | _formats[QSourceHighliter::Token::CodeString].setForeground(QColor(230, 219, 116)); 53 | _formats[QSourceHighliter::Token::CodeComment].setForeground(QColor(117, 113, 94)); 54 | _formats[QSourceHighliter::Token::CodeType].setForeground(QColor(102, 217, 239)); 55 | _formats[QSourceHighliter::Token::CodeOther].setForeground(QColor(249, 38, 114)); 56 | _formats[QSourceHighliter::Token::CodeNumLiteral].setForeground(QColor(174, 129, 255)); 57 | _formats[QSourceHighliter::Token::CodeBuiltIn].setForeground(QColor(166, 226, 46)); 58 | 59 | return _formats; 60 | } 61 | 62 | QHash 63 | QSourceHighliterTheme::theme(QSourceHighliter::Themes theme) { 64 | switch (theme) { 65 | case QSourceHighliter::Themes::Monokai: 66 | return monokai(); 67 | default: 68 | return {}; 69 | } 70 | } 71 | 72 | } 73 | -------------------------------------------------------------------------------- /QSourceHighlite/qsourcehighliterthemes.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019-2020 Waqar Ahmed -- 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included in all 12 | * copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | * SOFTWARE. 21 | * 22 | */ 23 | 24 | #ifndef QSOURCEHIGHLITERTHEMES_H 25 | #define QSOURCEHIGHLITERTHEMES_H 26 | 27 | #include "qsourcehighliter.h" 28 | 29 | namespace QSourceHighlite { 30 | 31 | namespace QSourceHighliterTheme 32 | { 33 | QHash theme(QSourceHighliter::Themes); 34 | 35 | } // namespace QSourceHighliterTheme 36 | 37 | } // namespace QSourceHighlite 38 | #endif // QSOURCEHIGHLITERTHEMES_H 39 | -------------------------------------------------------------------------------- /QVNCClient/QVNCClient.pri: -------------------------------------------------------------------------------- 1 | QT += core gui network widgets 2 | 3 | INCLUDEPATH += $$PWD 4 | 5 | HEADERS += $$PWD/qvncclientwidget.h 6 | 7 | SOURCES += $$PWD/qvncclientwidget.cpp 8 | -------------------------------------------------------------------------------- /QrwEmoticons/LICENSE.txt: -------------------------------------------------------------------------------- 1 | Attribution 4.0 International 2 | 3 | ======================================================================= 4 | 5 | Creative Commons Corporation ("Creative Commons") is not a law firm and 6 | does not provide legal services or legal advice. Distribution of 7 | Creative Commons public licenses does not create a lawyer-client or 8 | other relationship. Creative Commons makes its licenses and related 9 | information available on an "as-is" basis. Creative Commons gives no 10 | warranties regarding its licenses, any material licensed under their 11 | terms and conditions, or any related information. Creative Commons 12 | disclaims all liability for damages resulting from their use to the 13 | fullest extent possible. 14 | 15 | Using Creative Commons Public Licenses 16 | 17 | Creative Commons public licenses provide a standard set of terms and 18 | conditions that creators and other rights holders may use to share 19 | original works of authorship and other material subject to copyright 20 | and certain other rights specified in the public license below. The 21 | following considerations are for informational purposes only, are not 22 | exhaustive, and do not form part of our licenses. 23 | 24 | Considerations for licensors: Our public licenses are 25 | intended for use by those authorized to give the public 26 | permission to use material in ways otherwise restricted by 27 | copyright and certain other rights. Our licenses are 28 | irrevocable. Licensors should read and understand the terms 29 | and conditions of the license they choose before applying it. 30 | Licensors should also secure all rights necessary before 31 | applying our licenses so that the public can reuse the 32 | material as expected. Licensors should clearly mark any 33 | material not subject to the license. This includes other CC- 34 | licensed material, or material used under an exception or 35 | limitation to copyright. More considerations for licensors: 36 | wiki.creativecommons.org/Considerations_for_licensors 37 | 38 | Considerations for the public: By using one of our public 39 | licenses, a licensor grants the public permission to use the 40 | licensed material under specified terms and conditions. If 41 | the licensor's permission is not necessary for any reason--for 42 | example, because of any applicable exception or limitation to 43 | copyright--then that use is not regulated by the license. Our 44 | licenses grant only permissions under copyright and certain 45 | other rights that a licensor has authority to grant. Use of 46 | the licensed material may still be restricted for other 47 | reasons, including because others have copyright or other 48 | rights in the material. A licensor may make special requests, 49 | such as asking that all changes be marked or described. 50 | Although not required by our licenses, you are encouraged to 51 | respect those requests where reasonable. More considerations 52 | for the public: 53 | wiki.creativecommons.org/Considerations_for_licensees 54 | 55 | ======================================================================= 56 | 57 | Creative Commons Attribution 4.0 International Public License 58 | 59 | By exercising the Licensed Rights (defined below), You accept and agree 60 | to be bound by the terms and conditions of this Creative Commons 61 | Attribution 4.0 International Public License ("Public License"). To the 62 | extent this Public License may be interpreted as a contract, You are 63 | granted the Licensed Rights in consideration of Your acceptance of 64 | these terms and conditions, and the Licensor grants You such rights in 65 | consideration of benefits the Licensor receives from making the 66 | Licensed Material available under these terms and conditions. 67 | 68 | 69 | Section 1 -- Definitions. 70 | 71 | a. Adapted Material means material subject to Copyright and Similar 72 | Rights that is derived from or based upon the Licensed Material 73 | and in which the Licensed Material is translated, altered, 74 | arranged, transformed, or otherwise modified in a manner requiring 75 | permission under the Copyright and Similar Rights held by the 76 | Licensor. For purposes of this Public License, where the Licensed 77 | Material is a musical work, performance, or sound recording, 78 | Adapted Material is always produced where the Licensed Material is 79 | synched in timed relation with a moving image. 80 | 81 | b. Adapter's License means the license You apply to Your Copyright 82 | and Similar Rights in Your contributions to Adapted Material in 83 | accordance with the terms and conditions of this Public License. 84 | 85 | c. Copyright and Similar Rights means copyright and/or similar rights 86 | closely related to copyright including, without limitation, 87 | performance, broadcast, sound recording, and Sui Generis Database 88 | Rights, without regard to how the rights are labeled or 89 | categorized. For purposes of this Public License, the rights 90 | specified in Section 2(b)(1)-(2) are not Copyright and Similar 91 | Rights. 92 | 93 | d. Effective Technological Measures means those measures that, in the 94 | absence of proper authority, may not be circumvented under laws 95 | fulfilling obligations under Article 11 of the WIPO Copyright 96 | Treaty adopted on December 20, 1996, and/or similar international 97 | agreements. 98 | 99 | e. Exceptions and Limitations means fair use, fair dealing, and/or 100 | any other exception or limitation to Copyright and Similar Rights 101 | that applies to Your use of the Licensed Material. 102 | 103 | f. Licensed Material means the artistic or literary work, database, 104 | or other material to which the Licensor applied this Public 105 | License. 106 | 107 | g. Licensed Rights means the rights granted to You subject to the 108 | terms and conditions of this Public License, which are limited to 109 | all Copyright and Similar Rights that apply to Your use of the 110 | Licensed Material and that the Licensor has authority to license. 111 | 112 | h. Licensor means the individual(s) or entity(ies) granting rights 113 | under this Public License. 114 | 115 | i. Share means to provide material to the public by any means or 116 | process that requires permission under the Licensed Rights, such 117 | as reproduction, public display, public performance, distribution, 118 | dissemination, communication, or importation, and to make material 119 | available to the public including in ways that members of the 120 | public may access the material from a place and at a time 121 | individually chosen by them. 122 | 123 | j. Sui Generis Database Rights means rights other than copyright 124 | resulting from Directive 96/9/EC of the European Parliament and of 125 | the Council of 11 March 1996 on the legal protection of databases, 126 | as amended and/or succeeded, as well as other essentially 127 | equivalent rights anywhere in the world. 128 | 129 | k. You means the individual or entity exercising the Licensed Rights 130 | under this Public License. Your has a corresponding meaning. 131 | 132 | 133 | Section 2 -- Scope. 134 | 135 | a. License grant. 136 | 137 | 1. Subject to the terms and conditions of this Public License, 138 | the Licensor hereby grants You a worldwide, royalty-free, 139 | non-sublicensable, non-exclusive, irrevocable license to 140 | exercise the Licensed Rights in the Licensed Material to: 141 | 142 | a. reproduce and Share the Licensed Material, in whole or 143 | in part; and 144 | 145 | b. produce, reproduce, and Share Adapted Material. 146 | 147 | 2. Exceptions and Limitations. For the avoidance of doubt, where 148 | Exceptions and Limitations apply to Your use, this Public 149 | License does not apply, and You do not need to comply with 150 | its terms and conditions. 151 | 152 | 3. Term. The term of this Public License is specified in Section 153 | 6(a). 154 | 155 | 4. Media and formats; technical modifications allowed. The 156 | Licensor authorizes You to exercise the Licensed Rights in 157 | all media and formats whether now known or hereafter created, 158 | and to make technical modifications necessary to do so. The 159 | Licensor waives and/or agrees not to assert any right or 160 | authority to forbid You from making technical modifications 161 | necessary to exercise the Licensed Rights, including 162 | technical modifications necessary to circumvent Effective 163 | Technological Measures. For purposes of this Public License, 164 | simply making modifications authorized by this Section 2(a) 165 | (4) never produces Adapted Material. 166 | 167 | 5. Downstream recipients. 168 | 169 | a. Offer from the Licensor -- Licensed Material. Every 170 | recipient of the Licensed Material automatically 171 | receives an offer from the Licensor to exercise the 172 | Licensed Rights under the terms and conditions of this 173 | Public License. 174 | 175 | b. No downstream restrictions. You may not offer or impose 176 | any additional or different terms or conditions on, or 177 | apply any Effective Technological Measures to, the 178 | Licensed Material if doing so restricts exercise of the 179 | Licensed Rights by any recipient of the Licensed 180 | Material. 181 | 182 | 6. No endorsement. Nothing in this Public License constitutes or 183 | may be construed as permission to assert or imply that You 184 | are, or that Your use of the Licensed Material is, connected 185 | with, or sponsored, endorsed, or granted official status by, 186 | the Licensor or others designated to receive attribution as 187 | provided in Section 3(a)(1)(A)(i). 188 | 189 | b. Other rights. 190 | 191 | 1. Moral rights, such as the right of integrity, are not 192 | licensed under this Public License, nor are publicity, 193 | privacy, and/or other similar personality rights; however, to 194 | the extent possible, the Licensor waives and/or agrees not to 195 | assert any such rights held by the Licensor to the limited 196 | extent necessary to allow You to exercise the Licensed 197 | Rights, but not otherwise. 198 | 199 | 2. Patent and trademark rights are not licensed under this 200 | Public License. 201 | 202 | 3. To the extent possible, the Licensor waives any right to 203 | collect royalties from You for the exercise of the Licensed 204 | Rights, whether directly or through a collecting society 205 | under any voluntary or waivable statutory or compulsory 206 | licensing scheme. In all other cases the Licensor expressly 207 | reserves any right to collect such royalties. 208 | 209 | 210 | Section 3 -- License Conditions. 211 | 212 | Your exercise of the Licensed Rights is expressly made subject to the 213 | following conditions. 214 | 215 | a. Attribution. 216 | 217 | 1. If You Share the Licensed Material (including in modified 218 | form), You must: 219 | 220 | a. retain the following if it is supplied by the Licensor 221 | with the Licensed Material: 222 | 223 | i. identification of the creator(s) of the Licensed 224 | Material and any others designated to receive 225 | attribution, in any reasonable manner requested by 226 | the Licensor (including by pseudonym if 227 | designated); 228 | 229 | ii. a copyright notice; 230 | 231 | iii. a notice that refers to this Public License; 232 | 233 | iv. a notice that refers to the disclaimer of 234 | warranties; 235 | 236 | v. a URI or hyperlink to the Licensed Material to the 237 | extent reasonably practicable; 238 | 239 | b. indicate if You modified the Licensed Material and 240 | retain an indication of any previous modifications; and 241 | 242 | c. indicate the Licensed Material is licensed under this 243 | Public License, and include the text of, or the URI or 244 | hyperlink to, this Public License. 245 | 246 | 2. You may satisfy the conditions in Section 3(a)(1) in any 247 | reasonable manner based on the medium, means, and context in 248 | which You Share the Licensed Material. For example, it may be 249 | reasonable to satisfy the conditions by providing a URI or 250 | hyperlink to a resource that includes the required 251 | information. 252 | 253 | 3. If requested by the Licensor, You must remove any of the 254 | information required by Section 3(a)(1)(A) to the extent 255 | reasonably practicable. 256 | 257 | 4. If You Share Adapted Material You produce, the Adapter's 258 | License You apply must not prevent recipients of the Adapted 259 | Material from complying with this Public License. 260 | 261 | 262 | Section 4 -- Sui Generis Database Rights. 263 | 264 | Where the Licensed Rights include Sui Generis Database Rights that 265 | apply to Your use of the Licensed Material: 266 | 267 | a. for the avoidance of doubt, Section 2(a)(1) grants You the right 268 | to extract, reuse, reproduce, and Share all or a substantial 269 | portion of the contents of the database; 270 | 271 | b. if You include all or a substantial portion of the database 272 | contents in a database in which You have Sui Generis Database 273 | Rights, then the database in which You have Sui Generis Database 274 | Rights (but not its individual contents) is Adapted Material; and 275 | 276 | c. You must comply with the conditions in Section 3(a) if You Share 277 | all or a substantial portion of the contents of the database. 278 | 279 | For the avoidance of doubt, this Section 4 supplements and does not 280 | replace Your obligations under this Public License where the Licensed 281 | Rights include other Copyright and Similar Rights. 282 | 283 | 284 | Section 5 -- Disclaimer of Warranties and Limitation of Liability. 285 | 286 | a. UNLESS OTHERWISE SEPARATELY UNDERTAKEN BY THE LICENSOR, TO THE 287 | EXTENT POSSIBLE, THE LICENSOR OFFERS THE LICENSED MATERIAL AS-IS 288 | AND AS-AVAILABLE, AND MAKES NO REPRESENTATIONS OR WARRANTIES OF 289 | ANY KIND CONCERNING THE LICENSED MATERIAL, WHETHER EXPRESS, 290 | IMPLIED, STATUTORY, OR OTHER. THIS INCLUDES, WITHOUT LIMITATION, 291 | WARRANTIES OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR 292 | PURPOSE, NON-INFRINGEMENT, ABSENCE OF LATENT OR OTHER DEFECTS, 293 | ACCURACY, OR THE PRESENCE OR ABSENCE OF ERRORS, WHETHER OR NOT 294 | KNOWN OR DISCOVERABLE. WHERE DISCLAIMERS OF WARRANTIES ARE NOT 295 | ALLOWED IN FULL OR IN PART, THIS DISCLAIMER MAY NOT APPLY TO YOU. 296 | 297 | b. TO THE EXTENT POSSIBLE, IN NO EVENT WILL THE LICENSOR BE LIABLE 298 | TO YOU ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION, 299 | NEGLIGENCE) OR OTHERWISE FOR ANY DIRECT, SPECIAL, INDIRECT, 300 | INCIDENTAL, CONSEQUENTIAL, PUNITIVE, EXEMPLARY, OR OTHER LOSSES, 301 | COSTS, EXPENSES, OR DAMAGES ARISING OUT OF THIS PUBLIC LICENSE OR 302 | USE OF THE LICENSED MATERIAL, EVEN IF THE LICENSOR HAS BEEN 303 | ADVISED OF THE POSSIBILITY OF SUCH LOSSES, COSTS, EXPENSES, OR 304 | DAMAGES. WHERE A LIMITATION OF LIABILITY IS NOT ALLOWED IN FULL OR 305 | IN PART, THIS LIMITATION MAY NOT APPLY TO YOU. 306 | 307 | c. The disclaimer of warranties and limitation of liability provided 308 | above shall be interpreted in a manner that, to the extent 309 | possible, most closely approximates an absolute disclaimer and 310 | waiver of all liability. 311 | 312 | 313 | Section 6 -- Term and Termination. 314 | 315 | a. This Public License applies for the term of the Copyright and 316 | Similar Rights licensed here. However, if You fail to comply with 317 | this Public License, then Your rights under this Public License 318 | terminate automatically. 319 | 320 | b. Where Your right to use the Licensed Material has terminated under 321 | Section 6(a), it reinstates: 322 | 323 | 1. automatically as of the date the violation is cured, provided 324 | it is cured within 30 days of Your discovery of the 325 | violation; or 326 | 327 | 2. upon express reinstatement by the Licensor. 328 | 329 | For the avoidance of doubt, this Section 6(b) does not affect any 330 | right the Licensor may have to seek remedies for Your violations 331 | of this Public License. 332 | 333 | c. For the avoidance of doubt, the Licensor may also offer the 334 | Licensed Material under separate terms or conditions or stop 335 | distributing the Licensed Material at any time; however, doing so 336 | will not terminate this Public License. 337 | 338 | d. Sections 1, 5, 6, 7, and 8 survive termination of this Public 339 | License. 340 | 341 | 342 | Section 7 -- Other Terms and Conditions. 343 | 344 | a. The Licensor shall not be bound by any additional or different 345 | terms or conditions communicated by You unless expressly agreed. 346 | 347 | b. Any arrangements, understandings, or agreements regarding the 348 | Licensed Material not stated herein are separate from and 349 | independent of the terms and conditions of this Public License. 350 | 351 | 352 | Section 8 -- Interpretation. 353 | 354 | a. For the avoidance of doubt, this Public License does not, and 355 | shall not be interpreted to, reduce, limit, restrict, or impose 356 | conditions on any use of the Licensed Material that could lawfully 357 | be made without permission under this Public License. 358 | 359 | b. To the extent possible, if any provision of this Public License is 360 | deemed unenforceable, it shall be automatically reformed to the 361 | minimum extent necessary to make it enforceable. If the provision 362 | cannot be reformed, it shall be severed from this Public License 363 | without affecting the enforceability of the remaining terms and 364 | conditions. 365 | 366 | c. No term or condition of this Public License will be waived and no 367 | failure to comply consented to unless expressly agreed to by the 368 | Licensor. 369 | 370 | d. Nothing in this Public License constitutes or may be interpreted 371 | as a limitation upon, or waiver of, any privileges and immunities 372 | that apply to the Licensor or You, including from the legal 373 | processes of any jurisdiction or authority. 374 | 375 | 376 | ======================================================================= 377 | 378 | Creative Commons is not a party to its public 379 | licenses. Notwithstanding, Creative Commons may elect to apply one of 380 | its public licenses to material it publishes and in those instances 381 | will be considered the “Licensor.” The text of the Creative Commons 382 | public licenses is dedicated to the public domain under the CC0 Public 383 | Domain Dedication. Except for the limited purpose of indicating that 384 | material is shared under a Creative Commons public license or as 385 | otherwise permitted by the Creative Commons policies published at 386 | creativecommons.org/policies, Creative Commons does not authorize the 387 | use of the trademark "Creative Commons" or any other trademark or logo 388 | of Creative Commons without its prior written consent including, 389 | without limitation, in connection with any unauthorized modifications 390 | to any of its public licenses or any other arrangements, 391 | understandings, or agreements concerning use of licensed material. For 392 | the avoidance of doubt, this paragraph does not form part of the 393 | public licenses. 394 | 395 | Creative Commons may be contacted at creativecommons.org. 396 | -------------------------------------------------------------------------------- /QrwEmoticons/QrwEmoticons.pri: -------------------------------------------------------------------------------- 1 | QT += gui widgets svg xml 2 | 3 | INCLUDEPATH += $$PWD/include 4 | 5 | # Removed all emojis but openmoji and circles 6 | 7 | QMAKE_PRE_LINK += \ 8 | cd $$PWD/lib && $(QMAKE) && $(MAKE); \ 9 | cd $$PWD/plugin-openmoji && $(QMAKE) && $(MAKE) 10 | 11 | LIBS += \ 12 | -L$$PWD/lib \ 13 | -lQrwEmoticons \ 14 | -L$$PWD/plugin-openmoji \ 15 | -lemoticons_openmoji 16 | 17 | pre-clean.commands = \ 18 | cd $$PWD/lib && $(QMAKE) && $(MAKE) clean; \ 19 | cd $$PWD/plugin-openmoji && $(QMAKE) && $(MAKE) clean 20 | pre-distclean.commands = \ 21 | cd $$PWD/lib && $(QMAKE) && $(MAKE) distclean; \ 22 | cd $$PWD/plugin-openmoji && $(QMAKE) && $(MAKE) distclean 23 | QMAKE_EXTRA_TARGETS += pre-clean pre-distclean 24 | CLEAN_DEPS += pre-clean 25 | DISTCLEAN_DEPS += pre-distclean 26 | -------------------------------------------------------------------------------- /QrwEmoticons/README.md: -------------------------------------------------------------------------------- 1 | QrwEmoticons 2 | ============= 3 | Qt5 (Widgets) Emoticon library and plugins. 4 | 5 | Since its pure Qt code you can use it on almost any platform. 6 | 7 | License 8 | ------------- 9 | CreativeCommons Attribution 4.0 International (CC BY 4.0) 10 | 11 | https://creativecommons.org/licenses/by/4.0/ 12 | -------------------------------------------------------------------------------- /QrwEmoticons/include/QrwEmoticons/Global.h: -------------------------------------------------------------------------------- 1 | #ifndef QRWEMOTICONS_GLOBAL_H 2 | #define QRWEMOTICONS_GLOBAL_H 3 | 4 | #include 5 | 6 | #define NOT ! 7 | 8 | /* 9 | * LIB MACROS 10 | */ 11 | 12 | #if defined(QRWEMOTICONS_LIB) 13 | # define QRWEMOTICONS_EXPORT Q_DECL_EXPORT 14 | #else 15 | # define QRWEMOTICONS_EXPORT Q_DECL_IMPORT 16 | #endif 17 | 18 | #define QRWEMOTICONS_DECLARE_PUBLIC(CLASS) \ 19 | CLASS * q_ptr; \ 20 | Q_DECLARE_PUBLIC(CLASS) 21 | 22 | #define QRWEMOTICONS_DECLARE_PRIVATE(CLASS) \ 23 | CLASS##Private* p_ptr; \ 24 | Q_DECLARE_PRIVATE_D(p_ptr, CLASS) 25 | 26 | /* 27 | * HELPER MACROS 28 | */ 29 | 30 | #define EMOTICON_FILENAME(E) \ 31 | ( \ 32 | E.size() == 1 ? EMOTICON_FILENAME_1(E) : \ 33 | E.size() == 2 ? EMOTICON_FILENAME_2(E) : \ 34 | E.size() == 3 ? EMOTICON_FILENAME_3(E) : \ 35 | E.size() == 4 ? EMOTICON_FILENAME_4(E) : \ 36 | E.size() == 5 ? EMOTICON_FILENAME_5(E) : \ 37 | E.size() == 6 ? EMOTICON_FILENAME_6(E) : \ 38 | E.size() == 7 ? EMOTICON_FILENAME_7(E) : \ 39 | E.size() == 8 ? EMOTICON_FILENAME_8(E) : \ 40 | QString() \ 41 | ) 42 | 43 | #define EMOTICON_FILENAME_1(E) \ 44 | QStringLiteral("%1") \ 45 | .arg(E[0], 5, 16, QLatin1Char('0')) 46 | 47 | #define EMOTICON_FILENAME_2(E) \ 48 | QStringLiteral("%1-%2") \ 49 | .arg(E[0], 5, 16, QLatin1Char('0')) \ 50 | .arg(E[1], 5, 16, QLatin1Char('0')) 51 | 52 | #define EMOTICON_FILENAME_3(E) \ 53 | QStringLiteral("%1-%2-%3") \ 54 | .arg(E[0], 5, 16, QLatin1Char('0')) \ 55 | .arg(E[1], 5, 16, QLatin1Char('0')) \ 56 | .arg(E[2], 5, 16, QLatin1Char('0')) 57 | 58 | #define EMOTICON_FILENAME_4(E) \ 59 | QStringLiteral("%1-%2-%3-%4") \ 60 | .arg(E[0], 5, 16, QLatin1Char('0')) \ 61 | .arg(E[1], 5, 16, QLatin1Char('0')) \ 62 | .arg(E[2], 5, 16, QLatin1Char('0')) \ 63 | .arg(E[3], 5, 16, QLatin1Char('0')) 64 | 65 | #define EMOTICON_FILENAME_5(E) \ 66 | QStringLiteral("%1-%2-%3-%4-%5") \ 67 | .arg(E[0], 5, 16, QLatin1Char('0')) \ 68 | .arg(E[1], 5, 16, QLatin1Char('0')) \ 69 | .arg(E[2], 5, 16, QLatin1Char('0')) \ 70 | .arg(E[3], 5, 16, QLatin1Char('0')) \ 71 | .arg(E[4], 5, 16, QLatin1Char('0')) 72 | 73 | #define EMOTICON_FILENAME_6(E) \ 74 | QStringLiteral("%1-%2-%3-%4-%5-%6") \ 75 | .arg(E[0], 5, 16, QLatin1Char('0')) \ 76 | .arg(E[1], 5, 16, QLatin1Char('0')) \ 77 | .arg(E[2], 5, 16, QLatin1Char('0')) \ 78 | .arg(E[3], 5, 16, QLatin1Char('0')) \ 79 | .arg(E[4], 5, 16, QLatin1Char('0')) \ 80 | .arg(E[5], 5, 16, QLatin1Char('0')) 81 | 82 | #define EMOTICON_FILENAME_7(E) \ 83 | QStringLiteral("%1-%2-%3-%4-%5-%6-%7") \ 84 | .arg(E[0], 5, 16, QLatin1Char('0')) \ 85 | .arg(E[1], 5, 16, QLatin1Char('0')) \ 86 | .arg(E[2], 5, 16, QLatin1Char('0')) \ 87 | .arg(E[3], 5, 16, QLatin1Char('0')) \ 88 | .arg(E[4], 5, 16, QLatin1Char('0')) \ 89 | .arg(E[5], 5, 16, QLatin1Char('0')) \ 90 | .arg(E[6], 5, 16, QLatin1Char('0')) 91 | 92 | #define EMOTICON_FILENAME_8(E) \ 93 | QStringLiteral("%1-%2-%3-%4-%5-%6-%7-%8") \ 94 | .arg(E[0], 5, 16, QLatin1Char('0')) \ 95 | .arg(E[1], 5, 16, QLatin1Char('0')) \ 96 | .arg(E[2], 5, 16, QLatin1Char('0')) \ 97 | .arg(E[3], 5, 16, QLatin1Char('0')) \ 98 | .arg(E[4], 5, 16, QLatin1Char('0')) \ 99 | .arg(E[5], 5, 16, QLatin1Char('0')) \ 100 | .arg(E[6], 5, 16, QLatin1Char('0')) \ 101 | .arg(E[7], 5, 16, QLatin1Char('0')) 102 | 103 | #endif // QRWEMOTICONS_GLOBAL_H 104 | -------------------------------------------------------------------------------- /QrwEmoticons/include/QrwEmoticons/QrwEmoticons: -------------------------------------------------------------------------------- 1 | #include "Global.h" 2 | #include "QrwEmoticons.h" 3 | #include "TextEdit.h" 4 | #include "QrwEmoticonsPlugin.h" 5 | -------------------------------------------------------------------------------- /QrwEmoticons/include/QrwEmoticons/QrwEmoticons.h: -------------------------------------------------------------------------------- 1 | #ifndef QRWEMOTICONS_H 2 | #define QRWEMOTICONS_H 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | class QrwEmoticonsPrivate; 9 | 10 | class QRWEMOTICONS_EXPORT QrwEmoticons : public QObject 11 | { 12 | Q_OBJECT 13 | 14 | Q_PROPERTY( QString provider READ provider WRITE setProvider NOTIFY providerChanged ) 15 | Q_PROPERTY( int maximumEmoticonCharCount READ maximumEmoticonCharCount WRITE setMaximumEmoticonCharCount NOTIFY maximumEmoticonCharCountChanged ) 16 | Q_PROPERTY( QSize minimumEmoticonSize READ minimumEmoticonSize WRITE setMinimumEmoticonSize NOTIFY minimumEmoticonSizeChanged ) 17 | 18 | QRWEMOTICONS_DECLARE_PRIVATE(QrwEmoticons) 19 | 20 | public: 21 | explicit QrwEmoticons(QTextDocument* document, QObject* parent = Q_NULLPTR); 22 | virtual ~QrwEmoticons() Q_DECL_OVERRIDE; 23 | 24 | typedef QVector Emoticon; 25 | 26 | QString getPlainText() const; 27 | QString getPlainText(const QTextCursor & cursor) const; 28 | QString getHtml() const; 29 | QString getHtml(const QTextCursor & cursor) const; 30 | 31 | QString provider() const; 32 | void setProvider(const QString & provider, bool dynamic = true); 33 | quint8 maximumEmoticonCharCount() const; 34 | void setMaximumEmoticonCharCount(quint8 count); 35 | QSize minimumEmoticonSize() const; 36 | void setMinimumEmoticonSize(const QSize & size); 37 | 38 | Q_SIGNALS: 39 | void providerChanged(const QString & provider); 40 | void maximumEmoticonCharCountChanged(quint8 maximumEmoticonCharCount); 41 | void minimumEmoticonSizeChanged(const QSize & minimumEmoticonSize); 42 | }; 43 | 44 | Q_DECLARE_METATYPE(QrwEmoticons::Emoticon) 45 | 46 | #endif // QRWEMOTICONS_H 47 | -------------------------------------------------------------------------------- /QrwEmoticons/include/QrwEmoticons/QrwEmoticonsPlugin.h: -------------------------------------------------------------------------------- 1 | #ifndef QRWEMOTICONSPLUGININTERFACE_H 2 | #define QRWEMOTICONSPLUGININTERFACE_H 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | class QrwEmoticonsPluginInterface : public QObject 9 | { 10 | protected: 11 | explicit QrwEmoticonsPluginInterface(QObject* parent = Q_NULLPTR) : QObject(parent) {} 12 | 13 | public: 14 | virtual ~QrwEmoticonsPluginInterface() {} 15 | 16 | virtual bool hasEmoticon(const QrwEmoticons::Emoticon & code) = 0; 17 | virtual QPixmap getEmoticon(const QrwEmoticons::Emoticon & code, const QSize & size) = 0; 18 | }; 19 | 20 | #define QrwEmoticonsPluginInterface_iid "net.raven-worx.QrwEmoticons.PluginInterface" 21 | Q_DECLARE_INTERFACE(QrwEmoticonsPluginInterface, QrwEmoticonsPluginInterface_iid) 22 | 23 | #endif //QRWEMOTICONSPLUGININTERFACE_H 24 | -------------------------------------------------------------------------------- /QrwEmoticons/include/QrwEmoticons/TextEdit.h: -------------------------------------------------------------------------------- 1 | #ifndef QRWEMOTICONS_TEXTEDIT_H 2 | #define QRWEMOTICONS_TEXTEDIT_H 3 | 4 | #include 5 | #include 6 | 7 | class QrwEmoticons; 8 | 9 | class QRWEMOTICONS_EXPORT QrwEmoticonsTextEdit : public QTextEdit 10 | { 11 | Q_OBJECT 12 | 13 | public: 14 | explicit QrwEmoticonsTextEdit(QWidget* parent = Q_NULLPTR); 15 | 16 | QString toHtml() const; 17 | QString toPlainText() const; 18 | 19 | QrwEmoticons* emoticons() const; 20 | 21 | public Q_SLOTS: 22 | void relayout(); 23 | 24 | protected: 25 | virtual QMimeData* createMimeDataFromSelection() const; 26 | 27 | private: 28 | QrwEmoticons* m_Emoticons; 29 | }; 30 | 31 | #endif // QRWEMOTICONS_TEXTEDIT_H 32 | -------------------------------------------------------------------------------- /QrwEmoticons/lib/lib.pro: -------------------------------------------------------------------------------- 1 | TEMPLATE = lib 2 | CONFIG += static 3 | QT += gui widgets svg 4 | 5 | TARGET = QrwEmoticons 6 | 7 | # The following define makes your compiler emit warnings if you use 8 | # any feature of Qt which has been marked as deprecated (the exact warnings 9 | # depend on your compiler). Please consult the documentation of the 10 | # deprecated API in order to know how to port your code away from it. 11 | DEFINES += QT_DEPRECATED_WARNINGS 12 | 13 | # You can also make your code fail to compile if you use deprecated APIs. 14 | # In order to do so, uncomment the following line. 15 | # You can also select to disable deprecated APIs only up to a certain version of Qt. 16 | #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 17 | 18 | DEFINES += QRWEMOTICONS_LIB 19 | 20 | INCLUDEPATH += \ 21 | ../include \ 22 | ../include/QrwEmoticons 23 | 24 | SOURCES += \ 25 | src/QrwEmoticons.cpp \ 26 | src/QrwEmoticons_p.cpp \ 27 | src/QrwEmoticons_data.cpp \ 28 | src/TextEdit.cpp \ 29 | src/QrwEmoticonsTextObjectInterface.cpp 30 | 31 | HEADERS += \ 32 | ../include/QrwEmoticons/Global.h \ 33 | ../include/QrwEmoticons/QrwEmoticonsPlugin.h \ 34 | ../include/QrwEmoticons/QrwEmoticons.h \ 35 | ../include/QrwEmoticons/TextEdit.h \ 36 | src/QrwEmoticons_p.h \ 37 | src/QrwEmoticonsTextObjectInterface_p.h 38 | -------------------------------------------------------------------------------- /QrwEmoticons/lib/src/QrwEmoticons.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "QrwEmoticons_p.h" 3 | 4 | QrwEmoticons::QrwEmoticons(QTextDocument* document, QObject* parent) 5 | : QObject(parent) 6 | { 7 | p_ptr = new QrwEmoticonsPrivate(this, document); 8 | } 9 | 10 | QrwEmoticons::~QrwEmoticons() 11 | { 12 | } 13 | 14 | QString QrwEmoticons::getPlainText() const 15 | { 16 | Q_D(const QrwEmoticons); 17 | return d->getDocumentText( false ); 18 | } 19 | 20 | QString QrwEmoticons::getPlainText(const QTextCursor & cursor) const 21 | { 22 | Q_D(const QrwEmoticons); 23 | return d->getCursorText( cursor, false ); 24 | } 25 | 26 | QString QrwEmoticons::getHtml() const 27 | { 28 | Q_D(const QrwEmoticons); 29 | return d->getDocumentText( true ); 30 | } 31 | 32 | QString QrwEmoticons::getHtml(const QTextCursor & cursor) const 33 | { 34 | Q_D(const QrwEmoticons); 35 | return d->getCursorText( cursor, true ); 36 | } 37 | 38 | QString QrwEmoticons::provider() const 39 | { 40 | Q_D(const QrwEmoticons); 41 | if( d->m_Plugin ) 42 | return d->m_Plugin.metaData.value(QStringLiteral("id")).toString(); 43 | else 44 | return QString(); 45 | } 46 | 47 | void QrwEmoticons::setProvider(const QString & plugin, bool dynamic) 48 | { 49 | Q_D(QrwEmoticons); 50 | d->loadPlugin(plugin, dynamic); 51 | } 52 | 53 | quint8 QrwEmoticons::maximumEmoticonCharCount() const 54 | { 55 | Q_D(const QrwEmoticons); 56 | return d->m_MaxEmoticonCharCodeCount; 57 | } 58 | 59 | void QrwEmoticons::setMaximumEmoticonCharCount(quint8 count) 60 | { 61 | Q_D(QrwEmoticons); 62 | if( d->m_MaxEmoticonCharCodeCount != count ) 63 | { 64 | d->m_MaxEmoticonCharCodeCount = count; 65 | Q_EMIT maximumEmoticonCharCountChanged(count); 66 | } 67 | } 68 | 69 | QSize QrwEmoticons::minimumEmoticonSize() const 70 | { 71 | Q_D(const QrwEmoticons); 72 | return d->m_MinimumEmoticonSize; 73 | } 74 | 75 | void QrwEmoticons::setMinimumEmoticonSize(const QSize & size) 76 | { 77 | Q_D(QrwEmoticons); 78 | if( size.isValid() && d->m_MinimumEmoticonSize != size ) 79 | { 80 | d->m_MinimumEmoticonSize = size; 81 | Q_EMIT minimumEmoticonSizeChanged(size); 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /QrwEmoticons/lib/src/QrwEmoticonsTextObjectInterface.cpp: -------------------------------------------------------------------------------- 1 | #include "QrwEmoticonsTextObjectInterface_p.h" 2 | #include "QrwEmoticons_p.h" 3 | #include 4 | 5 | QrwEmoticonsTextObjectInterface::QrwEmoticonsTextObjectInterface(QrwEmoticonsPrivate* pvt) 6 | : QObject(pvt), m_Prvt(pvt) 7 | { 8 | } 9 | 10 | void QrwEmoticonsTextObjectInterface::drawObject(QPainter* painter, const QRectF & rect, QTextDocument* doc, int posInDocument, const QTextFormat & format) 11 | { 12 | Q_UNUSED(doc); 13 | Q_UNUSED(posInDocument); 14 | 15 | const QrwEmoticons::Emoticon code = format.property( QrwEmoticonsPrivate::EmoticonUnicode ).value(); 16 | //const QString emoticonImagePath = format.stringProperty( QrwEmoticonsPrivate::EmoticonImagePath ); 17 | //const QPixmap pix( emoticonImagePath ); 18 | 19 | const QRectF drawRect = rect.adjusted(1,0,-1,0); 20 | painter->save(); 21 | if( !m_Prvt->m_Plugin || !m_Prvt->m_Plugin.interf->hasEmoticon(code) ) 22 | { 23 | painter->setPen( QPen(Qt::darkGray, 1, Qt::SolidLine) ); 24 | painter->setBrush( QColor(240,240,240) ); 25 | painter->drawRect( drawRect.adjusted(1,0,-1,0) ); // adjust again 26 | painter->setFont( QFont("typewriter", qMax(6,int(drawRect.height()*0.6))) ); 27 | painter->drawText( drawRect, Qt::AlignCenter, QStringLiteral("?") ); 28 | } 29 | else 30 | { 31 | const QPixmap pix = m_Prvt->m_Plugin.interf->getEmoticon(code, drawRect.size().toSize()); 32 | 33 | painter->setPen( Qt::NoPen ); 34 | painter->setBrush( Qt::NoBrush ); 35 | painter->drawPixmap( drawRect, pix, QRectF(QPointF(0,0),pix.size()) ); 36 | } 37 | painter->restore(); 38 | } 39 | 40 | QSizeF QrwEmoticonsTextObjectInterface::intrinsicSize(QTextDocument* doc, int posInDocument, const QTextFormat & format) 41 | { 42 | int height = m_Prvt->getLineHeight(posInDocument, format); 43 | QSize size(height+2, height); 44 | if( m_Prvt->m_MinimumEmoticonSize.isValid() ) 45 | size = size.expandedTo( m_Prvt->m_MinimumEmoticonSize ); 46 | return size; 47 | } 48 | -------------------------------------------------------------------------------- /QrwEmoticons/lib/src/QrwEmoticonsTextObjectInterface_p.h: -------------------------------------------------------------------------------- 1 | #ifndef QRWEMOTICONSTEXTOBJECTINTERFACE_H 2 | #define QRWEMOTICONSTEXTOBJECTINTERFACE_H 3 | 4 | #include 5 | #include 6 | 7 | class QrwEmoticonsPrivate; 8 | 9 | class QrwEmoticonsTextObjectInterface : public QObject, public QTextObjectInterface 10 | { 11 | Q_OBJECT 12 | Q_INTERFACES(QTextObjectInterface) 13 | 14 | public: 15 | explicit QrwEmoticonsTextObjectInterface(QrwEmoticonsPrivate* pvt); 16 | 17 | // QTextObjectInterface interface 18 | virtual void drawObject(QPainter* painter, const QRectF & rect, QTextDocument* doc, int posInDocument, const QTextFormat & format) Q_DECL_OVERRIDE; 19 | virtual QSizeF intrinsicSize(QTextDocument* doc, int posInDocument, const QTextFormat & format) Q_DECL_OVERRIDE; 20 | 21 | private: 22 | QrwEmoticonsPrivate* m_Prvt; 23 | }; 24 | 25 | #endif // QRWEMOTICONSTEXTOBJECTINTERFACE_H 26 | -------------------------------------------------------------------------------- /QrwEmoticons/lib/src/QrwEmoticons_data.cpp: -------------------------------------------------------------------------------- 1 | #include "QrwEmoticons_p.h" 2 | const EmoticonsData QrwEmoticonsPrivate::EMOTICONS{ 3 | {0x1f535}, 4 | {0x1f7e2}, 5 | {0x26a0}, 6 | {0x26A0,0xFE0E}, 7 | {0x26A0,0xFE0F}, 8 | {0x2b50}, 9 | {0x2B50,0xFE0E}, 10 | {0x2B50,0xFE0F}, 11 | }; 12 | -------------------------------------------------------------------------------- /QrwEmoticons/lib/src/QrwEmoticons_p.cpp: -------------------------------------------------------------------------------- 1 | #include "QrwEmoticons_p.h" 2 | #include "QrwEmoticonsTextObjectInterface_p.h" 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | QrwEmoticonsPrivate::QrwEmoticonsPrivate(QrwEmoticons* q, QTextDocument* document) 11 | : QObject(q), q_ptr(q), m_CurrentlyApplying(false), m_TextDocument(document) 12 | , m_MaxEmoticonCharCodeCount(8), m_MinimumEmoticonSize(20,20) 13 | { 14 | bool loaded = this->loadPlugin(); 15 | Q_ASSERT( loaded ); 16 | 17 | Q_ASSERT( m_TextDocument ); 18 | if( m_TextDocument ) 19 | { 20 | connect(document, &QTextDocument::contentsChange, this, &QrwEmoticonsPrivate::onTextDocumentContentsChanged); 21 | 22 | QrwEmoticonsTextObjectInterface* interf = new QrwEmoticonsTextObjectInterface(this); 23 | m_TextDocument->documentLayout()->registerHandler(QrwEmoticonsPrivate::EmoticonTextFormatObjectType, interf); 24 | this->applyTextCharFormat(); 25 | } 26 | } 27 | 28 | QrwEmoticonsPrivate::~QrwEmoticonsPrivate() 29 | { 30 | if( m_PluginLoader.isLoaded() ) 31 | m_PluginLoader.unload(); 32 | } 33 | 34 | QString QrwEmoticonsPrivate::GetEmoticonString( const QrwEmoticons::Emoticon & code ) 35 | { 36 | QString emoticonStr; 37 | for( int i = 0; i < code.size(); ++i ) 38 | emoticonStr += QrwEmoticonsPrivate::GetEmoticonString( code.at(i) ); 39 | return emoticonStr; 40 | } 41 | 42 | QString QrwEmoticonsPrivate::GetEmoticonString( uint character ) 43 | { 44 | QString emoticonStr; 45 | if( QChar::requiresSurrogates(character) ) 46 | { 47 | QChar chars[] = { 48 | QChar(QChar::highSurrogate(character)), 49 | QChar(QChar::lowSurrogate(character)) 50 | }; 51 | emoticonStr = QString(chars,2); 52 | } 53 | else 54 | emoticonStr = QChar(character); 55 | 56 | return emoticonStr; 57 | } 58 | 59 | void QrwEmoticonsPrivate::onTextDocumentContentsChanged(int position, int /*charsRemoved*/, int charsAdded) 60 | { 61 | if( charsAdded > 0 ) 62 | this->applyTextCharFormat( position ); 63 | } 64 | 65 | bool QrwEmoticonsPrivate::isEmoticon( uint character ) 66 | { 67 | return this->isEmoticon( QrwEmoticons::Emoticon() << character ); 68 | } 69 | 70 | bool QrwEmoticonsPrivate::isEmoticon( const QrwEmoticons::Emoticon & code ) 71 | { 72 | if( code.isEmpty() ) 73 | return false; 74 | return EMOTICONS.contains( code ); 75 | } 76 | 77 | QrwEmoticons::Emoticon QrwEmoticonsPrivate::getEmoticonCode( QTextCursor c, int* selectionLength ) 78 | { 79 | if( selectionLength ) 80 | *selectionLength = 0; 81 | 82 | if( c.isNull() || c.atEnd() ) 83 | return QrwEmoticons::Emoticon(); 84 | 85 | int start = c.position(); 86 | c.setPosition( start, QTextCursor::MoveAnchor ); 87 | int end = start; 88 | // NOTE: 89 | // QTextCursor::movePosition(QTextCursor::NextCharacter) can increase the actual 90 | // selected characters by more than one, so we are checking the selection here 91 | // instead of simply iterating to the max count 92 | while( c.selectedText().length() < (m_MaxEmoticonCharCodeCount*2) ) 93 | { 94 | if( NOT c.movePosition( QTextCursor::NextCharacter, QTextCursor::KeepAnchor, 1) ) 95 | break; 96 | end = c.position(); 97 | } 98 | 99 | while( end > start ) 100 | { 101 | c.setPosition( start, QTextCursor::MoveAnchor ); 102 | c.setPosition( end, QTextCursor::KeepAnchor ); 103 | 104 | const QString selection = c.selectedText(); 105 | 106 | QrwEmoticons::Emoticon code; 107 | 108 | for( int i = 0; i < selection.length(); ++i ) 109 | { 110 | const ushort prevCharacter = i > 0 ? selection[i-1].unicode() : 0x0; 111 | const ushort unicodeCharacter = selection[i].unicode(); 112 | 113 | uint emoticonCharCode = 0x0; 114 | 115 | if( QChar::isHighSurrogate(unicodeCharacter) ) 116 | continue; 117 | 118 | if( QChar::isLowSurrogate(unicodeCharacter) && QChar::isHighSurrogate(prevCharacter) ) 119 | { 120 | // convert unicode surrogate pair back to unicode value 121 | emoticonCharCode = QChar::surrogateToUcs4(prevCharacter,unicodeCharacter); 122 | // QChar::surrogateToUcs4() is a little bit faster than the following: 123 | //const uint emoticonCharCode = ((hi - 0xd800) * 0x400) + (lo - 0xdc00) + 0x10000; 124 | } 125 | else 126 | emoticonCharCode = unicodeCharacter; 127 | 128 | if( emoticonCharCode > 0 ) 129 | code << emoticonCharCode; 130 | else 131 | break; 132 | } 133 | 134 | if( this->isEmoticon(code) ) 135 | { 136 | if( selectionLength ) 137 | *selectionLength = selection.length(); 138 | return code; 139 | } 140 | 141 | if( !c.movePosition(QTextCursor::PreviousCharacter, QTextCursor::KeepAnchor, 1) ) 142 | break; 143 | end = c.position(); 144 | } 145 | 146 | return QrwEmoticons::Emoticon(); 147 | } 148 | 149 | QString QrwEmoticonsPrivate::getDocumentText( bool html ) const 150 | { 151 | if( NOT m_TextDocument ) 152 | return QString(); 153 | 154 | QScopedPointer doc(m_TextDocument->clone()); 155 | 156 | QTextCursor c( doc.data() ); 157 | 158 | c.movePosition( QTextCursor::Start, QTextCursor::MoveAnchor ); 159 | while( NOT c.atEnd() ) 160 | { 161 | if( NOT c.movePosition( QTextCursor::NextCharacter, QTextCursor::KeepAnchor, 1 ) ) 162 | break; 163 | const QString selection = c.selectedText().trimmed(); 164 | if( selection == QString(QChar::ObjectReplacementCharacter) ) 165 | { 166 | const QTextCharFormat f = c.charFormat(); 167 | if( f.objectType() == QrwEmoticonsPrivate::EmoticonTextFormatObjectType ) 168 | { 169 | const QrwEmoticons::Emoticon code = f.property( QrwEmoticonsPrivate::EmoticonUnicode ).value(); 170 | Q_ASSERT( NOT code.isEmpty() ); 171 | 172 | const QString replaceText = f.stringProperty( QrwEmoticonsPrivate::EmoticonQString ); 173 | Q_ASSERT( NOT replaceText.isEmpty() ); 174 | 175 | c.insertText( replaceText ); 176 | } 177 | } 178 | 179 | c.setPosition( c.position(), QTextCursor::MoveAnchor ); // "collapse" selection 180 | } 181 | 182 | return html ? doc->toHtml() : doc->toPlainText(); 183 | } 184 | 185 | QString QrwEmoticonsPrivate::getCursorText( const QTextCursor & cursor, bool html ) const 186 | { 187 | if( NOT cursor.document() || NOT cursor.hasSelection() ) 188 | return QString(); 189 | else if( cursor.hasComplexSelection() ) 190 | { 191 | qWarning("QrwEmoticons: QTextCursor with complex selections may not work as expected"); 192 | } 193 | 194 | QScopedPointer doc( m_TextDocument->clone() ); 195 | QTextCursor c( doc.data() ); 196 | c.setPosition( qMin(cursor.position(), cursor.anchor()), QTextCursor::MoveAnchor ); 197 | c.setPosition( qMax(cursor.position(), cursor.anchor()), QTextCursor::KeepAnchor ); 198 | 199 | int start = c.anchor(); 200 | int end = c.position(); 201 | 202 | c.setPosition( start, QTextCursor::MoveAnchor ); 203 | while( c.position() <= end ) 204 | { 205 | if( NOT c.movePosition( QTextCursor::NextCharacter, QTextCursor::KeepAnchor, 1 ) ) 206 | break; 207 | const QString selection = c.selectedText().trimmed(); 208 | if( selection == QString(QChar::ObjectReplacementCharacter) ) 209 | { 210 | const QTextCharFormat f = c.charFormat(); 211 | if( f.objectType() == QrwEmoticonsPrivate::EmoticonTextFormatObjectType ) 212 | { 213 | const QrwEmoticons::Emoticon code = f.property( QrwEmoticonsPrivate::EmoticonUnicode ).value(); 214 | Q_ASSERT( NOT code.isEmpty() ); 215 | 216 | const QString replaceText = f.stringProperty( QrwEmoticonsPrivate::EmoticonQString ); 217 | Q_ASSERT( NOT replaceText.isEmpty() ); 218 | 219 | end += (replaceText.length()-1); // i am not quite sure why this is actually needed (only in conjunction with QTextDocumentFragment) 220 | c.insertText( replaceText, QTextCharFormat() ); 221 | } 222 | } 223 | 224 | c.setPosition( c.position(), QTextCursor::MoveAnchor ); // "collapse" selection 225 | } 226 | 227 | c.setPosition( start, QTextCursor::MoveAnchor ); 228 | c.setPosition( end, QTextCursor::KeepAnchor ); 229 | QTextDocumentFragment fragment = c.selection(); 230 | QString text = html ? fragment.toHtml() : fragment.toPlainText(); 231 | return text; 232 | } 233 | 234 | void QrwEmoticonsPrivate::applyTextCharFormat(int pos) 235 | { 236 | if( m_CurrentlyApplying ) 237 | return; 238 | 239 | m_CurrentlyApplying = true; // recursion protection 240 | const bool isModified = m_TextDocument->isModified(); 241 | 242 | QTextCursor c( m_TextDocument ); 243 | if( pos == 0 ) 244 | c.movePosition( QTextCursor::Start, QTextCursor::MoveAnchor ); 245 | else 246 | c.setPosition( pos, QTextCursor::MoveAnchor ); 247 | 248 | c.beginEditBlock(); 249 | while( NOT c.atEnd() ) 250 | { 251 | int increase = 1; 252 | 253 | QrwEmoticons::Emoticon code = this->getEmoticonCode( c, &increase ); 254 | if( NOT code.isEmpty() ) 255 | { 256 | QTextCharFormat emoticonFormat; 257 | emoticonFormat.setObjectType( QrwEmoticonsPrivate::EmoticonTextFormatObjectType ); 258 | emoticonFormat.setProperty( QrwEmoticonsPrivate::EmoticonUnicode, QVariant::fromValue(code) ); 259 | //emoticonFormat.setProperty( QrwEmoticonsPrivate::EmoticonImagePath, QVariant::fromValue(this->GetEmoticonPath(code)) ); 260 | emoticonFormat.setProperty( QrwEmoticonsPrivate::EmoticonQString, QVariant::fromValue(QrwEmoticonsPrivate::GetEmoticonString(code)) ); 261 | emoticonFormat.setVerticalAlignment( QTextCharFormat::AlignBottom ); 262 | 263 | c.setPosition( c.position()+increase, QTextCursor::KeepAnchor ); 264 | c.insertText( QString(QChar::ObjectReplacementCharacter), emoticonFormat ); 265 | //c.setPosition( c.position(), QTextCursor::MoveAnchor ); // collapse selection 266 | } 267 | else if( NOT c.movePosition( QTextCursor::NextCharacter, QTextCursor::MoveAnchor, 1 ) ) 268 | break; 269 | } 270 | c.endEditBlock(); 271 | 272 | m_TextDocument->setModified( isModified ); 273 | m_CurrentlyApplying = false; 274 | } 275 | 276 | bool QrwEmoticonsPrivate::loadPlugin(const QString & id, bool dynamic) 277 | { 278 | if( id.length() > 0 && m_Plugin.metaData.value(QStringLiteral("id")).toString() == id ) 279 | return true; 280 | 281 | if( m_PluginLoader.isLoaded() ) 282 | { 283 | m_PluginLoader.unload(); 284 | m_Plugin.clear(); 285 | } 286 | 287 | if ( !id.isEmpty() && !dynamic ) { 288 | const auto staticInstances = QPluginLoader::staticInstances(); 289 | for (QObject *plugin : staticInstances) { 290 | QrwEmoticonsPluginInterface* pluginInterface = qobject_cast(plugin); 291 | m_Plugin.interf = pluginInterface; 292 | return true; 293 | } 294 | } 295 | 296 | QStringList pluginPaths = QStringList() 297 | << QCoreApplication::applicationDirPath() 298 | #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) 299 | << QLibraryInfo::location(QLibraryInfo::PluginsPath) 300 | #else 301 | << QLibraryInfo::path(QLibraryInfo::PluginsPath) 302 | #endif 303 | << QCoreApplication::libraryPaths(); 304 | 305 | for( int p = 0; p < pluginPaths.count(); ++p ) 306 | { 307 | QString path = pluginPaths.at(p) % QStringLiteral("/emoticons"); 308 | QDir dir(path); 309 | if( !dir.exists(path) ) 310 | continue; 311 | 312 | QStringList files = dir.entryList(QDir::Files); 313 | for( int f = 0; f < files.count(); ++f ) 314 | { 315 | QString fileName = files.at(f); 316 | 317 | m_PluginLoader.setFileName( dir.absoluteFilePath(fileName) ); 318 | 319 | if( m_PluginLoader.metaData().value("IID").toString() != QrwEmoticonsPluginInterface_iid ) 320 | continue; 321 | 322 | QJsonObject metaData = m_PluginLoader.metaData().value("MetaData").toObject(); 323 | if( !id.isEmpty() && metaData.value(QStringLiteral("id")).toString() != id ) 324 | continue; 325 | 326 | if( m_PluginLoader.load() ) 327 | { 328 | if( QrwEmoticonsPluginInterface* pluginInterface = qobject_cast(m_PluginLoader.instance()) ) 329 | { 330 | m_Plugin.interf = pluginInterface; 331 | m_Plugin.metaData = metaData; 332 | return true; 333 | } 334 | } 335 | } 336 | } 337 | 338 | return false; 339 | } 340 | 341 | int QrwEmoticonsPrivate::getLineHeight(int posInDocument, const QTextFormat & format) const 342 | { 343 | switch( format.type() ) 344 | { 345 | case QTextFormat::BlockFormat: 346 | { 347 | QTextBlockFormat blockFormat = format.toBlockFormat(); 348 | //return int(blockFormat.lineHeight()); 349 | 350 | QTextBlock block = m_TextDocument->findBlock(posInDocument); 351 | int h = qRound(block.layout()->lineAt(0).height()); 352 | 353 | qDebug() << blockFormat.lineHeight() << h; 354 | return h; 355 | } 356 | case QTextFormat::CharFormat: 357 | { 358 | QTextCharFormat charFormat = format.toCharFormat(); 359 | QFont font = charFormat.font(); 360 | 361 | int h = font.pixelSize(); 362 | if( h == -1 ) 363 | h = qRound(font.pointSizeF() * 1.33333); // pt -> px 364 | 365 | return h; 366 | } 367 | default: 368 | Q_ASSERT( false ); 369 | return 20; 370 | } 371 | } 372 | -------------------------------------------------------------------------------- /QrwEmoticons/lib/src/QrwEmoticons_p.h: -------------------------------------------------------------------------------- 1 | #ifndef QRWEMOTICONS_P_H 2 | #define QRWEMOTICONS_P_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | typedef QSet EmoticonsData; 10 | 11 | class QrwEmoticonsPrivate : public QObject 12 | { 13 | Q_OBJECT 14 | 15 | QRWEMOTICONS_DECLARE_PUBLIC(QrwEmoticons) 16 | 17 | friend class QrwEmoticonsTextObjectInterface; 18 | 19 | public: 20 | ~QrwEmoticonsPrivate(); 21 | 22 | enum TextFormatProperty { 23 | EmoticonUnicode = QTextFormat::UserProperty, 24 | EmoticonImagePath, 25 | EmoticonQString 26 | }; 27 | Q_ENUMS(TextFormatProperty) 28 | 29 | static QString GetEmoticonString( const QrwEmoticons::Emoticon & code ); 30 | static QString GetEmoticonString( uint character ); 31 | 32 | protected Q_SLOTS: 33 | void onTextDocumentContentsChanged(int position, int charsRemoved, int charsAdded); 34 | 35 | protected: 36 | explicit QrwEmoticonsPrivate(QrwEmoticons*, QTextDocument*); 37 | 38 | static const EmoticonsData EMOTICONS; 39 | static const int EmoticonTextFormatObjectType = QTextFormat::UserObject + 0xEEEE; 40 | 41 | bool isEmoticon( uint character ); 42 | bool isEmoticon( const QrwEmoticons::Emoticon & code ); 43 | 44 | QrwEmoticons::Emoticon getEmoticonCode(QTextCursor c, int* selectionLength); 45 | 46 | QString getDocumentText( bool html = false ) const; 47 | QString getCursorText( const QTextCursor & cursor, bool html = false ) const; 48 | 49 | void applyTextCharFormat(int pos = 0); 50 | 51 | bool loadPlugin(const QString & id = QString(), bool dynamic = true); 52 | 53 | int getLineHeight(int posInDocument, const QTextFormat & format) const; 54 | 55 | protected: 56 | struct Plugin { 57 | QPointer interf; 58 | QJsonObject metaData; 59 | void clear() { 60 | interf = Q_NULLPTR; 61 | metaData = QJsonObject(); 62 | } 63 | operator bool() const { 64 | return interf != Q_NULLPTR; 65 | } 66 | } m_Plugin; 67 | 68 | QPluginLoader m_PluginLoader; 69 | bool m_CurrentlyApplying; 70 | QTextDocument* m_TextDocument; 71 | quint8 m_MaxEmoticonCharCodeCount; 72 | QSize m_MinimumEmoticonSize; 73 | }; 74 | 75 | inline uint qHash(const QrwEmoticons::Emoticon &code, uint seed) 76 | { 77 | return qHash(QrwEmoticonsPrivate::GetEmoticonString(code), seed); 78 | } 79 | 80 | #endif //QRWEMOTICONS_P_H 81 | -------------------------------------------------------------------------------- /QrwEmoticons/lib/src/TextEdit.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | QrwEmoticonsTextEdit::QrwEmoticonsTextEdit(QWidget* parent) 6 | : QTextEdit(parent) 7 | { 8 | m_Emoticons = new QrwEmoticons(this->document(),this); 9 | } 10 | 11 | QString QrwEmoticonsTextEdit::toHtml() const 12 | { 13 | return m_Emoticons->getHtml(); 14 | } 15 | 16 | QString QrwEmoticonsTextEdit::toPlainText() const 17 | { 18 | return m_Emoticons->getPlainText(); 19 | } 20 | 21 | QrwEmoticons* QrwEmoticonsTextEdit::emoticons() const 22 | { 23 | return m_Emoticons; 24 | } 25 | 26 | void QrwEmoticonsTextEdit::relayout() 27 | { 28 | QTextDocument* doc = this->document(); 29 | doc->markContentsDirty(0, doc->toPlainText().length()); 30 | } 31 | 32 | QMimeData* QrwEmoticonsTextEdit::createMimeDataFromSelection() const 33 | { 34 | QTextCursor cursor = this->textCursor(); 35 | if( NOT cursor.hasSelection() ) 36 | return Q_NULLPTR; 37 | 38 | const QString htmlText = m_Emoticons->getHtml( cursor ); 39 | const QString plainText = m_Emoticons->getPlainText( cursor ); 40 | 41 | QMimeData* data = new QMimeData; 42 | data->setHtml( htmlText ); 43 | data->setText( plainText ); 44 | return data; 45 | } 46 | 47 | /* 48 | QString stripQtTags( const QString & html ) 49 | { 50 | // strip html - only get contents between ... tags 51 | int start = html.indexOf( QLatin1String(""), -1, Qt::CaseInsensitive ); 53 | return html.mid( start, end-start+4 ); 54 | } 55 | */ 56 | -------------------------------------------------------------------------------- /QrwEmoticons/plugin-openmoji/emoticons_openmoji.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | openmoji/color/svg/1F535.svg 4 | openmoji/color/svg/1F7E2.svg 5 | openmoji/color/svg/26A0.svg 6 | openmoji/color/svg/2B50.svg 7 | 8 | 9 | -------------------------------------------------------------------------------- /QrwEmoticons/plugin-openmoji/openmoji/LICENSE.txt: -------------------------------------------------------------------------------- 1 | Attribution-ShareAlike 4.0 International 2 | 3 | ======================================================================= 4 | 5 | Creative Commons Corporation ("Creative Commons") is not a law firm and 6 | does not provide legal services or legal advice. Distribution of 7 | Creative Commons public licenses does not create a lawyer-client or 8 | other relationship. Creative Commons makes its licenses and related 9 | information available on an "as-is" basis. Creative Commons gives no 10 | warranties regarding its licenses, any material licensed under their 11 | terms and conditions, or any related information. Creative Commons 12 | disclaims all liability for damages resulting from their use to the 13 | fullest extent possible. 14 | 15 | Using Creative Commons Public Licenses 16 | 17 | Creative Commons public licenses provide a standard set of terms and 18 | conditions that creators and other rights holders may use to share 19 | original works of authorship and other material subject to copyright 20 | and certain other rights specified in the public license below. The 21 | following considerations are for informational purposes only, are not 22 | exhaustive, and do not form part of our licenses. 23 | 24 | Considerations for licensors: Our public licenses are 25 | intended for use by those authorized to give the public 26 | permission to use material in ways otherwise restricted by 27 | copyright and certain other rights. Our licenses are 28 | irrevocable. Licensors should read and understand the terms 29 | and conditions of the license they choose before applying it. 30 | Licensors should also secure all rights necessary before 31 | applying our licenses so that the public can reuse the 32 | material as expected. Licensors should clearly mark any 33 | material not subject to the license. This includes other CC- 34 | licensed material, or material used under an exception or 35 | limitation to copyright. More considerations for licensors: 36 | wiki.creativecommons.org/Considerations_for_licensors 37 | 38 | Considerations for the public: By using one of our public 39 | licenses, a licensor grants the public permission to use the 40 | licensed material under specified terms and conditions. If 41 | the licensor's permission is not necessary for any reason--for 42 | example, because of any applicable exception or limitation to 43 | copyright--then that use is not regulated by the license. Our 44 | licenses grant only permissions under copyright and certain 45 | other rights that a licensor has authority to grant. Use of 46 | the licensed material may still be restricted for other 47 | reasons, including because others have copyright or other 48 | rights in the material. A licensor may make special requests, 49 | such as asking that all changes be marked or described. 50 | Although not required by our licenses, you are encouraged to 51 | respect those requests where reasonable. More considerations 52 | for the public: 53 | wiki.creativecommons.org/Considerations_for_licensees 54 | 55 | ======================================================================= 56 | 57 | Creative Commons Attribution-ShareAlike 4.0 International Public 58 | License 59 | 60 | By exercising the Licensed Rights (defined below), You accept and agree 61 | to be bound by the terms and conditions of this Creative Commons 62 | Attribution-ShareAlike 4.0 International Public License ("Public 63 | License"). To the extent this Public License may be interpreted as a 64 | contract, You are granted the Licensed Rights in consideration of Your 65 | acceptance of these terms and conditions, and the Licensor grants You 66 | such rights in consideration of benefits the Licensor receives from 67 | making the Licensed Material available under these terms and 68 | conditions. 69 | 70 | 71 | Section 1 -- Definitions. 72 | 73 | a. Adapted Material means material subject to Copyright and Similar 74 | Rights that is derived from or based upon the Licensed Material 75 | and in which the Licensed Material is translated, altered, 76 | arranged, transformed, or otherwise modified in a manner requiring 77 | permission under the Copyright and Similar Rights held by the 78 | Licensor. For purposes of this Public License, where the Licensed 79 | Material is a musical work, performance, or sound recording, 80 | Adapted Material is always produced where the Licensed Material is 81 | synched in timed relation with a moving image. 82 | 83 | b. Adapter's License means the license You apply to Your Copyright 84 | and Similar Rights in Your contributions to Adapted Material in 85 | accordance with the terms and conditions of this Public License. 86 | 87 | c. BY-SA Compatible License means a license listed at 88 | creativecommons.org/compatiblelicenses, approved by Creative 89 | Commons as essentially the equivalent of this Public License. 90 | 91 | d. Copyright and Similar Rights means copyright and/or similar rights 92 | closely related to copyright including, without limitation, 93 | performance, broadcast, sound recording, and Sui Generis Database 94 | Rights, without regard to how the rights are labeled or 95 | categorized. For purposes of this Public License, the rights 96 | specified in Section 2(b)(1)-(2) are not Copyright and Similar 97 | Rights. 98 | 99 | e. Effective Technological Measures means those measures that, in the 100 | absence of proper authority, may not be circumvented under laws 101 | fulfilling obligations under Article 11 of the WIPO Copyright 102 | Treaty adopted on December 20, 1996, and/or similar international 103 | agreements. 104 | 105 | f. Exceptions and Limitations means fair use, fair dealing, and/or 106 | any other exception or limitation to Copyright and Similar Rights 107 | that applies to Your use of the Licensed Material. 108 | 109 | g. License Elements means the license attributes listed in the name 110 | of a Creative Commons Public License. The License Elements of this 111 | Public License are Attribution and ShareAlike. 112 | 113 | h. Licensed Material means the artistic or literary work, database, 114 | or other material to which the Licensor applied this Public 115 | License. 116 | 117 | i. Licensed Rights means the rights granted to You subject to the 118 | terms and conditions of this Public License, which are limited to 119 | all Copyright and Similar Rights that apply to Your use of the 120 | Licensed Material and that the Licensor has authority to license. 121 | 122 | j. Licensor means the individual(s) or entity(ies) granting rights 123 | under this Public License. 124 | 125 | k. Share means to provide material to the public by any means or 126 | process that requires permission under the Licensed Rights, such 127 | as reproduction, public display, public performance, distribution, 128 | dissemination, communication, or importation, and to make material 129 | available to the public including in ways that members of the 130 | public may access the material from a place and at a time 131 | individually chosen by them. 132 | 133 | l. Sui Generis Database Rights means rights other than copyright 134 | resulting from Directive 96/9/EC of the European Parliament and of 135 | the Council of 11 March 1996 on the legal protection of databases, 136 | as amended and/or succeeded, as well as other essentially 137 | equivalent rights anywhere in the world. 138 | 139 | m. You means the individual or entity exercising the Licensed Rights 140 | under this Public License. Your has a corresponding meaning. 141 | 142 | 143 | Section 2 -- Scope. 144 | 145 | a. License grant. 146 | 147 | 1. Subject to the terms and conditions of this Public License, 148 | the Licensor hereby grants You a worldwide, royalty-free, 149 | non-sublicensable, non-exclusive, irrevocable license to 150 | exercise the Licensed Rights in the Licensed Material to: 151 | 152 | a. reproduce and Share the Licensed Material, in whole or 153 | in part; and 154 | 155 | b. produce, reproduce, and Share Adapted Material. 156 | 157 | 2. Exceptions and Limitations. For the avoidance of doubt, where 158 | Exceptions and Limitations apply to Your use, this Public 159 | License does not apply, and You do not need to comply with 160 | its terms and conditions. 161 | 162 | 3. Term. The term of this Public License is specified in Section 163 | 6(a). 164 | 165 | 4. Media and formats; technical modifications allowed. The 166 | Licensor authorizes You to exercise the Licensed Rights in 167 | all media and formats whether now known or hereafter created, 168 | and to make technical modifications necessary to do so. The 169 | Licensor waives and/or agrees not to assert any right or 170 | authority to forbid You from making technical modifications 171 | necessary to exercise the Licensed Rights, including 172 | technical modifications necessary to circumvent Effective 173 | Technological Measures. For purposes of this Public License, 174 | simply making modifications authorized by this Section 2(a) 175 | (4) never produces Adapted Material. 176 | 177 | 5. Downstream recipients. 178 | 179 | a. Offer from the Licensor -- Licensed Material. Every 180 | recipient of the Licensed Material automatically 181 | receives an offer from the Licensor to exercise the 182 | Licensed Rights under the terms and conditions of this 183 | Public License. 184 | 185 | b. Additional offer from the Licensor -- Adapted Material. 186 | Every recipient of Adapted Material from You 187 | automatically receives an offer from the Licensor to 188 | exercise the Licensed Rights in the Adapted Material 189 | under the conditions of the Adapter's License You apply. 190 | 191 | c. No downstream restrictions. You may not offer or impose 192 | any additional or different terms or conditions on, or 193 | apply any Effective Technological Measures to, the 194 | Licensed Material if doing so restricts exercise of the 195 | Licensed Rights by any recipient of the Licensed 196 | Material. 197 | 198 | 6. No endorsement. Nothing in this Public License constitutes or 199 | may be construed as permission to assert or imply that You 200 | are, or that Your use of the Licensed Material is, connected 201 | with, or sponsored, endorsed, or granted official status by, 202 | the Licensor or others designated to receive attribution as 203 | provided in Section 3(a)(1)(A)(i). 204 | 205 | b. Other rights. 206 | 207 | 1. Moral rights, such as the right of integrity, are not 208 | licensed under this Public License, nor are publicity, 209 | privacy, and/or other similar personality rights; however, to 210 | the extent possible, the Licensor waives and/or agrees not to 211 | assert any such rights held by the Licensor to the limited 212 | extent necessary to allow You to exercise the Licensed 213 | Rights, but not otherwise. 214 | 215 | 2. Patent and trademark rights are not licensed under this 216 | Public License. 217 | 218 | 3. To the extent possible, the Licensor waives any right to 219 | collect royalties from You for the exercise of the Licensed 220 | Rights, whether directly or through a collecting society 221 | under any voluntary or waivable statutory or compulsory 222 | licensing scheme. In all other cases the Licensor expressly 223 | reserves any right to collect such royalties. 224 | 225 | 226 | Section 3 -- License Conditions. 227 | 228 | Your exercise of the Licensed Rights is expressly made subject to the 229 | following conditions. 230 | 231 | a. Attribution. 232 | 233 | 1. If You Share the Licensed Material (including in modified 234 | form), You must: 235 | 236 | a. retain the following if it is supplied by the Licensor 237 | with the Licensed Material: 238 | 239 | i. identification of the creator(s) of the Licensed 240 | Material and any others designated to receive 241 | attribution, in any reasonable manner requested by 242 | the Licensor (including by pseudonym if 243 | designated); 244 | 245 | ii. a copyright notice; 246 | 247 | iii. a notice that refers to this Public License; 248 | 249 | iv. a notice that refers to the disclaimer of 250 | warranties; 251 | 252 | v. a URI or hyperlink to the Licensed Material to the 253 | extent reasonably practicable; 254 | 255 | b. indicate if You modified the Licensed Material and 256 | retain an indication of any previous modifications; and 257 | 258 | c. indicate the Licensed Material is licensed under this 259 | Public License, and include the text of, or the URI or 260 | hyperlink to, this Public License. 261 | 262 | 2. You may satisfy the conditions in Section 3(a)(1) in any 263 | reasonable manner based on the medium, means, and context in 264 | which You Share the Licensed Material. For example, it may be 265 | reasonable to satisfy the conditions by providing a URI or 266 | hyperlink to a resource that includes the required 267 | information. 268 | 269 | 3. If requested by the Licensor, You must remove any of the 270 | information required by Section 3(a)(1)(A) to the extent 271 | reasonably practicable. 272 | 273 | b. ShareAlike. 274 | 275 | In addition to the conditions in Section 3(a), if You Share 276 | Adapted Material You produce, the following conditions also apply. 277 | 278 | 1. The Adapter's License You apply must be a Creative Commons 279 | license with the same License Elements, this version or 280 | later, or a BY-SA Compatible License. 281 | 282 | 2. You must include the text of, or the URI or hyperlink to, the 283 | Adapter's License You apply. You may satisfy this condition 284 | in any reasonable manner based on the medium, means, and 285 | context in which You Share Adapted Material. 286 | 287 | 3. You may not offer or impose any additional or different terms 288 | or conditions on, or apply any Effective Technological 289 | Measures to, Adapted Material that restrict exercise of the 290 | rights granted under the Adapter's License You apply. 291 | 292 | 293 | Section 4 -- Sui Generis Database Rights. 294 | 295 | Where the Licensed Rights include Sui Generis Database Rights that 296 | apply to Your use of the Licensed Material: 297 | 298 | a. for the avoidance of doubt, Section 2(a)(1) grants You the right 299 | to extract, reuse, reproduce, and Share all or a substantial 300 | portion of the contents of the database; 301 | 302 | b. if You include all or a substantial portion of the database 303 | contents in a database in which You have Sui Generis Database 304 | Rights, then the database in which You have Sui Generis Database 305 | Rights (but not its individual contents) is Adapted Material, 306 | 307 | including for purposes of Section 3(b); and 308 | c. You must comply with the conditions in Section 3(a) if You Share 309 | all or a substantial portion of the contents of the database. 310 | 311 | For the avoidance of doubt, this Section 4 supplements and does not 312 | replace Your obligations under this Public License where the Licensed 313 | Rights include other Copyright and Similar Rights. 314 | 315 | 316 | Section 5 -- Disclaimer of Warranties and Limitation of Liability. 317 | 318 | a. UNLESS OTHERWISE SEPARATELY UNDERTAKEN BY THE LICENSOR, TO THE 319 | EXTENT POSSIBLE, THE LICENSOR OFFERS THE LICENSED MATERIAL AS-IS 320 | AND AS-AVAILABLE, AND MAKES NO REPRESENTATIONS OR WARRANTIES OF 321 | ANY KIND CONCERNING THE LICENSED MATERIAL, WHETHER EXPRESS, 322 | IMPLIED, STATUTORY, OR OTHER. THIS INCLUDES, WITHOUT LIMITATION, 323 | WARRANTIES OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR 324 | PURPOSE, NON-INFRINGEMENT, ABSENCE OF LATENT OR OTHER DEFECTS, 325 | ACCURACY, OR THE PRESENCE OR ABSENCE OF ERRORS, WHETHER OR NOT 326 | KNOWN OR DISCOVERABLE. WHERE DISCLAIMERS OF WARRANTIES ARE NOT 327 | ALLOWED IN FULL OR IN PART, THIS DISCLAIMER MAY NOT APPLY TO YOU. 328 | 329 | b. TO THE EXTENT POSSIBLE, IN NO EVENT WILL THE LICENSOR BE LIABLE 330 | TO YOU ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION, 331 | NEGLIGENCE) OR OTHERWISE FOR ANY DIRECT, SPECIAL, INDIRECT, 332 | INCIDENTAL, CONSEQUENTIAL, PUNITIVE, EXEMPLARY, OR OTHER LOSSES, 333 | COSTS, EXPENSES, OR DAMAGES ARISING OUT OF THIS PUBLIC LICENSE OR 334 | USE OF THE LICENSED MATERIAL, EVEN IF THE LICENSOR HAS BEEN 335 | ADVISED OF THE POSSIBILITY OF SUCH LOSSES, COSTS, EXPENSES, OR 336 | DAMAGES. WHERE A LIMITATION OF LIABILITY IS NOT ALLOWED IN FULL OR 337 | IN PART, THIS LIMITATION MAY NOT APPLY TO YOU. 338 | 339 | c. The disclaimer of warranties and limitation of liability provided 340 | above shall be interpreted in a manner that, to the extent 341 | possible, most closely approximates an absolute disclaimer and 342 | waiver of all liability. 343 | 344 | 345 | Section 6 -- Term and Termination. 346 | 347 | a. This Public License applies for the term of the Copyright and 348 | Similar Rights licensed here. However, if You fail to comply with 349 | this Public License, then Your rights under this Public License 350 | terminate automatically. 351 | 352 | b. Where Your right to use the Licensed Material has terminated under 353 | Section 6(a), it reinstates: 354 | 355 | 1. automatically as of the date the violation is cured, provided 356 | it is cured within 30 days of Your discovery of the 357 | violation; or 358 | 359 | 2. upon express reinstatement by the Licensor. 360 | 361 | For the avoidance of doubt, this Section 6(b) does not affect any 362 | right the Licensor may have to seek remedies for Your violations 363 | of this Public License. 364 | 365 | c. For the avoidance of doubt, the Licensor may also offer the 366 | Licensed Material under separate terms or conditions or stop 367 | distributing the Licensed Material at any time; however, doing so 368 | will not terminate this Public License. 369 | 370 | d. Sections 1, 5, 6, 7, and 8 survive termination of this Public 371 | License. 372 | 373 | 374 | Section 7 -- Other Terms and Conditions. 375 | 376 | a. The Licensor shall not be bound by any additional or different 377 | terms or conditions communicated by You unless expressly agreed. 378 | 379 | b. Any arrangements, understandings, or agreements regarding the 380 | Licensed Material not stated herein are separate from and 381 | independent of the terms and conditions of this Public License. 382 | 383 | 384 | Section 8 -- Interpretation. 385 | 386 | a. For the avoidance of doubt, this Public License does not, and 387 | shall not be interpreted to, reduce, limit, restrict, or impose 388 | conditions on any use of the Licensed Material that could lawfully 389 | be made without permission under this Public License. 390 | 391 | b. To the extent possible, if any provision of this Public License is 392 | deemed unenforceable, it shall be automatically reformed to the 393 | minimum extent necessary to make it enforceable. If the provision 394 | cannot be reformed, it shall be severed from this Public License 395 | without affecting the enforceability of the remaining terms and 396 | conditions. 397 | 398 | c. No term or condition of this Public License will be waived and no 399 | failure to comply consented to unless expressly agreed to by the 400 | Licensor. 401 | 402 | d. Nothing in this Public License constitutes or may be interpreted 403 | as a limitation upon, or waiver of, any privileges and immunities 404 | that apply to the Licensor or You, including from the legal 405 | processes of any jurisdiction or authority. 406 | 407 | 408 | ======================================================================= 409 | 410 | Creative Commons is not a party to its public 411 | licenses. Notwithstanding, Creative Commons may elect to apply one of 412 | its public licenses to material it publishes and in those instances 413 | will be considered the “Licensor.” The text of the Creative Commons 414 | public licenses is dedicated to the public domain under the CC0 Public 415 | Domain Dedication. Except for the limited purpose of indicating that 416 | material is shared under a Creative Commons public license or as 417 | otherwise permitted by the Creative Commons policies published at 418 | creativecommons.org/policies, Creative Commons does not authorize the 419 | use of the trademark "Creative Commons" or any other trademark or logo 420 | of Creative Commons without its prior written consent including, 421 | without limitation, in connection with any unauthorized modifications 422 | to any of its public licenses or any other arrangements, 423 | understandings, or agreements concerning use of licensed material. For 424 | the avoidance of doubt, this paragraph does not form part of the 425 | public licenses. 426 | 427 | Creative Commons may be contacted at creativecommons.org. 428 | -------------------------------------------------------------------------------- /QrwEmoticons/plugin-openmoji/openmoji/README.md: -------------------------------------------------------------------------------- 1 | OpenMoji 2 | ======== 3 | 4 | Open-source emojis for designers, developers and everyone else! OpenMoji is an open-source project of the HfG Schwäbisch Gmünd by Benedikt Groß, Daniel Utz, 70+ students and external contributors. 5 | 6 | 👉 [OpenMoji.org/](http://openmoji.org/) 7 | 8 | ## Attribution Requirements 9 | As an open source project, attribution is critical from a legal, practical and motivational perspective. Please give us credits! Common places for attribution are for example: to mention us in your project README, the 'About' section or the footer on a website/in mobile apps. 10 | 11 | ## License 12 | ¹ OpenMoji graphics are licensed under the Creative Commons Share Alike License 4.0 ([CC BY-SA 4.0](https://creativecommons.org/licenses/by-sa/4.0/)) 13 | 14 | [![License: CC BY-SA 4.0](https://img.shields.io/badge/License-CC%20BY--SA%204.0-lightgrey.svg)](https://creativecommons.org/licenses/by-sa/4.0/) 15 | -------------------------------------------------------------------------------- /QrwEmoticons/plugin-openmoji/openmoji/color/72x72/1F535.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/afbjorklund/lima-gui/4b46e8509ca9b7ff97f2daa596d0ee13403ae0ed/QrwEmoticons/plugin-openmoji/openmoji/color/72x72/1F535.png -------------------------------------------------------------------------------- /QrwEmoticons/plugin-openmoji/openmoji/color/72x72/1F7E2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/afbjorklund/lima-gui/4b46e8509ca9b7ff97f2daa596d0ee13403ae0ed/QrwEmoticons/plugin-openmoji/openmoji/color/72x72/1F7E2.png -------------------------------------------------------------------------------- /QrwEmoticons/plugin-openmoji/openmoji/color/72x72/26A0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/afbjorklund/lima-gui/4b46e8509ca9b7ff97f2daa596d0ee13403ae0ed/QrwEmoticons/plugin-openmoji/openmoji/color/72x72/26A0.png -------------------------------------------------------------------------------- /QrwEmoticons/plugin-openmoji/openmoji/color/72x72/2B50.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/afbjorklund/lima-gui/4b46e8509ca9b7ff97f2daa596d0ee13403ae0ed/QrwEmoticons/plugin-openmoji/openmoji/color/72x72/2B50.png -------------------------------------------------------------------------------- /QrwEmoticons/plugin-openmoji/openmoji/color/svg/1F535.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /QrwEmoticons/plugin-openmoji/openmoji/color/svg/1F7E2.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /QrwEmoticons/plugin-openmoji/openmoji/color/svg/26A0.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /QrwEmoticons/plugin-openmoji/openmoji/color/svg/2B50.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /QrwEmoticons/plugin-openmoji/openmoji/src/symbols/geometric/1F535.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /QrwEmoticons/plugin-openmoji/openmoji/src/symbols/geometric/1F7E2.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /QrwEmoticons/plugin-openmoji/openmoji/src/symbols/warning/26A0.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /QrwEmoticons/plugin-openmoji/openmoji/src/travel-places/sky-weather/2B50.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /QrwEmoticons/plugin-openmoji/plugin-openmoji.pro: -------------------------------------------------------------------------------- 1 | TEMPLATE = lib 2 | CONFIG += plugin 3 | CONFIG += static 4 | QT += core svg xml 5 | 6 | TARGET = $$qtLibraryTarget(emoticons_openmoji) 7 | 8 | RESOURCES += \ 9 | $$files(*.qrc) 10 | 11 | INCLUDEPATH += \ 12 | ../include \ 13 | ../shared/src 14 | 15 | HEADERS = \ 16 | src/plugin.h \ 17 | ../shared/src/QrwEmoticonsHelper.h 18 | 19 | SOURCES = \ 20 | src/plugin.cpp \ 21 | ../shared/src/QrwEmoticonsHelper.cpp 22 | 23 | OTHER_FILES = \ 24 | plugin.json 25 | -------------------------------------------------------------------------------- /QrwEmoticons/plugin-openmoji/plugin.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "openmoji", 3 | "name" : "OpenMoji Emoticons", 4 | "version" : "1.0.0", 5 | "author" : "raven-worx Software", 6 | "url" : "http://www.raven-worx.net", 7 | "copyright" : "(c)2021 raven-worx Software", 8 | "description" : "Emoticons provided by OpenMoji", 9 | "provider": { 10 | "sizes" : ["svg"], 11 | "name" : "OpenMoji", 12 | "url" : "http://www.openmoji.org" 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /QrwEmoticons/plugin-openmoji/src/plugin.cpp: -------------------------------------------------------------------------------- 1 | #include "plugin.h" 2 | #include 3 | 4 | EmoticonOpenmojiPlugin::EmoticonOpenmojiPlugin(QObject* parent) 5 | : QrwEmoticonsPluginInterface(parent) 6 | { 7 | //Q_INIT_RESOURCE(emoticons_openmoji_X); 8 | } 9 | 10 | EmoticonOpenmojiPlugin::~EmoticonOpenmojiPlugin() 11 | { 12 | //Q_CLEANUP_RESOURCE(emoticons_openmoji_X); 13 | } 14 | 15 | QString EmoticonOpenmojiPlugin::getEmoticonPath(const QrwEmoticons::Emoticon &code) const 16 | { 17 | // OpenMoji doesn't add variation selectors (0xFE0E and 0xFE0F) to their filenames?! 18 | QrwEmoticons::Emoticon c = code; 19 | c.removeAll(0xFE0E); 20 | c.removeAll(0xFE0F); 21 | return QStringLiteral(":/QrwEmoticons/openmoji/") % EMOTICON_FILENAME(c) % QStringLiteral(".svg"); 22 | } 23 | 24 | bool EmoticonOpenmojiPlugin::hasEmoticon(const QrwEmoticons::Emoticon & code) 25 | { 26 | const QString fileName = this->getEmoticonPath(code); 27 | return QFile::exists(fileName); 28 | } 29 | 30 | QPixmap EmoticonOpenmojiPlugin::getEmoticon(const QrwEmoticons::Emoticon & code, const QSize & size) 31 | { 32 | const QString fileName = this->getEmoticonPath(code); 33 | QPixmap pix = QrwEmoticonsHelper::SvgToPixmap(fileName, size); 34 | return pix; 35 | } 36 | -------------------------------------------------------------------------------- /QrwEmoticons/plugin-openmoji/src/plugin.h: -------------------------------------------------------------------------------- 1 | #ifndef EMOTICON_OPENMOJI_PLUGIN_H 2 | #define EMOTICON_OPENMOJI_PLUGIN_H 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | class EmoticonOpenmojiPlugin : public QrwEmoticonsPluginInterface 9 | { 10 | Q_OBJECT 11 | Q_PLUGIN_METADATA(IID QrwEmoticonsPluginInterface_iid FILE "plugin.json") 12 | Q_INTERFACES(QrwEmoticonsPluginInterface) 13 | 14 | public: 15 | explicit EmoticonOpenmojiPlugin(QObject *parent = nullptr); 16 | ~EmoticonOpenmojiPlugin(); 17 | 18 | virtual bool hasEmoticon(const QrwEmoticons::Emoticon & code) Q_DECL_OVERRIDE; 19 | virtual QPixmap getEmoticon(const QrwEmoticons::Emoticon & code, const QSize & size) Q_DECL_OVERRIDE; 20 | 21 | private: 22 | QString getEmoticonPath(const QrwEmoticons::Emoticon &code) const; 23 | }; 24 | 25 | #endif // EMOTICON_OPENMOJI_PLUGIN_H 26 | -------------------------------------------------------------------------------- /QrwEmoticons/shared/src/QrwEmoticonsHelper.cpp: -------------------------------------------------------------------------------- 1 | #include "QrwEmoticonsHelper.h" 2 | #include 3 | #include 4 | #include 5 | 6 | QByteArray QrwEmoticonsHelper::SvgPrepare(const QString &fileName) 7 | { 8 | QDomDocument doc; 9 | QFile file(fileName); 10 | if (!file.open(QIODevice::ReadOnly) || !doc.setContent(&file)) 11 | return QByteArray(); 12 | 13 | /* 14 | * QSvgRenderer fill certain elements with "black" if they are not 15 | * explicitly filled 16 | */ 17 | 18 | const QString fillKey = QStringLiteral("fill"); 19 | const QString fillValue = QStringLiteral("transparent"); 20 | 21 | QDomNodeList pathElements = doc.elementsByTagName( QStringLiteral("path") ); 22 | for( int i = 0; i < pathElements.size(); i++ ) 23 | { 24 | QDomElement e = pathElements.item(i).toElement(); 25 | if( !e.hasAttribute(fillKey) ) 26 | e.setAttribute(fillKey, fillValue); 27 | } 28 | QDomNodeList rectElements = doc.elementsByTagName( QStringLiteral("rect") ); 29 | for( int i = 0; i < rectElements.size(); i++ ) 30 | { 31 | QDomElement e = rectElements.item(i).toElement(); 32 | if( !e.hasAttribute(fillKey) ) 33 | e.setAttribute(fillKey, fillValue); 34 | } 35 | return doc.toByteArray(); 36 | } 37 | 38 | QPixmap QrwEmoticonsHelper::SvgToPixmap(const QString & fileName, const QSize & size) 39 | { 40 | QPixmap pix; 41 | const QString cacheKey = fileName % QStringLiteral("@%1x%2").arg(size.width()).arg(size.height()); 42 | if( !QPixmapCache::find(cacheKey, &pix) ) 43 | { 44 | if( QFile::exists(fileName) ) 45 | { 46 | const QByteArray svg = QrwEmoticonsHelper::SvgPrepare(fileName); 47 | QSvgRenderer renderer(svg); 48 | if( renderer.isValid() ) 49 | { 50 | pix = QPixmap(size); 51 | pix.fill(Qt::transparent); 52 | 53 | QPainter pixPainter(&pix); 54 | renderer.render(&pixPainter, QRectF()); // bounding rectangle is not specified the SVG file is mapped to the whole paint device 55 | 56 | pixPainter.end(); 57 | 58 | QPixmapCache::insert(cacheKey, pix); 59 | } 60 | } 61 | } 62 | return pix; 63 | } 64 | -------------------------------------------------------------------------------- /QrwEmoticons/shared/src/QrwEmoticonsHelper.h: -------------------------------------------------------------------------------- 1 | #ifndef QRWEMOTICONS_HELPER_H 2 | #define QRWEMOTICONS_HELPER_H 3 | 4 | #include 5 | 6 | namespace QrwEmoticonsHelper 7 | { 8 | QByteArray SvgPrepare(const QString & fileName); 9 | QPixmap SvgToPixmap(const QString & fileName, const QSize & size); 10 | }; 11 | 12 | #endif //QRWEMOTICONS_HELPER_H 13 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Lima GUI 2 | 3 | See 4 | 5 | ## Running 6 | 7 | Open in [Qt Creator](https://doc.qt.io/qtcreator/) GUI: 8 | 9 | ```shell 10 | qtcreator systray.pro 11 | ``` 12 | 13 | Or on the command line: 14 | 15 | ```console 16 | $ qmake 17 | $ make 18 | ... 19 | $ ./lima-gui 20 | ``` 21 | 22 | ## Screenshots 23 | 24 | ### Main window 25 | 26 | ![screenshot](assets/screenshot1.png) 27 | 28 | #### Create 29 | 30 | ![screenshot](assets/screenshot2.png) 31 | 32 | #### Remove 33 | 34 | ![screenshot](assets/screenshot3.png) 35 | 36 | ### Themes 37 | 38 | You can use [Kvantum](https://github.com/tsujan/Kvantum), for theme support. 39 | It has several themes: 40 | 41 | ![kvantum light](assets/lima-gui-quick-start.light.png) 42 | 43 | ![kvantum dark](assets/lima-gui-quick-start.dark.png) 44 | 45 | `QT_STYLE_OVERRIDE=kvantum` (or use `kvantummanager` GUI) 46 | 47 | ---- 48 | 49 | See 50 | 51 | Tux icon from the Crystal project by Everaldo Coelho. 52 | The icons are licensed under the GNU Lesser General Public License (LGPL). 53 | 54 | ## Optional 55 | 56 | These features are optional, and can be disabled or enabled in build: 57 | 58 | * QTermWidget (default: off) 59 | * QrwEmoticons (default: on) 60 | * QSourceHighlite (default: on) 61 | * QVNCClient (default: on) 62 | 63 | The QTermWidget has a GPL-2+ license, and is not included by default. 64 | 65 | The default is to start the regular terminal application, externally. 66 | 67 | If you don't have a terminal application, there is one available here: 68 | 69 | * QTerminal (under GPL-2+ license) 70 | -------------------------------------------------------------------------------- /assets/lima-gui-quick-start.dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/afbjorklund/lima-gui/4b46e8509ca9b7ff97f2daa596d0ee13403ae0ed/assets/lima-gui-quick-start.dark.png -------------------------------------------------------------------------------- /assets/lima-gui-quick-start.light.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/afbjorklund/lima-gui/4b46e8509ca9b7ff97f2daa596d0ee13403ae0ed/assets/lima-gui-quick-start.light.png -------------------------------------------------------------------------------- /assets/screenshot1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/afbjorklund/lima-gui/4b46e8509ca9b7ff97f2daa596d0ee13403ae0ed/assets/screenshot1.png -------------------------------------------------------------------------------- /assets/screenshot2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/afbjorklund/lima-gui/4b46e8509ca9b7ff97f2daa596d0ee13403ae0ed/assets/screenshot2.png -------------------------------------------------------------------------------- /assets/screenshot3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/afbjorklund/lima-gui/4b46e8509ca9b7ff97f2daa596d0ee13403ae0ed/assets/screenshot3.png -------------------------------------------------------------------------------- /contrib/README.md: -------------------------------------------------------------------------------- 1 | ## Profile for cool-retro-term 2 | 3 | 4 | 5 | Use with `TERMINAL=cool-retro-term` 6 | 7 | * [cool-retro-term-lima.json](cool-retro-term-lima.json) 8 | 9 | ![cool-retro-term lima](cool-retro-term-lima.jpg) 10 | -------------------------------------------------------------------------------- /contrib/cool-retro-term-lima.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/afbjorklund/lima-gui/4b46e8509ca9b7ff97f2daa596d0ee13403ae0ed/contrib/cool-retro-term-lima.jpg -------------------------------------------------------------------------------- /contrib/cool-retro-term-lima.json: -------------------------------------------------------------------------------- 1 | { 2 | "backgroundColor": "#000000", 3 | "fontColor": "#32cd32", 4 | "flickering": 0.1, 5 | "horizontalSync": 0.08, 6 | "staticNoise": 0.1198, 7 | "chromaColor": 0, 8 | "saturationColor": 0, 9 | "screenCurvature": 0.3, 10 | "glowingLine": 0, 11 | "burnIn": 0.2517, 12 | "bloom": 0.5538, 13 | "rasterization": 0, 14 | "jitter": 0.1997, 15 | "rbgShift": 0, 16 | "brightness": 0.5, 17 | "contrast": 0.7959, 18 | "ambientLight": 0.2, 19 | "windowOpacity": 1, 20 | "fontName": "TERMINUS_SCALED", 21 | "fontWidth": 1, 22 | "margin": 0.5, 23 | "blinkingCursor": false, 24 | "frameMargin": 0.1, 25 | "name": "Lima", 26 | "version": 2 27 | } 28 | -------------------------------------------------------------------------------- /icons/16x16/tux.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/afbjorklund/lima-gui/4b46e8509ca9b7ff97f2daa596d0ee13403ae0ed/icons/16x16/tux.png -------------------------------------------------------------------------------- /icons/256x256/tux.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/afbjorklund/lima-gui/4b46e8509ca9b7ff97f2daa596d0ee13403ae0ed/icons/256x256/tux.png -------------------------------------------------------------------------------- /icons/32x32/tux.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/afbjorklund/lima-gui/4b46e8509ca9b7ff97f2daa596d0ee13403ae0ed/icons/32x32/tux.png -------------------------------------------------------------------------------- /icons/48x48/tux.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/afbjorklund/lima-gui/4b46e8509ca9b7ff97f2daa596d0ee13403ae0ed/icons/48x48/tux.png -------------------------------------------------------------------------------- /icons/tux.icns: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/afbjorklund/lima-gui/4b46e8509ca9b7ff97f2daa596d0ee13403ae0ed/icons/tux.icns -------------------------------------------------------------------------------- /images/add.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/afbjorklund/lima-gui/4b46e8509ca9b7ff97f2daa596d0ee13403ae0ed/images/add.png -------------------------------------------------------------------------------- /images/advanced.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/afbjorklund/lima-gui/4b46e8509ca9b7ff97f2daa596d0ee13403ae0ed/images/advanced.png -------------------------------------------------------------------------------- /images/desktopshare.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/afbjorklund/lima-gui/4b46e8509ca9b7ff97f2daa596d0ee13403ae0ed/images/desktopshare.png -------------------------------------------------------------------------------- /images/help.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/afbjorklund/lima-gui/4b46e8509ca9b7ff97f2daa596d0ee13403ae0ed/images/help.png -------------------------------------------------------------------------------- /images/info.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/afbjorklund/lima-gui/4b46e8509ca9b7ff97f2daa596d0ee13403ae0ed/images/info.png -------------------------------------------------------------------------------- /images/player_start.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/afbjorklund/lima-gui/4b46e8509ca9b7ff97f2daa596d0ee13403ae0ed/images/player_start.png -------------------------------------------------------------------------------- /images/player_stop.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/afbjorklund/lima-gui/4b46e8509ca9b7ff97f2daa596d0ee13403ae0ed/images/player_stop.png -------------------------------------------------------------------------------- /images/quick.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/afbjorklund/lima-gui/4b46e8509ca9b7ff97f2daa596d0ee13403ae0ed/images/quick.png -------------------------------------------------------------------------------- /images/reload.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/afbjorklund/lima-gui/4b46e8509ca9b7ff97f2daa596d0ee13403ae0ed/images/reload.png -------------------------------------------------------------------------------- /images/remove.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/afbjorklund/lima-gui/4b46e8509ca9b7ff97f2daa596d0ee13403ae0ed/images/remove.png -------------------------------------------------------------------------------- /images/search.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/afbjorklund/lima-gui/4b46e8509ca9b7ff97f2daa596d0ee13403ae0ed/images/search.png -------------------------------------------------------------------------------- /images/terminal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/afbjorklund/lima-gui/4b46e8509ca9b7ff97f2daa596d0ee13403ae0ed/images/terminal.png -------------------------------------------------------------------------------- /images/tux.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/afbjorklund/lima-gui/4b46e8509ca9b7ff97f2daa596d0ee13403ae0ed/images/tux.png -------------------------------------------------------------------------------- /instance.cpp: -------------------------------------------------------------------------------- 1 | #include "instance.h" 2 | 3 | #include 4 | #include 5 | 6 | Instance::Instance(const QJsonObject &obj) : Instance() 7 | { 8 | QString name; 9 | if (obj.contains("name")) { 10 | name = obj["name"].toString(); 11 | } 12 | if (name.isEmpty()) { 13 | return; 14 | } 15 | m_name = name; 16 | 17 | if (obj.contains("status")) { 18 | QString status = obj["status"].toString(); 19 | setStatus(status); 20 | } 21 | if (obj.contains("dir")) { 22 | QString dir = obj["dir"].toString(); 23 | setDir(dir); 24 | } 25 | if (obj.contains("vmType")) { 26 | QString type = obj["vmType"].toString(); 27 | setVmType(type); 28 | } else { 29 | setVmType(QString()); 30 | } 31 | if (obj.contains("arch")) { 32 | QString arch = obj["arch"].toString(); 33 | setArch(arch); 34 | } 35 | if (obj.contains("cpuType")) { 36 | QString type = obj["cpuType"].toString(); 37 | setCpuType(type); 38 | } else { 39 | setCpuType(QString()); 40 | } 41 | if (obj.contains("cpus")) { 42 | int cpus = obj["cpus"].toInt(); 43 | setCpus(cpus); 44 | } 45 | if (obj.contains("memory")) { 46 | double memory = obj["memory"].toDouble(); 47 | setMemory((qint64)memory); 48 | } 49 | if (obj.contains("disk")) { 50 | double disk = obj["disk"].toDouble(); 51 | setDisk((qint64)disk); 52 | } 53 | if (obj.contains("sshAddress")) { 54 | QString addr = obj["sshAddress"].toString(); 55 | setSshAddress(addr); 56 | } else { 57 | setSshAddress("127.0.0.1"); 58 | } 59 | if (obj.contains("sshLocalPort")) { 60 | int port = obj["sshLocalPort"].toInt(); 61 | setSshLocalPort(port); 62 | } else { 63 | setSshLocalPort(0); 64 | } 65 | if (obj.contains("sshConfigFile")) { 66 | QString file = obj["sshConfigFile"].toString(); 67 | setSshConfigFile(file); 68 | } else { 69 | setSshConfigFile(""); 70 | } 71 | 72 | if (obj.contains("config")) { 73 | QJsonObject config = obj["config"].toObject(); 74 | setConfig(config.toVariantMap()); 75 | 76 | if (config.contains("mountType")) { 77 | QString type = config["mountType"].toString(); 78 | setMountType(type); 79 | } else { 80 | setMountType(QString()); 81 | } 82 | } 83 | } 84 | 85 | QString Instance::audioDevice() 86 | { 87 | QString device; 88 | if (config().contains("audio")) { 89 | QJsonObject audio = config()["audio"].toJsonObject(); 90 | if (audio.contains("device")) { 91 | device = audio["device"].toString(); 92 | } 93 | } 94 | return device; 95 | } 96 | 97 | QString Instance::videoDisplay() 98 | { 99 | QString display; 100 | if (config().contains("video")) { 101 | QJsonObject video = config()["video"].toJsonObject(); 102 | if (video.contains("display")) { 103 | display = video["display"].toString(); 104 | } 105 | } 106 | return display; 107 | } 108 | 109 | void InstanceModel::setInstances(const InstanceList &instances) 110 | { 111 | beginResetModel(); 112 | instanceList = instances; 113 | endResetModel(); 114 | } 115 | 116 | int InstanceModel::rowCount(const QModelIndex &) const 117 | { 118 | return instanceList.count(); 119 | } 120 | 121 | int InstanceModel::columnCount(const QModelIndex &) const 122 | { 123 | return 7; 124 | } 125 | 126 | static QStringList binaryAbbrs = { "B", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "ZiB", "YiB" }; 127 | 128 | // BytesSize returns a human-readable size in bytes, kibibytes, 129 | // mebibytes, gibibytes, or tebibytes (eg. "44kiB", "17MiB"). 130 | static QString bytesSize(qint64 size) 131 | { 132 | qint64 base = 1024; 133 | int i, unitsLimit = binaryAbbrs.size(); 134 | for (i = 0; size >= base && i < unitsLimit; i++) { 135 | size /= base; 136 | } 137 | return QString("%1 %2").arg(size, 4).arg(binaryAbbrs[i]); 138 | } 139 | 140 | QString Instance::strCpus() const 141 | { 142 | return QString::number(cpus()); 143 | } 144 | 145 | QString Instance::strMemory() const 146 | { 147 | return bytesSize(memory()); 148 | } 149 | 150 | QString Instance::strDisk() const 151 | { 152 | return bytesSize(disk()); 153 | } 154 | 155 | QVariant InstanceModel::data(const QModelIndex &index, int role) const 156 | { 157 | if (!index.isValid()) 158 | return QVariant(); 159 | 160 | if (index.row() >= rowCount(index)) 161 | return QVariant(); 162 | if (index.column() >= columnCount(index)) 163 | return QVariant(); 164 | 165 | Qt::Alignment nameColumnHAlign; 166 | if (m_quiet) 167 | nameColumnHAlign = Qt::AlignHCenter; 168 | else 169 | nameColumnHAlign = Qt::AlignLeft; 170 | 171 | if (role == Qt::TextAlignmentRole) { 172 | switch (index.column()) { 173 | case 0: 174 | return QVariant(nameColumnHAlign | Qt::AlignVCenter); 175 | case 1: 176 | return QVariant(Qt::AlignRight | Qt::AlignVCenter); 177 | case 2: 178 | // fall-through 179 | case 3: 180 | // fall-through 181 | case 4: 182 | // fall-through 183 | case 5: 184 | // fall-through 185 | case 6: 186 | return QVariant(Qt::AlignHCenter | Qt::AlignVCenter); 187 | } 188 | } 189 | if (role == Qt::DisplayRole) { 190 | Instance instance = instanceList.at(index.row()); 191 | switch (index.column()) { 192 | case 0: 193 | return instance.name(); 194 | case 1: 195 | return instance.status(); 196 | case 2: 197 | return instance.vmType(); 198 | case 3: 199 | return instance.arch(); 200 | case 4: 201 | return instance.strCpus(); 202 | case 5: 203 | return instance.strMemory(); 204 | case 6: 205 | return instance.strDisk(); 206 | } 207 | } 208 | return QVariant(); 209 | } 210 | 211 | QVariant InstanceModel::headerData(int section, Qt::Orientation orientation, int role) const 212 | { 213 | if (role != Qt::DisplayRole) 214 | return QVariant(); 215 | 216 | if (orientation == Qt::Horizontal) { 217 | switch (section) { 218 | case 0: 219 | return tr("Name"); 220 | case 1: 221 | return tr("Status"); 222 | case 2: 223 | return tr("VMtype"); 224 | case 3: 225 | return tr("Arch"); 226 | case 4: 227 | return tr("CPUs"); 228 | case 5: 229 | return tr("Mem."); 230 | case 6: 231 | return tr("Disk"); 232 | } 233 | } 234 | return QVariant(); 235 | } 236 | -------------------------------------------------------------------------------- /instance.h: -------------------------------------------------------------------------------- 1 | #ifndef INSTANCE_H 2 | #define INSTANCE_H 3 | 4 | #include 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | // NAME STATUS SSH VMTYPE ARCH CPUS MEMORY DISK DIR 12 | 13 | //! [0] 14 | class Instance 15 | { 16 | public: 17 | Instance() : Instance("") { } 18 | Instance(const QString &name) 19 | : m_name(name), 20 | m_status(""), 21 | m_dir(""), 22 | m_vm_type(""), 23 | m_mount_type(""), 24 | m_arch(""), 25 | m_cpu_type(""), 26 | m_cpus(0), 27 | m_memory(0), 28 | m_disk(0), 29 | m_ssh_address(""), 30 | m_ssh_local_port(0), 31 | m_ssh_config_file("") 32 | { 33 | } 34 | Instance(const QJsonObject &obj); 35 | 36 | QString name() const { return m_name; } 37 | QString status() const { return m_status; } 38 | void setStatus(QString status) { m_status = status; } 39 | QString dir() const { return m_dir; } 40 | void setDir(QString dir) { m_dir = dir; } 41 | QString vmType() const { return m_vm_type; } 42 | void setVmType(QString type) { m_vm_type = type; } 43 | QString mountType() const { return m_mount_type; } 44 | void setMountType(QString type) { m_mount_type = type; } 45 | QString arch() const { return m_arch; } 46 | void setArch(QString arch) { m_arch = arch; } 47 | QString cpuType() const { return m_cpu_type; } 48 | void setCpuType(QString type) { m_cpu_type = type; } 49 | int cpus() const { return m_cpus; } 50 | QString strCpus() const; 51 | void setCpus(int cpus) { m_cpus = cpus; } 52 | qint64 memory() const { return m_memory; } 53 | QString strMemory() const; 54 | void setMemory(qint64 memory) { m_memory = memory; } 55 | qint64 disk() const { return m_disk; } 56 | QString strDisk() const; 57 | void setDisk(qint64 disk) { m_disk = disk; } 58 | QString sshAddress() const { return m_ssh_address; } 59 | void setSshAddress(QString addr) { m_ssh_address = addr; } 60 | int sshLocalPort() const { return m_ssh_local_port; } 61 | void setSshLocalPort(int port) { m_ssh_local_port = port; } 62 | QString sshConfigFile() const { return m_ssh_config_file; } 63 | void setSshConfigFile(QString file) { m_ssh_config_file = file; } 64 | QVariantMap config() const { return m_config; } 65 | void setConfig(QVariantMap config) { m_config = config; } 66 | 67 | QString audioDevice(); 68 | QString videoDisplay(); 69 | 70 | private: 71 | QString m_name; 72 | QString m_status; 73 | QString m_dir; 74 | QString m_vm_type; 75 | QString m_mount_type; 76 | QString m_arch; 77 | QString m_cpu_type; 78 | int m_cpus; 79 | qint64 m_memory; 80 | qint64 m_disk; 81 | QString m_ssh_address; 82 | int m_ssh_local_port; 83 | QString m_ssh_config_file; 84 | QVariantMap m_config; 85 | }; 86 | //! [0] 87 | 88 | typedef QList InstanceList; 89 | typedef QHash InstanceHash; 90 | 91 | //! [1] 92 | class InstanceModel : public QAbstractListModel 93 | { 94 | Q_OBJECT 95 | 96 | public: 97 | InstanceModel(const InstanceList &instances, QObject *parent = nullptr) 98 | : QAbstractListModel(parent), instanceList(instances), m_quiet(false) 99 | { 100 | } 101 | 102 | void setInstances(const InstanceList &instances); 103 | void setQuiet(bool quiet) { m_quiet = quiet; } 104 | int rowCount(const QModelIndex &parent = QModelIndex()) const override; 105 | int columnCount(const QModelIndex &parent = QModelIndex()) const override; 106 | QVariant data(const QModelIndex &index, int role) const override; 107 | QVariant headerData(int section, Qt::Orientation orientation, 108 | int role = Qt::DisplayRole) const override; 109 | 110 | private: 111 | InstanceList instanceList; 112 | bool m_quiet; 113 | }; 114 | //! [1] 115 | 116 | #endif // INSTANCE_H 117 | -------------------------------------------------------------------------------- /lima-gui.desktop: -------------------------------------------------------------------------------- 1 | [Desktop Entry] 2 | Version=1.0 3 | Name=Lima 4 | Exec=lima-gui 5 | Icon=tux 6 | Type=Application 7 | Terminal=false 8 | Keywords=Emulators;Virtualization;KVM; 9 | -------------------------------------------------------------------------------- /lima.cpp: -------------------------------------------------------------------------------- 1 | 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include "lima.h" 8 | 9 | QString defaultYAML() 10 | { 11 | return "templates/default.yaml"; 12 | } 13 | 14 | QString defaultURL() 15 | { 16 | return "https://github.com/lima-vm/lima/blob/master/templates/default.yaml"; 17 | } 18 | 19 | QStringList brewPaths() 20 | { 21 | return QStringList({ "/usr/local/bin", "/opt/homebrew/bin", "/home/linuxbrew/.linuxbrew/bin", 22 | "/opt/local/bin" }); 23 | } 24 | 25 | static QStringList standardPaths; 26 | 27 | QString limactlPath(const QStringList &paths) 28 | { 29 | QStringList searchPaths; 30 | if (paths.isEmpty()) { 31 | searchPaths = standardPaths; 32 | } else { 33 | standardPaths = paths; 34 | searchPaths = paths; 35 | } 36 | QString program = QStandardPaths::findExecutable("limactl", searchPaths); 37 | if (program.isEmpty()) { 38 | program = QStandardPaths::findExecutable("limactl", brewPaths()); 39 | } 40 | return program; 41 | } 42 | -------------------------------------------------------------------------------- /lima.h: -------------------------------------------------------------------------------- 1 | #ifndef LIMA_H 2 | #define LIMA_H 3 | 4 | extern QString defaultYAML(); 5 | extern QString defaultURL(); 6 | 7 | extern QStringList brewPaths(); 8 | extern QString limactlPath(const QStringList &paths = QStringList()); 9 | 10 | #endif // LIMA_H 11 | -------------------------------------------------------------------------------- /logos/README: -------------------------------------------------------------------------------- 1 | These logos are copyright respective example project. 2 | -------------------------------------------------------------------------------- /logos/almalinux.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/afbjorklund/lima-gui/4b46e8509ca9b7ff97f2daa596d0ee13403ae0ed/logos/almalinux.png -------------------------------------------------------------------------------- /logos/alpine.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/afbjorklund/lima-gui/4b46e8509ca9b7ff97f2daa596d0ee13403ae0ed/logos/alpine.png -------------------------------------------------------------------------------- /logos/apptainer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/afbjorklund/lima-gui/4b46e8509ca9b7ff97f2daa596d0ee13403ae0ed/logos/apptainer.png -------------------------------------------------------------------------------- /logos/archlinux.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/afbjorklund/lima-gui/4b46e8509ca9b7ff97f2daa596d0ee13403ae0ed/logos/archlinux.png -------------------------------------------------------------------------------- /logos/buildroot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/afbjorklund/lima-gui/4b46e8509ca9b7ff97f2daa596d0ee13403ae0ed/logos/buildroot.png -------------------------------------------------------------------------------- /logos/centos.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/afbjorklund/lima-gui/4b46e8509ca9b7ff97f2daa596d0ee13403ae0ed/logos/centos.png -------------------------------------------------------------------------------- /logos/coreos.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/afbjorklund/lima-gui/4b46e8509ca9b7ff97f2daa596d0ee13403ae0ed/logos/coreos.png -------------------------------------------------------------------------------- /logos/debian.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/afbjorklund/lima-gui/4b46e8509ca9b7ff97f2daa596d0ee13403ae0ed/logos/debian.png -------------------------------------------------------------------------------- /logos/fedora.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/afbjorklund/lima-gui/4b46e8509ca9b7ff97f2daa596d0ee13403ae0ed/logos/fedora.png -------------------------------------------------------------------------------- /logos/flatcar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/afbjorklund/lima-gui/4b46e8509ca9b7ff97f2daa596d0ee13403ae0ed/logos/flatcar.png -------------------------------------------------------------------------------- /logos/k3s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/afbjorklund/lima-gui/4b46e8509ca9b7ff97f2daa596d0ee13403ae0ed/logos/k3s.png -------------------------------------------------------------------------------- /logos/k8s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/afbjorklund/lima-gui/4b46e8509ca9b7ff97f2daa596d0ee13403ae0ed/logos/k8s.png -------------------------------------------------------------------------------- /logos/leap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/afbjorklund/lima-gui/4b46e8509ca9b7ff97f2daa596d0ee13403ae0ed/logos/leap.png -------------------------------------------------------------------------------- /logos/nerd-face.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/afbjorklund/lima-gui/4b46e8509ca9b7ff97f2daa596d0ee13403ae0ed/logos/nerd-face.png -------------------------------------------------------------------------------- /logos/nomad.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/afbjorklund/lima-gui/4b46e8509ca9b7ff97f2daa596d0ee13403ae0ed/logos/nomad.png -------------------------------------------------------------------------------- /logos/openfaas.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/afbjorklund/lima-gui/4b46e8509ca9b7ff97f2daa596d0ee13403ae0ed/logos/openfaas.png -------------------------------------------------------------------------------- /logos/opensuse.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/afbjorklund/lima-gui/4b46e8509ca9b7ff97f2daa596d0ee13403ae0ed/logos/opensuse.png -------------------------------------------------------------------------------- /logos/podman.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/afbjorklund/lima-gui/4b46e8509ca9b7ff97f2daa596d0ee13403ae0ed/logos/podman.png -------------------------------------------------------------------------------- /logos/rocky.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/afbjorklund/lima-gui/4b46e8509ca9b7ff97f2daa596d0ee13403ae0ed/logos/rocky.png -------------------------------------------------------------------------------- /logos/singularity.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/afbjorklund/lima-gui/4b46e8509ca9b7ff97f2daa596d0ee13403ae0ed/logos/singularity.png -------------------------------------------------------------------------------- /logos/stream.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/afbjorklund/lima-gui/4b46e8509ca9b7ff97f2daa596d0ee13403ae0ed/logos/stream.png -------------------------------------------------------------------------------- /logos/tinycore.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/afbjorklund/lima-gui/4b46e8509ca9b7ff97f2daa596d0ee13403ae0ed/logos/tinycore.png -------------------------------------------------------------------------------- /logos/tumbleweed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/afbjorklund/lima-gui/4b46e8509ca9b7ff97f2daa596d0ee13403ae0ed/logos/tumbleweed.png -------------------------------------------------------------------------------- /logos/ubuntu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/afbjorklund/lima-gui/4b46e8509ca9b7ff97f2daa596d0ee13403ae0ed/logos/ubuntu.png -------------------------------------------------------------------------------- /logos/whale.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/afbjorklund/lima-gui/4b46e8509ca9b7ff97f2daa596d0ee13403ae0ed/logos/whale.png -------------------------------------------------------------------------------- /main.cpp: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | ** 3 | ** Copyright (C) 2016 The Qt Company Ltd. 4 | ** Contact: https://www.qt.io/licensing/ 5 | ** 6 | ** This file is part of the examples of the Qt Toolkit. 7 | ** 8 | ** $QT_BEGIN_LICENSE:BSD$ 9 | ** Commercial License Usage 10 | ** Licensees holding valid commercial Qt licenses may use this file in 11 | ** accordance with the commercial license agreement provided with the 12 | ** Software or, alternatively, in accordance with the terms contained in 13 | ** a written agreement between you and The Qt Company. For licensing terms 14 | ** and conditions see https://www.qt.io/terms-conditions. For further 15 | ** information use the contact form at https://www.qt.io/contact-us. 16 | ** 17 | ** BSD License Usage 18 | ** Alternatively, you may use this file under the terms of the BSD license 19 | ** as follows: 20 | ** 21 | ** "Redistribution and use in source and binary forms, with or without 22 | ** modification, are permitted provided that the following conditions are 23 | ** met: 24 | ** * Redistributions of source code must retain the above copyright 25 | ** notice, this list of conditions and the following disclaimer. 26 | ** * Redistributions in binary form must reproduce the above copyright 27 | ** notice, this list of conditions and the following disclaimer in 28 | ** the documentation and/or other materials provided with the 29 | ** distribution. 30 | ** * Neither the name of The Qt Company Ltd nor the names of its 31 | ** contributors may be used to endorse or promote products derived 32 | ** from this software without specific prior written permission. 33 | ** 34 | ** 35 | ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 36 | ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 37 | ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 38 | ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 39 | ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 40 | ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 41 | ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 42 | ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 43 | ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 44 | ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 45 | ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." 46 | ** 47 | ** $QT_END_LICENSE$ 48 | ** 49 | ****************************************************************************/ 50 | 51 | #include 52 | #include 53 | #include 54 | #include 55 | 56 | #ifndef QT_NO_SYSTEMTRAYICON 57 | 58 | #include 59 | #include "window.h" 60 | #include "lima.h" 61 | 62 | #ifndef QT_NO_EMOTICONS 63 | Q_IMPORT_PLUGIN(EmoticonOpenmojiPlugin) 64 | #endif 65 | 66 | int main(int argc, char *argv[]) 67 | { 68 | Q_INIT_RESOURCE(systray); 69 | #ifndef QT_NO_EMOTICONS 70 | Q_INIT_RESOURCE(emoticons_openmoji); 71 | #endif 72 | 73 | #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) 74 | QCoreApplication::setAttribute(Qt::AA_UseHighDpiPixmaps); 75 | #endif 76 | 77 | QApplication app(argc, argv); 78 | 79 | QSettings settings("lima", "lima-gui"); 80 | QStringList paths = settings.value("paths").value(); 81 | QString program = limactlPath(paths); 82 | if (program.isEmpty()) { 83 | QMessageBox::critical(0, QObject::tr("Lima"), 84 | QObject::tr("I couldn't find limactl in PATH " 85 | "on this system.")); 86 | return 1; 87 | } 88 | if (QSystemTrayIcon::isSystemTrayAvailable()) { 89 | QApplication::setQuitOnLastWindowClosed(false); 90 | } 91 | 92 | Window window; 93 | window.setSettings(&settings); 94 | window.show(); 95 | return app.exec(); 96 | } 97 | 98 | #else 99 | 100 | #include 101 | #include 102 | 103 | int main(int argc, char *argv[]) 104 | { 105 | QApplication app(argc, argv); 106 | QString text("QSystemTrayIcon is not supported on this platform"); 107 | 108 | QLabel *label = new QLabel(text); 109 | label->setWordWrap(true); 110 | 111 | label->show(); 112 | qDebug() << text; 113 | 114 | app.exec(); 115 | } 116 | 117 | #endif 118 | -------------------------------------------------------------------------------- /systray.pro: -------------------------------------------------------------------------------- 1 | HEADERS = window.h \ 2 | lima.h \ 3 | templates.h \ 4 | instance.h 5 | SOURCES = main.cpp \ 6 | instance.cpp \ 7 | templates.cpp \ 8 | lima.cpp \ 9 | window.cpp 10 | RESOURCES = systray.qrc 11 | 12 | QT += widgets 13 | requires(qtConfig(combobox)) 14 | 15 | TARGET = lima-gui 16 | 17 | macx: ICON = icons/tux.icns 18 | 19 | DISTFILES += \ 20 | LICENSE 21 | 22 | //DEFINES += QT_NO_SOURCEHIGHLITER 23 | include(QSourceHighlite/QSourceHighlite.pri) 24 | 25 | //DEFINES += QT_NO_EMOTICONS 26 | include(QrwEmoticons/QrwEmoticons.pri) 27 | 28 | //DEFINES += QT_NO_VNCCLIENT 29 | include(QVNCClient/QVNCClient.pri) 30 | 31 | # Enabling qtermwidget requires GPL-v2 license 32 | #CONFIG += gpl_licensed 33 | 34 | gpl_licensed { 35 | win32: DEFINES += QT_NO_TERMWIDGET 36 | 37 | unix: CONFIG += link_pkgconfig 38 | unix: PKGCONFIG += qtermwidget5 39 | } else { 40 | DEFINES += QT_NO_TERMWIDGET 41 | 42 | win32: DEFINES += QT_NO_EMOTICONS 43 | } 44 | -------------------------------------------------------------------------------- /systray.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | images/tux.png 4 | images/add.png 5 | images/remove.png 6 | images/quick.png 7 | images/info.png 8 | images/reload.png 9 | images/terminal.png 10 | images/desktopshare.png 11 | images/player_start.png 12 | images/player_stop.png 13 | images/advanced.png 14 | images/help.png 15 | images/search.png 16 | logos/ubuntu.png 17 | logos/alpine.png 18 | logos/fedora.png 19 | logos/archlinux.png 20 | logos/debian.png 21 | logos/opensuse.png 22 | logos/rocky.png 23 | logos/nerd-face.png 24 | logos/whale.png 25 | logos/podman.png 26 | logos/singularity.png 27 | logos/apptainer.png 28 | logos/k3s.png 29 | logos/k8s.png 30 | logos/nomad.png 31 | logos/openfaas.png 32 | logos/centos.png 33 | logos/stream.png 34 | logos/coreos.png 35 | logos/flatcar.png 36 | logos/tinycore.png 37 | logos/buildroot.png 38 | logos/leap.png 39 | logos/tumbleweed.png 40 | 41 | 42 | -------------------------------------------------------------------------------- /templates.cpp: -------------------------------------------------------------------------------- 1 | #include "templates.h" 2 | 3 | static TemplateHash examples; 4 | 5 | TemplateHash &getTemplates() 6 | { 7 | TemplateHash hash; 8 | 9 | if (!examples.empty()) { 10 | return examples; 11 | } 12 | 13 | // Distro 14 | hash["almalinux"] = Template("almalinux", "AlmaLinux", "https://almalinux.org"); 15 | hash["alpine"] = Template("alpine", "Alpine", "https://alpinelinux.org"); 16 | hash["archlinux"] = Template("archlinux", "Arch", "https://archlinux.org"); 17 | hash["debian"] = Template("debian", "Debian", "https://debian.org"); 18 | hash["fedora"] = Template("fedora", "Fedora", "https://fedoraproject.org"); 19 | hash["opensuse"] = Template("opensuse", "openSUSE", "https://opensuse.org"); 20 | hash["rocky"] = Template("rocky", "Rocky", "https://rockylinux.org"); 21 | hash["ubuntu"] = Template("ubuntu", "Ubuntu", "https://ubuntu.com"); 22 | hash["centos"] = Template("centos", "CentOS", "https://www.centos.org/centos-linux/"); 23 | hash["flatcar"] = Template("flatcar", "Flatcar", "https://flatcar.org"); 24 | hash["tinycore"] = Template("tinycore", "TinyCore", "http://tinycorelinux.net/"); 25 | hash["buildroot"] = Template("buildroot", "Buildroot", "https://buildroot.org/"); 26 | 27 | hash["centos-stream"] = 28 | Template("centos-stream", "CentOS Stream", "https://www.centos.org/centos-stream/"); 29 | hash["fedora-coreos"] = 30 | Template("fedora-coreos", "Fedora CoreOS", "https://fedoraproject.org/coreos/"); 31 | hash["opensuse-leap"] = Template("opensuse-leap", "openSUSE Leap", "https://www.opensuse.org/"); 32 | hash["opensuse-tumbleweed"] = 33 | Template("opensuse-tumbleweed", "openSUSE Tumbleweed", "https://www.opensuse.org/"); 34 | 35 | // Container engines 36 | hash["default"] = Template("default", "Default", "https://containerd.io"); 37 | hash["docker"] = Template("docker", "Docker", "https://docker.com"); 38 | hash["podman"] = Template("podman", "Podman", "https://podman.io"); 39 | hash["singularity"] = Template("singularity", "Singularity", "https://singularity.hpcng.org"); 40 | hash["apptainer"] = Template("apptainer", "Apptainer", "https://apptainer.org"); 41 | 42 | // Container orchestration 43 | hash["k3s"] = Template("k3s", "Kubernetes (k3s)", "https://k3s.io"); 44 | hash["k8s"] = Template("k8s", "Kubernetes (k8s)", "https://k8s.io"); 45 | hash["nomad"] = Template("nomad", "Nomad", "https://nomadproject.io"); 46 | hash["faasd"] = Template("faasd", "Faasd", "https://openfaas.com"); 47 | 48 | hash["centos-stream"].setLogo("stream.png"); 49 | hash["fedora-coreos"].setLogo("coreos.png"); 50 | hash["opensuse-leap"].setLogo("leap.png"); 51 | hash["opensuse-leap"].setYaml("opensuse.yaml"); 52 | hash["opensuse-tumbleweed"].setLogo("tumbleweed.png"); 53 | hash["opensuse-tumbleweed"].setYaml("experimental/opensuse-tumbleweed.yaml"); 54 | hash["default"].setLogo("nerd-face.png"); 55 | hash["docker"].setLogo("whale.png"); 56 | hash["faasd"].setLogo("openfaas.png"); 57 | 58 | examples = hash; 59 | return examples; 60 | } 61 | -------------------------------------------------------------------------------- /templates.h: -------------------------------------------------------------------------------- 1 | #ifndef EXAMPLES_H 2 | #define EXAMPLES_H 3 | 4 | #include 5 | #include 6 | 7 | class Template 8 | { 9 | public: 10 | Template() : Template("", "", "") { } 11 | Template(const QString &name, const QString &text, const QString &url) 12 | : m_name(name), m_logo(""), m_yaml(""), m_text(text), m_url(url) 13 | { 14 | } 15 | 16 | QString name() const { return m_name; } 17 | QString logo() const { return m_logo.isEmpty() ? m_name + ".png" : m_logo; } 18 | void setLogo(QString logo) { m_logo = logo; } 19 | QString yaml() const { return m_yaml.isEmpty() ? m_name + ".yaml" : m_yaml; } 20 | void setYaml(QString yaml) { m_yaml = yaml; } 21 | QString text() const { return m_text; } 22 | void setText(QString text) { m_text = text; } 23 | QString url() const { return m_url; } 24 | void setUrl(QString url) { m_url = url; } 25 | 26 | private: 27 | QString m_name; 28 | QString m_logo; 29 | QString m_yaml; 30 | QString m_text; 31 | QString m_url; 32 | }; 33 | 34 | typedef QList