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