2016-12-06 02:12:44 +00:00
# include "mainwindow.h"
# include "ui_mainwindow.h"
# include "qfiledialog.h"
# include "qprocess.h"
# include "qdebug.h"
# include "qtimer.h"
# include "qmessagebox.h"
2017-01-15 22:39:11 +00:00
# include "qinputdialog.h"
2017-02-04 05:33:30 +00:00
# include "qformlayout.h"
# include "qdialogbuttonbox.h"
2016-12-06 02:45:11 +00:00
const QString MainWindow : : programName = QString ( " buckshot " ) ;
2019-12-17 02:21:28 +00:00
const QString MainWindow : : version = QString ( " 0.05 " ) ;
2016-12-06 02:12:44 +00:00
const QString MainWindow : : imageName = QString ( " saved " ) ;
MainWindow : : MainWindow ( QWidget * parent ) :
QMainWindow ( parent ) ,
ui ( new Ui : : MainWindow )
{
ui - > setupUi ( this ) ;
2016-12-06 02:45:11 +00:00
// Window Title
this - > setWindowTitle ( QString ( " %1 v%2 " ) . arg ( programName , version ) ) ;
2016-12-06 02:12:44 +00:00
// SET TEMP DIR FOR CACHE/BUILDING
tmpDir = new QTemporaryDir ( ) ;
if ( tmpDir - > isValid ( ) ) {
tmpDirPath = tmpDir - > path ( ) ; // dir.path() returns the unique directory path
} else {
tmpDirPath = " /tmp/ " ; // fallback. may not work on all OSes
}
2016-12-06 02:45:11 +00:00
// AND NOW THE PATHNAMES FOR OUR CACHE FILES
2016-12-06 02:12:44 +00:00
inputImgPath = QString ( " %1/%2.bmp " ) . arg ( tmpDirPath ) . arg ( imageName ) ;
previewImgPath = QString ( " %1/%2_Preview.bmp " ) . arg ( tmpDirPath ) . arg ( imageName ) ;
2016-12-06 02:45:11 +00:00
// POPULATE FORMAT COMBOBOX
2016-12-06 02:12:44 +00:00
QStringList outputFormats ;
outputFormats < < " LR " < < " DLR " < < " HGR " < < " DHGR " < < " MONO " ;
ui - > comboBox_outputFormat - > addItems ( outputFormats ) ;
2016-12-06 02:45:11 +00:00
// POPULATE RESOLUTION COMBOBOX
2016-12-06 02:12:44 +00:00
QStringList inputResolutions ;
inputResolutions < < " 40 x 48 - Full Scale LGR "
2017-02-05 04:20:35 +00:00
< < " 80 x 48 - Full Scale DLGR "
< < " 140 x 192 - Full Scale (HGR & DHGR) "
< < " 280 x 192 - Double Width Scale (HGR & DHGR) "
< < " 320 x 200 - Classic Size "
< < " 560 x 384 - Quadruple Width, Double Height Scale "
< < " 640 x 400 - Classic Size "
< < " 640 x 480 - Classic Size " ;
2016-12-06 02:12:44 +00:00
ui - > comboBox_inputResolution - > addItems ( inputResolutions ) ;
2017-02-04 05:33:30 +00:00
// POPULATE DITHERING COMBOBOX
QStringList ditheringAlgorithms ;
ditheringAlgorithms < < " Default "
< < " 1- Floyd-Steinberg "
< < " 2- Jarvis "
< < " 3- Stucki "
< < " 4- Atkinson "
< < " 5- Burkes "
< < " 6- Sierra "
< < " 7- Sierra Two "
< < " 8- Sierra Lite "
< < " 9- Buckels " ;
ui - > comboBox_dithering - > addItems ( ditheringAlgorithms ) ;
2018-12-28 15:52:41 +00:00
// POPULATE PALETTE COMBOBOX
QStringList previewPalettes ;
previewPalettes < < " Kegs32 RGB "
< < " CiderPress RGB "
< < " Old AppleWin NTSC "
< < " New AppleWin NTSC "
< < " Wikipedia NTSC "
< < " tohgr NTSC DHGR "
< < " (N/A) -- Imported "
< < " Legacy Canvas "
< < " Legacy Win16 "
< < " Legacy Win32 "
< < " Legacy VGA BIOS "
< < " Legacy VGA PCX "
< < " Super Convert RGB "
< < " Jace NTSC "
< < " Cybernesto-Munafo NTSC "
< < " Pseudo Palette "
< < " tohgr NTSC HGR " ;
ui - > comboBox_previewPalette - > addItems ( previewPalettes ) ;
2016-12-06 02:45:11 +00:00
// HANDLE DISPLAY MODE SELECTION (COMPATIBILITY)
2016-12-06 02:12:44 +00:00
updateDisplayModes ( ) ;
// live preview stuff
updateNeeded = false ;
previewTimer = new QTimer ( this ) ;
connect ( previewTimer , SIGNAL ( timeout ( ) ) , this , SLOT ( previewTimerTimeout ( ) ) ) ;
2019-12-17 02:21:28 +00:00
// decided to enable by checking in the form and calling this.
on_checkBox_livePreview_stateChanged ( 1 ) ;
2016-12-06 02:12:44 +00:00
}
2018-12-28 15:52:41 +00:00
MainWindow : : ~ MainWindow ( )
{
delete ui ;
}
2018-12-28 17:04:40 +00:00
bool MainWindow : : check_canPreview ( )
{
if ( ui - > label_source - > pixmap ( ) = = nullptr ) {
ui - > plainTextEdit_lastCmd - > setPlainText ( " Please open a source image to run a preview! " ) ;
repaint ( ) ;
return false ;
}
return true ;
}
bool MainWindow : : check_canSave ( )
{
if ( ui - > label_preview - > pixmap ( ) = = nullptr ) {
ui - > plainTextEdit_lastCmd - > setPlainText ( " Please open a source image and run a preview first! " ) ;
repaint ( ) ;
return false ;
}
return true ;
}
2016-12-06 02:12:44 +00:00
void MainWindow : : updateDisplayModes ( ) {
2016-12-06 02:45:11 +00:00
QList < int > disabledList = QList < int > ( ) ;
2016-12-06 02:12:44 +00:00
2018-12-28 15:52:41 +00:00
//---- display modes
// 0 "40 x 48 - Full Scale LGR (LGR ONLY)"
// 1 "80 x 48 - Full Scale DLGR (DLGR ONLY)"
// 2 "140 x 192 - Full Scale (HGR & DHGR)"
// 3 "280 x 192 - Double Width Scale (HGR & DHGR)"
// 4 "320 x 200 - Classic Size"
// 5 "560 x 384 - Quadruple Width, Double Height Scale"
// 6 "640 x 400 - Classic Size"
// 7 "640 x 480 - Classic Size";
2016-12-06 02:12:44 +00:00
// Enable all first
QList < int > enabledList = QList < int > ( ) < < 0 < < 1 < < 2 < < 3 < < 4 < < 5 < < 6 < < 7 ;
QListIterator < int > e ( enabledList ) ;
while ( e . hasNext ( ) ) {
// Get the index of the value to disable
QModelIndex index = ui - > comboBox_inputResolution - > model ( ) - > index ( e . next ( ) , 0 ) ;
// enable flag
QVariant vEnable ( 1 | 32 ) ;
// the magic
ui - > comboBox_inputResolution - > model ( ) - > setData ( index , vEnable , Qt : : UserRole - 1 ) ;
}
2016-12-06 02:45:11 +00:00
// SET DISABLED ITEMS LIST - AND DEFAULT RESOLUTION FOR MODE
2016-12-06 02:12:44 +00:00
if ( ui - > comboBox_outputFormat - > currentText ( ) = = " LR " ) {
disabledList < < 2 < < 3 ;
inputWidth = 40 ;
inputHeight = 48 ;
ui - > comboBox_inputResolution - > setCurrentIndex ( 0 ) ;
} else if ( ui - > comboBox_outputFormat - > currentText ( ) = = " DLR " ) {
disabledList < < 2 < < 3 ;
inputWidth = 80 ;
inputHeight = 48 ;
ui - > comboBox_inputResolution - > setCurrentIndex ( 1 ) ;
} else if ( ui - > comboBox_outputFormat - > currentText ( ) = = " MONO " ) {
disabledList < < 0 < < 1 < < 2 < < 4 < < 6 < < 7 ;
inputWidth = 280 ;
inputHeight = 192 ;
ui - > comboBox_inputResolution - > setCurrentIndex ( 3 ) ;
} else if ( ui - > comboBox_outputFormat - > currentText ( ) = = " DHGR " ) {
inputWidth = 280 ;
inputHeight = 192 ;
ui - > comboBox_inputResolution - > setCurrentIndex ( 3 ) ;
} else {
inputWidth = 140 ;
inputHeight = 192 ;
ui - > comboBox_inputResolution - > setCurrentIndex ( 2 ) ;
}
2016-12-06 02:45:11 +00:00
// NOW ACTUALLY DISABLE INVALID RESOLUTIONS IN THE COMBOBOX
2016-12-06 02:12:44 +00:00
QListIterator < int > d ( disabledList ) ;
while ( d . hasNext ( ) ) {
// Get the index of the value to disable
QModelIndex index = ui - > comboBox_inputResolution - > model ( ) - > index ( d . next ( ) , 0 ) ;
// This is the effective 'disable' flag
QVariant vDisable ( 0 ) ;
// the magic
ui - > comboBox_inputResolution - > model ( ) - > setData ( index , vDisable , Qt : : UserRole - 1 ) ;
}
}
2018-12-28 17:04:40 +00:00
2016-12-06 02:12:44 +00:00
void MainWindow : : on_pushButton_sourceFilename_clicked ( )
{
QString filename = QFileDialog : : getOpenFileName ( ) ;
2018-12-28 15:52:41 +00:00
if ( filename ! = nullptr ) {
2016-12-06 02:12:44 +00:00
ui - > lineEdit_sourceFilename - > setText ( filename ) ;
QPixmap mypix ( filename ) ;
ui - > label_source - > setPixmap ( mypix ) ;
ui - > label_source - > setScaledContents ( true ) ;
QSize sourceSize = ui - > label_source - > pixmap ( ) - > size ( ) ;
QString resolutionString = QString ( " %1 x %2 " ) . arg ( sourceSize . width ( ) ) . arg ( sourceSize . height ( ) ) ;
ui - > label_sourceResolution - > setText ( resolutionString ) ;
2017-01-15 22:39:11 +00:00
updateNeeded = 1 ;
2016-12-06 02:12:44 +00:00
}
}
2018-12-28 17:04:40 +00:00
2016-12-06 02:12:44 +00:00
void MainWindow : : updateInputSize ( )
{
switch ( ui - > comboBox_inputResolution - > currentIndex ( ) ) {
2017-02-05 04:20:35 +00:00
case 0 :
inputWidth = 40 ;
inputHeight = 48 ;
break ;
case 1 :
inputWidth = 80 ;
inputHeight = 48 ;
break ;
case 2 :
inputWidth = 140 ;
inputHeight = 192 ;
break ;
case 3 :
inputWidth = 280 ;
inputHeight = 192 ;
break ;
case 4 :
inputWidth = 320 ;
inputHeight = 200 ;
break ;
case 5 :
inputWidth = 560 ;
inputHeight = 384 ;
break ;
case 6 :
inputWidth = 640 ;
inputHeight = 400 ;
break ;
case 7 :
inputWidth = 640 ;
inputHeight = 480 ;
break ;
default :
qDebug ( ) < < " default, error? " ;
break ;
2016-12-06 02:12:44 +00:00
}
QSize sourceSize = ui - > label_source - > pixmap ( ) - > size ( ) ;
2018-12-28 15:52:41 +00:00
double sx = static_cast < double > ( inputWidth ) / sourceSize . width ( ) ;
double sy = static_cast < double > ( inputHeight ) / sourceSize . height ( ) ;
2016-12-06 02:12:44 +00:00
QString scaleString = QString ( " %1 x %2 " ) . arg ( sx ) . arg ( sy ) ;
ui - > label_scaleFactor - > setText ( scaleString ) ;
}
2018-12-28 17:04:40 +00:00
2016-12-06 02:12:44 +00:00
void MainWindow : : livePreview ( )
{
if ( ui - > checkBox_livePreview - > isChecked ( ) ) {
on_pushButton_preview_clicked ( ) ;
}
}
2016-12-06 02:45:11 +00:00
// This is the actual preview generation/main logic function
2016-12-06 02:12:44 +00:00
void MainWindow : : on_pushButton_preview_clicked ( )
{
2018-12-28 17:04:40 +00:00
if ( ! check_canPreview ( ) ) return ;
2016-12-06 02:12:44 +00:00
// GET SCALE FACTOR
updateInputSize ( ) ;
// NOW GENERATE SCALED QPIXMAP TO SAVE
QPixmap scaledPixmap = ui - > label_source - > pixmap ( ) - > scaled ( inputWidth , inputHeight ) ;
scaledPixmap . save ( inputImgPath , " BMP " , 0 ) ;
// NOW FIND OUR OUTPUT FORMAT
QString outputFormat = " H " ; // HIRES
switch ( ui - > comboBox_outputFormat - > currentIndex ( ) ) {
2017-02-05 04:20:35 +00:00
case 0 :
outputFormat = " L " ;
break ;
case 1 :
outputFormat = " DL " ;
break ;
case 2 :
outputFormat = " H " ;
break ;
case 3 :
outputFormat = " D " ;
break ;
case 4 :
outputFormat = " mono " ;
break ;
2016-12-06 02:12:44 +00:00
}
QString converterPath = " /Users/dbrock/appleiigs/grlib/b2d " ;
converterPath = QString ( " %1/b2d " ) . arg ( QCoreApplication : : applicationDirPath ( ) ) ;
QProcess process ;
QStringList args ;
args < < inputImgPath ; // "/tmp/saved.bmp"
args < < outputFormat ;
2019-12-17 02:21:28 +00:00
if ( outputFormat = = " DL " | | outputFormat = = " L " ) {
args < < " N " ;
}
2016-12-06 02:12:44 +00:00
if ( ui - > horizontalSlider_crossHatch - > value ( ) > 0 ) {
QString crossHatchArg = QString ( " Z%1 " ) . arg ( ui - > horizontalSlider_crossHatch - > value ( ) ) ;
args < < crossHatchArg ;
}
if ( ui - > horizontalSlider_colorBleed - > value ( ) > 0 ) {
QString colorBleedArg = QString ( " R%1 " ) . arg ( ui - > horizontalSlider_colorBleed - > value ( ) ) ;
args < < colorBleedArg ;
}
2017-02-04 05:33:30 +00:00
if ( ui - > comboBox_dithering - > currentIndex ( ) > 0 ) {
QString ditherArg = QString ( " D%1 " ) . arg ( ui - > comboBox_dithering - > currentIndex ( ) ) ;
args < < ditherArg ;
}
2018-12-28 15:52:41 +00:00
// MUST ALWAYS HAVE A "V" FLAG TO GENERATE OUR PREVIEW IMAGE
if ( ui - > comboBox_previewPalette - > currentIndex ( ) > - 1 ) {
QString ppalArg = QString ( " V%1 " ) . arg ( ui - > comboBox_previewPalette - > currentIndex ( ) ) ;
args < < ppalArg ;
}
args < < ui - > lineEdit_addArgs - > text ( ) ;
2016-12-06 02:12:44 +00:00
2016-12-06 02:45:11 +00:00
// RUN THE CONVERTER SCRIPT
2016-12-06 02:12:44 +00:00
process . start ( converterPath , args ) ;
process . waitForFinished ( ) ; // BLOCKS!!!
QString commandString = QString ( " %1 %2 " ) . arg ( converterPath , args . join ( " " ) ) ;
2020-07-17 17:15:15 +00:00
//qDebug() << commandString;
2016-12-06 02:12:44 +00:00
ui - > plainTextEdit_lastCmd - > document ( ) - > setPlainText ( commandString ) ;
// ALL DONE SO TRY TO LOAD PREVIEW
QPixmap previewPix ( previewImgPath ) ;
float realScale = 1 ;
if ( previewPix . width ( ) = = 80 ) {
int scale = 3 ;
realScale = scale ;
previewPix = previewPix . scaled ( 80 * scale , 48 * scale ) ;
2020-07-17 17:15:15 +00:00
//qDebug() << "W80";
2016-12-06 02:12:44 +00:00
}
if ( previewPix . width ( ) = = 560 ) {
float scale = 0.5f ;
realScale = scale ;
2018-12-28 15:52:41 +00:00
previewPix = previewPix . scaled ( qRound ( 560 * scale ) , qRound ( 384 * scale ) , Qt : : KeepAspectRatio , Qt : : SmoothTransformation ) ;
2020-07-17 17:15:15 +00:00
//qDebug() << "W560";
2016-12-06 02:12:44 +00:00
}
ui - > label_preview - > setPixmap ( previewPix ) ;
2018-12-28 15:52:41 +00:00
ui - > groupBox_preview - > setTitle ( QString ( " Preview - Scale %1 " ) . arg ( qRound ( realScale ) ) ) ;
repaint ( ) ;
2016-12-06 02:12:44 +00:00
}
2018-12-28 15:52:41 +00:00
2016-12-06 02:12:44 +00:00
// When this timer is running, it checks to see if a
// preview update has been requested, and handles it if so.
void MainWindow : : previewTimerTimeout ( )
{
if ( updateNeeded ) {
on_pushButton_preview_clicked ( ) ;
updateNeeded = false ;
}
}
2018-12-28 17:04:40 +00:00
2016-12-06 02:12:44 +00:00
void MainWindow : : on_horizontalSlider_crossHatch_valueChanged ( int value )
{
if ( value = = 0 ) {
ui - > label_crossHatch - > setText ( " Off " ) ;
} else {
ui - > label_crossHatch - > setText ( QString : : number ( value ) ) ;
}
updateNeeded = 1 ;
}
2016-12-06 02:45:11 +00:00
2016-12-06 02:12:44 +00:00
void MainWindow : : on_horizontalSlider_colorBleed_valueChanged ( int value )
{
if ( value = = 0 ) {
ui - > label_colorBleed - > setText ( " Off " ) ;
} else {
ui - > label_colorBleed - > setText ( QString : : number ( value ) ) ;
}
updateNeeded = 1 ;
}
2018-12-28 17:04:40 +00:00
2018-12-28 15:52:41 +00:00
void MainWindow : : on_comboBox_outputFormat_currentIndexChanged ( int /*unused*/ )
2016-12-06 02:12:44 +00:00
{
updateNeeded = 1 ;
updateDisplayModes ( ) ;
}
2016-12-06 02:45:11 +00:00
2018-12-28 15:52:41 +00:00
void MainWindow : : on_comboBox_inputResolution_currentIndexChanged ( int /*unused*/ )
2016-12-06 02:12:44 +00:00
{
updateNeeded = 1 ;
}
2016-12-06 02:45:11 +00:00
2016-12-06 02:12:44 +00:00
void MainWindow : : on_checkBox_livePreview_stateChanged ( int arg1 )
{
// preview update timer
if ( arg1 ) {
updateNeeded = 1 ;
previewTimer - > start ( 500 ) ;
} else {
previewTimer - > stop ( ) ;
}
}
2016-12-06 02:45:11 +00:00
2017-01-15 22:39:11 +00:00
void MainWindow : : on_actionWhat_is_this_triggered ( )
{
QMessageBox msgBox ;
2017-01-16 04:05:17 +00:00
msgBox . setText ( " Image conversion tool for OSX/Windows/Linux \n "
" Take modern image formats (PNG, JPEG, BMP, etc) and convert them for use in your Apple II programs or just for fun. \n \n \n "
" *USAGE* \n "
" Once you start the program, just \" Open Source Image \" , select the \" Apple ][ Display Mode \" you want to convert your image to, "
" and click \" Preview \" , or even better, click the \" Live Preview \" checkbox to get real-time feedback on your conversion settings. \n \n "
" Once you are satisfied with your conversion settings, click \" Save Image File \" to save in one of the Apple ][ image formats based on the display mode. "
" If you want to save that image file directly to a ProDOS volume, that is now supported via the \" Save To ProDOS \" function! \n \n "
" Then you can load it up in your favorite emulator, or transfer it to real disks/flash storage to view on glorious vintage hardware. \n \n "
2019-12-17 02:21:28 +00:00
" (c)2016-2020 Dagen Brock * \n \n \n * bmp2dhr is by Bill Buckels and CADIUS is by Brutal Deluxe. " ) ;
2017-01-15 22:39:11 +00:00
msgBox . exec ( ) ;
}
2018-12-28 17:04:40 +00:00
2017-01-15 22:39:11 +00:00
void MainWindow : : on_pushButton_saveImage_clicked ( )
2016-12-06 02:12:44 +00:00
{
2018-12-28 17:04:40 +00:00
if ( ! check_canSave ( ) ) return ;
2016-12-06 02:12:44 +00:00
QString a2filename ;
QString suffix ;
QString filters = QString ( " All Images (*.A2FC *.BIN *.SLO *.DLO);;HGR (*.BIN);;DHGR (*.A2FC);;LR (*.SLO);;DLR (*.DLO);;All files (*.*) " ) ;
QString defaultFilter ;
if ( ui - > comboBox_outputFormat - > currentText ( ) = = " LR " ) {
a2filename = QString ( " %1/%2.SLO " ) . arg ( tmpDirPath , imageName . toUpper ( ) ) ;
suffix = " .SLO " ;
defaultFilter = " LR (*.SLO) " ;
} else if ( ui - > comboBox_outputFormat - > currentText ( ) = = " DLR " ) {
a2filename = QString ( " %1/%2.DLO " ) . arg ( tmpDirPath , imageName . toUpper ( ) ) ;
suffix = " .DLO " ;
defaultFilter = " DLR (*.DLO) " ;
} else if ( ui - > comboBox_outputFormat - > currentText ( ) = = " HGR " ) {
a2filename = QString ( " %1/%2CH.BIN " ) . arg ( tmpDirPath , imageName . toUpper ( ) ) ;
suffix = " .BIN " ;
defaultFilter = " HGR (*.BIN) " ;
} else if ( ui - > comboBox_outputFormat - > currentText ( ) = = " DHGR " ) {
a2filename = QString ( " %1/%2.A2FC " ) . arg ( tmpDirPath , imageName . toUpper ( ) ) ;
suffix = " .A2FC " ;
defaultFilter = " DHGR (*.A2FC) " ;
} else if ( ui - > comboBox_outputFormat - > currentText ( ) = = " MONO " ) {
a2filename = QString ( " %1/%2M.BIN " ) . arg ( tmpDirPath , imageName . toUpper ( ) ) ;
suffix = " .BIN " ;
defaultFilter = " HGR (*.BIN) " ;
}
2016-12-06 02:45:11 +00:00
// PROMPT FOR SAVE FILENAME AND COPY (HOPEFULLY) TO SAVE FILENAME
2018-12-28 15:52:41 +00:00
QString saveFile = QFileDialog : : getSaveFileName ( nullptr , " Save file " , QDir : : currentPath ( ) , filters , & defaultFilter ) ;
2017-02-05 04:20:35 +00:00
if ( QFile : : exists ( saveFile ) ) {
QFile : : remove ( saveFile ) ;
}
2016-12-06 02:45:11 +00:00
QFile : : copy ( a2filename , saveFile ) ;
2016-12-06 02:12:44 +00:00
}
2017-01-15 22:39:11 +00:00
// HOLY CRAP WHAT IS THIS??
// Well you see, Johnny, this is a layer of hacks to try
// to wrap CADIUS, but it has no API. So I can clean this up
// but it's more of a proof of concept. I think it'd be
// smarter to add JSON output to CADIUS in the long run.
// I consider this small feature a present to the community.
void MainWindow : : on_pushButton_saveToProdos_clicked ( )
2016-12-06 02:12:44 +00:00
{
2018-12-28 17:04:40 +00:00
if ( ! check_canSave ( ) ) return ;
2017-01-15 22:39:11 +00:00
2020-06-08 15:32:39 +00:00
QString cadiusPath = " /Users/dbrock/appleiigs/cadius/cadius " ; // Dev mode
2020-06-08 15:30:06 +00:00
cadiusPath = QString ( " %1/cadius " ) . arg ( QCoreApplication : : applicationDirPath ( ) ) ;
2017-01-15 22:39:11 +00:00
2020-06-08 15:30:06 +00:00
// MYPICBIN=Type(06),AuxType(2000),VersionCreate(70),MinVersion(BE),Access(E3),FolderInfo1(000000000000000000000000000000000000),FolderInfo2(000000000000000000000000000000000000)
2017-01-15 22:39:11 +00:00
QString filetype = " 06 " ;
QString auxtype = " 2000 " ;
QString suffix = " .po " ;
QString defaultFilter = tr ( " All ProDOS Images (*.po *.hdv *.2mg) " ) ;
QString filters = QString ( tr ( " All ProDOS Images (*.po *.hdv *.2mg);;ProDOS Order (*.po);;HDV (*.hdv);;2MG (*.2mg);;All files (*.*) " ) ) ;
// PROMPT FOR SAVE FILENAME AND COPY (HOPEFULLY) TO SAVE FILENAME
2018-12-28 15:52:41 +00:00
QString prodosImageFile = QFileDialog : : getSaveFileName ( nullptr , " Choose ProDOS Image to Save to " , QDir : : currentPath ( ) , filters , & defaultFilter , QFileDialog : : DontConfirmOverwrite ) ;
2017-01-15 22:39:11 +00:00
// ALSO GENERATE PRODOS SAFE BASENAME
QFileInfo fi ( prodosImageFile ) ;
QString prodosVolumeName = fi . baseName ( ) . left ( 15 ) ; // get max volume name
// EMPTY FILENAME?!
if ( prodosImageFile . length ( ) = = 0 ) {
return ;
}
QString imageSize = " 140KB " ;
// NOW SEE IF IT'S A NEW FILE OR EXISTING IMAGE
QFileInfo check_file ( prodosImageFile ) ;
// check if file exists and if yes: Is it really a file and no directory?
if ( check_file . exists ( ) & & check_file . isFile ( ) ) {
// nothing yet. We'll open it below, either way.
} else {
// NEW FILE, PROMPT FOR IMAGE SIZE
QMessageBox msgBox ;
msgBox . setText ( tr ( " Select size for new ProDOS image " ) ) ;
msgBox . addButton ( tr ( " Cancel " ) , QMessageBox : : NoRole ) ;
QAbstractButton * pButton140 = msgBox . addButton ( tr ( " 140KB " ) , QMessageBox : : ApplyRole ) ;
QAbstractButton * pButton800 = msgBox . addButton ( tr ( " 800KB " ) , QMessageBox : : ApplyRole ) ;
2020-06-08 15:45:38 +00:00
QAbstractButton * pButton32768 = msgBox . addButton ( tr ( " 32MB " ) , QMessageBox : : ApplyRole ) ;
2017-01-15 22:39:11 +00:00
msgBox . setDefaultButton ( QMessageBox : : Yes ) ;
msgBox . exec ( ) ;
if ( msgBox . clickedButton ( ) = = pButton140 ) {
// set above, nothing to do
} else if ( msgBox . clickedButton ( ) = = pButton800 ) {
imageSize = " 800KB " ;
2020-06-08 15:45:38 +00:00
} else if ( msgBox . clickedButton ( ) = = pButton32768 ) {
imageSize = " 32MB " ;
2017-01-15 22:39:11 +00:00
} else {
return ; // cancelled
}
// NOW CREATE AN IMAGE
QProcess process ;
QStringList args ;
args < < " CREATEVOLUME " ;
args < < prodosImageFile ;
args < < prodosVolumeName ;
args < < imageSize ;
QString commandString = QString ( " %1 %2 " ) . arg ( cadiusPath , args . join ( " " ) ) ;
// RUN THE IMAGE CREATE
process . start ( cadiusPath , args ) ;
process . waitForFinished ( ) ; // BLOCKS!!!
// NOW CHECK AGAIN TO SEE IF OUR IMAGE FILE GOT CREATED
if ( check_file . exists ( ) & & check_file . isFile ( ) ) {
2018-12-28 15:52:41 +00:00
// qDebug() << "IMAGE FILE CREATED.";
2017-01-15 22:39:11 +00:00
} else {
ui - > plainTextEdit_lastCmd - > document ( ) - > setPlainText ( QString ( " Failed creating image with command: %1 " ) . arg ( commandString ) ) ;
return ;
}
ui - > plainTextEdit_lastCmd - > document ( ) - > setPlainText ( commandString ) ;
}
// NOW CATALOG WHATEVER IMAGE WE GOT... NEW/EXISTING
QProcess cat_process ;
QStringList cat_args ;
cat_args < < " CATALOG " ;
cat_args < < prodosImageFile ;
// RUN THE CATALOG AND GET OUTPUT
cat_process . start ( cadiusPath , cat_args ) ;
cat_process . waitForFinished ( ) ; // BLOCKS!!!
QString cat_output = QString ( cat_process . readAllStandardOutput ( ) ) ;
2018-12-28 15:52:41 +00:00
//qDebug() << "CATALOG OUTPUT (cat_output)\n " << cat_output;
2017-01-15 22:39:11 +00:00
// regex scanner index
int pos = 0 ;
QStringList list ;
// MUST MATCH FOR NEWLINES (VS USING ^ or &)
2017-02-04 07:03:10 +00:00
QRegExp vol_rx ( " \n (/.{1,15}/) \ r ? \ n " ) ;
2017-01-15 22:39:11 +00:00
// OVERWRITE PRODOS VOLUME NAME IF WE KNOW BETTER
while ( ( pos = vol_rx . indexIn ( cat_output , pos ) ) ! = - 1 ) {
prodosVolumeName = vol_rx . cap ( 1 ) ;
break ;
}
// NOW MATCH FOR SOME EXTRA DETAILS JUST BECAUSE WE CAN
QRegExp rx ( " (Block|Free|File|Directory) : ( \ \ d + ) " ) ;
pos = 0 ;
while ( ( pos = rx . indexIn ( cat_output , pos ) ) ! = - 1 ) {
list < < rx . cap ( 1 ) ;
2018-12-28 15:52:41 +00:00
//qDebug() << rx.cap(1);
2017-01-15 22:39:11 +00:00
pos + = rx . matchedLength ( ) ;
}
int diskBlocks , diskFree , diskFiles , diskDirs = 0 ;
if ( list . length ( ) = = 4 ) {
diskBlocks = list [ 0 ] . toInt ( ) ;
diskFree = list [ 1 ] . toInt ( ) ;
diskFiles = list [ 2 ] . toInt ( ) ;
diskDirs = list [ 3 ] . toInt ( ) ;
} else {
ui - > plainTextEdit_lastCmd - > document ( ) - > setPlainText ( QString ( " Failed to catalog ProDOS volume. Make sure that the file is one of: .po .hdv .2mg " ) ) ;
return ;
}
QString a2Filename ;
QString savedFilename ;
if ( ui - > comboBox_outputFormat - > currentText ( ) = = " LR " ) {
savedFilename = QString ( " %1/%2.SLO " ) . arg ( tmpDirPath , imageName . toUpper ( ) ) ;
a2Filename = QString ( " %1.SLO " ) . arg ( imageName . toUpper ( ) ) ;
2017-02-04 05:33:30 +00:00
auxtype = " 0400 " ; // different auxtype (not that it matters)
2017-01-15 22:39:11 +00:00
} else if ( ui - > comboBox_outputFormat - > currentText ( ) = = " DLR " ) {
savedFilename = QString ( " %1/%2.DLO " ) . arg ( tmpDirPath , imageName . toUpper ( ) ) ;
a2Filename = QString ( " %1.DLO " ) . arg ( imageName . toUpper ( ) ) ;
2017-02-04 05:33:30 +00:00
auxtype = " 0400 " ; // different auxtype (not that it matters)
2017-01-15 22:39:11 +00:00
} else if ( ui - > comboBox_outputFormat - > currentText ( ) = = " HGR " ) {
savedFilename = QString ( " %1/%2CH.BIN " ) . arg ( tmpDirPath , imageName . toUpper ( ) ) ;
a2Filename = QString ( " %1CH.BIN " ) . arg ( imageName . toUpper ( ) ) ;
} else if ( ui - > comboBox_outputFormat - > currentText ( ) = = " DHGR " ) {
savedFilename = QString ( " %1/%2.A2FC " ) . arg ( tmpDirPath , imageName . toUpper ( ) ) ;
a2Filename = QString ( " %1.A2FC " ) . arg ( imageName . toUpper ( ) ) ;
} else if ( ui - > comboBox_outputFormat - > currentText ( ) = = " MONO " ) {
savedFilename = QString ( " %1/%2M.BIN " ) . arg ( tmpDirPath , imageName . toUpper ( ) ) ;
a2Filename = QString ( " %1M.BIN " ) . arg ( imageName . toUpper ( ) ) ;
}
2017-02-04 05:33:30 +00:00
bool ok = false ;
QString prodosFileName ;
// manually build name/auxtype dialog
QDialog dialog ( this ) ;
// Use a layout allowing to have a label next to each field
QFormLayout form ( & dialog ) ;
// Add some text above the fields
form . addRow ( new QLabel ( tr ( " Save Image to ProDOS " ) ) ) ;
// Add the lineEdits with their respective labels
QList < QLineEdit * > fields ;
QLineEdit * lineEdit = new QLineEdit ( & dialog ) ;
lineEdit - > setText ( a2Filename ) ;
QString label = QString ( " ProDOS Name (max 15 chars): " ) ;
form . addRow ( label , lineEdit ) ;
QLineEdit * lineEdit2 = new QLineEdit ( & dialog ) ;
lineEdit2 - > setText ( auxtype ) ;
lineEdit2 - > setInputMask ( " HHHh " ) ;
QString label2 = QString ( " Change auxtype (optional): $ " ) ;
form . addRow ( label2 , lineEdit2 ) ;
fields < < lineEdit < < lineEdit2 ;
// Add some standard buttons (Cancel/Ok) at the bottom of the dialog
QDialogButtonBox buttonBox ( QDialogButtonBox : : Ok | QDialogButtonBox : : Cancel ,
Qt : : Horizontal , & dialog ) ;
form . addRow ( & buttonBox ) ;
QObject : : connect ( & buttonBox , SIGNAL ( accepted ( ) ) , & dialog , SLOT ( accept ( ) ) ) ;
QObject : : connect ( & buttonBox , SIGNAL ( rejected ( ) ) , & dialog , SLOT ( reject ( ) ) ) ;
// Show the dialog as modal
if ( dialog . exec ( ) = = QDialog : : Accepted ) {
// If the user didn't dismiss the dialog, do something with the fields
prodosFileName = fields [ 0 ] - > text ( ) ;
auxtype = fields [ 1 ] - > text ( ) ;
ok = true ;
}
2017-01-15 22:39:11 +00:00
if ( ok & & ! prodosFileName . isEmpty ( ) ) {
// COPY IT ... OVER EXISTING NAME?
QString saveFile = QString ( " %1/%2 " ) . arg ( tmpDirPath , prodosFileName ) ;
QFile : : copy ( savedFilename , saveFile ) ;
// GENERATE OUR STUPID _FileInformation.txt in the same directory
QString fileinfo_text = QString ( " %1=Type(%2),AuxType(%3),VersionCreate(70),MinVersion(BE),Access(E3),FolderInfo1(000000000000000000000000000000000000),FolderInfo2(000000000000000000000000000000000000) " ) . arg ( prodosFileName , filetype , auxtype ) ;
QString fileinfo_file = QString ( " %1/_FileInformation.txt " ) . arg ( tmpDirPath ) ;
2018-12-28 15:52:41 +00:00
//qDebug() << "TMP FILE: " << fileinfo_file;
2017-01-15 22:39:11 +00:00
QFile file ( fileinfo_file ) ;
if ( file . open ( QIODevice : : ReadWrite ) ) {
QTextStream stream ( & file ) ;
stream < < fileinfo_text < < endl ;
}
// NOW ADD / SAVE OUR FILE
QProcess addfile_process ;
QStringList addfile_args ;
addfile_args < < " ADDFILE " < < prodosImageFile < < prodosVolumeName < < saveFile ; // our tmp file
addfile_process . start ( cadiusPath , addfile_args ) ;
addfile_process . waitForFinished ( ) ; // BLOCKS!!!
QString addfile_output = QString ( addfile_process . readAllStandardOutput ( ) ) ;
// IF FILE ALREADY EXISTS, ASK IF THEY WANT TO OVERWRITE
2017-02-05 04:20:35 +00:00
if ( addfile_output . contains ( " A file already exist with the same name " ) ) {
2017-01-15 22:39:11 +00:00
QMessageBox : : StandardButton reply ;
reply = QMessageBox : : question ( this , " File exists in image " , " File exists, Replace? " ,
2017-02-05 04:20:35 +00:00
QMessageBox : : Yes | QMessageBox : : No ) ;
2017-01-15 22:39:11 +00:00
if ( reply = = QMessageBox : : Yes ) {
// ../tools/Cadius DELETEFILE <[2mg|hdv|po]_image_path> <prodos_file_path>
// YES - DELETE
QString deleteFile = QString ( " %1%2 " ) . arg ( prodosVolumeName , prodosFileName ) ;
2018-12-28 15:52:41 +00:00
// qDebug() << "DELETEFILE : " <<deleteFile;
2017-01-15 22:39:11 +00:00
QProcess delfile_process ;
QStringList delfile_args ;
delfile_args < < " DELETEFILE " ;
delfile_args < < prodosImageFile ;
delfile_args < < deleteFile ;
// NOW ADD / SAVE OUR FILE
delfile_process . start ( cadiusPath , delfile_args ) ;
delfile_process . waitForFinished ( ) ; // BLOCKS!!!
QString delfile_output = QString ( delfile_process . readAllStandardOutput ( ) ) ;
// MAYBE CHECK? BUT WE CAN JUST TRY TO RESAVE AND FAIL THERE
// TRY ADDFILE AGAIN
QProcess addfile2_process ;
QStringList addfile2_args ;
addfile2_args < < " ADDFILE " < < prodosImageFile < < prodosVolumeName < < saveFile ; // our tmp file
addfile2_process . start ( cadiusPath , addfile_args ) ;
addfile2_process . waitForFinished ( ) ; // BLOCKS!!!
QString addfile2_output = QString ( addfile2_process . readAllStandardOutput ( ) ) ;
// IF FILE ALREADY EXISTS, ASK IF THEY WANT TO OVERWRITE
if ( addfile2_output . contains ( " Error : " ) ) {
ui - > plainTextEdit_lastCmd - > document ( ) - > setPlainText ( " Save failed. Couldn't delete/overwrite file? I really am not sure what went wrong. Try saving the pictures to your computer and transferring them to ProDOS with another program. " ) ;
return ;
}
} else {
2018-12-28 15:52:41 +00:00
if ( ui - > label_preview - > pixmap ( ) = = nullptr ) {
2017-01-15 22:39:11 +00:00
ui - > plainTextEdit_lastCmd - > document ( ) - > setPlainText ( " Save cancelled because file exists. " ) ;
return ;
}
}
}
// IF WE MADE IT THIS FAR, ALL GOOD?
QFile : : remove ( saveFile ) ; // remove our tmp file
ui - > plainTextEdit_lastCmd - > document ( ) - > setPlainText ( " File saved. " ) ;
} else {
ui - > plainTextEdit_lastCmd - > document ( ) - > setPlainText ( " Save cancelled. " ) ;
// cancelled?
}
return ;
2016-12-06 02:12:44 +00:00
}
2017-02-04 05:33:30 +00:00
2018-12-28 15:52:41 +00:00
void MainWindow : : on_comboBox_dithering_currentIndexChanged ( int /*unused*/ )
{
updateNeeded = 1 ;
}
void MainWindow : : on_comboBox_previewPalette_currentIndexChanged ( int /*unused*/ )
2017-02-04 05:33:30 +00:00
{
updateNeeded = 1 ;
}
2018-12-28 17:04:40 +00:00
void MainWindow : : on_pushButton_savePreview_clicked ( )
{
if ( ! check_canSave ( ) ) return ;
QString a2filename ;
QString filters = QString ( " All Images (*.BMP *.PNG);;Bitmap (*.BMP);;PNG (*.PNG);;All files (*.*) " ) ;
QString defaultFilter = " PNG (*.PNG) " ;
QString suffix = " .PNG " ;
// PROMPT FOR SAVE FILENAME AND COPY (HOPEFULLY) TO SAVE FILENAME
QString saveFile = QFileDialog : : getSaveFileName ( nullptr , " Save file " , QDir : : currentPath ( ) , filters , & defaultFilter ) ;
if ( QFile : : exists ( saveFile ) ) {
QFile : : remove ( saveFile ) ;
}
// TRY TO SET CORRECT TYPE FOR SAVE, DEFAULT TO PNG
QFileInfo fi ( saveFile ) ;
QString ext = fi . completeSuffix ( ) . toUpper ( ) ;
if ( ext = = " BMP " ) {
ui - > label_preview - > pixmap ( ) - > save ( saveFile , " BMP " , 0 ) ;
} else {
ui - > label_preview - > pixmap ( ) - > save ( saveFile , " PNG " , 0 ) ;
}
}