SceneDialog.cpp #3

  • //
  • guest/
  • sam_stafford/
  • scenesaver/
  • SceneDialog.cpp
  • View
  • Commits
  • Open Download .zip Download (10 KB)
#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.