1   /**
2    * JHylaFax - A java client for HylaFAX.
3    *
4    * Copyright (C) 2005 by Steffen Pingel <steffenp@gmx.de>
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., 675 Mass Ave, Cambridge, MA 02139, USA.
19   */
20  package net.sf.jhylafax;
21  
22  import static net.sf.jhylafax.JHylaFAX.i18n;
23  import java.awt.Dimension;
24  import java.awt.event.ActionEvent;
25  import javax.swing.AbstractAction;
26  import javax.swing.Action;
27  import javax.swing.Box;
28  import javax.swing.ButtonGroup;
29  import javax.swing.JFrame;
30  import javax.swing.JLabel;
31  import javax.swing.JRadioButton;
32  import javax.swing.JSpinner;
33  import javax.swing.JTextField;
34  import javax.swing.SpinnerDateModel;
35  import javax.swing.event.ChangeEvent;
36  import javax.swing.event.ChangeListener;
37  import net.sf.jhylafax.addressbook.AbstractContactTransferHandler;
38  import net.sf.jhylafax.fax.FaxHelper;
39  import net.sf.jhylafax.fax.FaxJob;
40  import net.wimpi.pim.contact.facades.SimpleContact;
41  import net.wimpi.pim.contact.model.Contact;
42  import org.apache.commons.logging.Log;
43  import org.apache.commons.logging.LogFactory;
44  import org.xnap.commons.gui.Builder;
45  import org.xnap.commons.gui.DefaultDialog;
46  import org.xnap.commons.gui.Dialogs;
47  import org.xnap.commons.gui.action.AbstractXNapAction;
48  import org.xnap.commons.gui.completion.Completion;
49  import org.xnap.commons.gui.completion.DefaultCompletionModel;
50  import org.xnap.commons.settings.CompletionSettingDirector;
51  import com.jgoodies.forms.builder.DefaultFormBuilder;
52  import com.jgoodies.forms.layout.FormLayout;
53  
54  public abstract class AbstractFaxDialog extends DefaultDialog implements LocaleChangeListener {
55  
56  	private final static Log logger = LogFactory.getLog(AbstractQueuePanel.class);
57  	public static final int DEFAULT_COLUMNS = 20;
58  	
59  	private JobPanel jobPanel;
60  	private SpinnerDateModel dateModel;
61  	private FaxJob job;
62  	private JLabel dateLabel;
63  	private ParameterDialogAction parameterAction;
64  	private JRadioButton dateNowRadionButton;
65  	private JRadioButton dateLaterRadionButton;
66  	protected DefaultFormBuilder builder;
67  	private JTextField numberTextField;
68  	private JLabel numberLabel;
69  	private Completion numberCompletion;
70  	private DefaultCompletionModel numberCompletionModel;
71  	private AddressBookAction addressBookAction;
72  	
73  	public AbstractFaxDialog(JFrame owner) {
74  		super(owner, BUTTON_OKAY | BUTTON_CANCEL);
75  	
76  		FormLayout layout = new FormLayout("left:max(40dlu;pref), 3dlu, pref, 3dlu, min, min:grow", "");
77  		builder = new DefaultFormBuilder(layout);
78  		builder.setDefaultDialogBorder();
79  		setMainComponent(builder.getPanel());
80  		
81  		parameterAction = new ParameterDialogAction();
82  		getButtonPanel().add(Builder.createButton(parameterAction), 0);
83  	}
84  
85  	protected void addNumberTextField() {
86  		Box box = Box.createHorizontalBox();
87  
88  		addressBookAction = new AddressBookAction();
89  		
90  		numberTextField = new JTextField();
91  		numberTextField.setMaximumSize(new Dimension(Integer.MAX_VALUE, numberTextField.getPreferredSize().height));
92  		numberTextField.setTransferHandler(new ContactTransferHandler());
93  		//numberTextField.setDragEnabled(true);
94  		box.add(numberTextField);
95  		box.add(Box.createHorizontalStrut(4));
96  		box.add(Builder.createIconButton(addressBookAction));
97  		numberLabel = builder.append("", box, 4);
98  		builder.nextLine();
99  
100 		numberCompletionModel = new DefaultCompletionModel();
101 		numberCompletion = Builder.addCompletion(numberTextField, numberCompletionModel);
102 
103 		new CompletionSettingDirector(Settings.backstore, "number").restore(numberCompletion);
104 	}			
105 
106 	protected void addDateControls() {
107 		dateNowRadionButton = new JRadioButton();
108 		dateNowRadionButton.setSelected(true);
109 		dateLabel = builder.append("", dateNowRadionButton);
110 		builder.nextLine();
111 		
112 		dateLaterRadionButton = new JRadioButton();
113 		dateModel = new SpinnerDateModel();
114 		final JSpinner dateSpinner = new JSpinner(dateModel);
115 		dateSpinner.setEnabled(false);
116 		dateLaterRadionButton.addChangeListener(new ChangeListener() {
117 			public void stateChanged(ChangeEvent e) {
118 				dateSpinner.setEnabled(dateLaterRadionButton.isSelected());
119 			}			
120 		});
121 		builder.append("", dateLaterRadionButton, dateSpinner);
122 		builder.nextLine();
123 		
124 		ButtonGroup buttonGroup = new ButtonGroup();
125 		buttonGroup.add(dateNowRadionButton);
126 		buttonGroup.add(dateLaterRadionButton);		
127 	}
128 	
129 	@Override
130 	public boolean apply() {
131 		if (numberTextField != null) {
132 			if (numberTextField.getText().trim().length() == 0) {
133 				Dialogs.showError(this, i18n.tr("Please enter a number"), 
134 						i18n.tr("JHylaFAX Error"));
135 				numberTextField.requestFocus();
136 				return false;
137 			}
138 			getJob().setNumber(FaxHelper.extractNumber(numberTextField.getText().trim()));
139 			numberCompletionModel.insert(numberTextField.getText());
140 			new CompletionSettingDirector(Settings.backstore, "number").save(numberCompletion);
141 		}
142 		
143 		if (dateNowRadionButton != null) {
144 			job.setSendTime((dateNowRadionButton.isSelected()) 
145 					? null 
146 					: dateModel.getDate());
147 		}
148 		return true;
149 	}
150 	
151 	public FaxJob getJob() {
152 		return job;
153 	}
154 	
155 	public void updateLabels() {
156 		if (numberTextField != null) {
157 			numberLabel.setText(i18n.tr("Number"));
158 		}
159 		if (dateNowRadionButton != null) {
160 			dateLabel.setText(i18n.tr("Date"));
161 			dateNowRadionButton.setText(i18n.tr("Now"));
162 			dateLaterRadionButton.setText(i18n.tr("Later"));
163 		}		
164 		parameterAction.updateLabels();
165 	}
166 	
167 	public void revert() {
168 		if (numberTextField != null) {
169 			numberTextField.setText(getJob().getNumber());
170 		}
171 		if (dateNowRadionButton != null) {
172 			if (getJob().getSendTime() == null) {
173 				dateNowRadionButton.setSelected(true);
174 			}
175 			else {
176 				dateLaterRadionButton.setSelected(true);
177 				dateModel.setValue(job.getSendTime());
178 			}
179 		}
180 	}
181 
182 	public void setJob(FaxJob job) {
183 		this.job = job;
184 	}
185 	
186 	public void setNumber(String number) {
187 		if (numberTextField != null) {
188 			numberTextField.setText(number);
189 		}
190 	}
191 	
192 	private class ParameterDialogAction extends AbstractXNapAction implements LocaleChangeListener{
193 		
194 		private JobDialog dialog;
195 		
196 		public ParameterDialogAction() {
197 			//putValue(ICON_FILENAME, "configure.png");
198 		}
199 
200 		public void actionPerformed(ActionEvent e)
201 		{
202 			if (job == null) {
203 				return;
204 			}
205 			
206 			if (dialog == null) {
207 				dialog = new JobDialog(job);
208 				dialog.setLocationRelativeTo(AbstractFaxDialog.this);
209 				dialog.setModal(true);
210 			}
211 			
212 			if (!dialog.isVisible()) {
213 				dialog.revert();
214 				dialog.getJobPanel().setSenderEditable(getJob().getID() == -1);
215 				dialog.setVisible(true);
216 			}
217 		}
218 		
219 		public void updateLabels() {
220 			parameterAction.putValue(Action.NAME, i18n.tr("Parameter..."));
221 			parameterAction.putValue(Action.SHORT_DESCRIPTION, i18n.tr("Opens a dialog for entering job parameter"));
222 
223 			if (dialog != null) {
224 				dialog.updateLabels();
225 			}
226 		}
227 		
228 	}
229 
230 	private class InsertNumberAction extends AbstractAction {
231 		
232 		private boolean visible;
233 
234 		public InsertNumberAction() {
235 			visible = JHylaFAX.getInstance().getAddressBook().isVisible();
236 		}
237 
238 		public void actionPerformed(ActionEvent e)
239 		{
240 			SimpleContact[] contacts = JHylaFAX.getInstance().getAddressBook().getSelectedContacts();
241 			if (contacts.length > 0) {
242 				// TODO this is locale dependent
243 				String receipient = add("", "", contacts[0].getFirstname());
244 				receipient = add(receipient, " ", contacts[0].getLastname());
245 				receipient = add(receipient, ", ", contacts[0].getCompany());
246 				receipient += " <" + contacts[0].getFaxNumber() + ">";
247 				 
248 				setNumber(receipient);
249 			}
250 			JHylaFAX.getInstance().getAddressBook().setDoubleClickAction(null);
251 			JHylaFAX.getInstance().getAddressBook().setVisible(false);
252 			
253 			AbstractFaxDialog.this.requestFocus();
254 		 }
255 	
256 			public String add(String input, String glue, String token) {
257 				if (token != null) {
258 					return input + glue + token;
259 				}
260 				return input;
261 			}
262 		
263 	}
264 
265 	private class AddressBookAction extends AbstractXNapAction {
266 		
267 		public AddressBookAction() {
268 			putValue(ICON_FILENAME, "contents.png");
269 		}
270 
271 		public void actionPerformed(ActionEvent e)
272 		{
273 			JHylaFAX.getInstance().getAddressBook().setDoubleClickAction(new InsertNumberAction());
274 			JHylaFAX.getInstance().getAddressBook().setVisible(true);
275 		}
276 	
277 	}
278 
279 	private class ContactTransferHandler extends AbstractContactTransferHandler {
280 
281 		@Override
282 		public void importData(Contact[] contacts)
283 		{
284 			SimpleContact contact = new SimpleContact(contacts[0]);
285 			setNumber(contact.getFaxNumber());
286 		}
287 
288 	}
289 
290 }