001: /*
002: * P4.java
003: *
004: * Copyright (C) 1998-2004 Peter Graves
005: * $Id: P4.java,v 1.17 2004/09/17 18:30:07 piso Exp $
006: *
007: * This program is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU General Public License
009: * as published by the Free Software Foundation; either version 2
010: * of the License, or (at your option) any later version.
011: *
012: * This program is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
015: * GNU General Public License for more details.
016: *
017: * You should have received a copy of the GNU General Public License
018: * along with this program; if not, write to the Free Software
019: * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
020: */
021:
022: package org.armedbear.j;
023:
024: import gnu.regexp.RE;
025: import gnu.regexp.REMatch;
026: import gnu.regexp.UncheckedRE;
027: import java.util.ArrayList;
028: import java.util.Iterator;
029: import java.util.List;
030: import javax.swing.SwingUtilities;
031: import javax.swing.undo.CompoundEdit;
032:
033: public class P4 implements Constants {
034: public static void p4() {
035: if (!checkP4Installed())
036: return;
037: MessageDialog.showMessageDialog(
038: "The command \"p4\" requires an argument.", "Error");
039: }
040:
041: public static void p4(String s) {
042: if (!checkP4Installed())
043: return;
044: List args = Utilities.tokenize(s);
045: if (args.size() == 0)
046: return;
047: String command = (String) args.get(0);
048: if (command.equals("submit")) {
049: MessageDialog.showMessageDialog("Use \"p4Submit\".",
050: "Error");
051: return;
052: }
053: if (command.equals("change")) {
054: MessageDialog.showMessageDialog("Use \"p4Change\".",
055: "Error");
056: return;
057: }
058: final Editor editor = Editor.currentEditor();
059: editor.setWaitCursor();
060: FastStringBuffer sb = new FastStringBuffer("p4 ");
061: for (Iterator it = args.iterator(); it.hasNext();) {
062: String arg = (String) it.next();
063: if (arg.equals("%")) {
064: File file = editor.getBuffer().getFile();
065: if (file != null)
066: arg = file.canonicalPath();
067: }
068: sb.append(maybeQuote(arg));
069: sb.append(' ');
070: }
071: final String cmd = sb.toString().trim();
072: final Buffer parentBuffer = editor.getBuffer();
073: Runnable commandRunnable = new Runnable() {
074: public void run() {
075: final String output = command(cmd, editor
076: .getCurrentDirectory());
077: Runnable completionRunnable = new Runnable() {
078: public void run() {
079: p4Completed(editor, parentBuffer, cmd, output);
080: }
081: };
082: SwingUtilities.invokeLater(completionRunnable);
083: }
084: };
085: new Thread(commandRunnable).start();
086: }
087:
088: private static void p4Completed(Editor editor, Buffer parentBuffer,
089: String cmd, String output) {
090: if (output != null && output.length() > 0) {
091: Buffer buf;
092: if (cmd.startsWith("p4 diff"))
093: buf = new DiffOutputBuffer(parentBuffer, output, VC_P4);
094: else
095: buf = OutputBuffer.getOutputBuffer(output);
096: buf.setTitle(cmd);
097: editor.makeNext(buf);
098: editor.activateInOtherWindow(buf);
099: }
100: }
101:
102: public static void add() {
103: if (!checkP4Installed())
104: return;
105: final Editor editor = Editor.currentEditor();
106: final Buffer buffer = editor.getBuffer();
107: if (buffer.getFile() == null)
108: return;
109: editor.setWaitCursor();
110: final String name = buffer.getFile().getName();
111: FastStringBuffer sb = new FastStringBuffer("p4 add ");
112: sb.append(maybeQuote(name));
113: final String cmd = sb.toString();
114: final String output = command(cmd, buffer.getCurrentDirectory());
115: OutputBuffer buf = OutputBuffer.getOutputBuffer(output);
116: buf.setTitle(cmd);
117: editor.makeNext(buf);
118: editor.activateInOtherWindow(buf);
119: editor.setDefaultCursor();
120: }
121:
122: public static void edit() {
123: if (!checkP4Installed())
124: return;
125: final Editor editor = Editor.currentEditor();
126: final Buffer buffer = editor.getBuffer();
127: final File file = buffer.getFile();
128: if (file == null)
129: return;
130: buffer.setBusy(true);
131: editor.setWaitCursor();
132: FastStringBuffer sb = new FastStringBuffer("p4 edit ");
133: sb.append(maybeQuote(file.canonicalPath()));
134: final String cmd = sb.toString();
135: Runnable commandRunnable = new Runnable() {
136: public void run() {
137: final String output = command(cmd, null);
138: Runnable completionRunnable = new Runnable() {
139: public void run() {
140: editCompleted(editor, buffer, cmd, output);
141: }
142: };
143: SwingUtilities.invokeLater(completionRunnable);
144: }
145: };
146: new Thread(commandRunnable).start();
147: }
148:
149: private static void editCompleted(Editor editor, Buffer buffer,
150: String cmd, String output) {
151: // Don't bother with output buffer unless there's an error.
152: if (output.trim().endsWith(" - opened for edit")) {
153: editor.status("File opened for edit");
154: } else {
155: OutputBuffer buf = OutputBuffer.getOutputBuffer(output);
156: buf.setTitle(cmd);
157: editor.makeNext(buf);
158: editor.activateInOtherWindow(buf);
159: }
160: // Update read-only status.
161: if (editor.reactivate(buffer))
162: Sidebar.repaintBufferListInAllFrames();
163: buffer.setBusy(false);
164: EditorIterator iter = new EditorIterator();
165: while (iter.hasNext()) {
166: Editor ed = iter.nextEditor();
167: if (ed.getBuffer() == buffer)
168: ed.setDefaultCursor();
169: }
170: }
171:
172: // For Editor.checkReadOnly(). Displays output buffer if necessary.
173: public static boolean autoEdit(Editor editor) {
174: if (editor == null)
175: return false;
176: final Buffer buffer = editor.getBuffer();
177: final File file = buffer.getFile();
178: String output = _autoEdit(file);
179: if (output == null)
180: return false;
181: FastStringBuffer sb = new FastStringBuffer("p4 edit ");
182: sb.append(maybeQuote(file.canonicalPath()));
183: editCompleted(editor, buffer, sb.toString(), output);
184: return !buffer.isReadOnly();
185: }
186:
187: // For replaceInFiles(). Returns false if there are any complications.
188: public static boolean autoEdit(File file) {
189: final String output = _autoEdit(file);
190: if (output == null)
191: return false;
192: return output.trim().endsWith(" - opened for edit");
193: }
194:
195: // Returns output from "p4 edit" command or null if error.
196: private static String _autoEdit(File file) {
197: if (file == null)
198: return null;
199: if (file.isRemote())
200: return null;
201: if (!haveP4())
202: return null;
203: FastStringBuffer sb = new FastStringBuffer("p4 edit ");
204: sb.append(maybeQuote(file.canonicalPath()));
205: return command(sb.toString(), null);
206: }
207:
208: public static void revert() {
209: if (!checkP4Installed())
210: return;
211: final Editor editor = Editor.currentEditor();
212: final Buffer buffer = editor.getBuffer();
213: final File file = buffer.getFile();
214: if (file == null)
215: return;
216: if (buffer.isModified()) {
217: String prompt = "Discard changes to "
218: + maybeQuote(file.getName()) + "?";
219: if (!editor.confirm("Revert Buffer", prompt))
220: return;
221: }
222: final String cmd = "p4 revert "
223: + maybeQuote(file.canonicalPath());
224: String output = command(cmd, null);
225: if (output.trim().endsWith(" - was edit, reverted")) {
226: editor.status("File reverted");
227: } else {
228: OutputBuffer buf = OutputBuffer.getOutputBuffer(output);
229: buf.setTitle(cmd);
230: editor.makeNext(buf);
231: editor.activateInOtherWindow(buf);
232: }
233: editor.reload(buffer);
234: // Update read-only status.
235: if (editor.reactivate(buffer))
236: Sidebar.repaintBufferListInAllFrames();
237: }
238:
239: public static void diff() {
240: if (!checkP4Installed())
241: return;
242: final Editor editor = Editor.currentEditor();
243: Buffer parentBuffer = editor.getBuffer();
244: if (parentBuffer instanceof CheckinBuffer)
245: parentBuffer = parentBuffer.getParentBuffer();
246: final File file = parentBuffer.getFile();
247: if (file == null)
248: return;
249: final String baseCmd = "p4 diff -f -du ";
250: final String name = file.getName();
251: final String title = baseCmd + maybeQuote(name);
252: boolean save = false;
253: if (parentBuffer.isModified()) {
254: int response = ConfirmDialog
255: .showConfirmDialogWithCancelButton(editor,
256: CHECK_SAVE_PROMPT, "P4 diff");
257: switch (response) {
258: case RESPONSE_YES:
259: save = true;
260: break;
261: case RESPONSE_NO:
262: break;
263: case RESPONSE_CANCEL:
264: return;
265: }
266: editor.repaintNow();
267: }
268: editor.setWaitCursor();
269: if (!save || parentBuffer.save()) {
270: // Kill existing diff output buffer if any for same parent buffer.
271: for (BufferIterator it = new BufferIterator(); it.hasNext();) {
272: Buffer b = it.nextBuffer();
273: if (b instanceof DiffOutputBuffer) {
274: if (b.getParentBuffer() == parentBuffer) {
275: editor.maybeKillBuffer(b);
276: break; // There should be one at most.
277: }
278: }
279: }
280: final String cmd = baseCmd
281: + maybeQuote(file.canonicalPath());
282: final String output = command(cmd, null);
283: DiffOutputBuffer buf = new DiffOutputBuffer(parentBuffer,
284: output, VC_P4);
285: buf.setTitle(title);
286: Editor otherEditor = editor.getOtherEditor();
287: if (otherEditor != null)
288: buf.setUnsplitOnClose(otherEditor.getBuffer()
289: .unsplitOnClose());
290: else
291: buf.setUnsplitOnClose(true);
292: editor.makeNext(buf);
293: editor.activateInOtherWindow(buf);
294: editor.setDefaultCursor();
295: }
296: }
297:
298: public static void diffDir() {
299: if (!checkP4Installed())
300: return;
301: final Editor editor = Editor.currentEditor();
302: final Buffer buffer = editor.getBuffer();
303: editor.setWaitCursor();
304: final String cmd = "p4 diff -du";
305: final File directory = buffer.getCurrentDirectory();
306: // Kill existing diff output buffer if any for same directory.
307: for (BufferIterator it = new BufferIterator(); it.hasNext();) {
308: Buffer b = it.nextBuffer();
309: if (b instanceof DiffOutputBuffer) {
310: if (directory.equals(((DiffOutputBuffer) b)
311: .getDirectory())) {
312: editor.maybeKillBuffer(b);
313: break; // There should be one at most.
314: }
315: }
316: }
317: final String output = command(cmd, directory);
318: DiffOutputBuffer buf = new DiffOutputBuffer(directory, output,
319: VC_P4);
320: if (buf != null) {
321: buf.setTitle(cmd);
322: editor.makeNext(buf);
323: editor.activateInOtherWindow(buf);
324: }
325: editor.setDefaultCursor();
326: }
327:
328: public static void log() {
329: log(null);
330: }
331:
332: public static void log(String args) {
333: final Editor editor = Editor.currentEditor();
334: final Buffer parentBuffer = editor.getBuffer();
335: boolean useCurrentFile = true;
336: List list = Utilities.tokenize(args);
337: for (int i = 0; i < list.size(); i++) {
338: String arg = (String) list.get(i);
339: if (arg.charAt(0) != '-') {
340: // Must be a filename. Use its canonical path.
341: File file = File.getInstance(parentBuffer
342: .getCurrentDirectory(), arg);
343: list.set(i, file.canonicalPath());
344: useCurrentFile = false;
345: } else if (arg.equals("-l")) {
346: // We use this option by default.
347: list.set(i, "");
348: }
349: }
350: final String baseCmd = "p4 filelog -l ";
351: final String title;
352: FastStringBuffer sb = new FastStringBuffer(baseCmd);
353: for (int i = 0; i < list.size(); i++) {
354: sb.append((String) list.get(i));
355: sb.append(' ');
356: }
357: if (useCurrentFile) {
358: File file = parentBuffer.getFile();
359: if (file == null)
360: return;
361: sb.append(maybeQuote(file.canonicalPath()));
362: title = baseCmd + maybeQuote(file.getName());
363: } else
364: title = sb.toString();
365: final String cmd = sb.toString();
366: editor.setWaitCursor();
367: final String output = command(cmd, null);
368: OutputBuffer buf = OutputBuffer.getOutputBuffer(output);
369: buf.setTitle(title);
370: editor.makeNext(buf);
371: editor.activateInOtherWindow(buf);
372: editor.setDefaultCursor();
373: }
374:
375: public static void change(String arg) {
376: arg = arg.trim();
377: try {
378: // Make sure arg is a number.
379: Integer.parseInt(arg);
380: _change(arg);
381: } catch (NumberFormatException e) {
382: MessageDialog.showMessageDialog(
383: "Argument must be a changelist number.", "Error");
384: }
385: }
386:
387: public static void change() {
388: _change(null);
389: }
390:
391: // arg must be a changelist number or null.
392: private static void _change(String arg) {
393: if (!checkP4Installed())
394: return;
395: final Editor editor = Editor.currentEditor();
396: Buffer parentBuffer = editor.getBuffer();
397: if (parentBuffer instanceof DiffOutputBuffer) {
398: Log.debug("parentBuffer is DiffOutputBuffer");
399: parentBuffer = parentBuffer.getParentBuffer();
400: Log.debug("==> parentBuffer is " + parentBuffer);
401: }
402: if (parentBuffer == null)
403: return;
404: if (parentBuffer.getFile() == null)
405: return;
406: FastStringBuffer sb = new FastStringBuffer("p4 change");
407: if (arg != null) {
408: sb.append(' ');
409: sb.append(arg);
410: }
411: final String title = sb.toString();
412: CheckinBuffer checkinBuffer = null;
413: for (BufferIterator it = new BufferIterator(); it.hasNext();) {
414: Buffer buf = it.nextBuffer();
415: if (buf instanceof CheckinBuffer) {
416: if (title.equals(buf.getTitle())) {
417: checkinBuffer = (CheckinBuffer) buf;
418: break;
419: }
420: }
421: }
422: if (checkinBuffer == null) {
423: checkinBuffer = new CheckinBuffer(parentBuffer, VC_P4, true);
424: checkinBuffer.setProperty(Property.USE_TABS, true);
425: checkinBuffer.setFormatter(new P4ChangelistFormatter(
426: checkinBuffer));
427: checkinBuffer.setTitle(title);
428: sb.setText("p4 change -o");
429: if (arg != null) {
430: sb.append(' ');
431: sb.append(arg);
432: }
433: ShellCommand shellCommand = new ShellCommand(sb.toString());
434: shellCommand.run();
435: checkinBuffer.setText(shellCommand.getOutput());
436: Position dot = findStartOfComment(checkinBuffer);
437: if (dot != null) {
438: Position mark = findEndOfComment(checkinBuffer, dot);
439: View view = new View();
440: view.setDot(dot);
441: view.setCaretCol(checkinBuffer.getCol(dot));
442: if (mark != null)
443: view.setMark(mark);
444: checkinBuffer.setLastView(view);
445: }
446: }
447: editor.makeNext(checkinBuffer);
448: editor.activateInOtherWindow(checkinBuffer);
449: }
450:
451: public static void submit(String args) {
452: String message = null;
453: List list = Utilities.tokenize(args);
454: if (list.size() == 2) {
455: String arg = (String) list.get(0);
456: if (arg.equals("-c")) {
457: arg = (String) list.get(1);
458: try {
459: Integer.parseInt(arg);
460: // Success!
461: _submit(arg);
462: return;
463: } catch (NumberFormatException e) {
464: message = "Invalid changelist number";
465: }
466: }
467: }
468: if (message == null) {
469: FastStringBuffer sb = new FastStringBuffer(
470: "Unrecognized argument \"");
471: sb.append(args.trim());
472: sb.append('"');
473: message = sb.toString();
474: }
475: MessageDialog.showMessageDialog(message, "Error");
476: }
477:
478: public static void submit() {
479: _submit(null);
480: }
481:
482: // arg must be a changelist number or null.
483: private static void _submit(String arg) {
484: if (!checkP4Installed())
485: return;
486: final Editor editor = Editor.currentEditor();
487: Buffer parentBuffer = editor.getBuffer();
488: if (parentBuffer instanceof DiffOutputBuffer)
489: parentBuffer = parentBuffer.getParentBuffer();
490: FastStringBuffer sb = new FastStringBuffer("p4 submit");
491: if (arg != null) {
492: sb.append(" -c ");
493: sb.append(arg);
494: }
495: final String title = sb.toString();
496: boolean save = false;
497: List list = getModifiedBuffers();
498: if (list != null && list.size() > 0) {
499: int response = ConfirmDialog
500: .showConfirmDialogWithCancelButton(editor,
501: "Save modified buffers first?", title);
502: switch (response) {
503: case RESPONSE_YES:
504: save = true;
505: break;
506: case RESPONSE_NO:
507: break;
508: case RESPONSE_CANCEL:
509: return;
510: }
511: editor.repaintNow();
512: }
513: if (!save || saveModifiedBuffers(editor, list)) {
514: // Look for existing checkin buffer before making a new one.
515: CheckinBuffer checkinBuffer = null;
516: for (BufferIterator it = new BufferIterator(); it.hasNext();) {
517: Buffer buf = it.nextBuffer();
518: if (buf instanceof CheckinBuffer) {
519: if (title.equals(buf.getTitle())) {
520: checkinBuffer = (CheckinBuffer) buf;
521: break;
522: }
523: }
524: }
525: if (checkinBuffer == null) {
526: checkinBuffer = new CheckinBuffer(parentBuffer, VC_P4);
527: checkinBuffer.setProperty(Property.USE_TABS, true);
528: checkinBuffer.setFormatter(new P4ChangelistFormatter(
529: checkinBuffer));
530: checkinBuffer.setTitle(title);
531: sb.setText("p4 change -o");
532: if (arg != null) {
533: sb.append(' ');
534: sb.append(arg);
535: }
536: ShellCommand shellCommand = new ShellCommand(sb
537: .toString());
538: shellCommand.run();
539: checkinBuffer.setText(shellCommand.getOutput());
540: Position dot = findStartOfComment(checkinBuffer);
541: if (dot != null) {
542: Position mark = findEndOfComment(checkinBuffer, dot);
543: View view = new View();
544: view.setDot(dot);
545: view.setCaretCol(checkinBuffer.getCol(dot));
546: if (mark != null)
547: view.setMark(mark);
548: checkinBuffer.setLastView(view);
549: }
550: }
551: editor.makeNext(checkinBuffer);
552: editor.activate(checkinBuffer);
553: }
554: }
555:
556: private static List getModifiedBuffers() {
557: ArrayList list = null;
558: for (BufferIterator it = new BufferIterator(); it.hasNext();) {
559: Buffer buf = it.nextBuffer();
560: if (!buf.isModified())
561: continue;
562: if (buf.isUntitled())
563: continue;
564: final int modeId = buf.getModeId();
565: if (modeId == SEND_MAIL_MODE)
566: continue;
567: if (modeId == CHECKIN_MODE)
568: continue;
569: if (buf.getFile() != null && buf.getFile().isLocal()) {
570: if (list == null)
571: list = new ArrayList();
572: list.add(buf);
573: }
574: }
575: return list;
576: }
577:
578: private static boolean saveModifiedBuffers(Editor editor, List list) {
579: editor.setWaitCursor();
580: int numErrors = 0;
581: for (Iterator it = list.iterator(); it.hasNext();) {
582: Buffer buf = (Buffer) it.next();
583: if (buf.getFile() != null && buf.getFile().isLocal()) {
584: editor.status("Saving modified buffers...");
585: if (buf
586: .getBooleanProperty(Property.REMOVE_TRAILING_WHITESPACE))
587: buf.removeTrailingWhitespace();
588: if (!buf.save())
589: ++numErrors;
590: }
591: }
592: editor.setDefaultCursor();
593: if (numErrors == 0) {
594: editor.status("Saving modified buffers...done");
595: return true;
596: }
597: // User will already have seen detailed error information from Buffer.save().
598: editor.status("");
599: return false;
600: }
601:
602: public static void replaceComment(final Editor editor,
603: final String comment) {
604: if (!(editor.getBuffer() instanceof CheckinBuffer)) {
605: Debug.bug();
606: return;
607: }
608: final CheckinBuffer buffer = (CheckinBuffer) editor.getBuffer();
609: String oldComment = extractComment(buffer);
610: if (oldComment.equals(comment))
611: return;
612: insertComment(editor, comment);
613: }
614:
615: public static String extractComment(final CheckinBuffer buffer) {
616: Position begin = findStartOfComment(buffer);
617: if (begin != null) {
618: Position end = findEndOfComment(buffer, begin);
619: if (end != null) {
620: int offset1 = buffer.getAbsoluteOffset(begin);
621: int offset2 = buffer.getAbsoluteOffset(end);
622: if (offset1 >= 0 && offset2 > offset1) {
623: String s = buffer.getText().substring(offset1,
624: offset2);
625: if (!s.equals("<enter description here>"))
626: return s;
627: }
628: }
629: }
630: return "";
631: }
632:
633: private static void insertComment(final Editor editor,
634: final String comment) {
635: final CheckinBuffer buffer = (CheckinBuffer) editor.getBuffer();
636: Position dot = findStartOfComment(buffer);
637: if (dot == null)
638: return;
639: Position mark = findEndOfComment(buffer, dot);
640: if (mark == null)
641: return;
642: try {
643: buffer.lockWrite();
644: } catch (InterruptedException e) {
645: Log.error(e);
646: return;
647: }
648: try {
649: CompoundEdit compoundEdit = editor.beginCompoundEdit();
650: editor.moveDotTo(dot);
651: editor.setMark(mark);
652: editor.deleteRegion();
653: editor.insertString(comment);
654: editor.endCompoundEdit(compoundEdit);
655: buffer.modified();
656: } finally {
657: buffer.unlockWrite();
658: }
659: final Position end = findEndOfComment(buffer, null);
660: for (EditorIterator it = new EditorIterator(); it.hasNext();) {
661: Editor ed = it.nextEditor();
662: if (ed.getBuffer() == buffer) {
663: ed.setTopLine(buffer.getFirstLine());
664: ed.setDot(end.copy()); // No undo.
665: ed.moveCaretToDotCol();
666: ed.setUpdateFlag(REPAINT);
667: ed.updateDisplay();
668: }
669: }
670: }
671:
672: private static Position findStartOfComment(CheckinBuffer buffer) {
673: String s = buffer.getText();
674: String lookFor = "\nDescription:\n\t";
675: RE re = new UncheckedRE(lookFor);
676: REMatch match = re.getMatch(s);
677: if (match != null)
678: return buffer.getPosition(match.getStartIndex()
679: + lookFor.length());
680: return null;
681: }
682:
683: private static Position findEndOfComment(CheckinBuffer buffer,
684: Position start) {
685: String s = buffer.getText();
686: String lookFor = "\n\nFiles:\n\t";
687: RE re = new UncheckedRE(lookFor);
688: int offset = -1;
689: if (start != null)
690: offset = buffer.getAbsoluteOffset(start);
691: if (offset < 0)
692: offset = 0;
693: REMatch match = re.getMatch(s, offset);
694: if (match != null)
695: return buffer.getPosition(match.getStartIndex());
696: return null;
697: }
698:
699: public static void finish(Editor editor, CheckinBuffer checkinBuffer) {
700: final Buffer parentBuffer = checkinBuffer.getParentBuffer();
701: editor.getFrame().setWaitCursor();
702: final boolean editOnly = checkinBuffer.isEditOnly();
703: final String cmd;
704: final String title;
705: if (editOnly) {
706: cmd = "p4 change -i";
707: title = "Output from p4 change";
708: } else {
709: cmd = "p4 submit -i";
710: title = "Output from p4 submit";
711: }
712: final String input = checkinBuffer.getText();
713: ShellCommand shellCommand = new ShellCommand(cmd, null, input);
714: shellCommand.run();
715: if (shellCommand.exitValue() != 0) {
716: // Error.
717: Log.error("P4.finish input = |" + input + "|");
718: Log.error("P4.finish exit value = "
719: + shellCommand.exitValue());
720: OutputBuffer buf = null;
721: // Re-use existing output buffer if possible.
722: for (BufferIterator it = new BufferIterator(); it.hasNext();) {
723: Buffer b = it.nextBuffer();
724: if (b instanceof OutputBuffer) {
725: if (title.equals(b.getTitle())) {
726: buf = (OutputBuffer) b;
727: break; // There should be one at most.
728: }
729: }
730: }
731: if (buf != null)
732: buf.setText(shellCommand.getOutput());
733: else
734: buf = OutputBuffer.getOutputBuffer(shellCommand
735: .getOutput());
736: buf.setTitle(title);
737: editor.makeNext(buf);
738: editor.displayInOtherWindow(buf);
739: } else {
740: // Success. Kill old diff and output buffers, if any: their
741: // contents are no longer correct.
742: if (!editOnly && parentBuffer != null) {
743: for (BufferIterator it = new BufferIterator(); it
744: .hasNext();) {
745: Buffer b = it.nextBuffer();
746: if (b instanceof DiffOutputBuffer) {
747: if (b.getParentBuffer() == parentBuffer) {
748: Debug.assertTrue(Editor.getBufferList()
749: .contains(b));
750: Log
751: .debug("P4.finish killing diff output buffer");
752: b.kill();
753: Debug.assertFalse(Editor.getBufferList()
754: .contains(b));
755: Debug.assertTrue(editor.getBuffer() != b);
756: Editor otherEditor = editor
757: .getOtherEditor();
758: if (otherEditor != null)
759: Debug.assertTrue(otherEditor
760: .getBuffer() != b);
761: break; // There should be one at most.
762: }
763: }
764: }
765: }
766: for (BufferIterator it = new BufferIterator(); it.hasNext();) {
767: Buffer b = it.nextBuffer();
768: if (b instanceof OutputBuffer) {
769: if (title.equals(b.getTitle())) {
770: editor.maybeKillBuffer(b);
771: break; // One at most.
772: }
773: }
774: }
775: if (!editOnly)
776: // Read-only status of some buffers may have changed.
777: editor.getFrame().reactivate();
778: editor.otherWindow();
779: editor.unsplitWindow();
780: checkinBuffer.kill();
781: }
782: editor.getFrame().setDefaultCursor();
783: }
784:
785: public static String getStatusString(File file) {
786: if (file != null && haveP4()) {
787: FastStringBuffer sb = null;
788: String output = command("p4 fstat ".concat(file
789: .canonicalPath()), null);
790: String HAVE_REV = "... haveRev ";
791: int begin = output.indexOf(HAVE_REV);
792: if (begin >= 0) {
793: begin += HAVE_REV.length();
794: int end = output.indexOf('\n', begin);
795: if (end > begin) {
796: if (sb == null)
797: sb = new FastStringBuffer("Perforce");
798: sb.append(" revision ");
799: sb.append(output.substring(begin, end).trim());
800: }
801: }
802: String ACTION = "... action ";
803: begin = output.indexOf(ACTION);
804: if (begin >= 0) {
805: begin += ACTION.length();
806: int end = output.indexOf('\n', begin);
807: if (end > begin) {
808: if (sb == null)
809: sb = new FastStringBuffer("Perforce");
810: sb.append(" (opened for ");
811: sb.append(output.substring(begin, end).trim());
812: sb.append(')');
813: }
814: }
815: if (sb != null)
816: return sb.toString();
817: }
818: return null;
819: }
820:
821: // Implementation.
822: private static final String command(String cmd,
823: File workingDirectory) {
824: ShellCommand shellCommand = new ShellCommand(cmd,
825: workingDirectory);
826: shellCommand.run();
827: return shellCommand.getOutput();
828: }
829:
830: private static boolean checkP4Installed() {
831: if (haveP4())
832: return true;
833: MessageDialog
834: .showMessageDialog(
835: "The Perforce command-line client does not appear to be in your PATH.",
836: "Error");
837: return false;
838: }
839:
840: private static int haveP4 = -1;
841:
842: private static boolean haveP4() {
843: if (haveP4 > 0)
844: return true;
845: if (Utilities.have("p4")) {
846: haveP4 = 1; // Cache positive result.
847: return true;
848: }
849: return false;
850: }
851:
852: // Enclose string in quotes if it contains any embedded spaces.
853: private static String maybeQuote(String s) {
854: if (s.indexOf(' ') < 0)
855: return s;
856: FastStringBuffer sb = new FastStringBuffer('"');
857: sb.append(s);
858: sb.append('"');
859: return sb.toString();
860: }
861: }
|