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
;
518 lang_string("STR_4KN_UNSUPPORTED", msg
);
519 QMessageBox::critical(NULL
, title_err
, msg
);
523 if (ventoy_code_get_cur_part_style() == 0 && cur
->size_in_byte
> 2199023255552ULL)
525 lang_string("STR_DISK_2TB_MBR_ERROR", msg
);
526 QMessageBox::critical(NULL
, title_err
, msg
);
530 if (m_partcfg
->reserve
)
532 size
= cur
->size_in_byte
/ SIZE_1MB
;
533 space
= m_partcfg
->resvalue
;
534 if (m_partcfg
->unit
== 1)
536 space
= m_partcfg
->resvalue
* 1024;
539 if (size
<= space
|| (size
- space
) <= VTOYEFI_PART_BYTES
/ SIZE_1MB
)
541 lang_string("STR_SPACE_VAL_INVALID", msg
);
542 QMessageBox::critical(NULL
, title_err
, msg
);
543 vlog("reserved space too big.\n");
548 lang_string("STR_INSTALL_TIP", msg
);
549 if (QMessageBox::Yes
!= QMessageBox::warning(NULL
, title_warn
, msg
, QMessageBox::Yes
| QMessageBox::No
, QMessageBox::No
))
554 lang_string("STR_INSTALL_TIP2", msg
);
555 if (QMessageBox::Yes
!= QMessageBox::warning(NULL
, title_warn
, msg
, QMessageBox::Yes
| QMessageBox::No
, QMessageBox::No
))
560 ui
->ButtonRefresh
->setEnabled(false);
561 ui
->ButtonInstall
->setEnabled(false);
562 ui
->ButtonRefresh
->setEnabled(false);
564 m_thread
->m_type
= THREAD_TYPE_INSTALL
;
565 m_thread
->m_index
= index
;
566 m_thread
->m_reserve_space
= space
* SIZE_1MB
;
567 m_thread
->m_secureboot
= ui
->actionSecure_Boot_Support
->isChecked();
568 m_thread
->m_align4K
= m_partcfg
->align
;
569 m_thread
->m_running
= true;
574 void Ventoy2DiskWindow::on_ButtonUpdate_clicked()
578 QString title_info
, title_warn
, title_err
, msg
;
580 lang_string("STR_ERROR", title_err
);
581 lang_string("STR_WARNING", title_warn
);
582 lang_string("STR_INFO", title_info
);
584 if (m_thread
->m_running
|| ventoy_code_is_busy())
586 lang_string("STR_WAIT_PROCESS", msg
);
587 QMessageBox::warning(NULL
, title_warn
, msg
);
591 index
= ui
->comboBoxDevice
->currentIndex();
592 if (index
< 0 || index
> g_disk_num
)
594 vlog("Invalid combobox current index %d\n", index
);
598 cur
= g_disk_list
+ index
;
599 if (cur
->vtoydata
.ventoy_valid
== 0)
601 vlog("invalid ventoy version");
605 lang_string("STR_UPDATE_TIP", msg
);
606 if (QMessageBox::Yes
!= QMessageBox::information(NULL
, title_info
, msg
, QMessageBox::Yes
| QMessageBox::No
, QMessageBox::No
))
611 ui
->ButtonRefresh
->setEnabled(false);
612 ui
->ButtonInstall
->setEnabled(false);
613 ui
->ButtonRefresh
->setEnabled(false);
615 m_thread
->m_type
= THREAD_TYPE_UPDATE
;
616 m_thread
->m_index
= index
;
617 m_thread
->m_secureboot
= ui
->actionSecure_Boot_Support
->isChecked();
619 m_thread
->m_running
= true;
623 void Ventoy2DiskWindow::on_ButtonRefresh_clicked()
625 QString title_warn
, msg
;
627 if (m_thread
->m_running
|| ventoy_code_is_busy())
629 lang_string("STR_WARNING", title_warn
);
630 lang_string("STR_WAIT_PROCESS", msg
);
631 QMessageBox::warning(NULL
, title_warn
, msg
);
635 ventoy_code_refresh_device();
639 void Ventoy2DiskWindow::on_comboBoxDevice_currentIndexChanged(int index
)
644 ui
->labelVentoyDeviceSecure
->setHidden(true);
645 ui
->labelVentoyDeviceVer
->setText("");
646 ui
->labelVentoyDevicePartStyle
->setText("");
648 if (index
< 0 || index
> g_disk_num
)
650 vlog("invalid combobox index %d\n", index
);
654 cur
= g_disk_list
+ index
;
655 if (cur
->vtoydata
.ventoy_valid
)
657 if (cur
->vtoydata
.secure_boot_flag
)
659 ui
->labelVentoyDeviceSecure
->setHidden(false);
663 ui
->labelVentoyDeviceSecure
->setHidden(true);
666 if ((int)(ui
->actionSecure_Boot_Support
->isChecked()) != cur
->vtoydata
.secure_boot_flag
)
668 ui
->actionSecure_Boot_Support
->trigger();
671 snprintf(ver
, sizeof(ver
), VERSION_FMT
, cur
->vtoydata
.ventoy_ver
);
672 ui
->labelVentoyDeviceVer
->setText(QApplication::translate("Ventoy2DiskWindow", ver
, nullptr));
673 ui
->labelVentoyDevicePartStyle
->setText(cur
->vtoydata
.partition_style
? "GPT" : "MBR");
677 if (!(ui
->actionSecure_Boot_Support
->isChecked()))
679 ui
->actionSecure_Boot_Support
->trigger();
684 void Ventoy2DiskWindow::on_actionPartition_Configuration_triggered()
686 m_partcfg
->update_ui_status();
687 if (QDialog::Accepted
== m_partcfg
->exec())
691 lang_string("STR_DEVICE", dev
);
693 if (m_partcfg
->reserve
)
695 str
.sprintf(" [ -%lld%s ]", (long long)m_partcfg
->resvalue
, m_partcfg
->unit
? "GB" : "MB");
696 ui
->groupBoxDevice
->setTitle(dev
+ str
);
700 ui
->groupBoxDevice
->setTitle(dev
);
705 void Ventoy2DiskWindow::on_actionClear_Ventoy_triggered()
710 QString title_err
, title_warn
, title_info
, msg
;
715 lang_string("STR_ERROR", title_err
);
716 lang_string("STR_WARNING", title_warn
);
717 lang_string("STR_INFO", title_info
);
719 if (m_thread
->m_running
|| ventoy_code_is_busy())
721 lang_string("STR_WAIT_PROCESS", msg
);
722 QMessageBox::warning(NULL
, title_warn
, msg
);
726 index
= ui
->comboBoxDevice
->currentIndex();
727 if (index
< 0 || index
> g_disk_num
)
729 vlog("Invalid combobox current index %d\n", index
);
733 cur
= g_disk_list
+ index
;
735 lang_string("STR_INSTALL_TIP", msg
);
736 if (QMessageBox::Yes
!= QMessageBox::warning(NULL
, title_warn
, msg
, QMessageBox::Yes
| QMessageBox::No
, QMessageBox::No
))
741 lang_string("STR_INSTALL_TIP2", msg
);
742 if (QMessageBox::Yes
!= QMessageBox::warning(NULL
, title_warn
, msg
, QMessageBox::Yes
| QMessageBox::No
, QMessageBox::No
))
747 snprintf(disk_name
, sizeof(disk_name
), "%s", cur
->disk_name
);
748 snprintf(buf
, sizeof(buf
), "{\"method\":\"clean\",\"disk\":\"%s\"}", disk_name
);
751 ventoy_func_handler(buf
, out
, sizeof(out
));
752 vlog("func handler clean <%s>\n", out
);
754 if (strstr(out
, "success"))
756 ret
= ventoy_code_get_result();
757 ventoy_code_refresh_device();
767 lang_string("STR_CLEAR_SUCCESS", msg
);
768 QMessageBox::information(NULL
, title_info
, msg
);
772 lang_string("STR_CLEAR_FAILED", msg
);
773 QMessageBox::critical(NULL
, title_err
, msg
);
776 FillDeviceList(disk_name
);
779 void Ventoy2DiskWindow::on_actionShow_All_Devices_toggled(bool arg1
)
781 ventoy_code_set_cur_show_all(arg1
);
786 void Ventoy2DiskWindow::closeEvent(QCloseEvent
*event
)
788 vlog("On closeEvent ...\n");
790 if (m_thread
->m_running
)
795 lang_string("STR_WARNING", title
);
796 lang_string("STR_WAIT_PROCESS", msg
);
797 QMessageBox::warning(NULL
, title
, msg
);
803 ventoy_code_save_cfg();
808 void Ventoy2DiskWindow::on_actionSecure_Boot_Support_triggered()
810 ui
->labelVentoyLocalSecure
->setHidden(!(ui
->actionSecure_Boot_Support
->isChecked()));
813 void Ventoy2DiskWindow::set_percent(int percent
)
816 QString status
, radio
;
818 ui
->progressBar
->setValue(percent
);
820 lang_string("STR_STATUS", status
);
824 ui
->groupBoxStatus
->setTitle(status
);
828 index
= status
.indexOf("-");
829 radio
.sprintf("%d%%", percent
);
830 ui
->groupBoxStatus
->setTitle(status
.left(index
+ 2) + radio
);
834 void Ventoy2DiskWindow::thread_event(int msg
, int data
)
837 QString title_err
, title_info
, tipmsg
;
839 if (msg
== THREAD_MSG_PROGRESS_BAR
)
843 else if (msg
== THREAD_MSG_INSTALL_FINISH
)
845 lang_string("STR_ERROR", title_err
);
846 lang_string("STR_INFO", title_info
);
850 lang_string("STR_INSTALL_SUCCESS", tipmsg
);
851 QMessageBox::information(NULL
, title_info
, tipmsg
);
855 lang_string("STR_INSTALL_FAILED", tipmsg
);
856 QMessageBox::critical(NULL
, title_err
, tipmsg
);
860 ui
->ButtonRefresh
->setEnabled(true);
861 ui
->ButtonInstall
->setEnabled(true);
862 ui
->ButtonRefresh
->setEnabled(true);
864 snprintf(disk_name
, sizeof(disk_name
), "%s", g_disk_list
[m_thread
->m_index
].disk_name
);
865 FillDeviceList(disk_name
);
867 else if (msg
== THREAD_MSG_UPDATE_FINISH
)
869 lang_string("STR_ERROR", title_err
);
870 lang_string("STR_INFO", title_info
);
874 lang_string("STR_UPDATE_SUCCESS", tipmsg
);
875 QMessageBox::information(NULL
, title_info
, tipmsg
);
879 lang_string("STR_UPDATE_FAILED", tipmsg
);
880 QMessageBox::critical(NULL
, title_err
, tipmsg
);
884 ui
->ButtonRefresh
->setEnabled(true);
885 ui
->ButtonInstall
->setEnabled(true);
886 ui
->ButtonRefresh
->setEnabled(true);
888 snprintf(disk_name
, sizeof(disk_name
), "%s", g_disk_list
[m_thread
->m_index
].disk_name
);
889 FillDeviceList(disk_name
);