1 /* 2 * File : MultiTrackerEditor.java 3 * Created : 3 déc. 2003} 4 * By : Olivier 5 * 6 * Azureus - a Java Bittorrent client 7 * 8 * This program is free software; you can redistribute it and/or modify 9 * it under the terms of the GNU General Public License as published by 10 * the Free Software Foundation; either version 2 of the License, or 11 * (at your option) any later version. 12 * 13 * This program is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 * GNU General Public License for more details ( see the LICENSE file ). 17 * 18 * You should have received a copy of the GNU General Public License 19 * along with this program; if not, write to the Free Software 20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 21 */ 22 package org.gudy.azureus2.ui.swt.maketorrent; 23 24 import org.eclipse.swt.SWT; 25 import org.eclipse.swt.custom.TreeEditor; 26 import org.eclipse.swt.events.*; 27 import org.eclipse.swt.graphics.Point; 28 import org.eclipse.swt.graphics.Rectangle; 29 import org.eclipse.swt.layout.GridData; 30 import org.eclipse.swt.layout.GridLayout; 31 import org.eclipse.swt.widgets.*; 32 import org.gudy.azureus2.ui.swt.Messages; 33 import org.gudy.azureus2.ui.swt.Utils; 34 import org.gudy.azureus2.ui.swt.mainwindow.Colors; 35 36 import java.net.URL; 37 import java.util.Iterator; 38 import java.util.List; 39 import java.util.Map; 40 import java.util.HashMap; 41 import java.util.ArrayList; 42 43 44 /** 45 * @author Olivier 46 * 47 */ 48 public class WebSeedsEditor { 49 50 WebSeedsEditorListener listener; 51 String oldName; 52 String currentName; 53 boolean anonymous; 54 55 Map webseeds; 56 57 Display display; 58 Shell shell; 59 Text textName; 60 Tree treeGroups; 61 TreeEditor editor; 62 TreeItem itemEdited; 63 Button btnSave; 64 Button btnCancel; 65 66 Menu menu; 67 WebSeedsEditor(String name,Map webseeds,WebSeedsEditorListener listener)68 public WebSeedsEditor(String name,Map webseeds,WebSeedsEditorListener listener) { 69 this( name, webseeds, listener, false ); 70 } 71 72 public WebSeedsEditor( String name, Map webseeds, WebSeedsEditorListener listener, boolean _anonymous )73 WebSeedsEditor( 74 String name, 75 Map webseeds, 76 WebSeedsEditorListener listener, 77 boolean _anonymous ) 78 { 79 this.oldName = name; 80 if(name != null) 81 this.currentName = name; 82 else 83 this.currentName = ""; 84 this.listener = listener; 85 anonymous = _anonymous; 86 this.webseeds = new HashMap(webseeds); 87 createWindow(); 88 89 } 90 createWindow()91 private void createWindow() { 92 this.display = Display.getCurrent(); 93 this.shell = org.gudy.azureus2.ui.swt.components.shell.ShellFactory.createShell(SWT.DIALOG_TRIM | SWT.APPLICATION_MODAL); 94 Messages.setLanguageText(this.shell,"wizard.webseedseditor.edit.title"); 95 Utils.setShellIcon(shell); 96 GridLayout layout = new GridLayout(); 97 layout.numColumns = 3; 98 shell.setLayout(layout); 99 100 GridData gridData; 101 102 if ( !anonymous ){ 103 104 Label labelName = new Label(shell,SWT.NULL); 105 Messages.setLanguageText(labelName,"wizard.multitracker.edit.name"); 106 107 textName = new Text(shell,SWT.BORDER); 108 textName.setText(currentName); 109 gridData = new GridData(GridData.FILL_HORIZONTAL); 110 gridData.horizontalSpan = 2; 111 Utils.setLayoutData(textName, gridData); 112 textName.addModifyListener(new ModifyListener() { 113 public void modifyText(ModifyEvent arg0) { 114 currentName = textName.getText(); 115 computeSaveEnable(); 116 } 117 }); 118 } 119 120 treeGroups = new Tree(shell,SWT.BORDER); 121 gridData = new GridData(GridData.FILL_BOTH); 122 gridData.horizontalSpan = 3; 123 gridData.heightHint = 150; 124 Utils.setLayoutData(treeGroups, gridData); 125 126 treeGroups.addMouseListener( 127 new MouseAdapter() 128 { 129 public void 130 mouseDoubleClick( 131 MouseEvent arg0 ) 132 { 133 if(treeGroups.getSelectionCount() == 1) { 134 TreeItem treeItem = treeGroups.getSelection()[0]; 135 String type = (String) treeItem.getData("type"); 136 if(type.equals("tracker")) { 137 editTreeItem(treeItem); 138 } 139 } 140 } 141 }); 142 143 Label labelSeparator = new Label(shell,SWT.SEPARATOR | SWT.HORIZONTAL); 144 gridData = new GridData(GridData.FILL_HORIZONTAL); 145 gridData.horizontalSpan = 3; 146 Utils.setLayoutData(labelSeparator, gridData); 147 148 // button row 149 150 Label label = new Label(shell,SWT.NULL); 151 gridData = new GridData(GridData.FILL_HORIZONTAL ); 152 Utils.setLayoutData(label, gridData); 153 154 Composite cButtons = new Composite(shell, SWT.NULL); 155 gridData = new GridData(GridData.FILL_HORIZONTAL); 156 gridData.horizontalSpan = 3; 157 Utils.setLayoutData(cButtons, gridData); 158 GridLayout layoutButtons = new GridLayout(); 159 layoutButtons.numColumns = 3; 160 cButtons.setLayout(layoutButtons); 161 label = new Label(cButtons,SWT.NULL); 162 gridData = new GridData(GridData.FILL_HORIZONTAL ); 163 Utils.setLayoutData(label, gridData); 164 165 btnSave = new Button(cButtons,SWT.PUSH); 166 gridData = new GridData(); 167 gridData.widthHint = 70; 168 gridData.horizontalAlignment = GridData.END; 169 Utils.setLayoutData(btnSave, gridData); 170 Messages.setLanguageText(btnSave,"wizard.multitracker.edit.save"); 171 btnSave.addListener(SWT.Selection, new Listener() { 172 public void handleEvent(Event e) { 173 update(); 174 shell.dispose(); 175 } 176 }); 177 178 btnCancel = new Button(cButtons,SWT.PUSH); 179 gridData = new GridData(); 180 gridData.horizontalAlignment = GridData.END; 181 gridData.widthHint = 70; 182 Utils.setLayoutData(btnCancel, gridData); 183 Messages.setLanguageText(btnCancel,"Button.cancel"); 184 btnCancel.addListener(SWT.Selection, new Listener() { 185 public void handleEvent(Event e) { 186 shell.dispose(); 187 } 188 }); 189 190 shell.setDefaultButton( btnSave ); 191 192 shell.addListener(SWT.Traverse, new Listener() { 193 public void handleEvent(Event e) { 194 if ( e.character == SWT.ESC){ 195 shell.dispose(); 196 } 197 } 198 }); 199 200 201 computeSaveEnable(); 202 refresh(); 203 constructMenu(); 204 205 editor = new TreeEditor (treeGroups); 206 treeGroups.addSelectionListener(new SelectionAdapter() { 207 public void widgetSelected(SelectionEvent arg0) { 208 if(itemEdited != null && !editor.getEditor().isDisposed()) 209 itemEdited.setText(((Text)editor.getEditor()).getText()); 210 removeEditor(); 211 } 212 }); 213 214 shell.pack(); 215 216 Point size = shell.computeSize(400,SWT.DEFAULT); 217 shell.setSize(size); 218 219 Utils.centreWindow( shell ); 220 221 shell.open(); 222 } 223 update()224 private void update() { 225 webseeds = new HashMap(); 226 TreeItem[] groupItems = treeGroups.getItems(); 227 228 for(int i = 0 ; i < groupItems.length ; i++) { 229 TreeItem group = groupItems[i]; 230 TreeItem[] trackerItems = group.getItems(); 231 List groupList = new ArrayList(group.getItemCount()); 232 for(int j = 0 ; j < trackerItems.length ; j++) { 233 groupList.add(trackerItems[j].getText()); 234 } 235 webseeds.put(group.getText(),groupList); 236 } 237 238 listener.webSeedsChanged(oldName,currentName,webseeds); 239 oldName = currentName; 240 } 241 computeSaveEnable()242 private void computeSaveEnable() 243 { 244 boolean enabled = anonymous || !("".equals(currentName)); 245 246 if ( enabled ){ 247 248 TreeItem[] groupItems = treeGroups.getItems(); 249 250 outer: 251 for(int i = 0 ; i < groupItems.length ; i++) { 252 TreeItem group = groupItems[i]; 253 TreeItem[] trackerItems = group.getItems(); 254 for(int j = 0 ; j < trackerItems.length ; j++) { 255 256 if ( ! validURL(trackerItems[j].getText())){ 257 258 enabled = false; 259 260 break outer; 261 } 262 } 263 } 264 } 265 266 if ( enabled != btnSave.getEnabled()){ 267 268 btnSave.setEnabled( enabled ); 269 } 270 } 271 refresh()272 private void refresh() { 273 treeGroups.removeAll(); 274 Iterator iter = webseeds.entrySet().iterator(); 275 while(iter.hasNext()) { 276 Map.Entry entry = (Map.Entry) iter.next(); 277 TreeItem itemRoot = newGroup((String)entry.getKey()); 278 Iterator iter2 = ((List)entry.getValue()).iterator(); 279 while(iter2.hasNext()) { 280 String url = (String) iter2.next(); 281 newTracker(itemRoot,url); 282 } 283 } 284 } 285 constructMenu()286 private void constructMenu() { 287 menu = new Menu(shell,SWT.NULL); 288 menu.addListener(SWT.Show, new Listener() { 289 public void handleEvent(Event e) { 290 //1. Empty the menu 291 MenuItem[] items = menu.getItems(); 292 for(int i = 0 ; i < items.length ; i++) { 293 items[i].dispose(); 294 } 295 296 297 //3. Grab the element 298 final TreeItem treeItem = treeGroups.getSelection()[0]; 299 String type = (String) treeItem.getData("type"); 300 if(type.equals("tracker")) { 301 //The Tracker menu 302 MenuItem item = new MenuItem(menu,SWT.NULL); 303 Messages.setLanguageText(item,"wizard.multitracker.edit.deletetracker"); 304 item.addListener(SWT.Selection,new Listener(){ 305 public void handleEvent(Event arg0) { 306 treeItem.dispose(); 307 } 308 }); 309 310 item = new MenuItem(menu,SWT.NULL); 311 Messages.setLanguageText(item,"wizard.multitracker.edit.edit"); 312 item.addListener(SWT.Selection,new Listener(){ 313 public void handleEvent(Event arg0) { 314 editTreeItem(treeItem); 315 } 316 }); 317 } else 318 if(type.equals("group")) { 319 //The Group menu 320 321 MenuItem item = new MenuItem(menu,SWT.NULL); 322 Messages.setLanguageText(item,"wizard.webseedseditor.edit.newseed"); 323 item.addListener(SWT.Selection, new Listener() { 324 public void handleEvent(Event arg0) { 325 TreeItem itemTracker = newTracker(treeItem,"http://"); 326 editTreeItem(itemTracker); 327 } 328 }); 329 } 330 } 331 }); 332 treeGroups.setMenu(menu); 333 } 334 editTreeItem(final TreeItem item)335 private void editTreeItem(final TreeItem item) { 336 // Clean up any previous editor control 337 Control oldEditor = editor.getEditor(); 338 if (oldEditor != null) 339 oldEditor.dispose(); 340 341 itemEdited = item; 342 // The control that will be the editor must be a child of the Tree 343 final Text text = new Text(treeGroups, SWT.BORDER); 344 text.setText(item.getText()); 345 text.setForeground(item.getForeground()); 346 text.setSelection(item.getText().length()); 347 text.addListener (SWT.DefaultSelection, new Listener () { 348 public void handleEvent (Event e) { 349 String url = text.getText(); 350 if ( validURL(url)){ 351 text.setForeground( null ); 352 item.setForeground( null ); 353 }else{ 354 text.setForeground( Colors.colorError ); 355 item.setForeground( Colors.colorError ); 356 } 357 item.setText(url); 358 computeSaveEnable(); 359 removeEditor(); 360 } 361 }); 362 363 text.addListener(SWT.Modify, new Listener() { 364 public void handleEvent (Event e) { 365 String url = text.getText(); 366 if ( validURL(url)){ 367 text.setForeground( null ); 368 item.setForeground( null ); 369 }else{ 370 text.setForeground( Colors.colorError ); 371 item.setForeground( Colors.colorError ); 372 } 373 item.setText(url); 374 computeSaveEnable(); 375 } 376 }); 377 378 text.addKeyListener(new KeyAdapter() { 379 public void keyReleased(KeyEvent keyEvent) { 380 if(keyEvent.character == SWT.ESC) { 381 removeEditor(); 382 } 383 } 384 }); 385 386 387 //The text editor must have the same size as the cell and must 388 //not be any smaller than 50 pixels. 389 editor.horizontalAlignment = SWT.LEFT; 390 editor.grabHorizontal = true; 391 editor.minimumWidth = 50; 392 393 Rectangle r = text.computeTrim(0, 0, 100, text.getLineHeight()); 394 editor.minimumHeight = r.height; 395 396 397 // Open the text editor on the selected row. 398 editor.setEditor (text, item); 399 400 // Assign focus to the text control 401 text.setFocus (); 402 } 403 404 private boolean validURL( String str )405 validURL( 406 String str ) 407 { 408 try{ 409 URL url = new URL(str); 410 411 String prot = url.getProtocol().toLowerCase(); 412 413 if ( prot.startsWith( "http" )){ 414 415 return( true ); 416 } 417 418 return( false ); 419 420 }catch( Throwable e ){ 421 422 return( false ); 423 } 424 } 425 removeEditor()426 private void removeEditor() { 427 Control oldEditor = editor.getEditor(); 428 if (oldEditor != null) 429 oldEditor.dispose(); 430 } 431 newGroup(String name)432 private TreeItem newGroup(String name) { 433 TreeItem item = new TreeItem(treeGroups,SWT.NULL); 434 item.setData("type","group"); 435 item.setText(name); 436 return item; 437 } 438 newTracker(TreeItem root,String url)439 private TreeItem newTracker(TreeItem root,String url) { 440 TreeItem item = new TreeItem(root,SWT.NULL); 441 item.setText(url); 442 item.setData("type","tracker"); 443 root.setExpanded(true); 444 return item; 445 } 446 } 447