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
->actionSecure_Boot_Support
->trigger();
477 ui
->actionShow_All_Devices
->setChecked(ventoy_code_get_cur_show_all());
479 connect(m_thread
, &MyQThread::thread_event
, this, &Ventoy2DiskWindow::thread_event
);
484 void Ventoy2DiskWindow::showEvent(QShowEvent
*ev
)
486 QMainWindow::showEvent(ev
);
490 void Ventoy2DiskWindow::on_ButtonInstall_clicked()
493 quint64 size
= 0, space
= 0;
495 QString title_warn
, title_err
, msg
;
497 lang_string("STR_ERROR", title_err
);
498 lang_string("STR_WARNING", title_warn
);
500 if (m_thread
->m_running
|| ventoy_code_is_busy())
502 lang_string("STR_WAIT_PROCESS", msg
);
503 QMessageBox::warning(NULL
, title_warn
, msg
);
507 index
= ui
->comboBoxDevice
->currentIndex();
508 if (index
< 0 || index
> g_disk_num
)
510 vlog("Invalid combobox current index %d\n", index
);
514 cur
= g_disk_list
+ index
;
515 if (ventoy_code_get_cur_part_style() == 0 && cur
->size_in_byte
> 2199023255552ULL)
517 lang_string("STR_DISK_2TB_MBR_ERROR", msg
);
518 QMessageBox::critical(NULL
, title_err
, msg
);
522 if (m_partcfg
->reserve
)
524 size
= cur
->size_in_byte
/ SIZE_1MB
;
525 space
= m_partcfg
->resvalue
;
526 if (m_partcfg
->unit
== 1)
528 space
= m_partcfg
->resvalue
* 1024;
531 if (size
<= space
|| (size
- space
) <= VTOYEFI_PART_BYTES
/ SIZE_1MB
)
533 lang_string("STR_SPACE_VAL_INVALID", msg
);
534 QMessageBox::critical(NULL
, title_err
, msg
);
535 vlog("reserved space too big.\n");
540 lang_string("STR_INSTALL_TIP", msg
);
541 if (QMessageBox::Yes
!= QMessageBox::warning(NULL
, title_warn
, msg
, QMessageBox::Yes
| QMessageBox::No
, QMessageBox::No
))
546 lang_string("STR_INSTALL_TIP2", msg
);
547 if (QMessageBox::Yes
!= QMessageBox::warning(NULL
, title_warn
, msg
, QMessageBox::Yes
| QMessageBox::No
, QMessageBox::No
))
552 ui
->ButtonRefresh
->setEnabled(false);
553 ui
->ButtonInstall
->setEnabled(false);
554 ui
->ButtonRefresh
->setEnabled(false);
556 m_thread
->m_type
= THREAD_TYPE_INSTALL
;
557 m_thread
->m_index
= index
;
558 m_thread
->m_reserve_space
= space
* SIZE_1MB
;
559 m_thread
->m_secureboot
= ui
->actionSecure_Boot_Support
->isChecked();
560 m_thread
->m_align4K
= m_partcfg
->align
;
561 m_thread
->m_running
= true;
566 void Ventoy2DiskWindow::on_ButtonUpdate_clicked()
570 QString title_info
, title_warn
, title_err
, msg
;
572 lang_string("STR_ERROR", title_err
);
573 lang_string("STR_WARNING", title_warn
);
574 lang_string("STR_INFO", title_info
);
576 if (m_thread
->m_running
|| ventoy_code_is_busy())
578 lang_string("STR_WAIT_PROCESS", msg
);
579 QMessageBox::warning(NULL
, title_warn
, msg
);
583 index
= ui
->comboBoxDevice
->currentIndex();
584 if (index
< 0 || index
> g_disk_num
)
586 vlog("Invalid combobox current index %d\n", index
);
590 cur
= g_disk_list
+ index
;
591 if (cur
->vtoydata
.ventoy_valid
== 0)
593 vlog("invalid ventoy version");
597 lang_string("STR_UPDATE_TIP", msg
);
598 if (QMessageBox::Yes
!= QMessageBox::information(NULL
, title_info
, msg
, QMessageBox::Yes
| QMessageBox::No
, QMessageBox::No
))
603 ui
->ButtonRefresh
->setEnabled(false);
604 ui
->ButtonInstall
->setEnabled(false);
605 ui
->ButtonRefresh
->setEnabled(false);
607 m_thread
->m_type
= THREAD_TYPE_UPDATE
;
608 m_thread
->m_index
= index
;
609 m_thread
->m_secureboot
= ui
->actionSecure_Boot_Support
->isChecked();
611 m_thread
->m_running
= true;
615 void Ventoy2DiskWindow::on_ButtonRefresh_clicked()
617 QString title_warn
, msg
;
619 if (m_thread
->m_running
|| ventoy_code_is_busy())
621 lang_string("STR_WARNING", title_warn
);
622 lang_string("STR_WAIT_PROCESS", msg
);
623 QMessageBox::warning(NULL
, title_warn
, msg
);
627 ventoy_code_refresh_device();
631 void Ventoy2DiskWindow::on_comboBoxDevice_currentIndexChanged(int index
)
636 ui
->labelVentoyDeviceSecure
->setHidden(true);
637 ui
->labelVentoyDeviceVer
->setText("");
638 ui
->labelVentoyDevicePartStyle
->setText("");
640 if (index
< 0 || index
> g_disk_num
)
642 vlog("invalid combobox index %d\n", index
);
646 cur
= g_disk_list
+ index
;
647 if (cur
->vtoydata
.ventoy_valid
)
649 if (cur
->vtoydata
.secure_boot_flag
)
651 ui
->labelVentoyDeviceSecure
->setHidden(false);
655 ui
->labelVentoyDeviceSecure
->setHidden(true);
658 if ((int)(ui
->actionSecure_Boot_Support
->isChecked()) != cur
->vtoydata
.secure_boot_flag
)
660 ui
->actionSecure_Boot_Support
->trigger();
663 snprintf(ver
, sizeof(ver
), VERSION_FMT
, cur
->vtoydata
.ventoy_ver
);
664 ui
->labelVentoyDeviceVer
->setText(QApplication::translate("Ventoy2DiskWindow", ver
, nullptr));
665 ui
->labelVentoyDevicePartStyle
->setText(cur
->vtoydata
.partition_style
? "GPT" : "MBR");
669 if (!(ui
->actionSecure_Boot_Support
->isChecked()))
671 ui
->actionSecure_Boot_Support
->trigger();
676 void Ventoy2DiskWindow::on_actionPartition_Configuration_triggered()
678 m_partcfg
->update_ui_status();
679 if (QDialog::Accepted
== m_partcfg
->exec())
683 lang_string("STR_DEVICE", dev
);
685 if (m_partcfg
->reserve
)
687 str
.sprintf(" [ -%lld%s ]", (long long)m_partcfg
->resvalue
, m_partcfg
->unit
? "GB" : "MB");
688 ui
->groupBoxDevice
->setTitle(dev
+ str
);
692 ui
->groupBoxDevice
->setTitle(dev
);
697 void Ventoy2DiskWindow::on_actionClear_Ventoy_triggered()
702 QString title_err
, title_warn
, title_info
, msg
;
707 lang_string("STR_ERROR", title_err
);
708 lang_string("STR_WARNING", title_warn
);
709 lang_string("STR_INFO", title_info
);
711 if (m_thread
->m_running
|| ventoy_code_is_busy())
713 lang_string("STR_WAIT_PROCESS", msg
);
714 QMessageBox::warning(NULL
, title_warn
, msg
);
718 index
= ui
->comboBoxDevice
->currentIndex();
719 if (index
< 0 || index
> g_disk_num
)
721 vlog("Invalid combobox current index %d\n", index
);
725 cur
= g_disk_list
+ index
;
727 lang_string("STR_INSTALL_TIP", msg
);
728 if (QMessageBox::Yes
!= QMessageBox::warning(NULL
, title_warn
, msg
, QMessageBox::Yes
| QMessageBox::No
, QMessageBox::No
))
733 lang_string("STR_INSTALL_TIP2", msg
);
734 if (QMessageBox::Yes
!= QMessageBox::warning(NULL
, title_warn
, msg
, QMessageBox::Yes
| QMessageBox::No
, QMessageBox::No
))
739 snprintf(disk_name
, sizeof(disk_name
), "%s", cur
->disk_name
);
740 snprintf(buf
, sizeof(buf
), "{\"method\":\"clean\",\"disk\":\"%s\"}", disk_name
);
743 ventoy_func_handler(buf
, out
, sizeof(out
));
744 vlog("func handler clean <%s>\n", out
);
746 if (strstr(out
, "success"))
748 ret
= ventoy_code_get_result();
749 ventoy_code_refresh_device();
759 lang_string("STR_CLEAR_SUCCESS", msg
);
760 QMessageBox::information(NULL
, title_info
, msg
);
764 lang_string("STR_CLEAR_FAILED", msg
);
765 QMessageBox::critical(NULL
, title_err
, msg
);
768 FillDeviceList(disk_name
);
771 void Ventoy2DiskWindow::on_actionShow_All_Devices_toggled(bool arg1
)
773 ventoy_code_set_cur_show_all(arg1
);
778 void Ventoy2DiskWindow::closeEvent(QCloseEvent
*event
)
780 vlog("On closeEvent ...\n");
782 if (m_thread
->m_running
)
787 lang_string("STR_WARNING", title
);
788 lang_string("STR_WAIT_PROCESS", msg
);
789 QMessageBox::warning(NULL
, title
, msg
);
795 ventoy_code_save_cfg();
800 void Ventoy2DiskWindow::on_actionSecure_Boot_Support_triggered()
802 ui
->labelVentoyLocalSecure
->setHidden(!(ui
->actionSecure_Boot_Support
->isChecked()));
805 void Ventoy2DiskWindow::set_percent(int percent
)
808 QString status
, radio
;
810 ui
->progressBar
->setValue(percent
);
812 lang_string("STR_STATUS", status
);
816 ui
->groupBoxStatus
->setTitle(status
);
820 index
= status
.indexOf("-");
821 radio
.sprintf("%d%%", percent
);
822 ui
->groupBoxStatus
->setTitle(status
.left(index
+ 2) + radio
);
826 void Ventoy2DiskWindow::thread_event(int msg
, int data
)
829 QString title_err
, title_info
, tipmsg
;
831 if (msg
== THREAD_MSG_PROGRESS_BAR
)
835 else if (msg
== THREAD_MSG_INSTALL_FINISH
)
837 lang_string("STR_ERROR", title_err
);
838 lang_string("STR_INFO", title_info
);
842 lang_string("STR_INSTALL_SUCCESS", tipmsg
);
843 QMessageBox::information(NULL
, title_info
, tipmsg
);
847 lang_string("STR_INSTALL_FAILED", tipmsg
);
848 QMessageBox::critical(NULL
, title_err
, tipmsg
);
852 ui
->ButtonRefresh
->setEnabled(true);
853 ui
->ButtonInstall
->setEnabled(true);
854 ui
->ButtonRefresh
->setEnabled(true);
856 snprintf(disk_name
, sizeof(disk_name
), "%s", g_disk_list
[m_thread
->m_index
].disk_name
);
857 FillDeviceList(disk_name
);
859 else if (msg
== THREAD_MSG_UPDATE_FINISH
)
861 lang_string("STR_ERROR", title_err
);
862 lang_string("STR_INFO", title_info
);
866 lang_string("STR_UPDATE_SUCCESS", tipmsg
);
867 QMessageBox::information(NULL
, title_info
, tipmsg
);
871 lang_string("STR_UPDATE_FAILED", tipmsg
);
872 QMessageBox::critical(NULL
, title_err
, tipmsg
);
876 ui
->ButtonRefresh
->setEnabled(true);
877 ui
->ButtonInstall
->setEnabled(true);
878 ui
->ButtonRefresh
->setEnabled(true);
880 snprintf(disk_name
, sizeof(disk_name
), "%s", g_disk_list
[m_thread
->m_index
].disk_name
);
881 FillDeviceList(disk_name
);