001: /*
002: * :tabSize=8:indentSize=8:noTabs=false:
003: * :folding=explicit:collapseFolds=1:
004: *
005: * Delegate.java - A delegate for NSApplication
006: * Copyright (C) 2003 Kris Kopicki
007: *
008: * This program is free software; you can redistribute it and/or
009: * modify it under the terms of the GNU General Public License
010: * as published by the Free Software Foundation; either version 2
011: * of the License, or any later version.
012: *
013: * This program is distributed in the hope that it will be useful,
014: * but WITHOUT ANY WARRANTY; without even the implied warranty of
015: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
016: * GNU General Public License for more details.
017: *
018: * You should have received a copy of the GNU General Public License
019: * along with this program; if not, write to the Free Software
020: * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
021: */
022:
023: package macos;
024:
025: //{{{ Imports
026: import com.apple.eawt.*;
027: import com.apple.eio.*;
028: import com.apple.cocoa.application.*;
029: import com.apple.cocoa.foundation.*;
030: import java.util.*;
031: import java.io.File;
032: import javax.swing.*;
033: import org.gjt.sp.jedit.*;
034: import org.gjt.sp.jedit.browser.*;
035: import org.gjt.sp.jedit.gui.*;
036: import org.gjt.sp.jedit.msg.*;
037: import org.gjt.sp.jedit.options.GlobalOptions;
038: import org.gjt.sp.util.Log;
039:
040: //}}}
041:
042: public class Delegate extends ApplicationAdapter {
043: //{{{ Variables
044: private final NSSelector actionSel = new NSSelector("doAction",
045: new Class[] {});
046:
047: private List filenames = new LinkedList();
048:
049: //}}}
050:
051: //{{{ Constructor
052: public Delegate() {
053: if (jEdit
054: .getBooleanProperty(
055: "MacOSPlugin.useScreenMenuBar",
056: jEdit
057: .getBooleanProperty("MacOSPlugin.default.useScreenMenuBar")))
058: System.setProperty("apple.laf.useScreenMenuBar", "true");
059: else
060: System.setProperty("apple.laf.useScreenMenuBar", "false");
061: } //}}}
062:
063: //{{{ Handlers
064:
065: //{{{ handleAbout() method
066: public void handleAbout(ApplicationEvent event) {
067: event.setHandled(true);
068: new AboutDialog(jEdit.getActiveView());
069: } //}}}
070:
071: //{{{ handleFileCodes() method
072: public void handleFileCodes(BufferUpdate msg) {
073: Buffer buffer = msg.getBuffer();
074:
075: if (jEdit
076: .getBooleanProperty(
077: "MacOSPlugin.setTypeCreator",
078: jEdit
079: .getBooleanProperty("MacOSPlugin.default.setTypeCreator"))) {
080: // Set type/creator on save
081: if (!buffer.isDirty()
082: && msg.getWhat() == BufferUpdate.DIRTY_CHANGED) {
083: try {
084: int type = FileManager
085: .getFileType(buffer.getPath());
086: int creator = FileManager.getFileCreator(buffer
087: .getPath());
088:
089: if (type != 0)
090: buffer.setIntegerProperty("MacOSPlugin.type",
091: type);
092: if (creator != 0)
093: buffer.setIntegerProperty(
094: "MacOSPlugin.creator", creator);
095: FileManager
096: .setFileTypeAndCreator(
097: buffer.getPath(),
098: buffer
099: .getIntegerProperty(
100: "MacOSPlugin.type",
101: jEdit
102: .getIntegerProperty(
103: "MacOSPlugin.default.type",
104: 0)),
105: buffer
106: .getIntegerProperty(
107: "MacOSPlugin.creator",
108: jEdit
109: .getIntegerProperty(
110: "MacOSPlugin.default.creator",
111: 0)));
112: } catch (Exception e) {
113: // This will happen when a new file is created
114: // Fail silently, since we may be using UFS
115: }
116: }
117: // Add type/creator to local buffer property list on open
118: else if (msg.getWhat() == BufferUpdate.CREATED) {
119: if (jEdit
120: .getBooleanProperty(
121: "MacOSPlugin.preserveCodes",
122: jEdit
123: .getBooleanProperty("MacOSPlugin.default.preserveCodes"))) {
124: try {
125: int type = FileManager.getFileType(buffer
126: .getPath());
127: int creator = FileManager.getFileCreator(buffer
128: .getPath());
129:
130: if (type != 0)
131: buffer.setIntegerProperty(
132: "MacOSPlugin.type", type);
133: if (creator != 0)
134: buffer.setIntegerProperty(
135: "MacOSPlugin.creator", creator);
136: } catch (Exception e) {
137: // This will happen when a new file is created
138: }
139: }
140: }
141: }
142:
143: } //}}}
144:
145: //{{{ handleOpenFile() method
146: public void handleOpenFile(ApplicationEvent event) {
147: filenames.add(event.getFilename());
148: event.setHandled(true);
149: } //}}}
150:
151: //{{{ handleOpenFile() method
152: public void handleOpenFile(ViewUpdate msg) {
153: if (msg.getWhat() == ViewUpdate.CREATED) {
154: Iterator i = filenames.iterator();
155: while (i.hasNext())
156: jEdit.openFile(msg.getView(), (String) i.next());
157: MacOSPlugin.started = true;
158: NSApplication app = NSApplication.sharedApplication();
159: app.setServicesProvider(new Delegate());
160: }
161: } //}}}
162:
163: //{{{ handlePreferences() method
164: public void handlePreferences(ApplicationEvent event) {
165: event.setHandled(true);
166: new GlobalOptions(jEdit.getActiveView());
167: } //}}}
168:
169: //{{{ handleQuit() method
170: /**
171: * This never seems to be called when used with a delegate
172: */
173: //public void handleQuit(ApplicationEvent event)
174: //{
175: // event.setHandled(false);
176: // jEdit.exit(jEdit.getActiveView(),true);
177: //} //}}}
178: //}}}
179: //{{{ Delegate methods
180: //{{{ applicationDockMenu() method
181: public NSMenu applicationDockMenu(NSApplication sender) {
182: NSMenu dockMenu;
183: BufferMenu bufMenu;
184: MacrosMenu macMenu;
185: RecentMenu recMenu;
186: RecentDirMenu dirMenu;
187: NSMenuItem showCurrItem;
188: NSMenuItem showCurrDirItem;
189: NSMenuItem newViewItem;
190:
191: // Buffers
192: NSMenuItem miBuff = new NSMenuItem(jEdit
193: .getProperty("MacOSPlugin.menu.buffers.label"), null,
194: "");
195: miBuff.setSubmenu(bufMenu = new BufferMenu());
196:
197: // Recent Buffers
198: NSMenuItem miRec = new NSMenuItem(jEdit
199: .getProperty("MacOSPlugin.menu.recent.label"), null, "");
200: miRec.setSubmenu(recMenu = new RecentMenu());
201:
202: // Recent Directories
203: NSMenuItem miDir = new NSMenuItem(jEdit
204: .getProperty("MacOSPlugin.menu.recentDir.label"), null,
205: "");
206: miDir.setSubmenu(dirMenu = new RecentDirMenu());
207:
208: // Macros
209: NSMenuItem miMac = new NSMenuItem(jEdit
210: .getProperty("MacOSPlugin.menu.macros.label"), null, "");
211: miMac.setSubmenu(macMenu = new MacrosMenu());
212:
213: dockMenu = new NSMenu();
214: newViewItem = new NSMenuItem(jEdit
215: .getProperty("MacOSPlugin.menu.newView"), actionSel, "");
216: newViewItem.setTarget(new NewViewAction());
217: dockMenu.addItem(newViewItem);
218: dockMenu.addItem(new NSMenuItem().separatorItem());
219: showCurrItem = new NSMenuItem(jEdit
220: .getProperty("MacOSPlugin.menu.showCurrent"),
221: actionSel, "");
222: dockMenu.addItem(showCurrItem);
223: showCurrDirItem = new NSMenuItem(jEdit
224: .getProperty("MacOSPlugin.menu.showCurrentDir"),
225: actionSel, "");
226: dockMenu.addItem(showCurrDirItem);
227: dockMenu.addItem(new NSMenuItem().separatorItem());
228: dockMenu.addItem(miBuff);
229: dockMenu.addItem(miRec);
230: dockMenu.addItem(miDir);
231: //dockMenu.addItem(new NSMenuItem().separatorItem());
232: //dockMenu.addItem(miMac);
233: if (jEdit.getViewCount() == 0)
234: miMac.setEnabled(false);
235:
236: bufMenu.updateMenu();
237: recMenu.updateMenu();
238: dirMenu.updateMenu();
239: macMenu.updateMenu();
240:
241: View view = jEdit.getActiveView();
242: if (view != null) {
243: File buff = new File(view.getBuffer().getPath());
244: if (buff.exists()) {
245: showCurrItem.setTarget(new ShowFileAction(buff
246: .getPath()));
247: showCurrDirItem.setTarget(new ShowFileAction(buff
248: .getParent()));
249: }
250: } else {
251: showCurrItem.setEnabled(false);
252: showCurrDirItem.setEnabled(false);
253: }
254:
255: return dockMenu;
256: } //}}}
257:
258: //{{{ applicationOpenFiles() method
259: public void applicationOpenFiles(NSApplication sender,
260: NSArray filenames) {
261: // Must be declared final to be used by inner class
262: final Collection files = new ArrayList();
263: int count = filenames.count();
264: for (int i = 0; i < count; i++)
265: files.add(new File((String) filenames.objectAtIndex(i)));
266:
267: SwingUtilities.invokeLater(new Runnable() {
268: public void run() {
269: for (Iterator iter = files.iterator(); iter.hasNext();) {
270: File file = (File) iter.next();
271: View view = jEdit.getActiveView();
272: if (view == null)
273: view = PerspectiveManager.loadPerspective(true);
274:
275: if (file.isDirectory()) {
276: VFSBrowser.browseDirectory(jEdit
277: .getActiveView(), file.getPath());
278: return;
279: }
280:
281: if (jEdit.openFile(view, file.getPath()) == null)
282: Log.log(Log.ERROR, this , "Error opening file.");
283: }
284: }
285: });
286: } //}}}
287:
288: //{{{ applicationShouldHandleReopen() method
289: public boolean applicationShouldHandleReopen(
290: NSApplication theApplication, boolean flag) {
291: SwingUtilities.invokeLater(new Runnable() {
292: public void run() {
293: if (jEdit.getViewCount() == 0)
294: new NewViewAction().doAction();
295: }
296: });
297:
298: return false;
299: } //}}}
300:
301: //{{{ applicationShouldTerminate() method
302: public boolean applicationShouldTerminate(NSApplication sender) {
303: SwingUtilities.invokeLater(new Runnable() {
304: public void run() {
305: jEdit.exit(jEdit.getActiveView(), true);
306: }
307: });
308: return false;
309: }
310:
311: //}}}
312:
313: //}}}
314:
315: //{{{ Services
316:
317: //{{{ openFile() method
318: public String openFile(NSPasteboard pboard, String userData) {
319: if (jEdit.getViewCount() == 0)
320: return null;
321:
322: NSData data = pboard.dataForType("NSFilenamesPboardType");
323: String[] error = new String[1];
324: int[] format = new int[1];
325: NSArray filenames = (NSArray) NSPropertyListSerialization
326: .propertyListFromData(
327: data,
328: NSPropertyListSerialization.PropertyListImmutable,
329: format, error);
330: int count = filenames.count();
331: for (int i = 0; i < count; i++) {
332: File file = new File((String) filenames.objectAtIndex(i));
333: if (file.isDirectory())
334: VFSBrowser.browseDirectory(jEdit.getActiveView(), file
335: .getPath());
336: else
337: jEdit.openFile(jEdit.getActiveView(), file.getPath());
338: }
339:
340: return null;
341: } //}}}
342:
343: //{{{ insertSelection() method
344: public String insertSelection(NSPasteboard pboard, String userData) {
345: String string = pboard.stringForType("NSStringPboardType");
346: if (jEdit.getViewCount() > 0) {
347: View view = jEdit.getActiveView();
348: view.getBuffer().insert(
349: view.getTextArea().getCaretPosition(), string);
350: }
351: return null;
352: } //}}}
353:
354: //{{{ openSelection() method
355: public String openSelection(NSPasteboard pboard, String userData) {
356: String string = pboard.stringForType("NSStringPboardType");
357: if (jEdit.getViewCount() == 0)
358: new NewViewAction().doAction();
359: jEdit.newFile(jEdit.getActiveView()).insert(0,
360: pboard.stringForType("NSStringPboardType"));
361: return null;
362: } //}}}
363:
364: //}}}
365:
366: //{{{ Dock Menu
367:
368: //{{{ BufferMenu class
369: class BufferMenu extends NSMenu {
370: public BufferMenu() {
371: super ();
372: }
373:
374: public void updateMenu() {
375: NSMenuItem item;
376: for (int i = 0; i < numberOfItems(); i++)
377: removeItemAtIndex(0);
378:
379: Buffer[] buffs = jEdit.getBuffers();
380: for (int i = 0; i < buffs.length; i++) {
381: if (!buffs[i].isUntitled()) {
382: item = new NSMenuItem(buffs[i].getName(),
383: actionSel, "");
384: item.setTarget(new ShowFileAction(buffs[i]
385: .getPath()));
386: //item.setImage(NSWorkspace.sharedWorkspace().iconForFile(
387: // buffs[i].getPath()));
388: if (!new File(buffs[i].getPath()).exists())
389: item.setEnabled(false);
390: addItem(item);
391: }
392: }
393:
394: if (numberOfItems() == 0) {
395: item = new NSMenuItem(jEdit
396: .getProperty("MacOSPlugin.menu.buffers.none"),
397: null, "");
398: item.setEnabled(false);
399: addItem(item);
400: }
401: }
402: } //}}}
403:
404: //{{{ MacrosMenu class
405: class MacrosMenu extends NSMenu {
406: public MacrosMenu() {
407: super ();
408: }
409:
410: public void updateMenu() {
411: Vector macroVector = Macros.getMacroHierarchy();
412: NSMenuItem item;
413: File file;
414: int max = macroVector.size();
415:
416: int length = numberOfItems();
417: for (int i = 0; i < length; i++)
418: removeItemAtIndex(0);
419:
420: if (max == 0) {
421: item = new NSMenuItem(jEdit
422: .getProperty("MacOSPlugin.menu.macros.none"),
423: null, "");
424: item.setEnabled(false);
425: addItem(item);
426: return;
427: }
428:
429: createMenu(this , macroVector);
430: }
431:
432: public void createMenu(NSMenu menu, Vector vector) {
433: for (int i = 0; i < vector.size(); i++) {
434: Object obj = vector.elementAt(i);
435: if (obj instanceof Macros.Macro) {
436: Macros.Macro macro = (Macros.Macro) obj;
437: NSMenuItem item = new NSMenuItem(macro.getLabel(),
438: actionSel, "");
439: item.setTarget(new MacroAction(macro));
440: menu.addItem(item);
441: } else if (obj instanceof Vector) {
442: Vector subvector = (Vector) obj;
443: String name = (String) subvector.elementAt(0);
444: NSMenu submenu = new NSMenu();
445: createMenu(submenu, subvector);
446: if (submenu.numberOfItems() > 0) {
447: NSMenuItem submenuitem = new NSMenuItem(name,
448: null, "");
449: submenuitem.setSubmenu(submenu);
450: menu.addItem(submenuitem);
451: }
452: }
453: }
454: }
455: } //}}}
456:
457: //{{{ RecentMenu class
458: class RecentMenu extends NSMenu {
459: public RecentMenu() {
460: super ();
461: }
462:
463: public void updateMenu() {
464: List recent = BufferHistory.getHistory();
465: NSMenuItem item;
466: File file;
467: int max = recent.size();
468: int min = max - 20;
469:
470: int length = numberOfItems();
471: for (int i = 0; i < length; i++)
472: removeItemAtIndex(0);
473:
474: if (max == 0) {
475: item = new NSMenuItem(jEdit
476: .getProperty("MacOSPlugin.menu.recent.none"),
477: null, "");
478: item.setEnabled(false);
479: addItem(item);
480: return;
481: }
482:
483: if (min < 0)
484: min = 0;
485:
486: for (int i = max - 1; i >= min; i--) {
487: file = new File(
488: ((BufferHistory.Entry) recent.get(i)).path);
489: item = new NSMenuItem(file.getName(), actionSel, "");
490: item.setTarget(new ShowFileAction(file.getPath()));
491: if (!file.exists())
492: item.setEnabled(false);
493: addItem(item);
494: }
495: }
496: } //}}}
497:
498: //{{{ RecentDirMenu class
499: class RecentDirMenu extends NSMenu {
500: public RecentDirMenu() {
501: super ();
502: }
503:
504: public void updateMenu() {
505: HistoryModel model = HistoryModel
506: .getModel("vfs.browser.path");
507: NSMenuItem item;
508: File file;
509: int max = model.getSize();
510:
511: int length = numberOfItems();
512: for (int i = 0; i < length; i++)
513: removeItemAtIndex(0);
514:
515: if (max == 0) {
516: item = new NSMenuItem(
517: jEdit
518: .getProperty("MacOSPlugin.menu.recentDir.none"),
519: null, "");
520: item.setEnabled(false);
521: addItem(item);
522: return;
523: }
524:
525: for (int i = 0; i < max; i++) {
526: file = new File(model.getItem(i));
527: item = new NSMenuItem(file.getName(), actionSel, "");
528: item.setTarget(new ShowFileAction(file.getPath()));
529: if (!file.exists())
530: item.setEnabled(false);
531: addItem(item);
532: }
533: }
534: } //}}}
535:
536: //{{{ MacroAction class
537: class MacroAction {
538: private Macros.Macro macro;
539:
540: public MacroAction(Macros.Macro macro) {
541: this .macro = macro;
542: }
543:
544: public void doAction() {
545: macro.invoke(jEdit.getActiveView());
546: }
547: } //}}}
548:
549: //{{{ NewViewAction class
550: class NewViewAction {
551: public void doAction() {
552: SwingUtilities.invokeLater(new Runnable() {
553: public void run() {
554: if (jEdit.getViewCount() == 0)
555: PerspectiveManager.loadPerspective(true);
556: else
557: jEdit.newView(jEdit.getActiveView());
558: }
559: });
560: }
561: } //}}}
562:
563: //{{{ ShowFileAction class
564: class ShowFileAction {
565: private String path;
566:
567: public ShowFileAction(String path) {
568: this .path = path;
569: }
570:
571: public void doAction() {
572: MacOSActions.showInFinder(path);
573: }
574: } //}}}
575:
576: //}}}
577: }
|