1 /* Copyright (C) 2005-2011 Fabio Riccardi */ 2 3 package com.lightcrafts.platform.windows; 4 5 import java.awt.color.ICC_Profile; 6 import java.io.File; 7 import java.io.InputStream; 8 import java.io.IOException; 9 import java.util.*; 10 import java.util.stream.Stream; 11 12 import javax.swing.filechooser.FileSystemView; 13 import javax.swing.*; 14 15 import sun.awt.shell.ShellFolder; 16 17 import com.lightcrafts.platform.FileChooser; 18 import com.lightcrafts.platform.Platform; 19 import com.lightcrafts.platform.PrinterLayer; 20 import com.lightcrafts.utils.ColorProfileInfo; 21 import com.lightcrafts.utils.directory.DirectoryMonitor; 22 import com.lightcrafts.utils.directory.WindowsDirectoryMonitor; 23 import com.lightcrafts.utils.file.FileUtil; 24 import com.lightcrafts.utils.file.ICC_ProfileFileFilter; 25 import com.lightcrafts.utils.Version; 26 27 import static com.lightcrafts.platform.windows.WindowsFileUtil.*; 28 29 import com.lightcrafts.ui.LightZoneSkin; 30 import com.sun.java.swing.plaf.windows.WindowsLookAndFeel; 31 32 public final class WindowsPlatform extends Platform { 33 34 ////////// public ///////////////////////////////////////////////////////// 35 36 @Override getDefaultImageDirectory()37 public File getDefaultImageDirectory() { 38 final String path = 39 WindowsFileUtil.getFolderPathOf( FOLDER_MY_PICTURES ); 40 return path != null ? new File( path ) : null; 41 } 42 43 @Override getDirectoryMonitor()44 public DirectoryMonitor getDirectoryMonitor() { 45 return new WindowsDirectoryMonitor(); 46 } 47 48 @Override getDisplayProfile()49 public ICC_Profile getDisplayProfile() { 50 final String path = 51 WindowsColorProfileManager.getSystemDisplayProfilePath(); 52 if ( path == null ) 53 return null; 54 try { 55 final InputStream in = new File( path ).toURL().openStream(); 56 final ICC_Profile profile = ICC_Profile.getInstance( in ); 57 System.out.println( 58 "Display profile " + ColorProfileInfo.getNameOf( profile ) 59 ); 60 return profile; 61 } 62 catch ( IOException e ) { 63 return null; 64 } 65 } 66 67 @Override getExportProfiles()68 public Collection<ColorProfileInfo> getExportProfiles() { 69 return getColorProfiles(); 70 } 71 72 @Override getFileChooser()73 public FileChooser getFileChooser() { 74 return super.getFileChooser(); 75 // return new WindowsFileChooser(); 76 } 77 78 @Override getDisplayNameOf( File file )79 public String getDisplayNameOf( File file ) { 80 String displayName; 81 82 if ( file instanceof ShellFolder ) { 83 // 84 // This is a stupid hack fix when running on Vista that shows the 85 // GUID rather than the display name for the user's home directory 86 // (and a few other directories). 87 // 88 // See: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6488082 89 // 90 // It's apparently fixed for ShellFolder, but still broken for 91 // FileSystemView. 92 // 93 displayName = ((ShellFolder)file).getDisplayName(); 94 } else 95 displayName = getFileSystemView().getSystemDisplayName( file ); 96 97 if ( displayName.endsWith( ".lnk" ) ) { 98 // 99 // Windows shortcuts' display names sometimes incorrectly show the 100 // ".lnk" extension -- remove it. 101 // 102 displayName = FileUtil.trimExtensionOf( displayName ); 103 } 104 105 return displayName; 106 } 107 108 @Override getLightZoneDocumentsDirectory()109 public File getLightZoneDocumentsDirectory() { 110 final File myDocuments = 111 FileSystemView.getFileSystemView().getDefaultDirectory(); 112 return new File( myDocuments, Version.getApplicationName() ); 113 } 114 115 @Override getLookAndFeel()116 public LookAndFeel getLookAndFeel() { 117 LookAndFeel laf = LightZoneSkin.getLightZoneLookAndFeel(); 118 119 boolean addWindows = false; 120 121 if (addWindows) { 122 WindowsLookAndFeel quaqua = new WindowsLookAndFeel(); 123 124 UIDefaults quaquaDefaults = quaqua.getDefaults(); 125 Set<Object> quaquaKeys = quaquaDefaults.keySet(); 126 127 String[] fromQuaqua = new String[] { 128 "FileChooser", 129 }; 130 131 Stream.of(fromQuaqua).forEach(qk -> { 132 quaquaKeys.stream() 133 .filter(key -> key instanceof String && 134 ((String) key).startsWith(qk)) 135 .forEach(key -> { 136 Object value = quaquaDefaults.get(key); 137 UIManager.put(key, value); 138 }); 139 }); 140 } 141 142 return laf; 143 } 144 145 @Override getPathComponentsToPicturesFolder()146 public String[] getPathComponentsToPicturesFolder() { 147 final File picturesDir = 148 Platform.getPlatform().getDefaultImageDirectory(); 149 if ( picturesDir == null ) 150 return null; 151 final String[] picturesComponents = 152 picturesDir.toString().split( "\\\\" ); 153 if ( picturesComponents.length != 5 ) { 154 // 155 // We expect the components to be: 156 // 157 // C: 158 // Documents and Settings 159 // {user} 160 // My Documents 161 // My Pictures 162 // 163 // If it isn't, forget it. 164 // 165 return null; 166 } 167 final String[] wantedComponents = new String[2]; 168 System.arraycopy( picturesComponents, 3, wantedComponents, 0, 2 ); 169 return wantedComponents; 170 } 171 172 @Override getPhysicalMemoryInMB()173 public int getPhysicalMemoryInMB() { 174 return WindowsMemory.getPhysicalMemoryInMB(); 175 } 176 177 @Override getPrinterProfiles()178 public Collection<ColorProfileInfo> getPrinterProfiles() { 179 return getColorProfiles(); 180 } 181 182 @Override hasInternetConnectionTo( String hostName )183 public boolean hasInternetConnectionTo( String hostName ) { 184 return WindowsInternetConnection.hasConnection(); 185 } 186 187 @Override hideFile( File file )188 public void hideFile( File file ) throws IOException { 189 WindowsFileUtil.hideFile( file.getAbsolutePath() ); 190 } 191 192 @Override isKeyPressed( int keyCode )193 public boolean isKeyPressed( int keyCode ) { 194 return WindowsKeyUtil.isKeyPressed( keyCode ); 195 } 196 197 @Override isSpecialFile( File file )198 public File isSpecialFile( File file ) { 199 file = FileUtil.resolveAliasFile( file ); 200 if ( !(file instanceof WindowsSavedSearch) && 201 WindowsSavedSearch.isSavedSearch( file ) ) 202 return new WindowsSavedSearch( file ); 203 if ( isVista() ) 204 return isSpecialFileOnVista( file ); 205 return file; 206 } 207 208 /** 209 * True if it's newer than Vista. 210 */ isVista()211 public static boolean isVista() { 212 String version = System.getProperty( "os.version" ); 213 int majorVersion = Character.getNumericValue(version.charAt(0)); 214 return majorVersion >= 6; 215 } 216 217 @Override loadLibraries()218 public void loadLibraries() throws UnsatisfiedLinkError { 219 // We may need clib_jiio and either mlib_jai or mlib_jai_mmx, but we 220 // don't load these explicitly so JAI can make up its own mind. 221 System.loadLibrary( "Windows" ); 222 } 223 224 @Override moveFilesToTrash( String[] pathNames )225 public boolean moveFilesToTrash( String[] pathNames ) { 226 return WindowsFileUtil.moveToRecycleBin( pathNames ); 227 } 228 229 @Override readyToOpenFiles()230 public void readyToOpenFiles() { 231 if ( System.getProperty( "IDE" ) == null ) 232 WindowsLauncher.readyToOpenFiles(); 233 } 234 235 @Override resolveAliasFile( File file )236 public String resolveAliasFile( File file ) { 237 return WindowsFileUtil.resolveShortcut( file.getAbsolutePath() ); 238 } 239 240 @Override showFileInFolder( String path )241 public boolean showFileInFolder( String path ) { 242 return WindowsFileUtil.showInExplorer( path ); 243 } 244 245 @Override showHelpTopic( String topic )246 public void showHelpTopic( String topic ) { 247 WindowsHelp.showHelpTopic( topic ); 248 } 249 250 private PrinterLayer printerLayer = new WindowsPrinterLayer(); 251 252 @Override getPrinterLayer()253 public PrinterLayer getPrinterLayer() { 254 return printerLayer; 255 } 256 257 ////////// private //////////////////////////////////////////////////////// 258 getColorProfiles()259 private static synchronized Collection<ColorProfileInfo> getColorProfiles() { 260 if (m_profiles == null) { 261 String windir = System.getenv("WINDIR"); 262 if (windir == null) 263 windir = "C:\\WINDOWS"; 264 265 final File profileDir = new File( 266 windir + "\\system32\\spool\\drivers\\color"); 267 m_profiles = getColorProfiles(profileDir); 268 } 269 return m_profiles; 270 } 271 272 /** 273 * Checks whether the given {@link File} is special in some way on Windows 274 * Vista to deal with Vista-specific quirks. 275 * 276 * @param file The {@link File} to check. 277 * @return If the file is special, returns a new {@link File} to deal with 278 * a Vista-specific quirk; otherwise returns the passed-in file. 279 */ isSpecialFileOnVista( File file )280 private File isSpecialFileOnVista( File file ) { 281 // 282 // Under Vista, the user's Desktop has a special folder that's some 283 // kind of "link" to the user's home folder, i.e., Desktop\{user}. 284 // Java correctly recognizes it as a folder, but listFiles() on it 285 // always returns an empty array -- it must be a bug. 286 // 287 // To work around this, we check to see if the given file has the path 288 // Desktop\{user}. If so, we return a new File of the user's real home 289 // folder of C:\Users\{user} for which listFiles() works correctly. 290 // 291 final String displayName = getDisplayNameOf( file ); 292 if ( !displayName.equals( System.getProperty( "user.name" ) ) ) 293 return file; 294 final File parentDir = file.getParentFile(); 295 if ( parentDir == null ) 296 return file; 297 if ( parentDir.getName().equals( "Desktop" ) ) 298 return new File( System.getProperty( "user.home" ) ); 299 return file; 300 } 301 302 /** 303 * The ICC profiles from 304 * <code>$WINDIR\system32\spool\drivers\color</code>. 305 */ 306 private static Collection<ColorProfileInfo> m_profiles; 307 } 308 /* vim:set et sw=4 ts=4: */ 309