code dump - mostly done implementing media menus
This commit is contained in:
@@ -18,7 +18,8 @@ add_library(ui STATIC
|
||||
qt_mainwindow.ui
|
||||
qt_machinestatus.cpp
|
||||
qt_machinestatus.hpp
|
||||
#qt_machinestatus.ui
|
||||
qt_mediamenu.cpp
|
||||
qt_mediamenu.hpp
|
||||
qt_gleswidget.cpp
|
||||
qt_gleswidget.hpp
|
||||
|
||||
@@ -67,6 +68,9 @@ add_library(ui STATIC
|
||||
qt_filefield.cpp
|
||||
qt_filefield.hpp
|
||||
qt_filefield.ui
|
||||
qt_newfloppydialog.cpp
|
||||
qt_newfloppydialog.hpp
|
||||
qt_newfloppydialog.ui
|
||||
qt_harddiskdialog.cpp
|
||||
qt_harddiskdialog.hpp
|
||||
qt_harddiskdialog.ui
|
||||
|
||||
@@ -39,83 +39,6 @@
|
||||
#include <86box/plat.h>
|
||||
#include <86box/ui.h>
|
||||
|
||||
|
||||
|
||||
void
|
||||
cassette_mount(char *fn, uint8_t wp)
|
||||
{
|
||||
pc_cas_set_fname(cassette, NULL);
|
||||
memset(cassette_fname, 0, sizeof(cassette_fname));
|
||||
cassette_ui_writeprot = wp;
|
||||
pc_cas_set_fname(cassette, fn);
|
||||
if (fn != NULL)
|
||||
memcpy(cassette_fname, fn, MIN(511, strlen(fn)));
|
||||
ui_sb_update_icon_state(SB_CASSETTE, (fn == NULL) ? 1 : 0);
|
||||
//media_menu_update_cassette();
|
||||
ui_sb_update_tip(SB_CASSETTE);
|
||||
config_save();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
cassette_eject(void)
|
||||
{
|
||||
pc_cas_set_fname(cassette, NULL);
|
||||
memset(cassette_fname, 0x00, sizeof(cassette_fname));
|
||||
ui_sb_update_icon_state(SB_CASSETTE, 1);
|
||||
//media_menu_update_cassette();
|
||||
ui_sb_update_tip(SB_CASSETTE);
|
||||
config_save();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
cartridge_mount(uint8_t id, char *fn, uint8_t wp)
|
||||
{
|
||||
cart_close(id);
|
||||
cart_load(id, fn);
|
||||
ui_sb_update_icon_state(SB_CARTRIDGE | id, strlen(cart_fns[id]) ? 0 : 1);
|
||||
//media_menu_update_cartridge(id);
|
||||
ui_sb_update_tip(SB_CARTRIDGE | id);
|
||||
config_save();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
cartridge_eject(uint8_t id)
|
||||
{
|
||||
cart_close(id);
|
||||
ui_sb_update_icon_state(SB_CARTRIDGE | id, 1);
|
||||
//media_menu_update_cartridge(id);
|
||||
ui_sb_update_tip(SB_CARTRIDGE | id);
|
||||
config_save();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
floppy_mount(uint8_t id, char *fn, uint8_t wp)
|
||||
{
|
||||
fdd_close(id);
|
||||
ui_writeprot[id] = wp;
|
||||
fdd_load(id, fn);
|
||||
ui_sb_update_icon_state(SB_FLOPPY | id, strlen(floppyfns[id]) ? 0 : 1);
|
||||
//media_menu_update_floppy(id);
|
||||
ui_sb_update_tip(SB_FLOPPY | id);
|
||||
config_save();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
floppy_eject(uint8_t id)
|
||||
{
|
||||
fdd_close(id);
|
||||
ui_sb_update_icon_state(SB_FLOPPY | id, 1);
|
||||
//media_menu_update_floppy(id);
|
||||
ui_sb_update_tip(SB_FLOPPY | id);
|
||||
config_save();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
plat_cdrom_ui_update(uint8_t id, uint8_t reload)
|
||||
{
|
||||
@@ -130,135 +53,3 @@ plat_cdrom_ui_update(uint8_t id, uint8_t reload)
|
||||
//media_menu_update_cdrom(id);
|
||||
ui_sb_update_tip(SB_CDROM|id);
|
||||
}
|
||||
|
||||
void
|
||||
cdrom_mount(uint8_t id, char *fn)
|
||||
{
|
||||
cdrom[id].prev_host_drive = cdrom[id].host_drive;
|
||||
strcpy(cdrom[id].prev_image_path, cdrom[id].image_path);
|
||||
if (cdrom[id].ops && cdrom[id].ops->exit)
|
||||
cdrom[id].ops->exit(&(cdrom[id]));
|
||||
cdrom[id].ops = NULL;
|
||||
memset(cdrom[id].image_path, 0, sizeof(cdrom[id].image_path));
|
||||
cdrom_image_open(&(cdrom[id]), fn);
|
||||
/* Signal media change to the emulated machine. */
|
||||
if (cdrom[id].insert)
|
||||
cdrom[id].insert(cdrom[id].priv);
|
||||
cdrom[id].host_drive = (strlen(cdrom[id].image_path) == 0) ? 0 : 200;
|
||||
if (cdrom[id].host_drive == 200) {
|
||||
ui_sb_update_icon_state(SB_CDROM | id, 0);
|
||||
} else {
|
||||
ui_sb_update_icon_state(SB_CDROM | id, 1);
|
||||
}
|
||||
//media_menu_update_cdrom(id);
|
||||
ui_sb_update_tip(SB_CDROM | id);
|
||||
config_save();
|
||||
}
|
||||
|
||||
void
|
||||
mo_eject(uint8_t id)
|
||||
{
|
||||
mo_t *dev = (mo_t *) mo_drives[id].priv;
|
||||
|
||||
mo_disk_close(dev);
|
||||
if (mo_drives[id].bus_type) {
|
||||
/* Signal disk change to the emulated machine. */
|
||||
mo_insert(dev);
|
||||
}
|
||||
|
||||
ui_sb_update_icon_state(SB_MO | id, 1);
|
||||
//media_menu_update_mo(id);
|
||||
ui_sb_update_tip(SB_MO | id);
|
||||
config_save();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
mo_mount(uint8_t id, char *fn, uint8_t wp)
|
||||
{
|
||||
mo_t *dev = (mo_t *) mo_drives[id].priv;
|
||||
|
||||
mo_disk_close(dev);
|
||||
mo_drives[id].read_only = wp;
|
||||
mo_load(dev, fn);
|
||||
mo_insert(dev);
|
||||
|
||||
ui_sb_update_icon_state(SB_MO | id, strlen(mo_drives[id].image_path) ? 0 : 1);
|
||||
//media_menu_update_mo(id);
|
||||
ui_sb_update_tip(SB_MO | id);
|
||||
|
||||
config_save();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
mo_reload(uint8_t id)
|
||||
{
|
||||
mo_t *dev = (mo_t *) mo_drives[id].priv;
|
||||
|
||||
mo_disk_reload(dev);
|
||||
if (strlen(mo_drives[id].image_path) == 0) {
|
||||
ui_sb_update_icon_state(SB_MO|id, 1);
|
||||
} else {
|
||||
ui_sb_update_icon_state(SB_MO|id, 0);
|
||||
}
|
||||
|
||||
//media_menu_update_mo(id);
|
||||
ui_sb_update_tip(SB_MO|id);
|
||||
|
||||
config_save();
|
||||
}
|
||||
|
||||
void
|
||||
zip_eject(uint8_t id)
|
||||
{
|
||||
zip_t *dev = (zip_t *) zip_drives[id].priv;
|
||||
|
||||
zip_disk_close(dev);
|
||||
if (zip_drives[id].bus_type) {
|
||||
/* Signal disk change to the emulated machine. */
|
||||
zip_insert(dev);
|
||||
}
|
||||
|
||||
ui_sb_update_icon_state(SB_ZIP | id, 1);
|
||||
//media_menu_update_zip(id);
|
||||
ui_sb_update_tip(SB_ZIP | id);
|
||||
config_save();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
zip_mount(uint8_t id, char *fn, uint8_t wp)
|
||||
{
|
||||
zip_t *dev = (zip_t *) zip_drives[id].priv;
|
||||
|
||||
zip_disk_close(dev);
|
||||
zip_drives[id].read_only = wp;
|
||||
zip_load(dev, fn);
|
||||
zip_insert(dev);
|
||||
|
||||
ui_sb_update_icon_state(SB_ZIP | id, strlen(zip_drives[id].image_path) ? 0 : 1);
|
||||
//media_menu_update_zip(id);
|
||||
ui_sb_update_tip(SB_ZIP | id);
|
||||
|
||||
config_save();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
zip_reload(uint8_t id)
|
||||
{
|
||||
zip_t *dev = (zip_t *) zip_drives[id].priv;
|
||||
|
||||
zip_disk_reload(dev);
|
||||
if (strlen(zip_drives[id].image_path) == 0) {
|
||||
ui_sb_update_icon_state(SB_ZIP|id, 1);
|
||||
} else {
|
||||
ui_sb_update_icon_state(SB_ZIP|id, 0);
|
||||
}
|
||||
|
||||
//media_menu_update_zip(id);
|
||||
ui_sb_update_tip(SB_ZIP|id);
|
||||
|
||||
config_save();
|
||||
}
|
||||
|
||||
@@ -23,9 +23,9 @@ void FileField::setFileName(const QString &fileName) {
|
||||
void FileField::on_pushButton_clicked() {
|
||||
QString fileName;
|
||||
if (createFile_) {
|
||||
fileName = QFileDialog::getSaveFileName(this, "Create...");
|
||||
fileName = QFileDialog::getSaveFileName(this, "Create...", QString(), filter_, &selectedFilter_);
|
||||
} else {
|
||||
fileName = QFileDialog::getOpenFileName(this, "Open...");
|
||||
fileName = QFileDialog::getOpenFileName(this, "Open...", QString(), filter_, &selectedFilter_);
|
||||
}
|
||||
|
||||
fileName_ = fileName;
|
||||
|
||||
@@ -18,6 +18,9 @@ public:
|
||||
QString fileName() const { return fileName_; }
|
||||
void setFileName(const QString& fileName);
|
||||
|
||||
void setFilter(const QString& filter) { filter_ = filter; }
|
||||
QString selectedFilter() const { return selectedFilter_; }
|
||||
|
||||
void setCreateFile(bool createFile) { createFile_ = createFile; }
|
||||
|
||||
signals:
|
||||
@@ -29,6 +32,8 @@ private slots:
|
||||
private:
|
||||
Ui::FileField *ui;
|
||||
QString fileName_;
|
||||
QString selectedFilter_;
|
||||
QString filter_;
|
||||
bool createFile_ = false;
|
||||
};
|
||||
|
||||
|
||||
@@ -337,7 +337,7 @@ void HarddiskDialog::onCreateNewFile() {
|
||||
_86box_geometry = create_drive_vhd_dynamic(fileName, cylinders_, heads_, sectors_, block_size);
|
||||
break;
|
||||
case 5:
|
||||
QString vhdParent = QFileDialog::getOpenFileName(this, "Select the parent VHD", QString(), "VHD files (*.vhd);;All files (*.*)");
|
||||
QString vhdParent = QFileDialog::getOpenFileName(this, "Select the parent VHD", QString(), "VHD files (*.vhd);;All files (*)");
|
||||
if (vhdParent.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -196,6 +196,7 @@ struct MachineStatus::States {
|
||||
std::array<StateActive, HDD_BUS_USB> hdds;
|
||||
StateActive net;
|
||||
std::unique_ptr<QLabel> sound;
|
||||
std::unique_ptr<QLabel> text;
|
||||
};
|
||||
|
||||
MachineStatus::MachineStatus(QObject *parent) :
|
||||
@@ -206,6 +207,81 @@ MachineStatus::MachineStatus(QObject *parent) :
|
||||
|
||||
MachineStatus::~MachineStatus() = default;
|
||||
|
||||
bool MachineStatus::hasCassette() {
|
||||
return cassette_enable > 0 ? true : false;
|
||||
}
|
||||
|
||||
bool MachineStatus::hasCartridge() {
|
||||
return machines[machine].flags & MACHINE_CARTRIDGE;
|
||||
}
|
||||
|
||||
bool MachineStatus::hasIDE() {
|
||||
return machines[machine].flags & MACHINE_IDE_QUAD;
|
||||
}
|
||||
|
||||
bool MachineStatus::hasSCSI() {
|
||||
return machines[machine].flags & MACHINE_SCSI_DUAL;
|
||||
}
|
||||
|
||||
void MachineStatus::iterateFDD(const std::function<void (int)> &cb) {
|
||||
for (int i = 0; i < FDD_NUM; ++i) {
|
||||
if (fdd_get_type(i) != 0) {
|
||||
cb(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MachineStatus::iterateCDROM(const std::function<void (int)> &cb) {
|
||||
auto hdc_name = QString(hdc_get_internal_name(hdc_current));
|
||||
for (size_t i = 0; i < CDROM_NUM; i++) {
|
||||
/* Could be Internal or External IDE.. */
|
||||
if ((cdrom[i].bus_type == CDROM_BUS_ATAPI) &&
|
||||
!hasIDE() && hdc_name != QStringLiteral("ide"))
|
||||
continue;
|
||||
if ((cdrom[i].bus_type == CDROM_BUS_SCSI) && !hasSCSI() &&
|
||||
(scsi_card_current[0] == 0) && (scsi_card_current[1] == 0) &&
|
||||
(scsi_card_current[2] == 0) && (scsi_card_current[3] == 0))
|
||||
continue;
|
||||
if (cdrom[i].bus_type != 0) {
|
||||
cb(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MachineStatus::iterateZIP(const std::function<void (int)> &cb) {
|
||||
auto hdc_name = QString(hdc_get_internal_name(hdc_current));
|
||||
for (size_t i = 0; i < ZIP_NUM; i++) {
|
||||
/* Could be Internal or External IDE.. */
|
||||
if ((zip_drives[i].bus_type == ZIP_BUS_ATAPI) &&
|
||||
!hasIDE() && hdc_name != QStringLiteral("ide"))
|
||||
continue;
|
||||
if ((zip_drives[i].bus_type == ZIP_BUS_SCSI) && !hasSCSI() &&
|
||||
(scsi_card_current[0] == 0) && (scsi_card_current[1] == 0) &&
|
||||
(scsi_card_current[2] == 0) && (scsi_card_current[3] == 0))
|
||||
continue;
|
||||
if (zip_drives[i].bus_type != 0) {
|
||||
cb(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MachineStatus::iterateMO(const std::function<void (int)> &cb) {
|
||||
auto hdc_name = QString(hdc_get_internal_name(hdc_current));
|
||||
for (size_t i = 0; i < MO_NUM; i++) {
|
||||
/* Could be Internal or External IDE.. */
|
||||
if ((mo_drives[i].bus_type == MO_BUS_ATAPI) &&
|
||||
!hasIDE() && hdc_name != QStringLiteral("ide"))
|
||||
continue;
|
||||
if ((mo_drives[i].bus_type == MO_BUS_SCSI) && !hasSCSI() &&
|
||||
(scsi_card_current[0] == 0) && (scsi_card_current[1] == 0) &&
|
||||
(scsi_card_current[2] == 0) && (scsi_card_current[3] == 0))
|
||||
continue;
|
||||
if (mo_drives[i].bus_type != 0) {
|
||||
cb(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int hdd_count(int bus) {
|
||||
int c = 0;
|
||||
int i;
|
||||
@@ -220,12 +296,9 @@ static int hdd_count(int bus) {
|
||||
}
|
||||
|
||||
void MachineStatus::refresh(QStatusBar* sbar) {
|
||||
bool has_cart = machines[machine].flags & MACHINE_CARTRIDGE;
|
||||
bool has_mfm = machines[machine].flags & MACHINE_MFM;
|
||||
bool has_xta = machines[machine].flags & MACHINE_XTA;
|
||||
bool has_esdi = machines[machine].flags & MACHINE_ESDI;
|
||||
bool has_ide = machines[machine].flags & MACHINE_IDE_QUAD;
|
||||
bool has_scsi = machines[machine].flags & MACHINE_SCSI_DUAL;
|
||||
|
||||
int c_mfm = hdd_count(HDD_BUS_MFM);
|
||||
int c_esdi = hdd_count(HDD_BUS_ESDI);
|
||||
@@ -262,7 +335,7 @@ void MachineStatus::refresh(QStatusBar* sbar) {
|
||||
sbar->addWidget(d->cassette.label.get());
|
||||
}
|
||||
|
||||
if (has_cart) {
|
||||
if (hasCartridge()) {
|
||||
for (int i = 0; i < 2; ++i) {
|
||||
d->cartridge[i].label = std::make_unique<QLabel>();
|
||||
d->cartridge[i].setEmpty(QString(cart_fns[i]).isEmpty());
|
||||
@@ -270,73 +343,43 @@ void MachineStatus::refresh(QStatusBar* sbar) {
|
||||
}
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < FDD_NUM; ++i) {
|
||||
if (fdd_get_type(i) != 0) {
|
||||
d->fdd[i].label = std::make_unique<QLabel>();
|
||||
int t = fdd_get_type(i);
|
||||
if (t == 0) {
|
||||
d->fdd[i].pixmaps = &d->pixmaps.floppy_disabled;
|
||||
} else if (t >= 1 && t <= 6) {
|
||||
d->fdd[i].pixmaps = &d->pixmaps.floppy_525;
|
||||
} else {
|
||||
d->fdd[i].pixmaps = &d->pixmaps.floppy_35;
|
||||
}
|
||||
d->fdd[i].setEmpty(QString(floppyfns[i]).isEmpty());
|
||||
d->fdd[i].setActive(false);
|
||||
sbar->addWidget(d->fdd[i].label.get());
|
||||
iterateFDD([this, sbar](int i) {
|
||||
int t = fdd_get_type(i);
|
||||
if (t == 0) {
|
||||
d->fdd[i].pixmaps = &d->pixmaps.floppy_disabled;
|
||||
} else if (t >= 1 && t <= 6) {
|
||||
d->fdd[i].pixmaps = &d->pixmaps.floppy_525;
|
||||
} else {
|
||||
d->fdd[i].pixmaps = &d->pixmaps.floppy_35;
|
||||
}
|
||||
}
|
||||
d->fdd[i].label = std::make_unique<QLabel>();
|
||||
d->fdd[i].setEmpty(QString(floppyfns[i]).isEmpty());
|
||||
d->fdd[i].setActive(false);
|
||||
sbar->addWidget(d->fdd[i].label.get());
|
||||
});
|
||||
|
||||
iterateCDROM([this, sbar](int i) {
|
||||
d->cdrom[i].label = std::make_unique<QLabel>();
|
||||
d->cdrom[i].setEmpty(cdrom[i].host_drive != 200 || QString(cdrom[i].image_path).isEmpty());
|
||||
d->cdrom[i].setActive(false);
|
||||
sbar->addWidget(d->cdrom[i].label.get());
|
||||
});
|
||||
|
||||
iterateZIP([this, sbar](int i) {
|
||||
d->zip[i].label = std::make_unique<QLabel>();
|
||||
d->zip[i].setEmpty(QString(zip_drives[i].image_path).isEmpty());
|
||||
d->zip[i].setActive(false);
|
||||
sbar->addWidget(d->zip[i].label.get());
|
||||
});
|
||||
|
||||
iterateMO([this, sbar](int i) {
|
||||
d->mo[i].label = std::make_unique<QLabel>();
|
||||
d->mo[i].setEmpty(QString(mo_drives[i].image_path).isEmpty());
|
||||
d->mo[i].setActive(false);
|
||||
sbar->addWidget(d->mo[i].label.get());
|
||||
});
|
||||
|
||||
auto hdc_name = QString(hdc_get_internal_name(hdc_current));
|
||||
for (size_t i = 0; i < CDROM_NUM; i++) {
|
||||
/* Could be Internal or External IDE.. */
|
||||
if ((cdrom[i].bus_type == CDROM_BUS_ATAPI) &&
|
||||
!has_ide && hdc_name != QStringLiteral("ide"))
|
||||
continue;
|
||||
if ((cdrom[i].bus_type == CDROM_BUS_SCSI) && !has_scsi &&
|
||||
(scsi_card_current[0] == 0) && (scsi_card_current[1] == 0) &&
|
||||
(scsi_card_current[2] == 0) && (scsi_card_current[3] == 0))
|
||||
continue;
|
||||
if (cdrom[i].bus_type != 0) {
|
||||
d->cdrom[i].label = std::make_unique<QLabel>();
|
||||
d->cdrom[i].setEmpty(cdrom[i].host_drive != 200 || QString(cdrom[i].image_path).isEmpty());
|
||||
d->cdrom[i].setActive(false);
|
||||
sbar->addWidget(d->cdrom[i].label.get());
|
||||
}
|
||||
}
|
||||
for (size_t i = 0; i < ZIP_NUM; i++) {
|
||||
/* Could be Internal or External IDE.. */
|
||||
if ((zip_drives[i].bus_type == ZIP_BUS_ATAPI) &&
|
||||
!has_ide && hdc_name != QStringLiteral("ide"))
|
||||
continue;
|
||||
if ((zip_drives[i].bus_type == ZIP_BUS_SCSI) && !has_scsi &&
|
||||
(scsi_card_current[0] == 0) && (scsi_card_current[1] == 0) &&
|
||||
(scsi_card_current[2] == 0) && (scsi_card_current[3] == 0))
|
||||
continue;
|
||||
if (zip_drives[i].bus_type != 0) {
|
||||
d->zip[i].label = std::make_unique<QLabel>();
|
||||
d->zip[i].setEmpty(QString(zip_drives[i].image_path).isEmpty());
|
||||
d->zip[i].setActive(false);
|
||||
sbar->addWidget(d->zip[i].label.get());
|
||||
}
|
||||
}
|
||||
for (size_t i = 0; i < MO_NUM; i++) {
|
||||
/* Could be Internal or External IDE.. */
|
||||
if ((mo_drives[i].bus_type == MO_BUS_ATAPI) &&
|
||||
!has_ide && hdc_name != QStringLiteral("ide"))
|
||||
continue;
|
||||
if ((mo_drives[i].bus_type == MO_BUS_SCSI) && !has_scsi &&
|
||||
(scsi_card_current[0] == 0) && (scsi_card_current[1] == 0) &&
|
||||
(scsi_card_current[2] == 0) && (scsi_card_current[3] == 0))
|
||||
continue;
|
||||
if (mo_drives[i].bus_type != 0) {
|
||||
d->mo[i].label = std::make_unique<QLabel>();
|
||||
d->mo[i].setEmpty(QString(mo_drives[i].image_path).isEmpty());
|
||||
d->mo[i].setActive(false);
|
||||
sbar->addWidget(d->mo[i].label.get());
|
||||
}
|
||||
}
|
||||
|
||||
if ((has_mfm || hdc_name == QStringLiteral("st506")) && c_mfm > 0) {
|
||||
d->hdds[HDD_BUS_MFM].label = std::make_unique<QLabel>();
|
||||
d->hdds[HDD_BUS_MFM].setActive(false);
|
||||
@@ -352,12 +395,12 @@ void MachineStatus::refresh(QStatusBar* sbar) {
|
||||
d->hdds[HDD_BUS_XTA].setActive(false);
|
||||
sbar->addWidget(d->hdds[HDD_BUS_XTA].label.get());
|
||||
}
|
||||
if ((has_ide || hdc_name == QStringLiteral("xtide") || hdc_name == QStringLiteral("ide")) && c_ide > 0) {
|
||||
if ((hasIDE() || hdc_name == QStringLiteral("xtide") || hdc_name == QStringLiteral("ide")) && c_ide > 0) {
|
||||
d->hdds[HDD_BUS_IDE].label = std::make_unique<QLabel>();
|
||||
d->hdds[HDD_BUS_IDE].setActive(false);
|
||||
sbar->addWidget(d->hdds[HDD_BUS_IDE].label.get());
|
||||
}
|
||||
if ((has_scsi || (scsi_card_current[0] != 0) || (scsi_card_current[1] != 0) ||
|
||||
if ((hasSCSI() || (scsi_card_current[0] != 0) || (scsi_card_current[1] != 0) ||
|
||||
(scsi_card_current[2] != 0) || (scsi_card_current[3] != 0)) && c_scsi > 0) {
|
||||
d->hdds[HDD_BUS_SCSI].label = std::make_unique<QLabel>();
|
||||
d->hdds[HDD_BUS_SCSI].setActive(false);
|
||||
@@ -372,6 +415,8 @@ void MachineStatus::refresh(QStatusBar* sbar) {
|
||||
d->sound = std::make_unique<QLabel>();
|
||||
d->sound->setPixmap(d->pixmaps.sound);
|
||||
sbar->addWidget(d->sound.get());
|
||||
d->text = std::make_unique<QLabel>();
|
||||
sbar->addWidget(d->text.get());
|
||||
}
|
||||
|
||||
void MachineStatus::setActivity(int tag, bool active) {
|
||||
@@ -440,3 +485,7 @@ void MachineStatus::setEmpty(int tag, bool empty) {
|
||||
}
|
||||
}
|
||||
|
||||
void MachineStatus::message(const QString &msg) {
|
||||
d->text->setText(msg);
|
||||
}
|
||||
|
||||
|
||||
@@ -13,10 +13,19 @@ public:
|
||||
explicit MachineStatus(QObject *parent = nullptr);
|
||||
~MachineStatus();
|
||||
|
||||
static bool hasCassette();
|
||||
static bool hasCartridge();
|
||||
static bool hasIDE();
|
||||
static bool hasSCSI();
|
||||
static void iterateFDD(const std::function<void(int i)>& cb);
|
||||
static void iterateCDROM(const std::function<void(int i)>& cb);
|
||||
static void iterateZIP(const std::function<void(int i)>& cb);
|
||||
static void iterateMO(const std::function<void(int i)>& cb);
|
||||
public slots:
|
||||
void refresh(QStatusBar* sbar);
|
||||
void setActivity(int tag, bool active);
|
||||
void setEmpty(int tag, bool active);
|
||||
void message(const QString& msg);
|
||||
|
||||
private:
|
||||
struct States;
|
||||
|
||||
@@ -24,6 +24,7 @@ extern "C" {
|
||||
#include "qt_settings.hpp"
|
||||
#include "qt_gleswidget.hpp"
|
||||
#include "qt_machinestatus.hpp"
|
||||
#include "qt_mediamenu.hpp"
|
||||
|
||||
#ifdef __unix__
|
||||
#include <X11/Xlib.h>
|
||||
@@ -40,6 +41,8 @@ MainWindow::MainWindow(QWidget *parent) :
|
||||
{
|
||||
Q_INIT_RESOURCE(qt_resources);
|
||||
status = std::make_unique<MachineStatus>(this);
|
||||
mm = std::make_shared<MediaMenu>(this);
|
||||
MediaMenu::ptr = mm;
|
||||
|
||||
ui->setupUi(this);
|
||||
video_setblit(qt_blit);
|
||||
@@ -84,12 +87,10 @@ MainWindow::MainWindow(QWidget *parent) :
|
||||
connect(this, &MainWindow::updateStatusBarPanes, this, [this] {
|
||||
status->refresh(ui->statusbar);
|
||||
});
|
||||
connect(this, &MainWindow::updateStatusBarActivity, this, [this](int i, bool b) {
|
||||
status->setActivity(i, b);
|
||||
});
|
||||
connect(this, &MainWindow::updateStatusBarEmpty, this, [this](int i, bool b) {
|
||||
status->setEmpty(i, b);
|
||||
});
|
||||
connect(this, &MainWindow::updateStatusBarPanes, this, &MainWindow::refreshMediaMenu);
|
||||
connect(this, &MainWindow::updateStatusBarActivity, status.get(), &MachineStatus::setActivity);
|
||||
connect(this, &MainWindow::updateStatusBarEmpty, status.get(), &MachineStatus::setEmpty);
|
||||
connect(this, &MainWindow::statusBarMessage, status.get(), &MachineStatus::message);
|
||||
|
||||
ui->actionKeyboard_requires_capture->setChecked(kbd_req_capture);
|
||||
ui->actionRight_CTRL_is_left_ALT->setChecked(rctrl_is_lalt);
|
||||
@@ -684,6 +685,10 @@ void MainWindow::getTitle(wchar_t *title)
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::refreshMediaMenu() {
|
||||
mm->refresh(ui->menuMedia);
|
||||
}
|
||||
|
||||
void MainWindow::showMessage(const QString& header, const QString& message) {
|
||||
if (QThread::currentThread() == this->thread()) {
|
||||
showMessage_(header, message);
|
||||
|
||||
@@ -5,6 +5,10 @@
|
||||
#include <QLabel>
|
||||
#include <QEvent>
|
||||
|
||||
#include <memory>
|
||||
|
||||
class MediaMenu;
|
||||
|
||||
namespace Ui {
|
||||
class MainWindow;
|
||||
}
|
||||
@@ -27,6 +31,7 @@ signals:
|
||||
void paint(const QImage& image);
|
||||
void resizeContents(int w, int h);
|
||||
void pollMouse();
|
||||
void statusBarMessage(const QString& msg);
|
||||
void updateStatusBarPanes();
|
||||
void updateStatusBarActivity(int tag, bool active);
|
||||
void updateStatusBarEmpty(int tag, bool empty);
|
||||
@@ -48,6 +53,7 @@ private slots:
|
||||
void on_actionRight_CTRL_is_left_ALT_triggered();
|
||||
void on_actionKeyboard_requires_capture_triggered();
|
||||
|
||||
void refreshMediaMenu();
|
||||
void showMessage_(const QString& header, const QString& message);
|
||||
void setTitle_(const wchar_t* title);
|
||||
void getTitle_(wchar_t* title);
|
||||
@@ -57,6 +63,7 @@ protected:
|
||||
private:
|
||||
Ui::MainWindow *ui;
|
||||
std::unique_ptr<MachineStatus> status;
|
||||
std::shared_ptr<MediaMenu> mm;
|
||||
};
|
||||
|
||||
#endif // QT_MAINWINDOW_HPP
|
||||
|
||||
@@ -78,8 +78,14 @@
|
||||
</property>
|
||||
<addaction name="actionFullscreen"/>
|
||||
</widget>
|
||||
<widget class="QMenu" name="menuMedia">
|
||||
<property name="title">
|
||||
<string>Media</string>
|
||||
</property>
|
||||
</widget>
|
||||
<addaction name="menuAction"/>
|
||||
<addaction name="menuView"/>
|
||||
<addaction name="menuMedia"/>
|
||||
<addaction name="menuTools"/>
|
||||
</widget>
|
||||
<widget class="QStatusBar" name="statusbar"/>
|
||||
|
||||
533
src/qt/qt_mediamenu.cpp
Normal file
533
src/qt/qt_mediamenu.cpp
Normal file
@@ -0,0 +1,533 @@
|
||||
#include "qt_mediamenu.hpp"
|
||||
|
||||
#include "qt_machinestatus.hpp"
|
||||
|
||||
#include <QMenu>
|
||||
#include <QFileDialog>
|
||||
#include <QMessageBox>
|
||||
|
||||
extern "C" {
|
||||
#include <86box/config.h>
|
||||
#include <86box/device.h>
|
||||
#include <86box/timer.h>
|
||||
#include <86box/plat.h>
|
||||
#include <86box/cassette.h>
|
||||
#include <86box/cartridge.h>
|
||||
#include <86box/fdd.h>
|
||||
#include <86box/fdd_86f.h>
|
||||
#include <86box/cdrom.h>
|
||||
#include <86box/scsi_device.h>
|
||||
#include <86box/zip.h>
|
||||
#include <86box/mo.h>
|
||||
#include <86box/sound.h>
|
||||
#include <86box/ui.h>
|
||||
};
|
||||
|
||||
#include "qt_newfloppydialog.hpp"
|
||||
|
||||
std::shared_ptr<MediaMenu> MediaMenu::ptr;
|
||||
|
||||
MediaMenu::MediaMenu(QWidget* parent) : QObject(parent) {
|
||||
parentWidget = parent;
|
||||
}
|
||||
|
||||
void MediaMenu::refresh(QMenu *parentMenu) {
|
||||
parentMenu->clear();
|
||||
|
||||
if(MachineStatus::hasCassette()) {
|
||||
cassetteMenu = parentMenu->addMenu("");
|
||||
cassetteMenu->addAction("New Image", [this]() { cassetteNewImage(); });
|
||||
cassetteMenu->addSeparator();
|
||||
cassetteMenu->addAction("Existing Image", [this]() { cassetteSelectImage(false); });
|
||||
cassetteMenu->addAction("Existing Image (Write Protected)", [this]() { cassetteSelectImage(true); });
|
||||
cassetteMenu->addSeparator();
|
||||
cassetteMenu->addAction("Record")->setCheckable(true);
|
||||
cassetteMenu->addAction("Play")->setCheckable(true);
|
||||
cassetteMenu->addAction("Rewing");
|
||||
cassetteMenu->addAction("Fast Forward");
|
||||
cassetteMenu->addSeparator();
|
||||
cassetteMenu->addAction("Eject", [this]() { cassetteEject(); });
|
||||
cassetteUpdateMenu();
|
||||
}
|
||||
|
||||
cartridgeMenus.clear();
|
||||
if (MachineStatus::hasCartridge()) {
|
||||
for(int i = 0; i < 2; i++) {
|
||||
auto* menu = parentMenu->addMenu("");
|
||||
menu->addAction("Image", [this, i]() { cartridgeSelectImage(i); });
|
||||
menu->addSeparator();
|
||||
menu->addAction("Eject", [this, i]() { cartridgeEject(i); });
|
||||
cartridgeMenus.append(menu);
|
||||
cartridgeUpdateMenu(i);
|
||||
}
|
||||
}
|
||||
|
||||
floppyMenus.clear();
|
||||
MachineStatus::iterateFDD([this, parentMenu](int i) {
|
||||
auto* menu = parentMenu->addMenu("");
|
||||
menu->addAction("New Image", [this, i]() { floppyNewImage(i); });
|
||||
menu->addSeparator();
|
||||
menu->addAction("Existing Image", [this, i]() { floppySelectImage(i, false); });
|
||||
menu->addAction("Existing Image (Write Protected)", [this, i]() { floppySelectImage(i, true); });
|
||||
menu->addSeparator();
|
||||
menu->addAction("Export to 86F", [this, i]() { floppyExportTo86f(i); });
|
||||
menu->addSeparator();
|
||||
menu->addAction("Eject", [this, i]() { floppyEject(i); });
|
||||
floppyMenus.append(menu);
|
||||
floppyUpdateMenu(i);
|
||||
});
|
||||
|
||||
cdromMenus.clear();
|
||||
MachineStatus::iterateCDROM([this, parentMenu](int i) {
|
||||
auto* menu = parentMenu->addMenu("");
|
||||
cdromMutePos = menu->children().count();
|
||||
menu->addAction("Mute", [this, i]() { cdromMute(i); })->setCheckable(true);
|
||||
menu->addSeparator();
|
||||
cdromEmptyPos = menu->children().count();
|
||||
menu->addAction("Empty", [this, i]() { cdromEject(i); })->setCheckable(true);
|
||||
cdromReloadPos = menu->children().count();
|
||||
menu->addAction("Reload previous image", [this, i]() { cdromReload(i); });
|
||||
menu->addSeparator();
|
||||
cdromImagePos = menu->children().count();
|
||||
menu->addAction("Image", [this, i]() { cdromMount(i); })->setCheckable(true);
|
||||
cdromMenus.append(menu);
|
||||
cdromUpdateMenu(i);
|
||||
});
|
||||
|
||||
zipMenus.clear();
|
||||
MachineStatus::iterateZIP([this, parentMenu](int i) {
|
||||
auto* menu = parentMenu->addMenu("");
|
||||
menu->addAction("New Image", [this, i]() { zipNewImage(i); });
|
||||
menu->addSeparator();
|
||||
menu->addAction("Existing Image", [this, i]() { zipSelectImage(i, false); });
|
||||
menu->addAction("Existing Image (Write Protected)", [this, i]() { zipSelectImage(i, true); });
|
||||
menu->addSeparator();
|
||||
zipEjectPos = menu->children().count();
|
||||
menu->addAction("Eject", [this, i]() { zipEject(i); });
|
||||
zipReloadPos = menu->children().count();
|
||||
menu->addAction("Reload previous image", [this, i]() { zipReload(i); });
|
||||
zipMenus.append(menu);
|
||||
zipUpdateMenu(i);
|
||||
});
|
||||
|
||||
moMenus.clear();
|
||||
MachineStatus::iterateMO([this, parentMenu](int i) {
|
||||
auto* menu = parentMenu->addMenu("");
|
||||
menu->addAction("New Image", [this, i]() { moNewImage(i); });
|
||||
menu->addSeparator();
|
||||
menu->addAction("Existing Image", [this, i]() { moSelectImage(i, false); });
|
||||
menu->addAction("Existing Image (Write Protected)", [this, i]() { moSelectImage(i, true); });
|
||||
menu->addSeparator();
|
||||
moEjectPos = menu->children().count();
|
||||
menu->addAction("Eject", [this, i]() { moEject(i); });
|
||||
moReloadPos = menu->children().count();
|
||||
menu->addAction("Reload previous image", [this, i]() { moReload(i); });
|
||||
moMenus.append(menu);
|
||||
moUpdateMenu(i);
|
||||
});
|
||||
}
|
||||
|
||||
void MediaMenu::cassetteNewImage() {
|
||||
auto filename = QFileDialog::getSaveFileName(parentWidget, "Create...");
|
||||
QFileInfo fileinfo(filename);
|
||||
if (fileinfo.suffix().isEmpty()) {
|
||||
filename.append(".cas");
|
||||
}
|
||||
cassetteMount(filename, false);
|
||||
}
|
||||
|
||||
void MediaMenu::cassetteSelectImage(bool wp) {
|
||||
auto filename = QFileDialog::getOpenFileName(parentWidget, "Open", QString(), "Cassette images (*.pcm;*.raw;*.wav;*.cas);;All files (*)");
|
||||
cassetteMount(filename, wp);
|
||||
}
|
||||
|
||||
void MediaMenu::cassetteMount(const QString& filename, bool wp) {
|
||||
pc_cas_set_fname(cassette, nullptr);
|
||||
memset(cassette_fname, 0, sizeof(cassette_fname));
|
||||
cassette_ui_writeprot = wp ? 1 : 0;
|
||||
|
||||
if (! filename.isEmpty()) {
|
||||
QByteArray filenameBytes = filename.toUtf8();
|
||||
strncpy(cassette_fname, filenameBytes.data(), sizeof(cassette_fname));
|
||||
pc_cas_set_fname(cassette, cassette_fname);
|
||||
}
|
||||
|
||||
ui_sb_update_icon_state(SB_CASSETTE, filename.isEmpty() ? 1 : 0);
|
||||
ui_sb_update_tip(SB_CASSETTE);
|
||||
cassetteUpdateMenu();
|
||||
config_save();
|
||||
}
|
||||
|
||||
void MediaMenu::cassetteEject() {
|
||||
pc_cas_set_fname(cassette, nullptr);
|
||||
memset(cassette_fname, 0, sizeof(cassette_fname));
|
||||
ui_sb_update_icon_state(SB_CASSETTE, 1);
|
||||
ui_sb_update_tip(SB_CASSETTE);
|
||||
cassetteUpdateMenu();
|
||||
config_save();
|
||||
}
|
||||
|
||||
void MediaMenu::cassetteUpdateMenu() {
|
||||
QString name = cassette_fname;
|
||||
cassetteMenu->setTitle(QString("Cassette: %1").arg(name.isEmpty() ? "(empty)" : name));
|
||||
}
|
||||
|
||||
void MediaMenu::cartridgeSelectImage(int i) {
|
||||
auto filename = QFileDialog::getOpenFileName(parentWidget, "Open", QString(), "Cartridge images (*.a;*.b;*.jrc);;All files (*)");
|
||||
if (filename.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
cart_close(i);
|
||||
QByteArray filenameBytes = filename.toUtf8();
|
||||
cart_load(i, filenameBytes.data());
|
||||
|
||||
ui_sb_update_icon_state(SB_CARTRIDGE | i, filename.isEmpty() ? 1 : 0);
|
||||
ui_sb_update_tip(SB_CARTRIDGE | i);
|
||||
cartridgeUpdateMenu(i);
|
||||
config_save();
|
||||
}
|
||||
|
||||
void MediaMenu::cartridgeEject(int i) {
|
||||
cart_close(i);
|
||||
ui_sb_update_icon_state(SB_CARTRIDGE | i, 1);
|
||||
ui_sb_update_tip(SB_CARTRIDGE | i);
|
||||
cartridgeUpdateMenu(i);
|
||||
config_save();
|
||||
}
|
||||
|
||||
void MediaMenu::cartridgeUpdateMenu(int i) {
|
||||
QString name = cart_fns[i];
|
||||
cartridgeMenus[i]->setTitle(QString("Cartridge %1: %2").arg(QString::number(i+1), name.isEmpty() ? "(empty)" : name));
|
||||
}
|
||||
|
||||
void MediaMenu::floppyNewImage(int i) {
|
||||
NewFloppyDialog dialog(NewFloppyDialog::MediaType::Floppy, parentWidget);
|
||||
switch (dialog.exec()) {
|
||||
case QDialog::Accepted:
|
||||
QByteArray filename = dialog.fileName().toUtf8();
|
||||
floppyMount(i, filename, false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void MediaMenu::floppySelectImage(int i, bool wp) {
|
||||
auto filename = QFileDialog::getOpenFileName(parentWidget, "Open", QString(), "All images (*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF);;Advanced sector images (*.IMD;*.JSON;*.TD0);;Basic sector images (*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?);;Flux images (*.FDI);;Surface images (*.86F;*.MFM);;All files (*)");
|
||||
floppyMount(i, filename, wp);
|
||||
}
|
||||
|
||||
void MediaMenu::floppyMount(int i, const QString &filename, bool wp) {
|
||||
fdd_close(i);
|
||||
ui_writeprot[i] = wp ? 1 : 0;
|
||||
if (! filename.isEmpty()) {
|
||||
QByteArray filenameBytes = filename.toUtf8();
|
||||
fdd_load(i, filenameBytes.data());
|
||||
}
|
||||
ui_sb_update_icon_state(SB_FLOPPY | i, filename.isEmpty() ? 1 : 0);
|
||||
ui_sb_update_tip(SB_FLOPPY | i);
|
||||
floppyUpdateMenu(i);
|
||||
config_save();
|
||||
}
|
||||
|
||||
void MediaMenu::floppyEject(int i) {
|
||||
fdd_close(i);
|
||||
ui_sb_update_icon_state(SB_FLOPPY | i, 1);
|
||||
ui_sb_update_tip(SB_FLOPPY | i);
|
||||
floppyUpdateMenu(i);
|
||||
config_save();
|
||||
}
|
||||
|
||||
void MediaMenu::floppyExportTo86f(int i) {
|
||||
auto filename = QFileDialog::getSaveFileName(parentWidget, "Save as 86f", QString(), "Surface images (*.86f)");
|
||||
if (! filename.isEmpty()) {
|
||||
QByteArray filenameBytes = filename.toUtf8();
|
||||
plat_pause(1);
|
||||
if (d86f_export(i, filenameBytes.data()) == 0) {
|
||||
QMessageBox::critical(parentWidget, "Unable to write file", "Make sure the file is being saved to a writable directory");
|
||||
}
|
||||
plat_pause(0);
|
||||
}
|
||||
}
|
||||
|
||||
void MediaMenu::floppyUpdateMenu(int i) {
|
||||
QString name = floppyfns[i];
|
||||
int type = fdd_get_type(i);
|
||||
floppyMenus[i]->setTitle(QString("Floppy %1 (%2): %3").arg(QString::number(i+1), fdd_getname(type), name.isEmpty() ? "(empty)" : name));
|
||||
}
|
||||
|
||||
void MediaMenu::cdromMute(int i) {
|
||||
cdrom[i].sound_on ^= 1;
|
||||
config_save();
|
||||
cdromUpdateMenu(i);
|
||||
sound_cd_thread_reset();
|
||||
}
|
||||
|
||||
void MediaMenu::cdromMount(int i) {
|
||||
QString dir;
|
||||
QFileInfo fi(cdrom[i].image_path);
|
||||
|
||||
auto filename = QFileDialog::getOpenFileName(parentWidget, "CD-ROM images (*.ISO;*.CUE)\0*.ISO;*.CUE\0All files (*.*)\0*.*\0", fi.canonicalPath());
|
||||
if (filename.isEmpty()) {
|
||||
auto* imageMenu = dynamic_cast<QAction*>(cdromMenus[i]->children()[cdromImagePos]);
|
||||
imageMenu->setChecked(false);
|
||||
return;
|
||||
}
|
||||
QByteArray fn = filename.toUtf8().data();
|
||||
|
||||
cdrom[i].prev_host_drive = cdrom[i].host_drive;
|
||||
strcpy(cdrom[i].prev_image_path, cdrom[i].image_path);
|
||||
if (cdrom[i].ops && cdrom[i].ops->exit)
|
||||
cdrom[i].ops->exit(&(cdrom[i]));
|
||||
|
||||
cdrom[i].ops = nullptr;
|
||||
memset(cdrom[i].image_path, 0, sizeof(cdrom[i].image_path));
|
||||
cdrom_image_open(&(cdrom[i]), fn.data());
|
||||
/* Signal media change to the emulated machine. */
|
||||
if (cdrom[i].insert)
|
||||
cdrom[i].insert(cdrom[i].priv);
|
||||
cdrom[i].host_drive = (strlen(cdrom[i].image_path) == 0) ? 0 : 200;
|
||||
if (cdrom[i].host_drive == 200) {
|
||||
ui_sb_update_icon_state(SB_CDROM | i, 0);
|
||||
} else {
|
||||
ui_sb_update_icon_state(SB_CDROM | i, 1);
|
||||
}
|
||||
ui_sb_update_tip(SB_CDROM | i);
|
||||
cdromUpdateMenu(i);
|
||||
config_save();
|
||||
}
|
||||
|
||||
void MediaMenu::cdromEject(int i) {
|
||||
cdrom_eject(i);
|
||||
cdromUpdateMenu(i);
|
||||
}
|
||||
|
||||
void MediaMenu::cdromReload(int i) {
|
||||
cdrom_reload(i);
|
||||
cdromUpdateMenu(i);
|
||||
}
|
||||
|
||||
void MediaMenu::cdromUpdateMenu(int i) {
|
||||
QString name = cdrom[i].image_path;
|
||||
auto* menu = cdromMenus[i];
|
||||
auto childs = menu->children();
|
||||
|
||||
auto* muteMenu = dynamic_cast<QAction*>(childs[cdromMutePos]);
|
||||
muteMenu->setChecked(cdrom[i].sound_on == 0);
|
||||
|
||||
auto* imageMenu = dynamic_cast<QAction*>(childs[cdromImagePos]);
|
||||
auto* emptyMenu = dynamic_cast<QAction*>(childs[cdromEmptyPos]);
|
||||
imageMenu->setChecked(cdrom[i].host_drive == 200);
|
||||
emptyMenu->setChecked(cdrom[i].host_drive != 200);
|
||||
|
||||
auto* prevMenu = dynamic_cast<QAction*>(childs[cdromReloadPos]);
|
||||
prevMenu->setEnabled(cdrom[i].prev_host_drive != 0);
|
||||
|
||||
QString busName = "Unknown Bus";
|
||||
switch (cdrom[i].bus_type) {
|
||||
case CDROM_BUS_ATAPI:
|
||||
busName = "ATAPI";
|
||||
break;
|
||||
case CDROM_BUS_SCSI:
|
||||
busName = "SCSI";
|
||||
break;
|
||||
}
|
||||
|
||||
menu->setTitle(QString("CD-ROM %1 (%2): %3").arg(QString::number(i+1), busName, name.isEmpty() ? "(empty)" : name));
|
||||
}
|
||||
|
||||
void MediaMenu::zipNewImage(int i) {
|
||||
NewFloppyDialog dialog(NewFloppyDialog::MediaType::Zip, parentWidget);
|
||||
switch (dialog.exec()) {
|
||||
case QDialog::Accepted:
|
||||
QByteArray filename = dialog.fileName().toUtf8();
|
||||
zipMount(i, filename, false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void MediaMenu::zipSelectImage(int i, bool wp) {
|
||||
auto filename = QFileDialog::getOpenFileName(parentWidget, "Open", QString(), "ZIP images (*.im?;*.zdi);;All files (*)");
|
||||
zipMount(i, filename, wp);
|
||||
}
|
||||
|
||||
void MediaMenu::zipMount(int i, const QString &filename, bool wp) {
|
||||
zip_t *dev = (zip_t *) zip_drives[i].priv;
|
||||
|
||||
zip_disk_close(dev);
|
||||
zip_drives[i].read_only = wp;
|
||||
if (! filename.isEmpty()) {
|
||||
QByteArray filenameBytes = filename.toUtf8();
|
||||
zip_load(dev, filenameBytes.data());
|
||||
zip_insert(dev);
|
||||
}
|
||||
|
||||
ui_sb_update_icon_state(SB_ZIP | i, filename.isEmpty() ? 1 : 0);
|
||||
ui_sb_update_tip(SB_ZIP | i);
|
||||
zipUpdateMenu(i);
|
||||
|
||||
config_save();
|
||||
}
|
||||
|
||||
void MediaMenu::zipEject(int i) {
|
||||
zip_t *dev = (zip_t *) zip_drives[i].priv;
|
||||
|
||||
zip_disk_close(dev);
|
||||
if (zip_drives[i].bus_type) {
|
||||
/* Signal disk change to the emulated machine. */
|
||||
zip_insert(dev);
|
||||
}
|
||||
|
||||
ui_sb_update_icon_state(SB_ZIP | i, 1);
|
||||
ui_sb_update_tip(SB_ZIP | i);
|
||||
zipUpdateMenu(i);
|
||||
config_save();
|
||||
}
|
||||
|
||||
void MediaMenu::zipReload(int i) {
|
||||
zip_t *dev = (zip_t *) zip_drives[i].priv;
|
||||
|
||||
zip_disk_reload(dev);
|
||||
if (strlen(zip_drives[i].image_path) == 0) {
|
||||
ui_sb_update_icon_state(SB_ZIP|i, 1);
|
||||
} else {
|
||||
ui_sb_update_icon_state(SB_ZIP|i, 0);
|
||||
}
|
||||
|
||||
ui_sb_update_tip(SB_ZIP|i);
|
||||
zipUpdateMenu(i);
|
||||
|
||||
config_save();
|
||||
}
|
||||
|
||||
void MediaMenu::zipUpdateMenu(int i) {
|
||||
QString name = zip_drives[i].image_path;
|
||||
QString prev_name = zip_drives[i].prev_image_path;
|
||||
auto* menu = zipMenus[i];
|
||||
auto childs = menu->children();
|
||||
|
||||
auto* ejectMenu = dynamic_cast<QAction*>(childs[zipEjectPos]);
|
||||
auto* reloadMenu = dynamic_cast<QAction*>(childs[zipReloadPos]);
|
||||
ejectMenu->setEnabled(!name.isEmpty());
|
||||
reloadMenu->setEnabled(!prev_name.isEmpty());
|
||||
|
||||
QString busName = "Unknown Bus";
|
||||
switch (zip_drives[i].bus_type) {
|
||||
case ZIP_BUS_ATAPI:
|
||||
busName = "ATAPI";
|
||||
break;
|
||||
case ZIP_BUS_SCSI:
|
||||
busName = "SCSI";
|
||||
break;
|
||||
}
|
||||
|
||||
menu->setTitle(QString("ZIP %1 %2 (%3): %4").arg((zip_drives[i].is_250 > 0) ? "250" : "100", QString::number(i+1), busName, name.isEmpty() ? "(empty)" : name));
|
||||
}
|
||||
|
||||
void MediaMenu::moNewImage(int i) {
|
||||
NewFloppyDialog dialog(NewFloppyDialog::MediaType::Mo, parentWidget);
|
||||
switch (dialog.exec()) {
|
||||
case QDialog::Accepted:
|
||||
QByteArray filename = dialog.fileName().toUtf8();
|
||||
moMount(i, filename, false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void MediaMenu::moSelectImage(int i, bool wp) {
|
||||
auto filename = QFileDialog::getOpenFileName(parentWidget, "Open", QString(), "MO images (*.im?;*.mdi);;All files (*)");
|
||||
moMount(i, filename, wp);
|
||||
}
|
||||
|
||||
void MediaMenu::moMount(int i, const QString &filename, bool wp) {
|
||||
mo_t *dev = (mo_t *) mo_drives[i].priv;
|
||||
|
||||
mo_disk_close(dev);
|
||||
mo_drives[i].read_only = wp;
|
||||
if (! filename.isEmpty()) {
|
||||
QByteArray filenameBytes = filename.toUtf8();
|
||||
mo_load(dev, filenameBytes.data());
|
||||
mo_insert(dev);
|
||||
}
|
||||
|
||||
ui_sb_update_icon_state(SB_MO | i, filename.isEmpty() ? 1 : 0);
|
||||
ui_sb_update_tip(SB_MO | i);
|
||||
moUpdateMenu(i);
|
||||
|
||||
config_save();
|
||||
}
|
||||
|
||||
void MediaMenu::moEject(int i) {
|
||||
mo_t *dev = (mo_t *) mo_drives[i].priv;
|
||||
|
||||
mo_disk_close(dev);
|
||||
if (mo_drives[i].bus_type) {
|
||||
/* Signal disk change to the emulated machine. */
|
||||
mo_insert(dev);
|
||||
}
|
||||
|
||||
ui_sb_update_icon_state(SB_MO | i, 1);
|
||||
ui_sb_update_tip(SB_MO | i);
|
||||
moUpdateMenu(i);
|
||||
config_save();
|
||||
}
|
||||
|
||||
void MediaMenu::moReload(int i) {
|
||||
mo_t *dev = (mo_t *) mo_drives[i].priv;
|
||||
|
||||
mo_disk_reload(dev);
|
||||
if (strlen(mo_drives[i].image_path) == 0) {
|
||||
ui_sb_update_icon_state(SB_MO|i, 1);
|
||||
} else {
|
||||
ui_sb_update_icon_state(SB_MO|i, 0);
|
||||
}
|
||||
|
||||
ui_sb_update_tip(SB_MO|i);
|
||||
moUpdateMenu(i);
|
||||
|
||||
config_save();
|
||||
}
|
||||
|
||||
void MediaMenu::moUpdateMenu(int i) {
|
||||
QString name = mo_drives[i].image_path;
|
||||
QString prev_name = mo_drives[i].prev_image_path;
|
||||
auto* menu = moMenus[i];
|
||||
auto childs = menu->children();
|
||||
|
||||
auto* ejectMenu = dynamic_cast<QAction*>(childs[moEjectPos]);
|
||||
auto* reloadMenu = dynamic_cast<QAction*>(childs[moReloadPos]);
|
||||
ejectMenu->setEnabled(!name.isEmpty());
|
||||
reloadMenu->setEnabled(!prev_name.isEmpty());
|
||||
|
||||
QString busName = "Unknown Bus";
|
||||
switch (mo_drives[i].bus_type) {
|
||||
case MO_BUS_ATAPI:
|
||||
busName = "ATAPI";
|
||||
break;
|
||||
case MO_BUS_SCSI:
|
||||
busName = "SCSI";
|
||||
break;
|
||||
}
|
||||
|
||||
menu->setTitle(QString("MO %1 (%2): %3").arg(QString::number(i+1), busName, name.isEmpty() ? "(empty)" : name));
|
||||
}
|
||||
|
||||
|
||||
// callbacks from 86box C code
|
||||
extern "C" {
|
||||
|
||||
void zip_eject(uint8_t id) {
|
||||
MediaMenu::ptr->zipEject(id);
|
||||
}
|
||||
|
||||
void zip_reload(uint8_t id) {
|
||||
MediaMenu::ptr->zipReload(id);
|
||||
}
|
||||
|
||||
void mo_eject(uint8_t id) {
|
||||
MediaMenu::ptr->moEject(id);
|
||||
}
|
||||
|
||||
void mo_reload(uint8_t id) {
|
||||
MediaMenu::ptr->moReload(id);
|
||||
}
|
||||
|
||||
}
|
||||
76
src/qt/qt_mediamenu.hpp
Normal file
76
src/qt/qt_mediamenu.hpp
Normal file
@@ -0,0 +1,76 @@
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <QObject>
|
||||
|
||||
class QMenu;
|
||||
|
||||
class MediaMenu : QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
MediaMenu(QWidget* parent);
|
||||
|
||||
void refresh(QMenu* parentMenu);
|
||||
|
||||
// because some 86box C-only code needs to call zip and
|
||||
// mo eject directly
|
||||
static std::shared_ptr<MediaMenu> ptr;
|
||||
|
||||
void cassetteNewImage();
|
||||
void cassetteSelectImage(bool wp);
|
||||
void cassetteMount(const QString& filename, bool wp);
|
||||
void cassetteEject();
|
||||
void cassetteUpdateMenu();
|
||||
|
||||
void cartridgeSelectImage(int i);
|
||||
void cartridgeEject(int i);
|
||||
void cartridgeUpdateMenu(int i);
|
||||
|
||||
void floppyNewImage(int i);
|
||||
void floppySelectImage(int i, bool wp);
|
||||
void floppyMount(int i, const QString& filename, bool wp);
|
||||
void floppyEject(int i);
|
||||
void floppyExportTo86f(int i);
|
||||
void floppyUpdateMenu(int i);
|
||||
|
||||
void cdromMute(int i);
|
||||
void cdromMount(int i);
|
||||
void cdromEject(int i);
|
||||
void cdromReload(int i);
|
||||
void cdromUpdateMenu(int i);
|
||||
|
||||
void zipNewImage(int i);
|
||||
void zipSelectImage(int i, bool wp);
|
||||
void zipMount(int i, const QString& filename, bool wp);
|
||||
void zipEject(int i);
|
||||
void zipReload(int i);
|
||||
void zipUpdateMenu(int i);
|
||||
|
||||
void moNewImage(int i);
|
||||
void moSelectImage(int i, bool wp);
|
||||
void moMount(int i, const QString& filename, bool wp);
|
||||
void moEject(int i);
|
||||
void moReload(int i);
|
||||
void moUpdateMenu(int i);
|
||||
private:
|
||||
QWidget* parentWidget = nullptr;
|
||||
|
||||
QMenu* cassetteMenu = nullptr;
|
||||
QList<QMenu*> cartridgeMenus;
|
||||
QList<QMenu*> floppyMenus;
|
||||
QList<QMenu*> cdromMenus;
|
||||
QList<QMenu*> zipMenus;
|
||||
QList<QMenu*> moMenus;
|
||||
|
||||
int cdromMutePos;
|
||||
int cdromEmptyPos;
|
||||
int cdromReloadPos;
|
||||
int cdromImagePos;
|
||||
|
||||
int zipEjectPos;
|
||||
int zipReloadPos;
|
||||
|
||||
int moEjectPos;
|
||||
int moReloadPos;
|
||||
};
|
||||
648
src/qt/qt_newfloppydialog.cpp
Normal file
648
src/qt/qt_newfloppydialog.cpp
Normal file
@@ -0,0 +1,648 @@
|
||||
#include "qt_newfloppydialog.hpp"
|
||||
#include "ui_qt_newfloppydialog.h"
|
||||
|
||||
#include "qt_models_common.hpp"
|
||||
|
||||
extern "C" {
|
||||
#include <86box/random.h>
|
||||
#include <86box/scsi_device.h>
|
||||
#include <86box/zip.h>
|
||||
#include <86box/mo.h>
|
||||
}
|
||||
|
||||
#include <QFile>
|
||||
#include <QFileInfo>
|
||||
#include <QMessageBox>
|
||||
#include <QProgressDialog>
|
||||
#include <thread>
|
||||
|
||||
struct disk_size_t {
|
||||
int hole;
|
||||
int sides;
|
||||
int data_rate;
|
||||
int encoding;
|
||||
int rpm;
|
||||
int tracks;
|
||||
int sectors; /* For IMG and Japanese FDI only. */
|
||||
int sector_len; /* For IMG and Japanese FDI only. */
|
||||
int media_desc;
|
||||
int spc;
|
||||
int num_fats;
|
||||
int spfat;
|
||||
int root_dir_entries;
|
||||
};
|
||||
|
||||
static const disk_size_t disk_sizes[14] = { { 0, 1, 2, 1, 0, 40, 8, 2, 0xfe, 2, 2, 1, 64 }, /* 160k */
|
||||
{ 0, 1, 2, 1, 0, 40, 9, 2, 0xfc, 2, 2, 1, 64 }, /* 180k */
|
||||
{ 0, 2, 2, 1, 0, 40, 8, 2, 0xff, 2, 2, 1, 112 }, /* 320k */
|
||||
{ 0, 2, 2, 1, 0, 40, 9, 2, 0xfd, 2, 2, 2, 112 }, /* 360k */
|
||||
{ 0, 2, 2, 1, 0, 80, 8, 2, 0xfb, 2, 2, 2, 112 }, /* 640k */
|
||||
{ 0, 2, 2, 1, 0, 80, 9, 2, 0xf9, 2, 2, 3, 112 }, /* 720k */
|
||||
{ 1, 2, 0, 1, 1, 80, 15, 2, 0xf9, 1, 2, 7, 224 }, /* 1.2M */
|
||||
{ 1, 2, 0, 1, 1, 77, 8, 3, 0xfe, 1, 2, 2, 192 }, /* 1.25M */
|
||||
{ 1, 2, 0, 1, 0, 80, 18, 2, 0xf0, 1, 2, 9, 224 }, /* 1.44M */
|
||||
{ 1, 2, 0, 1, 0, 80, 21, 2, 0xf0, 2, 2, 5, 16 }, /* DMF cluster 1024 */
|
||||
{ 1, 2, 0, 1, 0, 80, 21, 2, 0xf0, 4, 2, 3, 16 }, /* DMF cluster 2048 */
|
||||
{ 2, 2, 3, 1, 0, 80, 36, 2, 0xf0, 2, 2, 9, 240 }, /* 2.88M */
|
||||
{ 0, 64, 0, 0, 0, 96, 32, 2, 0, 0, 0, 0, 0 }, /* ZIP 100 */
|
||||
{ 0, 64, 0, 0, 0, 239, 32, 2, 0, 0, 0, 0, 0 } }; /* ZIP 250 */
|
||||
|
||||
static const QStringList rpmModes = {
|
||||
"Perfect RPM",
|
||||
"1%% below perfect RPM",
|
||||
"1.5%% below perfect RPM",
|
||||
"2%% below perfect RPM",
|
||||
};
|
||||
|
||||
static const QStringList floppyTypes = {
|
||||
"160 kB",
|
||||
"180 kB",
|
||||
"320 kB",
|
||||
"360 kB",
|
||||
"640 kB",
|
||||
"720 kB",
|
||||
"1.2 MB",
|
||||
"1.25 MB",
|
||||
"1.44 MB",
|
||||
"DMF (cluster 1024)",
|
||||
"DMF (cluster 2048)",
|
||||
"2.88 MB",
|
||||
};
|
||||
|
||||
static const QStringList zipTypes = {
|
||||
"ZIP 100",
|
||||
"ZIP 250",
|
||||
};
|
||||
|
||||
static const QStringList moTypes = {
|
||||
"3.5\" 128Mb M.O. (ISO 10090)",
|
||||
"3.5\" 230Mb M.O. (ISO 13963)",
|
||||
"3.5\" 540Mb M.O. (ISO 15498)",
|
||||
"3.5\" 640Mb M.O. (ISO 15498)",
|
||||
"3.5\" 1.3Gb M.O. (GigaMO)",
|
||||
"3.5\" 2.3Gb M.O. (GigaMO 2)",
|
||||
"5.25\" 600Mb M.O.",
|
||||
"5.25\" 650Mb M.O.",
|
||||
"5.25\" 1Gb M.O.",
|
||||
"5.25\" 1.3Gb M.O.",
|
||||
};
|
||||
|
||||
NewFloppyDialog::NewFloppyDialog(MediaType type, QWidget *parent) :
|
||||
QDialog(parent),
|
||||
ui(new Ui::NewFloppyDialog),
|
||||
mediaType_(type)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
ui->fileField->setCreateFile(true);
|
||||
|
||||
auto* model = ui->comboBoxSize->model();
|
||||
switch (type) {
|
||||
case MediaType::Floppy:
|
||||
for (int i = 0; i < floppyTypes.size(); ++i) {
|
||||
Models::AddEntry(model, floppyTypes[i], i);
|
||||
}
|
||||
break;
|
||||
case MediaType::Zip:
|
||||
for (int i = 0; i < zipTypes.size(); ++i) {
|
||||
Models::AddEntry(model, zipTypes[i], i);
|
||||
}
|
||||
break;
|
||||
case MediaType::Mo:
|
||||
for (int i = 0; i < moTypes.size(); ++i) {
|
||||
Models::AddEntry(model, moTypes[i], i);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
model = ui->comboBoxRpm->model();
|
||||
for (int i = 0; i < rpmModes.size(); ++i) {
|
||||
Models::AddEntry(model, rpmModes[i], i);
|
||||
}
|
||||
|
||||
connect(ui->fileField, &FileField::fileSelected, this, [this](const QString& filename) {
|
||||
bool hide = true;
|
||||
if (mediaType_ == MediaType::Floppy) {
|
||||
if (QFileInfo(filename).suffix().toLower() == QStringLiteral("86f")) {
|
||||
hide = false;
|
||||
}
|
||||
}
|
||||
|
||||
ui->labelRpm->setHidden(hide);
|
||||
ui->comboBoxRpm->setHidden(hide);
|
||||
});
|
||||
connect(ui->buttonBox, &QDialogButtonBox::accepted, this, &NewFloppyDialog::onCreate);
|
||||
|
||||
ui->labelRpm->setHidden(true);
|
||||
ui->comboBoxRpm->setHidden(true);
|
||||
}
|
||||
|
||||
NewFloppyDialog::~NewFloppyDialog() {
|
||||
delete ui;
|
||||
}
|
||||
|
||||
QString NewFloppyDialog::fileName() const{
|
||||
return ui->fileField->fileName();
|
||||
}
|
||||
|
||||
void NewFloppyDialog::onCreate() {
|
||||
auto filename = ui->fileField->fileName();
|
||||
QFileInfo fi(filename);
|
||||
FileType fileType;
|
||||
|
||||
QProgressDialog progress("Creating floppy image", QString(), 0, 100, this);
|
||||
connect(this, &NewFloppyDialog::fileProgress, &progress, &QProgressDialog::setValue);
|
||||
switch (mediaType_) {
|
||||
case MediaType::Floppy:
|
||||
if (fi.suffix().toLower() == QStringLiteral("86f")) {
|
||||
if (create86f(filename, disk_sizes[ui->comboBoxSize->currentIndex()], ui->comboBoxRpm->currentIndex())) {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
fileType = fi.suffix().toLower() == QStringLiteral("zdi") ? FileType::Fdi : FileType::Img;
|
||||
if (createSectorImage(filename, disk_sizes[ui->comboBoxSize->currentIndex()], fileType)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case MediaType::Zip:
|
||||
{
|
||||
fileType = fi.suffix().toLower() == QStringLiteral("zdi") ? FileType::Zdi: FileType::Img;
|
||||
|
||||
std::atomic_bool res;
|
||||
std::thread t([this, &res, filename, fileType, &progress] {
|
||||
res = createZipSectorImage(filename, disk_sizes[ui->comboBoxSize->currentIndex() + 12], fileType, progress);
|
||||
});
|
||||
progress.exec();
|
||||
t.join();
|
||||
|
||||
if (res) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case MediaType::Mo:
|
||||
{
|
||||
fileType = fi.suffix().toLower() == QStringLiteral("mdi") ? FileType::Mdi: FileType::Img;
|
||||
|
||||
std::atomic_bool res;
|
||||
std::thread t([this, &res, filename, fileType, &progress] {
|
||||
res = createMoSectorImage(filename, ui->comboBoxSize->currentIndex(), fileType, progress);
|
||||
});
|
||||
progress.exec();
|
||||
t.join();
|
||||
|
||||
if (res) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
QMessageBox::critical(this, "Unable to write file", "Make sure the file is being saved to a writable directory");
|
||||
reject();
|
||||
}
|
||||
|
||||
bool NewFloppyDialog::create86f(const QString& filename, const disk_size_t& disk_size, uint8_t rpm_mode)
|
||||
{
|
||||
uint32_t magic = 0x46423638;
|
||||
uint16_t version = 0x020C;
|
||||
uint16_t dflags = 0;
|
||||
uint16_t tflags = 0;
|
||||
uint32_t index_hole_pos = 0;
|
||||
uint32_t tarray[512];
|
||||
uint32_t array_size;
|
||||
uint32_t track_base, track_size;
|
||||
int i;
|
||||
uint32_t shift = 0;
|
||||
|
||||
dflags = 0; /* Has surface data? - Assume no for now. */
|
||||
dflags |= (disk_size.hole << 1); /* Hole */
|
||||
dflags |= ((disk_size.sides - 1) << 3); /* Sides. */
|
||||
dflags |= (0 << 4); /* Write protect? - Assume no for now. */
|
||||
dflags |= (rpm_mode << 5); /* RPM mode. */
|
||||
dflags |= (0 << 7); /* Has extra bit cells? - Assume no for now. */
|
||||
|
||||
tflags = disk_size.data_rate; /* Data rate. */
|
||||
tflags |= (disk_size.encoding << 3); /* Encoding. */
|
||||
tflags |= (disk_size.rpm << 5); /* RPM. */
|
||||
|
||||
switch (disk_size.hole) {
|
||||
case 0:
|
||||
case 1:
|
||||
default:
|
||||
switch(rpm_mode) {
|
||||
case 1:
|
||||
array_size = 25250;
|
||||
break;
|
||||
case 2:
|
||||
array_size = 25374;
|
||||
break;
|
||||
case 3:
|
||||
array_size = 25750;
|
||||
break;
|
||||
default:
|
||||
array_size = 25000;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
switch(rpm_mode) {
|
||||
case 1:
|
||||
array_size = 50500;
|
||||
break;
|
||||
case 2:
|
||||
array_size = 50750;
|
||||
break;
|
||||
case 3:
|
||||
array_size = 51000;
|
||||
break;
|
||||
default:
|
||||
array_size = 50000;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
QByteArray bytes(array_size, 0);
|
||||
memset(tarray, 0, 2048);
|
||||
|
||||
QFile file(filename);
|
||||
if (! file.open(QIODevice::WriteOnly)) {
|
||||
return false;
|
||||
}
|
||||
QDataStream stream(&file);
|
||||
|
||||
stream << magic;
|
||||
stream << version;
|
||||
stream << dflags;
|
||||
|
||||
track_size = array_size + 6;
|
||||
track_base = 8 + ((disk_size.sides == 2) ? 2048 : 1024);
|
||||
|
||||
if (disk_size.tracks <= 43)
|
||||
shift = 1;
|
||||
|
||||
for (i = 0; i < (disk_size.tracks * disk_size.sides) << shift; i++)
|
||||
tarray[i] = track_base + (i * track_size);
|
||||
|
||||
stream.writeRawData(reinterpret_cast<const char *>(tarray), (disk_size.sides == 2) ? 2048 : 1024);
|
||||
|
||||
int max = i < (disk_size.tracks * disk_size.sides) << shift;
|
||||
for (i = 0; i < max; i++) {
|
||||
stream << tflags;
|
||||
stream << index_hole_pos;
|
||||
stream.writeRawData(bytes, bytes.size());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NewFloppyDialog::createSectorImage(const QString &filename, const disk_size_t& disk_size, FileType type)
|
||||
{
|
||||
uint32_t total_size = 0;
|
||||
uint32_t total_sectors = 0;
|
||||
uint32_t sector_bytes = 0;
|
||||
uint32_t root_dir_bytes = 0;
|
||||
uint32_t fat_size = 0;
|
||||
uint32_t fat1_offs = 0;
|
||||
uint32_t fat2_offs = 0;
|
||||
uint32_t zero_bytes = 0;
|
||||
uint16_t base = 0x1000;
|
||||
|
||||
QFile file(filename);
|
||||
if (! file.open(QIODevice::WriteOnly)) {
|
||||
return false;
|
||||
}
|
||||
QDataStream stream(&file);
|
||||
|
||||
sector_bytes = (128 << disk_size.sector_len);
|
||||
total_sectors = disk_size.sides * disk_size.tracks * disk_size.sectors;
|
||||
if (total_sectors > ZIP_SECTORS)
|
||||
total_sectors = ZIP_250_SECTORS;
|
||||
total_size = total_sectors * sector_bytes;
|
||||
root_dir_bytes = (disk_size.root_dir_entries << 5);
|
||||
fat_size = (disk_size.spfat * sector_bytes);
|
||||
fat1_offs = sector_bytes;
|
||||
fat2_offs = fat1_offs + fat_size;
|
||||
zero_bytes = fat2_offs + fat_size + root_dir_bytes;
|
||||
|
||||
if (type == FileType::Fdi) {
|
||||
QByteArray bytes(base, 0);
|
||||
auto empty = bytes.data();
|
||||
*(uint32_t *) &(empty[0x08]) = (uint32_t) base;
|
||||
*(uint32_t *) &(empty[0x0C]) = total_size;
|
||||
*(uint16_t *) &(empty[0x10]) = (uint16_t) sector_bytes;
|
||||
*(uint8_t *) &(empty[0x14]) = (uint8_t) disk_size.sectors;
|
||||
*(uint8_t *) &(empty[0x18]) = (uint8_t) disk_size.sides;
|
||||
*(uint8_t *) &(empty[0x1C]) = (uint8_t) disk_size.tracks;
|
||||
stream.writeRawData(empty, base);
|
||||
}
|
||||
|
||||
QByteArray bytes(total_size, 0);
|
||||
auto empty = bytes.data();
|
||||
|
||||
memset(empty + zero_bytes, 0xF6, total_size - zero_bytes);
|
||||
|
||||
empty[0x00] = 0xEB; /* Jump to make MS-DOS happy. */
|
||||
empty[0x01] = 0x58;
|
||||
empty[0x02] = 0x90;
|
||||
|
||||
empty[0x03] = 0x38; /* '86BOX5.0' OEM ID. */
|
||||
empty[0x04] = 0x36;
|
||||
empty[0x05] = 0x42;
|
||||
empty[0x06] = 0x4F;
|
||||
empty[0x07] = 0x58;
|
||||
empty[0x08] = 0x35;
|
||||
empty[0x09] = 0x2E;
|
||||
empty[0x0A] = 0x30;
|
||||
|
||||
*(uint16_t *) &(empty[0x0B]) = (uint16_t) sector_bytes;
|
||||
*(uint8_t *) &(empty[0x0D]) = (uint8_t) disk_size.spc;
|
||||
*(uint16_t *) &(empty[0x0E]) = (uint16_t) 1;
|
||||
*(uint8_t *) &(empty[0x10]) = (uint8_t) disk_size.num_fats;
|
||||
*(uint16_t *) &(empty[0x11]) = (uint16_t) disk_size.root_dir_entries;
|
||||
*(uint16_t *) &(empty[0x13]) = (uint16_t) total_sectors;
|
||||
*(uint8_t *) &(empty[0x15]) = (uint8_t) disk_size.media_desc;
|
||||
*(uint16_t *) &(empty[0x16]) = (uint16_t) disk_size.spfat;
|
||||
*(uint8_t *) &(empty[0x18]) = (uint8_t) disk_size.sectors;
|
||||
*(uint8_t *) &(empty[0x1A]) = (uint8_t) disk_size.sides;
|
||||
|
||||
empty[0x26] = 0x29; /* ')' followed by randomly-generated volume serial number. */
|
||||
empty[0x27] = random_generate();
|
||||
empty[0x28] = random_generate();
|
||||
empty[0x29] = random_generate();
|
||||
empty[0x2A] = random_generate();
|
||||
|
||||
memset(&(empty[0x2B]), 0x20, 11);
|
||||
|
||||
empty[0x36] = 'F';
|
||||
empty[0x37] = 'A';
|
||||
empty[0x38] = 'T';
|
||||
empty[0x39] = '1';
|
||||
empty[0x3A] = '2';
|
||||
memset(&(empty[0x3B]), 0x20, 0x0003);
|
||||
|
||||
empty[0x1FE] = 0x55;
|
||||
empty[0x1FF] = 0xAA;
|
||||
|
||||
empty[fat1_offs + 0x00] = empty[fat2_offs + 0x00] = empty[0x15];
|
||||
empty[fat1_offs + 0x01] = empty[fat2_offs + 0x01] = 0xFF;
|
||||
empty[fat1_offs + 0x02] = empty[fat2_offs + 0x02] = 0xFF;
|
||||
|
||||
stream.writeRawData(empty, total_size);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NewFloppyDialog::createZipSectorImage(const QString &filename, const disk_size_t& disk_size, FileType type, QProgressDialog& pbar)
|
||||
{
|
||||
uint32_t total_size = 0;
|
||||
uint32_t total_sectors = 0;
|
||||
uint32_t sector_bytes = 0;
|
||||
uint32_t root_dir_bytes = 0;
|
||||
uint32_t fat_size = 0;
|
||||
uint32_t fat1_offs = 0;
|
||||
uint32_t fat2_offs = 0;
|
||||
uint32_t zero_bytes = 0;
|
||||
uint16_t base = 0x1000;
|
||||
uint32_t pbar_max = 0;
|
||||
|
||||
QFile file(filename);
|
||||
if (! file.open(QIODevice::WriteOnly)) {
|
||||
return false;
|
||||
}
|
||||
QDataStream stream(&file);
|
||||
|
||||
sector_bytes = (128 << disk_size.sector_len);
|
||||
total_sectors = disk_size.sides * disk_size.tracks * disk_size.sectors;
|
||||
if (total_sectors > ZIP_SECTORS)
|
||||
total_sectors = ZIP_250_SECTORS;
|
||||
total_size = total_sectors * sector_bytes;
|
||||
root_dir_bytes = (disk_size.root_dir_entries << 5);
|
||||
fat_size = (disk_size.spfat * sector_bytes);
|
||||
fat1_offs = sector_bytes;
|
||||
fat2_offs = fat1_offs + fat_size;
|
||||
zero_bytes = fat2_offs + fat_size + root_dir_bytes;
|
||||
|
||||
pbar_max = total_size;
|
||||
if (type == FileType::Zdi) {
|
||||
pbar_max += base;
|
||||
}
|
||||
pbar_max >>= 11;
|
||||
|
||||
if (type == FileType::Zdi) {
|
||||
QByteArray data(base, 0);
|
||||
auto empty = data.data();
|
||||
|
||||
*(uint32_t *) &(empty[0x08]) = (uint32_t) base;
|
||||
*(uint32_t *) &(empty[0x0C]) = total_size;
|
||||
*(uint16_t *) &(empty[0x10]) = (uint16_t) sector_bytes;
|
||||
*(uint8_t *) &(empty[0x14]) = (uint8_t) disk_size.sectors;
|
||||
*(uint8_t *) &(empty[0x18]) = (uint8_t) disk_size.sides;
|
||||
*(uint8_t *) &(empty[0x1C]) = (uint8_t) disk_size.tracks;
|
||||
|
||||
stream.writeRawData(empty, base);
|
||||
pbar_max -= 2;
|
||||
}
|
||||
|
||||
QByteArray bytes(total_size, 0);
|
||||
auto empty = bytes.data();
|
||||
|
||||
if (total_sectors == ZIP_SECTORS) {
|
||||
/* ZIP 100 */
|
||||
/* MBR */
|
||||
*(uint64_t *) &(empty[0x0000]) = 0x2054524150492EEBLL;
|
||||
*(uint64_t *) &(empty[0x0008]) = 0x3930302065646F63LL;
|
||||
*(uint64_t *) &(empty[0x0010]) = 0x67656D6F49202D20LL;
|
||||
*(uint64_t *) &(empty[0x0018]) = 0x726F70726F432061LL;
|
||||
*(uint64_t *) &(empty[0x0020]) = 0x202D206E6F697461LL;
|
||||
*(uint64_t *) &(empty[0x0028]) = 0x30392F33322F3131LL;
|
||||
|
||||
*(uint64_t *) &(empty[0x01AE]) = 0x0116010100E90644LL;
|
||||
*(uint64_t *) &(empty[0x01B6]) = 0xED08BBE5014E0135LL;
|
||||
*(uint64_t *) &(empty[0x01BE]) = 0xFFFFFE06FFFFFE80LL;
|
||||
*(uint64_t *) &(empty[0x01C6]) = 0x0002FFE000000020LL;
|
||||
|
||||
*(uint16_t *) &(empty[0x01FE]) = 0xAA55;
|
||||
|
||||
/* 31 sectors filled with 0x48 */
|
||||
memset(&(empty[0x0200]), 0x48, 0x3E00);
|
||||
|
||||
/* Boot sector */
|
||||
*(uint64_t *) &(empty[0x4000]) = 0x584F4236389058EBLL;
|
||||
*(uint64_t *) &(empty[0x4008]) = 0x0008040200302E35LL;
|
||||
*(uint64_t *) &(empty[0x4010]) = 0x00C0F80000020002LL;
|
||||
*(uint64_t *) &(empty[0x4018]) = 0x0000002000FF003FLL;
|
||||
*(uint32_t *) &(empty[0x4020]) = 0x0002FFE0;
|
||||
*(uint16_t *) &(empty[0x4024]) = 0x0080;
|
||||
|
||||
empty[0x4026] = 0x29; /* ')' followed by randomly-generated volume serial number. */
|
||||
empty[0x4027] = random_generate();
|
||||
empty[0x4028] = random_generate();
|
||||
empty[0x4029] = random_generate();
|
||||
empty[0x402A] = random_generate();
|
||||
|
||||
memset(&(empty[0x402B]), 0x00, 0x000B);
|
||||
memset(&(empty[0x4036]), 0x20, 0x0008);
|
||||
|
||||
empty[0x4036] = 'F';
|
||||
empty[0x4037] = 'A';
|
||||
empty[0x4038] = 'T';
|
||||
empty[0x4039] = '1';
|
||||
empty[0x403A] = '6';
|
||||
memset(&(empty[0x403B]), 0x20, 0x0003);
|
||||
|
||||
empty[0x41FE] = 0x55;
|
||||
empty[0x41FF] = 0xAA;
|
||||
|
||||
empty[0x5000] = empty[0x1D000] = empty[0x4015];
|
||||
empty[0x5001] = empty[0x1D001] = 0xFF;
|
||||
empty[0x5002] = empty[0x1D002] = 0xFF;
|
||||
empty[0x5003] = empty[0x1D003] = 0xFF;
|
||||
|
||||
/* Root directory = 0x35000
|
||||
Data = 0x39000 */
|
||||
} else {
|
||||
/* ZIP 250 */
|
||||
/* MBR */
|
||||
*(uint64_t *) &(empty[0x0000]) = 0x2054524150492EEBLL;
|
||||
*(uint64_t *) &(empty[0x0008]) = 0x3930302065646F63LL;
|
||||
*(uint64_t *) &(empty[0x0010]) = 0x67656D6F49202D20LL;
|
||||
*(uint64_t *) &(empty[0x0018]) = 0x726F70726F432061LL;
|
||||
*(uint64_t *) &(empty[0x0020]) = 0x202D206E6F697461LL;
|
||||
*(uint64_t *) &(empty[0x0028]) = 0x30392F33322F3131LL;
|
||||
|
||||
*(uint64_t *) &(empty[0x01AE]) = 0x0116010100E900E9LL;
|
||||
*(uint64_t *) &(empty[0x01B6]) = 0x2E32A7AC014E0135LL;
|
||||
|
||||
*(uint64_t *) &(empty[0x01EE]) = 0xEE203F0600010180LL;
|
||||
*(uint64_t *) &(empty[0x01F6]) = 0x000777E000000020LL;
|
||||
*(uint16_t *) &(empty[0x01FE]) = 0xAA55;
|
||||
|
||||
/* 31 sectors filled with 0x48 */
|
||||
memset(&(empty[0x0200]), 0x48, 0x3E00);
|
||||
|
||||
/* The second sector begins with some strange data
|
||||
in my reference image. */
|
||||
*(uint64_t *) &(empty[0x0200]) = 0x3831393230334409LL;
|
||||
*(uint64_t *) &(empty[0x0208]) = 0x6A57766964483130LL;
|
||||
*(uint64_t *) &(empty[0x0210]) = 0x3C3A34676063653FLL;
|
||||
*(uint64_t *) &(empty[0x0218]) = 0x586A56A8502C4161LL;
|
||||
*(uint64_t *) &(empty[0x0220]) = 0x6F2D702535673D6CLL;
|
||||
*(uint64_t *) &(empty[0x0228]) = 0x255421B8602D3456LL;
|
||||
*(uint64_t *) &(empty[0x0230]) = 0x577B22447B52603ELL;
|
||||
*(uint64_t *) &(empty[0x0238]) = 0x46412CC871396170LL;
|
||||
*(uint64_t *) &(empty[0x0240]) = 0x704F55237C5E2626LL;
|
||||
*(uint64_t *) &(empty[0x0248]) = 0x6C7932C87D5C3C20LL;
|
||||
*(uint64_t *) &(empty[0x0250]) = 0x2C50503E47543D6ELL;
|
||||
*(uint64_t *) &(empty[0x0258]) = 0x46394E807721536ALL;
|
||||
*(uint64_t *) &(empty[0x0260]) = 0x505823223F245325LL;
|
||||
*(uint64_t *) &(empty[0x0268]) = 0x365C79B0393B5B6ELL;
|
||||
|
||||
/* Boot sector */
|
||||
*(uint64_t *) &(empty[0x4000]) = 0x584F4236389058EBLL;
|
||||
*(uint64_t *) &(empty[0x4008]) = 0x0001080200302E35LL;
|
||||
*(uint64_t *) &(empty[0x4010]) = 0x00EFF80000020002LL;
|
||||
*(uint64_t *) &(empty[0x4018]) = 0x0000002000400020LL;
|
||||
*(uint32_t *) &(empty[0x4020]) = 0x000777E0;
|
||||
*(uint16_t *) &(empty[0x4024]) = 0x0080;
|
||||
|
||||
empty[0x4026] = 0x29; /* ')' followed by randomly-generated volume serial number. */
|
||||
empty[0x4027] = random_generate();
|
||||
empty[0x4028] = random_generate();
|
||||
empty[0x4029] = random_generate();
|
||||
empty[0x402A] = random_generate();
|
||||
|
||||
memset(&(empty[0x402B]), 0x00, 0x000B);
|
||||
memset(&(empty[0x4036]), 0x20, 0x0008);
|
||||
|
||||
empty[0x4036] = 'F';
|
||||
empty[0x4037] = 'A';
|
||||
empty[0x4038] = 'T';
|
||||
empty[0x4039] = '1';
|
||||
empty[0x403A] = '6';
|
||||
memset(&(empty[0x403B]), 0x20, 0x0003);
|
||||
|
||||
empty[0x41FE] = 0x55;
|
||||
empty[0x41FF] = 0xAA;
|
||||
|
||||
empty[0x4200] = empty[0x22000] = empty[0x4015];
|
||||
empty[0x4201] = empty[0x22001] = 0xFF;
|
||||
empty[0x4202] = empty[0x22002] = 0xFF;
|
||||
empty[0x4203] = empty[0x22003] = 0xFF;
|
||||
|
||||
/* Root directory = 0x3FE00
|
||||
Data = 0x38200 */
|
||||
}
|
||||
|
||||
pbar.setMaximum(pbar_max);
|
||||
for (uint32_t i = 0; i < pbar_max; i++) {
|
||||
stream.writeRawData(&empty[i << 11], 2048);
|
||||
fileProgress(i);
|
||||
}
|
||||
fileProgress(pbar_max);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool NewFloppyDialog::createMoSectorImage(const QString& filename, int8_t disk_size, FileType type, QProgressDialog& pbar)
|
||||
{
|
||||
const mo_type_t *dp = &mo_types[disk_size];
|
||||
uint32_t total_size = 0, total_size2;
|
||||
uint32_t total_sectors = 0;
|
||||
uint32_t sector_bytes = 0;
|
||||
uint16_t base = 0x1000;
|
||||
uint32_t pbar_max = 0, blocks_num;
|
||||
|
||||
QFile file(filename);
|
||||
if (! file.open(QIODevice::WriteOnly)) {
|
||||
return false;
|
||||
}
|
||||
QDataStream stream(&file);
|
||||
|
||||
sector_bytes = dp->bytes_per_sector;
|
||||
total_sectors = dp->sectors;
|
||||
total_size = total_sectors * sector_bytes;
|
||||
|
||||
total_size2 = (total_size >> 20) << 20;
|
||||
total_size2 = total_size - total_size2;
|
||||
|
||||
pbar_max = total_size;
|
||||
pbar_max >>= 20;
|
||||
blocks_num = pbar_max;
|
||||
if (type == FileType::Mdi)
|
||||
pbar_max++;
|
||||
if (total_size2 == 0)
|
||||
pbar_max++;
|
||||
|
||||
if (type == FileType::Mdi) {
|
||||
QByteArray bytes(base, 0);
|
||||
auto empty = bytes.data();
|
||||
|
||||
*(uint32_t *) &(empty[0x08]) = (uint32_t) base;
|
||||
*(uint32_t *) &(empty[0x0C]) = total_size;
|
||||
*(uint16_t *) &(empty[0x10]) = (uint16_t) sector_bytes;
|
||||
*(uint8_t *) &(empty[0x14]) = (uint8_t) 25;
|
||||
*(uint8_t *) &(empty[0x18]) = (uint8_t) 64;
|
||||
*(uint8_t *) &(empty[0x1C]) = (uint8_t) (dp->sectors / 64) / 25;
|
||||
|
||||
stream.writeRawData(empty, base);
|
||||
}
|
||||
|
||||
QByteArray bytes(1048576, 0);
|
||||
auto empty = bytes.data();
|
||||
|
||||
pbar.setMaximum(blocks_num);
|
||||
for (uint32_t i = 0; i < blocks_num; i++) {
|
||||
stream.writeRawData(empty, bytes.size());
|
||||
fileProgress(i);
|
||||
}
|
||||
|
||||
if (total_size2 > 0) {
|
||||
QByteArray extra_bytes(total_size2, 0);
|
||||
stream.writeRawData(extra_bytes.data(), total_size2);
|
||||
}
|
||||
fileProgress(blocks_num);
|
||||
|
||||
return true;
|
||||
}
|
||||
50
src/qt/qt_newfloppydialog.hpp
Normal file
50
src/qt/qt_newfloppydialog.hpp
Normal file
@@ -0,0 +1,50 @@
|
||||
#ifndef QT_NEWFLOPPYDIALOG_HPP
|
||||
#define QT_NEWFLOPPYDIALOG_HPP
|
||||
|
||||
#include <QDialog>
|
||||
|
||||
namespace Ui {
|
||||
class NewFloppyDialog;
|
||||
}
|
||||
|
||||
struct disk_size_t;
|
||||
class QProgressDialog;
|
||||
|
||||
class NewFloppyDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
enum class MediaType {
|
||||
Floppy,
|
||||
Zip,
|
||||
Mo,
|
||||
};
|
||||
enum class FileType {
|
||||
Img,
|
||||
Fdi,
|
||||
Zdi,
|
||||
Mdi,
|
||||
};
|
||||
explicit NewFloppyDialog(MediaType type, QWidget *parent = nullptr);
|
||||
~NewFloppyDialog();
|
||||
|
||||
QString fileName() const;
|
||||
|
||||
signals:
|
||||
void fileProgress(int i);
|
||||
|
||||
private slots:
|
||||
void onCreate();
|
||||
|
||||
private:
|
||||
Ui::NewFloppyDialog *ui;
|
||||
MediaType mediaType_;
|
||||
|
||||
bool create86f(const QString& filename, const disk_size_t& disk_size, uint8_t rpm_mode);
|
||||
bool createSectorImage(const QString& filename, const disk_size_t& disk_size, FileType type);
|
||||
bool createZipSectorImage(const QString& filename, const disk_size_t& disk_size, FileType type, QProgressDialog& pbar);
|
||||
bool createMoSectorImage(const QString& filename, int8_t disk_size, FileType type, QProgressDialog& pbar);
|
||||
};
|
||||
|
||||
#endif // QT_NEWFLOPPYDIALOG_HPP
|
||||
115
src/qt/qt_newfloppydialog.ui
Normal file
115
src/qt/qt_newfloppydialog.ui
Normal file
@@ -0,0 +1,115 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>NewFloppyDialog</class>
|
||||
<widget class="QDialog" name="NewFloppyDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>287</width>
|
||||
<height>140</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>New Image</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="2" column="1">
|
||||
<widget class="QComboBox" name="comboBoxSize"/>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="5" column="0" colspan="2">
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>File Name</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Disk Size</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="FileField" name="fileField" native="true"/>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="labelRpm">
|
||||
<property name="text">
|
||||
<string>RPM Mode</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QComboBox" name="comboBoxRpm"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>FileField</class>
|
||||
<extends>QWidget</extends>
|
||||
<header>qt_filefield.hpp</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources/>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>accepted()</signal>
|
||||
<receiver>NewFloppyDialog</receiver>
|
||||
<slot>accept()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>248</x>
|
||||
<y>254</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>157</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>rejected()</signal>
|
||||
<receiver>NewFloppyDialog</receiver>
|
||||
<slot>reject()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>316</x>
|
||||
<y>260</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>286</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
</ui>
|
||||
@@ -91,7 +91,7 @@ ui_sb_update_panes() {
|
||||
}
|
||||
|
||||
void ui_sb_bugui(char *str) {
|
||||
main_window->statusBar()->showMessage(str);
|
||||
main_window->statusBarMessage(str);
|
||||
}
|
||||
|
||||
void ui_sb_set_ready(int ready) {
|
||||
|
||||
Reference in New Issue
Block a user