How to bring up a modal dialog (DialogWrapper or Messages) from within a WriteAction
Related to http://www.intellij.net/tracker/idea/viewSCR?publicId=17860 the clearcase plugin is supposed to ask whether to check out a file or not when a read-only file is modified.
I am listening to file modification through a ModificationAttemptListener. Would using EditFileProvider instead solve my problem? How am I supposed to use it?
Jacques
Please sign in to leave a comment.
BTW the problem is the assertion that is built in the DialogWrapper.show() to assert that a modal dialog is not shown inside a write action (or so I believe from the stacktrace ;)
In my case, the ModificationAttemptListener.readOnlyModifactionAttempt() is called from within a write action. From there I no longer can bring up a yes/no dialog anymore ;-(
How am I supposed to ask a question to the user?
Jacques
Here is the stacktrace
The answer is: you should never bring a modal dialog within a write action.
Reason? A bit tricky but here it is:
Suppose you have your own very precious Swing thread, you run a write action
from it, and you show a modal dialog MD1 from it. The write action will not
finish until a dialog is dismissed by user.
Imagine further that someone in a different thread (probably a VCS
integration or something) shows a modal dialog MD2 (such as progess dialog)
also and then invoked a read action.
Result: MD1 cannot close until MD2 is closed (because MD1 does not have
focus, but user need to press some button for it to close). MD2 cannot
close until read action is finished. Read action cannot start (and hence
finish) until write action is finished. Write action cannot finish until
MD1 is closed.
So there you are.
Morale: never, never ever, show a modal dialog in write action. Invoke it
later.
Friendly,
Dmitry
Jacques Morel wrote:
--
Dmitry Lomov
IntelliJ Labs / JetBrains Inc.
http://www.intellij.com
"Develop with pleasure!"
Jacques,
I am just offering this as a possible solution however, I don't really understand the whole threading issue. I invoke showCommentDialog from within certain VCS methods like "check-in". This was used in 3.0.5 so i am not sure how this applies to Aurora.
Dimitry, the arguments are clear although too far reaching.
The idea is: someone typed a character in a read/only file.
This is not a write action, since the file is readOnly.
The VCS plugins HAVE to ask the user whether the file should
become read/write and unless the user says Yes, the file
will be still R/O.
After confirming the action, the VCS plugin can checkout the file
and ONLY THEN the write action (insert char) could happen.
BTW, this wasn't a problem in previous versions I believe,
there was only the problem that if I type a character (or worse,
paste a text), the change wouldn't happen in the file.
And, it still doesn't work in 944 (maybe because of the exception?).
r.
P.S. You should never, never, never make a write action that
yet has to be confirmed it is a write action. ;)
Dmitry Lomov (JetBrains) wrote:
>>Related to http://www.intellij.net/tracker/idea/viewSCR?publicId=17860 the
>>clearcase plugin is supposed to ask whether to check out a file or not
>>when a read-only file is modified.
>>
>>I am listening to file modification through a ModificationAttemptListener.
>>Would using EditFileProvider instead solve my problem? How am I supposed
>>to use it?
>>
>>Jacques
Here is how my plugin does the same thing. I do in fact use invokeLater.
Why would this be a problem for you?
public void readOnlyModifactionAttempt(final ModificationAttemptEvent event) {
Project[] allProjects = ProjectManager.getInstance().getOpenProjects();
Project foundProject = null;
for(int i = 0, n = allProjects.length; i < n && foundProject == null; i++) {
Project project = allProjects+;
Window window = WindowManager.getInstance().suggestParentWindow(project);
if (window != null && window.isFocused()) {
foundProject = project;
}
}
if (foundProject != null) {
AbstractVcs av = VcsManager.getInstance(foundProject).getActiveVcs();
if (av instanceof VcsProject == false) {
// Not using this plugin as VCS.
return;
}
event.consume(); // So no alert or other message is shown. Doesn't work.
final Project finalProject = foundProject;
final VirtualFile[] files = event.getFiles();
SwingUtilities.invokeLater(new Runnable() {
public void run() {
if (_showing) {
return;
}
_showing = true;
try {
int result = Messages.showDialog(finalProject, MESSAGE, TITLE, CHOICES, CHECK_OUT_CHOICE, Messages.getWarningIcon());
if (result == CHECK_OUT_CHOICE) {
doCheckOut(finalProject, files);
}
else if (result == MAKE_WRITABLE_CHOICE) {
doMakeWritable(files);
}
}
finally {
_showing = false;
}
}
});
}
}
Jacques Morel wrote:
--
Erb
==============================================================
"Most of you are familiar with the virtues of a programmer.
There are three, of course: laziness, impatience, and hubris."
- Larry Wall
==============================================================
Erb wrote:
Nice, Erb. I hope this doesn't break any other IDEA restrictions.
However, it will not work if they will fix finishing the modification
action. The file is still readOnly when the listener is done.
So we will have the dialog but at that time the change will be gone.
Or will not?
r.
Thanks Richard for making it clear. The SCR I mentioned is completely unrelated and as it turns out I did not file one.
Dmitry I understand your point as Maxim explained to me a few days ago. I release now that I should have titled my post differently:
How to bring up a modal dialog from a ModificationAttemptListener? It seems that as much as possible any listener should be called outside a write action.
Here the VCS HAS TO ask the user whether he/she wants to check out the file. I don't see any other ways to do it.
Jacques
It isn't a problem now you are right because IDEA is not re-checking writability of files on any operations (refactoring).
However when they do (I REALLY hope they are going to do it), changing the writability of a file will need to be synchronous (see SCR http://www.intellij.net/tracker/idea/viewSCR?publicId=3671 ).
Erb, thanks for the tip on finding the current project. Smart! If you do not mind I will shamelessly rip it off ;) I fact I will rip off everything...
Stop stealing my ideas!!! ;)
It is so weird we are so in sync (in ideas and in timing ;)
Why not simply show the dialog in SwingUtilities.invokeLater()? As I
understand there is no need to show it synchroniously there (e.g. no result
is to be returned from the event handler). Am I wrong?
--
Valentin Kipiatkov
JetBrains, Inc
http://www.intellij.com
"Develop with pleasure!"
"Jacques Morel" <jacmorel@yahoo.com> wrote in message
news:6404168.1065191750074.JavaMail.itn@is.intellij.net...
unrelated and as it turns out I did not file one.
release now that I should have titled my post differently:
seems that as much as possible any listener should be called outside a write
action.
file. I don't see any other ways to do it.
>
Valentin Kipiatkov (JetBrains) wrote:
Yes and no.
The result is the event being consumed and file changed to R/W.
However, it seems for the time being both are ignored - we expect
this will change. Am I wrong? ;)
r.
See my solution above. Works fine.
Event being consumed would be an issue, but I assume it is consumed regardless
of the user response, because the event is being handled in some way.
Richard Nemec wrote:
>> Why not simply show the dialog in SwingUtilities.invokeLater()? As I
>> understand there is no need to show it synchroniously there (e.g. no
>> result
>> is to be returned from the event handler). Am I wrong?
--
Erb
==============================================================
"Most of you are familiar with the virtues of a programmer.
There are three, of course: laziness, impatience, and hubris."
- Larry Wall
==============================================================
regardless
Yes, I think it should be this way. Our own VCS intergations (SourceSafe and
CVS) work this way.
--
Valentin Kipiatkov
JetBrains, Inc
http://www.intellij.com
"Develop with pleasure!"
"Erb" <dont@evenbother.com> wrote in message
news:blkad7$ro6$1@is.intellij.net...
regardless
>
>
>
>
>
>
Valentin Kipiatkov (JetBrains) wrote:
>>Event being consumed would be an issue, but I assume it is consumed
>>regardless of the user response, because the event is being
>>handled in some way.
Yes, I agree that for the current behavior Erb's code is perfect.
However, what we are saying is that the mentioned behavior should
change. Don't you think that if I'm pasting some big text into a file
(let's say it is a huge XML with tons of repeating elements in which
case I cannot visually check whether it pasted or not), that file
is readonly, the automatic behavior works and unlocks the file for me,
then I should expect the pasted text to be there?
And in THAT case it shouldn't be a write action, since the unlock
step may ask the user whether really to unlock (e.g. checkout) and
finish the pasting sequence.
r.
One issue is that, if the action is to check out the file, then (at least in some VCS's),
the checked-out file may be different than the one on disk. So pasting where you thought you
wanted to paste might turn out to be wrong. However, it looks like IDEA checks whether the file
has changed or not, because it knows to maintain a text selection in this case but not if the file
changes. So supposedly it could do a similar trick for insertion, but, as you say, not if
that would be confusing.
Richard Nemec wrote:
>>> Event being consumed would be an issue, but I assume it is consumed
>>> regardless of the user response, because the event is being
>>
>> Yes, I think it should be this way. Our own VCS intergations
>> (SourceSafe and
>> CVS) work this way.
--
Erb
==============================================================
"Most of you are familiar with the virtues of a programmer.
There are three, of course: laziness, impatience, and hubris."
- Larry Wall
==============================================================