2 * Copyright 2000-2009 JetBrains s.r.o.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
16 package com
.intellij
.openapi
.vcs
.changes
.committed
;
18 import com
.intellij
.openapi
.application
.ApplicationManager
;
19 import com
.intellij
.openapi
.components
.ProjectComponent
;
20 import com
.intellij
.openapi
.diagnostic
.Logger
;
21 import com
.intellij
.openapi
.fileEditor
.FileEditor
;
22 import com
.intellij
.openapi
.fileEditor
.FileEditorManager
;
23 import com
.intellij
.openapi
.fileEditor
.FileEditorManagerEvent
;
24 import com
.intellij
.openapi
.fileEditor
.FileEditorManagerListener
;
25 import com
.intellij
.openapi
.project
.Project
;
26 import com
.intellij
.openapi
.util
.Key
;
27 import com
.intellij
.openapi
.util
.Pair
;
28 import com
.intellij
.openapi
.vcs
.VcsBundle
;
29 import com
.intellij
.openapi
.vcs
.changes
.Change
;
30 import com
.intellij
.openapi
.vcs
.versionBrowser
.CommittedChangeList
;
31 import com
.intellij
.openapi
.vfs
.VirtualFile
;
32 import com
.intellij
.ui
.EditorNotificationPanel
;
33 import com
.intellij
.util
.Consumer
;
34 import com
.intellij
.util
.messages
.MessageBus
;
35 import org
.jetbrains
.annotations
.NonNls
;
36 import org
.jetbrains
.annotations
.NotNull
;
37 import org
.jetbrains
.annotations
.Nullable
;
39 import java
.text
.DateFormat
;
40 import java
.util
.List
;
45 public class OutdatedVersionNotifier
implements ProjectComponent
{
46 private static final Logger LOG
= Logger
.getInstance("#com.intellij.openapi.vcs.changes.committed.OutdatedVersionNotifier");
48 private final FileEditorManager myFileEditorManager
;
49 private final CommittedChangesCache myCache
;
50 private final Project myProject
;
51 private static final Key
<OutdatedRevisionPanel
> PANEL_KEY
= new Key
<OutdatedRevisionPanel
>("OutdatedRevisionPanel");
52 private volatile boolean myIncomingChangesRequested
;
54 public OutdatedVersionNotifier(FileEditorManager fileEditorManager
,
55 CommittedChangesCache cache
,
56 MessageBus messageBus
, Project project
) {
57 myFileEditorManager
= fileEditorManager
;
60 messageBus
.connect().subscribe(CommittedChangesCache
.COMMITTED_TOPIC
, new CommittedChangesAdapter() {
61 public void incomingChangesUpdated(@Nullable final List
<CommittedChangeList
> receivedChanges
) {
62 if (myCache
.getCachedIncomingChanges() == null) {
63 requestLoadIncomingChanges();
66 updateAllEditorsLater();
72 private void requestLoadIncomingChanges() {
73 debug("Requesting load of incoming changes");
74 if (!myIncomingChangesRequested
) {
75 myIncomingChangesRequested
= true;
76 myCache
.loadIncomingChangesAsync(new Consumer
<List
<CommittedChangeList
>>() {
77 public void consume(final List
<CommittedChangeList
> committedChangeLists
) {
78 myIncomingChangesRequested
= false;
79 updateAllEditorsLater();
85 private static void debug(@NonNls String message
) {
89 public void projectOpened() {
90 final FileEditorManagerListener myFileEditorManagerListener
= new MyFileEditorManagerListener();
91 myFileEditorManager
.addFileEditorManagerListener(myFileEditorManagerListener
, myProject
);
94 public void projectClosed() {
99 public String
getComponentName() {
100 return "OutdatedVersionNotifier";
103 public void initComponent() {
106 public void disposeComponent() {
109 private void updateAllEditorsLater() {
110 debug("Queueing update of editors");
111 ApplicationManager
.getApplication().invokeLater(new Runnable() {
118 private void updateAllEditors() {
119 if (myCache
.getCachedIncomingChanges() == null) {
120 requestLoadIncomingChanges();
123 debug("Updating editors");
124 final VirtualFile
[] files
= myFileEditorManager
.getOpenFiles();
125 for(VirtualFile file
: files
) {
126 final Pair
<CommittedChangeList
,Change
> pair
= myCache
.getIncomingChangeList(file
);
127 final FileEditor
[] fileEditors
= myFileEditorManager
.getEditors(file
);
128 for(FileEditor editor
: fileEditors
) {
129 final OutdatedRevisionPanel oldPanel
= editor
.getUserData(PANEL_KEY
);
131 if (oldPanel
!= null) {
132 oldPanel
.setChangeList(pair
.first
, pair
.second
);
135 initPanel(pair
.first
, pair
.second
, editor
);
138 else if (oldPanel
!= null) {
139 myFileEditorManager
.removeTopComponent(editor
, oldPanel
);
140 editor
.putUserData(PANEL_KEY
, null);
146 private void initPanel(final CommittedChangeList list
, final Change c
, final FileEditor editor
) {
147 final OutdatedRevisionPanel component
= new OutdatedRevisionPanel(list
, c
);
148 editor
.putUserData(PANEL_KEY
, component
);
149 myFileEditorManager
.addTopComponent(editor
, component
);
152 private class MyFileEditorManagerListener
implements FileEditorManagerListener
{
153 public void fileOpened(FileEditorManager source
, VirtualFile file
) {
154 if (myCache
.getCachedIncomingChanges() == null) {
155 requestLoadIncomingChanges();
158 final Pair
<CommittedChangeList
, Change
> pair
= myCache
.getIncomingChangeList(file
);
160 final FileEditor
[] fileEditors
= source
.getEditors(file
);
161 for(FileEditor editor
: fileEditors
) {
162 initPanel(pair
.first
, pair
.second
, editor
);
168 public void fileClosed(FileEditorManager source
, VirtualFile file
) {
171 public void selectionChanged(FileEditorManagerEvent event
) {
175 private static class OutdatedRevisionPanel
extends EditorNotificationPanel
{
176 private CommittedChangeList myChangeList
;
178 public OutdatedRevisionPanel(CommittedChangeList changeList
, final Change c
) {
180 createActionLabel(VcsBundle
.message("outdated.version.show.diff.action"), "Compare.LastVersion");
181 createActionLabel(VcsBundle
.message("outdated.version.update.project.action"), "Vcs.UpdateProject");
182 myChangeList
= changeList
;
186 private void updateLabelText(final Change c
) {
187 final DateFormat dateFormat
= DateFormat
.getDateTimeInstance(DateFormat
.MEDIUM
, DateFormat
.MEDIUM
);
188 String comment
= myChangeList
.getComment();
189 int pos
= comment
.indexOf("\n");
191 comment
= comment
.substring(0, pos
).trim() + "...";
193 final String key
= c
.getType() == Change
.Type
.DELETED ?
"outdated.version.text.deleted" : "outdated.version.text";
194 myLabel
.setText(VcsBundle
.message(key
, myChangeList
.getCommitterName(),
195 dateFormat
.format(myChangeList
.getCommitDate()), comment
));
198 public void setChangeList(final CommittedChangeList changeList
, final Change c
) {
199 myChangeList
= changeList
;