1 /* 2 * PhotosController.java 5 nov 2012 3 * 4 * Sweet Home 3D, Copyright (c) 2012 Emmanuel PUYBARET / eTeks <info@eteks.com> 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; either version 2 of the License, or 9 * (at your option) any later version. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with this program; if not, write to the Free Software 18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 */ 20 package com.eteks.sweethome3d.viewcontroller; 21 22 import java.beans.PropertyChangeEvent; 23 import java.beans.PropertyChangeListener; 24 import java.beans.PropertyChangeSupport; 25 import java.lang.ref.WeakReference; 26 import java.util.ArrayList; 27 import java.util.Collections; 28 import java.util.List; 29 30 import com.eteks.sweethome3d.model.Camera; 31 import com.eteks.sweethome3d.model.Home; 32 import com.eteks.sweethome3d.model.UserPreferences; 33 34 /** 35 * The controller of multiple photos creation view. 36 * @author Emmanuel Puybaret 37 * @since 4.0 38 */ 39 public class PhotosController extends AbstractPhotoController { 40 /** 41 * The properties that may be edited by the view associated to this controller. 42 */ 43 public enum Property {CAMERAS, SELECTED_CAMERAS, FILE_FORMAT, FILE_COMPRESSION_QUALITY} 44 45 private final Home home; 46 private final UserPreferences preferences; 47 private final ViewFactory viewFactory; 48 private final PropertyChangeSupport propertyChangeSupport; 49 private DialogView photoView; 50 51 private List<Camera> cameras; 52 private List<Camera> selectedCameras; 53 private String fileFormat; 54 private Float fileCompressionQuality; 55 PhotosController(Home home, UserPreferences preferences, View view3D, ViewFactory viewFactory, ContentManager contentManager)56 public PhotosController(Home home, UserPreferences preferences, View view3D, 57 ViewFactory viewFactory, ContentManager contentManager) { 58 super(home, preferences, view3D, contentManager); 59 this.home = home; 60 this.preferences = preferences; 61 this.viewFactory = viewFactory; 62 this.propertyChangeSupport = new PropertyChangeSupport(this); 63 64 this.cameras = Collections.emptyList(); 65 this.selectedCameras = Collections.emptyList(); 66 67 home.addPropertyChangeListener(Home.Property.STORED_CAMERAS, new HomeStoredCamerasChangeListener(this)); 68 updateProperties(); 69 } 70 71 /** 72 * Home cameras listener that updates properties when home cameras change. This listener is bound to this controller 73 * with a weak reference to avoid strong link between home and this controller. 74 */ 75 private static class HomeStoredCamerasChangeListener implements PropertyChangeListener { 76 private WeakReference<PhotosController> photosController; 77 HomeStoredCamerasChangeListener(PhotosController photoController)78 public HomeStoredCamerasChangeListener(PhotosController photoController) { 79 this.photosController = new WeakReference<PhotosController>(photoController); 80 } 81 propertyChange(PropertyChangeEvent ev)82 public void propertyChange(PropertyChangeEvent ev) { 83 // If controller was garbage collected, remove this listener from home 84 final AbstractPhotoController controller = this.photosController.get(); 85 if (controller == null) { 86 ((Home)ev.getSource()).removePropertyChangeListener(Home.Property.STORED_CAMERAS, this); 87 } else { 88 controller.updateProperties(); 89 } 90 } 91 } 92 93 /** 94 * Returns the view associated with this controller. 95 */ getView()96 public DialogView getView() { 97 // Create view lazily only once it's needed 98 if (this.photoView == null) { 99 this.photoView = this.viewFactory.createPhotosView(this.home, this.preferences, this); 100 } 101 return this.photoView; 102 } 103 104 /** 105 * Displays the view controlled by this controller. 106 */ displayView(View parentView)107 public void displayView(View parentView) { 108 getView().displayView(parentView); 109 } 110 111 /** 112 * Adds the property change <code>listener</code> in parameter to this controller. 113 */ addPropertyChangeListener(Property property, PropertyChangeListener listener)114 public void addPropertyChangeListener(Property property, PropertyChangeListener listener) { 115 this.propertyChangeSupport.addPropertyChangeListener(property.name(), listener); 116 } 117 118 /** 119 * Removes the property change <code>listener</code> in parameter from this controller. 120 */ removePropertyChangeListener(Property property, PropertyChangeListener listener)121 public void removePropertyChangeListener(Property property, PropertyChangeListener listener) { 122 this.propertyChangeSupport.removePropertyChangeListener(property.name(), listener); 123 } 124 125 /** 126 * Updates edited properties from the photo creation preferences. 127 */ updateProperties()128 protected void updateProperties() { 129 // Update properties only once this object is initialized 130 if (this.home != null) { 131 super.updateProperties(); 132 setCameras(this.home.getStoredCameras()); 133 setSelectedCameras(this.home.getStoredCameras()); 134 } 135 } 136 137 /** 138 * Returns the cameras available to create photos. 139 */ getCameras()140 public List<Camera> getCameras() { 141 return this.cameras; 142 } 143 144 /** 145 * Sets the cameras available to create photos. 146 */ setCameras(List<Camera> cameras)147 private void setCameras(List<Camera> cameras) { 148 if (!cameras.equals(this.cameras)) { 149 List<Camera> oldCameras = this.cameras; 150 this.cameras = new ArrayList<Camera>(cameras); 151 this.propertyChangeSupport.firePropertyChange( 152 Property.CAMERAS.name(), Collections.unmodifiableList(oldCameras), Collections.unmodifiableList(cameras)); 153 } 154 } 155 156 /** 157 * Returns the selected cameras to create photos. 158 */ getSelectedCameras()159 public List<Camera> getSelectedCameras() { 160 return this.selectedCameras; 161 } 162 163 /** 164 * Sets the selected cameras to create photos. 165 */ setSelectedCameras(List<Camera> selectedCameras)166 public void setSelectedCameras(List<Camera> selectedCameras) { 167 if (!selectedCameras.equals(this.selectedCameras)) { 168 List<Camera> oldSelectedCameras = this.selectedCameras; 169 this.selectedCameras = new ArrayList<Camera>(selectedCameras); 170 this.propertyChangeSupport.firePropertyChange( 171 Property.SELECTED_CAMERAS.name(), Collections.unmodifiableList(oldSelectedCameras), Collections.unmodifiableList(selectedCameras)); 172 } 173 } 174 175 /** 176 * Returns the format used to save image files. 177 */ getFileFormat()178 public String getFileFormat() { 179 return this.fileFormat; 180 } 181 182 /** 183 * Sets the format used to save image files. 184 */ setFileFormat(String fileFormat)185 public void setFileFormat(String fileFormat) { 186 if (fileFormat != this.fileFormat) { 187 String oldFileFormat = this.fileFormat; 188 this.fileFormat = fileFormat; 189 this.propertyChangeSupport.firePropertyChange(Property.FILE_FORMAT.name(), oldFileFormat, fileFormat); 190 } 191 } 192 193 194 /** 195 * Returns the compression quality used to save image files. 196 */ getFileCompressionQuality()197 public Float getFileCompressionQuality() { 198 return this.fileCompressionQuality; 199 } 200 201 /** 202 * Sets the compression quality used to save image files. 203 */ setFileCompressionQuality(Float fileCompressionQuality)204 public void setFileCompressionQuality(Float fileCompressionQuality) { 205 if (fileCompressionQuality != this.fileCompressionQuality) { 206 Float oldFileCompressionQuality = this.fileCompressionQuality; 207 this.fileCompressionQuality = fileCompressionQuality; 208 this.propertyChangeSupport.firePropertyChange(Property.FILE_COMPRESSION_QUALITY.name(), oldFileCompressionQuality, fileCompressionQuality); 209 } 210 } 211 } 212