Mercurial > projects > dwt-samples
annotate examples/addressbook/AddressBook.d @ 82:9c2803aea121
Fix Addressbook example and HG ignores
author | Frank Benoit <benoit@tionex.de> |
---|---|
date | Mon, 12 May 2008 16:29:26 +0200 |
parents | 8a1930f94cbb |
children | cfd5fa2ce475 |
rev | line source |
---|---|
78 | 1 /******************************************************************************* |
2 * Copyright (c) 2000, 2006 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 examples.addressbook.AddressBook; | |
14 | |
15 import dwt.DWT; | |
16 import dwt.events.MenuAdapter; | |
17 import dwt.events.MenuEvent; | |
18 import dwt.events.SelectionAdapter; | |
19 import dwt.events.SelectionEvent; | |
20 import dwt.events.ShellAdapter; | |
21 import dwt.events.ShellEvent; | |
22 import dwt.graphics.Cursor; | |
23 import dwt.layout.FillLayout; | |
24 import dwt.widgets.Display; | |
25 import dwt.widgets.FileDialog; | |
26 import dwt.widgets.Menu; | |
27 import dwt.widgets.MenuItem; | |
28 import dwt.widgets.MessageBox; | |
29 import dwt.widgets.Shell; | |
30 import dwt.widgets.Table; | |
31 import dwt.widgets.TableColumn; | |
32 import dwt.widgets.TableItem; | |
33 | |
34 import dwt.dwthelper.ResourceBundle; | |
35 | |
36 import tango.core.Exception; | |
37 import tango.io.FilePath; | |
38 import tango.io.File; | |
39 import tango.io.FileConduit; | |
40 import tango.io.stream.FileStream; | |
41 import TextUtil = tango.text.Util; | |
42 import Unicode = tango.text.Unicode; | |
43 | |
44 import examples.addressbook.SearchDialog; | |
45 import examples.addressbook.DataEntryDialog; | |
46 import examples.addressbook.FindListener; | |
47 | |
82
9c2803aea121
Fix Addressbook example and HG ignores
Frank Benoit <benoit@tionex.de>
parents:
80
diff
changeset
|
48 version(JIVE){ |
9c2803aea121
Fix Addressbook example and HG ignores
Frank Benoit <benoit@tionex.de>
parents:
80
diff
changeset
|
49 import jive.stacktrace; |
9c2803aea121
Fix Addressbook example and HG ignores
Frank Benoit <benoit@tionex.de>
parents:
80
diff
changeset
|
50 } |
78 | 51 void main() { |
52 Display display = new Display(); | |
53 auto application = new AddressBook(); | |
54 Shell shell = application.open(display); | |
55 while(!shell.isDisposed()){ | |
56 if(!display.readAndDispatch()){ | |
57 display.sleep(); | |
58 } | |
59 } | |
60 display.dispose(); | |
61 } | |
62 | |
63 /** | |
64 * AddressBookExample is an example that uses <code>org.eclipse.swt</code> | |
65 * libraries to implement a simple address book. This application has | |
66 * save, load, sorting, and searching functions common | |
67 * to basic address books. | |
68 */ | |
69 public class AddressBook { | |
70 | |
71 private static ResourceBundle resAddressBook; | |
80 | 72 private static const char[] resAddressBookData = cast(char[]) import( "examples.addressbook.addressbook.properties" ); |
78 | 73 private Shell shell; |
74 | |
75 private Table table; | |
76 private SearchDialog searchDialog; | |
77 | |
78 private FilePath file; | |
79 private bool isModified; | |
80 | |
81 private char[][] copyBuffer; | |
82 | |
83 private int lastSortColumn= -1; | |
84 | |
85 private static const char[] DELIMITER = "\t"; | |
86 private static char[][] columnNames; | |
87 | |
88 public this(){ | |
89 if( resAddressBook is null ){ | |
90 resAddressBook = ResourceBundle.getBundleFromData(resAddressBookData); | |
91 columnNames = [ | |
92 resAddressBook.getString("Last_name"), | |
93 resAddressBook.getString("First_name"), | |
94 resAddressBook.getString("Business_phone"), | |
95 resAddressBook.getString("Home_phone"), | |
96 resAddressBook.getString("Email"), | |
97 resAddressBook.getString("Fax") ]; | |
98 } | |
99 } | |
100 | |
101 | |
102 public Shell open(Display display) { | |
103 shell = new Shell(display); | |
104 shell.setLayout(new FillLayout()); | |
105 | |
106 shell.addShellListener( new class() ShellAdapter { | |
107 public void shellClosed(ShellEvent e) { | |
108 e.doit = closeAddressBook(); | |
109 } | |
110 }); | |
111 | |
112 createMenuBar(); | |
113 | |
82
9c2803aea121
Fix Addressbook example and HG ignores
Frank Benoit <benoit@tionex.de>
parents:
80
diff
changeset
|
114 searchDialog = new SearchDialog(shell, resAddressBook ); |
78 | 115 searchDialog.setSearchAreaNames(columnNames); |
116 searchDialog.setSearchAreaLabel(resAddressBook.getString("Column")); | |
117 searchDialog.addFindListener(new class() FindListener { | |
118 public bool find() { | |
119 return findEntry(); | |
120 } | |
121 }); | |
122 | |
123 table = new Table(shell, DWT.SINGLE | DWT.BORDER | DWT.FULL_SELECTION); | |
124 table.setHeaderVisible(true); | |
125 table.setMenu(createPopUpMenu()); | |
126 table.addSelectionListener(new class() SelectionAdapter { | |
127 public void widgetDefaultSelected(SelectionEvent e) { | |
128 TableItem[] items = table.getSelection(); | |
129 if (items.length > 0) editEntry(items[0]); | |
130 } | |
131 }); | |
132 for(int i = 0; i < columnNames.length; i++) { | |
133 TableColumn column = new TableColumn(table, DWT.NONE); | |
134 column.setText(columnNames[i]); | |
135 column.setWidth(150); | |
136 int columnIndex = i; | |
137 column.addSelectionListener(new class(columnIndex) SelectionAdapter { | |
138 int c; | |
139 this( int c ){ this.c = c; } | |
140 public void widgetSelected(SelectionEvent e) { | |
141 sort(c); | |
142 } | |
143 }); | |
144 } | |
145 | |
146 newAddressBook(); | |
147 | |
148 shell.setSize(table.computeSize(DWT.DEFAULT, DWT.DEFAULT).x, 300); | |
149 shell.open(); | |
150 return shell; | |
151 } | |
152 | |
153 private bool closeAddressBook() { | |
154 if(isModified) { | |
155 //ask user if they want to save current address book | |
156 MessageBox box = new MessageBox(shell, DWT.ICON_WARNING | DWT.YES | DWT.NO | DWT.CANCEL); | |
157 box.setText(shell.getText()); | |
158 box.setMessage(resAddressBook.getString("Close_save")); | |
159 | |
160 int choice = box.open(); | |
161 if(choice is DWT.CANCEL) { | |
162 return false; | |
163 } else if(choice is DWT.YES) { | |
164 if (!save()) return false; | |
165 } | |
166 } | |
167 | |
168 TableItem[] items = table.getItems(); | |
169 for (int i = 0; i < items.length; i ++) { | |
170 items[i].dispose(); | |
171 } | |
172 | |
173 return true; | |
174 } | |
175 /** | |
176 * Creates the menu at the top of the shell where most | |
177 * of the programs functionality is accessed. | |
178 * | |
179 * @return The <code>Menu</code> widget that was created | |
180 */ | |
181 private Menu createMenuBar() { | |
182 Menu menuBar = new Menu(shell, DWT.BAR); | |
183 shell.setMenuBar(menuBar); | |
184 | |
185 //create each header and subMenu for the menuBar | |
186 createFileMenu(menuBar); | |
187 createEditMenu(menuBar); | |
188 createSearchMenu(menuBar); | |
189 createHelpMenu(menuBar); | |
190 | |
191 return menuBar; | |
192 } | |
193 | |
194 /** | |
195 * Converts an encoded <code>char[]</code> to a char[] array representing a table entry. | |
196 */ | |
197 private char[][] decodeLine(char[] line) { | |
198 char[][] toks = TextUtil.split( line, DELIMITER ); | |
199 while( toks.length < table.getColumnCount() ){ | |
200 toks ~= ""; | |
201 } | |
202 return toks[ 0 .. table.getColumnCount() ]; | |
203 } | |
204 private void displayError(char[] msg) { | |
205 MessageBox box = new MessageBox(shell, DWT.ICON_ERROR); | |
206 box.setMessage(msg); | |
207 box.open(); | |
208 } | |
209 private void editEntry(TableItem item) { | |
82
9c2803aea121
Fix Addressbook example and HG ignores
Frank Benoit <benoit@tionex.de>
parents:
80
diff
changeset
|
210 DataEntryDialog dialog = new DataEntryDialog(shell, resAddressBook ); |
78 | 211 dialog.setLabels(columnNames); |
212 char[][] values = new char[][table.getColumnCount()]; | |
213 for (int i = 0; i < values.length; i++) { | |
214 values[i] = item.getText(i); | |
215 } | |
216 dialog.setValues(values); | |
217 values = dialog.open(); | |
218 if (values !is null) { | |
219 item.setText(values); | |
220 isModified = true; | |
221 } | |
222 } | |
223 private char[] encodeLine(char[][] tableItems) { | |
224 char[] line = ""; | |
225 for (int i = 0; i < tableItems.length - 1; i++) { | |
226 line ~= tableItems[i] ~ DELIMITER; | |
227 } | |
228 line ~= tableItems[tableItems.length - 1] ~ "\n"; | |
229 | |
230 return line; | |
231 } | |
232 private bool findEntry() { | |
233 Cursor waitCursor = new Cursor(shell.getDisplay(), DWT.CURSOR_WAIT); | |
234 shell.setCursor(waitCursor); | |
235 | |
236 bool matchCase = searchDialog.getMatchCase(); | |
237 bool matchWord = searchDialog.getMatchWord(); | |
238 char[] searchString = searchDialog.getSearchString(); | |
239 int column = searchDialog.getSelectedSearchArea(); | |
240 | |
241 searchString = matchCase ? searchString : Unicode.toLower( searchString ); | |
242 | |
243 bool found = false; | |
244 if (searchDialog.getSearchDown()) { | |
245 for(int i = table.getSelectionIndex() + 1; i < table.getItemCount(); i++) { | |
246 found = findMatch(searchString, table.getItem(i), column, matchWord, matchCase); | |
247 if ( found ){ | |
248 table.setSelection(i); | |
249 break; | |
250 } | |
251 } | |
252 } else { | |
253 for(int i = table.getSelectionIndex() - 1; i > -1; i--) { | |
254 found = findMatch(searchString, table.getItem(i), column, matchWord, matchCase); | |
255 if ( found ){ | |
256 table.setSelection(i); | |
257 break; | |
258 } | |
259 } | |
260 } | |
261 | |
262 shell.setCursor(cast(Cursor)null); | |
263 waitCursor.dispose(); | |
264 | |
265 return found; | |
266 } | |
267 private bool findMatch(char[] searchString, TableItem item, int column, bool matchWord, bool matchCase) { | |
268 | |
269 char[] tableText = matchCase ? item.getText(column) : Unicode.toLower( item.getText(column)); | |
270 if (matchWord) { | |
271 if (tableText !is null && tableText==searchString) { | |
272 return true; | |
273 } | |
274 | |
275 } else { | |
276 if(tableText!is null && TextUtil.containsPattern( tableText, searchString)) { | |
277 return true; | |
278 } | |
279 } | |
280 return false; | |
281 } | |
282 private void newAddressBook() { | |
283 shell.setText(resAddressBook.getString("Title_bar") ~ resAddressBook.getString("New_title")); | |
284 *(cast(Object*)&file) = null; | |
285 ///cast(Object)file = null; | |
286 isModified = false; | |
287 } | |
288 private void newEntry() { | |
82
9c2803aea121
Fix Addressbook example and HG ignores
Frank Benoit <benoit@tionex.de>
parents:
80
diff
changeset
|
289 DataEntryDialog dialog = new DataEntryDialog(shell, resAddressBook); |
78 | 290 dialog.setLabels(columnNames); |
291 char[][] data = dialog.open(); | |
292 if (data !is null) { | |
293 TableItem item = new TableItem(table, DWT.NONE); | |
294 item.setText(data); | |
295 isModified = true; | |
296 } | |
297 } | |
298 | |
299 private void openAddressBook() { | |
300 FileDialog fileDialog = new FileDialog(shell, DWT.OPEN); | |
301 | |
302 fileDialog.setFilterExtensions(["*.adr;", "*.*"]); | |
303 fileDialog.setFilterNames([ | |
304 resAddressBook.getString("Book_filter_name") ~ " (*.adr)", | |
305 resAddressBook.getString("All_filter_name") ~ " (*.*)"]); | |
306 char[] name = fileDialog.open(); | |
307 | |
308 if(name is null) return; | |
309 FilePath file = new FilePath(name); | |
310 if (!file.exists()) { | |
311 displayError(resAddressBook.getString("File")~file.toString()~" "~resAddressBook.getString("Does_not_exist")); | |
312 return; | |
313 } | |
314 | |
315 Cursor waitCursor = new Cursor(shell.getDisplay(), DWT.CURSOR_WAIT); | |
316 shell.setCursor(waitCursor); | |
317 | |
318 char[][] data; | |
319 try { | |
320 scope ioFile = new File (file); | |
321 data = TextUtil.splitLines (cast(char[]) ioFile.read); | |
322 } catch (IOException e ) { | |
323 displayError(resAddressBook.getString("IO_error_read") ~ "\n" ~ file.toString()); | |
324 return; | |
325 } finally { | |
326 | |
327 shell.setCursor(cast(Cursor)null); | |
328 waitCursor.dispose(); | |
329 } | |
330 | |
331 char[][][] tableInfo = new char[][][](data.length,table.getColumnCount()); | |
332 foreach( idx, line; data ){ | |
333 char[][] linetoks = decodeLine(line); | |
334 tableInfo[ idx ] = linetoks; | |
335 } | |
336 /+ | |
337 int writeIndex = 0; | |
338 for (int i = 0; i < data.length; i++) { | |
339 char[][] line = decodeLine(data[i]); | |
340 if (line !is null) tableInfo[writeIndex++] = line; | |
341 } | |
342 if (writeIndex !is data.length) { | |
343 char[][][] result = new char[][writeIndex][table.getColumnCount()]; | |
344 System.arraycopy(tableInfo, 0, result, 0, writeIndex); | |
345 tableInfo = result; | |
346 } | |
347 +/ | |
348 tango.core.Array.sort( tableInfo, new RowComparator(0)); | |
349 | |
350 for (int i = 0; i < tableInfo.length; i++) { | |
351 TableItem item = new TableItem(table, DWT.NONE); | |
352 item.setText(tableInfo[i]); | |
353 } | |
354 shell.setText(resAddressBook.getString("Title_bar")~fileDialog.getFileName()); | |
355 isModified = false; | |
356 this.file = file; | |
357 } | |
358 private bool save() { | |
359 if(file is null) return saveAs(); | |
360 | |
361 Cursor waitCursor = new Cursor(shell.getDisplay(), DWT.CURSOR_WAIT); | |
362 shell.setCursor(waitCursor); | |
363 | |
364 TableItem[] items = table.getItems(); | |
365 char[][] lines = new char[][items.length]; | |
366 for(int i = 0; i < items.length; i++) { | |
367 char[][] itemText = new char[][table.getColumnCount()]; | |
368 for (int j = 0; j < itemText.length; j++) { | |
369 itemText[j] = items[i].getText(j); | |
370 } | |
371 lines[i] = encodeLine(itemText); | |
372 } | |
373 | |
374 FileOutput fileOutput; | |
375 bool result = true; | |
376 try { | |
377 fileOutput = new FileOutput( file.toString ); | |
378 for (int i = 0; i < lines.length; i++) { | |
379 fileOutput.write(lines[i]); | |
380 } | |
381 } catch(IOException e ) { | |
382 displayError(resAddressBook.getString("IO_error_write") ~ "\n" ~ file.toString()); | |
383 result = false; | |
384 } catch(Exception e2 ) { | |
385 displayError(resAddressBook.getString("error_write") ~ "\n" ~ e2.toString()); | |
386 result = false; | |
387 } finally { | |
388 shell.setCursor(null); | |
389 waitCursor.dispose(); | |
390 | |
391 } | |
392 | |
393 if(fileOutput !is null) { | |
394 try { | |
395 fileOutput.close(); | |
396 } catch(IOException e) { | |
397 displayError(resAddressBook.getString("IO_error_close") ~ "\n" ~ file.toString()); | |
398 return false; | |
399 } | |
400 } | |
401 if( !result ){ | |
402 return false; | |
403 } | |
404 | |
405 shell.setText(resAddressBook.getString("Title_bar")~file.toString()); | |
406 isModified = false; | |
407 return true; | |
408 } | |
409 private bool saveAs() { | |
410 | |
411 FileDialog saveDialog = new FileDialog(shell, DWT.SAVE); | |
412 saveDialog.setFilterExtensions(["*.adr;", "*.*"]); | |
413 saveDialog.setFilterNames(["Address Books (*.adr)", "All Files "]); | |
414 | |
415 saveDialog.open(); | |
416 char[] name = saveDialog.getFileName(); | |
417 if(!name) return false; | |
418 | |
419 if( TextUtil.locatePatternPrior( name, ".adr" ) !is name.length - 4) { | |
420 name ~= ".adr"; | |
421 } | |
422 | |
423 FilePath file = new FilePath(saveDialog.getFilterPath() ); | |
424 file.append( name ); | |
425 if(file.exists()) { | |
426 MessageBox box = new MessageBox(shell, DWT.ICON_WARNING | DWT.YES | DWT.NO); | |
427 box.setText(resAddressBook.getString("Save_as_title")); | |
428 box.setMessage(resAddressBook.getString("File") ~ file.toString()~" "~resAddressBook.getString("Query_overwrite")); | |
429 if(box.open() !is DWT.YES) { | |
430 return false; | |
431 } | |
432 } | |
433 this.file = file; | |
434 return save(); | |
435 } | |
436 private void sort(int column) { | |
437 if(table.getItemCount() <= 1) return; | |
438 | |
439 TableItem[] items = table.getItems(); | |
440 char[][][] data = new char[][][](items.length, table.getColumnCount()); | |
441 for(int i = 0; i < items.length; i++) { | |
442 for(int j = 0; j < table.getColumnCount(); j++) { | |
443 data[i][j] = items[i].getText(j); | |
444 } | |
445 } | |
446 | |
447 tango.core.Array.sort(data, new RowComparator(column)); | |
448 | |
449 if (lastSortColumn !is column) { | |
450 table.setSortColumn(table.getColumn(column)); | |
451 table.setSortDirection(DWT.DOWN); | |
452 for (int i = 0; i < data.length; i++) { | |
453 items[i].setText(data[i]); | |
454 } | |
455 lastSortColumn = column; | |
456 } else { | |
457 // reverse order if the current column is selected again | |
458 table.setSortDirection(DWT.UP); | |
459 int j = data.length -1; | |
460 for (int i = 0; i < data.length; i++) { | |
461 items[i].setText(data[j--]); | |
462 } | |
463 lastSortColumn = -1; | |
464 } | |
465 | |
466 } | |
467 /** | |
468 * Creates all the items located in the File submenu and | |
469 * associate all the menu items with their appropriate | |
470 * functions. | |
471 * | |
472 * @param menuBar Menu | |
473 * the <code>Menu</code> that file contain | |
474 * the File submenu. | |
475 */ | |
476 private void createFileMenu(Menu menuBar) { | |
477 //File menu. | |
478 MenuItem item = new MenuItem(menuBar, DWT.CASCADE); | |
479 item.setText(resAddressBook.getString("File_menu_title")); | |
480 Menu menu = new Menu(shell, DWT.DROP_DOWN); | |
481 item.setMenu(menu); | |
482 /** | |
483 * Adds a listener to handle enabling and disabling | |
484 * some items in the Edit submenu. | |
485 */ | |
486 menu.addMenuListener(new class() MenuAdapter { | |
487 public void menuShown(MenuEvent e) { | |
488 Menu menu = cast(Menu)e.widget; | |
489 MenuItem[] items = menu.getItems(); | |
490 items[1].setEnabled(table.getSelectionCount() !is 0); // edit contact | |
491 items[5].setEnabled((file !is null) && isModified); // save | |
492 items[6].setEnabled(table.getItemCount() !is 0); // save as | |
493 } | |
494 }); | |
495 | |
496 | |
497 //File -> New Contact | |
498 MenuItem subItem = new MenuItem(menu, DWT.NONE); | |
499 subItem.setText(resAddressBook.getString("New_contact")); | |
500 subItem.setAccelerator(DWT.MOD1 + 'N'); | |
501 subItem.addSelectionListener(new class() SelectionAdapter { | |
502 public void widgetSelected(SelectionEvent e) { | |
503 newEntry(); | |
504 } | |
505 }); | |
506 subItem = new MenuItem(menu, DWT.NONE); | |
507 subItem.setText(resAddressBook.getString("Edit_contact")); | |
508 subItem.setAccelerator(DWT.MOD1 + 'E'); | |
509 subItem.addSelectionListener(new class() SelectionAdapter { | |
510 public void widgetSelected(SelectionEvent e) { | |
511 TableItem[] items = table.getSelection(); | |
512 if (items.length is 0) return; | |
513 editEntry(items[0]); | |
514 } | |
515 }); | |
516 | |
517 | |
518 new MenuItem(menu, DWT.SEPARATOR); | |
519 | |
520 //File -> New Address Book | |
521 subItem = new MenuItem(menu, DWT.NONE); | |
522 subItem.setText(resAddressBook.getString("New_address_book")); | |
523 subItem.setAccelerator(DWT.MOD1 + 'B'); | |
524 subItem.addSelectionListener(new class() SelectionAdapter { | |
525 public void widgetSelected(SelectionEvent e) { | |
526 if (closeAddressBook()) { | |
527 newAddressBook(); | |
528 } | |
529 } | |
530 }); | |
531 | |
532 //File -> Open | |
533 subItem = new MenuItem(menu, DWT.NONE); | |
534 subItem.setText(resAddressBook.getString("Open_address_book")); | |
535 subItem.setAccelerator(DWT.MOD1 + 'O'); | |
536 subItem.addSelectionListener(new class() SelectionAdapter { | |
537 public void widgetSelected(SelectionEvent e) { | |
538 if (closeAddressBook()) { | |
539 openAddressBook(); | |
540 } | |
541 } | |
542 }); | |
543 | |
544 //File -> Save. | |
545 subItem = new MenuItem(menu, DWT.NONE); | |
546 subItem.setText(resAddressBook.getString("Save_address_book")); | |
547 subItem.setAccelerator(DWT.MOD1 + 'S'); | |
548 subItem.addSelectionListener(new class() SelectionAdapter { | |
549 public void widgetSelected(SelectionEvent e) { | |
550 save(); | |
551 } | |
552 }); | |
553 | |
554 //File -> Save As. | |
555 subItem = new MenuItem(menu, DWT.NONE); | |
556 subItem.setText(resAddressBook.getString("Save_book_as")); | |
557 subItem.setAccelerator(DWT.MOD1 + 'A'); | |
558 subItem.addSelectionListener(new class() SelectionAdapter { | |
559 public void widgetSelected(SelectionEvent e) { | |
560 saveAs(); | |
561 } | |
562 }); | |
563 | |
564 | |
565 new MenuItem(menu, DWT.SEPARATOR); | |
566 | |
567 //File -> Exit. | |
568 subItem = new MenuItem(menu, DWT.NONE); | |
569 subItem.setText(resAddressBook.getString("Exit")); | |
570 subItem.addSelectionListener(new class() SelectionAdapter { | |
571 public void widgetSelected(SelectionEvent e) { | |
572 shell.close(); | |
573 } | |
574 }); | |
575 } | |
576 | |
577 /** | |
578 * Creates all the items located in the Edit submenu and | |
579 * associate all the menu items with their appropriate | |
580 * functions. | |
581 * | |
582 * @param menuBar Menu | |
583 * the <code>Menu</code> that file contain | |
584 * the Edit submenu. | |
585 * | |
586 * @see #createSortMenu() | |
587 */ | |
588 private MenuItem createEditMenu(Menu menuBar) { | |
589 //Edit menu. | |
590 MenuItem item = new MenuItem(menuBar, DWT.CASCADE); | |
591 item.setText(resAddressBook.getString("Edit_menu_title")); | |
592 Menu menu = new Menu(shell, DWT.DROP_DOWN); | |
593 item.setMenu(menu); | |
594 | |
595 /** | |
596 * Add a listener to handle enabling and disabling | |
597 * some items in the Edit submenu. | |
598 */ | |
599 menu.addMenuListener(new class() MenuAdapter { | |
600 public void menuShown(MenuEvent e) { | |
601 Menu menu = cast(Menu)e.widget; | |
602 MenuItem[] items = menu.getItems(); | |
603 int count = table.getSelectionCount(); | |
604 items[0].setEnabled(count !is 0); // edit | |
605 items[1].setEnabled(count !is 0); // copy | |
606 items[2].setEnabled(copyBuffer !is null); // paste | |
607 items[3].setEnabled(count !is 0); // delete | |
608 items[5].setEnabled(table.getItemCount() !is 0); // sort | |
609 } | |
610 }); | |
611 | |
612 //Edit -> Edit | |
613 MenuItem subItem = new MenuItem(menu, DWT.PUSH); | |
614 subItem.setText(resAddressBook.getString("Edit")); | |
615 subItem.setAccelerator(DWT.MOD1 + 'E'); | |
616 subItem.addSelectionListener(new class() SelectionAdapter { | |
617 public void widgetSelected(SelectionEvent e) { | |
618 TableItem[] items = table.getSelection(); | |
619 if (items.length is 0) return; | |
620 editEntry(items[0]); | |
621 } | |
622 }); | |
623 | |
624 //Edit -> Copy | |
625 subItem = new MenuItem(menu, DWT.NONE); | |
626 subItem.setText(resAddressBook.getString("Copy")); | |
627 subItem.setAccelerator(DWT.MOD1 + 'C'); | |
628 subItem.addSelectionListener(new class() SelectionAdapter { | |
629 public void widgetSelected(SelectionEvent e) { | |
630 TableItem[] items = table.getSelection(); | |
631 if (items.length is 0) return; | |
632 copyBuffer = new char[][table.getColumnCount()]; | |
633 for (int i = 0; i < copyBuffer.length; i++) { | |
634 copyBuffer[i] = items[0].getText(i); | |
635 } | |
636 } | |
637 }); | |
638 | |
639 //Edit -> Paste | |
640 subItem = new MenuItem(menu, DWT.NONE); | |
641 subItem.setText(resAddressBook.getString("Paste")); | |
642 subItem.setAccelerator(DWT.MOD1 + 'V'); | |
643 subItem.addSelectionListener(new class() SelectionAdapter { | |
644 public void widgetSelected(SelectionEvent e) { | |
645 if (copyBuffer is null) return; | |
646 TableItem item = new TableItem(table, DWT.NONE); | |
647 item.setText(copyBuffer); | |
648 isModified = true; | |
649 } | |
650 }); | |
651 | |
652 //Edit -> Delete | |
653 subItem = new MenuItem(menu, DWT.NONE); | |
654 subItem.setText(resAddressBook.getString("Delete")); | |
655 subItem.addSelectionListener(new class() SelectionAdapter { | |
656 public void widgetSelected(SelectionEvent e) { | |
657 TableItem[] items = table.getSelection(); | |
658 if (items.length is 0) return; | |
659 items[0].dispose(); | |
660 isModified = true; } | |
661 }); | |
662 | |
663 new MenuItem(menu, DWT.SEPARATOR); | |
664 | |
665 //Edit -> Sort(Cascade) | |
666 subItem = new MenuItem(menu, DWT.CASCADE); | |
667 subItem.setText(resAddressBook.getString("Sort")); | |
668 Menu submenu = createSortMenu(); | |
669 subItem.setMenu(submenu); | |
670 | |
671 return item; | |
672 | |
673 } | |
674 | |
675 /** | |
676 * Creates all the items located in the Sort cascading submenu and | |
677 * associate all the menu items with their appropriate | |
678 * functions. | |
679 * | |
680 * @return Menu | |
681 * The cascading menu with all the sort menu items on it. | |
682 */ | |
683 private Menu createSortMenu() { | |
684 Menu submenu = new Menu(shell, DWT.DROP_DOWN); | |
685 MenuItem subitem; | |
686 for(int i = 0; i < columnNames.length; i++) { | |
687 subitem = new MenuItem (submenu, DWT.NONE); | |
688 subitem.setText(columnNames [i]); | |
689 int column = i; | |
690 subitem.addSelectionListener(new class(column) SelectionAdapter { | |
691 int c; | |
692 this(int c){ this.c = c; } | |
693 public void widgetSelected(SelectionEvent e) { | |
694 sort(c); | |
695 } | |
696 }); | |
697 } | |
698 | |
699 return submenu; | |
700 } | |
701 | |
702 /** | |
703 * Creates all the items located in the Search submenu and | |
704 * associate all the menu items with their appropriate | |
705 * functions. | |
706 * | |
707 * @param menuBar Menu | |
708 * the <code>Menu</code> that file contain | |
709 * the Search submenu. | |
710 */ | |
711 private void createSearchMenu(Menu menuBar) { | |
712 //Search menu. | |
713 MenuItem item = new MenuItem(menuBar, DWT.CASCADE); | |
714 item.setText(resAddressBook.getString("Search_menu_title")); | |
715 Menu searchMenu = new Menu(shell, DWT.DROP_DOWN); | |
716 item.setMenu(searchMenu); | |
717 | |
718 //Search -> Find... | |
719 item = new MenuItem(searchMenu, DWT.NONE); | |
720 item.setText(resAddressBook.getString("Find")); | |
721 item.setAccelerator(DWT.MOD1 + 'F'); | |
722 item.addSelectionListener(new class() SelectionAdapter { | |
723 public void widgetSelected(SelectionEvent e) { | |
724 searchDialog.setMatchCase(false); | |
725 searchDialog.setMatchWord(false); | |
726 searchDialog.setSearchDown(true); | |
727 searchDialog.setSearchString(""); | |
728 searchDialog.setSelectedSearchArea(0); | |
729 searchDialog.open(); | |
730 } | |
731 }); | |
732 | |
733 //Search -> Find Next | |
734 item = new MenuItem(searchMenu, DWT.NONE); | |
735 item.setText(resAddressBook.getString("Find_next")); | |
736 item.setAccelerator(DWT.F3); | |
737 item.addSelectionListener(new class() SelectionAdapter { | |
738 public void widgetSelected(SelectionEvent e) { | |
739 searchDialog.open(); | |
740 } | |
741 }); | |
742 } | |
743 | |
744 /** | |
745 * Creates all items located in the popup menu and associates | |
746 * all the menu items with their appropriate functions. | |
747 * | |
748 * @return Menu | |
749 * The created popup menu. | |
750 */ | |
751 private Menu createPopUpMenu() { | |
752 Menu popUpMenu = new Menu(shell, DWT.POP_UP); | |
753 | |
754 /** | |
755 * Adds a listener to handle enabling and disabling | |
756 * some items in the Edit submenu. | |
757 */ | |
758 popUpMenu.addMenuListener(new class() MenuAdapter { | |
759 public void menuShown(MenuEvent e) { | |
760 Menu menu = cast(Menu)e.widget; | |
761 MenuItem[] items = menu.getItems(); | |
762 int count = table.getSelectionCount(); | |
763 items[2].setEnabled(count !is 0); // edit | |
764 items[3].setEnabled(count !is 0); // copy | |
765 items[4].setEnabled(copyBuffer !is null); // paste | |
766 items[5].setEnabled(count !is 0); // delete | |
767 items[7].setEnabled(table.getItemCount() !is 0); // find | |
768 } | |
769 }); | |
770 | |
771 //New | |
772 MenuItem item = new MenuItem(popUpMenu, DWT.PUSH); | |
773 item.setText(resAddressBook.getString("Pop_up_new")); | |
774 item.addSelectionListener(new class() SelectionAdapter { | |
775 public void widgetSelected(SelectionEvent e) { | |
776 newEntry(); | |
777 } | |
778 }); | |
779 | |
780 new MenuItem(popUpMenu, DWT.SEPARATOR); | |
781 | |
782 //Edit | |
783 item = new MenuItem(popUpMenu, DWT.PUSH); | |
784 item.setText(resAddressBook.getString("Pop_up_edit")); | |
785 item.addSelectionListener(new class() SelectionAdapter { | |
786 public void widgetSelected(SelectionEvent e) { | |
787 TableItem[] items = table.getSelection(); | |
788 if (items.length is 0) return; | |
789 editEntry(items[0]); | |
790 } | |
791 }); | |
792 | |
793 //Copy | |
794 item = new MenuItem(popUpMenu, DWT.PUSH); | |
795 item.setText(resAddressBook.getString("Pop_up_copy")); | |
796 item.addSelectionListener(new class() SelectionAdapter { | |
797 public void widgetSelected(SelectionEvent e) { | |
798 TableItem[] items = table.getSelection(); | |
799 if (items.length is 0) return; | |
800 copyBuffer = new char[][table.getColumnCount()]; | |
801 for (int i = 0; i < copyBuffer.length; i++) { | |
802 copyBuffer[i] = items[0].getText(i); | |
803 } | |
804 } | |
805 }); | |
806 | |
807 //Paste | |
808 item = new MenuItem(popUpMenu, DWT.PUSH); | |
809 item.setText(resAddressBook.getString("Pop_up_paste")); | |
810 item.addSelectionListener(new class() SelectionAdapter { | |
811 public void widgetSelected(SelectionEvent e) { | |
812 if (copyBuffer is null) return; | |
813 TableItem item = new TableItem(table, DWT.NONE); | |
814 item.setText(copyBuffer); | |
815 isModified = true; | |
816 } | |
817 }); | |
818 | |
819 //Delete | |
820 item = new MenuItem(popUpMenu, DWT.PUSH); | |
821 item.setText(resAddressBook.getString("Pop_up_delete")); | |
822 item.addSelectionListener(new class() SelectionAdapter { | |
823 public void widgetSelected(SelectionEvent e) { | |
824 TableItem[] items = table.getSelection(); | |
825 if (items.length is 0) return; | |
826 items[0].dispose(); | |
827 isModified = true; | |
828 } | |
829 }); | |
830 | |
831 new MenuItem(popUpMenu, DWT.SEPARATOR); | |
832 | |
833 //Find... | |
834 item = new MenuItem(popUpMenu, DWT.PUSH); | |
835 item.setText(resAddressBook.getString("Pop_up_find")); | |
836 item.addSelectionListener(new class() SelectionAdapter { | |
837 public void widgetSelected(SelectionEvent e) { | |
838 searchDialog.open(); | |
839 } | |
840 }); | |
841 | |
842 return popUpMenu; | |
843 } | |
844 | |
845 /** | |
846 * Creates all the items located in the Help submenu and | |
847 * associate all the menu items with their appropriate | |
848 * functions. | |
849 * | |
850 * @param menuBar Menu | |
851 * the <code>Menu</code> that file contain | |
852 * the Help submenu. | |
853 */ | |
854 private void createHelpMenu(Menu menuBar) { | |
855 | |
856 //Help Menu | |
857 MenuItem item = new MenuItem(menuBar, DWT.CASCADE); | |
858 item.setText(resAddressBook.getString("Help_menu_title")); | |
859 Menu menu = new Menu(shell, DWT.DROP_DOWN); | |
860 item.setMenu(menu); | |
861 | |
862 //Help -> About Text Editor | |
863 MenuItem subItem = new MenuItem(menu, DWT.NONE); | |
864 subItem.setText(resAddressBook.getString("About")); | |
865 subItem.addSelectionListener(new class() SelectionAdapter { | |
866 public void widgetSelected(SelectionEvent e) { | |
867 MessageBox box = new MessageBox(shell, DWT.NONE); | |
868 box.setText(resAddressBook.getString("About_1") ~ shell.getText()); | |
869 box.setMessage(shell.getText() ~ resAddressBook.getString("About_2")); | |
870 box.open(); | |
871 } | |
872 }); | |
873 } | |
874 | |
875 | |
876 /** | |
877 * To compare entries (rows) by the given column | |
878 */ | |
879 private class RowComparator /*: Comparator*/ { | |
880 private int column; | |
881 | |
882 /** | |
883 * Constructs a RowComparator given the column index | |
884 * @param col The index (starting at zero) of the column | |
885 */ | |
886 public this(int col) { | |
887 column = col; | |
888 } | |
889 | |
890 /** | |
891 * Compares two rows (type char[][]) using the specified | |
892 * column entry. | |
893 * @param obj1 First row to compare | |
894 * @param obj2 Second row to compare | |
895 * @return negative if obj1 less than obj2, positive if | |
896 * obj1 greater than obj2, and zero if equal. | |
897 */ | |
898 public bool compare(char[][] row1, char[][] row2) { | |
899 return row1[column] < row2[column]; | |
900 } | |
901 | |
902 alias compare opCall; | |
903 } | |
904 | |
905 } |