# HG changeset patch # User Frank Benoit # Date 1200686029 -3600 # Node ID 396a9fa07672cb94d3d031f113f202e96c0e854e # Parent 34e9dc2642d5d2e6db491fa5e1af5326be3779c1 Added addressbook example. Does not yet compile diff -r 34e9dc2642d5 -r 396a9fa07672 .hgignore --- a/.hgignore Fri Jan 18 19:46:33 2008 +0100 +++ b/.hgignore Fri Jan 18 20:53:49 2008 +0100 @@ -14,8 +14,8 @@ ^dwtexamples/helloworld/HelloWorld3$ ^dwtexamples/helloworld/HelloWorld4$ ^dwtexamples/helloworld/HelloWorld5$ +^dwtexamples/addressbook/AddressBook$ - diff -r 34e9dc2642d5 -r 396a9fa07672 dsss.conf --- a/dsss.conf Fri Jan 18 19:46:33 2008 +0100 +++ b/dsss.conf Fri Jan 18 20:53:49 2008 +0100 @@ -36,4 +36,5 @@ [dwtexamples/helloworld/HelloWorld3.d] [dwtexamples/helloworld/HelloWorld4.d] [dwtexamples/helloworld/HelloWorld5.d] +[dwtexamples/addressbook/AddressBook.d] [t.d] diff -r 34e9dc2642d5 -r 396a9fa07672 dwt/dwthelper/ResourceBundle.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwt/dwthelper/ResourceBundle.d Fri Jan 18 20:53:49 2008 +0100 @@ -0,0 +1,18 @@ +module dwt.dwthelper.ResourceBundle; + +class ResourceBundle { + + public this( char[] name ){ + } + + public char[] getString( char[] key ){ + return key; + } + + public static ResourceBundle getBundle( char[] name ){ + return new ResourceBundle( name ); + } + +} + + diff -r 34e9dc2642d5 -r 396a9fa07672 dwtexamples/addressbook/AddressBook.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtexamples/addressbook/AddressBook.d Fri Jan 18 20:53:49 2008 +0100 @@ -0,0 +1,915 @@ +/******************************************************************************* + * Copyright (c) 2000, 2006 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +module dwtexamples.addressbook.AddressBook; + + +// /* Imports */ +// import java.io.BufferedReader; +// import java.io.File; +// import java.io.FileNotFoundException; +// import java.io.FileReader; +// import java.io.FileWriter; +// import java.io.IOException; +// import java.util.Arrays; +// import java.util.Comparator; +// import java.util.ResourceBundle; + + +import dwt.DWT; +import dwt.events.MenuAdapter; +import dwt.events.MenuEvent; +import dwt.events.SelectionAdapter; +import dwt.events.SelectionEvent; +import dwt.events.ShellAdapter; +import dwt.events.ShellEvent; +import dwt.graphics.Cursor; +import dwt.layout.FillLayout; +import dwt.widgets.Display; +import dwt.widgets.FileDialog; +import dwt.widgets.Menu; +import dwt.widgets.MenuItem; +import dwt.widgets.MessageBox; +import dwt.widgets.Shell; +import dwt.widgets.Table; +import dwt.widgets.TableColumn; +import dwt.widgets.TableItem; + +import dwtexamples.addressbook.SearchDialog; +import dwtexamples.addressbook.DataEntryDialog; + +import dwt.dwthelper.ResourceBundle; + +void main() { + Display display = new Display(); + AddressBook application = new AddressBook(); + Shell shell = application.open(display); + while(!shell.isDisposed()){ + if(!display.readAndDispatch()) + display.sleep(); + } + display.dispose(); +} + +/** + * AddressBookExample is an example that uses org.eclipse.swt + * libraries to implement a simple address book. This application has + * save, load, sorting, and searching functions common + * to basic address books. + */ +public class AddressBook { + + private static ResourceBundle resAddressBook; + private Shell shell; + + private Table table; + private SearchDialog searchDialog; + + private File file; + private bool isModified; + + private char[][] copyBuffer; + + private int lastSortColumn= -1; + + private static const char[] DELIMITER = "\t"; + private static char[][] columnNames; + +public this(){ + if( resAddressBook is null ){ + resAddressBook = ResourceBundle.getBundle("examples_addressbook"); + columnNames = [ + resAddressBook.getString("Last_name"), + resAddressBook.getString("First_name"), + resAddressBook.getString("Business_phone"), + resAddressBook.getString("Home_phone"), + resAddressBook.getString("Email"), + resAddressBook.getString("Fax") ]; + } +} +public Shell open(Display display) { + shell = new Shell(display); + shell.setLayout(new FillLayout()); + shell.addShellListener(new class() ShellAdapter { + public void shellClosed(ShellEvent e) { + e.doit = closeAddressBook(); + } + }); + + createMenuBar(); + + searchDialog = new SearchDialog(shell); + searchDialog.setSearchAreaNames(columnNames); + searchDialog.setSearchAreaLabel(resAddressBook.getString("Column")); + searchDialog.addFindListener(new class() FindListener { + public bool find() { + return findEntry(); + } + }); + + table = new Table(shell, DWT.SINGLE | DWT.BORDER | DWT.FULL_SELECTION); + table.setHeaderVisible(true); + table.setMenu(createPopUpMenu()); + table.addSelectionListener(new class() SelectionAdapter { + public void widgetDefaultSelected(SelectionEvent e) { + TableItem[] items = table.getSelection(); + if (items.length > 0) editEntry(items[0]); + } + }); + for(int i = 0; i < columnNames.length; i++) { + TableColumn column = new TableColumn(table, DWT.NONE); + column.setText(columnNames[i]); + column.setWidth(150); + final int columnIndex = i; + column.addSelectionListener(new class() SelectionAdapter { + public void widgetSelected(SelectionEvent e) { + sort(columnIndex); + } + }); + } + + newAddressBook(); + + shell.setSize(table.computeSize(DWT.DEFAULT, DWT.DEFAULT).x, 300); + shell.open(); + return shell; +} + +private bool closeAddressBook() { + if(isModified) { + //ask user if they want to save current address book + MessageBox box = new MessageBox(shell, DWT.ICON_WARNING | DWT.YES | DWT.NO | DWT.CANCEL); + box.setText(shell.getText()); + box.setMessage(resAddressBook.getString("Close_save")); + + int choice = box.open(); + if(choice is DWT.CANCEL) { + return false; + } else if(choice is DWT.YES) { + if (!save()) return false; + } + } + + TableItem[] items = table.getItems(); + for (int i = 0; i < items.length; i ++) { + items[i].dispose(); + } + + return true; +} +/** + * Creates the menu at the top of the shell where most + * of the programs functionality is accessed. + * + * @return The Menu widget that was created + */ +private Menu createMenuBar() { + Menu menuBar = new Menu(shell, DWT.BAR); + shell.setMenuBar(menuBar); + + //create each header and subMenu for the menuBar + createFileMenu(menuBar); + createEditMenu(menuBar); + createSearchMenu(menuBar); + createHelpMenu(menuBar); + + return menuBar; +} + +/** + * Converts an encoded char[] to a char[] array representing a table entry. + */ +private char[][] decodeLine(char[] line) { + if(line is null) return null; + + char[][] parsedLine = new char[][table.getColumnCount()]; + for(int i = 0; i < parsedLine.length - 1; i++) { + int index = line.indexOf(DELIMITER); + if (index > -1) { + parsedLine[i] = line.substring(0, index); + line = line.substring(index + DELIMITER.length(), line.length()); + } else { + return null; + } + } + + if (line.indexOf(DELIMITER) !is -1) return null; + + parsedLine[parsedLine.length - 1] = line; + + return parsedLine; +} +private void displayError(char[] msg) { + MessageBox box = new MessageBox(shell, DWT.ICON_ERROR); + box.setMessage(msg); + box.open(); +} +private void editEntry(TableItem item) { + DataEntryDialog dialog = new DataEntryDialog(shell); + dialog.setLabels(columnNames); + char[][] values = new char[][table.getColumnCount()]; + for (int i = 0; i < values.length; i++) { + values[i] = item.getText(i); + } + dialog.setValues(values); + values = dialog.open(); + if (values !is null) { + item.setText(values); + isModified = true; + } +} +private char[] encodeLine(char[][] tableItems) { + char[] line = ""; + for (int i = 0; i < tableItems.length - 1; i++) { + line += tableItems[i] + DELIMITER; + } + line += tableItems[tableItems.length - 1] + "\n"; + + return line; +} +private bool findEntry() { + Cursor waitCursor = new Cursor(shell.getDisplay(), DWT.CURSOR_WAIT); + shell.setCursor(waitCursor); + + bool matchCase = searchDialog.getMatchCase(); + bool matchWord = searchDialog.getMatchWord(); + char[] searchString = searchDialog.getSearchString(); + int column = searchDialog.getSelectedSearchArea(); + + searchString = matchCase ? searchString : searchString.toLowerCase(); + + bool found = false; + if (searchDialog.getSearchDown()) { + for(int i = table.getSelectionIndex() + 1; i < table.getItemCount(); i++) { + if (found = findMatch(searchString, table.getItem(i), column, matchWord, matchCase)){ + table.setSelection(i); + break; + } + } + } else { + for(int i = table.getSelectionIndex() - 1; i > -1; i--) { + if (found = findMatch(searchString, table.getItem(i), column, matchWord, matchCase)){ + table.setSelection(i); + break; + } + } + } + + shell.setCursor(null); + waitCursor.dispose(); + + return found; +} +private bool findMatch(char[] searchString, TableItem item, int column, bool matchWord, bool matchCase) { + + char[] tableText = matchCase ? item.getText(column) : item.getText(column).toLowerCase(); + if (matchWord) { + if (tableText !is null && tableText.equals(searchString)) { + return true; + } + + } else { + if(tableText!is null && tableText.indexOf(searchString) !is -1) { + return true; + } + } + return false; +} +private void newAddressBook() { + shell.setText(resAddressBook.getString("Title_bar") + resAddressBook.getString("New_title")); + file = null; + isModified = false; +} +private void newEntry() { + DataEntryDialog dialog = new DataEntryDialog(shell); + dialog.setLabels(columnNames); + char[][] data = dialog.open(); + if (data !is null) { + TableItem item = new TableItem(table, DWT.NONE); + item.setText(data); + isModified = true; + } +} + +private void openAddressBook() { + FileDialog fileDialog = new FileDialog(shell, DWT.OPEN); + + fileDialog.setFilterExtensions(["*.adr;", "*.*"]); + fileDialog.setFilterNames(new char[][] [resAddressBook.getString("Book_filter_name") + " (*.adr)", + resAddressBook.getString("All_filter_name") + " (*.*)"]); + char[] name = fileDialog.open(); + + if(name is null) return; + File file = new File(name); + if (!file.exists()) { + displayError(resAddressBook.getString("File")~file.getName()~" "~resAddressBook.getString("Does_not_exist")); + return; + } + + Cursor waitCursor = new Cursor(shell.getDisplay(), DWT.CURSOR_WAIT); + shell.setCursor(waitCursor); + + FileReader fileReader = null; + BufferedReader bufferedReader = null; + char[][] data = new char[][0]; + try { + fileReader = new FileReader(file.getAbsolutePath()); + bufferedReader = new BufferedReader(fileReader); + char[] nextLine = bufferedReader.readLine(); + while (nextLine !is null){ + char[][] newData = new char[][data.length + 1]; + System.arraycopy(data, 0, newData, 0, data.length); + newData[data.length] = nextLine; + data = newData; + nextLine = bufferedReader.readLine(); + } + } catch(FileNotFoundException e) { + displayError(resAddressBook.getString("File_not_found") ~ "\n" ~ file.getName()); + return; + } catch (IOException e ) { + displayError(resAddressBook.getString("IO_error_read") ~ "\n" ~ file.getName()); + return; + } finally { + + shell.setCursor(null); + waitCursor.dispose(); + + if(fileReader !is null) { + try { + fileReader.close(); + } catch(IOException e) { + displayError(resAddressBook.getString("IO_error_close") ~ "\n" ~file.getName()); + return; + } + } + } + + char[][][] tableInfo = new char[][data.length][table.getColumnCount()]; + int writeIndex = 0; + for (int i = 0; i < data.length; i++) { + char[][] line = decodeLine(data[i]); + if (line !is null) tableInfo[writeIndex++] = line; + } + if (writeIndex !is data.length) { + char[][][] result = new char[][writeIndex][table.getColumnCount()]; + System.arraycopy(tableInfo, 0, result, 0, writeIndex); + tableInfo = result; + } + Arrays.sort(tableInfo, new RowComparator(0)); + + for (int i = 0; i < tableInfo.length; i++) { + TableItem item = new TableItem(table, DWT.NONE); + item.setText(tableInfo[i]); + } + shell.setText(resAddressBook.getString("Title_bar")~fileDialog.getFileName()); + isModified = false; + this.file = file; +} +private bool save() { + if(file is null) return saveAs(); + + Cursor waitCursor = new Cursor(shell.getDisplay(), DWT.CURSOR_WAIT); + shell.setCursor(waitCursor); + + TableItem[] items = table.getItems(); + char[][] lines = new char[][items.length]; + for(int i = 0; i < items.length; i++) { + char[][] itemText = new char[][table.getColumnCount()]; + for (int j = 0; j < itemText.length; j++) { + itemText[j] = items[i].getText(j); + } + lines[i] = encodeLine(itemText); + } + + FileWriter fileWriter = null; + try { + fileWriter = new FileWriter(file.getAbsolutePath(), false); + for (int i = 0; i < lines.length; i++) { + fileWriter.write(lines[i]); + } + } catch(FileNotFoundException e) { + displayError(resAddressBook.getString("File_not_found") ~ "\n" ~ file.getName()); + return false; + } catch(IOException e ) { + displayError(resAddressBook.getString("IO_error_write") ~ "\n" ~ file.getName()); + return false; + } finally { + shell.setCursor(null); + waitCursor.dispose(); + + if(fileWriter !is null) { + try { + fileWriter.close(); + } catch(IOException e) { + displayError(resAddressBook.getString("IO_error_close") ~ "\n" ~ file.getName()); + return false; + } + } + } + + shell.setText(resAddressBook.getString("Title_bar")+file.getName()); + isModified = false; + return true; +} +private bool saveAs() { + + FileDialog saveDialog = new FileDialog(shell, DWT.SAVE); + saveDialog.setFilterExtensions(["*.adr;", "*.*"]); + saveDialog.setFilterNames(["Address Books (*.adr)", "All Files "]); + + saveDialog.open(); + char[] name = saveDialog.getFileName(); + + if(name.equals("")) return false; + + if(name.indexOf(".adr") !is name.length() - 4) { + name += ".adr"; + } + + File file = new File(saveDialog.getFilterPath(), name); + if(file.exists()) { + MessageBox box = new MessageBox(shell, DWT.ICON_WARNING | DWT.YES | DWT.NO); + box.setText(resAddressBook.getString("Save_as_title")); + box.setMessage(resAddressBook.getString("File") ~ file.getName()~" "~resAddressBook.getString("Query_overwrite")); + if(box.open() !is DWT.YES) { + return false; + } + } + this.file = file; + return save(); +} +private void sort(int column) { + if(table.getItemCount() <= 1) return; + + TableItem[] items = table.getItems(); + char[][][] data = new char[][items.length][table.getColumnCount()]; + for(int i = 0; i < items.length; i++) { + for(int j = 0; j < table.getColumnCount(); j++) { + data[i][j] = items[i].getText(j); + } + } + + Arrays.sort(data, new RowComparator(column)); + + if (lastSortColumn !is column) { + table.setSortColumn(table.getColumn(column)); + table.setSortDirection(DWT.DOWN); + for (int i = 0; i < data.length; i++) { + items[i].setText(data[i]); + } + lastSortColumn = column; + } else { + // reverse order if the current column is selected again + table.setSortDirection(DWT.UP); + int j = data.length -1; + for (int i = 0; i < data.length; i++) { + items[i].setText(data[j--]); + } + lastSortColumn = -1; + } + +} +/** + * Creates all the items located in the File submenu and + * associate all the menu items with their appropriate + * functions. + * + * @param menuBar Menu + * the Menu that file contain + * the File submenu. + */ +private void createFileMenu(Menu menuBar) { + //File menu. + MenuItem item = new MenuItem(menuBar, DWT.CASCADE); + item.setText(resAddressBook.getString("File_menu_title")); + Menu menu = new Menu(shell, DWT.DROP_DOWN); + item.setMenu(menu); + /** + * Adds a listener to handle enabling and disabling + * some items in the Edit submenu. + */ + menu.addMenuListener(new class() MenuAdapter { + public void menuShown(MenuEvent e) { + Menu menu = cast(Menu)e.widget; + MenuItem[] items = menu.getItems(); + items[1].setEnabled(table.getSelectionCount() !is 0); // edit contact + items[5].setEnabled((file !is null) && isModified); // save + items[6].setEnabled(table.getItemCount() !is 0); // save as + } + }); + + + //File -> New Contact + MenuItem subItem = new MenuItem(menu, DWT.NONE); + subItem.setText(resAddressBook.getString("New_contact")); + subItem.setAccelerator(DWT.MOD1 + 'N'); + subItem.addSelectionListener(new class() SelectionAdapter { + public void widgetSelected(SelectionEvent e) { + newEntry(); + } + }); + subItem = new MenuItem(menu, DWT.NONE); + subItem.setText(resAddressBook.getString("Edit_contact")); + subItem.setAccelerator(DWT.MOD1 + 'E'); + subItem.addSelectionListener(new class() SelectionAdapter { + public void widgetSelected(SelectionEvent e) { + TableItem[] items = table.getSelection(); + if (items.length is 0) return; + editEntry(items[0]); + } + }); + + + new MenuItem(menu, DWT.SEPARATOR); + + //File -> New Address Book + subItem = new MenuItem(menu, DWT.NONE); + subItem.setText(resAddressBook.getString("New_address_book")); + subItem.setAccelerator(DWT.MOD1 + 'B'); + subItem.addSelectionListener(new class() SelectionAdapter { + public void widgetSelected(SelectionEvent e) { + if (closeAddressBook()) { + newAddressBook(); + } + } + }); + + //File -> Open + subItem = new MenuItem(menu, DWT.NONE); + subItem.setText(resAddressBook.getString("Open_address_book")); + subItem.setAccelerator(DWT.MOD1 + 'O'); + subItem.addSelectionListener(new class() SelectionAdapter { + public void widgetSelected(SelectionEvent e) { + if (closeAddressBook()) { + openAddressBook(); + } + } + }); + + //File -> Save. + subItem = new MenuItem(menu, DWT.NONE); + subItem.setText(resAddressBook.getString("Save_address_book")); + subItem.setAccelerator(DWT.MOD1 + 'S'); + subItem.addSelectionListener(new class() SelectionAdapter { + public void widgetSelected(SelectionEvent e) { + save(); + } + }); + + //File -> Save As. + subItem = new MenuItem(menu, DWT.NONE); + subItem.setText(resAddressBook.getString("Save_book_as")); + subItem.setAccelerator(DWT.MOD1 + 'A'); + subItem.addSelectionListener(new class() SelectionAdapter { + public void widgetSelected(SelectionEvent e) { + saveAs(); + } + }); + + + new MenuItem(menu, DWT.SEPARATOR); + + //File -> Exit. + subItem = new MenuItem(menu, DWT.NONE); + subItem.setText(resAddressBook.getString("Exit")); + subItem.addSelectionListener(new class() SelectionAdapter { + public void widgetSelected(SelectionEvent e) { + shell.close(); + } + }); +} + +/** + * Creates all the items located in the Edit submenu and + * associate all the menu items with their appropriate + * functions. + * + * @param menuBar Menu + * the Menu that file contain + * the Edit submenu. + * + * @see #createSortMenu() + */ +private MenuItem createEditMenu(Menu menuBar) { + //Edit menu. + MenuItem item = new MenuItem(menuBar, DWT.CASCADE); + item.setText(resAddressBook.getString("Edit_menu_title")); + Menu menu = new Menu(shell, DWT.DROP_DOWN); + item.setMenu(menu); + + /** + * Add a listener to handle enabling and disabling + * some items in the Edit submenu. + */ + menu.addMenuListener(new class() MenuAdapter { + public void menuShown(MenuEvent e) { + Menu menu = cast(Menu)e.widget; + MenuItem[] items = menu.getItems(); + int count = table.getSelectionCount(); + items[0].setEnabled(count !is 0); // edit + items[1].setEnabled(count !is 0); // copy + items[2].setEnabled(copyBuffer !is null); // paste + items[3].setEnabled(count !is 0); // delete + items[5].setEnabled(table.getItemCount() !is 0); // sort + } + }); + + //Edit -> Edit + MenuItem subItem = new MenuItem(menu, DWT.PUSH); + subItem.setText(resAddressBook.getString("Edit")); + subItem.setAccelerator(DWT.MOD1 + 'E'); + subItem.addSelectionListener(new class() SelectionAdapter { + public void widgetSelected(SelectionEvent e) { + TableItem[] items = table.getSelection(); + if (items.length is 0) return; + editEntry(items[0]); + } + }); + + //Edit -> Copy + subItem = new MenuItem(menu, DWT.NONE); + subItem.setText(resAddressBook.getString("Copy")); + subItem.setAccelerator(DWT.MOD1 + 'C'); + subItem.addSelectionListener(new class() SelectionAdapter { + public void widgetSelected(SelectionEvent e) { + TableItem[] items = table.getSelection(); + if (items.length is 0) return; + copyBuffer = new char[][table.getColumnCount()]; + for (int i = 0; i < copyBuffer.length; i++) { + copyBuffer[i] = items[0].getText(i); + } + } + }); + + //Edit -> Paste + subItem = new MenuItem(menu, DWT.NONE); + subItem.setText(resAddressBook.getString("Paste")); + subItem.setAccelerator(DWT.MOD1 + 'V'); + subItem.addSelectionListener(new class() SelectionAdapter { + public void widgetSelected(SelectionEvent e) { + if (copyBuffer is null) return; + TableItem item = new TableItem(table, DWT.NONE); + item.setText(copyBuffer); + isModified = true; + } + }); + + //Edit -> Delete + subItem = new MenuItem(menu, DWT.NONE); + subItem.setText(resAddressBook.getString("Delete")); + subItem.addSelectionListener(new class() SelectionAdapter { + public void widgetSelected(SelectionEvent e) { + TableItem[] items = table.getSelection(); + if (items.length is 0) return; + items[0].dispose(); + isModified = true; } + }); + + new MenuItem(menu, DWT.SEPARATOR); + + //Edit -> Sort(Cascade) + subItem = new MenuItem(menu, DWT.CASCADE); + subItem.setText(resAddressBook.getString("Sort")); + Menu submenu = createSortMenu(); + subItem.setMenu(submenu); + + return item; + +} + +/** + * Creates all the items located in the Sort cascading submenu and + * associate all the menu items with their appropriate + * functions. + * + * @return Menu + * The cascading menu with all the sort menu items on it. + */ +private Menu createSortMenu() { + Menu submenu = new Menu(shell, DWT.DROP_DOWN); + MenuItem subitem; + for(int i = 0; i < columnNames.length; i++) { + subitem = new MenuItem (submenu, DWT.NONE); + subitem.setText(columnNames [i]); + final int column = i; + subitem.addSelectionListener(new class() SelectionAdapter { + public void widgetSelected(SelectionEvent e) { + sort(column); + } + }); + + } + + return submenu; +} + +/** + * Creates all the items located in the Search submenu and + * associate all the menu items with their appropriate + * functions. + * + * @param menuBar Menu + * the Menu that file contain + * the Search submenu. + */ +private void createSearchMenu(Menu menuBar) { + //Search menu. + MenuItem item = new MenuItem(menuBar, DWT.CASCADE); + item.setText(resAddressBook.getString("Search_menu_title")); + Menu searchMenu = new Menu(shell, DWT.DROP_DOWN); + item.setMenu(searchMenu); + + //Search -> Find... + item = new MenuItem(searchMenu, DWT.NONE); + item.setText(resAddressBook.getString("Find")); + item.setAccelerator(DWT.MOD1 + 'F'); + item.addSelectionListener(new class() SelectionAdapter { + public void widgetSelected(SelectionEvent e) { + searchDialog.setMatchCase(false); + searchDialog.setMatchWord(false); + searchDialog.setSearchDown(true); + searchDialog.setSearchString(""); + searchDialog.setSelectedSearchArea(0); + searchDialog.open(); + } + }); + + //Search -> Find Next + item = new MenuItem(searchMenu, DWT.NONE); + item.setText(resAddressBook.getString("Find_next")); + item.setAccelerator(DWT.F3); + item.addSelectionListener(new class() SelectionAdapter { + public void widgetSelected(SelectionEvent e) { + searchDialog.open(); + } + }); +} + +/** + * Creates all items located in the popup menu and associates + * all the menu items with their appropriate functions. + * + * @return Menu + * The created popup menu. + */ +private Menu createPopUpMenu() { + Menu popUpMenu = new Menu(shell, DWT.POP_UP); + + /** + * Adds a listener to handle enabling and disabling + * some items in the Edit submenu. + */ + popUpMenu.addMenuListener(new class() MenuAdapter { + public void menuShown(MenuEvent e) { + Menu menu = cast(Menu)e.widget; + MenuItem[] items = menu.getItems(); + int count = table.getSelectionCount(); + items[2].setEnabled(count !is 0); // edit + items[3].setEnabled(count !is 0); // copy + items[4].setEnabled(copyBuffer !is null); // paste + items[5].setEnabled(count !is 0); // delete + items[7].setEnabled(table.getItemCount() !is 0); // find + } + }); + + //New + MenuItem item = new MenuItem(popUpMenu, DWT.PUSH); + item.setText(resAddressBook.getString("Pop_up_new")); + item.addSelectionListener(new class() SelectionAdapter { + public void widgetSelected(SelectionEvent e) { + newEntry(); + } + }); + + new MenuItem(popUpMenu, DWT.SEPARATOR); + + //Edit + item = new MenuItem(popUpMenu, DWT.PUSH); + item.setText(resAddressBook.getString("Pop_up_edit")); + item.addSelectionListener(new class() SelectionAdapter { + public void widgetSelected(SelectionEvent e) { + TableItem[] items = table.getSelection(); + if (items.length is 0) return; + editEntry(items[0]); + } + }); + + //Copy + item = new MenuItem(popUpMenu, DWT.PUSH); + item.setText(resAddressBook.getString("Pop_up_copy")); + item.addSelectionListener(new class() SelectionAdapter { + public void widgetSelected(SelectionEvent e) { + TableItem[] items = table.getSelection(); + if (items.length is 0) return; + copyBuffer = new char[][table.getColumnCount()]; + for (int i = 0; i < copyBuffer.length; i++) { + copyBuffer[i] = items[0].getText(i); + } + } + }); + + //Paste + item = new MenuItem(popUpMenu, DWT.PUSH); + item.setText(resAddressBook.getString("Pop_up_paste")); + item.addSelectionListener(new class() SelectionAdapter { + public void widgetSelected(SelectionEvent e) { + if (copyBuffer is null) return; + TableItem item = new TableItem(table, DWT.NONE); + item.setText(copyBuffer); + isModified = true; + } + }); + + //Delete + item = new MenuItem(popUpMenu, DWT.PUSH); + item.setText(resAddressBook.getString("Pop_up_delete")); + item.addSelectionListener(new class() SelectionAdapter { + public void widgetSelected(SelectionEvent e) { + TableItem[] items = table.getSelection(); + if (items.length is 0) return; + items[0].dispose(); + isModified = true; + } + }); + + new MenuItem(popUpMenu, DWT.SEPARATOR); + + //Find... + item = new MenuItem(popUpMenu, DWT.PUSH); + item.setText(resAddressBook.getString("Pop_up_find")); + item.addSelectionListener(new class() SelectionAdapter { + public void widgetSelected(SelectionEvent e) { + searchDialog.open(); + } + }); + + return popUpMenu; +} + +/** + * Creates all the items located in the Help submenu and + * associate all the menu items with their appropriate + * functions. + * + * @param menuBar Menu + * the Menu that file contain + * the Help submenu. + */ +private void createHelpMenu(Menu menuBar) { + + //Help Menu + MenuItem item = new MenuItem(menuBar, DWT.CASCADE); + item.setText(resAddressBook.getString("Help_menu_title")); + Menu menu = new Menu(shell, DWT.DROP_DOWN); + item.setMenu(menu); + + //Help -> About Text Editor + MenuItem subItem = new MenuItem(menu, DWT.NONE); + subItem.setText(resAddressBook.getString("About")); + subItem.addSelectionListener(new class() SelectionAdapter { + public void widgetSelected(SelectionEvent e) { + MessageBox box = new MessageBox(shell, DWT.NONE); + box.setText(resAddressBook.getString("About_1") + shell.getText()); + box.setMessage(shell.getText() + resAddressBook.getString("About_2")); + box.open(); + } + }); +} + +/** + * To compare entries (rows) by the given column + */ +private class RowComparator : Comparator { + private int column; + + /** + * Constructs a RowComparator given the column index + * @param col The index (starting at zero) of the column + */ + public this(int col) { + column = col; + } + + /** + * Compares two rows (type char[][]) using the specified + * column entry. + * @param obj1 First row to compare + * @param obj2 Second row to compare + * @return negative if obj1 less than obj2, positive if + * obj1 greater than obj2, and zero if equal. + */ + public int compare(Object obj1, Object obj2) { + char[][] row1 = cast(char[][])obj1; + char[][] row2 = cast(char[][])obj2; + + return row1[column].compareTo(row2[column]); + } +} +} diff -r 34e9dc2642d5 -r 396a9fa07672 dwtexamples/addressbook/DataEntryDialog.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtexamples/addressbook/DataEntryDialog.d Fri Jan 18 20:53:49 2008 +0100 @@ -0,0 +1,176 @@ +/******************************************************************************* + * Copyright (c) 2000, 2005 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +module dwtexamples.addressbook.DataEntryDialog; + +import dwt.DWT; +import dwt.events.ModifyEvent; +import dwt.events.ModifyListener; +import dwt.events.SelectionAdapter; +import dwt.events.SelectionEvent; +import dwt.layout.GridData; +import dwt.layout.GridLayout; +import dwt.widgets.Button; +import dwt.widgets.Composite; +import dwt.widgets.Display; +import dwt.widgets.Label; +import dwt.widgets.Shell; +import dwt.widgets.Text; + +import dwt.dwthelper.ResourceBundle; + +/** + * DataEntryDialog class uses org.eclipse.swt + * libraries to implement a dialog that accepts basic personal information that + * is added to a Table widget or edits a TableItem entry + * to represent the entered data. + */ +public class DataEntryDialog { + + private static ResourceBundle resAddressBook; + + Shell shell; + char[][] values; + char[][] labels; + +public this(Shell parent) { + if( resAddressBook is null ){ + resAddressBook = ResourceBundle.getBundle("examples_addressbook"); + } + shell = new Shell(parent, DWT.DIALOG_TRIM | DWT.PRIMARY_MODAL); + shell.setLayout(new GridLayout()); +} + +private void addTextListener(Text text) { + text.addModifyListener(new class(test) ModifyListener { + Test text; + this( Text text ){ this.text = text; } + public void modifyText(ModifyEvent e){ + Integer index = (Integer)(this.text.getData("index")); + values[index.intValue()] = this.text.getText(); + } + }); +} +private void createControlButtons() { + Composite composite = new Composite(shell, DWT.NONE); + composite.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_CENTER)); + GridLayout layout = new GridLayout(); + layout.numColumns = 2; + composite.setLayout(layout); + + Button okButton = new Button(composite, DWT.PUSH); + okButton.setText(resAddressBook.getString("OK")); + okButton.addSelectionListener(new class() SelectionAdapter { + public void widgetSelected(SelectionEvent e) { + shell.close(); + } + }); + + Button cancelButton = new Button(composite, DWT.PUSH); + cancelButton.setText(resAddressBook.getString("Cancel")); + cancelButton.addSelectionListener(new class() SelectionAdapter { + public void widgetSelected(SelectionEvent e) { + values = null; + shell.close(); + } + }); + + shell.setDefaultButton(okButton); +} + +private void createTextWidgets() { + if (labels is null) return; + + Composite composite = new Composite(shell, DWT.NONE); + composite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + GridLayout layout= new GridLayout(); + layout.numColumns = 2; + composite.setLayout(layout); + + if (values is null) + values = new char[][labels.length]; + + for (int i = 0; i < labels.length; i++) { + Label label = new Label(composite, DWT.RIGHT); + label.setText(labels[i]); + Text text = new Text(composite, DWT.BORDER); + GridData gridData = new GridData(); + gridData.widthHint = 400; + text.setLayoutData(gridData); + if (values[i] !is null) { + text.setText(values[i]); + } + text.setData("index", new Integer(i)); + addTextListener(text); + } +} + +public char[][] getLabels() { + return labels; +} +public char[] getTitle() { + return shell.getText(); +} +/** + * Returns the contents of the Text widgets in the dialog in a + * char[] array. + * + * @return char[][] + * The contents of the text widgets of the dialog. + * May return null if all text widgets are empty. + */ +public char[][] getValues() { + return values; +} +/** + * Opens the dialog in the given state. Sets Text widget contents + * and dialog behaviour accordingly. + * + * @param dialogState int + * The state the dialog should be opened in. + */ +public char[][] open() { + createTextWidgets(); + createControlButtons(); + shell.pack(); + shell.open(); + Display display = shell.getDisplay(); + while(!shell.isDisposed()){ + if(!display.readAndDispatch()) + display.sleep(); + } + + return getValues(); +} +public void setLabels(char[][] labels) { + this.labels = labels; +} +public void setTitle(char[] title) { + shell.setText(title); +} +/** + * Sets the values of the Text widgets of the dialog to + * the values supplied in the parameter array. + * + * @param itemInfo char[][] + * The values to which the dialog contents will be set. + */ +public void setValues(char[][] itemInfo) { + if (labels is null) return; + + if (values is null) + values = new char[][labels.length]; + + int numItems = Math.min(values.length, itemInfo.length); + for(int i = 0; i < numItems; i++) { + values[i] = itemInfo[i]; + } +} +} diff -r 34e9dc2642d5 -r 396a9fa07672 dwtexamples/addressbook/FindListener.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtexamples/addressbook/FindListener.d Fri Jan 18 20:53:49 2008 +0100 @@ -0,0 +1,18 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +module dwtexamples.addressbook.FindListener; + + +public interface FindListener { + +public bool find(); + +} diff -r 34e9dc2642d5 -r 396a9fa07672 dwtexamples/addressbook/SearchDialog.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtexamples/addressbook/SearchDialog.d Fri Jan 18 20:53:49 2008 +0100 @@ -0,0 +1,219 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +module dwtexamples.addressbook.SearchDialog; + + +import dwt.DWT; +import dwt.events.ModifyEvent; +import dwt.events.ModifyListener; +import dwt.events.SelectionAdapter; +import dwt.events.SelectionEvent; +import dwt.events.ShellAdapter; +import dwt.events.ShellEvent; +import dwt.layout.FillLayout; +import dwt.layout.GridData; +import dwt.layout.GridLayout; +import dwt.widgets.Button; +import dwt.widgets.Combo; +import dwt.widgets.Composite; +import dwt.widgets.Group; +import dwt.widgets.Label; +import dwt.widgets.MessageBox; +import dwt.widgets.Shell; +import dwt.widgets.Text; + +import dwt.dwthelper.ResourceBundle; + +/** + * SearchDialog is a simple class that uses org.eclipse.swt + * libraries to implement a basic search dialog. + */ +public class SearchDialog { + + private static ResourceBundle resAddressBook; + + Shell shell; + Text searchText; + Combo searchArea; + Label searchAreaLabel; + Button matchCase; + Button matchWord; + Button findButton; + Button down; + FindListener findHandler; + +/** + * Class constructor that sets the parent shell and the table widget that + * the dialog will search. + * + * @param parent Shell + * The shell that is the parent of the dialog. + */ +public this(Shell parent) { + if( resAddressBook is null ){ + resAddressBook = ResourceBundle.getBundle("examples_addressbook"); + } + shell = new Shell(parent, DWT.CLOSE | DWT.BORDER | DWT.TITLE); + GridLayout layout = new GridLayout(); + layout.numColumns = 2; + shell.setLayout(layout); + shell.setText(resAddressBook.getString("Search_dialog_title")); + shell.addShellListener(new class() ShellAdapter{ + public void shellClosed(ShellEvent e) { + // don't dispose of the shell, just hide it for later use + e.doit = false; + shell.setVisible(false); + } + }); + + Label label = new Label(shell, DWT.LEFT); + label.setText(resAddressBook.getString("Dialog_find_what")); + searchText = new Text(shell, DWT.BORDER); + GridData gridData = new GridData(GridData.FILL_HORIZONTAL); + gridData.widthHint = 200; + searchText.setLayoutData(gridData); + searchText.addModifyListener(new class() ModifyListener { + public void modifyText(ModifyEvent e) { + bool enableFind = (searchText.getCharCount() !is 0); + findButton.setEnabled(enableFind); + } + }); + + searchAreaLabel = new Label(shell, DWT.LEFT); + searchArea = new Combo(shell, DWT.DROP_DOWN | DWT.READ_ONLY); + gridData = new GridData(GridData.FILL_HORIZONTAL); + gridData.widthHint = 200; + searchArea.setLayoutData(gridData); + + matchCase = new Button(shell, DWT.CHECK); + matchCase.setText(resAddressBook.getString("Dialog_match_case")); + gridData = new GridData(); + gridData.horizontalSpan = 2; + matchCase.setLayoutData(gridData); + + matchWord = new Button(shell, DWT.CHECK); + matchWord.setText(resAddressBook.getString("Dialog_match_word")); + gridData = new GridData(); + gridData.horizontalSpan = 2; + matchWord.setLayoutData(gridData); + + Group direction = new Group(shell, DWT.NONE); + gridData = new GridData(); + gridData.horizontalSpan = 2; + direction.setLayoutData(gridData); + direction.setLayout (new FillLayout ()); + direction.setText(resAddressBook.getString("Dialog_direction")); + + Button up = new Button(direction, DWT.RADIO); + up.setText(resAddressBook.getString("Dialog_dir_up")); + up.setSelection(false); + + down = new Button(direction, DWT.RADIO); + down.setText(resAddressBook.getString("Dialog_dir_down")); + down.setSelection(true); + + Composite composite = new Composite(shell, DWT.NONE); + gridData = new GridData(GridData.HORIZONTAL_ALIGN_FILL); + gridData.horizontalSpan = 2; + composite.setLayoutData(gridData); + layout = new GridLayout(); + layout.numColumns = 2; + layout.makeColumnsEqualWidth = true; + composite.setLayout(layout); + + findButton = new Button(composite, DWT.PUSH); + findButton.setText(resAddressBook.getString("Dialog_find")); + findButton.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_END)); + findButton.setEnabled(false); + findButton.addSelectionListener(new class() SelectionAdapter { + public void widgetSelected(SelectionEvent e) { + if (!findHandler.find()){ + MessageBox box = new MessageBox(shell, DWT.ICON_INFORMATION | DWT.OK | DWT.PRIMARY_MODAL); + box.setText(shell.getText()); + box.setMessage(resAddressBook.getString("Cannot_find") + "\"" + searchText.getText() + "\""); + box.open(); + } + } + }); + + Button cancelButton = new Button(composite, DWT.PUSH); + cancelButton.setText(resAddressBook.getString("Cancel")); + cancelButton.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING)); + cancelButton.addSelectionListener(new class() SelectionAdapter { + public void widgetSelected(SelectionEvent e) { + shell.setVisible(false); + } + }); + + shell.pack(); +} +public char[] getSearchAreaLabel(char[] label) { + return searchAreaLabel.getText(); +} + +public char[][] getsearchAreaNames() { + return searchArea.getItems(); +} +public bool getMatchCase() { + return matchCase.getSelection(); +} +public bool getMatchWord() { + return matchWord.getSelection(); +} +public char[] getSearchString() { + return searchText.getText(); +} +public bool getSearchDown(){ + return down.getSelection(); +} +public int getSelectedSearchArea() { + return searchArea.getSelectionIndex(); +} +public void open() { + if (shell.isVisible()) { + shell.setFocus(); + } else { + shell.open(); + } + searchText.setFocus(); +} +public void setSearchAreaNames(char[][] names) { + for (int i = 0; i < names.length; i++) { + searchArea.add(names[i]); + } + searchArea.select(0); +} +public void setSearchAreaLabel(char[] label) { + searchAreaLabel.setText(label); +} +public void setMatchCase(bool match) { + matchCase.setSelection(match); +} +public void setMatchWord(bool match) { + matchWord.setSelection(match); +} +public void setSearchDown(bool searchDown){ + down.setSelection(searchDown); +} +public void setSearchString(char[] searchString) { + searchText.setText(searchString); +} + +public void setSelectedSearchArea(int index) { + searchArea.select(index); +} +public void addFindListener(FindListener listener) { + this.findHandler = listener; +} +public void removeFindListener(FindListener listener) { + this.findHandler = null; +} +}