/*
GanttProject is an opensource project management tool.
Copyright (C) 2005-2011 Dmitry Barashev, GanttProject team
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 3
of the License, or (at your option) any later version.
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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package net.sourceforge.ganttproject;
import biz.ganttproject.core.calendar.GPCalendarCalc;
import biz.ganttproject.core.option.DefaultEnumerationOption;
import biz.ganttproject.core.option.GPOption;
import biz.ganttproject.core.option.GPOptionChangeListener;
import biz.ganttproject.core.option.GPOptionGroup;
import biz.ganttproject.core.option.IntegerOption;
import biz.ganttproject.core.table.ColumnList;
import biz.ganttproject.core.time.TimeUnitStack;
import biz.ganttproject.core.time.impl.GPTimeUnitStack;
import net.sourceforge.ganttproject.chart.Chart;
import net.sourceforge.ganttproject.chart.ChartModelBase;
import net.sourceforge.ganttproject.client.RssFeedChecker;
import net.sourceforge.ganttproject.document.Document;
import net.sourceforge.ganttproject.document.DocumentCreator;
import net.sourceforge.ganttproject.document.DocumentManager;
import net.sourceforge.ganttproject.gui.GanttLookAndFeelInfo;
import net.sourceforge.ganttproject.gui.GanttStatusBar;
import net.sourceforge.ganttproject.gui.GanttTabbedPane;
import net.sourceforge.ganttproject.gui.NotificationChannel;
import net.sourceforge.ganttproject.gui.NotificationManager;
import net.sourceforge.ganttproject.gui.NotificationManagerImpl;
import net.sourceforge.ganttproject.gui.ProjectUIFacade;
import net.sourceforge.ganttproject.gui.ProjectUIFacadeImpl;
import net.sourceforge.ganttproject.gui.TaskSelectionContext;
import net.sourceforge.ganttproject.gui.UIConfiguration;
import net.sourceforge.ganttproject.gui.UIFacade;
import net.sourceforge.ganttproject.gui.scrolling.ScrollingManager;
import net.sourceforge.ganttproject.gui.view.GPViewManager;
import net.sourceforge.ganttproject.gui.view.ViewManagerImpl;
import net.sourceforge.ganttproject.gui.window.ContentPaneBuilder;
import net.sourceforge.ganttproject.gui.zoom.ZoomManager;
import net.sourceforge.ganttproject.language.GanttLanguage;
import net.sourceforge.ganttproject.parser.ParserFactory;
import net.sourceforge.ganttproject.resource.HumanResourceManager;
import net.sourceforge.ganttproject.roles.RoleManager;
import net.sourceforge.ganttproject.search.SearchUiImpl;
import net.sourceforge.ganttproject.task.CustomColumnsManager;
import net.sourceforge.ganttproject.task.TaskContainmentHierarchyFacade;
import net.sourceforge.ganttproject.task.TaskManager;
import net.sourceforge.ganttproject.task.TaskSelectionManager;
import net.sourceforge.ganttproject.task.TaskView;
import net.sourceforge.ganttproject.undo.GPUndoManager;
import net.sourceforge.ganttproject.undo.UndoManagerImpl;
import javax.swing.*;
import javax.swing.table.AbstractTableModel;
import java.awt.*;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Locale;
/**
* This class is designed to be a GanttProject-after-refactorings. I am going to
* refactor GanttProject in order to make true view communicating with other
* views through interfaces. This class is intentionally package local to
* prevent using it in other packages (use interfaces rather than concrete
* implementations!)
*
* @author dbarashev
*/
abstract class GanttProjectBase extends JFrame implements IGanttProject, UIFacade {
protected final static GanttLanguage language = GanttLanguage.getInstance();
private final ViewManagerImpl myViewManager;
private final List<ProjectEventListener> myModifiedStateChangeListeners = new ArrayList<ProjectEventListener>();
private final UIFacadeImpl myUIFacade;
private final GanttStatusBar statusBar;
private final TimeUnitStack myTimeUnitStack;
private final ProjectUIFacadeImpl myProjectUIFacade;
private final DocumentManager myDocumentManager;
/** The tabbed pane with the different parts of the project */
private final GanttTabbedPane myTabPane;
private final GPUndoManager myUndoManager;
private final CustomColumnsManager myResourceCustomPropertyManager = new CustomColumnsManager();
private final RssFeedChecker myRssChecker;
private final ContentPaneBuilder myContentPaneBuilder;
private final SearchUiImpl mySearchUi;
protected GanttProjectBase() {
super("GanttProject");
statusBar = new GanttStatusBar(this);
myTabPane = new GanttTabbedPane();
myContentPaneBuilder = new ContentPaneBuilder(getTabs(), getStatusBar());
myTimeUnitStack = new GPTimeUnitStack();
NotificationManagerImpl notificationManager = new NotificationManagerImpl(myContentPaneBuilder.getAnimationHost());
myUIFacade = new UIFacadeImpl(this, statusBar, notificationManager, getProject(), this);
GPLogger.setUIFacade(myUIFacade);
myDocumentManager = new DocumentCreator(this, getUIFacade(), null) {
@Override
protected ParserFactory getParserFactory() {
return GanttProjectBase.this.getParserFactory();
}
@Override
protected ColumnList getVisibleFields() {
return getUIFacade().getTaskTree().getVisibleFields();
}
@Override
protected ColumnList getResourceVisibleFields() {
return getUIFacade().getResourceTree().getVisibleFields();
}
};
myUndoManager = new UndoManagerImpl(this, null, myDocumentManager) {
@Override
protected ParserFactory getParserFactory() {
return GanttProjectBase.this.getParserFactory();
}
};
myViewManager = new ViewManagerImpl(getProject(), myTabPane, getUndoManager());
myProjectUIFacade = new ProjectUIFacadeImpl(myUIFacade, myDocumentManager, myUndoManager);
myRssChecker = new RssFeedChecker((GPTimeUnitStack) getTimeUnitStack(), myUIFacade);
myUIFacade.addOptions(myRssChecker.getUiOptions());
mySearchUi = new SearchUiImpl(getProject(), getUIFacade());
}
@Override
public void addProjectEventListener(ProjectEventListener listener) {
myModifiedStateChangeListeners.add(listener);
}
@Override
public void removeProjectEventListener(ProjectEventListener listener) {
myModifiedStateChangeListeners.remove(listener);
}
protected void fireProjectModified(boolean isModified) {
for (ProjectEventListener modifiedStateChangeListener : myModifiedStateChangeListeners) {
try {
if (isModified) {
modifiedStateChangeListener.projectModified();
} else {
modifiedStateChangeListener.projectSaved();
}
} catch (Exception e) {
showErrorDialog(e);
}
}
}
protected void fireProjectCreated() {
for (ProjectEventListener modifiedStateChangeListener : myModifiedStateChangeListeners) {
modifiedStateChangeListener.projectCreated();
}
// A new project just got created, so it is not yet modified
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
setModified(false);
}
});
}
protected void fireProjectClosed() {
for (ProjectEventListener modifiedStateChangeListener : myModifiedStateChangeListeners) {
modifiedStateChangeListener.projectClosed();
}
}
protected void fireProjectOpened() {
for (ProjectEventListener modifiedStateChangeListener : myModifiedStateChangeListeners) {
modifiedStateChangeListener.projectOpened();
}
}
// ////////////////////////////////////////////////////////////////
// UIFacade
public ProjectUIFacade getProjectUIFacade() {
return myProjectUIFacade;
}
public UIFacade getUIFacade() {
return myUIFacade;
}
protected UIFacadeImpl getUiFacadeImpl() {
return myUIFacade;
}
@Override
public Frame getMainFrame() {
return myUIFacade.getMainFrame();
}
@Override
public Image getLogo() {
return myUIFacade.getLogo();
}
@Override
public void setLookAndFeel(GanttLookAndFeelInfo laf) {
myUIFacade.setLookAndFeel(laf);
}
@Override
public GanttLookAndFeelInfo getLookAndFeel() {
return myUIFacade.getLookAndFeel();
}
@Override
public DefaultEnumerationOption<Locale> getLanguageOption() {
return myUIFacade.getLanguageOption();
}
@Override
public IntegerOption getDpiOption() {
return myUIFacade.getDpiOption();
}
@Override
public GPOption<String> getLafOption() {
return myUIFacade.getLafOption();
}
@Override
public GPOptionGroup[] getOptions() {
return myUIFacade.getOptions();
}
@Override
public void addOnUpdateComponentTreeUi(Runnable callback) {
myUIFacade.addOnUpdateComponentTreeUi(callback);
}
@Override
public ScrollingManager getScrollingManager() {
return myUIFacade.getScrollingManager();
}
@Override
public ZoomManager getZoomManager() {
return myUIFacade.getZoomManager();
}
@Override
public GPUndoManager getUndoManager() {
return myUndoManager;
}
@Override
public void setStatusText(String text) {
myUIFacade.setStatusText(text);
}
@Override
public Dialog createDialog(Component content, Action[] buttonActions, String title) {
return myUIFacade.createDialog(content, buttonActions, title);
}
@Override
public UIFacade.Choice showConfirmationDialog(String message, String title) {
return myUIFacade.showConfirmationDialog(message, title);
}
@Override
public void showOptionDialog(int messageType, String message, Action[] actions) {
myUIFacade.showOptionDialog(messageType, message, actions);
}
@Override
public void showErrorDialog(String message) {
myUIFacade.showErrorDialog(message);
}
@Override
public void showErrorDialog(Throwable e) {
myUIFacade.showErrorDialog(e);
}
@Override
public void showNotificationDialog(NotificationChannel channel, String message) {
myUIFacade.showNotificationDialog(channel, message);
}
@Override
public void showSettingsDialog(String pageID) {
myUIFacade.showSettingsDialog(pageID);
}
@Override
public NotificationManager getNotificationManager() {
return myUIFacade.getNotificationManager();
}
@Override
public void showPopupMenu(Component invoker, Action[] actions, int x, int y) {
myUIFacade.showPopupMenu(invoker, actions, x, y);
}
@Override
public void showPopupMenu(Component invoker, Collection<Action> actions, int x, int y) {
myUIFacade.showPopupMenu(invoker, actions, x, y);
}
@Override
public TaskSelectionContext getTaskSelectionContext() {
return myUIFacade.getTaskSelectionContext();
}
@Override
public TaskSelectionManager getTaskSelectionManager() {
return myUIFacade.getTaskSelectionManager();
}
@Override
public TaskView getCurrentTaskView() {
return myUIFacade.getCurrentTaskView();
}
@Override
public void setWorkbenchTitle(String title) {
myUIFacade.setWorkbenchTitle(title);
}
public GPViewManager getViewManager() {
return myViewManager;
}
@Override
public Chart getActiveChart() {
return myViewManager.getSelectedView().getChart();
}
protected static class RowHeightAligner implements GPOptionChangeListener {
private final ChartModelBase myChartModel;
private final TreeTableContainer myTreeView;
public RowHeightAligner(TreeTableContainer treeView, ChartModelBase chartModel) {
myChartModel = chartModel;
myTreeView = treeView;
myChartModel.addOptionChangeListener(this);
}
@Override
public void optionsChanged() {
myTreeView.getTreeTable().setRowHeight(myChartModel.calculateRowHeight());
AbstractTableModel model = (AbstractTableModel) myTreeView.getTreeTable().getModel();
model.fireTableStructureChanged();
myTreeView.updateUI();
}
}
protected void createContentPane(JPanel toolbar) {
myContentPaneBuilder.build(toolbar, getContentPane());
setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
Dimension windowSize = getPreferredSize();
// Put the frame at the middle of the screen
setLocation(screenSize.width / 2 - (windowSize.width / 2), screenSize.height / 2 - (windowSize.height / 2));
pack();
}
public GanttTabbedPane getTabs() {
return myTabPane;
}
public IGanttProject getProject() {
return this;
}
@Override
public TimeUnitStack getTimeUnitStack() {
return myTimeUnitStack;
}
@Override
public CustomPropertyManager getTaskCustomColumnManager() {
return getTaskManager().getCustomPropertyManager();
}
@Override
public CustomPropertyManager getResourceCustomPropertyManager() {
return myResourceCustomPropertyManager;
}
protected RssFeedChecker getRssFeedChecker() {
return myRssChecker;
}
protected SearchUiImpl getSearchUi() {
return mySearchUi;
}
@Override
public abstract String getProjectName();
@Override
public abstract void setProjectName(String projectName);
@Override
public abstract String getDescription();
@Override
public abstract void setDescription(String description);
@Override
public abstract String getOrganization();
@Override
public abstract void setOrganization(String organization);
@Override
public abstract String getWebLink();
@Override
public abstract void setWebLink(String webLink);
@Override
public abstract UIConfiguration getUIConfiguration();
@Override
public abstract HumanResourceManager getHumanResourceManager();
@Override
public abstract RoleManager getRoleManager();
@Override
public abstract TaskManager getTaskManager();
@Override
public abstract TaskContainmentHierarchyFacade getTaskContainment();
@Override
public abstract GPCalendarCalc getActiveCalendar();
@Override
public abstract void setModified();
@Override
public abstract void close();
@Override
public abstract Document getDocument();
protected GanttStatusBar getStatusBar() {
return statusBar;
}
@Override
public DocumentManager getDocumentManager() {
return myDocumentManager;
}
protected abstract ParserFactory getParserFactory();
}