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