AlbumShaper  1.0a3
Functions
wallpaperTools.cpp File Reference
#include <qstring.h>
#include <qimage.h>
#include <qapplication.h>
#include <qdir.h>
#include <q3process.h>
#include <qfile.h>
#include <Q3TextStream>
#include <QDesktopWidget>
#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. More...
 
bool setWallpaperSupported ()
 Does Album Shaper support setting the wallpaper on this system? More...
 

Function Documentation

§ setWallpaper()

void setWallpaper ( Photo phto)

Sets desktop wallpaper using specified photo.

Definition at line 37 of file wallpaperTools.cpp.

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

Referenced by SubalbumWidget::setWallpaperAction().

38 {
39  //Get full size image dimensions
40  int imageW, imageH;
41  getImageSize( phto->getImageFilename(), imageW, imageH );
42 
43  //If image is larger than either screen dimension then scale it down
44  int screenW = qApp->desktop()->screenGeometry().size().width();
45  int screenH = qApp->desktop()->screenGeometry().size().height();
46 
47  //If image is larger than either screen dimensions then scale it to fit
48  QImage scaledImage;
49  if( imageW > screenW || imageH > screenH )
50  {
51  scaleImage( phto->getImageFilename(), scaledImage, screenW, screenH );
52  imageW = scaledImage.width();
53  imageH = scaledImage.height();
54  }
55 
56  //If image is <75% of either screen dimensions, center it when setting it to the background
57  //PLATFORM_SPECIFIC_CODE
58  #ifndef Q_OS_MACX
59  const bool centerImage = (imageW < 0.75*screenW) || (imageH < 0.75*screenH);
60  #endif
61 
62  //Determine the final output filename. On Windows this is pretty simple, but on OSX and KDE/Unix
63  //I've found that repeatedly setting the same filename to be used as the background does not result in a
64  //refreshing of the background image. Apparently these window managers are trying to be "smart" and
65  //avoid refreshing when the image has not changed, but in our case we are changing the image content,
66  //just not the image filename. Alas a simple fix to this problem is to alternate using spaces and
67  //underscores in the image filename and removing the old image. Another option might be to first set the
68  //background image to null, but this might result in unwanted flicker so we use the slightly more
69  //complicated approach involving alternating filenames.
70 
71  //PLATFORM_SPECIFIC_CODE
72 
73  //Windows
74  #if defined(Q_OS_WIN)
75 
76  //determine location to store the desktop image
77  QString outFilename;
78  if( !getWindowsFolderLocation(LOCAL_SETTINGS_APPLICATION_DATA, outFilename) )
79  {
80  outFilename = getenv("USERPROFILE") + QString("/Local Settings/Application Data");
81  }
82  outFilename = QDir::convertSeparators( outFilename + "/Album Shaper/Album Shaper Wallpaper.bmp" );
83 
84  //windows only support setting background image using BMP format, so if image was not scaled
85  //load it so we can use QImage to save it as a BMP image now
86  if( scaledImage.isNull() )
87  { scaledImage.load( phto->getImageFilename() ); }
88 
89  //save image out
90  scaledImage.save( outFilename, "BMP" );
91 
92  //OSX and other forms of UNIX
93  #else
94 
95  //determine location to store the desktop image
96  #if defined(Q_OS_MACX)
97  QString outFilename1 = QDir::homeDirPath() + QString("/Pictures/Album Shaper Wallpaper.jpg");
98  QString outFilename2 = QDir::homeDirPath() + QString("/Pictures/Album_Shaper_Wallpaper.jpg");
99  #else
100  QString outFilename1 = QDir::homeDirPath() + QString("/.albumShaper/Album Shaper Wallpaper.jpg");
101  QString outFilename2 = QDir::homeDirPath() + QString("/.albumShaper/Album_Shaper_Wallpaper.jpg");
102  #endif
103 
104  QString chosenFilename;
105  QString oldFilename;
106 
107  //check if outFilename already exists. MacOSX is annoying in that when we create an apple event to
108  //set the desktop wallpaper the Finder appears to ignore the event if the filename is the same
109  //the current filename. Ug, so to trick it use the opposite filename (swap spaces with _'s in filename)
110  QDir tmpDir;
111  if(tmpDir.exists( outFilename1 ) )
112  {
113  chosenFilename = outFilename2;
114  oldFilename = outFilename1;
115  }
116  else if( tmpDir.exists( outFilename2 ) )
117  {
118  chosenFilename = outFilename1;
119  oldFilename = outFilename2;
120  }
121  else
122  {
123  chosenFilename = outFilename1;
124  }
125 
126  //save out file in JPG format
127  if( !scaledImage.isNull() )
128  {
129  scaledImage.save( chosenFilename, "JPEG", 95 );
130  }
131  else
132  {
133  copyFile( phto->getImageFilename(), chosenFilename );
134  }
135 
136  #endif
137 
138  //-------------------------------
139  // The output filename has been determined, and the image prepared.
140  // Now save out the scaled image and set the wallpaper using system specific methods.
141  //-------------------------------
142  //PLATFORM_SPECIFIC_CODE
143 
144  //Windows
145  #if defined(Q_OS_WIN)
146 
147  //Set tile and stretch values
148  HKEY key;
149  char data[8];
150  if( RegOpenKeyExA( HKEY_CURRENT_USER, "Control Panel\\Desktop", 0, KEY_SET_VALUE, &key) == ERROR_SUCCESS)
151  {
152  //Set stretch factor, only stretch (2) if not using centering
153  itoa( centerImage ? 0 : 2, data, 10);
154  RegSetValueExA(key, "WallpaperStyle", NULL, REG_SZ, (UCHAR*)data, 8);
155 
156  //Never tile (0)
157  itoa(0, data, 10);
158  RegSetValueExA(key, "TileWallpaper", NULL, REG_SZ, (UCHAR*)data, 8);
159 
160  //Close the key
161  RegCloseKey(key);
162  }
163 
164  //set background wallpaper
165  SystemParametersInfoA( SPI_SETDESKWALLPAPER, 0,
166  (void*) outFilename.ascii(),
167  SPIF_UPDATEINIFILE | SPIF_SENDWININICHANGE );
168  //-------------------------------
169  //MacOSX
170  #elif defined(Q_OS_MACX)
171 
172  //create script
173  QString scriptFilename = ((Window*)qApp->mainWidget())->getTitle()->getAlbum()->getTmpDir() +
174  "/tmpBackgroundScript";
175 
176  QFile file( scriptFilename );
177  if(file.open(QIODevice::WriteOnly))
178  {
179  //-----
180  Q3TextStream stream;
181  stream.setDevice( &file );
182  stream.setEncoding( Q3TextStream::UnicodeUTF8 );
183  //-----
184  stream << "tell application \"Finder\"\n";
185  stream << "set pFile to POSIX file \"" << chosenFilename.ascii() << "\"\n";
186  stream << "set desktop picture to file pFile\n";
187  stream << "end tell";
188  }
189  file.close();
190 
191  //run script to set background
192  Q3Process p;
193  p.addArgument( "/usr/bin/osascript" );
194  p.addArgument( scriptFilename );
195  p.start();
196 
197  //if there is an old file remove it
198  if(!oldFilename.isNull())
199  { tmpDir.remove( oldFilename ); }
200 
201  //-------------------------------
202  //UNIX
203  #else
204 
205  //first try setting KDE background through DCOP interface
206  {
207  Q3Process p;
208  p.clearArguments();
209  p.addArgument( "dcop" );
210  p.addArgument( "kdesktop" );
211  p.addArgument( "KBackgroundIface" );
212  p.addArgument( "setWallpaper" );
213  p.addArgument( chosenFilename.ascii() );
214 
215  //if the image width and height are at least 75% of the screen size then
216  //use CENTERMAXSPECT. This will scale the image to fit the screen but
217  //will not warp it by changing it's effective aspect ratio. Otherwise scaling up
218  //will cause visible pixelation so user the CENTERED setting.
219  const int CENTERED = 1;
220  const int CENTER_MAXPECT = 4;
221  int positionOption = centerImage ? CENTERED : CENTER_MAXPECT;
222  p.addArgument( QString("%1").arg(positionOption) );
223 
224  //attempt to background now using DCOP interface
225  p.start();
226  }
227 
228  //try setting GNOME background using gconftool
229  {
230  Q3Process p;
231  p.clearArguments();
232  p.addArgument( "gconftool-2" );
233  p.addArgument( "-t" );
234  p.addArgument( "string" );
235  p.addArgument( "-s" );
236  p.addArgument( "/desktop/gnome/background/picture_filename" );
237  p.addArgument( chosenFilename.ascii() );
238  p.start();
239  }
240 
241  //try setting WindowMaker background using wmsetbg
242  {
243  Q3Process p;
244  p.clearArguments();
245  p.addArgument( "wmsetbg" );
246  p.addArgument( "--maxscale" );
247  p.addArgument( "-u" );
248  p.addArgument( chosenFilename.ascii() );
249  p.start();
250  }
251 
252  //if there is an old file remove it
253  if(!oldFilename.isNull())
254  { tmpDir.remove( oldFilename ); }
255  //-------------------------------
256  #endif
257 }
QString getImageFilename()
Gets the image filename.
Definition: photo.cpp:192
Top level widget, encapsulates the title widget, the layout widget, and the toolbar widget...
Definition: window.h:39
bool copyFile(QString oldFilePath, QString newFilePath)
Copies a file from one location to another.
Definition: fileTools.cpp:61
bool scaleImage(QString fileIn, QString fileOut, int newWidth, int newHeight)
Scale image and save copy to disk.
Definition: imageTools.cpp:157
bool getImageSize(const char *filename, QSize &size)
Get image dimensions.
Definition: imageTools.cpp:192

§ setWallpaperSupported()

bool setWallpaperSupported ( )

Does Album Shaper support setting the wallpaper on this system?

Definition at line 259 of file wallpaperTools.cpp.

Referenced by SubalbumWidget::SubalbumWidget().

260 {
261  //OSX supported!
262  #if defined(Q_OS_MACX)
263  return true;
264 
265  //Windows is supported!
266  #elif defined(Q_OS_WIN)
267  return true;
268 
269  //Last try, check if dcop or gconftool-2 can be used
270  #else
271  Q3Process p;
272 
273  p.addArgument( "dcop" );
274  bool DCOP_Present = p.start();
275 
276  p.clearArguments();
277  p.addArgument( "gconftool-2" );
278  bool gconftool_Present = p.start();
279 
280  p.clearArguments();
281  p.addArgument( "wmsetbg" );
282  bool wmsetbg_Present = p.start();
283 
284  return ( DCOP_Present || gconftool_Present || wmsetbg_Present );
285 
286  #endif
287 }