Mercurial > projects > dwt-linux
annotate dwt/program/Program.d @ 255:5a30aa9820f3
removed tango.stdc.stringz imports and allow null for arrays and string arguments.
author | Frank Benoit <benoit@tionex.de> |
---|---|
date | Sun, 15 Jun 2008 22:32:20 +0200 |
parents | ce446666f5a2 |
children | c0d810de7093 |
rev | line source |
---|---|
191 | 1 /******************************************************************************* |
2 * Copyright (c) 2000, 2007 IBM Corporation and others. | |
3 * All rights reserved. This program and the accompanying materials | |
4 * are made available under the terms of the Eclipse Public License v1.0 | |
5 * which accompanies this distribution, and is available at | |
6 * http://www.eclipse.org/legal/epl-v10.html | |
7 * | |
8 * Contributors: | |
9 * IBM Corporation - initial API and implementation | |
10 * Port to the D programming language: | |
11 * Frank Benoit <benoit@tionex.de> | |
12 *******************************************************************************/ | |
13 module dwt.program.Program; | |
14 | |
15 import dwt.DWT; | |
16 import dwt.graphics.ImageData; | |
17 import dwt.internal.Compatibility; | |
18 import dwt.internal.Converter; | |
19 import dwt.internal.Library; | |
20 import dwt.internal.gtk.OS; | |
21 import dwt.widgets.Display; | |
22 import dwt.widgets.Event; | |
23 import dwt.widgets.Listener; | |
24 import dwt.dwthelper.utils; | |
25 | |
26 import tango.sys.SharedLib; | |
27 import tango.core.Exception; | |
28 import tango.core.Array; | |
29 import tango.text.convert.Format; | |
206
3cb84407dc3e
Temporary impl for Program.getExtensions on gnome 2.4
Frank Benoit <benoit@tionex.de>
parents:
191
diff
changeset
|
30 import tango.io.FileConduit; |
3cb84407dc3e
Temporary impl for Program.getExtensions on gnome 2.4
Frank Benoit <benoit@tionex.de>
parents:
191
diff
changeset
|
31 import tango.text.stream.LineIterator; |
191 | 32 |
33 version( build ){ | |
34 pragma(link, "gnomeui-2" ); | |
35 } | |
36 | |
37 private extern(C) { | |
38 alias int GnomeIconLookupResultFlags; | |
39 alias int GnomeIconLookupFlags; | |
40 GnomeIconTheme *gnome_icon_theme_new (); | |
41 char *gnome_icon_lookup ( | |
42 GtkIconTheme *icon_theme, | |
43 void *thumbnail_factory, | |
44 char *file_uri, | |
45 char *custom_icon, | |
46 void *file_info, | |
47 char *mime_type, | |
48 GnomeIconLookupFlags flags, | |
49 GnomeIconLookupResultFlags *result); | |
50 int gnome_vfs_init(); | |
51 char* gnome_icon_theme_lookup_icon(GnomeIconTheme *theme,char *icon_name,int size, GnomeIconData **icon_data, int *base_size) ; | |
52 | |
53 alias void GnomeIconTheme; | |
54 alias void GnomeIconData; | |
55 | |
56 struct GnomeVFSMimeApplication{ | |
57 /*< public > */ | |
58 char *id; | |
59 char *name; | |
60 | |
61 /*< private > */ | |
62 char *command; | |
63 int can_open_multiple_files; | |
64 int expects_uris; | |
65 GList *supported_uri_schemes; | |
66 int requires_terminal; | |
67 | |
68 /* Padded to avoid future breaks in ABI compatibility */ | |
69 void * reserved1; | |
70 | |
71 void * priv; | |
72 } | |
73 } | |
74 | |
75 struct GNOME { | |
76 private static extern(C){ | |
77 enum { | |
78 GNOME_ICON_LOOKUP_FLAGS_NONE = 0, | |
79 GNOME_ICON_LOOKUP_FLAGS_EMBEDDING_TEXT = 1<<0, | |
80 GNOME_ICON_LOOKUP_FLAGS_SHOW_SMALL_IMAGES_AS_THEMSELVES = 1<<1, | |
81 GNOME_ICON_LOOKUP_FLAGS_ALLOW_SVG_AS_THEMSELVES = 1<<2 | |
82 } | |
83 enum { | |
84 GNOME_VFS_MAKE_URI_DIR_NONE = 0, | |
85 GNOME_VFS_MAKE_URI_DIR_HOMEDIR = 1 << 0, | |
86 GNOME_VFS_MAKE_URI_DIR_CURRENT = 1 << 1 | |
87 } | |
88 alias int GnomeVFSMakeURIDirs; | |
89 enum { | |
90 GNOME_VFS_OK, | |
91 GNOME_VFS_ERROR_NOT_FOUND, | |
92 GNOME_VFS_ERROR_GENERIC, | |
93 GNOME_VFS_ERROR_INTERNAL, | |
94 GNOME_VFS_ERROR_BAD_PARAMETERS, | |
95 GNOME_VFS_ERROR_NOT_SUPPORTED, | |
96 GNOME_VFS_ERROR_IO, | |
97 GNOME_VFS_ERROR_CORRUPTED_DATA, | |
98 GNOME_VFS_ERROR_WRONG_FORMAT, | |
99 GNOME_VFS_ERROR_BAD_FILE, | |
100 GNOME_VFS_ERROR_TOO_BIG, | |
101 GNOME_VFS_ERROR_NO_SPACE, | |
102 GNOME_VFS_ERROR_READ_ONLY, | |
103 GNOME_VFS_ERROR_INVALID_URI, | |
104 GNOME_VFS_ERROR_NOT_OPEN, | |
105 GNOME_VFS_ERROR_INVALID_OPEN_MODE, | |
106 GNOME_VFS_ERROR_ACCESS_DENIED, | |
107 GNOME_VFS_ERROR_TOO_MANY_OPEN_FILES, | |
108 GNOME_VFS_ERROR_EOF, | |
109 GNOME_VFS_ERROR_NOT_A_DIRECTORY, | |
110 GNOME_VFS_ERROR_IN_PROGRESS, | |
111 GNOME_VFS_ERROR_INTERRUPTED, | |
112 GNOME_VFS_ERROR_FILE_EXISTS, | |
113 GNOME_VFS_ERROR_LOOP, | |
114 GNOME_VFS_ERROR_NOT_PERMITTED, | |
115 GNOME_VFS_ERROR_IS_DIRECTORY, | |
116 GNOME_VFS_ERROR_NO_MEMORY, | |
117 GNOME_VFS_ERROR_HOST_NOT_FOUND, | |
118 GNOME_VFS_ERROR_INVALID_HOST_NAME, | |
119 GNOME_VFS_ERROR_HOST_HAS_NO_ADDRESS, | |
120 GNOME_VFS_ERROR_LOGIN_FAILED, | |
121 GNOME_VFS_ERROR_CANCELLED, | |
122 GNOME_VFS_ERROR_DIRECTORY_BUSY, | |
123 GNOME_VFS_ERROR_DIRECTORY_NOT_EMPTY, | |
124 GNOME_VFS_ERROR_TOO_MANY_LINKS, | |
125 GNOME_VFS_ERROR_READ_ONLY_FILE_SYSTEM, | |
126 GNOME_VFS_ERROR_NOT_SAME_FILE_SYSTEM, | |
127 GNOME_VFS_ERROR_NAME_TOO_LONG, | |
128 GNOME_VFS_ERROR_SERVICE_NOT_AVAILABLE, | |
129 GNOME_VFS_ERROR_SERVICE_OBSOLETE, | |
130 GNOME_VFS_ERROR_PROTOCOL_ERROR, | |
131 GNOME_VFS_ERROR_NO_MASTER_BROWSER, | |
132 GNOME_VFS_ERROR_NO_DEFAULT, | |
133 GNOME_VFS_ERROR_NO_HANDLER, | |
134 GNOME_VFS_ERROR_PARSE, | |
135 GNOME_VFS_ERROR_LAUNCH, | |
136 GNOME_VFS_ERROR_TIMEOUT, | |
137 GNOME_VFS_ERROR_NAMESERVER, | |
138 GNOME_VFS_ERROR_LOCKED, | |
139 GNOME_VFS_ERROR_DEPRECATED_FUNCTION, | |
140 GNOME_VFS_ERROR_INVALID_FILENAME, | |
141 GNOME_VFS_ERROR_NOT_A_SYMBOLIC_LINK, | |
142 GNOME_VFS_NUM_ERRORS | |
143 } | |
144 alias int GnomeVFSResult; | |
145 | |
146 enum { | |
147 GNOME_VFS_MIME_APPLICATION_ARGUMENT_TYPE_URIS, | |
148 GNOME_VFS_MIME_APPLICATION_ARGUMENT_TYPE_PATHS, | |
149 GNOME_VFS_MIME_APPLICATION_ARGUMENT_TYPE_URIS_FOR_NON_FILES | |
150 } | |
151 | |
152 alias GtkIconTheme GnomeIconTheme; | |
153 alias .gnome_icon_theme_lookup_icon gnome_icon_theme_lookup_icon; | |
154 alias .gnome_vfs_init gnome_vfs_init; | |
155 alias .gnome_icon_lookup gnome_icon_lookup; | |
156 alias .gnome_icon_theme_new gnome_icon_theme_new; | |
157 | |
158 | |
159 GnomeVFSMimeApplication * function ( char *mime_type ) gnome_vfs_mime_get_default_application; | |
160 char* function(char*, int ) gnome_vfs_make_uri_from_input_with_dirs; | |
161 GnomeVFSResult function( GnomeVFSMimeApplication*, GList*) gnome_vfs_mime_application_launch; | |
162 void function(GnomeVFSMimeApplication*) gnome_vfs_mime_application_free; | |
163 GList* function(char*) gnome_vfs_mime_get_extensions_list; | |
164 void function(GList*) gnome_vfs_mime_extensions_list_free; | |
165 void function(GList*) gnome_vfs_mime_registered_mime_type_list_free; | |
166 GnomeVFSResult function(char*) gnome_vfs_url_show; | |
167 char* function(char*) gnome_vfs_make_uri_from_input; | |
168 GList* function() gnome_vfs_get_registered_mime_types; | |
169 char* function(char*) gnome_vfs_mime_type_from_name; | |
170 } | |
171 } | |
172 | |
173 /** | |
174 * Instances of this class represent programs and | |
175 * their associated file extensions in the operating | |
176 * system. | |
177 */ | |
178 public final class Program { | |
238 | 179 String name; |
180 String command; | |
181 String iconPath; | |
191 | 182 Display display; |
183 | |
184 /* Gnome specific | |
185 * true if command expects a URI | |
186 * false if expects a path | |
187 */ | |
188 bool gnomeExpectUri; | |
189 | |
190 static int /*long*/ cdeShell; | |
191 | |
238 | 192 static const String[] CDE_ICON_EXT = [ ".m.pm"[], ".l.pm", ".s.pm", ".t.pm" ]; |
193 static const String[] CDE_MASK_EXT = [ ".m_m.bm"[], ".l_m.bm", ".s_m.bm", ".t_m.bm" ]; | |
194 static const String DESKTOP_DATA = "Program_DESKTOP"; | |
195 static const String ICON_THEME_DATA = "Program_GNOME_ICON_THEME"; | |
240 | 196 static const String PREFIX_HTTP = "http://"; //$NON-NLS-1$ |
197 static const String PREFIX_HTTPS = "https://"; //$NON-NLS-1$ | |
191 | 198 static const int DESKTOP_UNKNOWN = 0; |
199 static const int DESKTOP_GNOME = 1; | |
200 static const int DESKTOP_GNOME_24 = 2; | |
201 static const int DESKTOP_CDE = 3; | |
202 static const int PREFERRED_ICON_SIZE = 16; | |
203 | |
204 /** | |
205 * Prevents uninitialized instances from being created outside the package. | |
206 */ | |
207 this() { | |
208 } | |
209 | |
210 /* Determine the desktop for the given display. */ | |
211 static int getDesktop(Display display) { | |
212 if (display is null) return DESKTOP_UNKNOWN; | |
213 ValueWrapperInt desktopValue = cast(ValueWrapperInt)display.getData(DESKTOP_DATA); | |
214 if (desktopValue !is null) return desktopValue.value; | |
215 int desktop = DESKTOP_UNKNOWN; | |
216 | |
217 /* Get the list of properties on the root window. */ | |
218 void* xDisplay = OS.GDK_DISPLAY(); | |
219 uint rootWindow = OS.XDefaultRootWindow(xDisplay); | |
220 int numProp; | |
221 uint* propList = OS.XListProperties(xDisplay, rootWindow, &numProp); | |
222 uint[] property = new uint[numProp]; | |
223 if (propList !is null) { | |
224 property[ 0 .. numProp ] = propList[ 0 .. numProp ]; | |
225 OS.XFree(propList); | |
226 } | |
227 | |
228 /* | |
229 * Feature in Linux Desktop. There is currently no official way to | |
230 * determine whether the Gnome window manager or gnome-vfs is | |
231 * available. Earlier versions including Red Hat 9 and Suse 9 provide | |
232 * a documented Gnome specific property on the root window | |
233 * WIN_SUPPORTING_WM_CHECK. This property is no longer supported in newer | |
234 * versions such as Fedora Core 2. | |
235 * The workaround is to simply check that the window manager is a | |
236 * compliant one (property _NET_SUPPORTING_WM_CHECK) and to attempt to load | |
237 * our native library that depends on gnome-vfs. | |
238 */ | |
239 if (desktop is DESKTOP_UNKNOWN) { | |
238 | 240 String gnomeName = "_NET_SUPPORTING_WM_CHECK"; |
191 | 241 int /*long*/ gnome = OS.XInternAtom(xDisplay, gnomeName.ptr, true); |
242 if (gnome !is OS.None && gnome_init()) { | |
243 desktop = DESKTOP_GNOME; | |
244 int icon_theme = cast(int)GNOME.gnome_icon_theme_new(); | |
245 display.setData(ICON_THEME_DATA, new ValueWrapperInt(icon_theme)); | |
246 display.addListener(DWT.Dispose, new class(display) Listener { | |
247 Display display; | |
248 this( Display display ){ this.display = display; } | |
249 public void handleEvent(Event event) { | |
250 ValueWrapperInt gnomeIconTheme = cast(ValueWrapperInt)display.getData(ICON_THEME_DATA); | |
251 if (gnomeIconTheme is null) return; | |
252 display.setData(ICON_THEME_DATA, null); | |
253 /* | |
254 * Note. gnome_icon_theme_new uses g_object_new to allocate the | |
255 * data it returns. Use g_object_unref to free the pointer it returns. | |
256 */ | |
257 if (gnomeIconTheme.value !is 0) OS.g_object_unref( cast(void*)gnomeIconTheme.value); | |
258 } | |
259 }); | |
260 /* Check for libgnomevfs-2 version 2.4 */ | |
238 | 261 String buffer = "libgnomevfs-2.so.0"; |
191 | 262 auto libgnomevfs = SharedLib.load(buffer ); |
263 if (libgnomevfs !is null) { | |
264 buffer = "gnome_vfs_url_show"; | |
265 void* gnome_vfs_url_show = libgnomevfs.getSymbol( buffer.ptr ); | |
266 if (gnome_vfs_url_show !is null) { | |
267 desktop = DESKTOP_GNOME_24; | |
268 } | |
269 *cast(void**)&GNOME.gnome_vfs_mime_get_default_application = libgnomevfs.getSymbol( "gnome_vfs_mime_get_default_application" ); | |
270 *cast(void**)&GNOME.gnome_vfs_make_uri_from_input_with_dirs = libgnomevfs.getSymbol( "gnome_vfs_make_uri_from_input_with_dirs" ); | |
271 *cast(void**)&GNOME.gnome_vfs_mime_application_launch = libgnomevfs.getSymbol( "gnome_vfs_mime_application_launch" ); | |
272 *cast(void**)&GNOME.gnome_vfs_mime_application_free = libgnomevfs.getSymbol( "gnome_vfs_mime_application_free" ); | |
273 *cast(void**)&GNOME.gnome_vfs_url_show = libgnomevfs.getSymbol( "gnome_vfs_url_show" ); | |
274 *cast(void**)&GNOME.gnome_vfs_make_uri_from_input = libgnomevfs.getSymbol( "gnome_vfs_make_uri_from_input" ); | |
275 *cast(void**)&GNOME.gnome_vfs_get_registered_mime_types = libgnomevfs.getSymbol( "gnome_vfs_get_registered_mime_types" ); | |
276 *cast(void**)&GNOME.gnome_vfs_mime_get_extensions_list = libgnomevfs.getSymbol( "gnome_vfs_mime_get_extensions_list" ); | |
277 *cast(void**)&GNOME.gnome_vfs_mime_extensions_list_free = libgnomevfs.getSymbol( "gnome_vfs_mime_extensions_list_free" ); | |
278 *cast(void**)&GNOME.gnome_vfs_mime_registered_mime_type_list_free = libgnomevfs.getSymbol( "gnome_vfs_mime_registered_mime_type_list_free" ); | |
279 *cast(void**)&GNOME.gnome_vfs_mime_type_from_name = libgnomevfs.getSymbol( "gnome_vfs_mime_type_from_name" ); | |
280 } | |
281 } | |
282 } | |
283 | |
284 // PORTING CDE not supported | |
285 /+ | |
286 /* | |
287 * On CDE, the atom below may exist without DTWM running. If the atom | |
288 * below is defined, the CDE database exists and the available | |
289 * applications can be queried. | |
290 */ | |
291 if (desktop is DESKTOP_UNKNOWN) { | |
238 | 292 String cdeName = "_DT_SM_PREFERENCES"; |
191 | 293 int /*long*/ cde = OS.XInternAtom(xDisplay, cdeName.ptr, true); |
294 for (int index = 0; desktop is DESKTOP_UNKNOWN && index < property.length; index++) { | |
295 if (property[index] is OS.None) continue; /* do not match atoms that do not exist */ | |
296 if (property[index] is cde && cde_init(display)) desktop = DESKTOP_CDE; | |
297 } | |
298 } | |
299 +/ | |
300 | |
301 display.setData(DESKTOP_DATA, new ValueWrapperInt(desktop)); | |
302 return desktop; | |
303 } | |
304 | |
305 // PORTING CDE not supported | |
306 /+ | |
238 | 307 bool cde_execute(String fileName) { |
191 | 308 /* Use the character encoding for the default locale */ |
309 char* action = toStringz(command); | |
310 char* ptr = cast(char*)OS.g_malloc(fileName.length+1); | |
311 ptr[ 0 .. fileName.length ] = fileName; | |
312 ptr[ fileName.length ] = 0; | |
313 DtActionArg args = new DtActionArg(); | |
314 args.argClass = CDE.DtACTION_FILE; | |
315 args.name = ptr; | |
316 long actionID = CDE.DtActionInvoke(cdeShell, action, args, 1, null, null, null, 1, 0, 0); | |
317 OS.g_free(ptr); | |
318 return actionID !is 0; | |
319 } | |
320 | |
238 | 321 static String cde_getAction(String dataType) { |
322 String action = null; | |
323 String actions = cde_getAttribute(dataType, CDE.DtDTS_DA_ACTION_LIST); | |
191 | 324 if (actions !is null) { |
325 int index = actions.indexOf("Open"); | |
326 if (index !is -1) { | |
327 action = actions.substring(index, index + 4); | |
328 } else { | |
329 index = actions.indexOf(","); | |
330 action = index !is -1 ? actions.substring(0, index) : actions; | |
331 } | |
332 } | |
333 return action; | |
334 } | |
335 | |
238 | 336 static String cde_getAttribute(String dataType, String attrName) { |
191 | 337 /* Use the character encoding for the default locale */ |
338 byte[] dataTypeBuf = Converter.wcsToMbcs(null, dataType, true); | |
339 byte[] attrNameBuf = Converter.wcsToMbcs(null, attrName, true); | |
340 byte[] optNameBuf = null; | |
341 int /*long*/ attrValue = CDE.DtDtsDataTypeToAttributeValue(dataTypeBuf, attrNameBuf, optNameBuf); | |
342 if (attrValue is 0) return null; | |
343 int length = OS.strlen(attrValue); | |
344 byte[] attrValueBuf = new byte[length]; | |
345 OS.memmove(attrValueBuf, attrValue, length); | |
346 CDE.DtDtsFreeAttributeValue(attrValue); | |
347 /* Use the character encoding for the default locale */ | |
238 | 348 return new String(Converter.mbcsToWcs(null, attrValueBuf)); |
191 | 349 } |
350 | |
238 | 351 static String[][ String ] cde_getDataTypeInfo() { |
352 String[][ String ] dataTypeInfo; | |
191 | 353 int index; |
354 int /*long*/ dataTypeList = CDE.DtDtsDataTypeNames(); | |
355 if (dataTypeList !is 0) { | |
356 /* For each data type name in the list */ | |
357 index = 0; | |
358 int /*long*/ [] dataType = new int /*long*/ [1]; | |
359 OS.memmove(dataType, dataTypeList + (index++ * 4), 4); | |
360 while (dataType[0] !is 0) { | |
361 int length = OS.strlen(dataType[0]); | |
362 byte[] dataTypeBuf = new byte[length]; | |
363 OS.memmove(dataTypeBuf, dataType[0], length); | |
364 /* Use the character encoding for the default locale */ | |
238 | 365 String dataTypeName = new String(Converter.mbcsToWcs(null, dataTypeBuf)); |
191 | 366 |
367 /* The data type is valid if it is not an action, and it has an extension and an action. */ | |
238 | 368 String extension = cde_getExtension(dataTypeName); |
191 | 369 if (!CDE.DtDtsDataTypeIsAction(dataTypeBuf) && |
370 extension !is null && cde_getAction(dataTypeName) !is null) { | |
238 | 371 String[] exts; |
191 | 372 exts ~= extension; |
373 dataTypeInfo[ dataTypeName ] = exts; | |
374 } | |
375 OS.memmove(dataType, dataTypeList + (index++ * 4), 4); | |
376 } | |
377 CDE.DtDtsFreeDataTypeNames(dataTypeList); | |
378 } | |
379 | |
380 return dataTypeInfo; | |
381 } | |
382 | |
238 | 383 static String cde_getExtension(String dataType) { |
384 String fileExt = cde_getAttribute(dataType, CDE.DtDTS_DA_NAME_TEMPLATE); | |
191 | 385 if (fileExt is null || fileExt.indexOf("%s.") is -1) return null; |
386 int dot = fileExt.indexOf("."); | |
387 return fileExt.substring(dot); | |
388 } | |
389 | |
390 /** | |
391 * CDE - Get Image Data | |
392 * | |
393 * This method returns the image data of the icon associated with | |
394 * the data type. Since CDE supports multiple sizes of icons, several | |
395 * attempts are made to locate an icon of the desired size and format. | |
396 * CDE supports the sizes: tiny, small, medium and large. The best | |
397 * search order is medium, large, small and then tiny. Althoug CDE supports | |
398 * colour and monochrome bitmaps, only colour icons are tried. (The order is | |
399 * defined by the cdeIconExt and cdeMaskExt arrays above.) | |
400 */ | |
401 ImageData cde_getImageData() { | |
402 // TODO | |
403 return null; | |
404 } | |
405 | |
238 | 406 static String cde_getMimeType(String extension) { |
407 String mimeType = null; | |
408 String[][ String ] mimeInfo = cde_getDataTypeInfo(); | |
191 | 409 if (mimeInfo is null) return null; |
238 | 410 String[] keys = mimeInfo.keys(); |
191 | 411 int keyIdx = 0; |
412 while (mimeType is null && keyIdx < keys.length ) { | |
238 | 413 String type = keys[ keyIdx ]; |
414 String[] mimeExts = mimeInfo[type]; | |
191 | 415 for (int index = 0; index < mimeExts.length; index++){ |
416 if (extension.equals(mimeExts[index])) { | |
417 mimeType = type; | |
418 break; | |
419 } | |
420 } | |
421 keyIdx++; | |
422 } | |
423 return mimeType; | |
424 } | |
425 | |
238 | 426 static Program cde_getProgram(Display display, String mimeType) { |
191 | 427 Program program = new Program(); |
428 program.display = display; | |
429 program.name = mimeType; | |
430 program.command = cde_getAction(mimeType); | |
431 program.iconPath = cde_getAttribute(program.name, CDE.DtDTS_DA_ICON); | |
432 return program; | |
433 } | |
434 | |
435 static bool cde_init(Display display) { | |
436 try { | |
437 Library.loadLibrary("swt-cde"); | |
438 } catch (Throwable e) { | |
439 return false; | |
440 } | |
441 | |
442 /* Use the character encoding for the default locale */ | |
443 CDE.XtToolkitInitialize(); | |
444 int /*long*/ xtContext = CDE.XtCreateApplicationContext (); | |
445 int /*long*/ xDisplay = OS.GDK_DISPLAY(); | |
446 byte[] appName = Converter.wcsToMbcs(null, "CDE", true); | |
447 byte[] appClass = Converter.wcsToMbcs(null, "CDE", true); | |
448 int /*long*/ [] argc = [0]; | |
449 CDE.XtDisplayInitialize(xtContext, xDisplay, appName, appClass, 0, 0, argc, 0); | |
450 int /*long*/ widgetClass = CDE.topLevelShellWidgetClass (); | |
451 cdeShell = CDE.XtAppCreateShell (appName, appClass, widgetClass, xDisplay, null, 0); | |
452 CDE.XtSetMappedWhenManaged (cdeShell, false); | |
453 CDE.XtResizeWidget (cdeShell, 10, 10, 0); | |
454 CDE.XtRealizeWidget (cdeShell); | |
455 bool initOK = CDE.DtAppInitialize(xtContext, xDisplay, cdeShell, appName, appName); | |
456 if (initOK) CDE.DtDbLoad(); | |
457 return initOK; | |
458 } | |
459 +/ | |
460 | |
238 | 461 static String[] parseCommand(String cmd) { |
462 String[] args; | |
191 | 463 int sIndex = 0; |
464 int eIndex; | |
465 while (sIndex < cmd.length) { | |
466 /* Trim initial white space of argument. */ | |
467 while (sIndex < cmd.length && Compatibility.isWhitespace(cmd.charAt(sIndex))) { | |
468 sIndex++; | |
469 } | |
470 if (sIndex < cmd.length) { | |
471 /* If the command is a quoted string */ | |
472 if (cmd.charAt(sIndex) is '"' || cmd.charAt(sIndex) is '\'') { | |
473 /* Find the terminating quote (or end of line). | |
474 * This code currently does not handle escaped characters (e.g., " a\"b"). | |
475 */ | |
476 eIndex = sIndex + 1; | |
477 while (eIndex < cmd.length && cmd.charAt(eIndex) !is cmd.charAt(sIndex)) eIndex++; | |
478 if (eIndex >= cmd.length) { | |
479 /* The terminating quote was not found | |
480 * Add the argument as is with only one initial quote. | |
481 */ | |
482 args ~= cmd.substring(sIndex, eIndex); | |
483 } else { | |
484 /* Add the argument, trimming off the quotes. */ | |
485 args ~= cmd.substring(sIndex + 1, eIndex); | |
486 } | |
487 sIndex = eIndex + 1; | |
488 } | |
489 else { | |
490 /* Use white space for the delimiters. */ | |
491 eIndex = sIndex; | |
492 while (eIndex < cmd.length && !Compatibility.isWhitespace( firstCodePoint( cmd[ eIndex .. $ ]))) eIndex++; | |
493 args ~= cmd.substring(sIndex, eIndex); | |
494 sIndex = eIndex + 1; | |
495 } | |
496 } | |
497 } | |
498 | |
238 | 499 String[] strings = new String[args.length]; |
191 | 500 for (int index =0; index < args.length; index++) { |
501 strings[index] = args[index]; | |
502 } | |
503 return strings; | |
504 } | |
505 | |
506 /** | |
507 * GNOME 2.4 - Execute the program for the given file. | |
508 */ | |
238 | 509 bool gnome_24_execute(String fileName) { |
191 | 510 char* mimeTypeBuffer = toStringz(name); |
511 auto ptr = GNOME.gnome_vfs_mime_get_default_application(mimeTypeBuffer); | |
512 char* fileNameBuffer = toStringz(fileName); | |
513 char* uri = GNOME.gnome_vfs_make_uri_from_input_with_dirs(fileNameBuffer, GNOME.GNOME_VFS_MAKE_URI_DIR_CURRENT); | |
514 GList* list = OS.g_list_append( null, uri); | |
515 int result = GNOME.gnome_vfs_mime_application_launch(ptr, list); | |
516 GNOME.gnome_vfs_mime_application_free(ptr); | |
517 OS.g_free(uri); | |
518 OS.g_list_free(list); | |
519 return result is GNOME.GNOME_VFS_OK; | |
520 } | |
521 | |
522 /** | |
523 * GNOME 2.4 - Launch the default program for the given file. | |
524 */ | |
238 | 525 static bool gnome_24_launch(String fileName) { |
191 | 526 char* fileNameBuffer = toStringz(fileName); |
527 char* uri = GNOME.gnome_vfs_make_uri_from_input_with_dirs(fileNameBuffer, GNOME.GNOME_VFS_MAKE_URI_DIR_CURRENT); | |
528 int result = GNOME.gnome_vfs_url_show(uri); | |
529 OS.g_free(uri); | |
530 return (result is GNOME.GNOME_VFS_OK); | |
531 } | |
532 | |
533 /** | |
534 * GNOME 2.2 - Execute the program for the given file. | |
535 */ | |
238 | 536 bool gnome_execute(String fileName) { |
191 | 537 if (gnomeExpectUri) { |
538 /* Convert the given path into a URL */ | |
539 char* fileNameBuffer = toStringz(fileName); | |
540 char* uri = GNOME.gnome_vfs_make_uri_from_input(fileNameBuffer); | |
541 if (uri !is null) { | |
542 fileName = fromStringz( uri ).dup; | |
543 OS.g_free(uri); | |
544 } | |
545 } | |
546 | |
547 /* Parse the command into its individual arguments. */ | |
238 | 548 String[] args = parseCommand(command); |
191 | 549 int fileArg = -1; |
550 int index; | |
551 for (index = 0; index < args.length; index++) { | |
552 int j = args[index].indexOf("%f"); | |
553 if (j !is -1) { | |
238 | 554 String value = args[index]; |
191 | 555 fileArg = index; |
556 args[index] = value.substring(0, j) ~ fileName ~ value.substring(j + 2); | |
557 } | |
558 } | |
559 | |
560 /* If a file name was given but the command did not have "%f" */ | |
561 if ((fileName.length > 0) && (fileArg < 0)) { | |
238 | 562 String[] newArgs = new String[args.length + 1]; |
191 | 563 for (index = 0; index < args.length; index++) newArgs[index] = args[index]; |
564 newArgs[args.length] = fileName; | |
565 args = newArgs; | |
566 } | |
567 | |
568 /* Execute the command. */ | |
569 try { | |
570 Compatibility.exec(args); | |
571 } catch (IOException e) { | |
572 return false; | |
573 } | |
574 return true; | |
575 } | |
576 | |
577 /** | |
578 * GNOME - Get Image Data | |
579 * | |
580 */ | |
581 ImageData gnome_getImageData() { | |
582 if (iconPath is null) return null; | |
583 try { | |
584 return new ImageData(iconPath); | |
585 } catch (Exception e) {} | |
586 return null; | |
587 } | |
588 | |
206
3cb84407dc3e
Temporary impl for Program.getExtensions on gnome 2.4
Frank Benoit <benoit@tionex.de>
parents:
191
diff
changeset
|
589 /++ |
3cb84407dc3e
Temporary impl for Program.getExtensions on gnome 2.4
Frank Benoit <benoit@tionex.de>
parents:
191
diff
changeset
|
590 + DWT Extension |
3cb84407dc3e
Temporary impl for Program.getExtensions on gnome 2.4
Frank Benoit <benoit@tionex.de>
parents:
191
diff
changeset
|
591 + This is a temporary workaround until SWT will get the real implementation. |
3cb84407dc3e
Temporary impl for Program.getExtensions on gnome 2.4
Frank Benoit <benoit@tionex.de>
parents:
191
diff
changeset
|
592 +/ |
238 | 593 static String[][ String ] gnome24_getMimeInfo() { |
206
3cb84407dc3e
Temporary impl for Program.getExtensions on gnome 2.4
Frank Benoit <benoit@tionex.de>
parents:
191
diff
changeset
|
594 scope file = new FileConduit ("/usr/share/mime/globs"); |
3cb84407dc3e
Temporary impl for Program.getExtensions on gnome 2.4
Frank Benoit <benoit@tionex.de>
parents:
191
diff
changeset
|
595 scope it = new LineIterator!(char)(file); |
3cb84407dc3e
Temporary impl for Program.getExtensions on gnome 2.4
Frank Benoit <benoit@tionex.de>
parents:
191
diff
changeset
|
596 // process file one line at a time |
238 | 597 String[][ String ] mimeInfo; |
206
3cb84407dc3e
Temporary impl for Program.getExtensions on gnome 2.4
Frank Benoit <benoit@tionex.de>
parents:
191
diff
changeset
|
598 foreach (line; it ){ |
3cb84407dc3e
Temporary impl for Program.getExtensions on gnome 2.4
Frank Benoit <benoit@tionex.de>
parents:
191
diff
changeset
|
599 int colon = line.indexOf(':'); |
3cb84407dc3e
Temporary impl for Program.getExtensions on gnome 2.4
Frank Benoit <benoit@tionex.de>
parents:
191
diff
changeset
|
600 if( colon is line.length ){ |
3cb84407dc3e
Temporary impl for Program.getExtensions on gnome 2.4
Frank Benoit <benoit@tionex.de>
parents:
191
diff
changeset
|
601 continue; |
3cb84407dc3e
Temporary impl for Program.getExtensions on gnome 2.4
Frank Benoit <benoit@tionex.de>
parents:
191
diff
changeset
|
602 } |
3cb84407dc3e
Temporary impl for Program.getExtensions on gnome 2.4
Frank Benoit <benoit@tionex.de>
parents:
191
diff
changeset
|
603 if( line.length < colon+3 || line[colon+1 .. colon+3 ] != "*." ){ |
3cb84407dc3e
Temporary impl for Program.getExtensions on gnome 2.4
Frank Benoit <benoit@tionex.de>
parents:
191
diff
changeset
|
604 continue; |
3cb84407dc3e
Temporary impl for Program.getExtensions on gnome 2.4
Frank Benoit <benoit@tionex.de>
parents:
191
diff
changeset
|
605 } |
238 | 606 String mimeType = line[0..colon].dup; |
607 String ext = line[colon+3 .. $].dup; | |
206
3cb84407dc3e
Temporary impl for Program.getExtensions on gnome 2.4
Frank Benoit <benoit@tionex.de>
parents:
191
diff
changeset
|
608 if( auto exts = mimeType in mimeInfo ){ |
3cb84407dc3e
Temporary impl for Program.getExtensions on gnome 2.4
Frank Benoit <benoit@tionex.de>
parents:
191
diff
changeset
|
609 mimeInfo[ mimeType ] = *exts ~ ext; |
3cb84407dc3e
Temporary impl for Program.getExtensions on gnome 2.4
Frank Benoit <benoit@tionex.de>
parents:
191
diff
changeset
|
610 } |
3cb84407dc3e
Temporary impl for Program.getExtensions on gnome 2.4
Frank Benoit <benoit@tionex.de>
parents:
191
diff
changeset
|
611 else{ |
3cb84407dc3e
Temporary impl for Program.getExtensions on gnome 2.4
Frank Benoit <benoit@tionex.de>
parents:
191
diff
changeset
|
612 mimeInfo[ mimeType ] = [ ext ]; |
3cb84407dc3e
Temporary impl for Program.getExtensions on gnome 2.4
Frank Benoit <benoit@tionex.de>
parents:
191
diff
changeset
|
613 } |
3cb84407dc3e
Temporary impl for Program.getExtensions on gnome 2.4
Frank Benoit <benoit@tionex.de>
parents:
191
diff
changeset
|
614 } |
3cb84407dc3e
Temporary impl for Program.getExtensions on gnome 2.4
Frank Benoit <benoit@tionex.de>
parents:
191
diff
changeset
|
615 return mimeInfo; |
3cb84407dc3e
Temporary impl for Program.getExtensions on gnome 2.4
Frank Benoit <benoit@tionex.de>
parents:
191
diff
changeset
|
616 } |
191 | 617 /** |
618 * GNOME - Get mime types | |
619 * | |
620 * Obtain the registered mime type information and | |
621 * return it in a map. The key of each entry | |
622 * in the map is the mime type name. The value is | |
623 * a vector of the associated file extensions. | |
624 */ | |
238 | 625 static String[][ String ] gnome_getMimeInfo() { |
626 String[][ String ] mimeInfo; | |
191 | 627 GList* mimeList = GNOME.gnome_vfs_get_registered_mime_types(); |
628 GList* mimeElement = mimeList; | |
629 while (mimeElement !is null) { | |
630 char* mimePtr = cast(char*) OS.g_list_data(mimeElement); | |
238 | 631 String mimeTypeBuffer = fromStringz(mimePtr).dup; |
632 String mimeType = mimeTypeBuffer;//new String(Converter.mbcsToWcs(null, mimeTypeBuffer)); | |
191 | 633 GList* extensionList = GNOME.gnome_vfs_mime_get_extensions_list(mimePtr); |
634 if (extensionList !is null) { | |
238 | 635 String[] extensions; |
191 | 636 GList* extensionElement = extensionList; |
637 while (extensionElement !is null) { | |
638 char* extensionPtr = cast(char*) OS.g_list_data(extensionElement); | |
238 | 639 String extensionBuffer = fromStringz(extensionPtr).dup; |
640 String extension = extensionBuffer; | |
191 | 641 extension = '.' ~ extension; |
642 extensions ~= extension; | |
643 extensionElement = OS.g_list_next(extensionElement); | |
644 } | |
645 GNOME.gnome_vfs_mime_extensions_list_free(extensionList); | |
646 if (extensions.length > 0) mimeInfo[ mimeType ] = extensions; | |
647 } | |
648 mimeElement = OS.g_list_next(mimeElement); | |
649 } | |
650 if (mimeList !is null) GNOME.gnome_vfs_mime_registered_mime_type_list_free(mimeList); | |
651 return mimeInfo; | |
652 } | |
653 | |
238 | 654 static String gnome_getMimeType(String extension) { |
655 String mimeType = null; | |
656 String fileName = "swt" ~ extension; | |
191 | 657 char* extensionBuffer = toStringz(fileName); |
658 char* typeName = GNOME.gnome_vfs_mime_type_from_name(extensionBuffer); | |
659 if (typeName !is null) { | |
660 mimeType = fromStringz(typeName).dup; | |
661 } | |
662 return mimeType; | |
663 } | |
664 | |
238 | 665 static Program gnome_getProgram(Display display, String mimeType) { |
191 | 666 Program program = null; |
667 char* mimeTypeBuffer = toStringz(mimeType); | |
668 GnomeVFSMimeApplication* ptr = GNOME.gnome_vfs_mime_get_default_application(mimeTypeBuffer); | |
669 if (ptr !is null) { | |
670 program = new Program(); | |
671 program.display = display; | |
672 program.name = mimeType; | |
673 GnomeVFSMimeApplication* application = ptr; | |
238 | 674 String buffer = fromStringz(application.command).dup; |
191 | 675 program.command = buffer; |
676 program.gnomeExpectUri = application.expects_uris is GNOME.GNOME_VFS_MIME_APPLICATION_ARGUMENT_TYPE_URIS; | |
677 | |
678 buffer = fromStringz( application.id) ~ \0; | |
679 ValueWrapperInt gnomeIconTheme = cast(ValueWrapperInt)display.getData(ICON_THEME_DATA); | |
680 char* icon_name = GNOME.gnome_icon_lookup( cast(GtkIconTheme*) gnomeIconTheme.value, null, null, buffer.ptr, null, mimeTypeBuffer, | |
681 GNOME.GNOME_ICON_LOOKUP_FLAGS_NONE, null); | |
682 char* path = null; | |
683 if (icon_name !is null) path = GNOME.gnome_icon_theme_lookup_icon(cast(GtkIconTheme*)gnomeIconTheme.value, icon_name, PREFERRED_ICON_SIZE, null, null); | |
684 if (path !is null) { | |
685 program.iconPath = fromStringz( path).dup; | |
686 OS.g_free(path); | |
687 } | |
688 if (icon_name !is null) OS.g_free(icon_name); | |
689 GNOME.gnome_vfs_mime_application_free(ptr); | |
690 } | |
691 return program; | |
692 } | |
693 | |
694 static bool gnome_init() { | |
695 return cast(bool) GNOME.gnome_vfs_init(); | |
696 } | |
697 | |
698 /** | |
699 * Finds the program that is associated with an extension. | |
700 * The extension may or may not begin with a '.'. Note that | |
701 * a <code>Display</code> must already exist to guarantee that | |
702 * this method returns an appropriate result. | |
703 * | |
704 * @param extension the program extension | |
705 * @return the program or <code>null</code> | |
706 * | |
707 */ | |
238 | 708 public static Program findProgram(String extension) { |
191 | 709 return findProgram(Display.getCurrent(), extension); |
710 } | |
711 | |
712 /* | |
713 * API: When support for multiple displays is added, this method will | |
714 * become public and the original method above can be deprecated. | |
715 */ | |
238 | 716 static Program findProgram(Display display, String extension) { |
255
5a30aa9820f3
removed tango.stdc.stringz imports and allow null for arrays and string arguments.
Frank Benoit <benoit@tionex.de>
parents:
240
diff
changeset
|
717 // DWT extension: allow null for zero length string |
5a30aa9820f3
removed tango.stdc.stringz imports and allow null for arrays and string arguments.
Frank Benoit <benoit@tionex.de>
parents:
240
diff
changeset
|
718 //if (extension is null) DWT.error(DWT.ERROR_NULL_ARGUMENT); |
191 | 719 if (extension.length is 0) return null; |
720 if (extension.charAt(0) !is '.') extension = "." ~ extension; | |
721 int desktop = getDesktop(display); | |
238 | 722 String mimeType = null; |
191 | 723 switch (desktop) { |
724 case DESKTOP_GNOME_24: | |
725 case DESKTOP_GNOME: mimeType = gnome_getMimeType(extension); break; | |
726 //case DESKTOP_CDE: mimeType = cde_getMimeType(extension); break; | |
727 default: | |
728 } | |
729 if (mimeType is null) return null; | |
730 Program program = null; | |
731 switch (desktop) { | |
732 case DESKTOP_GNOME_24: | |
733 case DESKTOP_GNOME: program = gnome_getProgram(display, mimeType); break; | |
734 //case DESKTOP_CDE: program = cde_getProgram(display, mimeType); break; | |
735 default: | |
736 } | |
737 return program; | |
738 } | |
739 | |
740 /** | |
741 * Answer all program extensions in the operating system. Note | |
742 * that a <code>Display</code> must already exist to guarantee | |
743 * that this method returns an appropriate result. | |
744 * | |
745 * @return an array of extensions | |
746 */ | |
238 | 747 public static String[] getExtensions() { |
191 | 748 return getExtensions(Display.getCurrent()); |
749 } | |
750 | |
751 /* | |
752 * API: When support for multiple displays is added, this method will | |
753 * become public and the original method above can be deprecated. | |
754 */ | |
238 | 755 static String[] getExtensions(Display display) { |
191 | 756 int desktop = getDesktop(display); |
238 | 757 String[][ String ] mimeInfo = null; |
191 | 758 switch (desktop) { |
206
3cb84407dc3e
Temporary impl for Program.getExtensions on gnome 2.4
Frank Benoit <benoit@tionex.de>
parents:
191
diff
changeset
|
759 case DESKTOP_GNOME_24: mimeInfo = gnome24_getMimeInfo(); break; |
191 | 760 case DESKTOP_GNOME: mimeInfo = gnome_getMimeInfo(); break; |
761 //case DESKTOP_CDE: mimeInfo = cde_getDataTypeInfo(); break; | |
762 default: | |
763 } | |
206
3cb84407dc3e
Temporary impl for Program.getExtensions on gnome 2.4
Frank Benoit <benoit@tionex.de>
parents:
191
diff
changeset
|
764 if (mimeInfo is null) return null; |
191 | 765 |
766 /* Create a unique set of the file extensions. */ | |
238 | 767 String[] extensions; |
768 String[] keys = mimeInfo.keys; | |
191 | 769 int keyIdx = 0; |
770 while ( keyIdx < keys.length ) { | |
238 | 771 String mimeType = keys[ keyIdx ]; |
772 String[] mimeExts = mimeInfo[mimeType]; | |
191 | 773 for (int index = 0; index < mimeExts.length; index++){ |
774 if (!extensions.contains(mimeExts[index])) { | |
775 extensions ~= mimeExts[index]; | |
776 } | |
777 } | |
778 keyIdx++; | |
779 } | |
780 | |
781 /* Return the list of extensions. */ | |
238 | 782 String[] extStrings = new String[]( extensions.length ); |
191 | 783 for (int index = 0; index < extensions.length; index++) { |
784 extStrings[index] = extensions[index]; | |
785 } | |
786 return extStrings; | |
787 } | |
788 | |
789 /** | |
790 * Answers all available programs in the operating system. Note | |
791 * that a <code>Display</code> must already exist to guarantee | |
792 * that this method returns an appropriate result. | |
793 * | |
794 * @return an array of programs | |
795 */ | |
796 public static Program[] getPrograms() { | |
797 return getPrograms(Display.getCurrent()); | |
798 } | |
799 | |
800 /* | |
801 * API: When support for multiple displays is added, this method will | |
802 * become public and the original method above can be deprecated. | |
803 */ | |
804 static Program[] getPrograms(Display display) { | |
805 int desktop = getDesktop(display); | |
238 | 806 String[][ String ] mimeInfo = null; |
191 | 807 switch (desktop) { |
808 case DESKTOP_GNOME_24: break; | |
809 case DESKTOP_GNOME: mimeInfo = gnome_getMimeInfo(); break; | |
810 //case DESKTOP_CDE: mimeInfo = cde_getDataTypeInfo(); break; | |
811 default: | |
812 } | |
813 if (mimeInfo is null) return new Program[0]; | |
814 Program[] programs; | |
238 | 815 String[] keys = mimeInfo.keys; |
191 | 816 int keyIdx = 0; |
817 while ( keyIdx < keys.length ) { | |
238 | 818 String mimeType = keys[ keyIdx ]; |
191 | 819 Program program = null; |
820 switch (desktop) { | |
821 case DESKTOP_GNOME: program = gnome_getProgram(display, mimeType); break; | |
822 //case DESKTOP_CDE: program = cde_getProgram(display, mimeType); break; | |
823 default: | |
824 } | |
825 if (program !is null) programs ~= program; | |
826 keyIdx++; | |
827 } | |
828 Program[] programList = new Program[programs.length]; | |
829 for (int index = 0; index < programList.length; index++) { | |
830 programList[index] = programs[index]; | |
831 } | |
832 return programList; | |
833 } | |
834 | |
835 /** | |
836 * Launches the executable associated with the file in | |
837 * the operating system. If the file is an executable, | |
838 * then the executable is launched. Note that a <code>Display</code> | |
839 * must already exist to guarantee that this method returns | |
840 * an appropriate result. | |
841 * | |
842 * @param fileName the file or program name | |
843 * @return <code>true</code> if the file is launched, otherwise <code>false</code> | |
844 * | |
845 * @exception IllegalArgumentException <ul> | |
846 * <li>ERROR_NULL_ARGUMENT when fileName is null</li> | |
847 * </ul> | |
848 */ | |
238 | 849 public static bool launch(String fileName) { |
191 | 850 return launch(Display.getCurrent(), fileName); |
851 } | |
852 | |
853 /* | |
854 * API: When support for multiple displays is added, this method will | |
855 * become public and the original method above can be deprecated. | |
856 */ | |
240 | 857 static bool launch (Display display, String fileName) { |
191 | 858 if (fileName is null) DWT.error (DWT.ERROR_NULL_ARGUMENT); |
240 | 859 switch (getDesktop (display)) { |
191 | 860 case DESKTOP_GNOME_24: |
861 if (gnome_24_launch (fileName)) return true; | |
862 default: | |
240 | 863 int index = fileName.lastIndexOf ('.'); |
191 | 864 if (index !is -1) { |
238 | 865 String extension = fileName.substring (index); |
191 | 866 Program program = Program.findProgram (display, extension); |
867 if (program !is null && program.execute (fileName)) return true; | |
868 } | |
240 | 869 String lowercaseName = fileName.toLowerCase (); |
870 if (lowercaseName.startsWith (PREFIX_HTTP) || lowercaseName.startsWith (PREFIX_HTTPS)) { | |
871 Program program = Program.findProgram (display, ".html"); //$NON-NLS-1$ | |
872 if (program is null) { | |
873 program = Program.findProgram (display, ".htm"); //$NON-NLS-1$ | |
874 } | |
875 if (program !is null && program.execute (fileName)) return true; | |
876 } | |
191 | 877 break; |
878 } | |
879 try { | |
880 Compatibility.exec (fileName); | |
881 return true; | |
882 } catch (IOException e) { | |
883 return false; | |
884 } | |
885 } | |
886 | |
887 /** | |
888 * Compares the argument to the receiver, and returns true | |
889 * if they represent the <em>same</em> object using a class | |
890 * specific comparison. | |
891 * | |
892 * @param other the object to compare with this object | |
893 * @return <code>true</code> if the object is the same as this object and <code>false</code> otherwise | |
894 * | |
895 * @see #hashCode() | |
896 */ | |
897 public override int opEquals(Object other) { | |
898 if (this is other) return true; | |
899 if (!(cast(Program)other)) return false; | |
900 Program program = cast(Program)other; | |
901 return display is program.display && name.equals(program.name) && command.equals(program.command); | |
902 } | |
903 | |
904 /** | |
905 * Executes the program with the file as the single argument | |
906 * in the operating system. It is the responsibility of the | |
907 * programmer to ensure that the file contains valid data for | |
908 * this program. | |
909 * | |
910 * @param fileName the file or program name | |
911 * @return <code>true</code> if the file is launched, otherwise <code>false</code> | |
912 * | |
913 * @exception IllegalArgumentException <ul> | |
914 * <li>ERROR_NULL_ARGUMENT when fileName is null</li> | |
915 * </ul> | |
916 */ | |
238 | 917 public bool execute(String fileName) { |
191 | 918 if (fileName is null) DWT.error(DWT.ERROR_NULL_ARGUMENT); |
919 int desktop = getDesktop(display); | |
920 switch (desktop) { | |
921 case DESKTOP_GNOME_24: return gnome_24_execute(fileName); | |
922 case DESKTOP_GNOME: return gnome_execute(fileName); | |
923 //case DESKTOP_CDE: return cde_execute(fileName); | |
924 default: | |
925 } | |
926 return false; | |
927 } | |
928 | |
929 /** | |
930 * Returns the receiver's image data. This is the icon | |
931 * that is associated with the receiver in the operating | |
932 * system. | |
933 * | |
934 * @return the image data for the program, may be null | |
935 */ | |
936 public ImageData getImageData() { | |
937 switch (getDesktop(display)) { | |
938 case DESKTOP_GNOME_24: | |
939 case DESKTOP_GNOME: return gnome_getImageData(); | |
940 //case DESKTOP_CDE: return cde_getImageData(); | |
941 default: | |
942 } | |
943 return null; | |
944 } | |
945 | |
946 /** | |
947 * Returns the receiver's name. This is as short and | |
948 * descriptive a name as possible for the program. If | |
949 * the program has no descriptive name, this string may | |
950 * be the executable name, path or empty. | |
951 * | |
952 * @return the name of the program | |
953 */ | |
238 | 954 public String getName() { |
191 | 955 return name; |
956 } | |
957 | |
958 /** | |
959 * Returns an integer hash code for the receiver. Any two | |
960 * objects that return <code>true</code> when passed to | |
961 * <code>equals</code> must return the same value for this | |
962 * method. | |
963 * | |
964 * @return the receiver's hash | |
965 * | |
966 * @see #equals(Object) | |
967 */ | |
968 public override hash_t toHash() { | |
969 return .toHash(name) ^ .toHash(command) ^ display.toHash(); | |
970 } | |
971 | |
972 /** | |
973 * Returns a string containing a concise, human-readable | |
974 * description of the receiver. | |
975 * | |
976 * @return a string representation of the program | |
977 */ | |
238 | 978 public String toString() { |
191 | 979 return Format( "Program {{{}}", name ); |
980 } | |
981 } |