wallpaperTools.cpp File Reference

#include <qstring.h>
#include <qimage.h>
#include <qapplication.h>
#include <qdir.h>
#include <qprocess.h>
#include <qfile.h>
#include "wallpaperTools.h"
#include "fileTools.h"
#include "../album.h"
#include "../photo.h"
#include "../../gui/window.h"
#include "../../gui/titleWidget.h"

Include dependency graph for wallpaperTools.cpp:

Go to the source code of this file.

Functions

void setWallpaper (Photo *phto)
 Sets desktop wallpaper using specified photo.
bool setWallpaperSupported ()
 Does Album Shaper support setting the wallpaper on this system?


Function Documentation

void setWallpaper ( Photo phto  ) 

Sets desktop wallpaper using specified photo.

Definition at line 34 of file wallpaperTools.cpp.

References copyFile(), Photo::getImageFilename(), getImageSize(), and scaleImage().

Referenced by SubalbumWidget::setWallpaperAction().

00035 {
00036   //Get full size image dimensions
00037   int imageW, imageH;
00038   getImageSize( phto->getImageFilename(), imageW, imageH );
00039 
00040   //If image is larger than either screen dimension then scale it down
00041   int screenW = qApp->desktop()->screenGeometry().size().width();
00042   int screenH = qApp->desktop()->screenGeometry().size().height();
00043 
00044   //If image is larger than either screen dimensions then scale it to fit
00045   QImage scaledImage;
00046   if( imageW > screenW || imageH > screenH )
00047   {
00048     scaleImage( phto->getImageFilename(), scaledImage, screenW, screenH );
00049     imageW = scaledImage.width();
00050     imageH = scaledImage.height();
00051   }
00052 
00053   //If image is <75% of either screen dimensions, center it when setting it to the background
00054   //PLATFORM_SPECIFIC_CODE
00055   #ifndef Q_OS_MACX
00056   const bool centerImage = (imageW < 0.75*screenW) || (imageH < 0.75*screenH);
00057   #endif
00058 
00059   //Determine the final output filename. On Windows this is pretty simple, but on OSX and KDE/Unix
00060   //I've found that repeatedly setting the same filename to be used as the background does not result in a 
00061   //refreshing of the background image. Apparently these window managers are trying to be "smart" and 
00062   //avoid refreshing when the image has not changed, but in our case we are changing the image content,
00063   //just not the image filename. Alas a simple fix to this problem is to alternate using spaces and 
00064   //underscores in the image filename and removing the old image. Another option might be to first set the 
00065   //background image to null, but this might result in unwanted flicker so we use the slightly more 
00066   //complicated approach involving alternating filenames.
00067 
00068   //PLATFORM_SPECIFIC_CODE
00069 
00070   //Windows
00071   #if defined(Q_OS_WIN)
00072 
00073   //determine location to store the desktop image
00074   QString outFilename;
00075   if( !getWindowsFolderLocation(LOCAL_SETTINGS_APPLICATION_DATA,  outFilename) )
00076   {
00077     outFilename = getenv("USERPROFILE") + QString("/Local Settings/Application Data");
00078   }
00079   outFilename = QDir::convertSeparators( outFilename + "/Album Shaper/Album Shaper Wallpaper.bmp" );
00080   
00081   //windows only support setting background image using BMP format, so if image was not scaled
00082   //load it so we can use QImage to save it as a BMP image now
00083   if( scaledImage.isNull() )  
00084   { scaledImage.load( phto->getImageFilename() ); }
00085   
00086   //save image out
00087   scaledImage.save( outFilename, "BMP" );
00088  
00089   //OSX and other forms of UNIX
00090   #else
00091 
00092   //determine location to store the desktop image
00093   #if defined(Q_OS_MACX)
00094   QString outFilename1 = QDir::homeDirPath() + QString("/Pictures/Album Shaper Wallpaper.jpg");
00095   QString outFilename2 = QDir::homeDirPath() + QString("/Pictures/Album_Shaper_Wallpaper.jpg");  
00096   #else
00097   QString outFilename1 = QDir::homeDirPath() + QString("/.albumShaper/Album Shaper Wallpaper.jpg");
00098   QString outFilename2 = QDir::homeDirPath() + QString("/.albumShaper/Album_Shaper_Wallpaper.jpg");
00099   #endif
00100 
00101   QString chosenFilename;
00102   QString oldFilename;
00103   
00104   //check if outFilename already exists. MacOSX is annoying in that when we create an apple event to 
00105   //set the desktop wallpaper the Finder appears to ignore the event if the filename is the same
00106   //the current filename. Ug, so to trick it use the opposite filename (swap spaces with _'s in filename)
00107   QDir tmpDir;
00108   if(tmpDir.exists( outFilename1 ) )
00109   {
00110     chosenFilename = outFilename2;
00111     oldFilename = outFilename1;
00112   }
00113   else if( tmpDir.exists( outFilename2 ) )
00114   {
00115     chosenFilename = outFilename1;
00116     oldFilename = outFilename2;
00117   }
00118   else
00119   {
00120     chosenFilename = outFilename1;
00121   }
00122   
00123   //save out file in JPG format
00124   if( !scaledImage.isNull() )
00125   {
00126     scaledImage.save( chosenFilename, "JPEG", 95 );
00127   }
00128   else
00129   {
00130     copyFile( phto->getImageFilename(), chosenFilename );
00131   }
00132 
00133   #endif    
00134 
00135   //-------------------------------
00136   // The output filename has been determined, and the image prepared.
00137   // Now save out the scaled image and set the wallpaper using system specific methods.
00138   //-------------------------------
00139   //PLATFORM_SPECIFIC_CODE
00140 
00141   //Windows
00142   #if defined(Q_OS_WIN)
00143 
00144   //Set tile and stretch values
00145   HKEY key;
00146   char data[8];
00147   if( RegOpenKeyExA( HKEY_CURRENT_USER, "Control Panel\\Desktop", 0, KEY_SET_VALUE, &key) == ERROR_SUCCESS)
00148   {
00149     //Set stretch factor, only stretch (2) if not using centering
00150     itoa( centerImage ? 0 : 2, data, 10);
00151     RegSetValueExA(key, "WallpaperStyle", NULL, REG_SZ, (UCHAR*)data, 8);
00152 
00153     //Never tile (0)
00154     itoa(0, data, 10);
00155     RegSetValueExA(key, "TileWallpaper", NULL, REG_SZ, (UCHAR*)data, 8);  
00156 
00157     //Close the key
00158     RegCloseKey(key);
00159   }
00160   
00161   //set background wallpaper
00162   SystemParametersInfoA( SPI_SETDESKWALLPAPER, 0,
00163                          (void*) outFilename.ascii(),
00164                          SPIF_UPDATEINIFILE | SPIF_SENDWININICHANGE );
00165   //-------------------------------
00166   //MacOSX
00167   #elif defined(Q_OS_MACX)
00168 
00169   //create script
00170   QString scriptFilename = ((Window*)qApp->mainWidget())->getTitle()->getAlbum()->getTmpDir() +
00171     "/tmpBackgroundScript";
00172 
00173   QFile file( scriptFilename );
00174   if(file.open(IO_WriteOnly))
00175   {
00176     //-----
00177     QTextStream stream;
00178     stream.setDevice( &file );
00179     stream.setEncoding( QTextStream::UnicodeUTF8 );
00180     //-----
00181     stream << "tell application \"Finder\"\n";
00182     stream << "set pFile to POSIX file \"" << chosenFilename.ascii() << "\"\n";
00183     stream << "set desktop picture to file pFile\n";
00184     stream << "end tell";
00185   }
00186   file.close();
00187   
00188   //run script to set background
00189   QProcess p;
00190   p.addArgument( "/usr/bin/osascript" );
00191   p.addArgument( scriptFilename );
00192   p.start();
00193   
00194   //if there is an old file remove it
00195   if(!oldFilename.isNull())    
00196   { tmpDir.remove( oldFilename ); }
00197 
00198   //-------------------------------
00199   //UNIX
00200   #else
00201 
00202   //first try setting KDE background through DCOP interface
00203   {
00204     QProcess p;   
00205     p.clearArguments();
00206     p.addArgument( "dcop" );
00207     p.addArgument( "kdesktop" );
00208     p.addArgument( "KBackgroundIface" );
00209     p.addArgument( "setWallpaper" );
00210     p.addArgument( chosenFilename.ascii() );
00211 
00212     //if the image width and height are at least 75% of the screen size then
00213     //use CENTERMAXSPECT. This will scale the image to fit the screen but 
00214     //will not warp it by changing it's effective aspect ratio. Otherwise scaling up 
00215     //will cause visible pixelation so user the CENTERED setting.
00216     const int CENTERED = 1;
00217     const int CENTER_MAXPECT = 4;
00218     int positionOption = centerImage ? CENTERED : CENTER_MAXPECT;
00219     p.addArgument( QString("%1").arg(positionOption) );
00220 
00221     //attempt to background now using DCOP interface
00222     p.start();
00223   }
00224   
00225   //try setting GNOME background using gconftool
00226   {
00227     QProcess p;   
00228     p.clearArguments();
00229     p.addArgument( "gconftool-2" );
00230     p.addArgument( "-t" );
00231     p.addArgument( "string" );
00232     p.addArgument( "-s" );
00233     p.addArgument( "/desktop/gnome/background/picture_filename" );
00234     p.addArgument( chosenFilename.ascii() );
00235     p.start();  
00236   }
00237 
00238   //try setting WindowMaker background using wmsetbg
00239   {
00240     QProcess p;   
00241     p.clearArguments();
00242     p.addArgument( "wmsetbg" );
00243     p.addArgument( "--maxscale" );
00244     p.addArgument( "-u" );
00245     p.addArgument( chosenFilename.ascii() );
00246     p.start();  
00247   }
00248   
00249   //if there is an old file remove it
00250   if(!oldFilename.isNull())    
00251   { tmpDir.remove( oldFilename ); }
00252   //-------------------------------
00253   #endif
00254 }

bool setWallpaperSupported (  ) 

Does Album Shaper support setting the wallpaper on this system?

Definition at line 256 of file wallpaperTools.cpp.

Referenced by SubalbumWidget::SubalbumWidget().

00257 {
00258   //OSX supported!
00259   #if defined(Q_OS_MACX)
00260   return true;
00261   
00262   //Windows is supported!
00263   #elif defined(Q_OS_WIN)
00264   return true;
00265 
00266   //Last try, check if dcop or gconftool-2 can be used
00267   #else
00268   QProcess p;
00269 
00270   p.addArgument( "dcop" );
00271   bool DCOP_Present = p.start();
00272 
00273   p.clearArguments();
00274   p.addArgument( "gconftool-2" );
00275   bool gconftool_Present = p.start();
00276 
00277   p.clearArguments();
00278   p.addArgument( "wmsetbg" );
00279   bool wmsetbg_Present = p.start();
00280 
00281   return ( DCOP_Present || gconftool_Present || wmsetbg_Present );
00282 
00283   #endif
00284 }


Generated on Thu Jun 19 15:43:32 2008 for AlbumShaper by  doxygen 1.5.6