Documentation for OpenFLUID 2.2.2
Loading...
Searching...
No Matches
UIHelpers.hpp
Go to the documentation of this file.
1/*
2
3 This file is part of OpenFLUID software
4 Copyright(c) 2021-2026, INRAE
5
6
7 == GNU General Public License Usage ==
8
9 OpenFLUID is free software: you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version.
13
14 OpenFLUID is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with OpenFLUID. If not, see <http://www.gnu.org/licenses/>.
21
22
23 == Other Usage ==
24
25 Other Usage means a use of OpenFLUID that is inconsistent with the GPL
26 license, and requires a written agreement between You and INRA.
27 Licensees for Other Usage of OpenFLUID may use this file in accordance
28 with the terms contained in the written agreement between You and INRA.
29
30*/
31
32/**
33 @file UIHelpers.hpp
34
35 @author Jean-Christophe FABRE <jean-christophe.fabre@inra.fr>
36 @author Armel THÖNI <armel.thoni@inrae.fr>
37*/
38
39
40#ifndef __OPENFLUID_UICOMMON_UIHELPERS_HPP__
41#define __OPENFLUID_UICOMMON_UIHELPERS_HPP__
42
43
44#include <cmath>
45#include <random>
46
47#include <QInputDialog>
48#include <QColor>
49#if (QT_VERSION_MAJOR < 6)
50#include <QRegExp>
51#else
52#include <QRegularExpression>
53#endif
54#include <QLineEdit>
55#include <QIcon>
56#include <QApplication>
57#include <QFile>
58#include <QFileDialog>
59#include <QMessageBox>
60#include <QDesktopServices>
61
65
66
67namespace openfluid { namespace ui { namespace common {
68
69
70inline QColor getRandomColor()
71{
72 static std::random_device RD;
73 static std::mt19937 G(RD());
74 static std::uniform_int_distribution<> Distri255(0, 255);
75
76 return QColor(Distri255(G),Distri255(G),Distri255(G));
77}
78
79
80// =====================================================================
81// =====================================================================
82
83
84inline double computeLuminance(const QColor& Color)
85{
86 // Reference: https://www.w3.org/WAI/GL/wiki/Relative_luminance
87 auto adjustColor = [](const double ChannelValue)
88 {
89 double RelValue = ChannelValue/255;
90 if (RelValue <= 0.03928)
91 {
92 return RelValue/12.92;
93 }
94 else
95 {
96 // low-gamma adjust coefficient
97 return std::pow((RelValue + 0.055) / 1.055, 2.4);
98 }
99 };
100 return adjustColor(Color.red())*0.2126 + adjustColor(Color.green())*0.7152 + adjustColor(Color.blue())*0.0722;
101}
102
103
104// =====================================================================
105// =====================================================================
106
107
108#if (QT_VERSION_MAJOR < 6)
109inline void fixLineEdit(QLineEdit* LineEdit,QRegExp SearchRegExp = QRegExp("[^\\w]"),QString NewStr = "_")
110#else
111inline void fixLineEdit(QLineEdit* LineEdit,QRegularExpression SearchRegExp = QRegularExpression("[^\\w]"),
112 QString NewStr = "_")
113#endif
114{
115 int CPos = LineEdit->cursorPosition();
116 LineEdit->setText(LineEdit->text().replace(SearchRegExp,NewStr));
117 LineEdit->setCursorPosition(CPos);
118}
119
120
121// =====================================================================
122// =====================================================================
123
124
125inline bool isHiDPIDevice()
126{
127 return (qApp->devicePixelRatio() >= 2.0);
128}
129
130
131// =====================================================================
132// =====================================================================
133
134
135inline QIcon getIcon(const QString& IconName,const QString& ResourcePath,
136 bool IsLight = false,bool AutoHiDPI = true)
137{
138 QString IconSuffix = "dark";
139
140 if (IsLight)
141 {
142 IconSuffix = "light";
143 }
144
145 QString TmpPath = QString(":%1/icons/%2_%3.png").arg(ResourcePath).arg(IconName).arg(IconSuffix);
146
147 if (AutoHiDPI && isHiDPIDevice())
148 {
149 QString TmpHiDPIPath = QString(":%1/icons/%2_%3@2x.png").arg(ResourcePath).arg(IconName).arg(IconSuffix);
150
151 if (QFile::exists(TmpHiDPIPath))
152 {
153 TmpPath = TmpHiDPIPath;
154 }
155 }
156
157 QIcon TmpIcon(TmpPath);
158
159 if (IsLight)
160 {
161 QString TmpLightPath = QString(":%1/icons/%2_grayed.png").arg(ResourcePath).arg(IconName);
162
163 if (AutoHiDPI && isHiDPIDevice())
164 {
165 QString TmpLightHiDPIPath = QString(":%1/icons/%2_grayed@2x.png").arg(ResourcePath).arg(IconName);
166
167 if (QFile::exists(TmpLightHiDPIPath))
168 {
169 TmpLightPath = TmpLightHiDPIPath;
170 }
171 }
172 TmpIcon.addPixmap(QPixmap(TmpLightPath),QIcon::Disabled);
173 }
174
175 return TmpIcon;
176}
177
178
179// =====================================================================
180// =====================================================================
181
182
183inline QPixmap getImage(const QString& ImageName,const QString& ResourcePath,bool AutoHiDPI = true)
184{
185 QString TmpPath = QString(":%1/images/%2.png").arg(ResourcePath).arg(ImageName);
186
187 if (AutoHiDPI && isHiDPIDevice())
188 {
189 QString TmpHiDPIPath = QString(":%1/images/%2@2x.png").arg(ResourcePath).arg(ImageName);
190
191 if (QFile::exists(TmpHiDPIPath))
192 {
193 TmpPath = TmpHiDPIPath;
194 }
195 }
196
197 return QPixmap(TmpPath);
198}
199
200
201// =====================================================================
202// =====================================================================
203
204
205inline QString createNewFile(QWidget* Parent, const QString& PathString)
206{
207 if (PathString.isEmpty())
208 {
209 return "";
210 }
211
212 QString FileToCreate = "";
213 QString FileName = QFileDialog::getSaveFileName(Parent,
214 QApplication::translate("openfluid::ui::common","Create file"),
215 PathString,
216 QApplication::translate("openfluid::ui::common","All files"));
217 if (!FileName.isEmpty() && !FileName.isNull())
218 {
219 FileToCreate = FileName;
220 }
221
222 if (!FileToCreate.isEmpty())
223 {
224 auto NewFilePath = openfluid::tools::Path(FileToCreate.toStdString());
225
226 if (NewFilePath.isDirectory())
227 {
228 QMessageBox::critical(Parent,QApplication::translate("openfluid::ui::common","Error creating file"),
229 QApplication::translate("openfluid::ui::common","\"%1\" is an existing directory")
230 .arg(QString::fromStdString(NewFilePath.toNative())));
231 }
232 // Checks if new path included in ref path
233 else if (!openfluid::tools::Path(PathString.toStdString()).contains(FileToCreate.toStdString()))
234 {
235 QMessageBox::critical(Parent,QApplication::translate("openfluid::ui::common","Error creating file"),
236 QApplication::translate("openfluid::ui::common",
237 "\"%1\" is not in the current ware main directory")
238 .arg(QString::fromStdString(NewFilePath.toNative())));
239 return "";
240 }
241 else
242 {
243 NewFilePath.makeFile();
244 }
245 return FileToCreate;
246 }
247 return "";
248}
249
250
251// =====================================================================
252// =====================================================================
253
254
255inline void openPath(std::string CurrentPath, bool IsRemote=false)
256{
257#if OPENFLUID_OS_ISWSL_FLAG == 1
258 std::string FullLocation = CurrentPath;
259 if (!IsRemote)
260 {
261 openfluid::utils::Process P("wslpath",{"-m", CurrentPath});
262 P.run();
263 const auto OutLines = P.stdOutLines();
264 CurrentPath = OutLines[0];
265 FullLocation = "file://"+CurrentPath;
266 }
267 openfluid::utils::Process PR("cmd.exe",{"/C", "start", FullLocation});
268 bool Success = PR.run();
269 if (!Success)
270 {
271 openfluid::base::log::info("Path opening", "WSL context, path: "+CurrentPath);
272 openfluid::base::log::info("Path opening", "status: "+std::to_string(Success));
273 for (const auto& L : PR.stdOutLines())
274 {
275 openfluid::base::log::debug("Path opening", L);
276 }
277 for (const auto& L : PR.stdErrLines())
278 {
279 openfluid::base::log::error("Path opening", L);
280 }
281 }
282#else
283 QUrl CurrentURL;
284 if (IsRemote)
285 {
286 CurrentURL = QUrl(QString::fromStdString(CurrentPath), QUrl::TolerantMode);
287 }
288 else
289 {
290 CurrentURL = QUrl::fromLocalFile(QString::fromStdString(CurrentPath));
291 }
292 QDesktopServices::openUrl(CurrentURL);
293#endif
294}
295
296
297} } } // namespaces
298
299
300#endif /* __OPENFLUID_UICOMMON_UIHELPERS_HPP__ */
Definition FilesystemPath.hpp:62
bool contains(const std::string &Path) const
Definition Process.hpp:68
void OPENFLUID_API info(const std::string &Context, const std::string &Msg)
void OPENFLUID_API error(const std::string &Context, const std::string &Msg)
void OPENFLUID_API debug(const std::string &Context, const std::string &Msg)
FilesystemPath Path
Definition FilesystemPath.hpp:308
QString createNewFile(QWidget *Parent, const QString &PathString)
Definition UIHelpers.hpp:205
void openPath(std::string CurrentPath, bool IsRemote=false)
Definition UIHelpers.hpp:255
QPixmap getImage(const QString &ImageName, const QString &ResourcePath, bool AutoHiDPI=true)
Definition UIHelpers.hpp:183
void fixLineEdit(QLineEdit *LineEdit, QRegExp SearchRegExp=QRegExp("[^\\w]"), QString NewStr="_")
Definition UIHelpers.hpp:109
QIcon getIcon(const QString &IconName, const QString &ResourcePath, bool IsLight=false, bool AutoHiDPI=true)
Definition UIHelpers.hpp:135
double computeLuminance(const QColor &Color)
Definition UIHelpers.hpp:84
QColor getRandomColor()
Definition UIHelpers.hpp:70
bool isHiDPIDevice()
Definition UIHelpers.hpp:125
Definition ApplicationException.hpp:47