AlbumShaper
1.0a3
|
00001 //============================================== 00002 // copyright : (C) 2003-2005 by Will Stokes 00003 //============================================== 00004 // This program is free software; you can redistribute it 00005 // and/or modify it under the terms of the GNU General 00006 // Public License as published by the Free Software 00007 // Foundation; either version 2 of the License, or 00008 // (at your option) any later version. 00009 //============================================== 00010 00011 //Systemwide includes 00012 #include <qstring.h> 00013 #include <qimage.h> 00014 #include <qapplication.h> 00015 #include <qdir.h> 00016 #include <qprocess.h> 00017 #include <qfile.h> 00018 #include <qdir.h> 00019 00020 //PLATFORM_SPECIFIC_CODE 00021 #if defined(Q_OS_WIN) 00022 #include <windows.h> 00023 #endif //Q_OS_WIN 00024 00025 //Projectwide includes 00026 #include "wallpaperTools.h" 00027 #include "fileTools.h" 00028 #include "../album.h" 00029 #include "../photo.h" 00030 #include "../../gui/window.h" 00031 #include "../../gui/titleWidget.h" 00032 00033 //============================================== 00034 void setWallpaper( Photo* phto ) 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 } 00255 //============================================== 00256 bool setWallpaperSupported() 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 } 00285 //============================================== 00286