├── .gitignore ├── LICENSE.md ├── README.md ├── snap └── snapcraft.yaml ├── widgetci ├── Widgetci.pro ├── defaultwidgets │ ├── Arabic Watch │ │ └── main.qml │ ├── Example │ │ ├── main.qml │ │ └── test.png │ ├── Image │ │ ├── clock_img.jpg │ │ ├── image.conf │ │ ├── main.qml │ │ └── resizer.png │ ├── Note │ │ ├── main.qml │ │ └── notes.txt │ ├── SystemInfo │ │ └── main.qml │ └── Watch │ │ └── main.qml ├── img │ ├── icon.ico │ ├── icon.png │ ├── reload.png │ ├── showfolder.png │ ├── toggleoff.png │ └── toggleon.png ├── main.cpp ├── mainwindow.cpp ├── mainwindow.h ├── mainwindow.ui ├── qtresource.qrc ├── runguard.cpp ├── runguard.h ├── translations │ ├── widgetci_empty.ts │ ├── widgetci_tr.qm │ └── widgetci_tr.ts ├── widgetci.rc ├── wqmlfile.cpp ├── wqmlfile.h ├── wqmlsystem.cpp ├── wqmlsystem.h ├── wwidget.cpp └── wwidget.h └── widgetci_1.0.3.png /.gitignore: -------------------------------------------------------------------------------- 1 | # Prerequisites 2 | *.d 3 | 4 | # Compiled Object files 5 | *.slo 6 | *.lo 7 | *.o 8 | *.obj 9 | 10 | # Precompiled Headers 11 | *.gch 12 | *.pch 13 | 14 | # Compiled Dynamic libraries 15 | *.so 16 | *.dylib 17 | *.dll 18 | 19 | # Fortran module files 20 | *.mod 21 | *.smod 22 | 23 | # Compiled Static libraries 24 | *.lai 25 | *.la 26 | *.a 27 | *.lib 28 | 29 | # Executables 30 | *.exe 31 | *.out 32 | *.app 33 | 34 | # QT User files 35 | *.pro.user 36 | 37 | widgetci/Debug 38 | widgetci/Release 39 | Debug 40 | Release 41 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Widgetci 2 | a Widget Management App can run on Win/Linux/Mac. 3 | 4 | Uses **QT5.7.1**'s "**QML** + **Javascript** Engine" for **widgets.** 5 | 6 | ![Image](https://raw.githubusercontent.com/eminfedar/widgetci/dev-unstable/widgetci_1.0.3.png) 7 | 8 | ### Simple widget file (.qml): 9 | ``` 10 | import QtQuick 2.5 11 | 12 | // Widget's root object 13 | Item { 14 | width: 70 15 | height: 30 16 | 17 | 18 | // A Text element 19 | Text { 20 | x: 20 21 | y: 5 22 | text: "Hey!" 23 | } 24 | } 25 | ``` 26 | 27 | ### How to Create a Widget? 28 | Visit the Wiki =>> [How to Create a Widget](https://github.com/eminfedar/widgetci/wiki/How-to-create-a-widget) 29 | 30 | 31 | ### How to build from source code (Linux) ### 32 | Download the project: 33 | ``` 34 | git clone https://github.com/eminfedar/widgetci.git 35 | ``` 36 | 37 | #### Building: #### 38 | Requirements: 39 | - **Qt 5.7.1** (or >=) 40 | - **QtCreator** *(optional, you can build it from qtcreator just by opening the project on it and building it)* 41 | 42 | #### Building WITHOUT QtCreator: #### 43 | ``` 44 | cd widgetci/widgetci/ #path of the .pro file 45 | mkdir buildFolder 46 | cd buildFolder 47 | qmake ../ 48 | make 49 | ``` 50 | 51 | #### Run: 52 | `./widgetci` 53 | -------------------------------------------------------------------------------- /snap/snapcraft.yaml: -------------------------------------------------------------------------------- 1 | 2 | name: widgetci 3 | version: '1.0.3' # just for humans, typically '1.2+git' or '1.3.2' 4 | summary: a Cross-Platform Widget Management App. # 79 char long summary 5 | description: | 6 | You have multiple PC's but you want your widgets in all of them. Here is the Widgetci. 7 | grade: stable # must be 'stable' to release into candidate/stable channels 8 | confinement: devmode # use 'strict' once you have the right plugs and slots 9 | 10 | parts: 11 | my-part: 12 | # See 'snapcraft plugins' 13 | plugin: nil 14 | 15 | -------------------------------------------------------------------------------- /widgetci/Widgetci.pro: -------------------------------------------------------------------------------- 1 | #------------------------------------------------- 2 | # 3 | # Project created by QtCreator 2017-06-21T19:13:09 4 | # Author: Mehmet Emin Fedar 5 | # 6 | #------------------------------------------------- 7 | 8 | QT += widgets quick qml 9 | 10 | TARGET = Widgetci 11 | TEMPLATE = app 12 | 13 | SOURCES += main.cpp\ 14 | mainwindow.cpp \ 15 | wwidget.cpp \ 16 | runguard.cpp \ 17 | wqmlfile.cpp \ 18 | wqmlsystem.cpp 19 | 20 | HEADERS += mainwindow.h \ 21 | wwidget.h \ 22 | runguard.h \ 23 | wqmlfile.h \ 24 | wqmlsystem.h 25 | 26 | FORMS += mainwindow.ui 27 | 28 | !win32 { QMAKE_CXXFLAGS += -std=c++11 } 29 | 30 | win32{ CONFIG += static } 31 | 32 | RESOURCES += \ 33 | qtresource.qrc 34 | 35 | RC_FILE = widgetci.rc 36 | -------------------------------------------------------------------------------- /widgetci/defaultwidgets/Arabic Watch/main.qml: -------------------------------------------------------------------------------- 1 | /* 2 | == Widgetci - https://github.com/eminfedar/widgetci == 3 | 4 | "THIS 'arabic watch' IS ONE OF THE DEFAULT WIDGETS OF 'WIDGETCI'. 5 | CAN BE EDITED AND USED. LICENSED WITH GPL." 6 | 7 | - @eminfedar 8 | */ 9 | 10 | import QtQuick 2.5 11 | 12 | Item { 13 | id:base; 14 | width: (timeText.width > dateText.width ? timeText.width : dateText.width) + 8; 15 | height: dateText.height + dateText.y; 16 | 17 | property var locale: Qt.locale("ar_SA"); 18 | property real intervalMs: (60050 - ((new Date().getSeconds() * 1000) + new Date().getMilliseconds())); 19 | 20 | Timer{ 21 | interval: intervalMs; running: true; repeat: true; 22 | onTriggered: { 23 | intervalMs = 60000; // Did this because of precise reloading when the time arrived. 24 | timeText.text = new Date().toLocaleString(locale, "HH:mm"); 25 | base.width = (timeText.width > dateText.width ? timeText.width : dateText.width) + 8; 26 | } 27 | } 28 | Text{ 29 | id:timeText; 30 | x: (dateText.width - timeText.width > 0 ? (dateText.width - timeText.width) + 8 : 8); 31 | 32 | horizontalAlignment: Text.AlignRight; 33 | font.pointSize: 72; 34 | font.family: "Serif"; 35 | font.weight: Font.Thin; 36 | 37 | text: new Date().toLocaleString(locale, "HH:mm"); 38 | color: "#FFFFFF"; 39 | } 40 | 41 | Text{ 42 | id:dateText; 43 | x: (timeText.width - dateText.width > 0 ? (timeText.width - dateText.width) : 0); 44 | y: 135; 45 | 46 | horizontalAlignment: Text.AlignRight; 47 | font.pointSize: 24; 48 | font.family: "Serif"; 49 | font.weight: Font.Thin; 50 | 51 | text: new Date().toLocaleString(locale, "dddd, dd/MM"); 52 | color: "#FFFFFF"; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /widgetci/defaultwidgets/Example/main.qml: -------------------------------------------------------------------------------- 1 | // This is simple example of a widget. 2 | // Main widget must named by "main.qml" in the widget folder. 3 | // You must create a 'Item' or 'Rectangle' object as a parent 4 | 5 | // If you want a background has color, you can use Rectangle and set it's color property. 6 | /* FOR INFO ABOUT ALL OF THINGS YOU CAN DO AND QML API DOCUMENT : http://doc.qt.io/qt-5/qmltypes.html */ 7 | import QtQuick 2.5 8 | 9 | Item { 10 | width: 300 11 | height: 300 12 | 13 | // Drawing a Rectangle Example 14 | Rectangle{ 15 | width: 30 16 | height: 30 17 | y: 30 18 | color: "#FFFF0000"; 19 | } 20 | 21 | // Timer Example 22 | Timer { 23 | interval: 1000; running: true; repeat: true 24 | onTriggered: { 25 | time.text = Date().toString(); 26 | } 27 | } 28 | Text { id: time; text: "Hey!"; color:"#FFFFFF" } 29 | 30 | // Image Example 31 | Image { // AnimatedImage for gifs. 32 | id: img1 33 | width: 30 34 | height: 30 35 | x: 50 36 | y: 30 37 | source: "test.png" 38 | } 39 | 40 | // Text Input Example 41 | TextInput { 42 | y: 80 43 | color: "#FFFFFF" 44 | text: "Write here" 45 | focus: true 46 | } 47 | 48 | // Get text from an url: 49 | function getText(url, textelement){ 50 | var request = new XMLHttpRequest(); 51 | request.onreadystatechange = function() { 52 | if (request.readyState === XMLHttpRequest.DONE) 53 | textelement.text = request.responseText; 54 | } 55 | request.open("get", url); 56 | request.setRequestHeader("Content-Encoding", "UTF-8"); 57 | request.send(''); 58 | 59 | return "Loading..."; 60 | } 61 | 62 | Text { 63 | id: urltesttext 64 | y: 100 65 | color: "#00FF00" 66 | text: getText("https://api.ipify.org/?format=plain", urltesttext) 67 | } 68 | 69 | // Clickable text example. 70 | Text { 71 | y: 130 72 | width: 50 73 | height: 20 74 | color: "#FF0000" 75 | text: "Click here!" 76 | MouseArea{ 77 | anchors.fill: parent 78 | onClicked: { 79 | parent.text = "Okay okay enough!"; 80 | console.log(parent.text); 81 | } 82 | } 83 | } 84 | 85 | // Clickable image example. 86 | Image { 87 | x: 150 88 | y: 130 89 | width: 30 90 | height: 30 91 | source: "test.png" 92 | MouseArea{ 93 | anchors.fill: parent 94 | onPressed: { 95 | console.log("img clicked"); 96 | } 97 | } 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /widgetci/defaultwidgets/Example/test.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eminfedar/widgetci/05588c036cd4c6d6eddd5b595d027968ac484140/widgetci/defaultwidgets/Example/test.png -------------------------------------------------------------------------------- /widgetci/defaultwidgets/Image/clock_img.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eminfedar/widgetci/05588c036cd4c6d6eddd5b595d027968ac484140/widgetci/defaultwidgets/Image/clock_img.jpg -------------------------------------------------------------------------------- /widgetci/defaultwidgets/Image/image.conf: -------------------------------------------------------------------------------- 1 | 246|135 -------------------------------------------------------------------------------- /widgetci/defaultwidgets/Image/main.qml: -------------------------------------------------------------------------------- 1 | /* 2 | == Widgetci - https://github.com/eminfedar/widgetci == 3 | 4 | "THIS 'Image' IS ONE OF THE DEFAULT WIDGETS OF 'WIDGETCI'. 5 | CAN BE EDITED AND USED." 6 | 7 | - @eminfedar 8 | */ 9 | 10 | import QtQuick 2.5 11 | import com.widgetci.file 1.0 12 | 13 | Item { 14 | id: base 15 | 16 | // Image source 17 | property string imageSource: "clock_img.jpg" 18 | property string widgetName: "Image" // Required for saving conf file 19 | 20 | property var size: wFile.readFile(widgetName, "image.conf").split("|"); 21 | 22 | width: parseInt(size[0]) 23 | height: parseInt(size[1]) 24 | 25 | property bool isResizing: false 26 | 27 | // Image Example 28 | Image { 29 | id: img1 30 | anchors.fill: parent 31 | source: imageSource 32 | 33 | MouseArea{ 34 | id: img1_ma 35 | anchors.fill: parent 36 | hoverEnabled: true 37 | onClicked: { 38 | Qt.openUrlExternally(img1.source.toString()) 39 | } 40 | 41 | onEntered: { 42 | img1_ma.cursorShape = Qt.PointingHandCursor 43 | } 44 | 45 | onReleased: { 46 | isResizing = false 47 | } 48 | } 49 | } 50 | 51 | property var rPoint: "0,0" 52 | Image { 53 | id: resizer 54 | x: base.width - 16 55 | y: base.height - 16 56 | width: 16 57 | height: 16 58 | source: "resizer.png" 59 | 60 | MouseArea{ 61 | id: resizer_ma 62 | anchors.fill: parent 63 | hoverEnabled: true 64 | onPressed: { 65 | rPoint = Qt.point(mouse.x, mouse.y) 66 | isResizing = true 67 | } 68 | onPositionChanged: { 69 | if(isResizing){ 70 | var delta = Qt.point(mouse.x - rPoint.x, mouse.y - rPoint.y) 71 | base.width += delta.x 72 | base.height += delta.y 73 | } 74 | } 75 | onReleased:{ 76 | isResizing = false 77 | wFile.saveFile(widgetName, "image.conf", (base.width + "|" + base.height)) 78 | } 79 | } 80 | } 81 | 82 | WFile{ 83 | id: wFile 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /widgetci/defaultwidgets/Image/resizer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eminfedar/widgetci/05588c036cd4c6d6eddd5b595d027968ac484140/widgetci/defaultwidgets/Image/resizer.png -------------------------------------------------------------------------------- /widgetci/defaultwidgets/Note/main.qml: -------------------------------------------------------------------------------- 1 | /* 2 | == Widgetci - https://github.com/eminfedar/widgetci == 3 | 4 | "THIS 'Note' IS ONE OF THE DEFAULT WIDGETS OF 'WIDGETCI'. 5 | CAN BE EDITED AND USED FREELY." 6 | 7 | - @eminfedar 8 | */ 9 | 10 | import QtQuick 2.5 11 | import QtQuick.Controls 2.0 12 | import com.widgetci.file 1.0 //WFile. 13 | 14 | Item { 15 | id: base; 16 | 17 | // EDITABLES ===================================================== 18 | property string widgetName: "Note"; // Must be Name of the folder & widget. 19 | property string fileContent: wFile.readFile(widgetName, "notes.txt"); 20 | property string contentBackground: "#333" // #acea79 21 | property string contentBackgroundChecked: "#222" // #e4ea79 22 | width: 250; 23 | height: 400; 24 | // =============================================================== 25 | 26 | 27 | function getTabList(){ 28 | var pages = fileContent.split("_&_") 29 | var lst = [] 30 | for(var i in pages){ 31 | var pageArr = pages[i].split("_%_") 32 | lst.push(String(pageArr[0])) 33 | } 34 | return lst 35 | } 36 | function getContentList(){ 37 | var pages = fileContent.split("_&_") 38 | var lst = [] 39 | for(var i in pages){ 40 | var pageArr = pages[i].split("_%_") 41 | lst.push(String(pageArr[1])) 42 | } 43 | return lst 44 | } 45 | 46 | property var tabList: getTabList() 47 | property var contentList: getContentList() 48 | 49 | TabBar { 50 | id: tabBar 51 | width: parent.width 52 | height: 31 53 | background: Rectangle { color: contentBackground } 54 | 55 | currentIndex: swipeview.currentIndex 56 | 57 | Repeater{ 58 | model: tabList 59 | 60 | TabButton{ 61 | text: modelData 62 | width: contentItem.implicitWidth + 21 63 | height: tabBar.height 64 | 65 | font.bold: true 66 | 67 | contentItem: Text{ 68 | text: parent.text 69 | font: parent.font 70 | color: checked ? "#FFffffff" : "#77ffffff" 71 | horizontalAlignment: Text.AlignHCenter 72 | verticalAlignment: Text.AlignVCenter 73 | } 74 | 75 | background: Rectangle { 76 | color: parent.checked ? contentBackgroundChecked : contentBackground 77 | } 78 | } 79 | } 80 | 81 | TabButton{ 82 | text: "+" 83 | width: Math.max(29, tabBar.width/5) 84 | height: parent.height 85 | font.bold: true 86 | background: Rectangle { 87 | color: parent.checked ? "#DDD" : contentBackground 88 | } 89 | } 90 | } 91 | 92 | SwipeView{ 93 | id: swipeview 94 | y: tabBar.height 95 | height: parent.height - tabBar.height 96 | width: parent.width 97 | 98 | currentIndex: tabBar.currentIndex 99 | 100 | Repeater{ 101 | id: contentRepeater 102 | model: contentList 103 | 104 | Item{ 105 | width: swipeview.width 106 | height: swipeview.height 107 | Rectangle{ 108 | width: swipeview.width 109 | height: swipeview.height 110 | color : contentBackgroundChecked 111 | 112 | 113 | TextEdit { 114 | text: modelData 115 | wrapMode: TextEdit.Wrap; 116 | textFormat: TextEdit.PlainText; 117 | 118 | color: "#FFF"; 119 | 120 | selectByKeyboard: true 121 | selectByMouse: true 122 | 123 | anchors.fill: parent 124 | anchors.leftMargin: 7 125 | anchors.rightMargin: 7 126 | anchors.topMargin: 7 127 | anchors.bottomMargin: 7 128 | 129 | MouseArea{ 130 | anchors.fill: parent 131 | onClicked: { 132 | parent.forceActiveFocus() 133 | } 134 | } 135 | 136 | onTextChanged: { 137 | var totalString = "" 138 | for(var i in tabList){ 139 | if(Number(i) === swipeview.currentIndex){ 140 | totalString += tabList[i] + "_%_" + text + "_&_" 141 | contentList[i] = text 142 | } 143 | else 144 | totalString += tabList[i] + "_%_" + contentList[i] + "_&_" 145 | } 146 | totalString = totalString.slice(0, -3) 147 | wFile.saveFile(widgetName, "notes.txt", totalString); 148 | } 149 | } 150 | 151 | Button{ 152 | x: parent.width - 40 153 | y: parent.height - 40 154 | width: 32 155 | height: 32 156 | text: "X" 157 | 158 | contentItem: Text { 159 | text: parent.text 160 | font.bold: true 161 | color: "#AAA" 162 | horizontalAlignment: Text.AlignHCenter 163 | verticalAlignment: Text.AlignVCenter 164 | } 165 | 166 | background: Rectangle{ 167 | radius: 4 168 | color: parent.pressed ? "#191919" : (parent.hovered ? "#3F3F3F" : contentBackground) 169 | } 170 | 171 | ToolTip.visible: hovered 172 | ToolTip.text: "Double click to delete the Tab" 173 | 174 | onDoubleClicked: { 175 | var index = swipeview.currentIndex 176 | deleteTab(index) 177 | } 178 | 179 | } 180 | 181 | } 182 | } 183 | 184 | } 185 | 186 | Item { 187 | id: tab_add 188 | Button{ 189 | id: tab_add_button 190 | anchors.fill: parent 191 | text: "Add a new page" 192 | font.bold: true 193 | font.pointSize: 14 194 | 195 | onClicked: { 196 | tab_add_name.visible = true 197 | visible = false 198 | } 199 | 200 | } 201 | 202 | Rectangle{ 203 | id: tab_add_name 204 | anchors.fill: parent 205 | color: contentBackground 206 | visible: false 207 | 208 | TextEdit{ 209 | id: tab_add_name_txt 210 | anchors.fill: parent 211 | 212 | color: "#FFF" 213 | text: "Tab Name Here..." 214 | font.pointSize: 14 215 | font.bold: true 216 | font.underline: true 217 | verticalAlignment: Text.AlignVCenter 218 | horizontalAlignment: Text.AlignHCenter 219 | 220 | 221 | Keys.onReturnPressed: { 222 | tab_add_name.visible = false 223 | tab_add_button.visible = true 224 | 225 | 226 | var item = Qt.createQmlObject('import QtQuick 2.5;import QtQuick.Controls 2.0;import QtQuick.Layouts 1.1; 227 | Item{ 228 | width: swipeview.width 229 | height: swipeview.height 230 | Rectangle{ 231 | width: swipeview.width 232 | height: swipeview.height 233 | color : contentBackgroundChecked 234 | 235 | 236 | TextEdit { 237 | text: "Edit here!" 238 | wrapMode: TextEdit.Wrap; 239 | textFormat: TextEdit.PlainText; 240 | 241 | color: "#FFF"; 242 | 243 | selectByKeyboard: true 244 | selectByMouse: true 245 | 246 | anchors.fill: parent 247 | anchors.leftMargin: 7 248 | anchors.rightMargin: 7 249 | anchors.topMargin: 7 250 | anchors.bottomMargin: 7 251 | 252 | MouseArea{ 253 | anchors.fill: parent 254 | onClicked: { 255 | parent.forceActiveFocus() 256 | } 257 | } 258 | 259 | onActiveFocusChanged: { 260 | if(!activeFocus){ 261 | var totalString = "" 262 | for(var i in tabList){ 263 | if(Number(i) === swipeview.currentIndex){ 264 | totalString += tabList[i] + "_%_" + text + "_&_" 265 | contentList[i] = text 266 | } 267 | else 268 | totalString += tabList[i] + "_%_" + contentList[i] + "_&_" 269 | } 270 | totalString = totalString.slice(0, -3) 271 | wFile.saveFile(widgetName, "notes.txt", totalString); 272 | } 273 | } 274 | } 275 | 276 | Button{ 277 | x: parent.width - 40 278 | y: parent.height - 40 279 | width: 32 280 | height: 32 281 | text: "X" 282 | 283 | contentItem: Text { 284 | text: parent.text 285 | font.bold: true 286 | color: "#AAA" 287 | horizontalAlignment: Text.AlignHCenter 288 | verticalAlignment: Text.AlignVCenter 289 | } 290 | 291 | background: Rectangle{ 292 | radius: 4 293 | color: parent.pressed ? "#191919" : (parent.hovered ? "#3F3F3F" : contentBackground) 294 | } 295 | 296 | ToolTip.visible: hovered 297 | ToolTip.text: "Double click to delete the Tab" 298 | 299 | onDoubleClicked: { 300 | var index = swipeview.currentIndex 301 | deleteTab(index) 302 | } 303 | 304 | } 305 | } 306 | }', swipeview) 307 | 308 | var bar = Qt.createQmlObject('import QtQuick 2.5;import QtQuick.Controls 2.0;import QtQuick.Layouts 1.1; 309 | TabButton{ 310 | text: "' + text + '" 311 | width: contentItem.implicitWidth + 21 312 | height: tabBar.height 313 | 314 | font.bold: true 315 | 316 | contentItem: Text{ 317 | text: parent.text 318 | font: parent.font 319 | color: checked ? "#FFffffff" : "#77ffffff" 320 | horizontalAlignment: Text.AlignHCenter 321 | verticalAlignment: Text.AlignVCenter 322 | } 323 | 324 | background: Rectangle { 325 | color: parent.checked ? contentBackgroundChecked : contentBackground 326 | } 327 | }', tabBar) 328 | 329 | tabBar.moveItem(tabBar.count-1, tabBar.count-2) 330 | swipeview.moveItem(swipeview.count-1, swipeview.count-2) 331 | tabList.push(text) 332 | contentList.push("Edit here!") 333 | text = "Tab Name Here..." 334 | 335 | // Save 336 | saveAll() 337 | } 338 | 339 | onActiveFocusChanged: { 340 | if(activeFocus){ 341 | if(text === "Tab Name Here...") 342 | text = "" 343 | } 344 | } 345 | } 346 | } 347 | } 348 | } 349 | 350 | function deleteTab(index){ 351 | swipeview.removeItem(index) 352 | tabBar.removeItem(index) 353 | tabList.splice(index, 1) 354 | contentList.splice(index, 1) 355 | 356 | if(tabBar.count > 1 && tabBar.currentIndex < tabBar.count-1) 357 | tabBar.incrementCurrentIndex() 358 | 359 | saveAll() 360 | } 361 | 362 | function saveAll(){ 363 | var totalString = "" 364 | for(var i in tabList) 365 | totalString += tabList[i] + "_%_" + contentList[i] + "_&_" 366 | 367 | totalString = totalString.slice(0, -3) 368 | wFile.saveFile(widgetName, "notes.txt", totalString); 369 | } 370 | 371 | // Widgetci's file manager. (read & write files.) (import com.widgetci.file 1.0) 372 | WFile{ 373 | id: wFile; 374 | } 375 | } 376 | -------------------------------------------------------------------------------- /widgetci/defaultwidgets/Note/notes.txt: -------------------------------------------------------------------------------- 1 | To Do_%_Edit Here! -------------------------------------------------------------------------------- /widgetci/defaultwidgets/SystemInfo/main.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.5 2 | import com.widgetci.system 1.0 //WSystem 3 | 4 | Item { 5 | width: cputext.width 6 | height: cputext.height 7 | 8 | // For getting usage percentages. 9 | WSystem{ 10 | id:wSystem 11 | } 12 | 13 | 14 | 15 | Timer{ 16 | interval: 750; running: true; repeat: true; 17 | onTriggered: { 18 | if(Qt.platform.os !== "linux" ){ 19 | cputext.text = "This widget works only on Linux Systems." 20 | running = false 21 | }else{ 22 | cputext.text = "CPU: " + wSystem.getCPUName() + 23 | "\n - Cores: " + wSystem.getCPUUsage() + "% (" + wSystem.getCPUCoresUsages().join("%, ") + "%)" + 24 | "\n - MHz(s): " + wSystem.getCPUCurrentClockSpeeds().join(", ") + "\n" + 25 | "GPU: " + "..." + "\n" + 26 | "Storage: " + "..." + "\n" + 27 | "Network: " + "..." + "\n" + 28 | "Process List: " + "..."; 29 | } 30 | } 31 | } 32 | 33 | Text{ 34 | id: cputext; 35 | text: "Getting cpu info..." 36 | color: "#FFFFFF" 37 | font.pixelSize: 16 38 | } 39 | } 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | -------------------------------------------------------------------------------- /widgetci/defaultwidgets/Watch/main.qml: -------------------------------------------------------------------------------- 1 | /* 2 | == Widgetci - https://github.com/eminfedar/widgetci == 3 | 4 | "THIS 'watch' IS ONE OF THE DEFAULT WIDGETS OF 'WIDGETCI'. 5 | CAN BE EDITED AND USED FREELY." 6 | 7 | - @eminfedar 8 | */ 9 | 10 | import QtQuick 2.5 11 | 12 | Item { 13 | id:base; 14 | width: (timeText.width > dateText.width ? timeText.width : dateText.width) + 8; 15 | height: dateText.height + dateText.y; 16 | 17 | property var locale: Qt.locale(); 18 | property real intervalMs: (60050 - ((new Date().getSeconds() * 1000) + new Date().getMilliseconds())); 19 | 20 | Timer{ 21 | interval: intervalMs; running: true; repeat: true; 22 | onTriggered: { 23 | intervalMs = 60000; // Did this because of precise reloading when the time arrived. 24 | timeText.text = new Date().toLocaleString(locale, "HH:mm"); 25 | base.width = (timeText.width > dateText.width ? timeText.width : dateText.width) + 8; 26 | } 27 | } 28 | Text{ 29 | id:timeText; 30 | x: (dateText.width - timeText.width > 0 ? (dateText.width - timeText.width) + 8 : 8); 31 | 32 | horizontalAlignment: Text.AlignRight; 33 | font.pointSize: 72; 34 | font.family: "San Francisco Display, Segoe UI Light, Noto Sans"; 35 | font.weight: Font.Thin; 36 | 37 | text: new Date().toLocaleString(locale, "HH:mm"); 38 | color: "#FFFFFF"; 39 | } 40 | 41 | Text{ 42 | id:dateText; 43 | x: (timeText.width - dateText.width > 0 ? (timeText.width - dateText.width) : 0); 44 | y: timeText.height - 14; 45 | 46 | horizontalAlignment: Text.AlignRight; 47 | font.pointSize: 24; 48 | font.family: "San Francisco Display, Segoe UI Light, Noto Sans"; 49 | font.weight: Font.Thin; 50 | 51 | text: new Date().toLocaleString(locale, "dddd, dd/MM"); 52 | color: "#FFFFFF"; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /widgetci/img/icon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eminfedar/widgetci/05588c036cd4c6d6eddd5b595d027968ac484140/widgetci/img/icon.ico -------------------------------------------------------------------------------- /widgetci/img/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eminfedar/widgetci/05588c036cd4c6d6eddd5b595d027968ac484140/widgetci/img/icon.png -------------------------------------------------------------------------------- /widgetci/img/reload.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eminfedar/widgetci/05588c036cd4c6d6eddd5b595d027968ac484140/widgetci/img/reload.png -------------------------------------------------------------------------------- /widgetci/img/showfolder.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eminfedar/widgetci/05588c036cd4c6d6eddd5b595d027968ac484140/widgetci/img/showfolder.png -------------------------------------------------------------------------------- /widgetci/img/toggleoff.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eminfedar/widgetci/05588c036cd4c6d6eddd5b595d027968ac484140/widgetci/img/toggleoff.png -------------------------------------------------------------------------------- /widgetci/img/toggleon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eminfedar/widgetci/05588c036cd4c6d6eddd5b595d027968ac484140/widgetci/img/toggleon.png -------------------------------------------------------------------------------- /widgetci/main.cpp: -------------------------------------------------------------------------------- 1 | #include "mainwindow.h" 2 | #include "runguard.h" 3 | #include 4 | #include 5 | #include 6 | 7 | int main(int argc, char *argv[]) 8 | { 9 | // Prevent multiple instances 10 | RunGuard guard( "widgetci_prevent_double_run" ); 11 | if ( !guard.tryToRun() ) return 0; 12 | 13 | // Define the application 14 | QApplication app(argc, argv); 15 | QApplication::setQuitOnLastWindowClosed(false); 16 | 17 | // App configs 18 | QCoreApplication::setOrganizationName("Widgetci"); 19 | QCoreApplication::setOrganizationDomain("widgetci.com"); 20 | QCoreApplication::setApplicationName("Widgetci"); 21 | 22 | // STYLING. 23 | QString style( 24 | "QHeaderView::section{" 25 | "background: #393939;" 26 | "padding: 3px;" 27 | "border: none;" 28 | "border-bottom: 1px solid #202020;" 29 | "}" 30 | "" 31 | "" 32 | "QTreeView{ selection-background-color:transparent; border: 1px solid #202020; background: #262626; }" 33 | "QTreeView::item{" 34 | "margin-left: 0px;" 35 | "padding: 3px;" 36 | "}" 37 | "QTreeView::item:selected, QTreeView::item:pressed{" 38 | "background-color: rgba(0, 150, 0, 80);" 39 | "margin:0px;" 40 | "padding:0px;" 41 | "}" 42 | "QTreeView::branch:selected{" 43 | "background-color: rgba(0, 0, 0, 0);" 44 | "margin:0;" 45 | "padding:0;" 46 | "}" 47 | "" 48 | "" 49 | "QMenu::item:selected{" 50 | "background-color: rgb(0, 150, 0);" 51 | "}" 52 | "" 53 | "QMenu::item:disabled{" 54 | "color: #BBBBBB;" 55 | "background-color: #393939;" 56 | "}" 57 | "" 58 | "*{" 59 | "background: #292929;" 60 | "color: #FFFFFF;" 61 | "}" 62 | "" 63 | ); 64 | app.setStyleSheet(style); 65 | 66 | 67 | // CHECK IF TRANSLATION AVAILABLE 68 | QTranslator translator; 69 | QString lang = QLocale::system().name().left(2); 70 | QString langStr = QLocale::system().languageToString(QLocale::system().language()); 71 | 72 | if(lang != "en"){ 73 | if(translator.load(":/translations/translations/widgetci_" + lang)){ 74 | app.installTranslator(&translator); 75 | }else{ 76 | qDebug() << "There is no available translations for your language."; 77 | qDebug() << "You can translate this program to " << langStr << " VISIT ==> https://github.com/eminfedar/widgetci/tree/master/widgetci/translations"; 78 | } 79 | } 80 | 81 | // Define the window 82 | mainWindow window; 83 | //w.show(); // not show if has opened widgets. but if hasn't, inside the constructor, widgetManager will be shown. 84 | 85 | // Start the app loop 86 | return app.exec(); 87 | } 88 | -------------------------------------------------------------------------------- /widgetci/mainwindow.cpp: -------------------------------------------------------------------------------- 1 | #include "mainwindow.h" 2 | #include "ui_mainwindow.h" 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | #include 16 | #include "wqmlfile.h" 17 | #include "wqmlsystem.h" 18 | 19 | mainWindow::mainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::mainWindow){ 20 | ui->setupUi(this); 21 | 22 | appConfig(); 23 | addTrayIcon(); 24 | addQmlApis(); 25 | 26 | addTreeRightClickMenu(); 27 | openWidgetsInFile(); 28 | } 29 | 30 | mainWindow::~mainWindow() 31 | { 32 | delete ui; 33 | } 34 | 35 | void mainWindow::addQmlApis(){ 36 | qmlRegisterType("com.widgetci.file", 1, 0, "WFile"); 37 | qmlRegisterType("com.widgetci.system", 1, 0, "WSystem"); 38 | } 39 | 40 | void mainWindow::openWidgetsInFile(){ 41 | widgetsDataSettings = new QSettings(appDataDir + "/widgets.ini", QSettings::IniFormat); 42 | 43 | int count = 0; 44 | for(auto e : widgetsDataSettings->childGroups()){ 45 | widgetsDataSettings->beginGroup(e); 46 | int wx = widgetsDataSettings->value("x", -1000).toInt(); 47 | int wy = widgetsDataSettings->value("y", -1000).toInt(); 48 | bool visible = widgetsDataSettings->value("visible", false).toBool(); 49 | widgetsDataSettings->endGroup(); 50 | 51 | if(visible){ 52 | toggleWidget(e, wx, wy); 53 | count++; 54 | } 55 | } 56 | if(count == 0) this->show(); // if no widgets visible, show the form. 57 | } 58 | 59 | // Toggle widgets 60 | void mainWindow::toggleWidget(QTreeWidgetItem *item, int wx = -1000, int wy = -1000){ 61 | QString wid_filename = item->text(0); 62 | 63 | // If widget not exists. Create one. 64 | if(!map_widgetList.contains(wid_filename)){ 65 | 66 | // Load configs about the widget 67 | QMap widConf = getWidgetSettings(item->text(0)); 68 | 69 | //Check if has spesific coordinates 70 | if(wx == -1000 || wy == -1000){ 71 | wx = widConf["x"].toInt(); 72 | wy = widConf["y"].toInt(); 73 | } 74 | 75 | // Add the widget 76 | WWidget *wid = new WWidget(QUrl::fromLocalFile(widgetsDir + "/" + wid_filename + "/main.qml"), wid_filename, wx, wy); 77 | wid->toggleZPos(widConf["z-pos"].toInt()); 78 | wid->widgetSettings = widgetsDataSettings; 79 | 80 | 81 | // Check for errors. (File not found etc...) 82 | if( wid->status() == QQuickView::Error ){ 83 | 84 | QString errorString = ""; 85 | for (int i = 0; i < wid->errors().length(); ++i) { 86 | errorString.append(wid->errors().at(i).toString()); 87 | } 88 | errorString.append(tr("\n\nPlease try to fix the error and refresh the list")); 89 | 90 | item->setBackground(0, QBrush(QColor(160,0,0,255))); 91 | item->setTextColor(0, QColor(180, 180, 180, 255)); 92 | item->setSelected(false); 93 | 94 | QMessageBox::warning(this, tr("An error occured"), errorString, QMessageBox::Ok); 95 | return; 96 | }else if(wid->status() == QQuickView::Ready){ 97 | item->setBackground(0, QBrush(QColor(0,0,0,0))); 98 | } 99 | 100 | 101 | map_widgetList.insert(wid->filename, wid); 102 | 103 | item->setIcon(0, ico_toggleon); 104 | item->setTextColor(0, colorOn); 105 | 106 | // Delete the widget from list when destroyed 107 | disconnect(wid, &QQuickWindow::destroyed, 0, 0); 108 | connect(wid, &QQuickWindow::destroyed, [=]{ 109 | if(map_widgetList.contains(wid->filename)){ 110 | if(!CLOSING) saveWidgetSettings(wid->filename); // Save settings before closing the widgets. 111 | 112 | map_widgetList.remove(wid->filename); 113 | 114 | QList item_lst = obj_widgetList->findItems(wid->filename, Qt::MatchExactly, 0); 115 | if(item_lst.length() > 0){ 116 | item_lst[0]->setTextColor(0, colorOff); 117 | item_lst[0]->setIcon(0, ico_toggleoff); 118 | } 119 | } 120 | }); 121 | 122 | }else if(map_widgetList.contains(wid_filename)){ 123 | delete map_widgetList[wid_filename]; 124 | } 125 | } 126 | void mainWindow::toggleWidget(QString widgetName, int wx = -1000, int wy = -1000){ 127 | QList items = obj_widgetList->findItems(widgetName, Qt::MatchExactly, 0); 128 | if(items.length() > 0){ 129 | toggleWidget(items[0], wx, wy); 130 | } 131 | } 132 | 133 | QMap mainWindow::getWidgetSettings(QString widgetname){ 134 | QMap mapTmp; 135 | 136 | widgetsDataSettings->beginGroup(widgetname); 137 | mapTmp["x"] = widgetsDataSettings->value("x", -1000); 138 | mapTmp["y"] = widgetsDataSettings->value("y", -1000); 139 | mapTmp["visible"] = widgetsDataSettings->value("visible", false); 140 | mapTmp["z-pos"] = widgetsDataSettings->value("z-pos", 0); 141 | mapTmp["lock"] = widgetsDataSettings->value("lock", false); 142 | widgetsDataSettings->endGroup(); 143 | 144 | return mapTmp; 145 | } 146 | 147 | void mainWindow::saveWidgetSettings(QString widgetname){ 148 | widgetsDataSettings->beginGroup(widgetname); 149 | widgetsDataSettings->setValue("x", map_widgetList[widgetname]->x()); 150 | widgetsDataSettings->setValue("y", map_widgetList[widgetname]->y()); 151 | widgetsDataSettings->setValue("visible", map_widgetList[widgetname]->isVisible()); 152 | widgetsDataSettings->setValue("z-pos", map_widgetList[widgetname]->z_pos); 153 | widgetsDataSettings->endGroup(); 154 | widgetsDataSettings->sync(); 155 | } 156 | 157 | void mainWindow::updateWidgetList(QTreeWidget* widgetList_obj){ 158 | QMap tmpWidgetsMap(map_widgetList); 159 | widgetList_obj->clear(); 160 | 161 | QDir dir(widgetsDir); 162 | QStringList folderList = dir.entryList(QDir::Dirs | QDir::NoDotAndDotDot); 163 | 164 | // Close all widgets (to open just available ones later) 165 | for(QString e : map_widgetList.keys()){ 166 | delete map_widgetList.value(e); 167 | } 168 | 169 | // Add folders one by one 170 | for(int i=0; isetText(0, folder); 175 | item->setIcon(0, ico_toggleoff); 176 | 177 | if(tmpWidgetsMap.contains(folder)){ 178 | toggleWidget(folder); 179 | //item->setIcon(0, ico_toggleon); 180 | } 181 | } 182 | 183 | // Enable|Disable widgets by double clicking on themauto 184 | disconnect(widgetList_obj, &QTreeWidget::itemActivated, 0, 0); // prevent multiple connections & runs 185 | connect(widgetList_obj, &QTreeWidget::itemActivated, [=](QTreeWidgetItem* item) { 186 | toggleWidget(item); 187 | }); 188 | } 189 | 190 | void mainWindow::addTreeRightClickMenu(){ 191 | // Initialize the variables 192 | ico_toggleoff = QIcon(":/img/toggleoff.png"); 193 | ico_toggleon = QIcon(":/img/toggleon.png"); 194 | colorOn = QColor(0, 230, 0, 255); 195 | colorOff = QColor(255, 255, 255, 255); 196 | 197 | 198 | // QTreeWidget list object from ui: 199 | obj_widgetList = ui->obj_widgetList; 200 | 201 | // Update & Refresh the widgets 202 | updateWidgetList(obj_widgetList); 203 | 204 | // Right Click Menu 205 | obj_widgetList->setContextMenuPolicy(Qt::CustomContextMenu); 206 | menu_wlRightClick = new QMenu(this); 207 | 208 | // Right Click Menu Actions 209 | QAction* act_wlrc_ShowHide = new QAction(tr("Show"), this); 210 | connect(act_wlrc_ShowHide, &QAction::triggered, [=]{ 211 | // Show/Hide Action 212 | toggleWidget(obj_widgetList->currentItem()); 213 | }); 214 | QAction* act_wlrc_Edit = new QAction(tr("Edit"), this); 215 | connect(act_wlrc_Edit, &QAction::triggered, [=]{ 216 | // Edit the widget file with default editor 217 | QDesktopServices::openUrl(QUrl::fromLocalFile(widgetsDir + "/" + obj_widgetList->currentItem()->text(0) + "/main.qml")); 218 | }); 219 | QAction* act_wlrc_Reload = new QAction(tr("Reload"), this); 220 | connect(act_wlrc_Reload, &QAction::triggered, [=]{ 221 | // Reload the widget 222 | if(map_widgetList.contains(obj_widgetList->currentItem()->text(0))) 223 | map_widgetList.value(obj_widgetList->currentItem()->text(0))->reload(); 224 | }); 225 | QAction* act_wlrc_RefreshTheList = new QAction(tr("Refresh the list"), this); 226 | connect(act_wlrc_RefreshTheList, &QAction::triggered, [=]{ 227 | // Refresh all the list. 228 | updateWidgetList(obj_widgetList); 229 | }); 230 | QAction* act_wlrc_Delete = new QAction(tr("Remove"), this); 231 | connect(act_wlrc_Delete, &QAction::triggered, [=]{ 232 | if(map_widgetList.contains(obj_widgetList->currentItem()->text(0))) 233 | toggleWidget(obj_widgetList->currentItem()->text(0)); 234 | delete obj_widgetList->currentItem(); 235 | obj_widgetList->clearSelection(); 236 | }); 237 | QAction* act_wlrc_DeleteDisk = new QAction(tr("Delete From Disk..."), this); 238 | connect(act_wlrc_DeleteDisk, &QAction::triggered, [=]{ 239 | int answer = QMessageBox::warning(this, tr("Warning"), tr("The '%1' folder will be deleted from disk.\n\nAre you sure?").arg(obj_widgetList->currentItem()->text(0)), QMessageBox::Cancel | QMessageBox::Ok); 240 | if(answer == QMessageBox::Ok){ 241 | QDir folder(widgetsDir + "/" + obj_widgetList->currentItem()->text(0)); 242 | if(folder.removeRecursively()){ 243 | QMessageBox::information(this, tr("Information"), tr("The folder has been deleted successfully."), QMessageBox::Ok); 244 | if(map_widgetList.contains(obj_widgetList->currentItem()->text(0))){ 245 | toggleWidget(obj_widgetList->currentItem()->text(0)); 246 | updateWidgetList(obj_widgetList); 247 | } 248 | 249 | }else{ 250 | QMessageBox::critical(this, tr("Information"), tr("The folder couldn't be removed.\nCheck the folder and the files may be using by another program."), QMessageBox::Ok); 251 | } 252 | 253 | 254 | } 255 | }); 256 | 257 | 258 | 259 | // Add Actions to the QTreeWidget's Right Click Menu 260 | menu_wlRightClick->addAction(act_wlrc_ShowHide); 261 | menu_wlRightClick->addSeparator(); 262 | menu_wlRightClick->addAction(act_wlrc_Reload); 263 | menu_wlRightClick->addAction(act_wlrc_Edit); 264 | menu_wlRightClick->addAction(act_wlrc_RefreshTheList); 265 | menu_wlRightClick->addSeparator(); 266 | menu_wlRightClick->addAction(act_wlrc_Delete); 267 | menu_wlRightClick->addAction(act_wlrc_DeleteDisk); 268 | connect(obj_widgetList, &QTreeWidget::customContextMenuRequested, [=](const QPoint & pos) { 269 | QPoint pt(pos); 270 | pt.setX(pt.x()+2); 271 | pt.setY(pt.y()+22); 272 | 273 | QTreeWidgetItem *item = obj_widgetList->currentItem(); 274 | QString wid_filename = item->text(0); 275 | if(!map_widgetList.contains(wid_filename)){ 276 | act_wlrc_ShowHide->setText(tr("Show")); 277 | act_wlrc_Reload->setEnabled(false); 278 | }else if(map_widgetList.contains(wid_filename)){ 279 | act_wlrc_ShowHide->setText(tr("Hide")); 280 | act_wlrc_Reload->setEnabled(true); 281 | } 282 | 283 | menu_wlRightClick->exec( obj_widgetList->mapToGlobal(pt) ); 284 | }); 285 | } 286 | 287 | void mainWindow::addActionsToTray(){ 288 | // Create Menu & Items 289 | trayMenu = new QMenu(this); 290 | QAction* openManager = new QAction(tr("Open Manager..."), this); 291 | QAction* reloadAll = new QAction(tr("Reload All"), this); 292 | QAction* quit = new QAction(tr("Quit"), this); 293 | 294 | trayMenu->addAction(openManager); 295 | trayMenu->addAction(reloadAll); 296 | trayMenu->addSeparator(); 297 | trayMenu->addAction(quit); 298 | 299 | 300 | 301 | // Connect 302 | connect(openManager, &QAction::triggered, [=]{ 303 | this->setVisible(true); 304 | this->raise(); 305 | QApplication::setActiveWindow(this); 306 | }); 307 | connect(reloadAll, &QAction::triggered, [=]{ 308 | for(auto e : map_widgetList.keys()){ 309 | map_widgetList.value(e)->reload(); 310 | } 311 | }); 312 | connect(quit, &QAction::triggered, [=]{ 313 | onAppQuit(); 314 | }); 315 | } 316 | 317 | void mainWindow::addTrayIcon(){ 318 | // Add actions 319 | addActionsToTray(); 320 | 321 | 322 | // Set the app icon 323 | appIcon = new QIcon(":/img/icon.png"); 324 | setWindowIcon(*appIcon); 325 | 326 | 327 | // Set the tray 328 | trayIcon = new QSystemTrayIcon(this); 329 | trayIcon->setContextMenu(trayMenu); 330 | trayIcon->setIcon(*appIcon); 331 | trayIcon->show(); 332 | connect(trayIcon, &QSystemTrayIcon::activated, [=](QSystemTrayIcon::ActivationReason reason){ 333 | if(reason == QSystemTrayIcon::DoubleClick){ 334 | this->setVisible(true); 335 | this->raise(); 336 | QApplication::setActiveWindow(this); 337 | } 338 | }); 339 | 340 | } 341 | 342 | void mainWindow::appConfig(){ 343 | // Set directory variables. 344 | appDataDir = QStandardPaths::standardLocations(QStandardPaths::AppDataLocation)[0]; 345 | widgetsDir = appDataDir + "/widgets"; 346 | 347 | // Create the directory if not exists. 348 | QDir dir(widgetsDir); 349 | if(!dir.exists()){ 350 | QDir localdir(":/widgets/defaultwidgets/"); 351 | QStringList folderList = localdir.entryList(QDir::Dirs | QDir::NoDotAndDotDot); 352 | 353 | // Copy the local folders one by one 354 | QFile file; 355 | for(int i=0; iobj_widgetList); 384 | } 385 | 386 | // Before the app quit 387 | void mainWindow::onAppQuit(){ 388 | CLOSING = true; 389 | 390 | // Close the widgets too. 391 | for(auto e : map_widgetList.keys()){ 392 | // Save widget configs. 393 | saveWidgetSettings(e); 394 | 395 | // Destroy them. 396 | delete map_widgetList.value(e); 397 | } 398 | QApplication::quit(); 399 | } 400 | 401 | // Window Close Event 402 | void mainWindow::closeEvent(QCloseEvent *event){ 403 | event->ignore(); 404 | this->setVisible(false); 405 | } 406 | -------------------------------------------------------------------------------- /widgetci/mainwindow.h: -------------------------------------------------------------------------------- 1 | #ifndef MAINWINDOW_H 2 | #define MAINWINDOW_H 3 | 4 | #include 5 | #include "wwidget.h" 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | 16 | namespace Ui { 17 | class mainWindow; 18 | class WWidget; 19 | } 20 | 21 | // MAIN MANAGER WINDOWS 22 | class mainWindow : public QMainWindow 23 | { 24 | Q_OBJECT 25 | 26 | public: 27 | explicit mainWindow(QWidget *parent = 0); 28 | ~mainWindow(); 29 | 30 | bool CLOSING = false; 31 | 32 | private slots: 33 | void on_obj_showFolderBtn_clicked(); 34 | void on_obj_refreshWidgetListBtn_clicked(); 35 | 36 | private: 37 | Ui::mainWindow *ui; 38 | 39 | // Listing the widgets: 40 | void updateWidgetList(QTreeWidget* widgetList_obj); 41 | void addTreeRightClickMenu(); 42 | void toggleWidget(QTreeWidgetItem *item, int x, int y); 43 | void toggleWidget(QString widgetName, int x, int y); 44 | 45 | QSettings* widgetsDataSettings; 46 | QMap getWidgetSettings(QString name); 47 | void saveWidgetSettings(QString name); 48 | 49 | QTreeWidget *obj_widgetList; 50 | QMap map_widgetList; 51 | QIcon ico_toggleoff, ico_toggleon; 52 | QMenu *menu_wlRightClick; // menu_widgetlistRightClick 53 | QColor colorOn; 54 | QColor colorOff; 55 | 56 | // Tray Menu 57 | void addTrayIcon(); 58 | void addActionsToTray(); 59 | QSystemTrayIcon *trayIcon; 60 | QMenu *trayMenu; 61 | QIcon *appIcon; 62 | 63 | // App Config 64 | void appConfig(); 65 | QString appDataDir, widgetsDir; 66 | 67 | // Adding apis for qml using. (like file managing in qml) 68 | void addQmlApis(); 69 | 70 | // onStart 71 | void openWidgetsInFile(); 72 | 73 | // onQuit 74 | void onAppQuit(); 75 | 76 | protected: 77 | void closeEvent(QCloseEvent *event); 78 | }; 79 | 80 | #endif // MAINWINDOW_H 81 | -------------------------------------------------------------------------------- /widgetci/mainwindow.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | mainWindow 4 | 5 | 6 | 7 | 0 8 | 0 9 | 401 10 | 314 11 | 12 | 13 | 14 | Widgetci 15 | 16 | 17 | 18 | :/img/icon.png:/img/icon.png 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | Widgets 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | Go to http://github.com/eminfedar/widgetci 45 | 46 | 47 | <html><head/><body><p><a href="http://github.com/eminfedar/widgetci"><span style=" font-size:10pt; font-style:italic; text-decoration: underline; color:#00cc00;">contribute on GitHub</span></a></p></body></html> 48 | 49 | 50 | Qt::RichText 51 | 52 | 53 | true 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 0 62 | 0 63 | 64 | 65 | 66 | 67 | 24 68 | 24 69 | 70 | 71 | 72 | 73 | 24 74 | 24 75 | 76 | 77 | 78 | Refresh the widgets list 79 | 80 | 81 | 82 | 83 | 84 | 85 | :/img/reload.png:/img/reload.png 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 0 94 | 0 95 | 96 | 97 | 98 | 99 | 24 100 | 24 101 | 102 | 103 | 104 | 105 | 24 106 | 24 107 | 108 | 109 | 110 | Open the widgets folder... 111 | 112 | 113 | 114 | 115 | 116 | 117 | :/img/showfolder.png:/img/showfolder.png 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | -------------------------------------------------------------------------------- /widgetci/qtresource.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | img/showfolder.png 4 | img/toggleoff.png 5 | img/toggleon.png 6 | img/icon.png 7 | img/reload.png 8 | 9 | 10 | defaultwidgets/Example/test.png 11 | defaultwidgets/Example/main.qml 12 | defaultwidgets/Note/main.qml 13 | defaultwidgets/Watch/main.qml 14 | defaultwidgets/Image/main.qml 15 | defaultwidgets/Image/clock_img.jpg 16 | defaultwidgets/Arabic Watch/main.qml 17 | defaultwidgets/SystemInfo/main.qml 18 | defaultwidgets/Image/image.conf 19 | defaultwidgets/Image/resizer.png 20 | defaultwidgets/Note/notes.txt 21 | 22 | 23 | translations/widgetci_tr.ts 24 | translations/widgetci_tr.qm 25 | 26 | 27 | -------------------------------------------------------------------------------- /widgetci/runguard.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | -------------------------------------------------------------------------------- 3 | - Module : runGuard.cpp 4 | - Description : This file for usage with QT makes sure only a single 5 | - instance of the program is run. 6 | - Author : SaZ from Stackoverflow 7 | - Tim Zaman, 18-FEB-2016 8 | -------------------------------------------------------------------------------- 9 | */ 10 | 11 | #include "runguard.h" 12 | 13 | #include 14 | 15 | 16 | namespace 17 | { 18 | 19 | QString generateKeyHash( const QString& key, const QString& salt ) 20 | { 21 | QByteArray data; 22 | 23 | data.append( key.toUtf8() ); 24 | data.append( salt.toUtf8() ); 25 | data = QCryptographicHash::hash( data, QCryptographicHash::Sha1 ).toHex(); 26 | 27 | return data; 28 | } 29 | 30 | } 31 | 32 | 33 | RunGuard::RunGuard( const QString& key ) 34 | : key( key ) 35 | , memLockKey( generateKeyHash( key, "_memLockKey" ) ) 36 | , sharedmemKey( generateKeyHash( key, "_sharedmemKey" ) ) 37 | , sharedMem( sharedmemKey ) 38 | , memLock( memLockKey, 1 ) 39 | { 40 | memLock.acquire(); 41 | { 42 | QSharedMemory fix( sharedmemKey ); // Fix for *nix: http://habrahabr.ru/post/173281/ 43 | fix.attach(); 44 | } 45 | memLock.release(); 46 | } 47 | 48 | RunGuard::~RunGuard() 49 | { 50 | release(); 51 | } 52 | 53 | bool RunGuard::isAnotherRunning() 54 | { 55 | if ( sharedMem.isAttached() ) 56 | return false; 57 | 58 | memLock.acquire(); 59 | const bool isRunning = sharedMem.attach(); 60 | if ( isRunning ) 61 | sharedMem.detach(); 62 | memLock.release(); 63 | 64 | return isRunning; 65 | } 66 | 67 | bool RunGuard::tryToRun() 68 | { 69 | if ( isAnotherRunning() ) // Extra check 70 | return false; 71 | 72 | memLock.acquire(); 73 | const bool result = sharedMem.create( sizeof( quint64 ) ); 74 | memLock.release(); 75 | if ( !result ) 76 | { 77 | release(); 78 | return false; 79 | } 80 | 81 | return true; 82 | } 83 | 84 | void RunGuard::release() 85 | { 86 | memLock.acquire(); 87 | if ( sharedMem.isAttached() ) 88 | sharedMem.detach(); 89 | memLock.release(); 90 | } 91 | -------------------------------------------------------------------------------- /widgetci/runguard.h: -------------------------------------------------------------------------------- 1 | /** 2 | -------------------------------------------------------------------------------- 3 | - Module : runGuard.h 4 | - Description : This file for usage with QT makes sure only a single 5 | - instance of the program is run. 6 | - Author : SaZ from Stackoverflow 7 | - Tim Zaman, 18-FEB-2016 8 | -------------------------------------------------------------------------------- 9 | */ 10 | 11 | #ifndef RUNGUARD_H 12 | #define RUNGUARD_H 13 | 14 | #include 15 | #include 16 | #include 17 | 18 | 19 | class RunGuard 20 | { 21 | 22 | public: 23 | RunGuard( const QString& key ); 24 | ~RunGuard(); 25 | 26 | bool isAnotherRunning(); 27 | bool tryToRun(); 28 | void release(); 29 | 30 | private: 31 | const QString key; 32 | const QString memLockKey; 33 | const QString sharedmemKey; 34 | 35 | QSharedMemory sharedMem; 36 | QSystemSemaphore memLock; 37 | 38 | Q_DISABLE_COPY( RunGuard ) 39 | }; 40 | 41 | 42 | #endif // RUNGUARD_H 43 | -------------------------------------------------------------------------------- /widgetci/translations/widgetci_empty.ts: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | WWidget 6 | 7 | 8 | Hide 9 | 10 | 11 | 12 | 13 | Reload 14 | 15 | 16 | 17 | 18 | Edit 19 | 20 | 21 | 22 | 23 | Always on Most top 24 | 25 | 26 | 27 | 28 | Always on top 29 | 30 | 31 | 32 | 33 | Normal 34 | 35 | 36 | 37 | 38 | Always on bottom 39 | 40 | 41 | 42 | 43 | Lock 44 | 45 | 46 | 47 | 48 | Z-Position 49 | 50 | 51 | 52 | 53 | mainWindow 54 | 55 | 56 | Widgetci 57 | 58 | 59 | 60 | 61 | Widgets 62 | 63 | 64 | 65 | 66 | Go to http://github.com/eminfedar/widgetci 67 | 68 | 69 | 70 | 71 | <html><head/><body><p><a href="http://github.com/eminfedar/widgetci"><span style=" font-size:10pt; font-style:italic; text-decoration: underline; color:#00cc00;">contribute on GitHub</span></a></p></body></html> 72 | 73 | 74 | 75 | 76 | Refresh the widgets list 77 | 78 | 79 | 80 | 81 | Open the widgets folder... 82 | 83 | 84 | 85 | 86 | 87 | 88 | Please try to fix the error and refresh the list 89 | 90 | 91 | 92 | 93 | An error occured 94 | 95 | 96 | 97 | 98 | 99 | Show 100 | 101 | 102 | 103 | 104 | Edit 105 | 106 | 107 | 108 | 109 | Reload 110 | 111 | 112 | 113 | 114 | Refresh the list 115 | 116 | 117 | 118 | 119 | Remove 120 | 121 | 122 | 123 | 124 | Delete From Disk... 125 | 126 | 127 | 128 | 129 | Warning 130 | 131 | 132 | 133 | 134 | The '%1' folder will be deleted from disk. 135 | 136 | Are you sure? 137 | 138 | 139 | 140 | 141 | 142 | Information 143 | 144 | 145 | 146 | 147 | The folder has been deleted successfully. 148 | 149 | 150 | 151 | 152 | The folder couldn't be removed. 153 | Check the folder and the files may be using by another program. 154 | 155 | 156 | 157 | 158 | Hide 159 | 160 | 161 | 162 | 163 | Open Manager... 164 | 165 | 166 | 167 | 168 | Reload All 169 | 170 | 171 | 172 | 173 | Quit 174 | 175 | 176 | 177 | 178 | wqmlfile 179 | 180 | 181 | 182 | 183 | 184 | ERR: 1st parameter is empty or null. 185 | 186 | 187 | 188 | 189 | 190 | 191 | ERR: 2nd parameter is empty or null. 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | ERR: Can't access the file 200 | (maybe some program using it): 201 | 202 | 203 | 204 | 205 | ERR: 3rd parameter is empty or null. 206 | 207 | 208 | 209 | 210 | -------------------------------------------------------------------------------- /widgetci/translations/widgetci_tr.qm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eminfedar/widgetci/05588c036cd4c6d6eddd5b595d027968ac484140/widgetci/translations/widgetci_tr.qm -------------------------------------------------------------------------------- /widgetci/translations/widgetci_tr.ts: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | WWidget 6 | 7 | 8 | Hide 9 | Gizle 10 | 11 | 12 | 13 | Move 14 | Taşı 15 | 16 | 17 | 18 | Reload 19 | Yenile 20 | 21 | 22 | 23 | Edit 24 | Düzenle 25 | 26 | 27 | 28 | Always on Most top 29 | Her zaman En Üstte 30 | 31 | 32 | 33 | Always on top 34 | Her zaman Üstte 35 | 36 | 37 | 38 | Normal 39 | Normal 40 | 41 | 42 | 43 | Always on bottom 44 | Her zaman altta 45 | 46 | 47 | Lock 48 | Kilitle 49 | 50 | 51 | 52 | Z-Position 53 | Z-Pozisyon 54 | 55 | 56 | 57 | mainWindow 58 | 59 | 60 | Widgetci 61 | 62 | 63 | 64 | 65 | Widgets 66 | Widgetler 67 | 68 | 69 | 70 | Go to http://github.com/eminfedar/widgetci 71 | http://github.com/eminfedar/widgetci adresine gidin 72 | 73 | 74 | 75 | <html><head/><body><p><a href="http://github.com/eminfedar/widgetci"><span style=" font-size:10pt; font-style:italic; text-decoration: underline; color:#00cc00;">contribute on GitHub</span></a></p></body></html> 76 | <html><head/><body><p><a href="http://github.com/eminfedar/widgetci"><span style=" font-size:10pt; font-style:italic; text-decoration: underline; color:#00cc00;">GıtHub adresine git</span></a></p></body></html> 77 | 78 | 79 | 80 | Refresh the widgets list 81 | Widget listesini Yenile 82 | 83 | 84 | 85 | Open the widgets folder... 86 | Widgetlerin bulunduğu klasörü aç... 87 | 88 | 89 | 90 | 91 | Please try to fix the error and refresh the list. 92 | 93 | 94 | Lütfen hatayı çözün ve listeyi tekrardan yenileyin. 95 | 96 | 97 | 98 | 99 | 100 | Please try to fix the error and refresh the list 101 | 102 | 103 | Lütfen kodlardaki hatayı çözün ve widgeti tekrar yenileyin 104 | 105 | 106 | 107 | An error occured 108 | Bir hata oluştur 109 | 110 | 111 | 112 | 113 | Show 114 | Göster 115 | 116 | 117 | 118 | Edit 119 | Düzenle 120 | 121 | 122 | 123 | Reload 124 | Yenile 125 | 126 | 127 | 128 | Refresh the list 129 | Listeyi yenile 130 | 131 | 132 | 133 | Remove 134 | Kaldır 135 | 136 | 137 | 138 | Delete From Disk... 139 | Diskten sil... 140 | 141 | 142 | 143 | Warning 144 | Uyarı 145 | 146 | 147 | 148 | The '%1' folder will be deleted from disk. 149 | 150 | Are you sure? 151 | '%1' klasörü diskten silinecek. 152 | 153 | Emin misiniz? 154 | 155 | 156 | 157 | 158 | Information 159 | Bilgi 160 | 161 | 162 | 163 | The folder has been deleted successfully. 164 | Klasör başarıyla silindi. 165 | 166 | 167 | 168 | The folder couldn't be removed. 169 | Check the folder and the files may be using by another program. 170 | Klasör silinemedi. 171 | Klasörün veya dosyaların başka bir program tarafından kullanılmadığına emin olun. 172 | 173 | 174 | 175 | Hide 176 | Gizle 177 | 178 | 179 | 180 | Open Manager... 181 | Yöneticiyi Aç... 182 | 183 | 184 | 185 | Reload All 186 | Hepsini Yenile 187 | 188 | 189 | 190 | Quit 191 | Çıkış 192 | 193 | 194 | 195 | wqmlfile 196 | 197 | 198 | 199 | 200 | 201 | ERR: 1st parameter is empty or null. 202 | HATA: 1. Parametre boş veya null. 203 | 204 | 205 | 206 | 207 | 208 | ERR: 2nd parameter is empty or null. 209 | HATA: 2. Parametre boş veya null. 210 | 211 | 212 | 213 | 214 | 215 | 216 | ERR: Can't access the file 217 | (maybe some program using it): 218 | HATA: Dosyaya erişilemiyor 219 | (Bir programın dosyayı kullanmadığına emin olun): 220 | 221 | 222 | 223 | ERR: 3rd parameter is empty or null. 224 | HATA: 3. Parametre boş veya null. 225 | 226 | 227 | 228 | wqmlsystem 229 | 230 | 231 | ERR: Can't access the file 232 | (maybe some program using it): 233 | HATA: Dosyaya erişilemiyor 234 | (Bir programın dosyayı kullanmadığına emin olun): 235 | 236 | 237 | 238 | 239 | Can't find the CPU Name 240 | CPU İsmi bulunamadı 241 | 242 | 243 | 244 | -------------------------------------------------------------------------------- /widgetci/widgetci.rc: -------------------------------------------------------------------------------- 1 | IDI_ICON1 ICON DISCARDABLE "img/icon.ico" -------------------------------------------------------------------------------- /widgetci/wqmlfile.cpp: -------------------------------------------------------------------------------- 1 | #include "wqmlfile.h" 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | wqmlfile::wqmlfile() 9 | { 10 | appDataDir = QStandardPaths::standardLocations(QStandardPaths::AppDataLocation)[0]; 11 | widgetsDir = appDataDir + "/widgets/"; 12 | } 13 | 14 | 15 | QString wqmlfile::readFile(QString widgetName, QString file) const{ 16 | // Checking if parameters are null or empty. 17 | if(widgetName.isEmpty() || widgetName.isNull()){ 18 | return tr("ERR: 1st parameter is empty or null.") + " (widgetName)"; 19 | } 20 | if(file.isEmpty() || file.isNull()){ 21 | return tr("ERR: 2nd parameter is empty or null.") + " (file)"; 22 | } 23 | 24 | 25 | // Default path for creating file from qml is '%appDataDir%/widgets/%widgetName%'. 26 | file = widgetsDir + widgetName + "/" + file; 27 | 28 | 29 | // Creating the file and opening. 30 | QFile fi(file); 31 | if(!fi.open(QFile::ReadWrite | QFile::Text)) 32 | return tr("ERR: Can't access the file\n(maybe some program using it):") + file; 33 | 34 | // Reading. 35 | QTextStream in(&fi); 36 | QString content = in.readAll(); 37 | fi.close(); 38 | 39 | return content; 40 | } 41 | 42 | QString wqmlfile::saveFile(QString widgetName, QString file, QString data) const{ 43 | // Checking if parameters are null or empty. 44 | if(widgetName.isEmpty() || widgetName.isNull()){ 45 | return tr("ERR: 1st parameter is empty or null.") + " (widgetName)"; 46 | } 47 | if(file.isEmpty() || file.isNull()){ 48 | return tr("ERR: 2nd parameter is empty or null.") + " (file)"; 49 | } 50 | if(data.isEmpty() || data.isNull()){ 51 | return tr("ERR: 3rd parameter is empty or null.") + " (data)"; 52 | } 53 | 54 | 55 | // Default path for creating file from qml is '%appDataDir%/widgets/%widgetName%'. 56 | file = widgetsDir + widgetName + "/" + file; 57 | 58 | 59 | // Opening the file 60 | QFile fi(file); 61 | if(!fi.open(QFile::WriteOnly | QFile::Text)) 62 | return tr("ERR: Can't access the file\n(maybe some program using it):") + file; 63 | 64 | // Write the file. 65 | QTextStream out(&fi); 66 | out << data; 67 | fi.close(); 68 | 69 | return ""; 70 | } 71 | 72 | QString wqmlfile::readFileAnywhere(QString file) const{ 73 | // Checking if parameters are null or empty. 74 | if(file.isEmpty() || file.isNull()){ 75 | return tr("ERR: 1st parameter is empty or null.") + " (file)"; 76 | } 77 | 78 | // Creating the file and opening. 79 | QFile fi(file); 80 | if(!fi.open(QFile::ReadWrite | QFile::Text)) 81 | return tr("ERR: Can't access the file\n(maybe some program using it):") + file; 82 | 83 | // Reading. 84 | QTextStream in(&fi); 85 | QString content = in.readAll(); 86 | fi.close(); 87 | 88 | return content; 89 | } 90 | 91 | QString wqmlfile::saveFileAnywhere(QString file, QString data) const{ 92 | // Checking if parameters are null or empty. 93 | if(file.isEmpty() || file.isNull()){ 94 | return tr("ERR: 1st parameter is empty or null.") + " (file)"; 95 | } 96 | if(data.isEmpty() || data.isNull()){ 97 | return tr("ERR: 2nd parameter is empty or null.") + " (data)"; 98 | } 99 | 100 | // Opening the file 101 | QFile fi(file); 102 | if(!fi.open(QFile::WriteOnly | QFile::Text)) 103 | return tr("ERR: Can't access the file\n(maybe some program using it):") + file; 104 | 105 | // Write the file. 106 | QTextStream out(&fi); 107 | out << data; 108 | fi.close(); 109 | 110 | return ""; 111 | } 112 | -------------------------------------------------------------------------------- /widgetci/wqmlfile.h: -------------------------------------------------------------------------------- 1 | #ifndef WQMLFILE_H 2 | #define WQMLFILE_H 3 | 4 | #include 5 | 6 | class wqmlfile : public QObject 7 | { 8 | Q_OBJECT 9 | 10 | public: 11 | wqmlfile(); 12 | 13 | QString appDataDir, widgetsDir; 14 | 15 | public slots: 16 | QString readFile(QString widgetName, QString path) const; 17 | QString saveFile(QString widgetName, QString path, QString data) const; 18 | 19 | QString readFileAnywhere(QString path) const; 20 | QString saveFileAnywhere(QString path, QString data) const; 21 | }; 22 | 23 | #endif // WQMLFILE_H 24 | -------------------------------------------------------------------------------- /widgetci/wqmlsystem.cpp: -------------------------------------------------------------------------------- 1 | #include "wqmlsystem.h" 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | wqmlsystem::wqmlsystem() 9 | { 10 | // UPDATE CPU VALUES EVERY 100 MS. 11 | timer = new QTimer(this); 12 | updateCPUValues(); 13 | connect(timer, &QTimer::timeout, [=]{ 14 | updateCPUValues(); 15 | }); 16 | timer->start(100); 17 | } 18 | 19 | ////// ---- --- ---- ////// 20 | ////// ---- CPU ---- ////// 21 | ////// ---- --- ---- ////// 22 | void wqmlsystem::updateCPUValues(){ 23 | #ifdef Q_OS_LINUX 24 | QFile file("/proc/stat"); 25 | if(!file.open(QIODevice::ReadOnly | QIODevice::Text)) 26 | return; 27 | 28 | // Transfer the new array to the old one because we will fill new array with new values. 29 | for (int i = 0; i < 64; ++i) { 30 | for (int j = 0; j < 2; ++j) { 31 | run_idles1[i][j] = run_idles2[i][j]; 32 | run_idles2[i][j] = 0; 33 | } 34 | } 35 | 36 | int core_count = 0; 37 | 38 | // FIRST CHECK 39 | QTextStream in(&file); 40 | QString line = in.readLine(); 41 | while(!line.isNull()){ 42 | if(line.left(3) == "cpu" && line.left(4) != "cpu "){ 43 | 44 | QStringList usageList = line.split(" "); 45 | usageList.removeFirst(); 46 | run_idles2[core_count][0] = usageList.at(0).toInt() + usageList.at(1).toInt() + usageList.at(2).toInt() + usageList.at(5).toInt() + usageList.at(6).toInt() + usageList.at(7).toInt() + usageList.at(8).toInt() + usageList.at(9).toInt(); // RUN 47 | run_idles2[core_count][1] = usageList.at(3).toInt() + usageList.at(4).toInt(); // IDLE 48 | core_count++; 49 | } 50 | line = in.readLine(); 51 | } 52 | file.close(); 53 | 54 | // COMPARE: 55 | cpu_cores.clear(); // Clear old ones. 56 | for (int i = 0; i < core_count; ++i) { 57 | int diffRun = run_idles2[i][0] - run_idles1[i][0]; 58 | int diffIdle = run_idles2[i][1] - run_idles1[i][1]; 59 | int diffTotal = diffIdle + diffRun; 60 | 61 | // Write new values. 62 | if(diffTotal == 0) diffTotal = 1; 63 | cpu_cores.append(100 * diffRun / diffTotal); 64 | } 65 | #endif 66 | #ifdef Q_OS_WIN 67 | return; 68 | #endif 69 | } 70 | 71 | QList wqmlsystem::getCPUCoresUsages() const{ 72 | #ifdef Q_OS_LINUX 73 | return cpu_cores; 74 | #endif 75 | #ifdef Q_OS_WIN 76 | return; 77 | #endif 78 | } 79 | 80 | int wqmlsystem::getCPUUsage() const{ 81 | #ifdef Q_OS_LINUX 82 | int totalUsage = 0; 83 | for (int i = 0; i < cpu_cores.length(); ++i) { 84 | totalUsage += cpu_cores.at(i); 85 | } 86 | totalUsage /= cpu_cores.length(); 87 | return totalUsage; 88 | #endif 89 | #ifdef Q_OS_WIN 90 | return -1; 91 | #endif 92 | } 93 | 94 | QString wqmlsystem::getCPUName() const{ 95 | #ifdef Q_OS_LINUX 96 | QFile file("/proc/cpuinfo"); 97 | if(!file.open(QIODevice::ReadOnly | QIODevice::Text)) 98 | return tr("ERR: Can't access the file\n(maybe some program using it):") + "/proc/cpuinfo"; 99 | 100 | QTextStream in(&file); 101 | QString line = in.readLine(); 102 | while(!line.isNull()){ 103 | if(line.left(10) == "model name"){ 104 | return (QString)(line.split(":")[1]).remove(0, 1); 105 | break; 106 | } 107 | line = in.readLine(); 108 | } 109 | 110 | return tr("Can't find the CPU Name"); 111 | #endif 112 | #ifdef Q_OS_WIN 113 | return tr("Can't find the CPU Name"); 114 | #endif 115 | } 116 | 117 | QList wqmlsystem::getCPUCurrentClockSpeeds() const{ 118 | #ifdef Q_OS_LINUX 119 | QList coreClocks; 120 | for(int i=0; i<64; i++){ 121 | QString path = "/sys/devices/system/cpu/cpu" + QString::number(i) + "/cpufreq/scaling_cur_freq"; 122 | QFile file(path); 123 | if(!file.open(QIODevice::ReadOnly | QIODevice::Text)) 124 | break; 125 | 126 | QTextStream in(&file); 127 | QString line = in.readAll(); 128 | coreClocks.append( line.toInt() ); // For MHz 129 | 130 | file.close(); 131 | } 132 | 133 | return coreClocks; 134 | #endif 135 | #ifdef Q_OS_WIN 136 | return; 137 | #endif 138 | } 139 | 140 | 141 | ////// ---- --- ---- ////// 142 | ////// ---- GPU ---- ////// 143 | ////// ---- --- ---- ////// 144 | QString wqmlsystem::getNvidiaGPUName() const{ 145 | #ifdef Q_OS_LINUX 146 | QProcess process; 147 | process.start("/bin/bash -c \"nvidia-smi --query-gpu=name --format=csv,noheader\""); 148 | process.waitForFinished(1000); 149 | 150 | QString err = process.readAllStandardError(); 151 | if(err.length() > 0) // If an error occur, -1 152 | return "Err: " + err; 153 | 154 | QString output = process.readAllStandardOutput(); 155 | output = "NVIDIA " + output; 156 | output.remove('\n'); 157 | process.kill(); 158 | return output; 159 | #endif 160 | } 161 | QString wqmlsystem::getIntelGPUName() const{ 162 | #ifdef Q_OS_LINUX 163 | 164 | #endif 165 | } 166 | QString wqmlsystem::getAMDGPUName() const{ 167 | #ifdef Q_OS_LINUX 168 | 169 | #endif 170 | } 171 | 172 | int wqmlsystem::getNvidiaGPUUsage() const{ 173 | #ifdef Q_OS_LINUX 174 | QProcess process; 175 | process.start("/bin/bash -c \"nvidia-smi --query-gpu=utilization.gpu --format=csv,noheader\""); 176 | process.waitForFinished(1000); 177 | 178 | if(process.readAllStandardError().length() > 0) // If an error occur, -1 179 | return -1; 180 | 181 | QString output = process.readAllStandardOutput(); 182 | output.remove('%'); // Remove % Tag 183 | output.remove('\n'); 184 | process.kill(); 185 | return output.toInt(); 186 | #endif 187 | } 188 | int wqmlsystem::getIntelGPUUsage() const{ 189 | #ifdef Q_OS_LINUX 190 | 191 | #endif 192 | } 193 | int wqmlsystem::getAMDGPUUsage() const{ 194 | #ifdef Q_OS_LINUX 195 | 196 | #endif 197 | } 198 | 199 | int wqmlsystem::getNvidiaGPUMemoryUsage() const{ 200 | #ifdef Q_OS_LINUX 201 | QProcess process; 202 | process.start("/bin/bash -c \"nvidia-smi --query-gpu=memory.used --format=csv,noheader\""); 203 | process.waitForFinished(1000); 204 | 205 | if(process.readAllStandardError().length() > 0) // If an error occur, -1 206 | return -1; 207 | 208 | QString output = process.readAllStandardOutput(); 209 | output.remove('\n'); 210 | output.chop(4); // Remove MiB Tag 211 | process.kill(); 212 | return output.toInt(); 213 | #endif 214 | } 215 | int wqmlsystem::getIntelGPUMemoryUsage() const{ 216 | #ifdef Q_OS_LINUX 217 | 218 | #endif 219 | } 220 | int wqmlsystem::getAMDGPUMemoryUsage() const{ 221 | #ifdef Q_OS_LINUX 222 | 223 | #endif 224 | } 225 | 226 | int wqmlsystem::getNvidiaGPUCurrentClockSpeed() const{ 227 | #ifdef Q_OS_LINUX 228 | QProcess process; 229 | process.start("/bin/bash -c \"nvidia-smi --query-gpu=clocks.gr --format=csv,noheader\""); 230 | process.waitForFinished(1000); 231 | 232 | if(process.readAllStandardError().length() > 0) // If an error occur, -1 233 | return -1; 234 | 235 | QString output = process.readAllStandardOutput(); 236 | output.remove('\n'); 237 | output.chop(4); // Remove MHz tag. 238 | process.kill(); 239 | return output.toInt(); 240 | #endif 241 | } 242 | int wqmlsystem::getIntelGPUCurrentClockSpeed() const{ 243 | #ifdef Q_OS_LINUX 244 | 245 | #endif 246 | } 247 | int wqmlsystem::getAMDGPUCurrentClockSpeed() const{ 248 | #ifdef Q_OS_LINUX 249 | 250 | #endif 251 | } 252 | 253 | int wqmlsystem::getNvidiaGPUCurrentMemorySpeed() const{ 254 | #ifdef Q_OS_LINUX 255 | QProcess process; 256 | process.start("/bin/bash -c \"nvidia-smi --query-gpu=clocks.mem --format=csv,noheader\""); 257 | process.waitForFinished(1000); 258 | 259 | if(process.readAllStandardError().length() > 0) // If an error occur, -1 260 | return -1; 261 | 262 | QString output = process.readAllStandardOutput(); 263 | output.remove('\n'); 264 | output.chop(4); // Remove MHz tag. 265 | process.kill(); 266 | return output.toInt(); 267 | #endif 268 | } 269 | int wqmlsystem::getIntelGPUCurrentMemorySpeed() const{ 270 | #ifdef Q_OS_LINUX 271 | 272 | #endif 273 | } 274 | int wqmlsystem::getAMDGPUCurrentMemorySpeed() const{ 275 | #ifdef Q_OS_LINUX 276 | 277 | #endif 278 | } 279 | 280 | int wqmlsystem::getNvidiaGPUFanSpeed() const{ 281 | #ifdef Q_OS_LINUX 282 | QProcess process; 283 | process.start("/bin/bash -c \"nvidia-smi --query-gpu=fan.speed --format=csv,noheader\""); 284 | process.waitForFinished(1000); 285 | 286 | if(process.readAllStandardError().length() > 0) // If an error occur, -1 287 | return -1; 288 | 289 | QString output = process.readAllStandardOutput(); 290 | output.remove('\n'); 291 | 292 | if(output == "[Not Supported]") 293 | return -1; 294 | 295 | process.kill(); 296 | return output.toInt(); 297 | #endif 298 | } 299 | int wqmlsystem::getAMDGPUFanSpeed() const{ 300 | #ifdef Q_OS_LINUX 301 | 302 | #endif 303 | } 304 | 305 | int wqmlsystem::getNvidiaGPUTemperature() const{ 306 | #ifdef Q_OS_LINUX 307 | QProcess process; 308 | process.start("/bin/bash -c \"nvidia-smi --query-gpu=temperature.gpu --format=csv,noheader\""); 309 | process.waitForFinished(1000); 310 | 311 | if(process.readAllStandardError().length() > 0) // If an error occur, -1 312 | return -1; 313 | 314 | QString output = process.readAllStandardOutput(); 315 | output.remove('\n'); 316 | 317 | if(output == "[Not Supported]") 318 | return -1; 319 | 320 | process.kill(); 321 | return output.toInt(); 322 | #endif 323 | } 324 | int wqmlsystem::getIntelGPUTemperature() const{ 325 | #ifdef Q_OS_LINUX 326 | 327 | #endif 328 | } 329 | int wqmlsystem::getAMDGPUTemperature() const{ 330 | #ifdef Q_OS_LINUX 331 | 332 | #endif 333 | } 334 | 335 | int wqmlsystem::getNvidiaGPUPowerDraw() const{ 336 | #ifdef Q_OS_LINUX 337 | QProcess process; 338 | process.start("/bin/bash -c \"nvidia-smi --query-gpu=power.draw --format=csv,noheader\""); 339 | process.waitForFinished(1000); 340 | 341 | if(process.readAllStandardError().length() > 0) // If an error occur, -1 342 | return -1; 343 | 344 | QString output = process.readAllStandardOutput(); 345 | output.remove('\n'); 346 | 347 | if(output == "[Not Supported]") 348 | return -1; 349 | 350 | process.kill(); 351 | return output.toInt(); 352 | #endif 353 | } 354 | int wqmlsystem::getIntelGPUPowerDraw() const{ 355 | #ifdef Q_OS_LINUX 356 | 357 | #endif 358 | } 359 | int wqmlsystem::getAMDGPUPowerDraw() const{ 360 | #ifdef Q_OS_LINUX 361 | 362 | #endif 363 | } 364 | 365 | 366 | 367 | ////// ---- ------- ---- ////// 368 | ////// ---- STORAGE ---- ////// 369 | ////// ---- ------- ---- ////// 370 | /*QList> wqmlsystem::getStorage(){ 371 | #ifdef Q_OS_LINUX 372 | QProcess process; 373 | process.start("df --type=ext4 --output=source,size,used,avail,pcent,target --sync -BM"); 374 | process.waitForFinished(1000); 375 | 376 | QList> driveList; 377 | QMap drive; 378 | 379 | if(process.readAllStandardError().length() > 0){ // If an error occur, -1 380 | drive.insert("error", -1); 381 | driveList.append(drive); 382 | return driveList; 383 | } 384 | 385 | QString output = process.readAllStandardOutput(); 386 | QList lines = output.split('\n'); 387 | for (int i = 1; i < lines.length(); ++i) { 388 | qDebug() << lines[i]; 389 | } 390 | 391 | process.kill(); 392 | return driveList; 393 | #endif 394 | }*/ 395 | 396 | 397 | 398 | int wqmlsystem::getNetwork(){ 399 | 400 | } 401 | 402 | int wqmlsystem::getProcessList(const int count = -1){ 403 | 404 | } 405 | 406 | -------------------------------------------------------------------------------- /widgetci/wqmlsystem.h: -------------------------------------------------------------------------------- 1 | #ifndef WQMLSYSTEM_H 2 | #define WQMLSYSTEM_H 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | 9 | class wqmlsystem : public QObject 10 | { 11 | Q_OBJECT 12 | 13 | public: 14 | wqmlsystem(); 15 | 16 | // Timer & Refreshing values 17 | QTimer* timer; 18 | int timerInterval = 100; 19 | 20 | // CPU 21 | QList cpu_cores; 22 | void updateCPUValues(); 23 | int run_idles1[64][2] = {{0}}; // MAX 64 CORES (FOR XEON or EPYC PROCESSORS MAYBE...) [RUN, IDLE] 24 | int run_idles2[64][2] = {{0}}; // MAX 64 CORES (FOR XEON or EPYC PROCESSORS MAYBE...) [RUN, IDLE] 25 | 26 | public slots: 27 | // CPU 28 | QString getCPUName() const; // CPU Name 29 | QList getCPUCoresUsages() const; // Usage percents by core numbers 30 | int getCPUUsage() const; // Usage percent main CPU 31 | QList getCPUCurrentClockSpeeds() const; // CPU Current Clock Speeds (Hz) 32 | 33 | // GPU 34 | QString getNvidiaGPUName() const; // GPU Name 35 | QString getIntelGPUName() const; 36 | QString getAMDGPUName() const; 37 | 38 | int getNvidiaGPUUsage() const; // GPU Usage percent (%) 39 | int getIntelGPUUsage() const; 40 | int getAMDGPUUsage() const; 41 | 42 | int getNvidiaGPUMemoryUsage() const; // GPU RAM Usage percent (MB) 43 | int getIntelGPUMemoryUsage() const; 44 | int getAMDGPUMemoryUsage() const; 45 | 46 | int getNvidiaGPUCurrentClockSpeed() const; // GPU Clock Speeds (MHz) 47 | int getIntelGPUCurrentClockSpeed() const; 48 | int getAMDGPUCurrentClockSpeed() const; 49 | 50 | int getNvidiaGPUCurrentMemorySpeed() const; // GPU Memory Clock Speeds (MHz) 51 | int getIntelGPUCurrentMemorySpeed() const; 52 | int getAMDGPUCurrentMemorySpeed() const; 53 | 54 | int getNvidiaGPUFanSpeed() const; // Fan Speed (RPM) 55 | int getAMDGPUFanSpeed() const; 56 | 57 | int getNvidiaGPUTemperature() const; // Temperature (Celcius) 58 | int getIntelGPUTemperature() const; 59 | int getAMDGPUTemperature() const; 60 | 61 | int getNvidiaGPUPowerDraw() const; // Power Draw (Watts) 62 | int getIntelGPUPowerDraw() const; 63 | int getAMDGPUPowerDraw() const; 64 | 65 | // STORAGE 66 | //QList> getStorage(); // First Dimension is filesystems. (like /dev/sda1, /dev/sda2), 67 | // Second Dimension is informations about the filesystem. ( Total, Used, Empty, Percent, Mounted On ) 68 | 69 | // NETWORK 70 | int getNetwork(); 71 | 72 | // PROCESS LIST 73 | int getProcessList(const int count); 74 | }; 75 | 76 | #endif // WQMLSYSTEM_H 77 | -------------------------------------------------------------------------------- /widgetci/wwidget.cpp: -------------------------------------------------------------------------------- 1 | #include "wwidget.h" 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | 10 | 11 | WWidget::WWidget(const QUrl fileurl, const QString filename, const int wx, const int wy): 12 | QQuickView(fileurl), 13 | widgetpath(fileurl.toDisplayString()), 14 | fileurl(fileurl), 15 | filename(filename) 16 | { 17 | this->setParent(Q_NULLPTR); 18 | 19 | // Transparent and Frameless Window: 20 | this->setFlags(this->normalFlags); 21 | this->setColor(QColor(0,0,0,0)); 22 | 23 | // Position 24 | if(wx != -1000 && wy != -1000) this->setPosition(wx, wy); 25 | 26 | // Widget's RightClick Menu 27 | addRightClickMenu(); 28 | 29 | // Show: 30 | this->show(); 31 | 32 | } 33 | 34 | WWidget::~WWidget(){ 35 | // Deconstructor 36 | } 37 | 38 | void WWidget::reload(){ 39 | this->setSource(QUrl()); 40 | this->engine()->clearComponentCache(); 41 | this->setSource(fileurl); 42 | } 43 | 44 | void WWidget::startMoving(){ 45 | dragX = this->size().width()/2; 46 | dragY = this->size().height()/2; 47 | setCursor(Qt::SizeAllCursor); 48 | isDragging = true; 49 | } 50 | 51 | void WWidget::stopMoving(){ 52 | isDragging = false; 53 | isDragStarted = false; 54 | setCursor(Qt::ArrowCursor); 55 | } 56 | 57 | // Drag&Drop the widget: 58 | void WWidget::mousePressEvent(QMouseEvent *event){ 59 | if(isDragging){ 60 | stopMoving(); 61 | return; 62 | } 63 | 64 | QQuickView::mousePressEvent(event); 65 | 66 | switch (event->button()) { 67 | case (Qt::RightButton): { 68 | QPoint pt(event->pos()); 69 | pt.setX(pt.x()+2); 70 | pt.setY(pt.y()+2); 71 | menu_rightClick->exec( this->mapToGlobal(pt) ); 72 | break; 73 | } 74 | default: 75 | break; 76 | } 77 | 78 | } 79 | void WWidget::mouseMoveEvent(QMouseEvent *event){ 80 | QQuickView::mouseMoveEvent(event); 81 | 82 | if(isDragging) 83 | this->setPosition(event->globalX() - dragX, event->globalY() - dragY); 84 | } 85 | void WWidget::mouseReleaseEvent(QMouseEvent *event){ 86 | if(isDragging){ 87 | stopMoving(); 88 | return; 89 | } 90 | 91 | QQuickView::mouseReleaseEvent(event); 92 | } 93 | 94 | void WWidget::focusOutEvent(QFocusEvent *event){ 95 | Q_UNUSED(event); 96 | saveSettings(); 97 | } 98 | 99 | void WWidget::saveSettings(){ 100 | widgetSettings->beginGroup(filename); 101 | widgetSettings->setValue("x", this->x()); 102 | widgetSettings->setValue("y", this->y()); 103 | widgetSettings->setValue("visible", this->isVisible()); 104 | widgetSettings->setValue("z-pos", this->z_pos); 105 | widgetSettings->endGroup(); 106 | widgetSettings->sync(); 107 | } 108 | 109 | void WWidget::toggleZPos(int z_index = 0){ 110 | this->z_pos = z_index; 111 | switch (z_index) { 112 | // Normal [0] ------------- 113 | case 0: 114 | if(this->latestFlags == this->alwaysMostTopFlags){ 115 | this->destroy(); 116 | this->create(); 117 | this->setFlags(this->normalFlags); 118 | this->show(); 119 | }else{ 120 | this->setFlags((this->flags() ^ this->latestFlags)); 121 | this->show(); 122 | } 123 | 124 | this->latestFlags = Q_NULLPTR; 125 | break; 126 | 127 | // Always on most top [1] ------------- 128 | case 1: 129 | if(this->latestFlags == this->alwaysMostTopFlags){ 130 | this->destroy(); 131 | this->create(); 132 | this->setFlags(this->normalFlags | this->alwaysMostTopFlags); 133 | this->show(); 134 | }else{ 135 | this->hide(); 136 | this->setFlags((this->flags() ^ this->latestFlags) | this->alwaysMostTopFlags); 137 | this->show(); 138 | this->requestActivate(); 139 | } 140 | 141 | this->latestFlags = this->alwaysMostTopFlags; 142 | break; 143 | 144 | // Always on top [2] ------------- 145 | case 2: 146 | if(this->latestFlags == this->alwaysMostTopFlags){ 147 | this->destroy(); 148 | this->create(); 149 | this->setFlags(this->normalFlags); 150 | this->setFlags(this->flags() | this->alwaysTopFlags); 151 | this->show(); 152 | }else{ 153 | this->setFlags((this->flags() ^ this->latestFlags) | this->alwaysTopFlags); 154 | this->show(); 155 | } 156 | 157 | this->latestFlags = this->alwaysTopFlags; 158 | break; 159 | 160 | // Always on bottom [3] ------------- 161 | case 3: 162 | if(this->latestFlags == this->alwaysMostTopFlags){ 163 | this->destroy(); 164 | this->create(); 165 | this->setFlags(this->normalFlags | this->alwaysBottomFlags); 166 | this->show(); 167 | }else{ 168 | this->setFlags((this->flags() ^ this->latestFlags) | this->alwaysBottomFlags); 169 | this->show(); 170 | } 171 | 172 | this->latestFlags = this->alwaysBottomFlags; 173 | break; 174 | default: 175 | break; 176 | } 177 | 178 | if(!actionsList.at(z_index)->isChecked()) 179 | actionsList.at(z_index)->setChecked(true); 180 | } 181 | 182 | void WWidget::addRightClickMenu(){ 183 | // Menu 184 | menu_rightClick = new QMenu(); 185 | menu_rightClick->setContextMenuPolicy(Qt::CustomContextMenu); 186 | 187 | // Groups (for Radio Button effect) 188 | QActionGroup* actgr_zPositionGroup = new QActionGroup( this ); 189 | 190 | // MENU ACTIONS -->> 191 | // -- Hide 192 | QAction* act_Hide = new QAction(tr("Hide"),this); 193 | connect(act_Hide, &QAction::triggered, [=]{ 194 | delete this; 195 | }); 196 | 197 | // -- Move 198 | QAction* act_Move = new QAction(tr("Move"),this); 199 | connect(act_Move, &QAction::triggered, [=]{ 200 | startMoving(); 201 | }); 202 | 203 | // -- {SEPERATOR_AT_HERE} -- 204 | 205 | // -- Reload 206 | QAction* act_Reload = new QAction(tr("Reload"),this); 207 | connect(act_Reload, &QAction::triggered, [=]{ 208 | this->reload(); 209 | }); 210 | 211 | // -- Edit 212 | QAction* act_Edit = new QAction(tr("Edit"),this); 213 | connect(act_Edit, &QAction::triggered, [=]{ 214 | QDesktopServices::openUrl(fileurl); 215 | }); 216 | 217 | // -- {SEPERATOR_AT_HERE} -- 218 | 219 | // -- Always on Most Top [1] 220 | QAction* act_alwaysOnMostTop = new QAction(tr("Always on Most top"),this); 221 | act_alwaysOnMostTop->setCheckable(true); 222 | act_alwaysOnMostTop->setActionGroup( actgr_zPositionGroup ); 223 | connect(act_alwaysOnMostTop, &QAction::triggered, [=]{ 224 | toggleZPos(1); 225 | }); 226 | 227 | // -- Always on top [2] 228 | QAction* act_alwaysOnTop = new QAction(tr("Always on top"),this); 229 | act_alwaysOnTop->setCheckable(true); 230 | act_alwaysOnTop->setActionGroup( actgr_zPositionGroup ); 231 | connect(act_alwaysOnTop, &QAction::triggered, [=]{ 232 | toggleZPos(2); 233 | }); 234 | 235 | // -- Normal (DEFAULT) [0] 236 | QAction* act_normal = new QAction(tr("Normal"),this); 237 | act_normal->setCheckable(true); 238 | act_normal->setActionGroup( actgr_zPositionGroup ); 239 | connect(act_normal, &QAction::triggered, [=]{ 240 | toggleZPos(0); 241 | }); 242 | 243 | // -- Always on bottom [3] 244 | QAction* act_alwaysOnBottom = new QAction(tr("Always on bottom"),this); 245 | act_alwaysOnBottom->setCheckable(true); 246 | act_alwaysOnBottom->setActionGroup( actgr_zPositionGroup ); 247 | connect(act_alwaysOnBottom, &QAction::triggered, [=]{ 248 | toggleZPos(3); 249 | }); 250 | 251 | 252 | 253 | // Adding Sub-Menus & Actions 254 | menu_rightClick->addAction(act_Hide); 255 | menu_rightClick->addAction(act_Move); 256 | menu_rightClick->addSeparator(); 257 | menu_rightClick->addAction(act_Reload); 258 | menu_rightClick->addAction(act_Edit); 259 | menu_rightClick->addSeparator(); 260 | QMenu* submenu_zindex = menu_rightClick->addMenu(tr("Z-Position")); 261 | submenu_zindex->addAction(act_alwaysOnMostTop); 262 | submenu_zindex->addAction(act_alwaysOnTop); 263 | submenu_zindex->addAction(act_normal); 264 | submenu_zindex->addAction(act_alwaysOnBottom); 265 | 266 | 267 | // Adding actions to list. 268 | actionsList.append(act_normal); 269 | actionsList.append(act_alwaysOnMostTop); 270 | actionsList.append(act_alwaysOnTop); 271 | actionsList.append(act_alwaysOnBottom); 272 | } 273 | 274 | 275 | 276 | -------------------------------------------------------------------------------- /widgetci/wwidget.h: -------------------------------------------------------------------------------- 1 | #ifndef WWIDGET_H 2 | #define WWIDGET_H 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | class WWidget : public QQuickView 9 | { 10 | Q_OBJECT 11 | 12 | public: 13 | WWidget(const QUrl fileurl, const QString filename, const int wx, const int wy); 14 | ~WWidget(); 15 | 16 | // QML File and Reloading the QML Engine 17 | void reload(); 18 | 19 | // Widget's path 20 | QString widgetpath; 21 | QUrl fileurl; 22 | QString filename; 23 | 24 | // Z-Pos & Lock settings 25 | int z_pos = 0; 26 | 27 | void toggleZPos(int z_index); // Toggle between z positions. 28 | QSettings* widgetSettings; 29 | 30 | void saveSettings(); 31 | 32 | private: 33 | // Window Dragging. 34 | bool isDragging = false; 35 | bool isDragStarted = false; 36 | void startMoving(); 37 | void stopMoving(); 38 | quint16 dragX = 0, dragY = 0; 39 | 40 | // Right Click Menu 41 | QMenu *menu_rightClick; 42 | void addRightClickMenu(); 43 | 44 | // Window Flags 45 | Qt::WindowFlags normalFlags = Qt::FramelessWindowHint | Qt::SplashScreen | Qt::NoDropShadowWindowHint; // Normal [0] 46 | Qt::WindowFlags alwaysMostTopFlags = Qt::WindowStaysOnTopHint | Qt::BypassWindowManagerHint | Qt::BypassGraphicsProxyWidget; // Always on Most top [1] 47 | Qt::WindowFlags alwaysTopFlags = Qt::CustomizeWindowHint | Qt::WindowStaysOnTopHint; // Always on top [2] 48 | Qt::WindowFlags alwaysBottomFlags = Qt::CustomizeWindowHint | Qt::WindowStaysOnBottomHint; // Always on bottom [3] 49 | Qt::WindowFlags latestFlags; // For storing the latest change of flags 50 | QVector actionsList; 51 | 52 | 53 | 54 | protected: 55 | // Window Dragging & Right Click 56 | void mousePressEvent(QMouseEvent* event) override; 57 | void mouseMoveEvent(QMouseEvent* event) override; 58 | void mouseReleaseEvent(QMouseEvent* event) override; 59 | 60 | void focusOutEvent(QFocusEvent* event) override; 61 | 62 | }; 63 | 64 | #endif // WWIDGET_H 65 | -------------------------------------------------------------------------------- /widgetci_1.0.3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eminfedar/widgetci/05588c036cd4c6d6eddd5b595d027968ac484140/widgetci_1.0.3.png --------------------------------------------------------------------------------