macOS system profiler parser

This commit is contained in:
Jack Andersen 2018-01-02 14:24:45 -10:00
parent df01970bac
commit 3f2f8f6b35
9 changed files with 720 additions and 552 deletions

View File

@ -6,6 +6,7 @@ set(CMAKE_AUTOUIC ON)
find_package(Qt5Widgets)
find_package(Qt5Network)
find_package(Qt5Xml)
if(APPLE)
set(PLAT_SRCS MacOSSystemVersion.hpp MacOSSystemVersion.mm)
@ -27,6 +28,7 @@ list(APPEND PLAT_SRCS mainicon_qt.cpp)
add_executable(hecl-gui WIN32 MACOSX_BUNDLE
MainWindow.ui MainWindow.hpp MainWindow.cpp
EscapeSequenceParser.hpp EscapeSequenceParser.cpp
FileDirDialog.hpp ErrorLabel.hpp
SysReqTableView.hpp SysReqTableView.cpp
VectorISATableView.hpp VectorISATableView.cpp
@ -37,4 +39,5 @@ add_executable(hecl-gui WIN32 MACOSX_BUNDLE
set_target_properties(hecl-gui PROPERTIES
MACOSX_BUNDLE_INFO_PLIST "${CMAKE_CURRENT_SOURCE_DIR}/platforms/mac/Info.plist")
target_link_libraries(hecl-gui ${PLAT_LIBS} ${Qt5Widgets_LIBRARIES} ${Qt5Network_LIBRARIES} zeus)
target_link_libraries(hecl-gui ${PLAT_LIBS}
${Qt5Widgets_LIBRARIES} ${Qt5Network_LIBRARIES} ${Qt5Xml_LIBRARIES} zeus)

View File

@ -0,0 +1,515 @@
#include "EscapeSequenceParser.hpp"
#include <QFontDatabase>
/* TODO: more complete Vt102 emulation */
// based on information: http://en.m.wikipedia.org/wiki/ANSI_escape_code
// http://misc.flogisoft.com/bash/tip_colors_and_formatting
// http://invisible-island.net/xterm/ctlseqs/ctlseqs.html
void ParseEscapeSequence(int attribute, QListIterator<QString>& i, QTextCharFormat& textCharFormat,
const QTextCharFormat& defaultTextCharFormat)
{
switch (attribute) {
case 0 : { // Normal/Default (reset all attributes)
textCharFormat = defaultTextCharFormat;
break;
}
case 1 : { // Bold/Bright (bold or increased intensity)
textCharFormat.setFontWeight(QFont::Bold);
break;
}
case 2 : { // Dim/Faint (decreased intensity)
textCharFormat.setFontWeight(QFont::Light);
break;
}
case 3 : { // Italicized (italic on)
textCharFormat.setFontItalic(true);
break;
}
case 4 : { // Underscore (single underlined)
textCharFormat.setUnderlineStyle(QTextCharFormat::SingleUnderline);
textCharFormat.setFontUnderline(true);
break;
}
case 5 : { // Blink (slow, appears as Bold)
textCharFormat.setFontWeight(QFont::Bold);
break;
}
case 6 : { // Blink (rapid, appears as very Bold)
textCharFormat.setFontWeight(QFont::Black);
break;
}
case 7 : { // Reverse/Inverse (swap foreground and background)
QBrush foregroundBrush = textCharFormat.foreground();
textCharFormat.setForeground(textCharFormat.background());
textCharFormat.setBackground(foregroundBrush);
break;
}
case 8 : { // Concealed/Hidden/Invisible (usefull for passwords)
textCharFormat.setForeground(textCharFormat.background());
break;
}
case 9 : { // Crossed-out characters
textCharFormat.setFontStrikeOut(true);
break;
}
case 10 : { // Primary (default) font
textCharFormat.setFont(defaultTextCharFormat.font());
break;
}
case 11:
case 12:
case 13:
case 14:
case 15:
case 16:
case 17:
case 18:
case 19: {
QFontDatabase fontDatabase;
QString fontFamily = textCharFormat.fontFamily();
QStringList fontStyles = fontDatabase.styles(fontFamily);
int fontStyleIndex = attribute - 11;
if (fontStyleIndex < fontStyles.length()) {
textCharFormat.setFont(fontDatabase.font(fontFamily, fontStyles.at(fontStyleIndex), textCharFormat.font().pointSize()));
}
break;
}
case 20 : { // Fraktur (unsupported)
break;
}
case 21 : { // Set Bold off
textCharFormat.setFontWeight(QFont::Normal);
break;
}
case 22 : { // Set Dim off
textCharFormat.setFontWeight(QFont::Normal);
break;
}
case 23 : { // Unset italic and unset fraktur
textCharFormat.setFontItalic(false);
break;
}
case 24 : { // Unset underlining
textCharFormat.setUnderlineStyle(QTextCharFormat::NoUnderline);
textCharFormat.setFontUnderline(false);
break;
}
case 25 : { // Unset Blink/Bold
textCharFormat.setFontWeight(QFont::Normal);
break;
}
case 26 : { // Reserved
break;
}
case 27 : { // Positive (non-inverted)
QBrush backgroundBrush = textCharFormat.background();
textCharFormat.setBackground(textCharFormat.foreground());
textCharFormat.setForeground(backgroundBrush);
break;
}
case 28 : {
textCharFormat.setForeground(defaultTextCharFormat.foreground());
textCharFormat.setBackground(defaultTextCharFormat.background());
break;
}
case 29 : {
textCharFormat.setUnderlineStyle(QTextCharFormat::NoUnderline);
textCharFormat.setFontUnderline(false);
break;
}
case 30:
case 31:
case 32:
case 33:
case 34:
case 35:
case 36:
case 37:
{
int colorIndex = attribute - 30;
QColor color;
if (QFont::Normal < textCharFormat.fontWeight()) {
switch (colorIndex) {
case 0 : {
color = Qt::darkGray;
break;
}
case 1 : {
color = Qt::red;
break;
}
case 2 : {
color = Qt::green;
break;
}
case 3 : {
color = Qt::yellow;
break;
}
case 4 : {
color = Qt::blue;
break;
}
case 5 : {
color = Qt::magenta;
break;
}
case 6 : {
color = Qt::cyan;
break;
}
case 7 : {
color = Qt::white;
break;
}
default : {
Q_ASSERT(false);
}
}
} else {
switch (colorIndex) {
case 0 : {
color = Qt::black;
break;
}
case 1 : {
color = Qt::darkRed;
break;
}
case 2 : {
color = Qt::darkGreen;
break;
}
case 3 : {
color = Qt::darkYellow;
break;
}
case 4 : {
color = Qt::darkBlue;
break;
}
case 5 : {
color = Qt::darkMagenta;
break;
}
case 6 : {
color = Qt::darkCyan;
break;
}
case 7 : {
color = Qt::lightGray;
break;
}
default : {
Q_ASSERT(false);
}
}
}
textCharFormat.setForeground(color);
break;
}
case 38 : {
if (i.hasNext()) {
bool ok = false;
int selector = i.next().toInt(&ok);
Q_ASSERT(ok);
QColor color;
switch (selector) {
case 2 : {
if (!i.hasNext()) {
break;
}
int red = i.next().toInt(&ok);
Q_ASSERT(ok);
if (!i.hasNext()) {
break;
}
int green = i.next().toInt(&ok);
Q_ASSERT(ok);
if (!i.hasNext()) {
break;
}
int blue = i.next().toInt(&ok);
Q_ASSERT(ok);
color.setRgb(red, green, blue);
break;
}
case 5 :
{
if (!i.hasNext()) {
break;
}
int index = i.next().toInt(&ok);
Q_ASSERT(ok);
if (index >= 0 && index <= 0x07)
{ // 0x00-0x07: standard colors (as in ESC [ 30..37 m)
return ParseEscapeSequence(index - 0x00 + 30, i, textCharFormat, defaultTextCharFormat);
}
else if (index >= 0x08 && index <= 0x0F)
{ // 0x08-0x0F: high intensity colors (as in ESC [ 90..97 m)
return ParseEscapeSequence(index - 0x08 + 90, i, textCharFormat, defaultTextCharFormat);
}
else if (index >= 0x10 && index <= 0xE7)
{ // 0x10-0xE7: 6*6*6=216 colors: 16 + 36*r + 6*g + b (0≤r,g,b≤5)
index -= 0x10;
int red = index % 6;
index /= 6;
int green = index % 6;
index /= 6;
int blue = index % 6;
index /= 6;
Q_ASSERT(index == 0);
color.setRgb(red, green, blue);
break;
}
else if (index >= 0xE8 && index <= 0xFF)
{ // 0xE8-0xFF: grayscale from black to white in 24 steps
qreal intensity = qreal(index - 0xE8) / (0xFF - 0xE8);
color.setRgbF(intensity, intensity, intensity);
break;
}
textCharFormat.setForeground(color);
break;
}
default : {
break;
}
}
}
break;
}
case 39 : {
textCharFormat.setForeground(defaultTextCharFormat.foreground());
break;
}
case 40:
case 41:
case 42:
case 43:
case 44:
case 45:
case 46:
case 47: {
int colorIndex = attribute - 40;
QColor color;
switch (colorIndex) {
case 0 : {
color = Qt::darkGray;
break;
}
case 1 : {
color = Qt::red;
break;
}
case 2 : {
color = Qt::green;
break;
}
case 3 : {
color = Qt::yellow;
break;
}
case 4 : {
color = Qt::blue;
break;
}
case 5 : {
color = Qt::magenta;
break;
}
case 6 : {
color = Qt::cyan;
break;
}
case 7 : {
color = Qt::white;
break;
}
default : {
Q_ASSERT(false);
}
}
textCharFormat.setBackground(color);
break;
}
case 48 : {
if (i.hasNext()) {
bool ok = false;
int selector = i.next().toInt(&ok);
Q_ASSERT(ok);
QColor color;
switch (selector) {
case 2 : {
if (!i.hasNext()) {
break;
}
int red = i.next().toInt(&ok);
Q_ASSERT(ok);
if (!i.hasNext()) {
break;
}
int green = i.next().toInt(&ok);
Q_ASSERT(ok);
if (!i.hasNext()) {
break;
}
int blue = i.next().toInt(&ok);
Q_ASSERT(ok);
color.setRgb(red, green, blue);
break;
}
case 5 : {
if (!i.hasNext()) {
break;
}
int index = i.next().toInt(&ok);
Q_ASSERT(ok);
if (index >= 0x00 && index <= 0x07)
{ // 0x00-0x07: standard colors (as in ESC [ 40..47 m)
return ParseEscapeSequence(index - 0x00 + 40, i, textCharFormat, defaultTextCharFormat);
}
else if (index >= 0x08 && index <= 0x0F)
{ // 0x08-0x0F: high intensity colors (as in ESC [ 100..107 m)
return ParseEscapeSequence(index - 0x08 + 100, i, textCharFormat, defaultTextCharFormat);
}
else if (index >= 0x10 && index <= 0xE7)
{ // 0x10-0xE7: 6*6*6=216 colors: 16 + 36*r + 6*g + b (0≤r,g,b≤5)
index -= 0x10;
int red = index % 6;
index /= 6;
int green = index % 6;
index /= 6;
int blue = index % 6;
index /= 6;
Q_ASSERT(index == 0);
color.setRgb(red, green, blue);
break;
}
else if (index >= 0xE8 && index <= 0xFF)
{ // 0xE8-0xFF: grayscale from black to white in 24 steps
qreal intensity = qreal(index - 0xE8) / (0xFF - 0xE8);
color.setRgbF(intensity, intensity, intensity);
}
}
textCharFormat.setBackground(color);
break;
}
}
break;
}
case 49: {
textCharFormat.setBackground(defaultTextCharFormat.background());
break;
}
case 90:
case 91:
case 92:
case 93:
case 94:
case 95:
case 96:
case 97: {
int colorIndex = attribute - 90;
QColor color;
switch (colorIndex) {
case 0 : {
color = Qt::darkGray;
break;
}
case 1 : {
color = Qt::red;
break;
}
case 2 : {
color = Qt::green;
break;
}
case 3 : {
color = Qt::yellow;
break;
}
case 4 : {
color = Qt::blue;
break;
}
case 5 : {
color = Qt::magenta;
break;
}
case 6 : {
color = Qt::cyan;
break;
}
case 7 : {
color = Qt::white;
break;
}
default : {
Q_ASSERT(false);
}
}
color.setRedF(color.redF() * 0.8);
color.setGreenF(color.greenF() * 0.8);
color.setBlueF(color.blueF() * 0.8);
textCharFormat.setForeground(color);
break;
}
case 100:
case 101:
case 102:
case 103:
case 104:
case 105:
case 106:
case 107:
{
int colorIndex = attribute - 100;
QColor color;
switch (colorIndex) {
case 0 : {
color = Qt::darkGray;
break;
}
case 1 : {
color = Qt::red;
break;
}
case 2 : {
color = Qt::green;
break;
}
case 3 : {
color = Qt::yellow;
break;
}
case 4 : {
color = Qt::blue;
break;
}
case 5 : {
color = Qt::magenta;
break;
}
case 6 : {
color = Qt::cyan;
break;
}
case 7 : {
color = Qt::white;
break;
}
default : {
Q_ASSERT(false);
}
}
color.setRedF(color.redF() * 0.8);
color.setGreenF(color.greenF() * 0.8);
color.setBlueF(color.blueF() * 0.8);
textCharFormat.setBackground(color);
break;
}
default : {
break;
}
}
}

View File

@ -0,0 +1,10 @@
#ifndef GUI_ESCAPESEQUENCEPARSER_HPP
#define GUI_ESCAPESEQUENCEPARSER_HPP
#include <QString>
#include <QTextCharFormat>
void ParseEscapeSequence(int attribute, QListIterator<QString>& i, QTextCharFormat& textCharFormat,
const QTextCharFormat& defaultTextCharFormat);
#endif // GUI_ESCAPESEQUENCEPARSER_HPP

View File

@ -1,11 +1,7 @@
#include "MainWindow.hpp"
#include "ui_MainWindow.h"
#include <QFontDatabase>
#include <QProcess>
#include <QScrollBar>
#include <QFileInfo>
#include <QDebug>
#include <QTextCursor>
#include "EscapeSequenceParser.hpp"
#include "FileDirDialog.hpp"
#if _WIN32
@ -59,518 +55,6 @@ MainWindow::~MainWindow()
m_heclProc.terminate();
delete m_ui;
}
/* TODO: more complete Vt102 emulation */
// based on information: http://en.m.wikipedia.org/wiki/ANSI_escape_code
// http://misc.flogisoft.com/bash/tip_colors_and_formatting
// http://invisible-island.net/xterm/ctlseqs/ctlseqs.html
void MainWindow::parseEscapeSequence(int attribute, QListIterator<QString>& i, QTextCharFormat& textCharFormat,
const QTextCharFormat& defaultTextCharFormat)
{
switch (attribute) {
case 0 : { // Normal/Default (reset all attributes)
textCharFormat = defaultTextCharFormat;
break;
}
case 1 : { // Bold/Bright (bold or increased intensity)
textCharFormat.setFontWeight(QFont::Bold);
break;
}
case 2 : { // Dim/Faint (decreased intensity)
textCharFormat.setFontWeight(QFont::Light);
break;
}
case 3 : { // Italicized (italic on)
textCharFormat.setFontItalic(true);
break;
}
case 4 : { // Underscore (single underlined)
textCharFormat.setUnderlineStyle(QTextCharFormat::SingleUnderline);
textCharFormat.setFontUnderline(true);
break;
}
case 5 : { // Blink (slow, appears as Bold)
textCharFormat.setFontWeight(QFont::Bold);
break;
}
case 6 : { // Blink (rapid, appears as very Bold)
textCharFormat.setFontWeight(QFont::Black);
break;
}
case 7 : { // Reverse/Inverse (swap foreground and background)
QBrush foregroundBrush = textCharFormat.foreground();
textCharFormat.setForeground(textCharFormat.background());
textCharFormat.setBackground(foregroundBrush);
break;
}
case 8 : { // Concealed/Hidden/Invisible (usefull for passwords)
textCharFormat.setForeground(textCharFormat.background());
break;
}
case 9 : { // Crossed-out characters
textCharFormat.setFontStrikeOut(true);
break;
}
case 10 : { // Primary (default) font
textCharFormat.setFont(defaultTextCharFormat.font());
break;
}
case 11:
case 12:
case 13:
case 14:
case 15:
case 16:
case 17:
case 18:
case 19: {
QFontDatabase fontDatabase;
QString fontFamily = textCharFormat.fontFamily();
QStringList fontStyles = fontDatabase.styles(fontFamily);
int fontStyleIndex = attribute - 11;
if (fontStyleIndex < fontStyles.length()) {
textCharFormat.setFont(fontDatabase.font(fontFamily, fontStyles.at(fontStyleIndex), textCharFormat.font().pointSize()));
}
break;
}
case 20 : { // Fraktur (unsupported)
break;
}
case 21 : { // Set Bold off
textCharFormat.setFontWeight(QFont::Normal);
break;
}
case 22 : { // Set Dim off
textCharFormat.setFontWeight(QFont::Normal);
break;
}
case 23 : { // Unset italic and unset fraktur
textCharFormat.setFontItalic(false);
break;
}
case 24 : { // Unset underlining
textCharFormat.setUnderlineStyle(QTextCharFormat::NoUnderline);
textCharFormat.setFontUnderline(false);
break;
}
case 25 : { // Unset Blink/Bold
textCharFormat.setFontWeight(QFont::Normal);
break;
}
case 26 : { // Reserved
break;
}
case 27 : { // Positive (non-inverted)
QBrush backgroundBrush = textCharFormat.background();
textCharFormat.setBackground(textCharFormat.foreground());
textCharFormat.setForeground(backgroundBrush);
break;
}
case 28 : {
textCharFormat.setForeground(defaultTextCharFormat.foreground());
textCharFormat.setBackground(defaultTextCharFormat.background());
break;
}
case 29 : {
textCharFormat.setUnderlineStyle(QTextCharFormat::NoUnderline);
textCharFormat.setFontUnderline(false);
break;
}
case 30:
case 31:
case 32:
case 33:
case 34:
case 35:
case 36:
case 37:
{
int colorIndex = attribute - 30;
QColor color;
if (QFont::Normal < textCharFormat.fontWeight()) {
switch (colorIndex) {
case 0 : {
color = Qt::darkGray;
break;
}
case 1 : {
color = Qt::red;
break;
}
case 2 : {
color = Qt::green;
break;
}
case 3 : {
color = Qt::yellow;
break;
}
case 4 : {
color = Qt::blue;
break;
}
case 5 : {
color = Qt::magenta;
break;
}
case 6 : {
color = Qt::cyan;
break;
}
case 7 : {
color = Qt::white;
break;
}
default : {
Q_ASSERT(false);
}
}
} else {
switch (colorIndex) {
case 0 : {
color = Qt::black;
break;
}
case 1 : {
color = Qt::darkRed;
break;
}
case 2 : {
color = Qt::darkGreen;
break;
}
case 3 : {
color = Qt::darkYellow;
break;
}
case 4 : {
color = Qt::darkBlue;
break;
}
case 5 : {
color = Qt::darkMagenta;
break;
}
case 6 : {
color = Qt::darkCyan;
break;
}
case 7 : {
color = Qt::lightGray;
break;
}
default : {
Q_ASSERT(false);
}
}
}
textCharFormat.setForeground(color);
break;
}
case 38 : {
if (i.hasNext()) {
bool ok = false;
int selector = i.next().toInt(&ok);
Q_ASSERT(ok);
QColor color;
switch (selector) {
case 2 : {
if (!i.hasNext()) {
break;
}
int red = i.next().toInt(&ok);
Q_ASSERT(ok);
if (!i.hasNext()) {
break;
}
int green = i.next().toInt(&ok);
Q_ASSERT(ok);
if (!i.hasNext()) {
break;
}
int blue = i.next().toInt(&ok);
Q_ASSERT(ok);
color.setRgb(red, green, blue);
break;
}
case 5 :
{
if (!i.hasNext()) {
break;
}
int index = i.next().toInt(&ok);
Q_ASSERT(ok);
if (index >= 0 && index <= 0x07)
{ // 0x00-0x07: standard colors (as in ESC [ 30..37 m)
return parseEscapeSequence(index - 0x00 + 30, i, textCharFormat, defaultTextCharFormat);
}
else if (index >= 0x08 && index <= 0x0F)
{ // 0x08-0x0F: high intensity colors (as in ESC [ 90..97 m)
return parseEscapeSequence(index - 0x08 + 90, i, textCharFormat, defaultTextCharFormat);
}
else if (index >= 0x10 && index <= 0xE7)
{ // 0x10-0xE7: 6*6*6=216 colors: 16 + 36*r + 6*g + b (0≤r,g,b≤5)
index -= 0x10;
int red = index % 6;
index /= 6;
int green = index % 6;
index /= 6;
int blue = index % 6;
index /= 6;
Q_ASSERT(index == 0);
color.setRgb(red, green, blue);
break;
}
else if (index >= 0xE8 && index <= 0xFF)
{ // 0xE8-0xFF: grayscale from black to white in 24 steps
qreal intensity = qreal(index - 0xE8) / (0xFF - 0xE8);
color.setRgbF(intensity, intensity, intensity);
break;
}
textCharFormat.setForeground(color);
break;
}
default : {
break;
}
}
}
break;
}
case 39 : {
textCharFormat.setForeground(defaultTextCharFormat.foreground());
break;
}
case 40:
case 41:
case 42:
case 43:
case 44:
case 45:
case 46:
case 47: {
int colorIndex = attribute - 40;
QColor color;
switch (colorIndex) {
case 0 : {
color = Qt::darkGray;
break;
}
case 1 : {
color = Qt::red;
break;
}
case 2 : {
color = Qt::green;
break;
}
case 3 : {
color = Qt::yellow;
break;
}
case 4 : {
color = Qt::blue;
break;
}
case 5 : {
color = Qt::magenta;
break;
}
case 6 : {
color = Qt::cyan;
break;
}
case 7 : {
color = Qt::white;
break;
}
default : {
Q_ASSERT(false);
}
}
textCharFormat.setBackground(color);
break;
}
case 48 : {
if (i.hasNext()) {
bool ok = false;
int selector = i.next().toInt(&ok);
Q_ASSERT(ok);
QColor color;
switch (selector) {
case 2 : {
if (!i.hasNext()) {
break;
}
int red = i.next().toInt(&ok);
Q_ASSERT(ok);
if (!i.hasNext()) {
break;
}
int green = i.next().toInt(&ok);
Q_ASSERT(ok);
if (!i.hasNext()) {
break;
}
int blue = i.next().toInt(&ok);
Q_ASSERT(ok);
color.setRgb(red, green, blue);
break;
}
case 5 : {
if (!i.hasNext()) {
break;
}
int index = i.next().toInt(&ok);
Q_ASSERT(ok);
if (index >= 0x00 && index <= 0x07)
{ // 0x00-0x07: standard colors (as in ESC [ 40..47 m)
return parseEscapeSequence(index - 0x00 + 40, i, textCharFormat, defaultTextCharFormat);
}
else if (index >= 0x08 && index <= 0x0F)
{ // 0x08-0x0F: high intensity colors (as in ESC [ 100..107 m)
return parseEscapeSequence(index - 0x08 + 100, i, textCharFormat, defaultTextCharFormat);
}
else if (index >= 0x10 && index <= 0xE7)
{ // 0x10-0xE7: 6*6*6=216 colors: 16 + 36*r + 6*g + b (0≤r,g,b≤5)
index -= 0x10;
int red = index % 6;
index /= 6;
int green = index % 6;
index /= 6;
int blue = index % 6;
index /= 6;
Q_ASSERT(index == 0);
color.setRgb(red, green, blue);
break;
}
else if (index >= 0xE8 && index <= 0xFF)
{ // 0xE8-0xFF: grayscale from black to white in 24 steps
qreal intensity = qreal(index - 0xE8) / (0xFF - 0xE8);
color.setRgbF(intensity, intensity, intensity);
}
}
textCharFormat.setBackground(color);
break;
}
}
break;
}
case 49: {
textCharFormat.setBackground(defaultTextCharFormat.background());
break;
}
case 90:
case 91:
case 92:
case 93:
case 94:
case 95:
case 96:
case 97: {
int colorIndex = attribute - 90;
QColor color;
switch (colorIndex) {
case 0 : {
color = Qt::darkGray;
break;
}
case 1 : {
color = Qt::red;
break;
}
case 2 : {
color = Qt::green;
break;
}
case 3 : {
color = Qt::yellow;
break;
}
case 4 : {
color = Qt::blue;
break;
}
case 5 : {
color = Qt::magenta;
break;
}
case 6 : {
color = Qt::cyan;
break;
}
case 7 : {
color = Qt::white;
break;
}
default : {
Q_ASSERT(false);
}
}
color.setRedF(color.redF() * 0.8);
color.setGreenF(color.greenF() * 0.8);
color.setBlueF(color.blueF() * 0.8);
textCharFormat.setForeground(color);
break;
}
case 100:
case 101:
case 102:
case 103:
case 104:
case 105:
case 106:
case 107:
{
int colorIndex = attribute - 100;
QColor color;
switch (colorIndex) {
case 0 : {
color = Qt::darkGray;
break;
}
case 1 : {
color = Qt::red;
break;
}
case 2 : {
color = Qt::green;
break;
}
case 3 : {
color = Qt::yellow;
break;
}
case 4 : {
color = Qt::blue;
break;
}
case 5 : {
color = Qt::magenta;
break;
}
case 6 : {
color = Qt::cyan;
break;
}
case 7 : {
color = Qt::white;
break;
}
default : {
Q_ASSERT(false);
}
}
color.setRedF(color.redF() * 0.8);
color.setGreenF(color.greenF() * 0.8);
color.setBlueF(color.blueF() * 0.8);
textCharFormat.setBackground(color);
break;
}
default : {
break;
}
}
}
void MainWindow::onExtract()
{
@ -668,7 +152,7 @@ void MainWindow::doHECLTerminate()
void MainWindow::onReturnPressed()
{
if (sender() == m_ui->pathEdit && !m_ui->pathEdit->text().isEmpty())
if (sender() == m_ui->pathEdit)
setPath(m_ui->pathEdit->text());
}
@ -722,8 +206,8 @@ void MainWindow::onBinaryDownloaded(const QString& file)
#else
SHFILEOPSTRUCT fileOp = {};
fileOp.wFunc = FO_COPY;
fileOp.pFrom = (path.fileName().toStdWString() + L"\\*.*\0\0").c_str();
fileOp.pTo = (path.dir().absolutePath().toStdWString() + L"\0\0").c_str();
fileOp.pFrom = (path.absoluteFilePath().toStdWString() + L"\\*.*\0\0").c_str();
fileOp.pTo = (path.absolutePath().toStdWString() + L"\0\0").c_str();
fileOp.fFlags |= FOF_NOCONFIRMATION;
int err = SHFileOperationW(&fileOp);
if (fileOp.fAnyOperationsAborted)
@ -968,7 +452,7 @@ void MainWindow::setTextTermFormatting(const QString& text)
bool ok = false;
int attribute = i.next().toInt(&ok);
Q_ASSERT(ok);
parseEscapeSequence(attribute, i, textCharFormat, defaultTextCharFormat);
ParseEscapeSequence(attribute, i, textCharFormat, defaultTextCharFormat);
}
offset = escapeSequenceExpression.indexIn(text, previousOffset);
if (offset < 0) {

View File

@ -33,8 +33,6 @@ public:
~MainWindow();
void setTextTermFormatting(const QString& text);
void insertContinueNote(const QString& text);
void parseEscapeSequence(int attribute, QListIterator<QString>& i, QTextCharFormat& textCharFormat,
const QTextCharFormat& defaultTextCharFormat);
private slots:
void onExtract();
void onExtractFinished(int exitCode);

View File

@ -135,7 +135,7 @@
<item row="1" column="0" colspan="5">
<widget class="QTabWidget" name="heclTabs">
<property name="currentIndex">
<number>1</number>
<number>2</number>
</property>
<widget class="QWidget" name="dataTab">
<attribute name="title">
@ -604,35 +604,168 @@
<height>0</height>
</size>
</property>
<property name="palette">
<palette>
<active>
<colorrole role="WindowText">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>208</red>
<green>208</green>
<blue>208</blue>
</color>
</brush>
</colorrole>
<colorrole role="Text">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>208</red>
<green>208</green>
<blue>208</blue>
</color>
</brush>
</colorrole>
<colorrole role="ButtonText">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>208</red>
<green>208</green>
<blue>208</blue>
</color>
</brush>
</colorrole>
<colorrole role="Base">
<brush brushstyle="SolidPattern">
<color alpha="0">
<red>46</red>
<green>47</green>
<blue>48</blue>
</color>
</brush>
</colorrole>
<colorrole role="Window">
<brush brushstyle="SolidPattern">
<color alpha="0">
<red>46</red>
<green>47</green>
<blue>48</blue>
</color>
</brush>
</colorrole>
</active>
<inactive>
<colorrole role="WindowText">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>208</red>
<green>208</green>
<blue>208</blue>
</color>
</brush>
</colorrole>
<colorrole role="Text">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>208</red>
<green>208</green>
<blue>208</blue>
</color>
</brush>
</colorrole>
<colorrole role="ButtonText">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>208</red>
<green>208</green>
<blue>208</blue>
</color>
</brush>
</colorrole>
<colorrole role="Base">
<brush brushstyle="SolidPattern">
<color alpha="0">
<red>46</red>
<green>47</green>
<blue>48</blue>
</color>
</brush>
</colorrole>
<colorrole role="Window">
<brush brushstyle="SolidPattern">
<color alpha="0">
<red>46</red>
<green>47</green>
<blue>48</blue>
</color>
</brush>
</colorrole>
</inactive>
<disabled>
<colorrole role="WindowText">
<brush brushstyle="SolidPattern">
<color alpha="0">
<red>64</red>
<green>66</green>
<blue>68</blue>
</color>
</brush>
</colorrole>
<colorrole role="Text">
<brush brushstyle="SolidPattern">
<color alpha="0">
<red>64</red>
<green>66</green>
<blue>68</blue>
</color>
</brush>
</colorrole>
<colorrole role="ButtonText">
<brush brushstyle="SolidPattern">
<color alpha="0">
<red>64</red>
<green>66</green>
<blue>68</blue>
</color>
</brush>
</colorrole>
<colorrole role="Base">
<brush brushstyle="SolidPattern">
<color alpha="0">
<red>46</red>
<green>47</green>
<blue>48</blue>
</color>
</brush>
</colorrole>
<colorrole role="Window">
<brush brushstyle="SolidPattern">
<color alpha="0">
<red>46</red>
<green>47</green>
<blue>48</blue>
</color>
</brush>
</colorrole>
</disabled>
</palette>
</property>
<property name="html">
<string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'Noto Sans'; font-size:10pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p align=&quot;center&quot; style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-size:x-large; font-weight:600;&quot;&gt;About HECL Frontend&lt;/span&gt;&lt;/p&gt;
&lt;p align=&quot;center&quot; style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;br /&gt;The hecl frontend UI is designed and built by &lt;a href=&quot;https://axiodl.com&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#007af4;&quot;&gt;Axiomatic Data Laboratories&lt;/span&gt;&lt;/a&gt; Copyright 2017 &lt;br /&gt;&lt;br /&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;Authors:&lt;/span&gt;&lt;br /&gt;Phillip &amp;quot;Antidote&amp;quot; Stephens&lt;br /&gt;Jack &amp;quot;jackoalan&amp;quot; Andersen&lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:'Courier New';&quot;&gt;The MIT License&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Courier New';&quot;&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:'Courier New';&quot;&gt;Copyright (c) 2015-2017 URDE Contributors&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:'Courier New';&quot;&gt;Original Authors: Jack Andersen and Phillip &amp;quot;Antidote&amp;quot; Stephens&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Courier New';&quot;&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:'Courier New';&quot;&gt;Permission is hereby granted, free of charge, to any person obtaining a copy&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:'Courier New';&quot;&gt;of this software and associated documentation files (the &amp;quot;Software&amp;quot;), to deal&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:'Courier New';&quot;&gt;in the Software without restriction, including without limitation the rights&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:'Courier New';&quot;&gt;to use, copy, modify, merge, publish, distribute, sublicense, and/or sell&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:'Courier New';&quot;&gt;copies of the Software, and to permit persons to whom the Software is&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:'Courier New';&quot;&gt;furnished to do so, subject to the following conditions:&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Courier New';&quot;&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:'Courier New';&quot;&gt;The above copyright notice and this permission notice shall be included in all&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:'Courier New';&quot;&gt;copies or substantial portions of the Software.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Courier New';&quot;&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:'Courier New';&quot;&gt;THE SOFTWARE IS PROVIDED &amp;quot;AS IS&amp;quot;, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:'Courier New';&quot;&gt;IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:'Courier New';&quot;&gt;FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:'Courier New';&quot;&gt;AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:'Courier New';&quot;&gt;LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:'Courier New';&quot;&gt;OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:'Courier New';&quot;&gt;SOFTWARE.&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'.SF NS Text'; font-size:13pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p align=&quot;center&quot; style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:'Noto Sans'; font-size:10pt; font-weight:600;&quot;&gt;About HECL Frontend&lt;/span&gt;&lt;/p&gt;
&lt;p align=&quot;center&quot; style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:'Noto Sans'; font-size:10pt;&quot;&gt;&lt;br /&gt;The hecl frontend UI is designed and built by &lt;/span&gt;&lt;a href=&quot;https://axiodl.com&quot;&gt;&lt;span style=&quot; font-family:'Noto Sans'; font-size:10pt; text-decoration: underline; color:#007af4;&quot;&gt;Axiomatic Data Laboratories&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot; font-family:'Noto Sans'; font-size:10pt;&quot;&gt; Copyright 2017 &lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot; font-family:'Noto Sans'; font-size:10pt; font-weight:600;&quot;&gt;Authors:&lt;/span&gt;&lt;span style=&quot; font-family:'Noto Sans'; font-size:10pt;&quot;&gt;&lt;br /&gt;Phillip &amp;quot;Antidote&amp;quot; Stephens&lt;br /&gt;Jack &amp;quot;jackoalan&amp;quot; Andersen&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:'Courier New'; font-size:10pt;&quot;&gt;The MIT License&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Courier New'; font-size:10pt;&quot;&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:'Courier New'; font-size:10pt;&quot;&gt;Copyright (c) 2015-2018 URDE Contributors&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:'Courier New'; font-size:10pt;&quot;&gt;Original Authors: Jack Andersen and Phillip &amp;quot;Antidote&amp;quot; Stephens&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Courier New'; font-size:10pt;&quot;&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:'Courier New'; font-size:10pt;&quot;&gt;Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the &amp;quot;Software&amp;quot;), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Courier New'; font-size:10pt;&quot;&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:'Courier New'; font-size:10pt;&quot;&gt;The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Courier New'; font-size:10pt;&quot;&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:'Courier New'; font-size:10pt;&quot;&gt;THE SOFTWARE IS PROVIDED &amp;quot;AS IS&amp;quot;, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="openExternalLinks">
<bool>true</bool>

View File

@ -5,6 +5,7 @@
#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonArray>
#include <QDomDocument>
#include <QProcess>
#if _WIN32
@ -60,7 +61,31 @@ SysReqTableModel::SysReqTableModel(QObject* parent)
}
}
}
#elif defined(__APPLE__)
QProcess spProc;
spProc.start("system_profiler", {"-xml", "SPHardwareDataType"}, QProcess::ReadOnly);
spProc.waitForFinished();
QDomDocument spDoc;
spDoc.setContent(spProc.readAll());
QDomElement spDocElem = spDoc.documentElement();
QDomElement n = spDocElem.firstChildElement("array").firstChildElement("dict").firstChildElement("key");
while (!n.isNull() && n.text() != "_items")
n = n.nextSiblingElement("key");
if (!n.isNull())
{
n = n.nextSiblingElement("array").firstChildElement("dict").firstChildElement("key");
while (!n.isNull() && n.text() != "current_processor_speed")
n = n.nextSiblingElement("key");
if (!n.isNull())
{
n = n.nextSiblingElement("string");
double speed = n.text().split(' ').front().toDouble();
m_cpuSpeed = uint64_t(speed * 1000.0);
m_cpuSpeedStr.sprintf("%g GHz", speed);
}
}
#else
/* This only works for Skylake+ */
int regs[4] = {};
zeus::getCpuInfo(0, regs);
if (regs[0] >= 0x16)

View File

@ -7,7 +7,7 @@
<key>CFBundleGetInfoString</key>
<string>Version BETA</string>
<key>NSHumanReadableCopyright</key>
<string>2015-2017 Antidote / Jackoalan</string>
<string>2015-2018 Antidote / Jackoalan</string>
<key>CFBundleIconFile</key>
<string>mainicon.icns</string>
<key>CFBundleIdentifier</key>

View File

@ -19,7 +19,7 @@ BEGIN
VALUE "CompanyName", "Antidote / Jackoalan"
VALUE "FileDescription", "HECL"
VALUE "FileVersion", "BETA"
VALUE "LegalCopyright", "Copyright (C) 2015-2017 Antidote / Jackoalan"
VALUE "LegalCopyright", "Copyright (C) 2015-2018 Antidote / Jackoalan"
VALUE "InternalName", "urde"
VALUE "OriginalFilename", "hecl.exe"
VALUE "ProductName", "HECL"