time tracking moved to ultimate

This commit is contained in:
Dmitry Avdeev
2013-08-09 13:02:57 +04:00
parent 962813704c
commit a7ff291912
10 changed files with 0 additions and 1100 deletions
-1
View File
@@ -131,7 +131,6 @@
<module fileurl="file://$PROJECT_DIR$/plugins/tasks/tasks-core/tasks-core.iml" filepath="$PROJECT_DIR$/plugins/tasks/tasks-core/tasks-core.iml" group="plugins/tasks" />
<module fileurl="file://$PROJECT_DIR$/plugins/tasks/tasks-java/tasks-java.iml" filepath="$PROJECT_DIR$/plugins/tasks/tasks-java/tasks-java.iml" group="plugins/tasks" />
<module fileurl="file://$PROJECT_DIR$/plugins/tasks/tasks-tests/tasks-tests.iml" filepath="$PROJECT_DIR$/plugins/tasks/tasks-tests/tasks-tests.iml" group="plugins/tasks" />
<module fileurl="file://$PROJECT_DIR$/plugins/tasks/tasks-time-tracking/tasks-time-tracking.iml" filepath="$PROJECT_DIR$/plugins/tasks/tasks-time-tracking/tasks-time-tracking.iml" group="plugins/tasks" />
<module fileurl="file://$PROJECT_DIR$/plugins/terminal/terminal.iml" filepath="$PROJECT_DIR$/plugins/terminal/terminal.iml" group="plugins" />
<module fileurl="file://$PROJECT_DIR$/platform/testFramework/testFramework.iml" filepath="$PROJECT_DIR$/platform/testFramework/testFramework.iml" group="platform" />
<module fileurl="file://$PROJECT_DIR$/java/testFramework/testFramework-java.iml" filepath="$PROJECT_DIR$/java/testFramework/testFramework-java.iml" group="java" />
@@ -1,26 +0,0 @@
<idea-plugin version="2">
<id>com.intellij.tasks.timeTracking</id>
<name>Time Tracking</name>
<description>Enables time tracking for "Task Management" plugin</description>
<vendor>JetBrains</vendor>
<version>1.0</version>
<depends>com.intellij.tasks</depends>
<project-components>
<component>
<implementation-class>com.intellij.tasks.timeTracking.TimeTrackingManager</implementation-class>
</component>
</project-components>
<extensions defaultExtensionNs="com.intellij">
<projectConfigurable instance="com.intellij.tasks.timeTracking.TimeTrackingConfigurable" displayName="Time Tracking"
id="tasks.timeTracking"
nonDefaultProject="true"
parentId="tasks"/>
<toolWindow id="Time Tracking" anchor="right" secondary="false" icon="TasksIcons.Clock"
factoryClass="com.intellij.tasks.timeTracking.TasksToolWindowFactory"
conditionClass="com.intellij.tasks.timeTracking.TasksToolWindowFactory"/>
</extensions>
</idea-plugin>
@@ -1,130 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="com.intellij.tasks.timeTracking.SendTimeTrackingInformationDialog">
<grid id="27dc6" binding="myPanel" layout-manager="GridLayoutManager" row-count="3" column-count="3" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<xy x="20" y="20" width="721" height="328"/>
</constraints>
<properties/>
<border type="none"/>
<children>
<component id="c5275" class="com.intellij.ui.components.JBLabel">
<constraints>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="Issue:"/>
</properties>
</component>
<component id="59138" class="com.intellij.ui.components.JBLabel">
<constraints>
<grid row="2" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="9" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="&amp;Comment:"/>
<toolTipText value=""/>
</properties>
</component>
<component id="225af" class="javax.swing.JLabel" binding="myTaskNameLabel">
<constraints>
<grid row="0" column="1" row-span="1" col-span="2" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="Label"/>
</properties>
</component>
<scrollpane id="f2f7d" class="com.intellij.ui.components.JBScrollPane">
<constraints>
<grid row="2" column="1" row-span="1" col-span="2" vsize-policy="7" hsize-policy="7" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
</constraints>
<properties/>
<border type="none"/>
<children>
<component id="e531f" class="javax.swing.JTextArea" binding="myCommentTextArea">
<constraints/>
<properties/>
</component>
</children>
</scrollpane>
<grid id="50cf9" layout-manager="GridLayoutManager" row-count="3" column-count="3" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="5" left="0" bottom="5" right="0"/>
<constraints>
<grid row="1" column="0" row-span="1" col-span="3" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="true"/>
</constraints>
<properties/>
<border type="none"/>
<children>
<component id="45822" class="javax.swing.JRadioButton" binding="myFromPreviousPostRadioButton" default-binding="true">
<constraints>
<grid row="1" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="From &amp;previous post:"/>
</properties>
</component>
<component id="a4c4" class="javax.swing.JRadioButton" binding="myCustomRadioButton" default-binding="true">
<constraints>
<grid row="2" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="Custo&amp;m:"/>
</properties>
</component>
<component id="89994" class="javax.swing.JTextField" binding="myFromPreviousPostTextField">
<constraints>
<grid row="1" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false">
<preferred-size width="150" height="-1"/>
</grid>
</constraints>
<properties>
<editable value="false"/>
</properties>
</component>
<component id="c9593" class="javax.swing.JTextField" binding="myCustomTextField">
<constraints>
<grid row="2" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false">
<preferred-size width="150" height="-1"/>
</grid>
</constraints>
<properties>
<text value="0d 0h 0m"/>
</properties>
</component>
<component id="65cc2" class="javax.swing.JRadioButton" binding="myTotallyRadioButton" default-binding="true">
<constraints>
<grid row="0" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="Totall&amp;y:"/>
</properties>
</component>
<component id="8f5d7" class="javax.swing.JTextField" binding="myTotallyTextField">
<constraints>
<grid row="0" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false">
<preferred-size width="150" height="-1"/>
</grid>
</constraints>
<properties>
<editable value="false"/>
</properties>
</component>
<component id="bbd54" class="com.intellij.ui.components.JBLabel">
<constraints>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="Time Spent:"/>
</properties>
</component>
</children>
</grid>
</children>
</grid>
<buttonGroups>
<group name="myGroup1">
<member id="45822"/>
<member id="65cc2"/>
<member id="a4c4"/>
</group>
</buttonGroups>
</form>
@@ -1,137 +0,0 @@
/*
* Copyright 2000-2012 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.tasks.timeTracking;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.ui.ValidationInfo;
import com.intellij.tasks.LocalTask;
import com.intellij.tasks.TaskRepository;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.util.Date;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* User: evgeny.zakrevsky
* Date: 12/26/12
*/
public class SendTimeTrackingInformationDialog extends DialogWrapper {
private final static Logger LOG = Logger.getInstance("#com.intellij.tasks.timeTracking.TasksToolWindowPanel");
public static final Pattern PATTERN = Pattern.compile("([0-9]+)d ([0-9]+)h ([0-9]+)m");
@Nullable private final Project myProject;
private final LocalTask myTask;
private JRadioButton myFromPreviousPostRadioButton;
private JRadioButton myTotallyRadioButton;
private JRadioButton myCustomRadioButton;
private JTextField myFromPreviousPostTextField;
private JTextField myTotallyTextField;
private JTextField myCustomTextField;
private JTextArea myCommentTextArea;
private JPanel myPanel;
private JLabel myTaskNameLabel;
protected SendTimeTrackingInformationDialog(@Nullable final Project project, final LocalTask localTask) {
super(project);
myProject = project;
myTask = localTask;
setTitle("Time Tracking");
myTaskNameLabel.setText(myTask.getPresentableName());
myFromPreviousPostRadioButton.setSelected(true);
if (myTask.getLastPost() == null) {
myFromPreviousPostRadioButton.setVisible(false);
myFromPreviousPostTextField.setVisible(false);
myTotallyRadioButton.setSelected(true);
}
myFromPreviousPostTextField.setText(formatDuration(myTask.getTimeSpentFromLastPost()));
myTotallyTextField.setText(formatDuration(myTask.getTotalTimeSpent()));
init();
}
@Nullable
@Override
protected JComponent createCenterPanel() {
return myPanel;
}
private static String formatDuration(final long milliseconds) {
final int second = 1000;
final int minute = 60 * second;
final int hour = 60 * minute;
final int day = 24 * hour;
final int days = (int)(milliseconds / day);
final int hours = (int)(milliseconds % day / hour);
final int minutes = (int)(milliseconds % hour / minute);
String daysString = days + "d ";
String hoursString = hours + "h ";
String minutesString = minutes + "m";
return daysString + hoursString + minutesString;
}
@Override
protected void doOKAction() {
String timeSpentText = myFromPreviousPostRadioButton.isSelected() ? myFromPreviousPostTextField.getText()
: myTotallyRadioButton.isSelected() ? myTotallyTextField.getText() : myCustomTextField.getText();
final Matcher matcher = PATTERN.matcher(timeSpentText);
if (matcher.matches()) {
final int timeSpent = Integer.valueOf(matcher.group(1)) * 24 * 60 + Integer.valueOf(matcher.group(2)) * 60 + Integer.valueOf(
matcher.group(3));
final TaskRepository repository = myTask.getRepository();
if (repository != null &&
repository.isSupported(TaskRepository.TIME_MANAGEMENT)) {
try {
repository.updateTimeSpent(myTask, timeSpentText, myCommentTextArea.getText());
myTask.setLastPost(new Date());
}
catch (Exception e1) {
Messages
.showErrorDialog(myProject, "<html>Could not send information for " + myTask.getPresentableName() + "<br/>" + e1.getMessage(),
"Error");
LOG.warn(e1);
}
}
}
super.doOKAction();
}
@Nullable
@Override
protected ValidationInfo doValidate() {
String timeSpentText = myFromPreviousPostRadioButton.isSelected() ? myFromPreviousPostTextField.getText()
: myTotallyRadioButton.isSelected() ? myTotallyTextField.getText() : myCustomTextField.getText();
if (!PATTERN.matcher(timeSpentText).matches()) return new ValidationInfo("Time Spent has broken format");
return null;
}
@Nullable
@Override
protected String getDimensionServiceKey() {
return "com.intellij.tasks.timeTracking.TasksToolWindowPanel";
}
}
@@ -1,32 +0,0 @@
package com.intellij.tasks.timeTracking;
import com.intellij.openapi.project.DumbAware;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.wm.ToolWindow;
import com.intellij.openapi.wm.ToolWindowAnchor;
import com.intellij.openapi.wm.ToolWindowFactory;
import com.intellij.ui.content.Content;
import com.intellij.ui.content.ContentFactory;
import com.intellij.ui.content.ContentManager;
/**
* User: evgeny.zakrevsky
* Date: 11/8/12
*/
public class TasksToolWindowFactory implements ToolWindowFactory, Condition<Project>, DumbAware {
@Override
public boolean value(final Project project) {
return TimeTrackingManager.getInstance(project).isTimeTrackingToolWindowAvailable();
}
@Override
public void createToolWindowContent(final Project project, final ToolWindow toolWindow) {
final ContentManager contentManager = toolWindow.getContentManager();
final Content content = ContentFactory.SERVICE.getInstance().
createContent(new TasksToolWindowPanel(project, toolWindow.getAnchor() == ToolWindowAnchor.LEFT ||
toolWindow.getAnchor() == ToolWindowAnchor.RIGHT), null, false);
contentManager.addContent(content);
}
}
@@ -1,363 +0,0 @@
package com.intellij.tasks.timeTracking;
import com.intellij.icons.AllIcons;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.SimpleToolWindowPanel;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.IconLoader;
import com.intellij.tasks.*;
import com.intellij.tasks.actions.GotoTaskAction;
import com.intellij.tasks.actions.SwitchTaskAction;
import com.intellij.ui.LayeredIcon;
import com.intellij.ui.ScrollPaneFactory;
import com.intellij.ui.SimpleColoredComponent;
import com.intellij.ui.SimpleTextAttributes;
import com.intellij.ui.table.TableView;
import com.intellij.util.IconUtil;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.text.DateFormatUtil;
import com.intellij.util.ui.ColumnInfo;
import com.intellij.util.ui.ListTableModel;
import com.intellij.util.ui.UIUtil;
import icons.TasksIcons;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import javax.swing.table.TableCellRenderer;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Comparator;
/**
* User: evgeny.zakrevsky
* Date: 11/8/12
*/
public class TasksToolWindowPanel extends SimpleToolWindowPanel implements Disposable {
private final ListTableModel<LocalTask> myTableModel;
private final TimeTrackingManager myTimeTrackingManager;
private final Project myProject;
private Timer myTimer;
private final TableView<LocalTask> myTable;
private final TaskManager myTaskManager;
public TasksToolWindowPanel(final Project project, final boolean vertical) {
super(vertical);
myProject = project;
myTimeTrackingManager = TimeTrackingManager.getInstance(project);
myTaskManager = TaskManager.getManager(project);
myTable = new TableView<LocalTask>(createListModel());
myTableModel = myTable.getListTableModel();
updateTable();
setContent(ScrollPaneFactory.createScrollPane(myTable, true));
setToolbar(createToolbar());
myTaskManager.addTaskListener(new TaskListenerAdapter() {
@Override
public void taskDeactivated(final LocalTask task) {
myTable.repaint();
}
@Override
public void taskActivated(final LocalTask task) {
myTable.repaint();
}
@Override
public void taskAdded(final LocalTask task) {
updateTable();
}
@Override
public void taskRemoved(final LocalTask task) {
updateTable();
}
});
myTimer = new Timer(TimeTrackingManager.TIME_TRACKING_TIME_UNIT, new ActionListener() {
@Override
public void actionPerformed(final ActionEvent e) {
myTable.repaint();
}
});
myTimer.start();
}
private static SimpleTextAttributes getAttributes(final boolean isClosed, final boolean isActive, final boolean isSelected) {
return new SimpleTextAttributes(isActive ? SimpleTextAttributes.STYLE_BOLD : SimpleTextAttributes.STYLE_PLAIN,
isSelected
? UIUtil.getTableSelectionForeground()
: isClosed && !isActive ? UIUtil.getLabelDisabledForeground() : UIUtil.getTableForeground());
}
private static String formatDuration(final long milliseconds) {
final int second = 1000;
final int minute = 60 * second;
final int hour = 60 * minute;
final int day = 24 * hour;
final int days = (int)milliseconds / day;
String daysString = days != 0 ? days + "d " : "";
return daysString + String.format("%d:%02d:%02d", milliseconds % day / hour, milliseconds % hour / minute,
milliseconds % minute / second);
}
private JComponent createToolbar() {
DefaultActionGroup group = new DefaultActionGroup();
final AnAction action = ActionManager.getInstance().getAction(GotoTaskAction.ID);
assert action instanceof GotoTaskAction;
final GotoTaskAction gotoTaskAction = (GotoTaskAction)action;
group.add(gotoTaskAction);
group.add(new AnAction("Remove Task", "Remove Task", IconUtil.getRemoveIcon()) {
@Override
public void actionPerformed(final AnActionEvent e) {
for (LocalTask localTask : myTable.getSelectedObjects()) {
SwitchTaskAction.removeTask(myProject, localTask, myTaskManager);
}
}
});
group.add(new ToggleAction("Show closed tasks", "Show closed tasks", AllIcons.Actions.Checked) {
@Override
public boolean isSelected(final AnActionEvent e) {
return myTimeTrackingManager.getState().showClosedTasks;
}
@Override
public void setSelected(final AnActionEvent e, final boolean state) {
myTimeTrackingManager.getState().showClosedTasks = state;
updateTable();
}
});
group.add(new ModeToggleAction());
group.add(new StartStopAction());
if (timeManagementExist()) {
group.add(new AnAction("Post work item to bugtracker", "Post work item to bugtracker", AllIcons.Actions.Export) {
@Override
public void actionPerformed(final AnActionEvent e) {
final LocalTask localTask = myTable.getSelectedObject();
if (localTask == null) return;
new SendTimeTrackingInformationDialog(myProject, localTask).show();
}
@Override
public void update(final AnActionEvent e) {
final LocalTask localTask = myTable.getSelectedObject();
if (localTask == null) {
e.getPresentation().setEnabled(false);
}
else {
final TaskRepository repository = localTask.getRepository();
e.getPresentation().setEnabled(repository != null && repository.isSupported(TaskRepository.TIME_MANAGEMENT));
}
}
});
group.add(new ToggleAction("Show time spent from last post of work item", "Show time spent from last post of work item",
TasksIcons.Clock) {
@Override
public boolean isSelected(final AnActionEvent e) {
return myTimeTrackingManager.getState().showSpentTimeFromLastPost;
}
@Override
public void setSelected(final AnActionEvent e, final boolean state) {
myTimeTrackingManager.getState().showSpentTimeFromLastPost = state;
myTable.repaint();
}
});
}
final ActionToolbar actionToolBar = ActionManager.getInstance().createActionToolbar(ActionPlaces.UNKNOWN, group, myVertical);
return actionToolBar.getComponent();
}
private void updateTable() {
myTableModel.setItems(ContainerUtil.filter(myTaskManager.getLocalTasks(),
new Condition<LocalTask>() {
@Override
public boolean value(final LocalTask task) {
return task.isActive() ||
(task.getTotalTimeSpent() != 0 &&
(myTimeTrackingManager.getState().showClosedTasks ||
!myTaskManager.isLocallyClosed(task)));
}
}));
}
private ListTableModel<LocalTask> createListModel() {
final ColumnInfo<LocalTask, String> task = new ColumnInfo<LocalTask, String>("Task") {
@Nullable
@Override
public String valueOf(final LocalTask task) {
return task.getPresentableName();
}
@Nullable
@Override
public TableCellRenderer getRenderer(final LocalTask task) {
return new TableCellRenderer() {
@Override
public Component getTableCellRendererComponent(final JTable table,
final Object value,
final boolean isSelected,
final boolean hasFocus,
final int row,
final int column) {
JPanel panel = new JPanel(new BorderLayout());
panel.setBackground(UIUtil.getTableBackground(isSelected));
final SimpleColoredComponent component = new SimpleColoredComponent();
final boolean isClosed = task.isClosed() || myTaskManager.isLocallyClosed(task);
final boolean isActive = task.isActive();
final boolean isRunning = myTimeTrackingManager.getState().autoMode ? isActive : isActive && task.isRunning();
component.append((String)value, getAttributes(isClosed, isActive, isSelected));
component.setIcon(isRunning
? LayeredIcon.create(task.getIcon(), AllIcons.Nodes.RunnableMark)
: isClosed && !isActive ? IconLoader.getTransparentIcon(task.getIcon()) : task.getIcon());
component.setOpaque(false);
panel.add(component, BorderLayout.CENTER);
panel.setOpaque(true);
return panel;
}
};
}
@Nullable
@Override
public Comparator<LocalTask> getComparator() {
return new Comparator<LocalTask>() {
public int compare(LocalTask o1, LocalTask o2) {
int i = Comparing.compare(o2.getUpdated(), o1.getUpdated());
return i == 0 ? Comparing.compare(o2.getCreated(), o1.getCreated()) : i;
}
};
}
};
final ColumnInfo<LocalTask, String> spentTime = new ColumnInfo<LocalTask, String>("Time Spent") {
@Nullable
@Override
public String valueOf(final LocalTask task) {
long timeSpent =
myTimeTrackingManager.getState().showSpentTimeFromLastPost ? task.getTimeSpentFromLastPost() : task.getTotalTimeSpent();
if (task.isActive()) {
return formatDuration(timeSpent);
}
return DateFormatUtil.formatDuration(timeSpent);
}
@Nullable
@Override
public TableCellRenderer getRenderer(final LocalTask task) {
return new TableCellRenderer() {
@Override
public Component getTableCellRendererComponent(final JTable table,
final Object value,
final boolean isSelected,
final boolean hasFocus,
final int row,
final int column) {
JPanel panel = new JPanel(new BorderLayout());
panel.setBackground(UIUtil.getTableBackground(isSelected));
final SimpleColoredComponent component = new SimpleColoredComponent();
final boolean isClosed = task.isClosed() || myTaskManager.isLocallyClosed(task);
final boolean isActive = task.isActive();
component.append((String)value, getAttributes(isClosed, isActive, isSelected));
component.setOpaque(false);
panel.add(component, BorderLayout.CENTER);
panel.setOpaque(true);
return panel;
}
};
}
@Nullable
@Override
public Comparator<LocalTask> getComparator() {
return new Comparator<LocalTask>() {
@Override
public int compare(final LocalTask o1, final LocalTask o2) {
final long timeSpent1 =
myTimeTrackingManager.getState().showSpentTimeFromLastPost ? o1.getTimeSpentFromLastPost() : o1.getTotalTimeSpent();
final long timeSpent2 =
myTimeTrackingManager.getState().showSpentTimeFromLastPost ? o2.getTimeSpentFromLastPost() : o2.getTotalTimeSpent();
return Comparing.compare(timeSpent1, timeSpent2);
}
};
}
};
return new ListTableModel<LocalTask>((new ColumnInfo[]{task, spentTime}));
}
private boolean timeManagementExist() {
for (TaskRepository repository : myTaskManager.getAllRepositories()) {
if (repository.isSupported(TaskRepository.TIME_MANAGEMENT)) {
return true;
}
}
return false;
}
@Override
public void dispose() {
myTimer.stop();
myTimer = null;
}
private class StartStopAction extends AnAction {
@Override
public void update(final AnActionEvent e) {
if (myTimeTrackingManager.getState().autoMode) {
e.getPresentation().setEnabled(false);
e.getPresentation().setIcon(TasksIcons.StartTimer);
e.getPresentation().setText("Start timer for active task");
}
else {
e.getPresentation().setEnabled(true);
if (myTaskManager.getActiveTask().isRunning()) {
e.getPresentation().setIcon(TasksIcons.StopTimer);
e.getPresentation().setText("Stop timer for active task");
}
else {
e.getPresentation().setIcon(TasksIcons.StartTimer);
e.getPresentation().setText("Start timer for active task");
}
}
}
@Override
public void actionPerformed(final AnActionEvent e) {
final LocalTask activeTask = myTaskManager.getActiveTask();
if (activeTask.isRunning()) {
activeTask.setRunning(false);
}
else {
activeTask.setRunning(true);
}
}
}
private class ModeToggleAction extends ToggleAction {
public ModeToggleAction() {
super("Auto mode", "Automatic starting and stopping of timer", TasksIcons.AutoMode);
}
@Override
public boolean isSelected(final AnActionEvent e) {
return myTimeTrackingManager.getState().autoMode;
}
@Override
public void setSelected(final AnActionEvent e, final boolean state) {
myTimeTrackingManager.setAutoMode(state);
updateTable();
}
}
}
@@ -1,68 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="com.intellij.tasks.timeTracking.TimeTrackingConfigurable">
<grid id="27dc6" binding="myPanel" layout-manager="GridLayoutManager" row-count="3" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<xy x="20" y="20" width="500" height="400"/>
</constraints>
<properties/>
<border type="none"/>
<children>
<vspacer id="9d80d">
<constraints>
<grid row="2" column="0" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
</constraints>
</vspacer>
<grid id="f42" binding="myTimeTrackingSettings" layout-manager="GridLayoutManager" row-count="1" column-count="4" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
</constraints>
<properties/>
<clientProperties>
<BorderFactoryClass class="java.lang.String" value="com.intellij.ui.IdeBorderFactory$PlainSmallWithIndent"/>
</clientProperties>
<border type="none" title="Time Tracking settings"/>
<children>
<component id="e1b59" class="com.intellij.ui.components.JBLabel">
<constraints>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="0" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="Suspend delay:"/>
</properties>
</component>
<component id="463e7" class="javax.swing.JTextField" binding="myTimeTrackingSuspendDelay">
<constraints>
<grid row="0" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="1" indent="0" use-parent-layout="false">
<preferred-size width="50" height="-1"/>
</grid>
</constraints>
<properties/>
</component>
<component id="5584b" class="com.intellij.ui.components.JBLabel">
<constraints>
<grid row="0" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="0" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="seconds"/>
</properties>
</component>
</children>
</grid>
<component id="c5b5" class="javax.swing.JCheckBox" binding="myEnableTimeTrackingCheckBox" default-binding="true">
<constraints>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="&amp;Enable Time Tracking"/>
</properties>
</component>
<hspacer id="e6e8e">
<constraints>
<grid row="1" column="1" row-span="1" col-span="1" vsize-policy="1" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
</hspacer>
</children>
</grid>
</form>
@@ -1,106 +0,0 @@
package com.intellij.tasks.timeTracking;
import com.intellij.openapi.options.Configurable;
import com.intellij.openapi.options.SearchableConfigurable;
import com.intellij.openapi.project.Project;
import com.intellij.ui.GuiUtils;
import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
/**
* User: Evgeny.Zakrevsky
* Date: 11/19/12
*/
public class TimeTrackingConfigurable implements SearchableConfigurable, Configurable.NoScroll {
private JCheckBox myEnableTimeTrackingCheckBox;
private JTextField myTimeTrackingSuspendDelay;
private JPanel myTimeTrackingSettings;
private JPanel myPanel;
private Project myProject;
public TimeTrackingConfigurable(Project project) {
myProject = project;
myEnableTimeTrackingCheckBox.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
enableTimeTrackingPanel();
}
});
}
private void enableTimeTrackingPanel() {
GuiUtils.enableChildren(myTimeTrackingSettings, myEnableTimeTrackingCheckBox.isSelected());
}
private TimeTrackingManager.Config getConfig() {
return TimeTrackingManager.getInstance(myProject).getState();
}
@Override
public void reset() {
myEnableTimeTrackingCheckBox.setSelected(getConfig().enabled);
myTimeTrackingSuspendDelay.setText(String.valueOf(getConfig().suspendDelayInSeconds));
enableTimeTrackingPanel();
}
@Override
public void disposeUIResources() {
}
@Override
public boolean isModified() {
return myEnableTimeTrackingCheckBox.isSelected() != getConfig().enabled ||
!myTimeTrackingSuspendDelay.getText().equals(String.valueOf(getConfig().suspendDelayInSeconds));
}
@Override
public void apply() {
boolean oldTimeTrackingEnabled = getConfig().enabled;
getConfig().enabled = myEnableTimeTrackingCheckBox.isSelected();
if (getConfig().enabled != oldTimeTrackingEnabled) {
TimeTrackingManager.getInstance(myProject).updateTimeTrackingToolWindow();
}
try{
getConfig().suspendDelayInSeconds = Integer.parseInt(myTimeTrackingSuspendDelay.getText());
}
catch (NumberFormatException ignored) {
}
}
@NotNull
@Override
public String getId() {
return "tasks.timeTracking";
}
@Nullable
@Override
public Runnable enableSearch(final String option) {
return null;
}
@Nls
@Override
public String getDisplayName() {
return "Time Tracking";
}
@Nullable
@Override
public String getHelpTopic() {
return null;
//return "reference.settings.project.tasks.timeTracking";
}
@Nullable
@Override
public JComponent createComponent() {
return myPanel;
}
}
@@ -1,218 +0,0 @@
package com.intellij.tasks.timeTracking;
import com.intellij.ide.IdeEventQueue;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.components.*;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.startup.StartupManager;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.wm.*;
import com.intellij.tasks.LocalTask;
import com.intellij.tasks.TaskManager;
import com.intellij.tasks.timeTracking.model.WorkItem;
import com.intellij.util.Alarm;
import com.intellij.util.ui.UIUtil;
import com.intellij.util.xmlb.XmlSerializerUtil;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Date;
/**
* User: Evgeny.Zakrevsky
* Date: 11/19/12
*/
@State(
name = "TimeTrackingManager",
storages = {
@Storage(file = StoragePathMacros.WORKSPACE_FILE)
}
)
public class TimeTrackingManager implements ProjectComponent, PersistentStateComponent<TimeTrackingManager.Config> {
public static final int TIME_TRACKING_TIME_UNIT = 1000;
private final Project myProject;
private final TaskManager myTaskManager;
private final Config myConfig = new Config();
private Timer myTimeTrackingTimer;
private final Alarm myIdleAlarm = new Alarm(Alarm.ThreadToUse.SWING_THREAD);
private Runnable myActivityListener;
private LocalTask myLastActiveTask;
public TimeTrackingManager(Project project,
TaskManager taskManager) {
myProject = project;
myTaskManager = taskManager;
}
public static TimeTrackingManager getInstance(Project project) {
return project.getComponent(TimeTrackingManager.class);
}
private void startTimeTrackingTimer() {
if (!myTimeTrackingTimer.isRunning()) {
myTimeTrackingTimer.start();
}
myIdleAlarm.cancelAllRequests();
myIdleAlarm.addRequest(new Runnable() {
@Override
public void run() {
if (myTimeTrackingTimer.isRunning()) {
myTimeTrackingTimer.stop();
}
}
}, getState().suspendDelayInSeconds * 1000);
}
public void updateTimeTrackingToolWindow() {
ToolWindow toolWindow = ToolWindowManager.getInstance(myProject).getToolWindow(ToolWindowId.TASKS);
if (isTimeTrackingToolWindowAvailable()) {
if (toolWindow == null) {
toolWindow =
ToolWindowManager.getInstance(myProject).registerToolWindow(ToolWindowId.TASKS, true, ToolWindowAnchor.RIGHT, myProject, true);
new TasksToolWindowFactory().createToolWindowContent(myProject, toolWindow);
}
final ToolWindow finalToolWindow = toolWindow;
ApplicationManager.getApplication().invokeLater(new Runnable() {
@Override
public void run() {
finalToolWindow.setAvailable(true, null);
finalToolWindow.show(null);
finalToolWindow.activate(null);
}
});
}
else {
if (toolWindow != null) {
final ToolWindow finalToolWindow = toolWindow;
ApplicationManager.getApplication().invokeLater(new Runnable() {
@Override
public void run() {
finalToolWindow.setAvailable(false, null);
}
});
}
}
}
public boolean isTimeTrackingToolWindowAvailable() {
return getState().enabled;
}
@Override
public void initComponent() {
if (!ApplicationManager.getApplication().isUnitTestMode()) {
myTimeTrackingTimer = UIUtil.createNamedTimer("TaskManager time tracking", TIME_TRACKING_TIME_UNIT, new ActionListener() {
@Override
public void actionPerformed(final ActionEvent e) {
final LocalTask activeTask = myTaskManager.getActiveTask();
if (myLastActiveTask != activeTask) {
activeTask.addWorkItem(new WorkItem(new Date()));
}
if (getState().autoMode) {
final WorkItem lastWorkItem = activeTask.getWorkItems().get(activeTask.getWorkItems().size() - 1);
lastWorkItem.duration += TIME_TRACKING_TIME_UNIT;
getState().totallyTimeSpent += TIME_TRACKING_TIME_UNIT;
}
else {
if (activeTask.isRunning()) {
final WorkItem lastWorkItem = activeTask.getWorkItems().get(activeTask.getWorkItems().size() - 1);
lastWorkItem.duration += TIME_TRACKING_TIME_UNIT;
getState().totallyTimeSpent += TIME_TRACKING_TIME_UNIT;
}
}
myLastActiveTask = activeTask;
}
});
StartupManager.getInstance(myProject).registerStartupActivity(new Runnable() {
public void run() {
ApplicationManager.getApplication().invokeLater(new Runnable() {
@Override
public void run() {
startTimeTrackingTimer();
}
});
}
});
myActivityListener = new Runnable() {
@Override
public void run() {
final IdeFrame frame = IdeFocusManager.getGlobalInstance().getLastFocusedFrame();
if (frame == null) return;
final Project project = frame.getProject();
if (project == null || !myProject.equals(project)) return;
startTimeTrackingTimer();
}
};
if (getState().autoMode) {
IdeEventQueue.getInstance().addActivityListener(myActivityListener, myProject);
}
}
}
public void setAutoMode(final boolean on) {
final boolean oldState = getState().autoMode;
if (on != oldState) {
getState().autoMode = on;
if (on) {
IdeEventQueue.getInstance().addActivityListener(myActivityListener, myProject);
}
else {
IdeEventQueue.getInstance().removeActivityListener(myActivityListener);
myIdleAlarm.cancelAllRequests();
if (!myTimeTrackingTimer.isRunning()) {
myTimeTrackingTimer.start();
}
}
}
}
@Override
public void disposeComponent() {
if (myTimeTrackingTimer != null) {
myTimeTrackingTimer.stop();
}
myIdleAlarm.cancelAllRequests();
Disposer.dispose(myIdleAlarm);
}
@NotNull
@Override
public String getComponentName() {
return "Time Tracking Manager";
}
@NotNull
@Override
public TimeTrackingManager.Config getState() {
return myConfig;
}
@Override
public void loadState(final TimeTrackingManager.Config state) {
XmlSerializerUtil.copyBean(state, myConfig);
}
@Override
public void projectOpened() {
}
@Override
public void projectClosed() {
}
public static class Config {
public boolean enabled = false;
public long totallyTimeSpent = 0;
public int suspendDelayInSeconds = 600;
public boolean autoMode = true;
public boolean showClosedTasks = true;
public boolean showSpentTimeFromLastPost = false;
}
}
@@ -1,19 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="module" module-name="tasks-api" />
<orderEntry type="module" module-name="tasks-core" />
<orderEntry type="module" module-name="util" />
<orderEntry type="module" module-name="core-api" />
<orderEntry type="module" module-name="platform-api" />
<orderEntry type="module" module-name="platform-impl" />
<orderEntry type="module" module-name="lang-impl" />
</component>
</module>