mirror of
https://github.com/wh201906/Proxmark3GUI.git
synced 2026-07-14 22:55:32 +08:00
Merge branch 'dev'
This commit is contained in:
@@ -51,18 +51,19 @@ FORMS += \
|
||||
ui/mf_attack_hardnesteddialog.ui
|
||||
|
||||
TRANSLATIONS += \
|
||||
i18n/zh_CN.ts \
|
||||
i18n/en_US.ts
|
||||
../i18n/zh_CN.ts \
|
||||
../i18n/en_US.ts
|
||||
|
||||
# Default rules for deployment.
|
||||
qnx: target.path = /tmp/$${TARGET}/bin
|
||||
else: unix:!android: target.path = /opt/$${TARGET}/bin
|
||||
!isEmpty(target.path): INSTALLS += target
|
||||
|
||||
VERSION = 0.2.5
|
||||
VERSION = 0.2.6
|
||||
QMAKE_TARGET_PRODUCT = "Proxmark3GUI"
|
||||
QMAKE_TARGET_DESCRIPTION = "Proxmark3GUI"
|
||||
QMAKE_TARGET_COMPANY = "wh201906"
|
||||
|
||||
RESOURCES += \
|
||||
i18n/language.qrc
|
||||
../i18n/language.qrc \
|
||||
../config/config.qrc
|
||||
|
||||
@@ -13,6 +13,8 @@ PM3Process::PM3Process(QThread* thread, QObject* parent): QProcess(parent)
|
||||
connect(serialListener, &QTimer::timeout, this, &PM3Process::onTimeout);
|
||||
connect(this, &PM3Process::readyRead, this, &PM3Process::onReadyRead);
|
||||
portInfo = nullptr;
|
||||
|
||||
qRegisterMetaType<QProcess::ProcessError>("QProcess::ProcessError");
|
||||
}
|
||||
|
||||
void PM3Process::connectPM3(const QString& path, const QStringList args)
|
||||
@@ -26,7 +28,8 @@ void PM3Process::connectPM3(const QString& path, const QStringList args)
|
||||
currArgs = args;
|
||||
|
||||
// using "-f" option to make the client output flushed after every print.
|
||||
start(path, args, QProcess::Unbuffered | QProcess::ReadWrite | QProcess::Text);
|
||||
// single '\r' might appear. Don't use QProcess::Text there or '\r' is ignored.
|
||||
start(path, args, QProcess::Unbuffered | QProcess::ReadWrite);
|
||||
if(waitForStarted(10000))
|
||||
{
|
||||
waitForReadyRead(10000);
|
||||
@@ -59,8 +62,13 @@ void PM3Process::connectPM3(const QString& path, const QStringList args)
|
||||
emit PM3StatedChanged(true, result);
|
||||
}
|
||||
else
|
||||
{
|
||||
emit HWConnectFailed();
|
||||
kill();
|
||||
}
|
||||
}
|
||||
|
||||
setRequiringOutput(false);
|
||||
}
|
||||
|
||||
void PM3Process::reconnectPM3()
|
||||
|
||||
@@ -48,6 +48,7 @@ signals:
|
||||
void PM3StatedChanged(bool st, const QString& info = "");
|
||||
void newOutput(const QString& output);
|
||||
void changeClientType(Util::ClientType);
|
||||
void HWConnectFailed();
|
||||
};
|
||||
|
||||
#endif // PM3PROCESS_H
|
||||
|
||||
+17
-5
@@ -119,17 +119,29 @@ bool Util::chooseLanguage(QSettings* guiSettings, QMainWindow* window)
|
||||
QStringList langList = langSettings->allKeys();
|
||||
for(int i = 0; i < langList.size(); i++)
|
||||
langMap.insert(langSettings->value(langList[i]).toString(), langList[i]);
|
||||
langMap.insert(tr("Load from external file"), "(ext)");
|
||||
langSettings->endGroup();
|
||||
delete langSettings;
|
||||
bool isOk = false;
|
||||
QString selectedText = QInputDialog::getItem(window, "", "Choose a language:", langMap.keys(), 0, false, &isOk);
|
||||
if(isOk)
|
||||
QString selectedText = QInputDialog::getItem(window, "", tr("Choose a language:"), langMap.keys(), 0, false, &isOk);
|
||||
if(!isOk)
|
||||
return false;
|
||||
if(langMap[selectedText] == "(ext)")
|
||||
{
|
||||
guiSettings->beginGroup("lang");
|
||||
guiSettings->setValue("language", langMap[selectedText]);
|
||||
QString extPath = QFileDialog::getOpenFileName(nullptr, tr("Select the translation file:"));
|
||||
if(extPath.isEmpty())
|
||||
return false;
|
||||
|
||||
guiSettings->beginGroup("language");
|
||||
guiSettings->setValue("extPath", extPath);
|
||||
guiSettings->endGroup();
|
||||
guiSettings->sync();
|
||||
}
|
||||
|
||||
guiSettings->beginGroup("language");
|
||||
guiSettings->setValue("name", langMap[selectedText]);
|
||||
guiSettings->endGroup();
|
||||
guiSettings->sync();
|
||||
|
||||
return isOk;
|
||||
}
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include <QSettings>
|
||||
#include <QMainWindow>
|
||||
#include <QInputDialog>
|
||||
#include <QFileDialog>
|
||||
#include <QDockWidget>
|
||||
|
||||
#include "ui_mainwindow.h"
|
||||
|
||||
Binary file not shown.
-1450
File diff suppressed because it is too large
Load Diff
@@ -1,7 +0,0 @@
|
||||
<RCC>
|
||||
<qresource prefix="/i18n">
|
||||
<file>en_US.qm</file>
|
||||
<file>languages.ini</file>
|
||||
<file>zh_CN.qm</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
@@ -1,4 +0,0 @@
|
||||
[Languages]
|
||||
en_US=English
|
||||
zh_CN=简体中文
|
||||
ext=Load from external file
|
||||
Binary file not shown.
-1466
File diff suppressed because it is too large
Load Diff
+16
-15
@@ -27,33 +27,34 @@ int main(int argc, char *argv[])
|
||||
|
||||
QSettings* settings = new QSettings("GUIsettings.ini", QSettings::IniFormat);
|
||||
settings->setIniCodec("UTF-8");
|
||||
settings->beginGroup("lang");
|
||||
QString currLang = settings->value("language", "").toString();
|
||||
settings->beginGroup("language");
|
||||
QString languageFile = settings->value("extPath").toString();
|
||||
QString languageName = settings->value("name").toString();
|
||||
settings->endGroup();
|
||||
if(currLang == "")
|
||||
if(languageName == "")
|
||||
{
|
||||
if(Util::chooseLanguage(settings, &w))
|
||||
{
|
||||
settings->beginGroup("lang");
|
||||
currLang = settings->value("language", "").toString();
|
||||
settings->beginGroup("language");
|
||||
languageName = settings->value("name").toString();
|
||||
settings->endGroup();
|
||||
}
|
||||
else
|
||||
currLang = "en_US";
|
||||
languageName = "en_US";
|
||||
}
|
||||
if(languageName == "(ext)")
|
||||
{
|
||||
settings->beginGroup("language");
|
||||
languageFile = settings->value("extPath").toString();
|
||||
settings->endGroup();
|
||||
}
|
||||
if(currLang == "ext")
|
||||
currLang = QFileDialog::getOpenFileName(nullptr, "Select the translation file:");
|
||||
else
|
||||
currLang = ":/i18n/" + currLang + ".qm";
|
||||
languageFile = ":/i18n/" + languageName + ".qm";
|
||||
QTranslator* translator = new QTranslator(&w);
|
||||
if(translator->load(currLang))
|
||||
{
|
||||
if(translator->load(languageFile))
|
||||
a.installTranslator(translator);
|
||||
}
|
||||
else
|
||||
{
|
||||
QMessageBox::information(&w, "Error", "Can't load " + currLang + " as translation file.");
|
||||
}
|
||||
QMessageBox::information(&w, "Error", "Can't load " + languageFile + " as translation file.");
|
||||
delete settings;
|
||||
w.initUI();
|
||||
w.show();
|
||||
|
||||
+4
-2
@@ -81,8 +81,10 @@ void LF::getLFConfig()
|
||||
QVariantMap config = configMap["get config"].toMap();
|
||||
QString cmd = config["cmd"].toString();
|
||||
result = util->execCMDWithOutput(cmd, 400);
|
||||
start = result.indexOf(config["field start"].toString());
|
||||
end = result.indexOf(config["field end"].toString());
|
||||
reMatch = QRegularExpression(config["field start"].toString(), QRegularExpression::MultilineOption).match(result);
|
||||
start = reMatch.hasMatch() ? reMatch.capturedEnd() : 0;
|
||||
reMatch = QRegularExpression(config["field end"].toString(), QRegularExpression::MultilineOption).match(result, start);
|
||||
end = reMatch.hasMatch() ? reMatch.capturedStart() : result.length();
|
||||
result = result.mid(start, end - start);
|
||||
#if (QT_VERSION <= QT_VERSION_CHECK(5,14,0))
|
||||
resultList = result.split("\n", QString::SkipEmptyParts);
|
||||
|
||||
+16
-6
@@ -130,7 +130,7 @@ void Mifare::chk()
|
||||
QString cmd = config["cmd"].toString();
|
||||
int keyAindex = config["key A index"].toInt();
|
||||
int keyBindex = config["key B index"].toInt();
|
||||
QRegularExpression keyPattern = QRegularExpression(config["key pattern"].toString());
|
||||
QRegularExpression keyPattern = QRegularExpression(config["key pattern"].toString(), QRegularExpression::MultilineOption);
|
||||
cmd.replace("<card type>", config["card type"].toMap()[cardType.typeText].toString());
|
||||
|
||||
result = util->execCMDWithOutput(
|
||||
@@ -169,7 +169,7 @@ void Mifare::nested(bool isStaticNested)
|
||||
cmd = config["cmd"].toString();
|
||||
int keyAindex = config["key A index"].toInt();
|
||||
int keyBindex = config["key B index"].toInt();
|
||||
QRegularExpression keyPattern = QRegularExpression(config["key pattern"].toString());
|
||||
QRegularExpression keyPattern = QRegularExpression(config["key pattern"].toString(), QRegularExpression::MultilineOption);
|
||||
QRegularExpressionMatch reMatch;
|
||||
QString result;
|
||||
int offset = 0;
|
||||
@@ -212,7 +212,7 @@ void Mifare::nested(bool isStaticNested)
|
||||
}
|
||||
result = util->execCMDWithOutput(
|
||||
cmd,
|
||||
Util::ReturnTrigger(15000, {"Can't found", "Can't authenticate", keyPattern_res->pattern()}),
|
||||
Util::ReturnTrigger(15000, {"Quit", "Can't found", "Can't authenticate", keyPattern_res->pattern()}),
|
||||
true);
|
||||
|
||||
if(result.contains("static") && !isStaticNested)
|
||||
@@ -691,10 +691,14 @@ void Mifare::writeSelected(TargetType targetType)
|
||||
{
|
||||
result = _writeblk(item, KEY_B, keyBList->at(data_b2s(item)), dataList->at(item), TARGET_MIFARE);
|
||||
}
|
||||
if(!result)
|
||||
if(!result && keyAList->at(data_b2s(item)) != "FFFFFFFFFFFF")
|
||||
{
|
||||
result = _writeblk(item, KEY_A, "FFFFFFFFFFFF", dataList->at(item), TARGET_MIFARE);
|
||||
}
|
||||
if(!result && keyBList->at(data_b2s(item)) != "FFFFFFFFFFFF") // for access bits like "80 f7 87", the block can only be written with keyB
|
||||
{
|
||||
result = _writeblk(item, KEY_B, "FFFFFFFFFFFF", dataList->at(item), TARGET_MIFARE);
|
||||
}
|
||||
}
|
||||
else // key doesn't matter when writing to Chinese Magic Card and Emulator Memory
|
||||
{
|
||||
@@ -743,14 +747,20 @@ void Mifare::writeSelected(TargetType targetType)
|
||||
void Mifare::dump()
|
||||
{
|
||||
QVariantMap config = configMap["dump"].toMap();
|
||||
util->execCMD(config["cmd"].toString());
|
||||
QString cmd = config["cmd"].toString();
|
||||
if(cmd.contains("<card type>"))
|
||||
cmd.replace("<card type>", config["card type"].toMap()[cardType.typeText].toString());
|
||||
util->execCMD(cmd);
|
||||
Util::gotoRawTab();
|
||||
}
|
||||
|
||||
void Mifare::restore()
|
||||
{
|
||||
QVariantMap config = configMap["restore"].toMap();
|
||||
util->execCMD(config["cmd"].toString());
|
||||
QString cmd = config["cmd"].toString();
|
||||
if(cmd.contains("<card type>"))
|
||||
cmd.replace("<card type>", config["card type"].toMap()[cardType.typeText].toString());
|
||||
util->execCMD(cmd);
|
||||
Util::gotoRawTab();
|
||||
}
|
||||
|
||||
|
||||
+85
-9
@@ -2,6 +2,7 @@
|
||||
#include "ui_mainwindow.h"
|
||||
|
||||
#include <QJsonDocument>
|
||||
#include <QDirIterator>
|
||||
|
||||
MainWindow::MainWindow(QWidget *parent):
|
||||
QMainWindow(parent)
|
||||
@@ -30,7 +31,9 @@ MainWindow::MainWindow(QWidget *parent):
|
||||
settings->setIniCodec("UTF-8");
|
||||
|
||||
pm3Thread = new QThread(this);
|
||||
connect(QApplication::instance(), &QApplication::aboutToQuit, pm3Thread, &QThread::quit);
|
||||
pm3 = new PM3Process(pm3Thread);
|
||||
connect(pm3Thread, &QThread::finished, pm3, &PM3Process::deleteLater);
|
||||
pm3Thread->start();
|
||||
pm3state = false;
|
||||
clientWorkingDir = new QDir;
|
||||
@@ -77,7 +80,11 @@ MainWindow::~MainWindow()
|
||||
|
||||
void MainWindow::loadConfig()
|
||||
{
|
||||
QFile configList(ui->Set_Client_configPathEdit->text());
|
||||
QString filename = ui->Set_Client_configFileBox->currentData().toString();
|
||||
if(filename == "(ext)")
|
||||
filename = ui->Set_Client_configPathEdit->text();
|
||||
qDebug() << "config file:" << filename;
|
||||
QFile configList(filename);
|
||||
if(!configList.open(QFile::ReadOnly | QFile::Text))
|
||||
{
|
||||
QMessageBox::information(this, tr("Info"), tr("Failed to load config file"));
|
||||
@@ -104,18 +111,46 @@ void MainWindow::initUI() // will be called by main.app
|
||||
|
||||
void MainWindow::on_portSearchTimer_timeout()
|
||||
{
|
||||
QStringList newPortList;
|
||||
QStringList newPortList; // for actural port name
|
||||
QStringList newPortNameList; // for display name
|
||||
const QString hint = " *";
|
||||
|
||||
foreach(const QSerialPortInfo &info, QSerialPortInfo::availablePorts())
|
||||
{
|
||||
// qDebug() << info.isBusy() << info.isNull() << info.portName() << info.description();
|
||||
// qDebug() << info.isNull() << info.portName() << info.description() << info.serialNumber() << info.manufacturer();
|
||||
if(!info.isNull())
|
||||
newPortList << info.portName();
|
||||
{
|
||||
QString idString = (info.description() + info.serialNumber() + info.manufacturer()).toLower();
|
||||
QString portName = info.portName();
|
||||
|
||||
newPortList << portName;
|
||||
if(info.hasVendorIdentifier() && info.hasProductIdentifier())
|
||||
{
|
||||
quint16 vid = info.vendorIdentifier();
|
||||
quint16 pid = info.productIdentifier();
|
||||
if(vid == 0x9AC4 && pid == 0x4B8F)
|
||||
portName += hint;
|
||||
else if(vid == 0x2D2D && pid == 0x504D)
|
||||
portName += hint;
|
||||
}
|
||||
else if(idString.contains("proxmark") || idString.contains("iceman"))
|
||||
portName += hint;
|
||||
newPortNameList << portName;
|
||||
}
|
||||
}
|
||||
if(newPortList != portList) // update PM3_portBox when available ports changed
|
||||
{
|
||||
portList = newPortList;
|
||||
ui->PM3_portBox->clear();
|
||||
ui->PM3_portBox->addItems(portList);
|
||||
int selectId = -1;
|
||||
for(int i = 0; i < portList.size(); i++)
|
||||
{
|
||||
ui->PM3_portBox->addItem(newPortNameList[i], newPortList[i]);
|
||||
if(selectId == -1 && newPortNameList[i].endsWith(hint))
|
||||
selectId = i;
|
||||
}
|
||||
if(selectId != -1)
|
||||
ui->PM3_portBox->setCurrentIndex(selectId);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -123,7 +158,7 @@ void MainWindow::on_PM3_connectButton_clicked()
|
||||
{
|
||||
qDebug() << "Main:" << QThread::currentThread();
|
||||
|
||||
QString port = ui->PM3_portBox->currentText();
|
||||
QString port = ui->PM3_portBox->currentData().toString();
|
||||
QString startArgs = ui->Set_Client_startArgsEdit->text();
|
||||
|
||||
// on RRG repo, if no port is specified, the client will search the available port
|
||||
@@ -193,6 +228,18 @@ void MainWindow::on_PM3_connectButton_clicked()
|
||||
envSetProcess.kill();
|
||||
}
|
||||
|
||||
void MainWindow::onPM3ErrorOccurred(QProcess::ProcessError error)
|
||||
{
|
||||
qDebug() << "PM3 Error:" << error << pm3->errorString();
|
||||
if(error == QProcess::FailedToStart)
|
||||
QMessageBox::information(this, tr("Info"), tr("Failed to start the client"));
|
||||
}
|
||||
|
||||
void MainWindow::onPM3HWConnectFailed()
|
||||
{
|
||||
QMessageBox::information(this, tr("Info"), tr("Failed to connect to the hardware"));
|
||||
}
|
||||
|
||||
void MainWindow::onPM3StateChanged(bool st, const QString& info)
|
||||
{
|
||||
pm3state = st;
|
||||
@@ -220,7 +267,8 @@ void MainWindow::on_PM3_disconnectButton_clicked()
|
||||
void MainWindow::refreshOutput(const QString& output)
|
||||
{
|
||||
// qDebug() << "MainWindow::refresh:" << output;
|
||||
ui->Raw_outputEdit->appendPlainText(output);
|
||||
ui->Raw_outputEdit->moveCursor(QTextCursor::End);
|
||||
ui->Raw_outputEdit->insertPlainText(output);
|
||||
ui->Raw_outputEdit->moveCursor(QTextCursor::End);
|
||||
}
|
||||
|
||||
@@ -1054,6 +1102,8 @@ void MainWindow::uiInit()
|
||||
ui->PM3_pathEdit->setText(settings->value("path", "proxmark3").toString());
|
||||
settings->endGroup();
|
||||
|
||||
ui->Set_Client_GUIWorkingDirLabel->setText(QDir::currentPath());
|
||||
|
||||
settings->beginGroup("Client_Args");
|
||||
ui->Set_Client_startArgsEdit->setText(settings->value("args", "<port> -f").toString());
|
||||
settings->endGroup();
|
||||
@@ -1068,11 +1118,27 @@ void MainWindow::uiInit()
|
||||
ui->Set_Client_keepClientActiveBox->setChecked(keepClientActive);
|
||||
settings->endGroup();
|
||||
|
||||
QDirIterator configFiles(":/config/");
|
||||
ui->Set_Client_configFileBox->blockSignals(true);
|
||||
while(configFiles.hasNext())
|
||||
{
|
||||
configFiles.next();
|
||||
ui->Set_Client_configFileBox->addItem(configFiles.fileName(), configFiles.filePath());
|
||||
}
|
||||
ui->Set_Client_configFileBox->addItem(tr("External file"), "(ext)");
|
||||
|
||||
int configId = -1;
|
||||
settings->beginGroup("Client_Env");
|
||||
ui->Set_Client_envScriptEdit->setText(settings->value("scriptPath").toString());
|
||||
ui->Set_Client_workingDirEdit->setText(settings->value("workingDir", "../data").toString());
|
||||
ui->Set_Client_configPathEdit->setText(settings->value("configPath", "config.json").toString());
|
||||
configId = ui->Set_Client_configFileBox->findData(settings->value("configFile"));
|
||||
ui->Set_Client_configPathEdit->setText(settings->value("extConfigFilePath", "config.json").toString());
|
||||
settings->endGroup();
|
||||
if(configId != -1)
|
||||
ui->Set_Client_configFileBox->setCurrentIndex(configId);
|
||||
ui->Set_Client_configFileBox->blockSignals(false);
|
||||
on_Set_Client_configFileBox_currentIndexChanged(ui->Set_Client_configFileBox->currentIndex());
|
||||
|
||||
|
||||
ui->MF_RW_keyTypeBox->addItem("A", Mifare::KEY_A);
|
||||
ui->MF_RW_keyTypeBox->addItem("B", Mifare::KEY_B);
|
||||
@@ -1091,6 +1157,8 @@ void MainWindow::signalInit()
|
||||
connect(this, &MainWindow::reconnectPM3, pm3, &PM3Process::reconnectPM3);
|
||||
connect(pm3, &PM3Process::PM3StatedChanged, this, &MainWindow::onPM3StateChanged);
|
||||
connect(pm3, &PM3Process::PM3StatedChanged, util, &Util::setRunningState);
|
||||
connect(pm3, &PM3Process::errorOccurred, this, &MainWindow::onPM3ErrorOccurred);
|
||||
connect(pm3, &PM3Process::HWConnectFailed, this, &MainWindow::onPM3HWConnectFailed);
|
||||
connect(this, &MainWindow::killPM3, pm3, &PM3Process::killPM3);
|
||||
connect(this, &MainWindow::setProcEnv, pm3, &PM3Process::setProcEnv);
|
||||
connect(this, &MainWindow::setWorkingDir, pm3, &PM3Process::setWorkingDir);
|
||||
@@ -1274,7 +1342,7 @@ void MainWindow::on_Set_Client_workingDirEdit_editingFinished()
|
||||
void MainWindow::on_Set_Client_configPathEdit_editingFinished()
|
||||
{
|
||||
settings->beginGroup("Client_Env");
|
||||
settings->setValue("configPath", ui->Set_Client_configPathEdit->text());
|
||||
settings->setValue("extConfigFilePath", ui->Set_Client_configPathEdit->text());
|
||||
settings->endGroup();
|
||||
}
|
||||
|
||||
@@ -1412,3 +1480,11 @@ void MainWindow::on_LF_LFConf_resetButton_clicked()
|
||||
setState(true);
|
||||
}
|
||||
|
||||
void MainWindow::on_Set_Client_configFileBox_currentIndexChanged(int index)
|
||||
{
|
||||
ui->Set_Client_configPathEdit->setVisible(ui->Set_Client_configFileBox->itemData(index).toString() == "(ext)");
|
||||
settings->beginGroup("Client_Env");
|
||||
settings->setValue("configFile", ui->Set_Client_configFileBox->currentData());
|
||||
settings->endGroup();
|
||||
}
|
||||
|
||||
|
||||
+6
-1
@@ -51,7 +51,7 @@ public:
|
||||
~MainWindow();
|
||||
|
||||
void initUI();
|
||||
bool eventFilter(QObject *watched, QEvent *event);
|
||||
bool eventFilter(QObject *watched, QEvent *event) override;
|
||||
public slots:
|
||||
void refreshOutput(const QString& output);
|
||||
void refreshCMD(const QString& cmd);
|
||||
@@ -60,6 +60,8 @@ public slots:
|
||||
void MF_onMFCardTypeChanged(int id, bool st);
|
||||
void on_Raw_keyPressed(QObject *obj_addr, QEvent &event);
|
||||
void on_MF_keyWidget_resized(QObject *obj_addr, QEvent &event);
|
||||
void onPM3ErrorOccurred(QProcess::ProcessError error);
|
||||
void onPM3HWConnectFailed();
|
||||
private slots:
|
||||
|
||||
void on_PM3_connectButton_clicked();
|
||||
@@ -207,6 +209,9 @@ private slots:
|
||||
void on_Set_Client_configPathEdit_editingFinished();
|
||||
|
||||
void setState(bool st);
|
||||
|
||||
void on_Set_Client_configFileBox_currentIndexChanged(int index);
|
||||
|
||||
private:
|
||||
Ui::MainWindow* ui;
|
||||
QButtonGroup* MFCardTypeBtnGroup;
|
||||
|
||||
+44
-3
@@ -1454,8 +1454,8 @@ When setting the freq, the "hw setlfdivisor" will also be called.</str
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QCheckBox" name="LF_LFConf_averagingBox">
|
||||
<property name="text">
|
||||
<string/>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
@@ -2650,6 +2650,23 @@ or the communication between a tag and a reader.</string>
|
||||
<string>Client</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_10">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_65">
|
||||
<property name="text">
|
||||
<string>GUI working directory:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="Set_Client_GUIWorkingDirLabel"/>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="Line" name="line_9">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_11">
|
||||
<property name="text">
|
||||
@@ -2746,10 +2763,34 @@ or the communication between a tag and a reader.</string>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_63">
|
||||
<property name="text">
|
||||
<string>Config file path(Reconnect to apply):</string>
|
||||
<string>Config file(Reconnect to apply):</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_15">
|
||||
<item>
|
||||
<widget class="QComboBox" name="Set_Client_configFileBox">
|
||||
<property name="sizeAdjustPolicy">
|
||||
<enum>QComboBox::AdjustToContents</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_13">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="Set_Client_configPathEdit">
|
||||
<property name="text">
|
||||
|
||||
Reference in New Issue
Block a user