#include "SceneDialog.h"
#include "globals.h"
#include <qapplication.h>
#include <qdesktopwidget.h>
#include <qdir.h>
#include <qfiledialog.h>
#include <qhbox.h>
#include <qheader.h>
#include <qimage.h>
#include <qlayout.h>
#include <qmessagebox.h>
#include <qprocess.h>
#include <qpushbutton.h>
#include <qtooltip.h>
#include <qvbox.h>
#include <qwhatsthis.h>
SceneDialog::SceneDialog( QWidget* wid )
:QDialog( wid )
{
QDesktopWidget *d = QApplication::desktop();
int w = d->width(); // returns desktop width
int h = d->height(); // returns desktop height
w /= 5;
h /= 5;
QVBoxLayout* v = new QVBoxLayout( this );
v->setMargin( 10 );
v->setSpacing( 10 );
QHBox* hbg = new QHBox( this );
hbg->setSpacing( 10 );
bg = new QLabel( hbg );
bg->setFixedSize( w, h );
QVBox* vbg = new QVBox( hbg );
background = new QLabel( vbg );
background->setText( "No background selected" );
QPushButton* bgb = new QPushButton( "Choose Background...", vbg );
connect( bgb, SIGNAL(clicked()), this, SLOT(choose_bg()) );
new QWidget( vbg );
hbg->setStretchFactor( vbg, 0 );
QWidget* bruno = new QWidget( hbg );
hbg->setStretchFactor( bruno, 1 );
v->addWidget( hbg );
QWhatsThis::add( hbg, "This is the image that SceneSaver will always start with. It is also what determines the resolution that SceneSaver runs at; if SceneSaver runs slowly, try using a smaller background image." );
QHBox* hsc = new QHBox( this );
hsc->setSpacing( 10 );
sc = new QLabel( hsc );
sc->setFixedSize( w / 2, h / 2 );
QWhatsThis::add(sc,"This is a preview of whatever image you've selected from the image playlist, in case you've forgotten what it looks like.");
scenes = new QListView( hsc );
scenes->addColumn( "Image Playlist" );
scenes->setResizeMode( QListView::LastColumn );
scenes->setSorting( -1 );
scenes->setSortColumn( -1 );
scenes->setSelectionMode( QListView::Extended );
scenes->header()->setClickEnabled( false );
connect(scenes,SIGNAL(currentChanged(QListViewItem*)),this,SLOT(selected(QListViewItem*)));
QWhatsThis::add( scenes, "These are the images that the painters will draw while SceneSaver runs. If the \"shuffle images\" option is not checked, they will be drawn in the order listed here." );
QVBox* vsc = new QVBox( hsc );
vsc->setSpacing( 5 );
QPushButton* add = new QPushButton( "Add Images...", vsc );
del = new QPushButton( "Remove Images", vsc );
QWidget* nil = new QWidget( vsc );
nil->setFixedHeight( add->height() );
QPushButton* exp = new QPushButton( "Explore...", vsc );
aut = new QPushButton( "Import All", vsc );
nil = new QWidget( vsc );
connect(add,SIGNAL(clicked()),this,SLOT(add()));
QWhatsThis::add( add, "Click here to browse for images to add to the list." );
connect(del,SIGNAL(clicked()),this,SLOT(remove()));
QWhatsThis::add( del, "Click here to remove selected images from the list." );
connect(exp,SIGNAL(clicked()),this,SLOT(explore()));
QWhatsThis::add( exp, "Click here to open the SceneSaver folder in Explorer." );
connect(aut,SIGNAL(clicked()),this,SLOT(autoload()));
QWhatsThis::add( aut, "Click here to automatically add all new images in the SceneSaver folder to the list." );
v->addWidget( hsc );
QHBox* buttons = new QHBox( this );
buttons->setSpacing( 10 );
bruno = new QWidget( buttons );
buttons->setStretchFactor( bruno, 1 );
QWhatsThis::add(bruno,"It is rumored that there is buried treasure hidden here.");
QPushButton* ok = new QPushButton( "OK", buttons );
connect(ok,SIGNAL(clicked()),this,SLOT(ok()));
QWhatsThis::add(ok,"Click here to save the background image and playlist you've chosen.");
QPushButton* cancel = new QPushButton( "Cancel", buttons );
connect(cancel,SIGNAL(clicked()),this,SLOT(close()));
QWhatsThis::add(cancel,"Click here to retreat with your tail between your legs.");
v->addWidget( buttons );
setCaption( "Choose Images" );
setModal( true );
load_scenes();
}
SceneDialog::~SceneDialog(void)
{
}
void SceneDialog::choose_bg()
{
QString file = QFileDialog::getOpenFileName(
QString::null,
"Images (*.bmp *.gif *.jpg *.png)",
this,
"Choose Background",
"Select the starting image" );
if ( file.isEmpty() ) return;
QString dir = QDir::currentDirPath();
dir = QDir::convertSeparators( dir );
dir += "\\";
file = QDir::convertSeparators( file );
if ( file.startsWith( dir, false ) ) file.remove( dir, false );
bgfile = file;
refresh_background();
}
void SceneDialog::add()
{
QStringList files = QFileDialog::getOpenFileNames(
"Images (*.bmp *.gif *.jpg *.png)",
QString::null,
this,
"Add Images",
"Select one or more images to add" );
if ( files.empty() ) return;
QString dir = QDir::currentDirPath();
dir = QDir::convertSeparators( dir );
dir += "\\";
QString file;
QListViewItem* item = scenes->currentItem();
if ( !item ) item = scenes->lastItem();
if ( item ) item->setSelected( false );
for ( QStringList::Iterator it = files.begin(); it != files.end(); ++it )
{
file = QDir::convertSeparators( *it );
if ( file.startsWith( dir, false ) ) file.remove( dir, false );
item = new QListViewItem( scenes, item );
item->setText( 0, file );
}
scenes->setCurrentItem( item );
if ( item ) item->setSelected( true );
}
void SceneDialog::remove()
{
setCursor( QCursor::BusyCursor );
//Get list of selected items. (Why can't QListView just do this?)
QPtrList<QListViewItem> lst;
QListViewItemIterator it( scenes );
while ( it.current() )
{
if ( it.current()->isSelected() )
lst.append( it.current() );
++it;
}
QListViewItem* i;
for ( i = lst.first() ; i ; i = lst.next() )
{
scenes->removeItem( i );
}
setCursor( QCursor::ArrowCursor );
}
void SceneDialog::explore()
{
QProcess explorer;
explorer.addArgument( "explorer" );
explorer.addArgument( QDir::convertSeparators( QDir::currentDirPath() ) );
explorer.start();
}
void SceneDialog::autoload()
{
setCursor( QCursor::BusyCursor );
QString cwd = QDir::currentDirPath();
cwd = QDir::convertSeparators( cwd );
cwd += "\\";
QStringList ls = QDir::current().entryList( QDir::Files );
QStringList lst;
QListViewItemIterator lit( scenes );
while ( lit.current() )
{
lst.append( lit.current()->text(0).simplifyWhiteSpace() );
++lit;
}
QListViewItem* i;
QString file;
int count = 0;
for ( QStringList::Iterator it = ls.begin(); it != ls.end(); ++it )
{
file = *it;
file = file.simplifyWhiteSpace();
if ( file.endsWith( ".jpg", false ) ||
file.endsWith( ".bmp", false ) ||
file.endsWith( ".png", false ) ||
file.endsWith( ".gif", false ) )
{
file.remove( cwd, false );
if ( file == bgfile ) continue;
if ( lst.contains( file ) ) continue;
i = new QListViewItem( scenes, scenes->lastItem() );
i->setText( 0, file );
count++;
}
}
setCursor( QCursor::ArrowCursor );
QWhatsThis::display( "Added " + QString::number( count ) + " new images from\n" + cwd );
}
void SceneDialog::ok()
{
if ( !save_scenes() )
{
QMessageBox::warning( this, "SceneSaver warning", "Unable to write Scenes.txt." );
return;
}
close();
}
void SceneDialog::load_scenes()
{
QFile file( "Scenes.txt" );
if ( !file.open( IO_ReadOnly ) ) return;
scenes->clear();
QString image;
if ( file.readLine( image, 1024 ) > 0 )
{
bgfile = image.simplifyWhiteSpace();
}
refresh_background();
QListViewItem* item;
while ( file.readLine( image, 1024 ) > 0 )
{
item = new QListViewItem( scenes, scenes->lastItem() );
item->setText( 0, image );
}
file.close();
scenes->setCurrentItem( scenes->firstChild() );
selected( scenes->firstChild() );
}
bool SceneDialog::save_scenes()
{
QFile file( "Scenes.txt" );
if ( !file.open( IO_WriteOnly ) ) return false;
QString image = bgfile.simplifyWhiteSpace();
file.writeBlock( image.latin1(), image.length() );
file.putch( '\n' );
QListViewItemIterator it( scenes );
while ( it.current() )
{
image = it.current()->text(0).simplifyWhiteSpace();
file.writeBlock( image.latin1(), image.length() );
file.putch( '\n' );
++it;
}
file.close();
return true;
}
void SceneDialog::refresh_background()
{
QString bgtext = bgfile + "\n";
QImage bgimage( bgfile );
if ( bgimage.isNull() )
{
bgtext += "(invalid image file)";
}
else
{
bgtext = "Background image:\n" + bgtext;
bgtext += "(";
bgtext += QString::number( bgimage.width() );
bgtext += "x";
bgtext += QString::number( bgimage.height() );
bgtext += " pixels)";
QImage bgi( bg->width(), bg->height(), 32 );
bgi.fill( qRgb( 0, 0, 0 ) );
switch( settings.autoscale )
{
case 'N': //no scale
bitBlt( &bgi, 0, 0, &bgimage );
break;
case 'S': //stretch
bgi = bgimage.smoothScale( bgi.size(), QImage::ScaleFree );
break;
case 'L': //letterbox
bgimage = bgimage.smoothScale( bgi.size(), QImage::ScaleMin );
bitBlt( &bgi, (bgi.width() - bgimage.width()) / 2, (bgi.height() - bgimage.height()) / 2, &bgimage );
break;
case 'M': //panscan
bgimage = bgimage.smoothScale( bgi.size(), QImage::ScaleMax );
bitBlt( &bgi, (bgi.width() - bgimage.width()) / 2, (bgi.height() - bgimage.height()) / 2, &bgimage );
break;
}
bg->setPixmap( bgi );
}
background->setText( bgtext );
}
void SceneDialog::selected( QListViewItem* i )
{
if ( !i ) return;
QImage scimage( i->text(0).simplifyWhiteSpace() );
if ( scimage.isNull() )
{
sc->setText( "(invalid image file)" );
sc->setPixmap( QPixmap() );
}
else
{
QImage sci( sc->width(), sc->height(), 32 );
sci.fill( qRgb( 0, 0, 0 ) );
switch( settings.autoscale )
{
case 'N': //no scale
bitBlt( &sci, 0, 0, &scimage );
break;
case 'S': //stretch
sci = scimage.smoothScale( sci.size(), QImage::ScaleFree );
break;
case 'L': //letterbox
scimage = scimage.smoothScale( sci.size(), QImage::ScaleMin );
bitBlt( &sci, (sci.width() - scimage.width()) / 2, (sci.height() - scimage.height()) / 2, &scimage );
break;
case 'M': //panscan
scimage = scimage.smoothScale( sci.size(), QImage::ScaleMax );
bitBlt( &sci, (sci.width() - scimage.width()) / 2, (sci.height() - scimage.height()) / 2, &scimage );
break;
}
sc->setPixmap( sci );
}
sc->show();
}
| # | Change | User | Description | Committed | |
|---|---|---|---|---|---|
| #3 | 5420 | Sam Stafford |
Have the image selection dialog pop up an error if it's unable to save the images file - I was seeing some problems earlier. Haven't been able to repeat them since I put the check in, of course. :P |
||
| #2 | 5299 | Sam Stafford |
A second pass for usability - tightened up some terminology and extended some of the "What's This?" help blurbs. |
||
| #1 | 5296 | Sam Stafford |
Cleaned up config dialog a little, added scenes dialog and a couple of icons. |