1 #include "ventoy2diskwindow.h"
2 #include "ui_ventoy2diskwindow.h"
3 #include "partcfgdialog.h"
8 #include "ventoy_define.h"
9 #include "ventoy_util.h"
10 #include "ventoy_disk.h"
11 #include "ventoy_json.h"
12 #include "ventoy_http.h"
13 #include "ventoy_qt.h"
16 MyQThread::MyQThread(QObject
*parent
) : QThread(parent
)
23 void MyQThread::install_run()
35 vlog("install run %d ...\n", m_index
);
37 cur
= g_disk_list
+ m_index
;
38 snprintf(disk_name
, sizeof(disk_name
), "%s", cur
->disk_name
);
39 snprintf(dec
, sizeof(dec
), "%llu", (unsigned long long)m_reserve_space
);
42 VTOY_JSON_FMT_BEGIN(pos
, buf
, buflen
);
43 VTOY_JSON_FMT_OBJ_BEGIN();
44 VTOY_JSON_FMT_STRN("method", "install");
45 VTOY_JSON_FMT_STRN("disk", disk_name
);
46 VTOY_JSON_FMT_STRN("reserve_space", dec
);
47 VTOY_JSON_FMT_UINT("partstyle", ventoy_code_get_cur_part_style());
48 VTOY_JSON_FMT_UINT("secure_boot", m_secureboot
);
49 VTOY_JSON_FMT_UINT("align_4kb", m_align4K
);
50 VTOY_JSON_FMT_OBJ_END();
51 VTOY_JSON_FMT_END(pos
);
54 ventoy_func_handler(buf
, out
, sizeof(out
));
55 vlog("func handler install <%s>\n", out
);
57 if (strstr(out
, "success"))
59 while (percent
!= 100)
61 percent
= ventoy_code_get_percent();
62 emit
thread_event(THREAD_MSG_PROGRESS_BAR
, percent
);
66 ret
= ventoy_code_get_result();
67 ventoy_code_refresh_device();
75 emit
thread_event(THREAD_MSG_INSTALL_FINISH
, ret
);
79 void MyQThread::update_run()
88 vlog("install run %d ...\n", m_index
);
90 cur
= g_disk_list
+ m_index
;
91 snprintf(disk_name
, sizeof(disk_name
), "%s", cur
->disk_name
);
92 snprintf(buf
, sizeof(buf
), "{\"method\":\"update\",\"disk\":\"%s\",\"secure_boot\":%d}", disk_name
, m_secureboot
);
95 ventoy_func_handler(buf
, out
, sizeof(out
));
96 vlog("func handler update <%s>\n", out
);
98 if (strstr(out
, "success"))
100 while (percent
!= 100)
102 percent
= ventoy_code_get_percent();
103 emit
thread_event(THREAD_MSG_PROGRESS_BAR
, percent
);
107 ret
= ventoy_code_get_result();
108 ventoy_code_refresh_device();
116 emit
thread_event(THREAD_MSG_UPDATE_FINISH
, ret
);
120 void MyQThread::run()
122 if (THREAD_TYPE_INSTALL
== m_type
)
126 else if (THREAD_TYPE_UPDATE
== m_type
)
137 Ventoy2DiskWindow::Ventoy2DiskWindow(QWidget
*parent
)
138 : QMainWindow(parent
)
139 , ui(new Ui::Ventoy2DiskWindow
)
141 m_partcfg
= new PartCfgDialog();
142 m_part_group
= new QActionGroup(this);
143 m_lang_group
= new QActionGroup(this);
144 m_thread
= new MyQThread(this);
149 Ventoy2DiskWindow::~Ventoy2DiskWindow()
158 bool LangCompare(const QString
&s1
, const QString
&s2
)
160 if (true == s1
.startsWith("Chinese Simplified") && false == s2
.startsWith("Chinese Simplified"))
164 else if (false == s1
.startsWith("Chinese Simplified") && true == s2
.startsWith("Chinese Simplified"))
174 int Ventoy2DiskWindow::lang_string(const QString
&id
, QString
&str
)
176 QString cur
= ventoy_code_get_cur_language();
178 for (QJsonArray::iterator p
= m_lang_array
.begin(); p
!= m_lang_array
.end(); p
++)
180 if (p
->toObject().value("name") == cur
)
182 str
= p
->toObject().value(id
).toString();
183 str
= str
.replace("#@", "\r\n");
191 void Ventoy2DiskWindow::update_ui_language()
195 QString cur
= ventoy_code_get_cur_language();
197 for (QJsonArray::iterator p
= m_lang_array
.begin(); p
!= m_lang_array
.end(); p
++)
199 if (p
->toObject().value("name") == cur
)
206 ui
->menuOption
->setTitle(_LANG_STR("STR_MENU_OPTION"));
207 ui
->actionSecure_Boot_Support
->setText(_LANG_STR("STR_MENU_SECURE_BOOT"));
208 ui
->menuPartition_Style
->setTitle(_LANG_STR("STR_MENU_PART_STYLE"));
209 ui
->actionPartition_Configuration
->setText(_LANG_STR("STR_MENU_PART_CFG"));
210 ui
->actionClear_Ventoy
->setText(_LANG_STR("STR_MENU_CLEAR"));
211 ui
->actionShow_All_Devices
->setText(_LANG_STR("STR_SHOW_ALL_DEV"));
213 dev
= _LANG_STR("STR_DEVICE");
214 if (m_partcfg
->reserve
)
217 str
.sprintf(" [ -%lld%s ]", (long long)m_partcfg
->resvalue
, m_partcfg
->unit
? "GB" : "MB");
218 ui
->groupBoxDevice
->setTitle(dev
+ str
);
222 ui
->groupBoxDevice
->setTitle(dev
);
225 ui
->groupBoxVentoyLocal
->setTitle(_LANG_STR("STR_LOCAL_VER"));
226 ui
->groupBoxVentoyDevice
->setTitle(_LANG_STR("STR_DISK_VER"));
227 ui
->groupBoxStatus
->setTitle(_LANG_STR("STR_STATUS"));
228 ui
->ButtonInstall
->setText(_LANG_STR("STR_INSTALL"));
229 ui
->ButtonUpdate
->setText(_LANG_STR("STR_UPDATE"));
230 m_partcfg
->update_language_ui(obj
);
231 m_partcfg
->setWindowTitle(_LANG_STR("STR_MENU_PART_CFG"));
234 void Ventoy2DiskWindow::lang_check_action(QAction
*act
)
236 ventoy_code_set_cur_language(act
->text().toStdString().c_str());
237 update_ui_language();
240 void Ventoy2DiskWindow::LoadLanguages()
242 QString curlang
= ventoy_code_get_cur_language();
243 if (curlang
.isEmpty())
245 QString LANG
= qgetenv("LANG");
246 if (LANG
.startsWith("zh_CN"))
248 ventoy_code_set_cur_language("Chinese Simplified (ç®€ä½“ä¸æ–‡)");
252 ventoy_code_set_cur_language("English (English)");
254 curlang
= ventoy_code_get_cur_language();
258 QFile
inFile("./tool/languages.json");
259 inFile
.open(QIODevice::ReadOnly
|QIODevice::Text
);
260 QByteArray data
= inFile
.readAll();
263 QJsonParseError errorPtr
;
264 QJsonDocument doc
= QJsonDocument::fromJson(data
, &errorPtr
);
266 m_lang_array
= doc
.array();
267 QVector
<QString
> List
;
268 for (QJsonArray::iterator p
= m_lang_array
.begin(); p
!= m_lang_array
.end(); p
++)
270 List
.push_back(p
->toObject().value("name").toString());
273 connect(m_lang_group
, SIGNAL(triggered(QAction
*)), this, SLOT(lang_check_action(QAction
*)));
275 std::sort(List
.begin(), List
.end(), LangCompare
);
277 for (QVector
<QString
>::iterator p
= List
.begin(); p
!= List
.end(); p
++)
279 QAction
*action
= new QAction(*p
, m_lang_group
);
280 action
->setCheckable(true);
282 if (p
->compare(curlang
) == 0)
284 action
->setChecked(true);
285 m_lang_group
->triggered(action
);
288 ui
->menuLanguage
->addAction(action
);
294 void Ventoy2DiskWindow::part_style_check_action(QAction
*action
)
298 if (action
->text() == "MBR")
301 ui
->labelVentoyLocalPartStyle
->setText("MBR");
306 ui
->labelVentoyLocalPartStyle
->setText("GPT");
309 if (style
!= ventoy_code_get_cur_part_style())
311 ventoy_code_set_cur_part_style(style
);
315 static ventoy_disk
*select_active_dev(const QString
&select
, int *activeid
)
318 int alldev
= ventoy_code_get_cur_show_all();
319 ventoy_disk
*cur
= NULL
;
321 /* find the match one */
322 if (!select
.isEmpty())
324 for (i
= 0; i
< g_disk_num
; i
++)
326 cur
= g_disk_list
+ i
;
327 if (alldev
== 0 && cur
->type
!= VTOY_DEVICE_USB
)
332 if (select
.compare(cur
->disk_name
) == 0)
340 /* find the first one that installed with Ventoy */
341 for (i
= 0; i
< g_disk_num
; i
++)
343 cur
= g_disk_list
+ i
;
344 if (alldev
== 0 && cur
->type
!= VTOY_DEVICE_USB
)
349 if (cur
->vtoydata
.ventoy_valid
)
356 /* find the first USB interface device */
357 for (i
= 0; i
< g_disk_num
; i
++)
359 cur
= g_disk_list
+ i
;
360 if (alldev
== 0 && cur
->type
!= VTOY_DEVICE_USB
)
365 if (cur
->type
== VTOY_DEVICE_USB
)
372 /* use the first one */
373 for (i
= 0; i
< g_disk_num
; i
++)
375 cur
= g_disk_list
+ i
;
376 if (alldev
== 0 && cur
->type
!= VTOY_DEVICE_USB
)
389 void Ventoy2DiskWindow::FillDeviceList(const QString
&select
)
393 int alldev
= ventoy_code_get_cur_show_all();
396 ui
->comboBoxDevice
->clear();
398 for (int i
= 0; i
< g_disk_num
; i
++)
400 cur
= g_disk_list
+ i
;
402 if (alldev
== 0 && cur
->type
!= VTOY_DEVICE_USB
)
408 item
.sprintf("%s [%s] %s", cur
->disk_name
, cur
->human_readable_size
, cur
->disk_model
);
409 ui
->comboBoxDevice
->addItem(item
);
413 cur
= select_active_dev(select
, &active
);
416 vlog("combox count:%d, active:%s id:%d\n", count
, cur
->disk_name
, active
);
417 ui
->ButtonInstall
->setEnabled(true);
418 ui
->ButtonUpdate
->setEnabled(cur
->vtoydata
.ventoy_valid
);
419 ui
->comboBoxDevice
->setCurrentIndex(active
);
423 vlog("combox count:%d, no active id\n", count
);
424 ui
->ButtonInstall
->setEnabled(false);
425 ui
->ButtonUpdate
->setEnabled(false);
430 void Ventoy2DiskWindow::OnInitWindow(void)
439 ui
->labelVentoyLocalSecure
->hide();
441 m_part_group
->addAction(ui
->actionMBR
);
442 m_part_group
->addAction(ui
->actionGPT
);
443 connect(m_part_group
, SIGNAL(triggered(QAction
*)), this, SLOT(part_style_check_action(QAction
*)));
445 if (ventoy_code_get_cur_part_style())
447 ui
->actionGPT
->setChecked(true);
448 m_part_group
->triggered(ui
->actionGPT
);
452 ui
->actionMBR
->setChecked(true);
453 m_part_group
->triggered(ui
->actionMBR
);
456 snprintf(ver
, sizeof(ver
), VERSION_FMT
, ventoy_get_local_version());
457 ui
->labelVentoyLocalVer
->setText(QApplication::translate("Ventoy2DiskWindow", ver
, nullptr));
461 data
= (const uchar
*)get_refresh_icon_raw_data(&len
);
462 pix1
.loadFromData(data
, len
);
463 icon
.addPixmap(pix1
);
464 ui
->ButtonRefresh
->setIcon(icon
);
466 data
= (const uchar
*)get_secure_icon_raw_data(&len
);
467 pix2
.loadFromData(data
, len
);
468 ui
->labelVentoyLocalSecure
->setPixmap(pix2
);
469 ui
->labelVentoyDeviceSecure
->setPixmap(pix2
);
471 ui
->labelVentoyDeviceSecure
->setHidden(true);
472 ui
->labelVentoyDeviceVer
->setText("");
473 ui
->labelVentoyDevicePartStyle
->setText("");
475 ui
->actionShow_All_Devices
->setChecked(ventoy_code_get_cur_show_all());
477 connect(m_thread
, &MyQThread::thread_event
, this, &Ventoy2DiskWindow::thread_event
);
482 void Ventoy2DiskWindow::showEvent(QShowEvent
*ev
)
484 QMainWindow::showEvent(ev
);
488 void Ventoy2DiskWindow::on_ButtonInstall_clicked()
491 quint64 size
= 0, space
= 0;
493 QString title_warn
, title_err
, msg
;
495 lang_string("STR_ERROR", title_err
);
496 lang_string("STR_WARNING", title_warn
);
498 if (m_thread
->m_running
|| ventoy_code_is_busy())
500 lang_string("STR_WAIT_PROCESS", msg
);
501 QMessageBox::warning(NULL
, title_warn
, msg
);
505 index
= ui
->comboBoxDevice
->currentIndex();
506 if (index
< 0 || index
> g_disk_num
)
508 vlog("Invalid combobox current index %d\n", index
);
512 cur
= g_disk_list
+ index
;
513 if (ventoy_code_get_cur_part_style() == 0 && cur
->size_in_byte
> 2199023255552ULL)
515 lang_string("STR_DISK_2TB_MBR_ERROR", msg
);
516 QMessageBox::critical(NULL
, title_err
, msg
);
520 if (m_partcfg
->reserve
)
522 size
= cur
->size_in_byte
/ SIZE_1MB
;
523 space
= m_partcfg
->resvalue
;
524 if (m_partcfg
->unit
== 1)
526 space
= m_partcfg
->resvalue
* 1024;
529 if (size
<= space
|| (size
- space
) <= VTOYEFI_PART_BYTES
/ SIZE_1MB
)
531 lang_string("STR_SPACE_VAL_INVALID", msg
);
532 QMessageBox::critical(NULL
, title_err
, msg
);
533 vlog("reserved space too big.\n");
538 lang_string("STR_INSTALL_TIP", msg
);
539 if (QMessageBox::Yes
!= QMessageBox::warning(NULL
, title_warn
, msg
, QMessageBox::Yes
| QMessageBox::No
, QMessageBox::No
))
544 lang_string("STR_INSTALL_TIP2", msg
);
545 if (QMessageBox::Yes
!= QMessageBox::warning(NULL
, title_warn
, msg
, QMessageBox::Yes
| QMessageBox::No
, QMessageBox::No
))
550 ui
->ButtonRefresh
->setEnabled(false);
551 ui
->ButtonInstall
->setEnabled(false);
552 ui
->ButtonRefresh
->setEnabled(false);
554 m_thread
->m_type
= THREAD_TYPE_INSTALL
;
555 m_thread
->m_index
= index
;
556 m_thread
->m_reserve_space
= space
* SIZE_1MB
;
557 m_thread
->m_secureboot
= ui
->actionSecure_Boot_Support
->isChecked();
558 m_thread
->m_align4K
= m_partcfg
->align
;
559 m_thread
->m_running
= true;
564 void Ventoy2DiskWindow::on_ButtonUpdate_clicked()
568 QString title_info
, title_warn
, title_err
, msg
;
570 lang_string("STR_ERROR", title_err
);
571 lang_string("STR_WARNING", title_warn
);
572 lang_string("STR_INFO", title_info
);
574 if (m_thread
->m_running
|| ventoy_code_is_busy())
576 lang_string("STR_WAIT_PROCESS", msg
);
577 QMessageBox::warning(NULL
, title_warn
, msg
);
581 index
= ui
->comboBoxDevice
->currentIndex();
582 if (index
< 0 || index
> g_disk_num
)
584 vlog("Invalid combobox current index %d\n", index
);
588 cur
= g_disk_list
+ index
;
589 if (cur
->vtoydata
.ventoy_valid
== 0)
591 vlog("invalid ventoy version");
595 lang_string("STR_UPDATE_TIP", msg
);
596 if (QMessageBox::Yes
!= QMessageBox::information(NULL
, title_info
, msg
, QMessageBox::Yes
| QMessageBox::No
, QMessageBox::No
))
601 ui
->ButtonRefresh
->setEnabled(false);
602 ui
->ButtonInstall
->setEnabled(false);
603 ui
->ButtonRefresh
->setEnabled(false);
605 m_thread
->m_type
= THREAD_TYPE_UPDATE
;
606 m_thread
->m_index
= index
;
607 m_thread
->m_secureboot
= ui
->actionSecure_Boot_Support
->isChecked();
609 m_thread
->m_running
= true;
613 void Ventoy2DiskWindow::on_ButtonRefresh_clicked()
615 QString title_warn
, msg
;
617 if (m_thread
->m_running
|| ventoy_code_is_busy())
619 lang_string("STR_WARNING", title_warn
);
620 lang_string("STR_WAIT_PROCESS", msg
);
621 QMessageBox::warning(NULL
, title_warn
, msg
);
625 ventoy_code_refresh_device();
629 void Ventoy2DiskWindow::on_comboBoxDevice_currentIndexChanged(int index
)
634 ui
->labelVentoyDeviceSecure
->setHidden(true);
635 ui
->labelVentoyDeviceVer
->setText("");
636 ui
->labelVentoyDevicePartStyle
->setText("");
638 if (index
< 0 || index
> g_disk_num
)
640 vlog("invalid combobox index %d\n", index
);
644 cur
= g_disk_list
+ index
;
645 if (cur
->vtoydata
.ventoy_valid
)
647 if (cur
->vtoydata
.secure_boot_flag
)
649 ui
->labelVentoyDeviceSecure
->setHidden(false);
653 ui
->labelVentoyDeviceSecure
->setHidden(true);
656 if ((int)(ui
->actionSecure_Boot_Support
->isChecked()) != cur
->vtoydata
.secure_boot_flag
)
658 ui
->actionSecure_Boot_Support
->trigger();
661 snprintf(ver
, sizeof(ver
), VERSION_FMT
, cur
->vtoydata
.ventoy_ver
);
662 ui
->labelVentoyDeviceVer
->setText(QApplication::translate("Ventoy2DiskWindow", ver
, nullptr));
663 ui
->labelVentoyDevicePartStyle
->setText(cur
->vtoydata
.partition_style
? "GPT" : "MBR");
667 if (ui
->actionSecure_Boot_Support
->isChecked())
669 ui
->actionSecure_Boot_Support
->trigger();
674 void Ventoy2DiskWindow::on_actionPartition_Configuration_triggered()
676 m_partcfg
->update_ui_status();
677 if (QDialog::Accepted
== m_partcfg
->exec())
681 lang_string("STR_DEVICE", dev
);
683 if (m_partcfg
->reserve
)
685 str
.sprintf(" [ -%lld%s ]", (long long)m_partcfg
->resvalue
, m_partcfg
->unit
? "GB" : "MB");
686 ui
->groupBoxDevice
->setTitle(dev
+ str
);
690 ui
->groupBoxDevice
->setTitle(dev
);
695 void Ventoy2DiskWindow::on_actionClear_Ventoy_triggered()
700 QString title_err
, title_warn
, title_info
, msg
;
705 lang_string("STR_ERROR", title_err
);
706 lang_string("STR_WARNING", title_warn
);
707 lang_string("STR_INFO", title_info
);
709 if (m_thread
->m_running
|| ventoy_code_is_busy())
711 lang_string("STR_WAIT_PROCESS", msg
);
712 QMessageBox::warning(NULL
, title_warn
, msg
);
716 index
= ui
->comboBoxDevice
->currentIndex();
717 if (index
< 0 || index
> g_disk_num
)
719 vlog("Invalid combobox current index %d\n", index
);
723 cur
= g_disk_list
+ index
;
725 lang_string("STR_INSTALL_TIP", msg
);
726 if (QMessageBox::Yes
!= QMessageBox::warning(NULL
, title_warn
, msg
, QMessageBox::Yes
| QMessageBox::No
, QMessageBox::No
))
731 lang_string("STR_INSTALL_TIP2", msg
);
732 if (QMessageBox::Yes
!= QMessageBox::warning(NULL
, title_warn
, msg
, QMessageBox::Yes
| QMessageBox::No
, QMessageBox::No
))
737 snprintf(disk_name
, sizeof(disk_name
), "%s", cur
->disk_name
);
738 snprintf(buf
, sizeof(buf
), "{\"method\":\"clean\",\"disk\":\"%s\"}", disk_name
);
741 ventoy_func_handler(buf
, out
, sizeof(out
));
742 vlog("func handler clean <%s>\n", out
);
744 if (strstr(out
, "success"))
746 ret
= ventoy_code_get_result();
747 ventoy_code_refresh_device();
757 lang_string("STR_CLEAR_SUCCESS", msg
);
758 QMessageBox::information(NULL
, title_info
, msg
);
762 lang_string("STR_CLEAR_FAILED", msg
);
763 QMessageBox::critical(NULL
, title_err
, msg
);
766 FillDeviceList(disk_name
);
769 void Ventoy2DiskWindow::on_actionShow_All_Devices_toggled(bool arg1
)
771 ventoy_code_set_cur_show_all(arg1
);
776 void Ventoy2DiskWindow::closeEvent(QCloseEvent
*event
)
778 vlog("On closeEvent ...\n");
780 if (m_thread
->m_running
)
785 lang_string("STR_WARNING", title
);
786 lang_string("STR_WAIT_PROCESS", msg
);
787 QMessageBox::warning(NULL
, title
, msg
);
793 ventoy_code_save_cfg();
798 void Ventoy2DiskWindow::on_actionSecure_Boot_Support_triggered()
800 ui
->labelVentoyLocalSecure
->setHidden(!(ui
->actionSecure_Boot_Support
->isChecked()));
803 void Ventoy2DiskWindow::set_percent(int percent
)
806 QString status
, radio
;
808 ui
->progressBar
->setValue(percent
);
810 lang_string("STR_STATUS", status
);
814 ui
->groupBoxStatus
->setTitle(status
);
818 index
= status
.indexOf("-");
819 radio
.sprintf("%d%%", percent
);
820 ui
->groupBoxStatus
->setTitle(status
.left(index
+ 2) + radio
);
824 void Ventoy2DiskWindow::thread_event(int msg
, int data
)
827 QString title_err
, title_info
, tipmsg
;
829 if (msg
== THREAD_MSG_PROGRESS_BAR
)
833 else if (msg
== THREAD_MSG_INSTALL_FINISH
)
835 lang_string("STR_ERROR", title_err
);
836 lang_string("STR_INFO", title_info
);
840 lang_string("STR_INSTALL_SUCCESS", tipmsg
);
841 QMessageBox::information(NULL
, title_info
, tipmsg
);
845 lang_string("STR_INSTALL_FAILED", tipmsg
);
846 QMessageBox::critical(NULL
, title_err
, tipmsg
);
850 ui
->ButtonRefresh
->setEnabled(true);
851 ui
->ButtonInstall
->setEnabled(true);
852 ui
->ButtonRefresh
->setEnabled(true);
854 snprintf(disk_name
, sizeof(disk_name
), "%s", g_disk_list
[m_thread
->m_index
].disk_name
);
855 FillDeviceList(disk_name
);
857 else if (msg
== THREAD_MSG_UPDATE_FINISH
)
859 lang_string("STR_ERROR", title_err
);
860 lang_string("STR_INFO", title_info
);
864 lang_string("STR_UPDATE_SUCCESS", tipmsg
);
865 QMessageBox::information(NULL
, title_info
, tipmsg
);
869 lang_string("STR_UPDATE_FAILED", tipmsg
);
870 QMessageBox::critical(NULL
, title_err
, tipmsg
);
874 ui
->ButtonRefresh
->setEnabled(true);
875 ui
->ButtonInstall
->setEnabled(true);
876 ui
->ButtonRefresh
->setEnabled(true);
878 snprintf(disk_name
, sizeof(disk_name
), "%s", g_disk_list
[m_thread
->m_index
].disk_name
);
879 FillDeviceList(disk_name
);