AlbumShaper 1.0a3
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.
 
bool setWallpaperSupported ()
 Does Album Shaper support setting the wallpaper on this system?
 

Function Documentation

◆ setWallpaper()

void setWallpaper ( Photo * phto)

Sets desktop wallpaper using specified photo.

Definition at line 37 of file wallpaperTools.cpp.

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:40
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.
bool getImageSize(const char *filename, QSize &size)
Get image dimensions.

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

Referenced by SubalbumWidget::setWallpaperAction().

◆ setWallpaperSupported()

bool setWallpaperSupported ( )

Does Album Shaper support setting the wallpaper on this system?

Definition at line 259 of file wallpaperTools.cpp.

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}

Referenced by SubalbumWidget::SubalbumWidget().