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();
440 ui
->actionSecure_Boot_Support
->trigger();
442 m_part_group
->addAction(ui
->actionMBR
);
443 m_part_group
->addAction(ui
->actionGPT
);
444 connect(m_part_group
, SIGNAL(triggered(QAction
*)), this, SLOT(part_style_check_action(QAction
*)));
446 if (ventoy_code_get_cur_part_style())
448 ui
->actionGPT
->setChecked(true);
449 m_part_group
->triggered(ui
->actionGPT
);
453 ui
->actionMBR
->setChecked(true);
454 m_part_group
->triggered(ui
->actionMBR
);
457 snprintf(ver
, sizeof(ver
), VERSION_FMT
, ventoy_get_local_version());
458 ui
->labelVentoyLocalVer
->setText(QApplication::translate("Ventoy2DiskWindow", ver
, nullptr));
462 data
= (const uchar
*)get_refresh_icon_raw_data(&len
);
463 pix1
.loadFromData(data
, len
);
464 icon
.addPixmap(pix1
);
465 ui
->ButtonRefresh
->setIcon(icon
);
467 data
= (const uchar
*)get_secure_icon_raw_data(&len
);
468 pix2
.loadFromData(data
, len
);
469 ui
->labelVentoyLocalSecure
->setPixmap(pix2
);
470 ui
->labelVentoyDeviceSecure
->setPixmap(pix2
);
472 ui
->labelVentoyDeviceSecure
->setHidden(true);
473 ui
->labelVentoyDeviceVer
->setText("");
474 ui
->labelVentoyDevicePartStyle
->setText("");
476 ui
->actionShow_All_Devices
->setChecked(ventoy_code_get_cur_show_all());
478 connect(m_thread
, &MyQThread::thread_event
, this, &Ventoy2DiskWindow::thread_event
);
483 void Ventoy2DiskWindow::showEvent(QShowEvent
*ev
)
485 QMainWindow::showEvent(ev
);
489 void Ventoy2DiskWindow::on_ButtonInstall_clicked()
492 quint64 size
= 0, space
= 0;
494 QString title_warn
, title_err
, msg
;
496 lang_string("STR_ERROR", title_err
);
497 lang_string("STR_WARNING", title_warn
);
499 if (m_thread
->m_running
|| ventoy_code_is_busy())
501 lang_string("STR_WAIT_PROCESS", msg
);
502 QMessageBox::warning(NULL
, title_warn
, msg
);
506 index
= ui
->comboBoxDevice
->currentIndex();
507 if (index
< 0 || index
> g_disk_num
)
509 vlog("Invalid combobox current index %d\n", index
);
513 cur
= g_disk_list
+ index
;
514 if (ventoy_code_get_cur_part_style() == 0 && cur
->size_in_byte
> 2199023255552ULL)
516 lang_string("STR_DISK_2TB_MBR_ERROR", msg
);
517 QMessageBox::critical(NULL
, title_err
, msg
);
521 if (m_partcfg
->reserve
)
523 size
= cur
->size_in_byte
/ SIZE_1MB
;
524 space
= m_partcfg
->resvalue
;
525 if (m_partcfg
->unit
== 1)
527 space
= m_partcfg
->resvalue
* 1024;
530 if (size
<= space
|| (size
- space
) <= VTOYEFI_PART_BYTES
/ SIZE_1MB
)
532 lang_string("STR_SPACE_VAL_INVALID", msg
);
533 QMessageBox::critical(NULL
, title_err
, msg
);
534 vlog("reserved space too big.\n");
539 lang_string("STR_INSTALL_TIP", msg
);
540 if (QMessageBox::Yes
!= QMessageBox::warning(NULL
, title_warn
, msg
, QMessageBox::Yes
| QMessageBox::No
, QMessageBox::No
))
545 lang_string("STR_INSTALL_TIP2", msg
);
546 if (QMessageBox::Yes
!= QMessageBox::warning(NULL
, title_warn
, msg
, QMessageBox::Yes
| QMessageBox::No
, QMessageBox::No
))
551 ui
->ButtonRefresh
->setEnabled(false);
552 ui
->ButtonInstall
->setEnabled(false);
553 ui
->ButtonRefresh
->setEnabled(false);
555 m_thread
->m_type
= THREAD_TYPE_INSTALL
;
556 m_thread
->m_index
= index
;
557 m_thread
->m_reserve_space
= space
* SIZE_1MB
;
558 m_thread
->m_secureboot
= ui
->actionSecure_Boot_Support
->isChecked();
559 m_thread
->m_align4K
= m_partcfg
->align
;
560 m_thread
->m_running
= true;
565 void Ventoy2DiskWindow::on_ButtonUpdate_clicked()
569 QString title_info
, title_warn
, title_err
, msg
;
571 lang_string("STR_ERROR", title_err
);
572 lang_string("STR_WARNING", title_warn
);
573 lang_string("STR_INFO", title_info
);
575 if (m_thread
->m_running
|| ventoy_code_is_busy())
577 lang_string("STR_WAIT_PROCESS", msg
);
578 QMessageBox::warning(NULL
, title_warn
, msg
);
582 index
= ui
->comboBoxDevice
->currentIndex();
583 if (index
< 0 || index
> g_disk_num
)
585 vlog("Invalid combobox current index %d\n", index
);
589 cur
= g_disk_list
+ index
;
590 if (cur
->vtoydata
.ventoy_valid
== 0)
592 vlog("invalid ventoy version");
596 lang_string("STR_UPDATE_TIP", msg
);
597 if (QMessageBox::Yes
!= QMessageBox::information(NULL
, title_info
, msg
, QMessageBox::Yes
| QMessageBox::No
, QMessageBox::No
))
602 ui
->ButtonRefresh
->setEnabled(false);
603 ui
->ButtonInstall
->setEnabled(false);
604 ui
->ButtonRefresh
->setEnabled(false);
606 m_thread
->m_type
= THREAD_TYPE_UPDATE
;
607 m_thread
->m_index
= index
;
608 m_thread
->m_secureboot
= ui
->actionSecure_Boot_Support
->isChecked();
610 m_thread
->m_running
= true;
614 void Ventoy2DiskWindow::on_ButtonRefresh_clicked()
616 QString title_warn
, msg
;
618 if (m_thread
->m_running
|| ventoy_code_is_busy())
620 lang_string("STR_WARNING", title_warn
);
621 lang_string("STR_WAIT_PROCESS", msg
);
622 QMessageBox::warning(NULL
, title_warn
, msg
);
626 ventoy_code_refresh_device();
630 void Ventoy2DiskWindow::on_comboBoxDevice_currentIndexChanged(int index
)
635 ui
->labelVentoyDeviceSecure
->setHidden(true);
636 ui
->labelVentoyDeviceVer
->setText("");
637 ui
->labelVentoyDevicePartStyle
->setText("");
639 if (index
< 0 || index
> g_disk_num
)
641 vlog("invalid combobox index %d\n", index
);
645 cur
= g_disk_list
+ index
;
646 if (cur
->vtoydata
.ventoy_valid
)
648 if (cur
->vtoydata
.secure_boot_flag
)
650 ui
->labelVentoyDeviceSecure
->setHidden(false);
654 ui
->labelVentoyDeviceSecure
->setHidden(true);
657 if ((int)(ui
->actionSecure_Boot_Support
->isChecked()) != cur
->vtoydata
.secure_boot_flag
)
659 ui
->actionSecure_Boot_Support
->trigger();
662 snprintf(ver
, sizeof(ver
), VERSION_FMT
, cur
->vtoydata
.ventoy_ver
);
663 ui
->labelVentoyDeviceVer
->setText(QApplication::translate("Ventoy2DiskWindow", ver
, nullptr));
664 ui
->labelVentoyDevicePartStyle
->setText(cur
->vtoydata
.partition_style
? "GPT" : "MBR");
668 if (ui
->actionSecure_Boot_Support
->isChecked())
670 ui
->actionSecure_Boot_Support
->trigger();
675 void Ventoy2DiskWindow::on_actionPartition_Configuration_triggered()
677 m_partcfg
->update_ui_status();
678 if (QDialog::Accepted
== m_partcfg
->exec())
682 lang_string("STR_DEVICE", dev
);
684 if (m_partcfg
->reserve
)
686 str
.sprintf(" [ -%lld%s ]", (long long)m_partcfg
->resvalue
, m_partcfg
->unit
? "GB" : "MB");
687 ui
->groupBoxDevice
->setTitle(dev
+ str
);
691 ui
->groupBoxDevice
->setTitle(dev
);
696 void Ventoy2DiskWindow::on_actionClear_Ventoy_triggered()
701 QString title_err
, title_warn
, title_info
, msg
;
706 lang_string("STR_ERROR", title_err
);
707 lang_string("STR_WARNING", title_warn
);
708 lang_string("STR_INFO", title_info
);
710 if (m_thread
->m_running
|| ventoy_code_is_busy())
712 lang_string("STR_WAIT_PROCESS", msg
);
713 QMessageBox::warning(NULL
, title_warn
, msg
);
717 index
= ui
->comboBoxDevice
->currentIndex();
718 if (index
< 0 || index
> g_disk_num
)
720 vlog("Invalid combobox current index %d\n", index
);
724 cur
= g_disk_list
+ index
;
726 lang_string("STR_INSTALL_TIP", msg
);
727 if (QMessageBox::Yes
!= QMessageBox::warning(NULL
, title_warn
, msg
, QMessageBox::Yes
| QMessageBox::No
, QMessageBox::No
))
732 lang_string("STR_INSTALL_TIP2", msg
);
733 if (QMessageBox::Yes
!= QMessageBox::warning(NULL
, title_warn
, msg
, QMessageBox::Yes
| QMessageBox::No
, QMessageBox::No
))
738 snprintf(disk_name
, sizeof(disk_name
), "%s", cur
->disk_name
);
739 snprintf(buf
, sizeof(buf
), "{\"method\":\"clean\",\"disk\":\"%s\"}", disk_name
);
742 ventoy_func_handler(buf
, out
, sizeof(out
));
743 vlog("func handler clean <%s>\n", out
);
745 if (strstr(out
, "success"))
747 ret
= ventoy_code_get_result();
748 ventoy_code_refresh_device();
758 lang_string("STR_CLEAR_SUCCESS", msg
);
759 QMessageBox::information(NULL
, title_info
, msg
);
763 lang_string("STR_CLEAR_FAILED", msg
);
764 QMessageBox::critical(NULL
, title_err
, msg
);
767 FillDeviceList(disk_name
);
770 void Ventoy2DiskWindow::on_actionShow_All_Devices_toggled(bool arg1
)
772 ventoy_code_set_cur_show_all(arg1
);
777 void Ventoy2DiskWindow::closeEvent(QCloseEvent
*event
)
779 vlog("On closeEvent ...\n");
781 if (m_thread
->m_running
)
786 lang_string("STR_WARNING", title
);
787 lang_string("STR_WAIT_PROCESS", msg
);
788 QMessageBox::warning(NULL
, title
, msg
);
794 ventoy_code_save_cfg();
799 void Ventoy2DiskWindow::on_actionSecure_Boot_Support_triggered()
801 ui
->labelVentoyLocalSecure
->setHidden(!(ui
->actionSecure_Boot_Support
->isChecked()));
804 void Ventoy2DiskWindow::set_percent(int percent
)
807 QString status
, radio
;
809 ui
->progressBar
->setValue(percent
);
811 lang_string("STR_STATUS", status
);
815 ui
->groupBoxStatus
->setTitle(status
);
819 index
= status
.indexOf("-");
820 radio
.sprintf("%d%%", percent
);
821 ui
->groupBoxStatus
->setTitle(status
.left(index
+ 2) + radio
);
825 void Ventoy2DiskWindow::thread_event(int msg
, int data
)
828 QString title_err
, title_info
, tipmsg
;
830 if (msg
== THREAD_MSG_PROGRESS_BAR
)
834 else if (msg
== THREAD_MSG_INSTALL_FINISH
)
836 lang_string("STR_ERROR", title_err
);
837 lang_string("STR_INFO", title_info
);
841 lang_string("STR_INSTALL_SUCCESS", tipmsg
);
842 QMessageBox::information(NULL
, title_info
, tipmsg
);
846 lang_string("STR_INSTALL_FAILED", tipmsg
);
847 QMessageBox::critical(NULL
, title_err
, tipmsg
);
851 ui
->ButtonRefresh
->setEnabled(true);
852 ui
->ButtonInstall
->setEnabled(true);
853 ui
->ButtonRefresh
->setEnabled(true);
855 snprintf(disk_name
, sizeof(disk_name
), "%s", g_disk_list
[m_thread
->m_index
].disk_name
);
856 FillDeviceList(disk_name
);
858 else if (msg
== THREAD_MSG_UPDATE_FINISH
)
860 lang_string("STR_ERROR", title_err
);
861 lang_string("STR_INFO", title_info
);
865 lang_string("STR_UPDATE_SUCCESS", tipmsg
);
866 QMessageBox::information(NULL
, title_info
, tipmsg
);
870 lang_string("STR_UPDATE_FAILED", tipmsg
);
871 QMessageBox::critical(NULL
, title_err
, tipmsg
);
875 ui
->ButtonRefresh
->setEnabled(true);
876 ui
->ButtonInstall
->setEnabled(true);
877 ui
->ButtonRefresh
->setEnabled(true);
879 snprintf(disk_name
, sizeof(disk_name
), "%s", g_disk_list
[m_thread
->m_index
].disk_name
);
880 FillDeviceList(disk_name
);