001 /**
002 * ========================================
003 * JFreeReport : a free Java report library
004 * ========================================
005 *
006 * Project Info: http://reporting.pentaho.org/
007 *
008 * (C) Copyright 2000-2007, by Object Refinery Limited, Pentaho Corporation and Contributors.
009 *
010 * This library is free software; you can redistribute it and/or modify it under the terms
011 * of the GNU Lesser General Public License as published by the Free Software Foundation;
012 * either version 2.1 of the License, or (at your option) any later version.
013 *
014 * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
015 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
016 * See the GNU Lesser General Public License for more details.
017 *
018 * You should have received a copy of the GNU Lesser General Public License along with this
019 * library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
020 * Boston, MA 02111-1307, USA.
021 *
022 * [Java is a trademark or registered trademark of Sun Microsystems, Inc.
023 * in the United States and other countries.]
024 *
025 * ------------
026 * $Id: HtmlFileExportDialog.java,v 1.6 2007/04/01 18:49:30 taqua Exp $
027 * ------------
028 * (C) Copyright 2000-2005, by Object Refinery Limited.
029 * (C) Copyright 2005-2007, by Pentaho Corporation.
030 */
031
032 package org.jfree.report.modules.gui.swing.html;
033
034 import java.awt.BorderLayout;
035 import java.awt.Dialog;
036 import java.awt.Frame;
037 import java.awt.GridBagConstraints;
038 import java.awt.GridBagLayout;
039 import java.awt.GridLayout;
040 import java.awt.Insets;
041 import java.awt.event.ActionEvent;
042 import java.awt.event.KeyEvent;
043 import java.io.File;
044 import java.text.MessageFormat;
045 import java.util.ResourceBundle;
046 import javax.swing.AbstractAction;
047 import javax.swing.Action;
048 import javax.swing.ButtonGroup;
049 import javax.swing.JButton;
050 import javax.swing.JComponent;
051 import javax.swing.JFileChooser;
052 import javax.swing.JLabel;
053 import javax.swing.JOptionPane;
054 import javax.swing.JPanel;
055 import javax.swing.JRadioButton;
056 import javax.swing.JTextField;
057 import javax.swing.KeyStroke;
058
059 import org.jfree.base.config.ModifiableConfiguration;
060 import org.jfree.report.flow.ReportJob;
061 import org.jfree.report.modules.gui.common.DefaultIconTheme;
062 import org.jfree.report.modules.gui.common.GuiContext;
063 import org.jfree.report.modules.gui.swing.common.AbstractExportDialog;
064 import org.jfree.report.modules.gui.swing.common.JStatusBar;
065 import org.jfree.report.modules.gui.swing.common.localization.JLabelLocaleUpdateHandler;
066 import org.jfree.ui.FilesystemFilter;
067 import org.jfree.ui.action.ActionButton;
068 import org.jfree.util.Configuration;
069 import org.jfree.util.DefaultConfiguration;
070 import org.jfree.util.StringUtils;
071
072 /**
073 * A dialog that is used to perform the printing of a report into an HTML file.
074 */
075 public class HtmlFileExportDialog extends AbstractExportDialog
076 {
077 private static final String HTML_FILE_EXTENSION = ".html";
078 private static final String HTM_FILE_EXTENSION = ".htm";
079
080 /**
081 * An action to select the export target file.
082 */
083 private class ActionSelectTargetFile extends AbstractAction
084 {
085 /**
086 * Default constructor.
087 */
088 public ActionSelectTargetFile(final ResourceBundle resources)
089 {
090 putValue(Action.NAME, resources.getString("htmlexportdialog.select"));
091 }
092
093 /**
094 * Receives notification that the action has occurred.
095 *
096 * @param e the action event.
097 */
098 public void actionPerformed(final ActionEvent e)
099 {
100 performSelectFile();
101 }
102
103 }
104
105 private JTextField filenameField;
106 private JFileChooser fileChooserHtml;
107 private JTextField dataDirField;
108 private JStatusBar statusBar;
109
110 private JRadioButton rbPageableExport;
111 private JRadioButton rbStreamExport;
112 private JRadioButton rbFlowExport;
113
114 /**
115 * Creates a non-modal dialog without a title and without a specified
116 * <code>Frame</code> owner. A shared, hidden frame will be set as the owner
117 * of the dialog.
118 */
119 public HtmlFileExportDialog()
120 {
121 initializeComponents();
122 }
123
124 /**
125 * Creates a non-modal dialog without a title with the specified
126 * <code>Frame</code> as its owner. If <code>owner</code> is
127 * <code>null</code>, a shared, hidden frame will be set as the owner of the
128 * dialog.
129 *
130 * @param owner the <code>Frame</code> from which the dialog is displayed
131 */
132 public HtmlFileExportDialog(final Frame owner)
133 {
134 super(owner);
135 initializeComponents();
136 }
137
138 /**
139 * Creates a non-modal dialog without a title with the specified
140 * <code>Dialog</code> as its owner.
141 *
142 * @param owner the non-null <code>Dialog</code> from which the dialog is
143 * displayed
144 */
145 public HtmlFileExportDialog(final Dialog owner)
146 {
147 super(owner);
148 initializeComponents();
149 }
150
151 public String getFilename()
152 {
153 return filenameField.getText();
154 }
155
156 public void setFilename(final String filename)
157 {
158 this.filenameField.setText(filename);
159 }
160
161 private void initializeComponents()
162 {
163 JPanel contentPane = new JPanel();
164 contentPane.setLayout(new GridBagLayout());
165
166 filenameField = new JTextField();
167 filenameField.setColumns(60);
168 dataDirField = new JTextField();
169 dataDirField.setColumns(60);
170 statusBar = new JStatusBar(new DefaultIconTheme());
171
172 rbStreamExport = new JRadioButton(getResources().getString
173 ("htmlexportdialog.stream-export"));
174 rbStreamExport.setSelected(true);
175 rbFlowExport = new JRadioButton(getResources().getString
176 ("htmlexportdialog.flow-export"));
177 rbPageableExport = new JRadioButton(getResources().getString
178 ("htmlexportdialog.pageable-export"));
179
180 final ButtonGroup bgExport = new ButtonGroup();
181 bgExport.add(rbStreamExport);
182 bgExport.add(rbFlowExport);
183 bgExport.add(rbPageableExport);
184
185
186 final JPanel exportTypeSelectionPanel = new JPanel();
187 exportTypeSelectionPanel.setLayout(new GridLayout(3, 1, 5, 5));
188 exportTypeSelectionPanel.add(rbStreamExport);
189 exportTypeSelectionPanel.add(rbFlowExport);
190 exportTypeSelectionPanel.add(rbPageableExport);
191
192 JLabel targetLabel =
193 new JLabel(getResources().getString("htmlexportdialog.filename"));
194 addPropertyChangeListener("locale", new JLabelLocaleUpdateHandler(targetLabel,
195 SwingHtmlModule.BUNDLE_NAME, "htmlexportdialog.filename"));
196
197 JLabel dataLabel =
198 new JLabel(getResources().getString("htmlexportdialog.datafilename"));
199 addPropertyChangeListener("locale", new JLabelLocaleUpdateHandler(dataLabel,
200 SwingHtmlModule.BUNDLE_NAME, "htmlexportdialog.datafilename"));
201
202 final JLabel exportMethodLabel =
203 new JLabel(getResources().getString("htmlexportdialog.exportMethod"));
204 addPropertyChangeListener("locale", new JLabelLocaleUpdateHandler(exportMethodLabel,
205 SwingHtmlModule.BUNDLE_NAME, "htmlexportdialog.exportMethod"));
206
207 GridBagConstraints gbc = new GridBagConstraints();
208 gbc.fill = GridBagConstraints.NONE;
209 gbc.anchor = GridBagConstraints.WEST;
210 gbc.gridx = 0;
211 gbc.gridy = 0;
212 gbc.insets = new Insets(1, 1, 1, 5);
213 contentPane.add(targetLabel, gbc);
214
215 gbc = new GridBagConstraints();
216 gbc.fill = GridBagConstraints.NONE;
217 gbc.anchor = GridBagConstraints.WEST;
218 gbc.gridx = 0;
219 gbc.gridy = 1;
220 gbc.insets = new Insets(1, 1, 1, 5);
221 contentPane.add(dataLabel, gbc);
222
223 gbc = new GridBagConstraints();
224 gbc.anchor = GridBagConstraints.WEST;
225 gbc.fill = GridBagConstraints.HORIZONTAL;
226 gbc.gridx = 1;
227 gbc.gridy = 0;
228 gbc.gridwidth = 1;
229 gbc.weightx = 1;
230 gbc.insets = new Insets(1, 1, 1, 1);
231 contentPane.add(filenameField, gbc);
232
233 gbc = new GridBagConstraints();
234 gbc.anchor = GridBagConstraints.WEST;
235 gbc.fill = GridBagConstraints.HORIZONTAL;
236 gbc.gridx = 2;
237 gbc.gridy = 0;
238 final ActionSelectTargetFile selectTargetAction =
239 new ActionSelectTargetFile(getResources());
240 contentPane.add(new ActionButton(selectTargetAction), gbc);
241
242 gbc = new GridBagConstraints();
243 gbc.anchor = GridBagConstraints.WEST;
244 gbc.fill = GridBagConstraints.HORIZONTAL;
245 gbc.gridx = 1;
246 gbc.gridy = 1;
247 gbc.gridwidth = 1;
248 gbc.weightx = 1;
249 gbc.insets = new Insets(1, 1, 1, 1);
250 contentPane.add(dataDirField, gbc);
251
252 gbc = new GridBagConstraints();
253 gbc.anchor = GridBagConstraints.WEST;
254 gbc.fill = GridBagConstraints.HORIZONTAL;
255 gbc.gridx = 0;
256 gbc.gridy = 2;
257 contentPane.add(exportMethodLabel, gbc);
258
259 gbc = new GridBagConstraints();
260 gbc.anchor = GridBagConstraints.WEST;
261 gbc.fill = GridBagConstraints.HORIZONTAL;
262 gbc.gridx = 1;
263 gbc.gridy = 2;
264 gbc.gridwidth = 1;
265 gbc.insets = new Insets(1, 1, 1, 1);
266 contentPane.add(exportTypeSelectionPanel, gbc);
267
268
269 final JButton btnCancel = new ActionButton(getCancelAction());
270 final JButton btnConfirm = new ActionButton(getConfirmAction());
271
272 final JPanel buttonPanel = new JPanel();
273 buttonPanel.setLayout(new GridLayout());
274 buttonPanel.add(btnConfirm);
275 buttonPanel.add(btnCancel);
276 btnConfirm.setDefaultCapable(true);
277 buttonPanel.registerKeyboardAction(getConfirmAction(),
278 KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0),
279 JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
280
281 gbc = new GridBagConstraints();
282 gbc.fill = GridBagConstraints.NONE;
283 gbc.anchor = GridBagConstraints.EAST;
284 gbc.weightx = 1;
285 gbc.gridx = 0;
286 gbc.gridwidth = 3;
287 gbc.gridy = 15;
288 gbc.insets = new Insets(10, 0, 10, 0);
289 contentPane.add(buttonPanel, gbc);
290
291
292 final JPanel contentWithStatus = new JPanel();
293 contentWithStatus.setLayout(new BorderLayout());
294 contentWithStatus.add(contentPane, BorderLayout.CENTER);
295 contentWithStatus.add(statusBar, BorderLayout.SOUTH);
296
297 setContentPane(contentWithStatus);
298
299
300 getFormValidator().registerTextField(dataDirField);
301 getFormValidator().registerTextField(filenameField);
302 }
303
304
305 public JStatusBar getStatusBar()
306 {
307 return statusBar;
308 }
309
310 protected boolean performValidate()
311 {
312 getStatusBar().clear();
313
314 final String filename = getFilename();
315 if (filename.trim().length() == 0)
316 {
317 getStatusBar().setStatus(JStatusBar.TYPE_ERROR,
318 getResources().getString("htmlexportdialog.targetIsEmpty"));
319 return false;
320 }
321 final File f = new File(filename);
322 if (f.exists())
323 {
324 if (f.isFile() == false)
325 {
326 getStatusBar().setStatus(JStatusBar.TYPE_ERROR,
327 getResources().getString("htmlexportdialog.targetIsNoFile"));
328 return false;
329 }
330 if (f.canWrite() == false)
331 {
332 getStatusBar().setStatus(JStatusBar.TYPE_ERROR,
333 getResources().getString("htmlexportdialog.targetIsNotWritable"));
334 return false;
335 }
336
337 final String message = MessageFormat.format(getResources().getString
338 ("htmlexportdialog.targetExistsWarning"),
339 new Object[]{filename});
340 getStatusBar().setStatus(JStatusBar.TYPE_WARNING, message);
341 }
342
343
344 final String text = dataDirField.getText();
345 if (text.length() > 0)
346 {
347 final File dataDir = new File(text).getAbsoluteFile();
348 if (dataDir.exists())
349 {
350 // dataDirectory does exist ... if no directory : fail
351 if (dataDir.isDirectory() == false)
352 {
353 getStatusBar().setStatus(JStatusBar.TYPE_ERROR,
354 getResources().getString("htmlexportdialog.targetDataDirIsNoDirectory"));
355 return false;
356 }
357 }
358 }
359
360 return true;
361 }
362
363
364 protected boolean performConfirm ()
365 {
366 final String filename = getFilename();
367 final File f = new File(filename).getAbsoluteFile();
368 if (f.exists())
369 {
370 final String key1 = "htmlexportdialog.targetOverwriteConfirmation";
371 final String key2 = "htmlexportdialog.targetOverwriteTitle";
372 if (JOptionPane.showConfirmDialog(this,
373 MessageFormat.format(getResources().getString(key1),
374 new Object[]{getFilename()}),
375 getResources().getString(key2),
376 JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE)
377 == JOptionPane.NO_OPTION)
378 {
379 return false;
380 }
381 }
382
383 final String text = dataDirField.getText();
384 if (text.length() > 0)
385 {
386 final File dataDir = createDataDir(f.getParentFile(), text);
387 if (dataDir.exists() == false)
388 {
389 final String dataDirKey1 = "htmlexportdialog.targetCreateDataDirConfirmation";
390 final String dataDirKey2 = "htmlexportdialog.targetCreateDataDirTitle";
391 if (JOptionPane.showConfirmDialog(this,
392 MessageFormat.format(getResources().getString(dataDirKey1),
393 new Object[]{text}),
394 getResources().getString(dataDirKey2),
395 JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE)
396 == JOptionPane.NO_OPTION)
397 {
398 return false;
399 }
400 }
401 }
402 return true;
403 }
404
405 private File createDataDir(final File targetFile, final String dataDirectory)
406 {
407 File dataDirFile = new File(dataDirectory);
408 if (dataDirFile.isAbsolute())
409 {
410 return dataDirFile;
411 }
412
413 return new File (targetFile.getParentFile(), dataDirectory);
414 }
415
416 protected void initializeFromJob(ReportJob job, final GuiContext guiContext)
417 {
418 statusBar.setIconTheme(guiContext.getIconTheme());
419 }
420
421 protected String getConfigurationPrefix()
422 {
423 return "org.jfree.report.modules.gui.common.html.file.";
424 }
425
426 protected Configuration grabDialogContents(boolean full)
427 {
428 ModifiableConfiguration conf = new DefaultConfiguration();
429 if (full)
430 {
431 conf.setConfigProperty
432 ("org.jfree.report.modules.gui.common.html.file.TargetFileName", filenameField.getText());
433 conf.setConfigProperty
434 ("org.jfree.report.modules.gui.common.html.file.DataDirectory", dataDirField.getText());
435 }
436 conf.setConfigProperty
437 ("org.jfree.report.modules.gui.common.html.file.ExportMethod", getExportMethod());
438
439 return conf;
440 }
441
442 protected void setDialogContents(Configuration properties)
443 {
444 filenameField.setText(properties.getConfigProperty
445 ("org.jfree.report.modules.gui.common.html.file.TargetFileName", ""));
446 dataDirField.setText(properties.getConfigProperty
447 ("org.jfree.report.modules.gui.common.html.file.DataDirectory", ""));
448 setExportMethod(properties.getConfigProperty
449 ("org.jfree.report.modules.gui.common.html.file.ExportMethod", ""));
450 }
451
452 protected String getConfigurationSuffix()
453 {
454 return "_htmlexport_file";
455 }
456
457 public String getExportMethod()
458 {
459 if (rbPageableExport.isSelected())
460 {
461 return "pageable";
462 }
463 if (rbFlowExport.isSelected())
464 {
465 return "flow";
466 }
467 return "stream";
468 }
469
470 public void setExportMethod (String method)
471 {
472 if ("pageable".equals(method))
473 {
474 rbPageableExport.setSelected(true);
475 }
476 else if ("flow".equals(method))
477 {
478 rbFlowExport.setSelected(true);
479 }
480 else
481 {
482 rbStreamExport.setSelected(true);
483 }
484 }
485
486 public void clear()
487 {
488 filenameField.setText("");
489 dataDirField.setText("");
490 rbStreamExport.setSelected(true);
491 }
492
493 protected String getResourceBaseName()
494 {
495 return SwingHtmlModule.BUNDLE_NAME;
496 }
497
498
499 /**
500 * Selects a file to use as target for the report processing.
501 */
502 protected void performSelectFile()
503 {
504 final File file = new File(getFilename());
505
506 if (fileChooserHtml == null)
507 {
508 fileChooserHtml = new JFileChooser();
509 fileChooserHtml.addChoosableFileFilter
510 (new FilesystemFilter(new String[]{HTML_FILE_EXTENSION, HTM_FILE_EXTENSION},
511 getResources().getString("htmlexportdialog.html-documents"), true));
512 fileChooserHtml.setMultiSelectionEnabled(false);
513 }
514
515 fileChooserHtml.setCurrentDirectory(file);
516 fileChooserHtml.setSelectedFile(file);
517 final int option = fileChooserHtml.showSaveDialog(this);
518 if (option == JFileChooser.APPROVE_OPTION)
519 {
520 final File selFile = fileChooserHtml.getSelectedFile();
521 String selFileName = selFile.getAbsolutePath();
522
523 // Test if ends on html
524 if (StringUtils.endsWithIgnoreCase(selFileName, HTML_FILE_EXTENSION) == false)
525 {
526 selFileName = selFileName + HTML_FILE_EXTENSION;
527 }
528 setFilename(selFileName);
529 }
530 }
531
532 }