Package org.pentaho.reporting.designer.core

Source Code of org.pentaho.reporting.designer.core.ReportDesignerFrame$PageTextHandler

/*!
* This program is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License, version 2.1 as published by the Free Software
* Foundation.
*
* You should have received a copy of the GNU Lesser General Public License along with this
* program; if not, you can obtain a copy at http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html
* or from the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU Lesser General Public License for more details.
*
* Copyright (c) 2002-2013 Pentaho Corporation..  All rights reserved.
*/

package org.pentaho.reporting.designer.core;

import java.awt.AWTEvent;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Cursor;
import java.awt.KeyboardFocusManager;
import java.awt.Toolkit;
import java.awt.dnd.DnDConstants;
import java.awt.dnd.DragSource;
import java.awt.dnd.DropTarget;
import java.awt.dnd.DropTargetAdapter;
import java.awt.dnd.DropTargetDragEvent;
import java.awt.dnd.DropTargetDropEvent;
import java.awt.dnd.DropTargetEvent;
import java.awt.event.AWTEventListener;
import java.awt.event.ActionEvent;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.beans.IndexedPropertyChangeEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.io.File;
import java.util.Arrays;
import java.util.List;
import java.util.Locale;
import javax.swing.Action;
import javax.swing.BorderFactory;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JRadioButtonMenuItem;
import javax.swing.JScrollBar;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
import javax.swing.JToolBar;
import javax.swing.SwingUtilities;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.plaf.TabbedPaneUI;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.TreeModel;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.pentaho.reporting.designer.core.actions.elements.InsertElementAction;
import org.pentaho.reporting.designer.core.actions.elements.MorphAction;
import org.pentaho.reporting.designer.core.actions.elements.barcode.BarcodeTypeAction;
import org.pentaho.reporting.designer.core.actions.global.AboutAction;
import org.pentaho.reporting.designer.core.actions.global.OpenReportAction;
import org.pentaho.reporting.designer.core.actions.global.OpenSampleReportAction;
import org.pentaho.reporting.designer.core.actions.global.QuitAction;
import org.pentaho.reporting.designer.core.actions.global.SelectTabAction;
import org.pentaho.reporting.designer.core.actions.global.SettingsAction;
import org.pentaho.reporting.designer.core.actions.report.CloseAllReportsAction;
import org.pentaho.reporting.designer.core.actions.report.CloseChildReportsAction;
import org.pentaho.reporting.designer.core.actions.report.CloseOtherReportsAction;
import org.pentaho.reporting.designer.core.actions.report.CloseReportAction;
import org.pentaho.reporting.designer.core.actions.report.CloseUnmodifiedReportsAction;
import org.pentaho.reporting.designer.core.editor.ContextMenuUtility;
import org.pentaho.reporting.designer.core.editor.ElementPropertiesPanel;
import org.pentaho.reporting.designer.core.editor.ReportDocumentContext;
import org.pentaho.reporting.designer.core.editor.ReportRenderContext;
import org.pentaho.reporting.designer.core.editor.ReportRendererComponent;
import org.pentaho.reporting.designer.core.editor.fieldselector.FieldSelectorPaletteDialog;
import org.pentaho.reporting.designer.core.editor.palette.PaletteButton;
import org.pentaho.reporting.designer.core.frame.RecentFilesUpdateHandler;
import org.pentaho.reporting.designer.core.inspections.InspectionSidePanePanel;
import org.pentaho.reporting.designer.core.settings.WorkspaceSettings;
import org.pentaho.reporting.designer.core.status.StatusBar;
import org.pentaho.reporting.designer.core.util.IconLoader;
import org.pentaho.reporting.designer.core.util.docking.Category;
import org.pentaho.reporting.designer.core.util.docking.GlobalPane;
import org.pentaho.reporting.designer.core.util.docking.InternalWindow;
import org.pentaho.reporting.designer.core.util.exceptions.UncaughtExceptionsModel;
import org.pentaho.reporting.designer.core.welcome.SamplesTreeBuilder;
import org.pentaho.reporting.designer.core.welcome.WelcomePane;
import org.pentaho.reporting.designer.core.widgets.FancyTabbedPane;
import org.pentaho.reporting.designer.core.widgets.TabRenderer;
import org.pentaho.reporting.designer.core.xul.ActionSwingMenuitem;
import org.pentaho.reporting.designer.core.xul.XulDesignerFrame;
import org.pentaho.reporting.engine.classic.core.metadata.ElementMetaData;
import org.pentaho.reporting.engine.classic.core.metadata.ElementTypeRegistry;
import org.pentaho.reporting.engine.classic.core.metadata.GroupedMetaDataComparator;
import org.pentaho.reporting.engine.classic.extensions.modules.sbarcodes.BarcodeTypePropertyEditor;
import org.pentaho.reporting.libraries.base.util.DebugLog;
import org.pentaho.reporting.libraries.base.util.ObjectUtilities;
import org.pentaho.reporting.libraries.base.util.StringUtils;
import org.pentaho.reporting.libraries.designtime.swing.MacOSXIntegration;
import org.pentaho.ui.xul.XulComponent;
import org.pentaho.ui.xul.XulException;
import org.pentaho.ui.xul.components.XulMenuitem;
import org.pentaho.ui.xul.containers.XulMenupopup;
import org.pentaho.ui.xul.swing.tags.SwingMenuseparator;

public class ReportDesignerFrame extends JFrame
{
  /**
   * Class for handling cursor changes during drags
   * See PRD-1674
   */
  public class DefaultDropTargetListener extends DropTargetAdapter
  {
    public void dragEnter(final DropTargetDragEvent dtde)
    {
      final DropTarget dropTarget = (DropTarget) dtde.getSource();
      dropTarget.getComponent().setCursor(DragSource.DefaultCopyNoDrop);
    }

    public void dragExit(final DropTargetEvent dte)
    {
      final DropTarget dropTarget = (DropTarget) dte.getSource();
      dropTarget.getComponent().setCursor(Cursor.getDefaultCursor());
    }

    public void drop(final DropTargetDropEvent dtde)
    {
      final DropTarget dropTarget = (DropTarget) dtde.getSource();
      dropTarget.getComponent().setCursor(Cursor.getDefaultCursor());
      dtde.rejectDrop();
    }
  }

  private static class ScrollbarSyncHandler extends ComponentAdapter
  {
    private final JScrollBar theVerticalScrollBar;
    private final JToolBar toolBar;

    public ScrollbarSyncHandler(final JScrollBar theVerticalScrollBar, final JToolBar toolBar)
    {
      this.theVerticalScrollBar = theVerticalScrollBar;
      this.toolBar = toolBar;
    }

    public void componentResized(final ComponentEvent e)
    {
      if (theVerticalScrollBar.isShowing())
      {
        toolBar.setBorder(BorderFactory.createEmptyBorder(25, 0, 0, 19));
      }
      else
      {
        toolBar.setBorder(BorderFactory.createEmptyBorder(25, 0, 0, 4));
      }
    }
  }

  private class WindowCloseHandler extends WindowAdapter
  {
    private WindowCloseHandler()
    {
    }

    /**
     * Invoked when a window is in the process of being closed. The close operation can be overridden at this point.
     */
    public void windowClosing(final WindowEvent e)
    {
      final QuitAction quitAction = new QuitAction();
      quitAction.setReportDesignerContext(context);
      quitAction.actionPerformed(new ActionEvent(this, 0, "quit", 0)); // NON-NLS
    }
  }

  private class ReportTabActivationHandler implements ChangeListener, PropertyChangeListener
  {
    private ReportTabActivationHandler()
    {
    }

    public void propertyChange(final PropertyChangeEvent evt)
    {
      final ReportDesignerDocumentContext activeContext = getContext().getActiveDocument();
      final JTabbedPane editorPanes = getReportEditorPane();
      final int i = findTabForContext(activeContext);
      if (i != -1 && editorPanes.getSelectedIndex() != i)
      {
        editorPanes.setSelectedIndex(i);
      }

      updateFrameTitle();
    }

    private int findTabForContext(final ReportDesignerDocumentContext activeContext)
    {
      final JTabbedPane editorPanes = getReportEditorPane();
      final int count = editorPanes.getTabCount();
      for (int i = 0; i < count; i++)
      {
        final Component c = editorPanes.getComponentAt(i);
        if (c instanceof ReportRendererComponent)
        {
          final ReportRendererComponent rrc = (ReportRendererComponent) c;
          if (rrc.getRenderContext() == activeContext)
          {
            return i;
          }
        }
      }
      return -1;
    }

    /**
     * Invoked when the target of the listener has changed its state.
     *
     * @param e a ChangeEvent object
     */
    public void stateChanged(final ChangeEvent e)
    {
      final JTabbedPane editorPanes = getReportEditorPane();
      final DefaultReportDesignerContext context = getContext();
      if (editorPanes.getTabCount() == 0)
      {
        context.setActiveDocument(null);
        return;
      }

      final int index = editorPanes.getSelectedIndex();
      if (index == -1 || editorPanes.getComponentAt(index) instanceof ReportRendererComponent == false)
      {
        context.setActiveDocument(null);
      }
      else
      {
        // try to sync the context.
        final ReportRendererComponent rendererComponent = (ReportRendererComponent) editorPanes.getComponentAt(index);
        final ReportDocumentContext rendererContext = rendererComponent.getRenderContext();
        for (int i = 0; i < context.getReportRenderContextCount(); i++)
        {
          final ReportRenderContext context1 = context.getReportRenderContext(i);
          if (context1 == rendererContext)
          {
            context.setActiveDocument(rendererContext);
            rendererContext.onDocumentActivated();
            return;
          }
        }

        if (context.getReportRenderContextCount() > 0)
        {
          // we couldn't find a context, but we do at least have a context
          // instead of blowing away the context, let's grab one and
          // attempt to use it
          // this works around PRD-1609
          context.setActiveDocument(context.getReportRenderContext(context.getReportRenderContextCount() - 1));
        }
        else
        {
          // not found, so we are probably in a remove at the moment.
          context.setActiveDocument(null);
        }
      }
    }
  }

  private class StatusTextHandler implements PropertyChangeListener
  {
    private StatusTextHandler()
    {
    }

    /**
     * This method gets called when a bound property is changed.
     *
     * @param evt A PropertyChangeEvent object describing the event source and the property that has changed.
     */

    public void propertyChange(final PropertyChangeEvent evt)
    {
      getStatusBar().setGeneralInfoText(getContext().getStatusText());
    }
  }

  private class ReportEditorContextHandler implements PropertyChangeListener
  {
    private ReportEditorContextHandler()
    {
    }

    /**
     * This method gets called when a bound property is changed.
     *
     * @param evt A PropertyChangeEvent object describing the event source and the property that has changed.
     */

    public void propertyChange(final PropertyChangeEvent evt)
    {
      if (ReportDesignerContext.REPORT_RENDER_CONTEXT_PROPERTY.equals(evt.getPropertyName()) == false)
      {
        return;
      }

      if (!(evt instanceof IndexedPropertyChangeEvent))
      {
        throw new UnsupportedOperationException();
      }

      final JTabbedPane editorPanes = getReportEditorPane();
      final IndexedPropertyChangeEvent ievt = (IndexedPropertyChangeEvent) evt;
      if (ievt.getNewValue() != null)
      {
        // added
        final ReportRenderContext renderContext = (ReportRenderContext) ievt.getNewValue();
        DefaultReportDesignerContext reportDesignerContext = getContext();
        final ReportRendererComponent rendererComponent = new ReportRendererComponent(reportDesignerContext, renderContext);

        final String title = renderContext.getTabName();
        final Icon icon = renderContext.getIcon();
        final TabRenderer tabRenderer = new TabRenderer(icon, title, reportDesignerContext, editorPanes);
        editorPanes.addTab(title, null, rendererComponent);
        editorPanes.setTabComponentAt(editorPanes.getTabCount() - 1, tabRenderer);
        editorPanes.setSelectedComponent(rendererComponent);
        renderContext.addPropertyChangeListener("tabName",
            new DocumentNameChangeHandler(renderContext, tabRenderer, editorPanes.getTabCount() - 1));

      }
      else if (ievt.getOldValue() != null)
      {
        if (editorPanes.getTabCount() <= 0)
        {
          return;
        }
        // removed
        int index = ievt.getIndex();
        final ReportRenderContext reportRenderContext = (ReportRenderContext) ievt.getOldValue();
        boolean removedTab = false;

        for (int i = 0; i < editorPanes.getTabCount(); i++)
        {
          final Component tabContent = editorPanes.getComponentAt(i);
          if (tabContent instanceof ReportRendererComponent)
          {
            final ReportRendererComponent myReportRenderer = (ReportRendererComponent) tabContent;
            if (myReportRenderer.getRenderContext() == reportRenderContext)
            {
              index = i;
              editorPanes.removeTabAt(index);
              removedTab = true;
              myReportRenderer.dispose();
              break;
            }
          }
        }

        // if we didn't remove a tab, the tab was probably not a report, so remove it by index
        if (!removedTab)
        {
          editorPanes.removeTabAt(index);
        }

        // unregister the listeners ...
        if (editorPanes.getTabCount() > 0)
        {
          if (index < editorPanes.getTabCount())
          {
            editorPanes.setSelectedIndex(index);
          }
          else
          {
            editorPanes.setSelectedIndex(editorPanes.getTabCount() - 1);
          }
        }
      }

      recomputeAllTabTitles();
      rebuildReportMenu();
    }
  }

  private class ReportTabPanePopupHandler extends MouseAdapter
  {
    private ReportTabPanePopupHandler()
    {
    }

    private void handlePopup(final MouseEvent e)
    {
      final JTabbedPane reportEditorPane = getReportEditorPane();
      final TabbedPaneUI ui = reportEditorPane.getUI();
      final int tabIndex = ui.tabForCoordinate(reportEditorPane, e.getX(), e.getY());
      final JPopupMenu popupMenu = new JPopupMenu();

      final CloseReportAction closeThisAction = new CloseReportAction(tabIndex);
      closeThisAction.setReportDesignerContext(getContext());
      final CloseChildReportsAction closeChildsAction = new CloseChildReportsAction(tabIndex);
      closeChildsAction.setReportDesignerContext(getContext());
      final CloseOtherReportsAction closeOthersAction = new CloseOtherReportsAction(tabIndex);
      closeOthersAction.setReportDesignerContext(getContext());
      final CloseAllReportsAction closeAllAction = new CloseAllReportsAction();
      closeAllAction.setReportDesignerContext(getContext());
      final CloseUnmodifiedReportsAction closeUnmodifiedReportsAction = new CloseUnmodifiedReportsAction();
      closeUnmodifiedReportsAction.setReportDesignerContext(getContext());

      popupMenu.add(new JMenuItem(closeThisAction));
      popupMenu.addSeparator();
      popupMenu.add(new JMenuItem(closeChildsAction));
      popupMenu.add(new JMenuItem(closeUnmodifiedReportsAction));
      popupMenu.add(new JMenuItem(closeOthersAction));
      popupMenu.add(new JMenuItem(closeAllAction));
      popupMenu.show(reportEditorPane, e.getX(), e.getY());
    }

    public void mouseClicked(final MouseEvent e)
    {
      if (e.isPopupTrigger())
      {
        handlePopup(e);
      }
    }

    public void mousePressed(final MouseEvent e)
    {
      if (e.isPopupTrigger())
      {
        handlePopup(e);
      }
    }

    public void mouseReleased(final MouseEvent e)
    {
      if (e.isPopupTrigger())
      {
        handlePopup(e);
      }
    }
  }

  private class FrameViewController implements ReportDesignerView
  {
    private PropertyChangeSupport propertyChangeSupport;
    private XulDesignerFrame xulDesignerFrame;
    private Component parent;

    private FrameViewController(final Component parent)
    {
      this.propertyChangeSupport = new PropertyChangeSupport(this);
      this.parent = parent;
    }

    private void initializeXulDesignerFrame(final ReportDesignerContext context) throws XulException
    {
      this.xulDesignerFrame = new XulDesignerFrame();
      this.xulDesignerFrame.setReportDesignerContext(context);
    }

    public void addPropertyChangeListener(final PropertyChangeListener listener)
    {
      propertyChangeSupport.addPropertyChangeListener(listener);
    }

    public void removePropertyChangeListener(final PropertyChangeListener listener)
    {
      propertyChangeSupport.removePropertyChangeListener(listener);
    }

    public void addPropertyChangeListener(final String propertyName, final PropertyChangeListener listener)
    {
      propertyChangeSupport.addPropertyChangeListener(propertyName, listener);
    }

    public void removePropertyChangeListener(final String propertyName, final PropertyChangeListener listener)
    {
      propertyChangeSupport.removePropertyChangeListener(propertyName, listener);
    }

    public boolean isStructureVisible()
    {
      final Category reportTreeToolWindow = getReportTreeToolWindow();
      return reportTreeToolWindow != null && reportTreeToolWindow.isMinimized() == false;
    }

    public void setStructureVisible(final boolean visible)
    {
      final Category reportTreeToolWindow = getReportTreeToolWindow();
      final boolean oldValue = reportTreeToolWindow.isMinimized() == false;
      reportTreeToolWindow.setMinimized(visible == false);
      propertyChangeSupport.firePropertyChange(STRUCTURE_VISIBLE_PROPERTY, oldValue, visible);
    }

    public boolean isPropertiesEditorVisible()
    {
      final Category attributeToolWindow = getAttributeToolWindow();
      if (attributeToolWindow == null)
      {
        return false;
      }
      return attributeToolWindow.isMinimized() == false;
    }

    public void setPropertiesEditorVisible(final boolean visible)
    {
      final Category attributeToolWindow = getAttributeToolWindow();
      final boolean oldValue = attributeToolWindow.isMinimized() == false;
      attributeToolWindow.setMinimized(visible == false);
      propertyChangeSupport.firePropertyChange(PROPERTIES_EDITOR_VISIBLE_PROPERTY, oldValue, visible);
    }

    public boolean isMessagesVisible()
    {
      final Category inspectionsToolWindow = getInspectionsToolWindow();
      return inspectionsToolWindow != null && !inspectionsToolWindow.isMinimized();
    }

    public void setMessagesVisible(final boolean visible)
    {
      final Category inspectionsToolWindow = getInspectionsToolWindow();
      final boolean oldValue = inspectionsToolWindow.isMinimized() == false;
      inspectionsToolWindow.setMinimized(visible == false);
      propertyChangeSupport.firePropertyChange(MESSAGES_VISIBLE_PROPERTY, oldValue, visible);
    }

    public boolean isPreviewVisible()
    {
      final JTabbedPane reportEditorPane = getReportEditorPane();
      if (reportEditorPane == null || reportEditorPane.getTabCount() == 0)
      {
        return false;
      }
      if (reportEditorPane.getSelectedComponent() instanceof ReportRendererComponent)
      {
        final ReportRendererComponent rendererComponent = (ReportRendererComponent) reportEditorPane.getSelectedComponent();
        return !rendererComponent.isDesignVisible();
      }
      return false;
    }

    public void setPreviewVisible(final boolean visible)
    {
      final boolean oldValue = isPreviewVisible();
      final JTabbedPane reportEditorPane = getReportEditorPane();
      if (reportEditorPane != null && reportEditorPane.getTabCount() > 0)
      {
        if (reportEditorPane.getSelectedComponent() instanceof ReportRendererComponent)
        {
          final ReportRendererComponent rendererComponent = (ReportRendererComponent) reportEditorPane.getSelectedComponent();
          if (visible)
          {
            rendererComponent.showPreview();
          }
          else
          {
            rendererComponent.showDesign();
          }
        }
      }
      propertyChangeSupport.firePropertyChange(PREVIEW_VISIBLE_PROPERTY, oldValue, visible);
    }

    public boolean isWelcomeVisible()
    {
      if (welcomePane == null)
      {
        return false;
      }
      return welcomePane.isVisible();
    }

    public void setWelcomeVisible(final boolean visible)
    {
      if (welcomePane == null)
      {
        return;
      }
      welcomePane.setVisible(visible);
      welcomePane.toFront();
    }

    public boolean isFieldSelectorVisible()
    {
      if (fieldSelectorPaletteDialog == null)
      {
        return false;
      }
      return fieldSelectorPaletteDialog.isVisible();
    }

    public void setFieldSelectorVisible(final boolean visible)
    {
      if (fieldSelectorPaletteDialog == null)
      {
        return;
      }
      fieldSelectorPaletteDialog.setVisible(visible);
      fieldSelectorPaletteDialog.toFront();
    }

    public void redrawAll()
    {
      getReportEditorPane().invalidate();
      getReportEditorPane().revalidate();
      getReportEditorPane().repaint();
    }

    public void showDataTree()
    {
      treePanel.refreshTabPanel(getAttributeEditorPanel());
      treePanel.showDataTab();
    }

    public JPopupMenu getPopupMenu(final String id)
    {
      return xulDesignerFrame.getComponent(id, JPopupMenu.class);
    }

    public JComponent getToolBar(final String id)
    {
      JComponent toolBar = xulDesignerFrame.getComponent(id, JComponent.class);
      if (toolBar instanceof JToolBar)
      {
        final JToolBar realToolBar = (JToolBar) toolBar;
        realToolBar.setFloatable(false);
      }
      return toolBar;
    }

    public Component getParent()
    {
      return parent;
    }

    public <T extends JComponent> T getComponent(final String id, final Class<T> type)
    {
      T xulComponentById = xulDesignerFrame.getComponent(id, type);
      if (type.isInstance(xulComponentById))
      {
        return (T) xulComponentById;
      }
      return null;
    }

    public <T extends XulComponent> T getXulComponent(final String id, final Class<T> type)
    {
      T xulComponentById = xulDesignerFrame.getXulComponent(id, type);
      if (type.isInstance(xulComponentById))
      {
        return (T) xulComponentById;
      }
      return null;
    }

    public ActionSwingMenuitem createMenuItem(final Action action)
    {
      return xulDesignerFrame.createMenu(action);
    }

    public XulMenupopup createPopupMenu(final String label, final XulComponent parent) throws XulException
    {
      return xulDesignerFrame.createPopupMenu(label, parent);
    }
  }

  private class ShowWelcomeScreenTask implements Runnable
  {
    public void run()
    {
      viewController.setWelcomeVisible(WorkspaceSettings.getInstance().isShowLauncher());
    }
  }

  private class DragSelectionToggleHandler implements AWTEventListener
  {
    private DragSelectionToggleHandler()
    {
    }

    /**
     * Invoked when an event is dispatched in the AWT.
     */
    public void eventDispatched(final AWTEvent event)
    {
      if (event instanceof KeyEvent == false)
      {
        return;
      }
      final KeyEvent keyevent = (KeyEvent) event;
      if (KeyboardFocusManager.getCurrentKeyboardFocusManager().getActiveWindow() ==
          ReportDesignerFrame.this)
      {
        context.setSelectionWaiting(keyevent.isShiftDown());
      }
    }
  }

  private class PageTextHandler implements PropertyChangeListener
  {
    /**
     * This method gets called when a bound property is changed.
     *
     * @param evt A PropertyChangeEvent object describing the event source
     *            and the property that has changed.
     */
    public void propertyChange(final PropertyChangeEvent evt)
    {
      statusBar.setPages(context.getPage(), context.getPageTotal());
    }
  }

  private class DocumentNameChangeHandler implements PropertyChangeListener
  {
    private ReportDesignerDocumentContext documentContext;
    private TabRenderer tabRenderer;
    private int tabIndex;

    private DocumentNameChangeHandler(final ReportDesignerDocumentContext documentContext,
                                      final TabRenderer tabRenderer,
                                      final int tabIndex)
    {
      this.documentContext = documentContext;
      this.tabRenderer = tabRenderer;
      this.tabIndex = tabIndex;
    }

    public void propertyChange(final PropertyChangeEvent evt)
    {
      String tabName = documentContext.getTabName();
      tabRenderer.setRawTabName(tabName);
      getReportEditorPane().setTitleAt(tabIndex, tabName);
      recomputeAllTabTitles();
      rebuildReportMenu();
    }
  }

  private static final Log logger = LogFactory.getLog(ReportDesignerFrame.class);
  private JTabbedPane reportEditorPane;
  private GlobalPane dockingPane;
  private StatusBar statusBar;
  private DefaultReportDesignerContext context;
  private Category attributeToolWindow;
  private Category reportTreeToolWindow;
  private Category inspectionsToolWindow;
  private FrameViewController viewController;
  private ElementPropertiesPanel attributeEditorPanel;
  private WelcomePane welcomePane;
  private FieldSelectorPaletteDialog fieldSelectorPaletteDialog;
  private TreeSidePanel treePanel;

  public ReportDesignerFrame() throws XulException
  {
    setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
    final ImageIcon icon = IconLoader.getInstance().getProductIcon();
    if (icon != null)
    {
      setIconImage(icon.getImage());
    }

    setTitle(Messages.getString("ReportDesignerFrame.Title"));
    addWindowListener(new WindowCloseHandler());

    viewController = new FrameViewController(this);
    context = new DefaultReportDesignerContext(viewController);
    viewController.initializeXulDesignerFrame(context);

    welcomePane = new WelcomePane(ReportDesignerFrame.this, getContext());
    fieldSelectorPaletteDialog = new FieldSelectorPaletteDialog(ReportDesignerFrame.this, getContext());

    statusBar = new StatusBar(context);

    reportEditorPane = new FancyTabbedPane();
    reportEditorPane.setTabLayoutPolicy(JTabbedPane.SCROLL_TAB_LAYOUT);
    reportEditorPane.getModel().addChangeListener(new ReportTabActivationHandler());
    reportEditorPane.addMouseListener(new ReportTabPanePopupHandler());

    dockingPane = new GlobalPane(false);
    dockingPane.setMainComponent(reportEditorPane);

    attributeEditorPanel = new ElementPropertiesPanel();
    attributeEditorPanel.setAllowAttributeCard(true);
    attributeEditorPanel.setReportDesignerContext(context);

    treePanel = new TreeSidePanel(context, attributeEditorPanel);

    initializeToolWindows();

    final JPanel contentPane = new JPanel();
    contentPane.setLayout(new BorderLayout());
    contentPane.add(context.getToolBar("main-toolbar"), BorderLayout.NORTH); // NON-NLS
    contentPane.add(dockingPane, BorderLayout.CENTER);
    contentPane.add(statusBar, BorderLayout.SOUTH);
    contentPane.add(createPaletteToolBar(), BorderLayout.WEST);
    setContentPane(contentPane);

    setJMenuBar(createMenuBar());
    setDropTarget(new DropTarget(this, DnDConstants.ACTION_COPY_OR_MOVE, new DefaultDropTargetListener()));

    context.addPropertyChangeListener(ReportDesignerContext.ACTIVE_CONTEXT_PROPERTY, new ReportTabActivationHandler());
    context.addPropertyChangeListener(ReportDesignerContext.STATUS_TEXT_PROPERTY, new StatusTextHandler());
    context.addPropertyChangeListener(ReportDesignerContext.PAGE_PROPERTY, new PageTextHandler());
    context.addPropertyChangeListener(ReportDesignerContext.REPORT_RENDER_CONTEXT_PROPERTY, new ReportEditorContextHandler());

    Toolkit.getDefaultToolkit().addAWTEventListener(new DragSelectionToggleHandler(), AWTEvent.KEY_EVENT_MASK);

    if (MacOSXIntegration.MAC_OS_X)
    {
      try
      {
        final AboutAction aboutAction = new AboutAction();
        aboutAction.setReportDesignerContext(context);

        final SettingsAction settingsAction = new SettingsAction();
        settingsAction.setReportDesignerContext(context);

        final QuitAction quitAction = new QuitAction();
        quitAction.setReportDesignerContext(context);

        final OpenReportAction openReportAction = new OpenReportAction();
        openReportAction.setReportDesignerContext(context);

        MacOSXIntegration.setOpenFileAction(openReportAction);
        MacOSXIntegration.setAboutAction(aboutAction);
        MacOSXIntegration.setPreferencesAction(settingsAction);
        MacOSXIntegration.setQuitAction(quitAction);
      }
      catch (Throwable e)
      {
        DebugLog.log("Failed to activate MacOS-X integration", e); // NON-NLS
      }
    }
  }

  public void initWindowLocations(final File[] filesToOpen)
  {
    fieldSelectorPaletteDialog.initWindowLocation();
    viewController.setFieldSelectorVisible(WorkspaceSettings.getInstance().isFieldSelectorVisible());

    welcomePane.setLocationRelativeTo(ReportDesignerFrame.this);

    if (filesToOpen == null || filesToOpen.length == 0)
    {
      if (WorkspaceSettings.getInstance().isReopenLastReport())
      {
        final File[] recentFiles = context.getRecentFilesModel().getRecentFiles();
        if (recentFiles.length > 0)
        {
          SwingUtilities.invokeLater(new OpenReportAction.OpenReportTask(recentFiles[0], context));
          return;
        }
      }

      /*
      * PRD-1676:  Since the report designer frame will steal the focus from the Welcome dialog
      * we must let the report designer frame finish it's initialization before we try to display
      * the welcome panel.
      */
      SwingUtilities.invokeLater(new ShowWelcomeScreenTask());
    }
    else
    {
      for (int i = 0; i < filesToOpen.length; i++)
      {
        final File file = filesToOpen[i];
        SwingUtilities.invokeLater(new OpenReportAction.OpenReportTask(file, context));
      }
    }
  }

  protected Category getAttributeToolWindow()
  {
    return attributeToolWindow;
  }

  protected Category getReportTreeToolWindow()
  {
    return reportTreeToolWindow;
  }

  protected Category getInspectionsToolWindow()
  {
    return inspectionsToolWindow;
  }

  protected ElementPropertiesPanel getAttributeEditorPanel()
  {
    return attributeEditorPanel;
  }

  protected JTabbedPane getReportEditorPane()
  {
    return reportEditorPane;
  }

  protected DefaultReportDesignerContext getContext()
  {
    return context;
  }

  protected StatusBar getStatusBar()
  {
    return statusBar;
  }

  private JMenuBar createMenuBar()
  {
    createRecentFilesMenu();
    createZoomMenu();
    createMorphMenu();
    createInsertElementsMenu();
    createInsertDataSourcesMenu();
    createSamplesMenu();

    return context.getView().getComponent("main-menubar", JMenuBar.class);
  }

  private void createInsertDataSourcesMenu()
  {
    final JMenu insertDataSourcesMenu = context.getView().getComponent("insert-datasources-menu", JMenu.class);// NON-NLS
    if (insertDataSourcesMenu != null)
    {
      ContextMenuUtility.createDataSourceMenu(context, insertDataSourcesMenu);
    }
  }

  private void createInsertElementsMenu()
  {
    final XulMenupopup insertElementsMenu = context.getView().getXulComponent("insert-elements-popup", XulMenupopup.class);// NON-NLS
    if (insertElementsMenu != null)
    {
      final ElementMetaData[] datas = ElementTypeRegistry.getInstance().getAllElementTypes();
      Arrays.sort(datas, new GroupedMetaDataComparator());
      Object grouping = null;
      boolean firstElement = true;
      for (int i = 0; i < datas.length; i++)
      {
        final ElementMetaData data = datas[i];
        if (data.isHidden())
        {
          continue;
        }
       
        final String currentGrouping = data.getGrouping(Locale.getDefault());
        if (firstElement == false)
        {
          if (ObjectUtilities.equal(currentGrouping, grouping) == false)
          {
            grouping = currentGrouping;
            SwingMenuseparator separator = new SwingMenuseparator(null, null, null, "menuseparator");
            insertElementsMenu.addChild(separator);
          }
        }
        else
        {
          grouping = currentGrouping;
          firstElement = false;
        }
       
        final InsertElementAction action = new InsertElementAction(data);
        action.setReportDesignerContext(context);
        ActionSwingMenuitem menuItem = new ActionSwingMenuitem(ActionSwingMenuitem.MENUITEM);
        menuItem.setAction(action);
        insertElementsMenu.addChild(menuItem);
      }
    }
  }

  private void createRecentFilesMenu()
  {
    final XulMenupopup reopenMenu = context.getView().getXulComponent("file-reopen-popup", XulMenupopup.class); // NON-NLS
    final XulMenuitem clearMenuitem = context.getView().getXulComponent("file-clear-recent", XulMenuitem.class);// NON-NLS
    if (reopenMenu != null && clearMenuitem != null)
    {
      final RecentFilesUpdateHandler updateHandler = new RecentFilesUpdateHandler(context, reopenMenu, clearMenuitem);
      updateHandler.settingsChanged();
      context.getRecentFilesModel().addSettingsListener(updateHandler);
    }
  }

  private void createZoomMenu()
  {
    final XulComponent zoomMenu = context.getView().getXulComponent("view-zoom-selection-popup", XulMenupopup.class);// NON-NLS
    if (zoomMenu == null)
    {
      return;
    }

    final InternalZoomAction zoom50action = new InternalZoomAction(50);
    final InternalZoomAction zoom100action = new InternalZoomAction(100);
    final InternalZoomAction zoom200action = new InternalZoomAction(200);
    final InternalZoomAction zoom400action = new InternalZoomAction(400);

    zoom50action.setReportDesignerContext(context);
    zoom100action.setReportDesignerContext(context);
    zoom200action.setReportDesignerContext(context);
    zoom400action.setReportDesignerContext(context);

    zoomMenu.addChild(context.getView().createMenuItem(zoom50action));
    zoomMenu.addChild(context.getView().createMenuItem(zoom100action));
    zoomMenu.addChild(context.getView().createMenuItem(zoom200action));
    zoomMenu.addChild(context.getView().createMenuItem(zoom400action));
  }

  private void createSamplesMenu()
  {
    final XulComponent samplesopup = context.getView().getXulComponent("help-samples-popup", XulMenupopup.class);// NON-NLS
    if (samplesopup == null)
    {
      return;
    }

    final XulMenupopup xulMenupopup = (XulMenupopup) samplesopup;
    final TreeModel treeModel = SamplesTreeBuilder.getSampleTreeModel();
    final Object root = treeModel.getRoot();
    try
    {
      insertReports(treeModel, root, xulMenupopup);
    }
    catch (XulException e)
    {
      logger.warn("Failed to initialize sample menu", e);
    }
  }

  private void insertReports(final TreeModel model,
                             final Object currentLevel,
                             final XulMenupopup popup) throws XulException
  {
    final int childCount = model.getChildCount(currentLevel);
    for (int i = 0; i < childCount; i += 1)
    {
      final ReportDesignerView frame = context.getView();

      final Object child = model.getChild(currentLevel, i);
      if (model.isLeaf(child))
      {
        final DefaultMutableTreeNode node = (DefaultMutableTreeNode) child;
        final File file = new File(String.valueOf(node.getUserObject()));
        final OpenSampleReportAction action = new OpenSampleReportAction(file, node.toString());
        action.setReportDesignerContext(context);
        popup.addChild(frame.createMenuItem(action));
      }
      else
      {
        final XulMenupopup childPopup = frame.createPopupMenu(String.valueOf(child), popup);
        insertReports(model, child, childPopup);
      }
    }
  }

  private void createMorphMenu()
  {
    final JMenu morphMenu = context.getView().getComponent("format-morph-menu", JMenu.class);// NON-NLS     PRD-4452
    if (morphMenu == null)
    {
      return;
    }

    final ElementMetaData[] datas = ElementTypeRegistry.getInstance().getAllElementTypes();
    Arrays.sort(datas, new GroupedMetaDataComparator());
    Object grouping = null;
    boolean firstElement = true;
    for (int i = 0; i < datas.length; i++)
    {
      final ElementMetaData data = datas[i];
      if (data.isHidden())
      {
        continue;
      }
      final String currentGrouping = data.getGrouping(Locale.getDefault());
      if (firstElement == false)
      {
        if (ObjectUtilities.equal(currentGrouping, grouping) == false)
        {
          grouping = currentGrouping;
          morphMenu.addSeparator();
        }
      }
      else
      {
        grouping = currentGrouping;
        firstElement = false;
      }

      try
      {
        final MorphAction action = new MorphAction(data.create());
        action.setReportDesignerContext(context);
        morphMenu.add(new JMenuItem(action));
      }
      catch (InstantiationException e)
      {
        UncaughtExceptionsModel.getInstance().addException(e);
      }
    }
  }

  private void initializeToolWindows()
  {
    this.reportTreeToolWindow = createStructureTreeToolWindow();
    this.attributeToolWindow = createAttributesToolWindow();
    this.inspectionsToolWindow = createInspectionsToolWindow();

    dockingPane.add(GlobalPane.Alignment.RIGHT, reportTreeToolWindow);
    dockingPane.add(GlobalPane.Alignment.RIGHT, attributeToolWindow);
    dockingPane.add(GlobalPane.Alignment.BOTTOM, inspectionsToolWindow);
    dockingPane.setPreferredContentSize(GlobalPane.Alignment.BOTTOM, 100);
    dockingPane.setPreferredContentSize(GlobalPane.Alignment.RIGHT, 300);
    // initialize add elements
    initAddElements("popup-Band.add-element-menu");// NON-NLS
    initAddElements("popup-RootLevelBand.add-element-menu");// NON-NLS
    initSetBarcodeTypeElements("popup-Barcode.type");// NON-NLS

  }

  private Category createAttributesToolWindow()
  {
    final ImageIcon propertyTableIcon = IconLoader.getInstance().getPropertyTableIcon();

    return new Category(propertyTableIcon, Messages.getString("Attribute.Title"), attributeEditorPanel);// NON-NLS
  }

  private Category createInspectionsToolWindow()
  {
    // this is the bottom 'messages' panel
    final InspectionSidePanePanel inspectionsMessagePanel = new InspectionSidePanePanel();
    inspectionsMessagePanel.setReportDesignerContext(context);

    final InternalWindow inspectionGadgetInternalWindow = new InternalWindow(Messages.getString("InspectionGadget.Title"));// NON-NLS
    inspectionGadgetInternalWindow.add(inspectionsMessagePanel, BorderLayout.CENTER);

    final Category category = new Category
        (IconLoader.getInstance().getMessagesIcon(),
            Messages.getString("Messages.Title"),// NON-NLS
            inspectionGadgetInternalWindow);
    category.setMinimized(true);
    return category;
  }

  private Category createStructureTreeToolWindow()
  {
    return new Category(IconLoader.getInstance().getReportTreeIcon(),
            Messages.getString("StructureView.Title"),// NON-NLS
            treePanel);

  }


  private void initSetBarcodeTypeElements(final String id)
  {
    final JMenu menu = context.getView().getComponent(id, JMenu.class);
    if (menu == null)
    {
      return;
    }

    final BarcodeTypePropertyEditor editor = new BarcodeTypePropertyEditor();
    final String[] tags = editor.getTags();
    for (int i = 0; i < tags.length; i++)
    {
      final String tag = tags[i];
      final BarcodeTypeAction action = new BarcodeTypeAction(tag);
      action.setReportDesignerContext(context);
      menu.add(new JRadioButtonMenuItem(action));
    }
  }

  private void initAddElements(final String id)
  {
    final JMenu menu = context.getView().getComponent(id, JMenu.class);
    if (menu == null)
    {
      return;
    }

    final ElementMetaData[] datas = ElementTypeRegistry.getInstance().getAllElementTypes();
    Arrays.sort(datas, new GroupedMetaDataComparator());
    Object grouping = null;
    boolean firstElement = true;
    for (int i = 0; i < datas.length; i++)
    {
      final ElementMetaData data = datas[i];
      if (data.isHidden())
      {
        continue;
      }
      if (WorkspaceSettings.getInstance().isShowExpertItems() == false && data.isExpert())
      {
        continue;
      }
      if (WorkspaceSettings.getInstance().isShowDeprecatedItems() == false && data.isDeprecated())
      {
        continue;
      }

      final String currentGrouping = data.getGrouping(Locale.getDefault());
      if (firstElement == false)
      {
        if (ObjectUtilities.equal(currentGrouping, grouping) == false)
        {
          grouping = currentGrouping;
          menu.addSeparator();
        }
      }
      else
      {
        grouping = currentGrouping;
        firstElement = false;
      }
      final InsertElementAction action = new InsertElementAction(data);
      action.setReportDesignerContext(context);
      menu.add(new JMenuItem(action));
    }
  }

  private JComponent createPaletteToolBar()
  {
    final JToolBar toolBar = new JToolBar();
    toolBar.setFloatable(false);
    toolBar.setOrientation(JToolBar.VERTICAL);

    final ElementMetaData[] datas = ElementTypeRegistry.getInstance().getAllElementTypes();
    Arrays.sort(datas, new GroupedMetaDataComparator());
    Object grouping = null;
    boolean firstElement = true;
    for (int i = 0; i < datas.length; i++)
    {
      final ElementMetaData data = datas[i];
      if (data.isHidden())
      {
        continue;
      }
      if (WorkspaceSettings.getInstance().isShowExpertItems() == false && data.isExpert())
      {
        continue;
      }
      if (WorkspaceSettings.getInstance().isShowDeprecatedItems() == false && data.isDeprecated())
      {
        continue;
      }
      if (WorkspaceSettings.getInstance().isExperimentalFeaturesVisible() == false && data.isExperimental())
      {
        continue;
      }


      final String currentGrouping = data.getGrouping(Locale.getDefault());
      if (firstElement == false)
      {
        if (ObjectUtilities.equal(currentGrouping, grouping) == false)
        {
          grouping = currentGrouping;
          toolBar.addSeparator();
        }
      }
      else
      {
        grouping = currentGrouping;
        firstElement = false;
      }
      final InsertElementAction action = new InsertElementAction(data);
      action.setReportDesignerContext(context);
      toolBar.add(new PaletteButton(data, context));
    }

    final JScrollPane paletteScrollpane = new JScrollPane(toolBar);
    paletteScrollpane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
    paletteScrollpane.addComponentListener(new ScrollbarSyncHandler(paletteScrollpane.getVerticalScrollBar(), toolBar));
    return paletteScrollpane;
  }

  private void rebuildReportMenu()
  {
    final XulComponent reopenMenu = context.getView().getXulComponent("window.reports-area", XulComponent.class);
    if (reopenMenu == null)
    {
      return;
    }

    final List<XulComponent> xulComponents = reopenMenu.getChildNodes();
    final XulComponent[] objects = xulComponents.toArray(new XulComponent[xulComponents.size()]);
    for (int i = 0; i < objects.length; i++)
    {
      final XulComponent object = objects[i];
      reopenMenu.removeChild(object);
    }

    final JTabbedPane tabbedPane = getReportEditorPane();
    final int count = tabbedPane.getTabCount();
    if (count > 0)
    {
      reopenMenu.addChild(new SwingMenuseparator(null, null, null, "menu-separator")); // NON-NLS
      for (int i = 0; i < count; i++)
      {
        final Component at = tabbedPane.getTabComponentAt(i);
        final String tabName;
        if (at instanceof TabRenderer)
        {
          final TabRenderer renderer = (TabRenderer) at;
          tabName = renderer.getTitle();
        }
        else
        {
          tabName = tabbedPane.getTitleAt(i);
        }
        final SelectTabAction action = new SelectTabAction(i, tabName);
        final ActionSwingMenuitem actionSwingMenuitem = context.getView().createMenuItem(action);
        actionSwingMenuitem.setReportDesignerContext(context);
        reopenMenu.addChild(actionSwingMenuitem);
      }
    }
  }

  protected void updateFrameTitle()
  {
    final int i = getReportEditorPane().getSelectedIndex();
    final String report;
    final String reportName;
    if (getContext() != null && getContext().getActiveContext() != null)
    {
      if (i == -1)
      {
        reportName = null;
      }
      else
      {
        final Component at = getReportEditorPane().getTabComponentAt(i);
        if (at instanceof TabRenderer)
        {
          final TabRenderer renderer = (TabRenderer) at;
          reportName = renderer.getTitle();
        }
        else
        {
          reportName = getReportEditorPane().getTitleAt(i);
        }
      }

      report = getContext().getActiveContext().getDocumentFile();
    }
    else
    {
      report = null;
      reportName = null;
    }
    setTitle(computeFrameTitle(reportName, report));
  }

  private String computeFrameTitle(final String tabName, final String path)
  {
    if (tabName == null || path == null)
    {
      return Messages.getString("ReportDesignerFrame.Title");// NON-NLS
    }

    if (StringUtils.isEmpty(path))
    {
      return Messages.getString("ReportDesignerFrame.TitleWithName", tabName);// NON-NLS
    }
    else
    {
      return Messages.getString("ReportDesignerFrame.TitleWithNameAndPath", tabName, path);// NON-NLS
    }
  }

  private void recomputeAllTabTitles()
  {
    final JTabbedPane editorPane = getReportEditorPane();
    final int count = editorPane.getTabCount();
    for (int i = 0; i < count; i++)
    {
      final Component at = editorPane.getTabComponentAt(i);
      if (at instanceof TabRenderer)
      {
        final TabRenderer renderer = (TabRenderer) at;
        renderer.setTitle(renderer.recomputeTabName());
      }
    }

    updateFrameTitle();
  }
}
TOP

Related Classes of org.pentaho.reporting.designer.core.ReportDesignerFrame$PageTextHandler

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.