/**
* Copyright (C) Azureus Software, Inc, All Rights Reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
*/
package com.aelitis.azureus.ui.swt.shells.opentorrent;
import java.io.File;
import java.io.UnsupportedEncodingException;
import java.util.*;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.regex.Pattern;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.StackLayout;
import org.eclipse.swt.events.*;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.*;
import org.eclipse.swt.widgets.*;
import org.gudy.azureus2.core3.config.COConfigurationManager;
import org.gudy.azureus2.core3.config.StringIterator;
import org.gudy.azureus2.core3.config.StringList;
import org.gudy.azureus2.core3.config.impl.ConfigurationDefaults;
import org.gudy.azureus2.core3.internat.LocaleTorrentUtil;
import org.gudy.azureus2.core3.internat.LocaleUtilDecoder;
import org.gudy.azureus2.core3.internat.MessageText;
import org.gudy.azureus2.core3.peer.PEPeerSource;
import org.gudy.azureus2.core3.torrent.TOTorrent;
import org.gudy.azureus2.core3.torrent.TOTorrentException;
import org.gudy.azureus2.core3.torrent.TOTorrentFactory;
import org.gudy.azureus2.core3.torrent.impl.TorrentOpenFileOptions;
import org.gudy.azureus2.core3.torrent.impl.TorrentOpenOptions;
import org.gudy.azureus2.core3.util.*;
import org.gudy.azureus2.plugins.PluginInterface;
import org.gudy.azureus2.plugins.ui.UIInputReceiver;
import org.gudy.azureus2.plugins.ui.UIInputReceiverListener;
import org.gudy.azureus2.plugins.ui.tables.TableColumn;
import org.gudy.azureus2.plugins.ui.tables.TableColumnCreationListener;
import org.gudy.azureus2.ui.swt.*;
import org.gudy.azureus2.ui.swt.config.generic.GenericIntParameter;
import org.gudy.azureus2.ui.swt.config.generic.GenericParameterAdapter;
import org.gudy.azureus2.ui.swt.mainwindow.Colors;
import org.gudy.azureus2.ui.swt.mainwindow.SWTThread;
import org.gudy.azureus2.ui.swt.mainwindow.TorrentOpener;
import org.gudy.azureus2.ui.swt.maketorrent.MultiTrackerEditor;
import org.gudy.azureus2.ui.swt.maketorrent.TrackerEditorListener;
import org.gudy.azureus2.ui.swt.shells.MessageBoxShell;
import org.gudy.azureus2.ui.swt.views.table.TableViewSWT;
import org.gudy.azureus2.ui.swt.views.table.TableViewSWTMenuFillListener;
import org.gudy.azureus2.ui.swt.views.table.impl.TableViewFactory;
import org.gudy.azureus2.ui.swt.views.tableitems.mytorrents.TrackerNameItem;
import org.gudy.azureus2.ui.swt.views.utils.TagUIUtils;
import com.aelitis.azureus.core.AzureusCore;
import com.aelitis.azureus.core.AzureusCoreFactory;
import com.aelitis.azureus.core.tag.Tag;
import com.aelitis.azureus.core.tag.TagFeatureFileLocation;
import com.aelitis.azureus.core.tag.TagManagerFactory;
import com.aelitis.azureus.core.tag.TagType;
import com.aelitis.azureus.core.tag.TagTypeListener;
import com.aelitis.azureus.core.util.RegExUtil;
import com.aelitis.azureus.ui.IUIIntializer;
import com.aelitis.azureus.ui.InitializerListener;
import com.aelitis.azureus.ui.UIFunctionsManager;
import com.aelitis.azureus.ui.common.table.TableRowCore;
import com.aelitis.azureus.ui.common.table.TableSelectionListener;
import com.aelitis.azureus.ui.common.table.TableViewFilterCheck;
import com.aelitis.azureus.ui.common.table.impl.TableColumnManager;
import com.aelitis.azureus.ui.common.updater.UIUpdatable;
import com.aelitis.azureus.ui.swt.imageloader.ImageLoader;
import com.aelitis.azureus.ui.swt.shells.main.UIFunctionsImpl;
import com.aelitis.azureus.ui.swt.skin.*;
import com.aelitis.azureus.ui.swt.skin.SWTSkinButtonUtility.ButtonListenerAdapter;
import com.aelitis.azureus.ui.swt.uiupdater.UIUpdaterSWT;
import com.aelitis.azureus.ui.swt.views.skin.SkinnedDialog;
import com.aelitis.azureus.ui.swt.views.skin.SkinnedDialog.SkinnedDialogClosedListener;
import com.aelitis.azureus.ui.swt.views.skin.StandardButtonsArea;
@SuppressWarnings({
"unchecked",
"rawtypes"
})
public class OpenTorrentOptionsWindow
implements UIUpdatable
{
private static final Map<HashWrapper,OpenTorrentOptionsWindow> active_windows = new HashMap<HashWrapper, OpenTorrentOptionsWindow>();
private final static class FileStatsCacheItem
{
boolean exists;
long freeSpace;
public FileStatsCacheItem(final File f) {
exists = f.exists();
if (exists)
freeSpace = FileUtil.getUsableSpace(f);
else
freeSpace = -1;
}
}
private final static class Partition
{
long bytesToConsume = 0;
long freeSpace = 0;
final File root;
public Partition(File root) {
this.root = root;
}
}
private final static String PARAM_DEFSAVEPATH = "Default save path";
private final static String[] queueLocations = {
"first",
"last"
};
private final static String[] startModes = {
"queued",
"stopped",
"forceStarted",
"seeding"
};
public static final String TABLEID_TORRENTS = "OpenTorrentTorrent";
public static final String TABLEID_FILES = "OpenTorrentFile";
public static void main(String[] args) {
try{
SWTThread.createInstance(
new IUIIntializer() {
public void stopIt(boolean isForRestart, boolean isCloseAreadyInProgress) {
// TODO Auto-generated method stub
}
public void runInSWTThread() {
// TODO Auto-generated method stub
}
public void run() {
AzureusCore core = AzureusCoreFactory.create();
core.start();
UIConfigDefaultsSWT.initialize();
Colors.getInstance();
UIFunctionsImpl uiFunctions = new UIFunctionsImpl(null);
UIFunctionsManager.setUIFunctions(uiFunctions);
File file1 = new File("C:\\temp\\test.torrent");
File file2 = new File("C:\\temp\\test1.torrent");
TOTorrent torrent1 = null;
try {
torrent1 = TOTorrentFactory.deserialiseFromBEncodedFile(file1);
} catch (TOTorrentException e) {
e.printStackTrace();
};
TOTorrent torrent2 = null;
try {
torrent2 = TOTorrentFactory.deserialiseFromBEncodedFile(file2);
} catch (TOTorrentException e) {
e.printStackTrace();
};
COConfigurationManager.setParameter( ConfigurationDefaults.CFG_TORRENTADD_OPENOPTIONS_SEP, false );
COConfigurationManager.setParameter( "User Mode", 2 );
addTorrent( new TorrentOpenOptions(null, torrent1, false));
addTorrent( new TorrentOpenOptions(null, torrent2, false));
}
public void reportPercent(int percent) {
// TODO Auto-generated method stub
}
public void reportCurrentTask(String currentTaskString) {
// TODO Auto-generated method stub
}
public void removeListener(InitializerListener listener) {
// TODO Auto-generated method stub
}
public void initializationComplete() {
// TODO Auto-generated method stub
}
public void increaseProgress() {
// TODO Auto-generated method stub
}
public void addListener(InitializerListener listener) {
// TODO Auto-generated method stub
}
public void abortProgress() {
// TODO Auto-generated method stub
}
});
}catch( Throwable e ){
e.printStackTrace();
}
}
private SkinnedDialog dlg;
private ImageLoader image_loader;
private SWTSkinObjectSash sash_object;
private StackLayout expand_stack;
private Composite expand_stack_area;
private StandardButtonsArea buttonsArea;
private boolean window_initialised;
private Button buttonTorrentUp;
private Button buttonTorrentDown;
private Button buttonTorrentRemove;
private List<String> images_to_dispose = new ArrayList<String>();
private TableViewSWT<OpenTorrentInstance> tvTorrents;
private Label torrents_info_label;
private OpenTorrentInstanceListener optionListener;
private List<OpenTorrentInstance> open_instances = new ArrayList<OpenTorrentOptionsWindow.OpenTorrentInstance>();
private List<OpenTorrentInstance> selected_instances = new ArrayList<OpenTorrentOptionsWindow.OpenTorrentInstance>();
private OpenTorrentInstance multi_selection_instance;
public static OpenTorrentOptionsWindow
addTorrent(
final TorrentOpenOptions torrentOptions )
{
TOTorrent torrent = torrentOptions.getTorrent();
try{
final HashWrapper hw = torrent.getHashWrapper();
synchronized( active_windows ){
final OpenTorrentOptionsWindow existing = active_windows.get( hw );
if ( existing != null ){
Utils.execSWTThread(new AERunnable() {
public void runSupport() {
existing.swt_activate();
}
});
return( existing );
}
boolean separate_dialogs = COConfigurationManager.getBooleanParameter( ConfigurationDefaults.CFG_TORRENTADD_OPENOPTIONS_SEP );
if ( !separate_dialogs ){
if ( active_windows.size() > 0 ){
final OpenTorrentOptionsWindow reuse_window = active_windows.values().iterator().next();
active_windows.put( hw, reuse_window );
Utils.execSWTThread(new AERunnable() {
public void runSupport()
{
reuse_window.swt_addTorrent( hw, torrentOptions );
}
});
return( reuse_window );
}
}
final OpenTorrentOptionsWindow new_window = new OpenTorrentOptionsWindow();
active_windows.put( hw, new_window );
Utils.execSWTThread(new AERunnable() {
public void runSupport() {
new_window.swt_addTorrent( hw, torrentOptions );
}
});
return( new_window );
}
}catch( Throwable e ){
Debug.out( e );
return( null );
}
}
private
OpenTorrentOptionsWindow()
{
image_loader = SWTSkinFactory.getInstance().getImageLoader(SWTSkinFactory.getInstance().getSkinProperties());
optionListener =
new OpenTorrentInstanceListener()
{
public void
instanceChanged(
OpenTorrentInstance instance )
{
updateInstanceInfo();
}
};
}
protected void
swt_addTorrent(
HashWrapper hash,
TorrentOpenOptions torrentOptions )
{
try{
if ( dlg == null ){
dlg = new SkinnedDialog("skin3_dlg_opentorrent_options", "shell",
SWT.RESIZE | SWT.MAX | SWT.DIALOG_TRIM);
final SWTSkin skin_outter = dlg.getSkin();
SWTSkinObject so;
if (COConfigurationManager.hasParameter(ConfigurationDefaults.CFG_TORRENTADD_OPENOPTIONS, true)) {
so = skin_outter.getSkinObject("showagain-area");
if (so != null) {
so.setVisible(false);
}
}
SWTSkinObject soButtonArea = skin_outter.getSkinObject("button-area");
if (soButtonArea instanceof SWTSkinObjectContainer) {
buttonsArea = new StandardButtonsArea() {
protected void clicked(int intValue) {
if (intValue == SWT.OK) {
boolean all_ok = true;
AsyncDispatcher dispatcher = new AsyncDispatcher();
for ( final OpenTorrentInstance instance: new ArrayList<OpenTorrentInstance>( open_instances )){
String dataDir = instance.cmbDataDir.getText();
if ( !instance.okPressed(dataDir)){
all_ok = false;
}else{
// serialise additions in correct order
dispatcher.dispatch(
new AERunnable()
{
public void
runSupport()
{
TorrentOpener.addTorrent( instance.getOptions());
}
});
removeInstance( instance );
}
}
if ( all_ok ){
if (dlg != null){
dlg.close();
}
}
}else if (dlg != null){
dlg.close();
}
}
};
buttonsArea.setButtonIDs(new String[] {
MessageText.getString("Button.ok"),
MessageText.getString("Button.cancel")
});
buttonsArea.setButtonVals(new Integer[] {
SWT.OK,
SWT.CANCEL
});
buttonsArea.swt_createButtons(((SWTSkinObjectContainer) soButtonArea).getComposite());
}
sash_object = (SWTSkinObjectSash)skin_outter.getSkinObject("multi-sash");
SWTSkinObjectContainer select_area = (SWTSkinObjectContainer)skin_outter.getSkinObject( "torrents-table" );
setupTVTorrents( select_area.getComposite());
SWTSkinObjectContainer torrents_info = (SWTSkinObjectContainer)skin_outter.getSkinObject( "torrents-info" );
Composite info_area = torrents_info.getComposite();
info_area.setLayout( new GridLayout());
torrents_info_label = new Label( info_area, SWT.NULL );
torrents_info_label.setLayoutData( new GridData( GridData.FILL_HORIZONTAL ));
sash_object.setVisible( false );
sash_object.setAboveVisible( false );
so = skin_outter.getSkinObject("expand-area");
expand_stack_area = ((SWTSkinObjectContainer)so).getComposite();
expand_stack = new StackLayout();
expand_stack_area.setLayout( expand_stack );
Composite expand_area = new Composite( expand_stack_area, SWT.NULL );
expand_area.setLayout( new FormLayout());
expand_stack.topControl = expand_area;
OpenTorrentInstance instance = new OpenTorrentInstance( hash, expand_area, torrentOptions, optionListener );
addInstance( instance );
selected_instances.add( instance );
UIUpdaterSWT.getInstance().addUpdater(this);
setupShowAgainOptions(skin_outter);
/*
* The bring-to-front logic for torrent addition is controlled by other parts of the code so we don't
* want the dlg to override this behaviour (main example here is torrents passed from, say, a browser,
* and the user has disabled the 'show vuze on external torrent add' feature)
*/
dlg.open("otow",false);
synchronized( active_windows ){
int num_active_windows = active_windows.size();
if ( num_active_windows > 1 ){
int max_x = 0;
int max_y = 0;
for ( OpenTorrentOptionsWindow window: active_windows.values()){
if ( window == this || !window.isInitialised()){
continue;
}
Rectangle rect = window.getBounds();
max_x = Math.max( max_x, rect.x );
max_y = Math.max( max_y, rect.y );
}
Shell shell = dlg.getShell();
Rectangle rect = shell.getBounds();
rect.x = max_x + 16;
rect.y = max_y + 16;
shell.setBounds( rect );
Utils.verifyShellRect( shell, true );
}
}
dlg.addCloseListener(new SkinnedDialogClosedListener() {
public void skinDialogClosed(SkinnedDialog dialog) {
try{
dispose();
}finally{
synchronized( active_windows ){
Iterator<OpenTorrentOptionsWindow> it = active_windows.values().iterator();
while( it.hasNext()){
if ( it.next() == OpenTorrentOptionsWindow.this ){
it.remove();
}
}
}
}
}
});
window_initialised = true;
}else{
Composite expand_area = new Composite( expand_stack_area, SWT.NULL );
expand_area.setLayout( new FormLayout());
OpenTorrentInstance instance = new OpenTorrentInstance( hash, expand_area, torrentOptions, optionListener );
addInstance( instance );
if ( !sash_object.isVisible()){
sash_object.setVisible( true );
sash_object.setAboveVisible( true );
Utils.execSWTThreadLater(
0,
new Runnable()
{
public void
run()
{
tvTorrents.processDataSourceQueueSync();
List<TableRowCore> rows = new ArrayList<TableRowCore>();
for ( OpenTorrentInstance instance: selected_instances ){
TableRowCore row = tvTorrents.getRow( instance );
if ( row != null ){
rows.add( row );
}
}
if ( rows.size() > 0 ){
tvTorrents.setSelectedRows( rows.toArray( new TableRowCore[ rows.size() ]));
}
}
});
}
}
}catch( Throwable e ){
Debug.out( e );
synchronized( active_windows ){
active_windows.remove( hash );
}
}
}
private boolean
isInitialised()
{
return( window_initialised );
}
private void setupShowAgainOptions(SWTSkin skin) {
SWTSkinObjectCheckbox soNever = (SWTSkinObjectCheckbox) skin.getSkinObject("showagain-never");
SWTSkinObjectCheckbox soAlways = (SWTSkinObjectCheckbox) skin.getSkinObject("showagain-always");
SWTSkinObjectCheckbox soMany = (SWTSkinObjectCheckbox) skin.getSkinObject("showagain-manyfile");
String showAgainMode = COConfigurationManager.getStringParameter(ConfigurationDefaults.CFG_TORRENTADD_OPENOPTIONS);
boolean hasUserChosen = COConfigurationManager.hasParameter(ConfigurationDefaults.CFG_TORRENTADD_OPENOPTIONS, true);
if (soNever != null) {
soNever.addSelectionListener(new SWTSkinCheckboxListener() {
public void checkboxChanged(SWTSkinObjectCheckbox so, boolean checked) {
COConfigurationManager.setParameter(ConfigurationDefaults.CFG_TORRENTADD_OPENOPTIONS, ConfigurationDefaults.CFG_TORRENTADD_OPENOPTIONS_NEVER);
}
});
if (hasUserChosen) {
soNever.setChecked(ConfigurationDefaults.CFG_TORRENTADD_OPENOPTIONS_NEVER.equals(showAgainMode));
}
}
if (soAlways != null) {
soAlways.addSelectionListener(new SWTSkinCheckboxListener() {
public void checkboxChanged(SWTSkinObjectCheckbox so, boolean checked) {
COConfigurationManager.setParameter(ConfigurationDefaults.CFG_TORRENTADD_OPENOPTIONS, ConfigurationDefaults.CFG_TORRENTADD_OPENOPTIONS_ALWAYS);
}
});
if (hasUserChosen) {
soAlways.setChecked(ConfigurationDefaults.CFG_TORRENTADD_OPENOPTIONS_ALWAYS.equals(showAgainMode));
}
}
if (soMany != null) {
soMany.addSelectionListener(new SWTSkinCheckboxListener() {
public void checkboxChanged(SWTSkinObjectCheckbox so, boolean checked) {
COConfigurationManager.setParameter(ConfigurationDefaults.CFG_TORRENTADD_OPENOPTIONS, ConfigurationDefaults.CFG_TORRENTADD_OPENOPTIONS_MANY);
}
});
if (hasUserChosen) {
soMany.setChecked(ConfigurationDefaults.CFG_TORRENTADD_OPENOPTIONS_MANY.equals(showAgainMode));
}
}
}
private void
setupTVTorrents(
Composite parent )
{
GridLayout layout = new GridLayout();
layout.marginWidth = layout.marginHeight = 0;
layout.horizontalSpacing = layout.verticalSpacing = 0;
parent.setLayout( layout );
GridData gd;
// table
Composite table_area = new Composite( parent, SWT.NULL );
layout = new GridLayout();
layout.marginWidth = layout.marginHeight = 0;
layout.horizontalSpacing = layout.verticalSpacing = 0;
table_area.setLayout( layout );
gd = new GridData( GridData.FILL_BOTH );
table_area.setLayoutData( gd );
// toolbar area
Composite button_area = new Composite( parent, SWT.NULL );
layout = new GridLayout(5,false);
layout.marginWidth = layout.marginHeight = 0;
layout.horizontalSpacing = layout.verticalSpacing = 0;
layout.marginTop = 5;
button_area.setLayout( layout);
gd = new GridData( GridData.FILL_HORIZONTAL );
button_area.setLayoutData( gd );
Label label = new Label( button_area, SWT.NULL );
gd = new GridData( GridData.FILL_HORIZONTAL );
label.setLayoutData( gd );
buttonTorrentUp = new Button(button_area, SWT.PUSH);
buttonTorrentUp.setImage( loadImage( "image.toolbar.up" ));
buttonTorrentUp.setToolTipText(MessageText.getString("Button.moveUp"));
buttonTorrentUp.addListener(SWT.Selection, new Listener() {
public void handleEvent(Event event) {
List<OpenTorrentInstance> selected = (List<OpenTorrentInstance>)(Object)tvTorrents.getSelectedDataSources();
if ( selected.size() > 1 ){
Collections.sort(
selected,
new Comparator<OpenTorrentInstance>()
{
public int
compare(
OpenTorrentInstance o1,
OpenTorrentInstance o2)
{
return( o1.getIndex() - o2.getIndex());
}
});
}
boolean modified = false;
for ( OpenTorrentInstance instance: selected ){
int index = instance.getIndex();
if ( index > 0 ){
open_instances.remove( instance );
open_instances.add( index-1, instance );
modified = true;
}
}
if ( modified ){
swt_updateTVTorrentButtons();
refreshTVTorrentIndexes();
}
}});
buttonTorrentDown = new Button(button_area, SWT.PUSH);
buttonTorrentDown.setImage( loadImage( "image.toolbar.down" ));
buttonTorrentDown.setToolTipText(MessageText.getString("Button.moveDown"));
buttonTorrentDown.addListener(SWT.Selection, new Listener() {
public void handleEvent(Event event) {
List<OpenTorrentInstance> selected = (List<OpenTorrentInstance>)(Object)tvTorrents.getSelectedDataSources();
if ( selected.size() > 1 ){
Collections.sort(
selected,
new Comparator<OpenTorrentInstance>()
{
public int
compare(
OpenTorrentInstance o1,
OpenTorrentInstance o2)
{
return( o2.getIndex() - o1.getIndex());
}
});
}
boolean modified = false;
for ( Object obj: selected ){
OpenTorrentInstance instance = (OpenTorrentInstance)obj;
int index = instance.getIndex();
if ( index < open_instances.size() - 1 ){
open_instances.remove( instance );
open_instances.add( index+1, instance );
modified = true;
}
}
if ( modified ){
swt_updateTVTorrentButtons();
refreshTVTorrentIndexes();
}
}});
buttonTorrentRemove = new Button(button_area, SWT.PUSH);
buttonTorrentRemove.setToolTipText(MessageText.getString("OpenTorrentWindow.torrent.remove"));
buttonTorrentRemove.setImage( loadImage( "image.toolbar.remove" ));
buttonTorrentRemove.addListener(SWT.Selection, new Listener() {
public void handleEvent(Event event) {
List<Object> selected = tvTorrents.getSelectedDataSources();
for ( Object obj: selected ){
OpenTorrentInstance instance = (OpenTorrentInstance)obj;
removeInstance( instance );
}
}});
buttonTorrentUp.setEnabled( false );
buttonTorrentDown.setEnabled( false );
buttonTorrentRemove.setEnabled( false );
label = new Label( button_area, SWT.NULL );
gd = new GridData( GridData.FILL_HORIZONTAL );
label.setLayoutData( gd );
TableColumnManager tcm = TableColumnManager.getInstance();
if (tcm.getDefaultColumnNames(TABLEID_TORRENTS) == null) {
tcm.registerColumn(OpenTorrentInstance.class,
TableColumnOTOT_Position.COLUMN_ID, new TableColumnCreationListener() {
public void tableColumnCreated(TableColumn column) {
new TableColumnOTOT_Position(column);
}
});
tcm.registerColumn(OpenTorrentInstance.class,
TableColumnOTOT_Name.COLUMN_ID, new TableColumnCreationListener() {
public void tableColumnCreated(TableColumn column) {
new TableColumnOTOT_Name(column);
}
});
tcm.registerColumn(OpenTorrentInstance.class,
TableColumnOTOT_Size.COLUMN_ID, new TableColumnCreationListener() {
public void tableColumnCreated(TableColumn column) {
new TableColumnOTOT_Size(column);
}
});
tcm.setDefaultColumnNames(TABLEID_TORRENTS, new String[] {
TableColumnOTOT_Position.COLUMN_ID,
TableColumnOTOT_Name.COLUMN_ID,
TableColumnOTOT_Size.COLUMN_ID,
});
tcm.setDefaultSortColumnName(TABLEID_TORRENTS, TableColumnOTOT_Position.COLUMN_ID);
}
tvTorrents = TableViewFactory.createTableViewSWT(OpenTorrentInstance.class,
TABLEID_TORRENTS, TABLEID_TORRENTS, null, "#", SWT.BORDER
| SWT.FULL_SELECTION | SWT.MULTI );
tvTorrents.initialize( table_area );
tvTorrents.setRowDefaultHeight(20);
tvTorrents.addMenuFillListener(
new TableViewSWTMenuFillListener()
{
public void
fillMenu(
String sColumnName,
Menu menu )
{
final List<Object> selected = tvTorrents.getSelectedDataSources();
if ( selected.size() > 0 ){
final List<OpenTorrentInstance> instances = new ArrayList<OpenTorrentOptionsWindow.OpenTorrentInstance>( selected.size());
for ( Object o: selected ){
instances.add((OpenTorrentInstance)o );
}
MenuItem item = new MenuItem(menu, SWT.PUSH);
Messages.setLanguageText(item, "OpenTorrentWindow.fileList.changeDestination");
item.addSelectionListener(
new SelectionAdapter()
{
public void
widgetSelected(
SelectionEvent e )
{
for ( Object obj: selected ){
OpenTorrentInstance instance = (OpenTorrentInstance)obj;
instance.setSavePath();
}
}
});
new MenuItem(menu, SWT.SEPARATOR);
item = new MenuItem(menu, SWT.PUSH);
Messages.setLanguageText(item, "Button.remove");
item.addSelectionListener(
new SelectionAdapter()
{
public void
widgetSelected(
SelectionEvent e )
{
for ( Object obj: selected ){
OpenTorrentInstance instance = (OpenTorrentInstance)obj;
removeInstance( instance );
}
}
});
new MenuItem(menu, SWT.SEPARATOR);
}
}
public void
addThisColumnSubMenu(
String sColumnName,
Menu menuThisColumn)
{
}
});
tvTorrents.addSelectionListener(
new TableSelectionListener()
{
public void
selected(
TableRowCore[] rows_not_used )
{
TableRowCore[] rows = tvTorrents.getSelectedRows();
List<OpenTorrentInstance> instances = new ArrayList<OpenTorrentOptionsWindow.OpenTorrentInstance>();
for ( TableRowCore row: rows ){
instances.add((OpenTorrentInstance)row.getDataSource());
}
selectInstances( instances );
updateButtons();
}
public void mouseExit(TableRowCore row) {
}
public void mouseEnter(TableRowCore row) {
}
public void focusChanged(TableRowCore focus) {
}
public void
deselected(TableRowCore[] rows)
{
selected( rows );
}
private void
updateButtons()
{
Utils.execSWTThread(
new Runnable()
{
public void
run()
{
swt_updateTVTorrentButtons();
}
});
}
public void defaultSelected(TableRowCore[] rows, int stateMask) {
}
}, false);
}
private void
addInstance(
OpenTorrentInstance instance )
{
open_instances.add( instance );
updateDialogTitle();
instance.initialize();
tvTorrents.addDataSources( new OpenTorrentInstance[]{ instance });
updateInstanceInfo();
swt_updateTVTorrentButtons();
}
private void
selectInstance(
OpenTorrentInstance instance )
{
List<OpenTorrentInstance> instances = new ArrayList<OpenTorrentOptionsWindow.OpenTorrentInstance>();
if ( instance != null ){
instances.add( instance );
}
selectInstances( instances );
}
private void
selectInstances(
List<OpenTorrentInstance> _instances )
{
if ( _instances.equals( selected_instances )){
return;
}
final List<OpenTorrentInstance> instances = new ArrayList<OpenTorrentInstance>( _instances );
Iterator<OpenTorrentInstance> it = instances.iterator();
while( it.hasNext()){
if ( !open_instances.contains( it.next())){
it.remove();
}
}
if ( instances.size() == 0 ){
if ( selected_instances.size() > 0 && open_instances.contains( selected_instances.get(0))){
instances.add( selected_instances.get(0));
}else if ( open_instances.size() > 0 ){
instances.add( open_instances.get(0));
}
}
selected_instances.clear();
selected_instances.addAll( instances );
Utils.execSWTThread(
new Runnable()
{
public void
run()
{
if ( multi_selection_instance != null ){
multi_selection_instance.getComposite().dispose();
multi_selection_instance = null;
}
if ( instances.size() == 1 ){
OpenTorrentInstance first_instance = instances.get(0);
expand_stack.topControl = first_instance.getComposite();
expand_stack_area.layout(true);
first_instance.layout();
}else{
Composite expand_area = new Composite( expand_stack_area, SWT.NULL );
expand_area.setLayout( new FormLayout());
List<TorrentOpenOptions> toos = new ArrayList<TorrentOpenOptions>();
for ( OpenTorrentInstance oti: instances ){
toos.add( oti.getOptions());
}
multi_selection_instance = new OpenTorrentInstance( expand_area, toos, optionListener );
multi_selection_instance.initialize();
expand_stack.topControl = multi_selection_instance.getComposite();
expand_stack_area.layout(true);
multi_selection_instance.layout();
}
}
});
List<TableRowCore> rows = new ArrayList<TableRowCore>();
for ( OpenTorrentInstance instance: instances ){
TableRowCore row = tvTorrents.getRow( instance );
if ( row != null ){
rows.add( row );
}
}
tvTorrents.setSelectedRows( rows.toArray( new TableRowCore[rows.size()]));
}
private void
removeInstance(
OpenTorrentInstance instance )
{
synchronized( active_windows ){
active_windows.remove( instance.getHash());
}
int index = open_instances.indexOf( instance );
open_instances.remove( instance );
updateDialogTitle();
tvTorrents.removeDataSource( instance );
instance.getComposite().dispose();
updateInstanceInfo();
if ( selected_instances.contains( instance ) && selected_instances.size() > 1 ){
List<OpenTorrentInstance> temp = new ArrayList<OpenTorrentOptionsWindow.OpenTorrentInstance>( selected_instances );
temp.remove( instance );
selectInstances( temp );
}else{
int num_instances = open_instances.size();
if ( num_instances > index ){
selectInstance( open_instances.get( index ));
}else if ( num_instances > 0 ){
selectInstance( open_instances.get( num_instances-1 ));
}else{
selectInstance( null );
}
}
swt_updateTVTorrentButtons();
refreshTVTorrentIndexes();
instance.dispose();
}
private void
updateDialogTitle()
{
int num = open_instances.size();
String text;
if ( num == 1 ){
text = open_instances.get(0).getOptions().getTorrentName();
}else{
text = MessageText.getString("label.num.torrents",new String[]{ String.valueOf( open_instances.size())});
}
dlg.setTitle(MessageText.getString("OpenTorrentOptions.title") + " [" + text + "]");
}
private void
swt_updateTVTorrentButtons()
{
List<Object> selected = tvTorrents.getSelectedDataSources();
buttonTorrentRemove.setEnabled( selected.size() > 0 );
if ( selected.size() > 0 ){
int min_index = Integer.MAX_VALUE;
int max_index = -1;
for ( Object obj: selected ){
OpenTorrentInstance instance = (OpenTorrentInstance)obj;
int index = instance.getIndex();
min_index = Math.min( min_index, index );
max_index = Math.max( max_index, index );
}
buttonTorrentUp.setEnabled( min_index > 0 );
buttonTorrentDown.setEnabled( max_index < open_instances.size()-1);
}else{
buttonTorrentUp.setEnabled( false );
buttonTorrentDown.setEnabled( false );
}
}
private void
refreshTVTorrentIndexes()
{
Utils.execSWTThreadLater(
0,
new Runnable()
{
public void
run()
{
tvTorrents.columnInvalidate( "#" );
tvTorrents.refreshTable( true );
}
});
}
private void
updateInstanceInfo()
{
if ( torrents_info_label == null ){
return;
}
long total_size = 0;
long selected_size = 0;
for ( OpenTorrentInstance instance: open_instances ){
total_size += instance.getOptions().getTorrent().getSize();
selected_size += instance.getSelectedDataSize();
}
String sel_str = DisplayFormatters.formatByteCountToKiBEtc(selected_size);
String tot_str = DisplayFormatters.formatByteCountToKiBEtc(total_size);
String text;
if ( sel_str.equals( tot_str )){
text = MessageText.getString("label.n.will.be.downloaded", new String[] { tot_str });
}else{
text = MessageText.getString("OpenTorrentWindow.filesInfo", new String[] { sel_str, tot_str });
}
torrents_info_label.setText( text );
}
public void
updateUI()
{
if ( tvTorrents != null ){
tvTorrents.refreshTable( false );
}
for( OpenTorrentInstance instance: open_instances ){
instance.updateUI();
}
if ( multi_selection_instance != null ){
multi_selection_instance.updateUI();
}
}
public String getUpdateUIName() {
return null;
}
private void
swt_activate()
{
Shell shell = dlg.getShell();
if ( !shell.isDisposed()){
shell.forceActive();
}
}
private Rectangle
getBounds()
{
return( dlg.getShell().getBounds());
}
private Image
loadImage(
String key )
{
Image img = image_loader.getImage( key );
if ( img != null ){
images_to_dispose.add( key );
}
return( img );
}
private void
unloadImage(
String key )
{
image_loader.releaseImage( key );
}
protected void
dispose()
{
UIUpdaterSWT.getInstance().removeUpdater(this);
for ( OpenTorrentInstance instance: open_instances ){
instance.dispose();
}
for ( String key: images_to_dispose ){
unloadImage( key );
}
images_to_dispose.clear();
tvTorrents.delete();
}
protected class
OpenTorrentInstance
implements TableViewFilterCheck<TorrentOpenFileOptions>
{
final private HashWrapper hash;
final private TorrentOpenOptions torrentOptions;
final private List<TorrentOpenOptions> torrentOptionsMulti;
final private OpenTorrentInstanceListener changeListener;
final private Composite parent;
final private Shell shell;
private SWTSkin skin;
/* prevents loop of modifications */
protected boolean bSkipDataDirModify = false;
private Button btnSwarmIt;
private Combo cmbDataDir;
private Combo cmbQueueLocation;
private Combo cmbStartMode;
private StringList dirList;
private volatile boolean diskFreeInfoRefreshPending = false;
private volatile boolean diskFreeInfoRefreshRunning = false;
private Composite diskspaceComp;
private long currentSelectedDataSize;
private final Map fileStatCache = new WeakHashMap(20);
private final Map parentToRootCache = new WeakHashMap(20);
private SWTSkinObjectExpandItem soExpandItemFiles;
private SWTSkinObjectExpandItem soExpandItemSaveTo;
private SWTSkinObjectExpandItem soExpandItemTorrentInfo;
private SWTSkinObjectText soFileAreaInfo;
private TableViewSWT<TorrentOpenFileOptions> tvFiles;
private SWTSkinObjectExpandItem soStartOptionsExpandItem;
//private SWTSkinObjectExpandItem soExpandItemPeer;
private AtomicInteger settingToDownload = new AtomicInteger(0);
private Button btnSelectAll;
private Button btnMarkSelected;
private Button btnUnmarkSelected;
private Button btnRename;
private Button btnRetarget;
private
OpenTorrentInstance(
HashWrapper _hash,
Composite _parent,
TorrentOpenOptions _torrentOptions,
OpenTorrentInstanceListener _changeListener )
{
hash = _hash;
parent = _parent;
torrentOptions = _torrentOptions;
torrentOptionsMulti = new ArrayList<TorrentOpenOptions>();
changeListener = _changeListener;
torrentOptionsMulti.add( torrentOptions );
shell = parent.getShell();
torrentOptions.addListener(new TorrentOpenOptions.FileListener() {
public void toDownloadChanged(TorrentOpenFileOptions fo, boolean toDownload) {
TableRowCore row = tvFiles.getRow(fo);
if (row != null) {
row.invalidate(true);
row.refresh(true);
}
if ( settingToDownload.get() == 0 ){
updateFileButtons();
updateSize();
}
}
public void priorityChanged(TorrentOpenFileOptions fo, int priority) {
TableRowCore row = tvFiles.getRow(fo);
if (row != null) {
row.invalidate(true);
row.refresh(true);
}
}
public void parentDirChanged(){
if ( torrentOptions != null && cmbDataDir != null ){
String toText = torrentOptions.getParentDir();
String text = cmbDataDir.getText();
if ( !text.equals( toText )){
cmbDataDir.setText( toText );
}
}
}
});
}
private
OpenTorrentInstance(
Composite _parent,
List<TorrentOpenOptions> _torrentOptionsMulti,
OpenTorrentInstanceListener _changeListener )
{
hash = null;
parent = _parent;
torrentOptions = null;
torrentOptionsMulti = new ArrayList<TorrentOpenOptions>( _torrentOptionsMulti );
changeListener = _changeListener;
shell = parent.getShell();
}
private HashWrapper
getHash()
{
return( hash );
}
protected TorrentOpenOptions
getOptions()
{
return( torrentOptions );
}
protected int
getIndex()
{
return( open_instances.indexOf( this ));
}
protected Composite
getComposite()
{
return( parent );
}
private void
initialize()
{
skin = SWTSkinFactory.getNonPersistentInstance(
getClass().getClassLoader(),
"com/aelitis/azureus/ui/skin", "skin3_dlg_opentorrent_options_instance.properties" );
skin.initialize( parent, "expandview");
if ( torrentOptions != null ){
SWTSkinObject so = skin.getSkinObject("filearea-table");
if (so instanceof SWTSkinObjectContainer) {
setupTVFiles((SWTSkinObjectContainer) so, (SWTSkinObjectTextbox)skin.getSkinObject("filearea-filter"));
}
so = skin.getSkinObject("filearea-buttons");
if (so instanceof SWTSkinObjectContainer) {
setupFileAreaButtons((SWTSkinObjectContainer) so);
}
}
SWTSkinObject so = skin.getSkinObject("disk-space");
if (so instanceof SWTSkinObjectContainer) {
diskspaceComp = (Composite) so.getControl();
GridLayout gl = new GridLayout(2, false);
gl.marginHeight = gl.marginWidth = 0;
diskspaceComp.setLayout(gl);
}
if ( torrentOptions != null ){
so = skin.getSkinObject("filearea-info");
if (so instanceof SWTSkinObjectText) {
setupFileAreaInfo((SWTSkinObjectText) so);
}
so = skin.getSkinObject("start-options");
if (so instanceof SWTSkinObjectExpandItem) {
setupStartOptions((SWTSkinObjectExpandItem) so);
}
so = skin.getSkinObject("peer-sources");
if (so instanceof SWTSkinObjectContainer) {
setupPeerSourcesOptions((SWTSkinObjectContainer) so);
}
so = skin.getSkinObject("trackers");
if (so instanceof SWTSkinObjectContainer) {
setupTrackers((SWTSkinObjectContainer) so);
}
so = skin.getSkinObject("updownlimit");
if (so instanceof SWTSkinObjectContainer) {
setupUpDownLimitOption((SWTSkinObjectContainer) so);
}
so = skin.getSkinObject("ipfilter");
if (so instanceof SWTSkinObjectContainer) {
setupIPFilterOption((SWTSkinObjectContainer) so);
}
}
SWTSkinObject so1 = skin.getSkinObject("saveto-textarea");
SWTSkinObject so2 = skin.getSkinObject("saveto-browse");
if ((so1 instanceof SWTSkinObjectContainer)
&& (so2 instanceof SWTSkinObjectButton)) {
setupSaveLocation((SWTSkinObjectContainer) so1, (SWTSkinObjectButton) so2);
}
so = skin.getSkinObject("expanditem-saveto");
if (so instanceof SWTSkinObjectExpandItem) {
soExpandItemSaveTo = (SWTSkinObjectExpandItem) so;
}
if ( torrentOptions != null ){
so = skin.getSkinObject("expanditem-files");
if (so instanceof SWTSkinObjectExpandItem) {
soExpandItemFiles = (SWTSkinObjectExpandItem) so;
}
/*
so = skin.getSkinObject("expanditem-peer");
if (so instanceof SWTSkinObjectExpandItem) {
soExpandItemPeer = (SWTSkinObjectExpandItem) so;
}
*/
so = skin.getSkinObject("expanditem-torrentinfo");
if (so instanceof SWTSkinObjectExpandItem) {
soExpandItemTorrentInfo = (SWTSkinObjectExpandItem) so;
soExpandItemTorrentInfo.setText(MessageText.getString("OpenTorrentOptions.header.torrentinfo")
+ ": " + torrentOptions.getTorrentName());
}
setupInfoFields(skin);
updateStartOptionsHeader();
cmbDataDirChanged();
updateSize();
}else{
cmbDataDirChanged();
}
skin.layout();
}
private void
layout()
{
SWTSkinObjectExpandItem so = (SWTSkinObjectExpandItem)skin.getSkinObject("expanditem-files");
SWTSkinObjectExpandBar bar = (SWTSkinObjectExpandBar)so.getParent();
bar.relayout();
for ( SWTSkinObjectExpandItem item: bar.getChildren()){
item.relayout();
}
}
private void checkSeedingMode() {
if ( torrentOptions == null ){
return;
}
// Check for seeding
boolean bTorrentValid = true;
if (torrentOptions.iStartID == TorrentOpenOptions.STARTMODE_SEEDING) {
// check if all selected files exist
TorrentOpenFileOptions[] files = torrentOptions.getFiles();
for (int j = 0; j < files.length; j++) {
TorrentOpenFileOptions fileInfo = files[j];
if (!fileInfo.isToDownload())
continue;
File file = fileInfo.getInitialLink();
if (file == null) {
file = fileInfo.getDestFileFullName();
}
if (!file.exists()) {
fileInfo.isValid = false;
bTorrentValid = false;
} else if (!fileInfo.isValid) {
fileInfo.isValid = true;
}
}
}
torrentOptions.isValid = bTorrentValid;
}
protected void cmbDataDirChanged() {
if (bSkipDataDirModify || cmbDataDir == null) {
return;
}
String dirText = cmbDataDir.getText();
for ( TorrentOpenOptions too: torrentOptionsMulti ){
too.setParentDir( dirText);
}
checkSeedingMode();
if (!Utils.isCocoa || SWT.getVersion() > 3600) { // See Eclipse Bug 292449
File file = new File( dirText );
if (!file.isDirectory()) {
cmbDataDir.setBackground(Colors.colorErrorBG);
// make the error state visible
soExpandItemSaveTo.setExpanded(true);
} else {
cmbDataDir.setBackground(null);
}
cmbDataDir.redraw();
cmbDataDir.update();
}
if (soExpandItemSaveTo != null) {
String s = MessageText.getString("OpenTorrentOptions.header.saveto",
new String[] { dirText });
soExpandItemSaveTo.setText(s);
}
diskFreeInfoRefreshPending = true;
}
private long getCachedDirFreeSpace(File directory) {
FileStatsCacheItem item = (FileStatsCacheItem) fileStatCache.get(directory);
if (item == null)
fileStatCache.put(directory, item = new FileStatsCacheItem(directory));
return item.freeSpace;
}
private boolean getCachedExistsStat(File directory) {
FileStatsCacheItem item = (FileStatsCacheItem) fileStatCache.get(directory);
if (item == null)
fileStatCache.put(directory, item = new FileStatsCacheItem(directory));
return item.exists;
}
protected void setSelectedQueueLocation(int iLocation) {
torrentOptions.iQueueLocation = iLocation;
updateStartOptionsHeader();
}
private void updateStartOptionsHeader() {
if (soStartOptionsExpandItem == null) {
return;
}
String optionText = MessageText.getString("OpenTorrentWindow.startMode."
+ startModes[torrentOptions.iStartID])
+ ", "
+ MessageText.getString("OpenTorrentWindow.addPosition."
+ queueLocations[torrentOptions.iQueueLocation]);
String s = MessageText.getString("OpenTorrentOptions.header.startoptions",
new String[] {
optionText
});
List<Tag> initialtags = torrentOptions.getInitialTags();
String tag_str;
if ( initialtags.size() == 0 ){
tag_str = MessageText.getString( "label.none" );
}else{
tag_str = "";
for ( Tag t: initialtags ){
tag_str += (tag_str==""?"":", ") + t.getTagName( true );
}
}
s += " " + MessageText.getString( "OpenTorrentOptions.header.tags", new String[]{ tag_str });
soStartOptionsExpandItem.setText(s);
}
protected void setSelectedStartMode(int iStartID) {
torrentOptions.iStartID = iStartID;
checkSeedingMode();
updateStartOptionsHeader();
}
private void setupFileAreaButtons(SWTSkinObjectContainer so) {
Composite cButtons = so.getComposite();
cButtons.setLayout(new GridLayout(7,false));
List<Button> buttons = new ArrayList<Button>();
btnSelectAll = new Button(cButtons, SWT.PUSH);
buttons.add( btnSelectAll );
Messages.setLanguageText(btnSelectAll, "Button.selectAll");
btnSelectAll.addListener(SWT.Selection, new Listener() {
public void handleEvent(Event event) {
tvFiles.selectAll();
}
});
btnMarkSelected = new Button(cButtons, SWT.PUSH);
buttons.add( btnMarkSelected );
Messages.setLanguageText(btnMarkSelected, "Button.mark");
btnMarkSelected.addListener(SWT.Selection, new Listener() {
public void handleEvent(Event event) {
TorrentOpenFileOptions[] infos = tvFiles.getSelectedDataSources().toArray(new TorrentOpenFileOptions[0]);
setToDownload( infos, true );
}
});
btnUnmarkSelected = new Button(cButtons, SWT.PUSH);
buttons.add( btnUnmarkSelected );
Messages.setLanguageText(btnUnmarkSelected, "Button.unmark");
btnUnmarkSelected.addListener(SWT.Selection, new Listener() {
public void handleEvent(Event event) {
TorrentOpenFileOptions[] infos = tvFiles.getSelectedDataSources().toArray(new TorrentOpenFileOptions[0]);
setToDownload( infos, false );
}
});
btnRename = new Button(cButtons, SWT.PUSH);
buttons.add( btnRename );
Messages.setLanguageText(btnRename, "Button.rename");
btnRename.addListener(SWT.Selection, new Listener() {
public void handleEvent(Event event) {
TorrentOpenFileOptions[] infos = tvFiles.getSelectedDataSources().toArray(
new TorrentOpenFileOptions[0]);
renameFilenames(infos);
}
});
btnRetarget = new Button(cButtons, SWT.PUSH);
buttons.add( btnRetarget );
Messages.setLanguageText(btnRetarget, "Button.retarget");
btnRetarget.addListener(SWT.Selection, new Listener() {
public void handleEvent(Event event) {
TorrentOpenFileOptions[] infos = tvFiles.getSelectedDataSources().toArray(
new TorrentOpenFileOptions[0]);
changeFileDestination(infos, false );
}
});
try {
if (COConfigurationManager.getBooleanParameter("rcm.overall.enabled",
true) && AzureusCoreFactory.isCoreRunning()) {
final PluginInterface pi = AzureusCoreFactory.getSingleton().getPluginManager().getPluginInterfaceByID(
"aercm");
if (pi != null && pi.getPluginState().isOperational()
&& pi.getIPC().canInvoke("lookupBySize", new Object[] {
new Long(0)
})) {
Label pad = new Label(cButtons, SWT.NONE);
GridData gridData = new GridData( GridData.FILL_HORIZONTAL);
pad.setLayoutData( gridData );
btnSwarmIt = new Button(cButtons, SWT.PUSH);
buttons.add( btnSwarmIt );
Messages.setLanguageText(btnSwarmIt, "Button.swarmit");
btnSwarmIt.addListener(SWT.Selection, new Listener() {
public void handleEvent(Event event) {
List<Object> selectedDataSources = tvFiles.getSelectedDataSources();
for (Object ds : selectedDataSources) {
TorrentOpenFileOptions file = (TorrentOpenFileOptions) ds;
try {
pi.getIPC().invoke("lookupBySize", new Object[] {
new Long(file.lSize)
});
} catch (Throwable e) {
Debug.out(e);
}
break;
}
}
});
btnSwarmIt.setEnabled(false);
}
}
} catch (Throwable e) {
}
Utils.makeButtonsEqualWidth( buttons );
updateFileButtons();
}
private void
setToDownload(
TorrentOpenFileOptions[] infos,
boolean download )
{
boolean changed = false;
try{
settingToDownload.incrementAndGet();
for (TorrentOpenFileOptions info: infos ){
if ( info.isToDownload() != download ){
info.setToDownload( download );
changed = true;
}
}
}finally{
settingToDownload.decrementAndGet();
}
if ( changed ){
updateFileButtons();
updateSize();
}
}
private void setupFileAreaInfo(SWTSkinObjectText so) {
soFileAreaInfo = so;
}
private void setupSaveLocation(SWTSkinObjectContainer soInputArea,
SWTSkinObjectButton soBrowseButton) {
cmbDataDir = new Combo(soInputArea.getComposite(), SWT.NONE);
cmbDataDir.setLayoutData(Utils.getFilledFormData());
cmbDataDir.addModifyListener(new ModifyListener() {
public void modifyText(ModifyEvent e) {
cmbDataDirChanged();
}
});
cmbDataDir.addListener(SWT.Selection, new Listener() {
public void handleEvent(Event event) {
cmbDataDirChanged();
}
});
updateDataDirCombo();
dirList = COConfigurationManager.getStringListParameter("saveTo_list");
StringIterator iter = dirList.iterator();
while (iter.hasNext()) {
String s = iter.next();
if (torrentOptions==null || !s.equals(torrentOptions.getParentDir())) {
cmbDataDir.add(s);
}
}
soBrowseButton.addSelectionListener(new ButtonListenerAdapter() {
@Override
public void pressed(SWTSkinButtonUtility buttonUtility,
SWTSkinObject skinObject, int stateMask) {
String sSavePath;
String sDefPath = cmbDataDir.getText();
File f = new File(sDefPath);
if (sDefPath.length() > 0) {
while (!f.exists()) {
f = f.getParentFile();
if (f == null) {
f = new File(sDefPath);
break;
}
}
}
DirectoryDialog dDialog = new DirectoryDialog(cmbDataDir.getShell(),
SWT.SYSTEM_MODAL);
dDialog.setFilterPath(f.getAbsolutePath());
dDialog.setMessage(MessageText.getString("MainWindow.dialog.choose.savepath_forallfiles"));
sSavePath = dDialog.open();
if (sSavePath != null) {
cmbDataDir.setText(sSavePath);
}
}
});
}
private void setupStartOptions(SWTSkinObjectExpandItem so) {
soStartOptionsExpandItem = so;
Composite cTorrentOptions = so.getComposite();
Composite cTorrentModes = new Composite(cTorrentOptions, SWT.NONE);
GridData gridData = new GridData(GridData.FILL_HORIZONTAL);
cTorrentModes.setLayoutData(Utils.getFilledFormData());
GridLayout layout = new GridLayout();
layout.numColumns = 4;
layout.marginWidth = 5;
layout.marginHeight = 5;
cTorrentModes.setLayout(layout);
Label label = new Label(cTorrentModes, SWT.NONE);
gridData = new GridData(GridData.VERTICAL_ALIGN_CENTER);
label.setLayoutData(gridData);
Messages.setLanguageText(label, "OpenTorrentWindow.startMode");
cmbStartMode = new Combo(cTorrentModes, SWT.BORDER | SWT.READ_ONLY);
gridData = new GridData(GridData.FILL_HORIZONTAL);
cmbStartMode.setLayoutData(gridData);
updateStartModeCombo();
cmbStartMode.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
setSelectedStartMode(cmbStartMode.getSelectionIndex());
}
});
label = new Label(cTorrentModes, SWT.NONE);
gridData = new GridData(GridData.VERTICAL_ALIGN_CENTER);
label.setLayoutData(gridData);
Messages.setLanguageText(label, "OpenTorrentWindow.addPosition");
cmbQueueLocation = new Combo(cTorrentModes, SWT.BORDER | SWT.READ_ONLY);
gridData = new GridData(GridData.FILL_HORIZONTAL);
cmbQueueLocation.setLayoutData(gridData);
updateQueueLocationCombo();
cmbQueueLocation.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
setSelectedQueueLocation(cmbQueueLocation.getSelectionIndex());
}
});
if ( TagManagerFactory.getTagManager().isEnabled()){
// tag area
Composite tagLeft = new Composite( cTorrentModes, SWT.NULL);
tagLeft.setLayoutData( new GridData(GridData.VERTICAL_ALIGN_CENTER ));
Composite tagRight = new Composite( cTorrentModes, SWT.NULL);
gridData = new GridData(GridData.FILL_HORIZONTAL );
gridData.horizontalSpan=3;
tagRight.setLayoutData(gridData);
layout = new GridLayout();
layout.numColumns = 1;
layout.marginWidth = 0;
layout.marginHeight = 0;
tagLeft.setLayout(layout);
layout = new GridLayout();
layout.numColumns = 2;
layout.marginWidth = 0;
layout.marginHeight = 0;
tagRight.setLayout(layout);
label = new Label(tagLeft, SWT.NONE);
gridData = new GridData(GridData.VERTICAL_ALIGN_CENTER);
Messages.setLanguageText(label, "label.initial_tags");
Composite tagButtons = new Composite( tagRight, SWT.NULL);
gridData = new GridData(GridData.FILL_HORIZONTAL );
tagButtons.setLayoutData(gridData);
RowLayout tagLayout = new RowLayout();
tagLayout.pack = false;
tagButtons.setLayout( tagLayout);
buildTagButtonPanel( tagButtons );
Button addTag = new Button( tagRight, SWT.NULL );
addTag.setLayoutData( new GridData(GridData.VERTICAL_ALIGN_CENTER ));
Messages.setLanguageText( addTag, "label.add.tag" );
addTag.addSelectionListener(
new SelectionAdapter() {
public void
widgetSelected(
SelectionEvent e)
{
TagUIUtils.createManualTag();
}
});
}
}
private void
buildTagButtonPanel(
Composite parent )
{
buildTagButtonPanel( parent, false );
}
private void
buildTagButtonPanel(
final Composite parent,
boolean is_rebuild )
{
if ( parent.isDisposed()){
return;
}
final String SP_KEY = "oto:tag:initsp";
if ( is_rebuild ){
Utils.disposeComposite( parent, false );
}else{
parent.setData( SP_KEY, getSavePath());
}
final TagType tt = TagManagerFactory.getTagManager().getTagType( TagType.TT_DOWNLOAD_MANUAL );
List<Tag> initialTags = torrentOptions.getInitialTags();
for ( final Tag tag: TagUIUtils.sortTags( tt.getTags())){
if ( tag.canBePublic() && !tag.isTagAuto()){
final Button but = new Button( parent, SWT.TOGGLE );
but.setText( tag.getTagName( true ));
but.setToolTipText( TagUIUtils.getTagTooltip(tag));
if ( initialTags.contains( tag )){
but.setSelection( true );
}
but.addSelectionListener(
new SelectionAdapter() {
public void
widgetSelected(
SelectionEvent e)
{
List<Tag> tags = torrentOptions.getInitialTags();
if ( but.getSelection()){
tags.add( tag );
TagFeatureFileLocation fl = (TagFeatureFileLocation)tag;
if ( fl.supportsTagInitialSaveFolder()){
File save_loc = fl.getTagInitialSaveFolder();
if ( save_loc != null ){
setSavePath( save_loc.getAbsolutePath());
}
}
}else{
tags.remove( tag );
TagFeatureFileLocation fl = (TagFeatureFileLocation)tag;
if ( fl.supportsTagInitialSaveFolder()){
File save_loc = fl.getTagInitialSaveFolder();
if ( save_loc != null && getSavePath().equals( save_loc.getAbsolutePath())){
String old = (String)parent.getData( SP_KEY );
if ( old != null ){
setSavePath( old );
}
}
}
}
torrentOptions.setInitialTags( tags );
updateStartOptionsHeader();
}
});
Menu menu = new Menu( but );
but.setMenu( menu );
TagUIUtils.createSideBarMenuItems(menu, tag);
}
}
if ( is_rebuild ){
parent.getParent().layout( true, true );
return;
}
tt.addTagTypeListener(
new TagTypeListener()
{
public void
tagTypeChanged(
TagType tag_type)
{
}
public void
tagRemoved(
Tag tag )
{
rebuild();
}
public void
tagChanged(
Tag tag)
{
rebuild();
}
public void
tagAdded(
Tag tag)
{
rebuild();
}
private void
rebuild()
{
if ( parent.isDisposed()){
tt.removeTagTypeListener( this );
}else{
Utils.execSWTThread(
new Runnable()
{
public void
run()
{
buildTagButtonPanel( parent, true );
}
});
}
}
}, false );
}
private void setupTVFiles(SWTSkinObjectContainer soFilesTable, SWTSkinObjectTextbox soFilesFilter ) {
TableColumnManager tcm = TableColumnManager.getInstance();
if (tcm.getDefaultColumnNames(TABLEID_FILES) == null) {
tcm.registerColumn(TorrentOpenFileOptions.class,
TableColumnOTOF_Position.COLUMN_ID,
new TableColumnCreationListener() {
public void tableColumnCreated(TableColumn column) {
new TableColumnOTOF_Position(column);
}
});
tcm.registerColumn(TorrentOpenFileOptions.class,
TableColumnOTOF_Download.COLUMN_ID,
new TableColumnCreationListener() {
public void tableColumnCreated(TableColumn column) {
new TableColumnOTOF_Download(column);
}
});
tcm.registerColumn(TorrentOpenFileOptions.class,
TableColumnOTOF_Name.COLUMN_ID, new TableColumnCreationListener() {
public void tableColumnCreated(TableColumn column) {
new TableColumnOTOF_Name(column);
}
});
tcm.registerColumn(TorrentOpenFileOptions.class,
TableColumnOTOF_Size.COLUMN_ID, new TableColumnCreationListener() {
public void tableColumnCreated(TableColumn column) {
new TableColumnOTOF_Size(column);
}
});
tcm.registerColumn(TorrentOpenFileOptions.class,
TableColumnOTOF_Path.COLUMN_ID, new TableColumnCreationListener() {
public void tableColumnCreated(TableColumn column) {
new TableColumnOTOF_Path(column);
}
});
tcm.registerColumn(TorrentOpenFileOptions.class,
TableColumnOTOF_Ext.COLUMN_ID, new TableColumnCreationListener() {
public void tableColumnCreated(TableColumn column) {
new TableColumnOTOF_Ext(column);
}
});
tcm.registerColumn(TorrentOpenFileOptions.class,
TableColumnOTOF_Priority.COLUMN_ID, new TableColumnCreationListener() {
public void tableColumnCreated(TableColumn column) {
new TableColumnOTOF_Priority(column);
}
});
tcm.setDefaultColumnNames(TABLEID_FILES, new String[] {
TableColumnOTOF_Position.COLUMN_ID,
TableColumnOTOF_Download.COLUMN_ID,
TableColumnOTOF_Name.COLUMN_ID,
TableColumnOTOF_Size.COLUMN_ID,
TableColumnOTOF_Path.COLUMN_ID,
TableColumnOTOF_Priority.COLUMN_ID
});
tcm.setDefaultSortColumnName(TABLEID_FILES, TableColumnOTOF_Position.COLUMN_ID);
}
tvFiles = TableViewFactory.createTableViewSWT(TorrentOpenFileOptions.class,
TABLEID_FILES, TABLEID_FILES, null, "#", SWT.BORDER
| SWT.FULL_SELECTION | SWT.MULTI);
tvFiles.initialize(soFilesTable.getComposite());
tvFiles.setRowDefaultHeight(20);
if ( torrentOptions.getFiles().length > 1 && soFilesFilter != null ){
soFilesFilter.setVisible( true );
Text text = soFilesFilter.getTextControl();
tvFiles.enableFilterCheck(text, this);
}else{
if ( soFilesFilter != null ){
soFilesFilter.setVisible( false );
}
}
tvFiles.addKeyListener(new KeyListener() {
public void keyPressed(KeyEvent e) {
}
public void keyReleased(KeyEvent e) {
// if (e.keyCode == SWT.SPACE) {
// TableRowCore focusedRow = tvFiles.getFocusedRow();
// TorrentOpenFileOptions tfi_focus = ((TorrentOpenFileOptions) focusedRow.getDataSource());
// boolean download = !tfi_focus.isToDownload();
//
// TorrentOpenFileOptions[] infos = tvFiles.getSelectedDataSources().toArray(new TorrentOpenFileOptions[0]);
// setToDownload( infos, download );
// }
if (e.keyCode == SWT.F2 && (e.stateMask & SWT.MODIFIER_MASK) == 0) {
TorrentOpenFileOptions[] infos = tvFiles.getSelectedDataSources().toArray(
new TorrentOpenFileOptions[0]);
renameFilenames(infos);
e.doit = false;
return;
}
}
});
tvFiles.addMenuFillListener(new TableViewSWTMenuFillListener() {
public void fillMenu(String sColumnName, Menu menu) {
final Shell shell = menu.getShell();
MenuItem item;
TableRowCore focusedRow = tvFiles.getFocusedRow();
final TorrentOpenFileOptions[] infos = tvFiles.getSelectedDataSources().toArray(new TorrentOpenFileOptions[0]);
final TorrentOpenFileOptions tfi_focus = ((TorrentOpenFileOptions) focusedRow.getDataSource());
boolean download = tfi_focus.isToDownload();
item = new MenuItem(menu, SWT.CHECK);
Messages.setLanguageText(item, "label.download.file");
item.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
TableRowCore focusedRow = tvFiles.getFocusedRow();
TorrentOpenFileOptions tfi_focus = ((TorrentOpenFileOptions) focusedRow.getDataSource());
boolean download = !tfi_focus.isToDownload();
setToDownload( infos, download );
}
});
item.setSelection(download);
// priority
final MenuItem itemPriority = new MenuItem(menu, SWT.CASCADE);
Messages.setLanguageText(itemPriority, "FilesView.menu.setpriority");
final Menu menuPriority = new Menu(shell, SWT.DROP_DOWN);
itemPriority.setMenu(menuPriority);
final MenuItem itemHigh = new MenuItem(menuPriority, SWT.CASCADE);
Messages.setLanguageText(itemHigh, "FilesView.menu.setpriority.high");
final MenuItem itemNormal = new MenuItem(menuPriority, SWT.CASCADE);
Messages.setLanguageText(itemNormal, "FilesView.menu.setpriority.normal");
final MenuItem itemLow = new MenuItem(menuPriority, SWT.CASCADE);
Messages.setLanguageText(itemLow, "FileItem.low");
final MenuItem itemNumeric = new MenuItem(menuPriority, SWT.CASCADE);
Messages.setLanguageText(itemNumeric, "FilesView.menu.setpriority.numeric");
final MenuItem itemNumericAuto = new MenuItem(menuPriority, SWT.CASCADE);
Messages.setLanguageText(itemNumericAuto, "FilesView.menu.setpriority.numeric.auto");
Listener priorityListener = new Listener() {
public void handleEvent(Event event) {
Widget widget = event.widget;
int priority;
if ( widget == itemHigh ){
priority = 1;
}else if ( widget == itemNormal ){
priority = 0;
}else if ( widget == itemLow ){
priority = -1;
}else if ( widget == itemNumeric ){
SimpleTextEntryWindow entryWindow = new SimpleTextEntryWindow(
"FilesView.dialog.priority.title",
"FilesView.dialog.priority.text");
entryWindow.prompt(
new UIInputReceiverListener() {
public void UIInputReceiverClosed(UIInputReceiver entryWindow) {
if (!entryWindow.hasSubmittedInput()) {
return;
}
String sReturn = entryWindow.getSubmittedInput();
if (sReturn == null)
return;
int priority = 0;
try {
priority = Integer.valueOf(sReturn).intValue();
} catch (NumberFormatException er) {
Debug.out( "Invalid priority: " + sReturn );
new MessageBoxShell(SWT.ICON_ERROR | SWT.OK,
MessageText.getString("FilePriority.invalid.title"),
MessageText.getString("FilePriority.invalid.text", new String[]{ sReturn })).open(null);
return;
}
for (TorrentOpenFileOptions torrentFileInfo : infos) {
torrentFileInfo.setPriority( priority );
}
}
});
return;
}else if ( widget == itemNumericAuto ){
int next_priority = 0;
TorrentOpenFileOptions[] all_files = torrentOptions.getFiles();
if ( all_files.length != infos.length ){
Set<Integer> affected_indexes = new HashSet<Integer>();
for ( TorrentOpenFileOptions file: infos ){
affected_indexes.add( file.getIndex());
}
for ( TorrentOpenFileOptions file: all_files ){
if ( !( affected_indexes.contains( file.getIndex()) || !file.isToDownload())){
next_priority = Math.max( next_priority, file.getPriority()+1);
}
}
}
next_priority += infos.length;
for ( TorrentOpenFileOptions file: infos ){
file.setPriority( --next_priority );
}
return;
}else{
return;
}
for (TorrentOpenFileOptions torrentFileInfo : infos) {
torrentFileInfo.setPriority( priority );
}
}
};
itemNumeric.addListener(SWT.Selection, priorityListener);
itemNumericAuto.addListener(SWT.Selection, priorityListener);
itemHigh.addListener(SWT.Selection, priorityListener);
itemNormal.addListener(SWT.Selection, priorityListener);
itemLow.addListener(SWT.Selection, priorityListener);
// rename
item = new MenuItem(menu, SWT.PUSH);
Messages.setLanguageText(item, "FilesView.menu.rename_only");
item.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
renameFilenames(infos);
}
});
item = new MenuItem(menu, SWT.PUSH);
Messages.setLanguageText(item,
"OpenTorrentWindow.fileList.changeDestination");
item.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
changeFileDestination(infos,false);
}
});
if ( infos.length > 1 && torrentOptions.iStartID != TorrentOpenOptions.STARTMODE_SEEDING ){
item = new MenuItem(menu, SWT.PUSH);
Messages.setLanguageText(item,
"OpenTorrentWindow.fileList.changeDestination.all", new String[]{ String.valueOf( infos.length )});
item.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
changeFileDestination(infos,true);
}
});
}
new MenuItem(menu, SWT.SEPARATOR);
item = new MenuItem(menu, SWT.PUSH);
Messages.setLanguageText(item, "Button.selectAll");
item.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
tvFiles.selectAll();
}
});
String dest_path = tfi_focus.getDestPathName();
String parentDir = tfi_focus.parent.getParentDir();
List<String> folder_list = new ArrayList<String>();
folder_list.add( dest_path );
if ( dest_path.startsWith( parentDir ) && dest_path.length() > parentDir.length()){
String relativePath = dest_path.substring( parentDir.length() + 1 );
while ( relativePath.contains( File.separator )){
int pos = relativePath.lastIndexOf( File.separator );
relativePath = relativePath.substring( 0, pos );
folder_list.add( parentDir + File.separator + relativePath );
}
}
for ( int i=folder_list.size()-1;i>=0;i-- ){
final String this_dest_path = folder_list.get(i);
item = new MenuItem(menu, SWT.PUSH);
Messages.setLanguageText(item, "menu.selectfilesinfolder", new String[] {
this_dest_path
});
item.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
TableRowCore[] rows = tvFiles.getRows();
for (TableRowCore row : rows) {
Object dataSource = row.getDataSource();
if (dataSource instanceof TorrentOpenFileOptions) {
TorrentOpenFileOptions fileOptions = (TorrentOpenFileOptions) dataSource;
if ( fileOptions.getDestPathName().startsWith( this_dest_path )){
row.setSelected(true);
}
}
}
}
});
}
if ( !torrentOptions.isSimpleTorrent()){
new MenuItem(menu, SWT.SEPARATOR );
item = new MenuItem(menu, SWT.PUSH);
Messages.setLanguageText(item, "OpenTorrentWindow.set.savepath");
item.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
setSavePath();
}
});
}
}
public void addThisColumnSubMenu(String sColumnName, Menu menuThisColumn) {
}
});
tvFiles.addSelectionListener(new TableSelectionListener() {
public void selected(TableRowCore[] row) {
updateFileButtons();
}
public void mouseExit(TableRowCore row) {
}
public void mouseEnter(TableRowCore row) {
}
public void focusChanged(TableRowCore focus) {
}
public void deselected(TableRowCore[] rows) {
updateFileButtons();
}
public void defaultSelected(TableRowCore[] rows, int stateMask) {
}
}, false);
tvFiles.addDataSources(torrentOptions.getFiles());
}
public boolean
filterCheck(
TorrentOpenFileOptions ds,
String filter,
boolean regex )
{
if ( filter == null || filter.length() == 0 ){
return( true );
}
try {
File file = ds.getDestFileFullName();
String name = filter.contains( File.separator )?file.getAbsolutePath():file.getName();
String s = regex ? filter : "\\Q" + filter.replaceAll("[|;]", "\\\\E|\\\\Q") + "\\E";
boolean match_result = true;
if ( regex && s.startsWith( "!" )){
s = s.substring(1);
match_result = false;
}
Pattern pattern = RegExUtil.getCachedPattern( "fv:search", s, Pattern.CASE_INSENSITIVE);
return( pattern.matcher(name).find() == match_result );
} catch (Exception e) {
return true;
}
}
public void filterSet(String filter)
{
}
protected void updateFileButtons() {
Utils.execSWTThread(new AERunnable() {
public void runSupport() {
TableRowCore[] rows = tvFiles.getSelectedRows();
boolean hasRowsSelected = rows.length > 0;
if (btnRename != null && !btnRename.isDisposed()) {
btnRename.setEnabled(hasRowsSelected);
}
if (btnRetarget != null && !btnRetarget.isDisposed()) {
btnRetarget.setEnabled(hasRowsSelected);
}
boolean all_marked = true;
boolean all_unmarked = true;
for ( TableRowCore row: rows ){
TorrentOpenFileOptions tfi = ((TorrentOpenFileOptions) row.getDataSource());
if ( tfi.isToDownload()){
all_unmarked = false;
}else{
all_marked = false;
}
}
btnSelectAll.setEnabled( rows.length < torrentOptions.getFiles().length );
btnMarkSelected.setEnabled( hasRowsSelected && !all_marked );
btnUnmarkSelected.setEnabled( hasRowsSelected && !all_unmarked );
if (btnSwarmIt != null && !btnSwarmIt.isDisposed()){
boolean enable=false;
if ( rows.length == 1 ){
TorrentOpenFileOptions tfi = ((TorrentOpenFileOptions) rows[0].getDataSource());
enable = tfi.lSize >= 50*1024*1024;
}
btnSwarmIt.setEnabled(enable);
}
}
});
}
protected void renameFilenames(TorrentOpenFileOptions[] infos) {
for (TorrentOpenFileOptions torrentFileInfo : infos) {
String renameFilename = askForRenameFilename(torrentFileInfo);
if (renameFilename == null) {
break;
}
torrentFileInfo.setDestFileName(renameFilename);
TableRowCore row = tvFiles.getRow(torrentFileInfo);
if (row != null) {
row.invalidate(true);
row.refresh(true);
}
}
}
private String askForRenameFilename(TorrentOpenFileOptions fileInfo) {
SimpleTextEntryWindow dialog = new SimpleTextEntryWindow(
"FilesView.rename.filename.title", "FilesView.rename.filename.text");
dialog.setPreenteredText(fileInfo.orgFileName, false); // false -> it's not "suggested", it's a previous value
dialog.allowEmptyInput(false);
dialog.prompt();
if (!dialog.hasSubmittedInput()) {
return null;
}
return dialog.getSubmittedInput();
}
private void
setSavePath()
{
if ( torrentOptions.isSimpleTorrent()){
changeFileDestination( torrentOptions.getFiles(), false );
}else{
DirectoryDialog dDialog = new DirectoryDialog(shell,SWT.SYSTEM_MODAL);
File filterPath = new File( torrentOptions.getDataDir());
if ( !filterPath.exists()){
filterPath = filterPath.getParentFile();
}
dDialog.setFilterPath( filterPath.getAbsolutePath());
dDialog.setMessage(MessageText.getString("MainWindow.dialog.choose.savepath")
+ " (" + torrentOptions.getTorrentName() + ")");
String sNewDir = dDialog.open();
if (sNewDir == null){
return;
}
File newDir = new File(sNewDir).getAbsoluteFile();
if ( !newDir.isDirectory()){
if ( newDir.exists()){
Debug.out( "new dir isn't a dir!" );
return;
}else if ( !newDir.mkdirs()){
Debug.out( "Failed to create '" + newDir + "'" );
return;
}
}
File new_parent = newDir.getParentFile();
if ( new_parent == null ){
Debug.out( "Invalid save path, parent folder is null" );
return;
}
torrentOptions.setParentDir( new_parent.getAbsolutePath());
torrentOptions.setSubDir( newDir.getName());
updateDataDirCombo();
cmbDataDirChanged();
/* old window used to reset this - not sure why, if the user's
* made some per-file changes already then we should keep them
for ( TorrentOpenFileOptions tfi: torrentOptions.getFiles()){
tfi.setFullDestName( null );
}
*/
}
}
private void changeFileDestination(TorrentOpenFileOptions[] infos, boolean allAtOnce ) {
if ( allAtOnce && infos.length > 1 ){
// find a common ancestor if it exists
String current_parent = null;
for (TorrentOpenFileOptions fileInfo : infos) {
String dest = fileInfo.getDestPathName();
if ( current_parent == null ){
current_parent = dest;
}else{
if ( !current_parent.equals( dest )){
char[] cp_chars = current_parent.toCharArray();
char[] p_chars = dest.toCharArray();
int cp_len = cp_chars.length;
int p_len = p_chars.length;
int min = Math.min( cp_len, p_len );
int pos = 0;
while ( pos < min && cp_chars[pos] == p_chars[pos] ){
pos++;
}
if ( pos < cp_len ){
File f = new File( new String( cp_chars, 0, pos ) + "x" );
File pf = f.getParentFile();
if ( pf == null ){
current_parent = "";
}else{
current_parent = pf.toString();
}
}
}
}
}
DirectoryDialog dDialog = new DirectoryDialog( shell, SWT.SYSTEM_MODAL );
if ( current_parent.length() > 0 ){
dDialog.setFilterPath( current_parent );
}
dDialog.setMessage(MessageText.getString("MainWindow.dialog.choose.savepath_forallfiles"));
String sSavePath = dDialog.open();
if ( sSavePath != null) {
if ( sSavePath.endsWith( File.separator )){
sSavePath = sSavePath.substring( 0, sSavePath.length() - 1 );
}
int prefix_len = current_parent.length();
for ( TorrentOpenFileOptions fileInfo: infos ){
String dest = fileInfo.getDestPathName();
if ( prefix_len == 0 ){
File f = new File( dest );
while( f.getParentFile() != null ){
f = f.getParentFile();
}
dest = dest.substring( f.toString().length());
}else{
dest = dest.substring( prefix_len );
}
if ( dest.startsWith( File.separator )){
dest = dest.substring( 1 );
}
if ( dest.length() > 0 ){
fileInfo.setDestPathName( sSavePath + File.separator + dest );
}else{
fileInfo.setDestPathName( sSavePath );
}
}
}
}else{
for (TorrentOpenFileOptions fileInfo : infos) {
int style = (fileInfo.parent.iStartID == TorrentOpenOptions.STARTMODE_SEEDING)
? SWT.OPEN : SWT.SAVE;
FileDialog fDialog = new FileDialog(shell, SWT.SYSTEM_MODAL
| style);
String sFilterPath = fileInfo.getDestPathName();
String sFileName = fileInfo.orgFileName;
File f = new File(sFilterPath);
if (!f.isDirectory()) {
// Move up the tree until we have an existing path
while (sFilterPath != null) {
String parentPath = f.getParent();
if (parentPath == null)
break;
sFilterPath = parentPath;
f = new File(sFilterPath);
if (f.isDirectory())
break;
}
}
if (sFilterPath != null){
fDialog.setFilterPath(sFilterPath);
}
fDialog.setFileName(sFileName);
fDialog.setText(MessageText.getString("MainWindow.dialog.choose.savepath")
+ " (" + fileInfo.orgFullName + ")");
String sNewName = fDialog.open();
if (sNewName == null)
return;
if (fileInfo.parent.iStartID == TorrentOpenOptions.STARTMODE_SEEDING) {
File file = new File(sNewName);
if (file.length() == fileInfo.lSize)
fileInfo.setFullDestName(sNewName);
else {
MessageBoxShell mb = new MessageBoxShell(SWT.OK,
"OpenTorrentWindow.mb.badSize", new String[] {
file.getName(),
fileInfo.orgFullName
});
mb.setParent(shell);
mb.open(null);
}
} else
fileInfo.setFullDestName(sNewName);
} // for i
}
checkSeedingMode();
updateDataDirCombo();
diskFreeInfoRefreshPending = true;
}
private void setupInfoFields(SWTSkin skin) {
SWTSkinObject so;
so = skin.getSkinObject("torrentinfo-name");
if (so instanceof SWTSkinObjectText) {
((SWTSkinObjectText) so).setText(torrentOptions.getTorrentName());
}
so = skin.getSkinObject("torrentinfo-trackername");
TOTorrent torrent = torrentOptions.getTorrent();
if ( torrent != null ){
if (so instanceof SWTSkinObjectText) {
((SWTSkinObjectText) so).setText(TrackerNameItem.getTrackerName(torrent));
}
so = skin.getSkinObject("torrentinfo-comment");
if (so instanceof SWTSkinObjectText) {
try {
LocaleUtilDecoder decoder = LocaleTorrentUtil.getTorrentEncoding(torrent);
String s = decoder.decodeString(torrent.getComment());
((SWTSkinObjectText) so).setText(s);
} catch (UnsupportedEncodingException e) {
} catch (TOTorrentException e) {
}
}
so = skin.getSkinObject("torrentinfo-createdon");
if (so instanceof SWTSkinObjectText) {
String creation_date = DisplayFormatters.formatDate(torrent.getCreationDate());
((SWTSkinObjectText) so).setText(creation_date);
}
}
}
private void setupTrackers(SWTSkinObjectContainer so) {
Composite parent = so.getComposite();
Button button = new Button( parent, SWT.PUSH );
Messages.setLanguageText( button, "label.edit.trackers" );
TOTorrent torrent = torrentOptions.getTorrent();
button.setEnabled( torrent != null && !TorrentUtils.isReallyPrivate( torrent ));
button.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
List<List<String>> trackers = torrentOptions.getTrackers( false );
new MultiTrackerEditor( shell, null, trackers, new TrackerEditorListener() {
public void trackersChanged(String str, String str2, List<List<String>> updatedTrackers) {
torrentOptions.setTrackers(updatedTrackers);
}
}, true, true );
}});
}
private void setupUpDownLimitOption(SWTSkinObjectContainer so) {
Composite parent = so.getComposite();
parent.setBackgroundMode( SWT.INHERIT_FORCE ); // win 7 classic theme shows grey background without this
parent.setLayout( new GridLayout(4, false));
GridData gridData = new GridData();
Label label = new Label(parent, SWT.NULL);
label.setText( MessageText.getString( "TableColumn.header.maxupspeed") + "[" + DisplayFormatters.getRateUnit(DisplayFormatters.UNIT_KB ) + "]" );
gridData = new GridData();
GenericIntParameter paramMaxUploadSpeed =
new GenericIntParameter(
new IntAdapter()
{
public void
setIntValue(
String key,
int value )
{
torrentOptions.setMaxUploadSpeed( value );
}
},
parent,
"torrentoptions.config.uploadspeed", 0, -1);
paramMaxUploadSpeed.setLayoutData(gridData);
label = new Label(parent, SWT.NULL);
label.setText( MessageText.getString( "TableColumn.header.maxdownspeed") + "[" + DisplayFormatters.getRateUnit(DisplayFormatters.UNIT_KB ) + "]" );
gridData = new GridData();
GenericIntParameter paramMaxDownloadSpeed =
new GenericIntParameter(
new IntAdapter()
{
public void
setIntValue(
String key,
int value )
{
torrentOptions.setMaxDownloadSpeed( value );
}
},
parent,
"torrentoptions.config.downloadspeed", 0, -1);
paramMaxDownloadSpeed.setLayoutData(gridData);
}
private void setupIPFilterOption(SWTSkinObjectContainer so) {
Composite parent = so.getComposite();
parent.setBackgroundMode( SWT.INHERIT_FORCE ); // win 7 classic theme shows grey background without this
parent.setLayout( new GridLayout());
Button button = new Button(parent, SWT.CHECK | SWT.WRAP );
Messages.setLanguageText(button, "MyTorrentsView.menu.ipf_enable");
GridData gd = new GridData();
gd.verticalAlignment = SWT.CENTER;
button.setLayoutData( gd);
button.setSelection(!torrentOptions.disableIPFilter);
button.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
torrentOptions.disableIPFilter = !((Button) e.widget).getSelection();
}
});
}
private void setupPeerSourcesOptions(SWTSkinObjectContainer so) {
Composite parent = so.getComposite();
parent.setBackgroundMode( SWT.INHERIT_FORCE ); // win 7 classic theme shows grey background without this
Group peer_sources_group = new Group(parent, SWT.NULL);
Messages.setLanguageText(peer_sources_group,
"ConfigView.section.connection.group.peersources");
GridLayout peer_sources_layout = new GridLayout(3, true);
peer_sources_group.setLayout(peer_sources_layout);
peer_sources_group.setLayoutData(Utils.getFilledFormData());
// Label label = new Label(peer_sources_group, SWT.WRAP);
// Messages.setLanguageText(label,
// "ConfigView.section.connection.group.peersources.info");
// GridData gridData = new GridData();
// label.setLayoutData(gridData);
for (int i = 0; i < PEPeerSource.PS_SOURCES.length; i++) {
final String p = PEPeerSource.PS_SOURCES[i];
String config_name = "Peer Source Selection Default." + p;
String msg_text = "ConfigView.section.connection.peersource." + p;
Button button = new Button(peer_sources_group, SWT.CHECK);
Messages.setLanguageText(button, msg_text);
button.setSelection(COConfigurationManager.getBooleanParameter(config_name));
button.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
torrentOptions.peerSource.put(p, ((Button)e.widget).getSelection());
}
});
GridData gridData = new GridData();
button.setLayoutData(gridData);
}
}
private void updateDataDirCombo() {
if (cmbDataDir == null) {
return;
}
try {
bSkipDataDirModify = true;
cmbDataDir.setText( torrentOptions==null?"":torrentOptions.getParentDir());
} finally {
bSkipDataDirModify = false;
}
}
private void
setSavePath(
String path )
{
cmbDataDir.setText( path );
}
private String
getSavePath()
{
return( torrentOptions.getParentDir());
}
private void updateQueueLocationCombo() {
if (cmbQueueLocation == null)
return;
String[] sItemsText = new String[queueLocations.length];
for (int i = 0; i < queueLocations.length; i++) {
String sText = MessageText.getString("OpenTorrentWindow.addPosition."
+ queueLocations[i]);
sItemsText[i] = sText;
}
cmbQueueLocation.setItems(sItemsText);
cmbQueueLocation.select(torrentOptions.iQueueLocation);
}
private void updateSize() {
if (soFileAreaInfo == null && soExpandItemFiles == null) {
return;
}
/*
* determine info for selected torrents only
*/
long totalSize = 0;
long checkedSize = 0;
long numToDownload = 0;
TorrentOpenFileOptions[] dataFiles = torrentOptions.getFiles();
for (TorrentOpenFileOptions file : dataFiles) {
totalSize += file.lSize;
if (file.isToDownload()) {
checkedSize += file.lSize;
numToDownload++;
}
}
boolean changed = checkedSize != currentSelectedDataSize;
currentSelectedDataSize = checkedSize;
String text;
// build string and set label
if (totalSize == 0) {
text = "";
} else if (checkedSize == totalSize) {
text = DisplayFormatters.formatByteCountToKiBEtc(totalSize);
} else {
text = MessageText.getString("OpenTorrentWindow.filesInfo", new String[] {
DisplayFormatters.formatByteCountToKiBEtc(checkedSize),
DisplayFormatters.formatByteCountToKiBEtc(totalSize)
});
}
if (soFileAreaInfo != null) {
soFileAreaInfo.setText(text);
}
if (soExpandItemFiles != null) {
String id = "OpenTorrentOptions.header.filesInfo."
+ (numToDownload == dataFiles.length ? "all" : "some");
soExpandItemFiles.setText(MessageText.getString(id, new String[] {
String.valueOf(numToDownload),
String.valueOf(dataFiles.length),
text
}));
}
diskFreeInfoRefreshPending = true;
if ( changed ){
changeListener.instanceChanged( this );
}
}
protected long
getSelectedDataSize()
{
return( currentSelectedDataSize );
}
private void updateStartModeCombo() {
if (cmbStartMode == null)
return;
String[] sItemsText = new String[startModes.length];
for (int i = 0; i < startModes.length; i++) {
String sText = MessageText.getString("OpenTorrentWindow.startMode."
+ startModes[i]);
sItemsText[i] = sText;
}
cmbStartMode.setItems(sItemsText);
cmbStartMode.select(torrentOptions.iStartID);
cmbStartMode.layout(true);
}
public void updateUI() {
if ( tvFiles != null ){
tvFiles.refreshTable(false);
}
if (diskFreeInfoRefreshPending && !diskFreeInfoRefreshRunning
&& FileUtil.getUsableSpaceSupported()) {
diskFreeInfoRefreshRunning = true;
diskFreeInfoRefreshPending = false;
final HashSet FSroots = new HashSet(Arrays.asList(File.listRoots()));
final HashMap partitions = new HashMap();
for ( TorrentOpenOptions too: torrentOptionsMulti ){
TorrentOpenFileOptions[] files = too.getFiles();
for (int j = 0; j < files.length; j++) {
TorrentOpenFileOptions file = files[j];
if (!file.isToDownload())
continue;
// reduce each file to its partition root
File root = file.getDestFileFullName().getAbsoluteFile();
Partition part = (Partition) partitions.get(parentToRootCache.get(root.getParentFile()));
if (part == null) {
File next;
while (true) {
root = root.getParentFile();
next = root.getParentFile();
if (next == null)
break;
// bubble up until we hit an existing directory
if (!getCachedExistsStat(root) || !root.isDirectory())
continue;
// check for mount points (different free space) or simple loops in the directory structure
if (FSroots.contains(root) || root.equals(next)
|| getCachedDirFreeSpace(next) != getCachedDirFreeSpace(root))
break;
}
parentToRootCache.put(
file.getDestFileFullName().getAbsoluteFile().getParentFile(),
root);
part = (Partition) partitions.get(root);
if (part == null) {
part = new Partition(root);
part.freeSpace = getCachedDirFreeSpace(root);
partitions.put(root, part);
}
}
part.bytesToConsume += file.lSize;
}
}
// clear child objects
if (diskspaceComp != null && !diskspaceComp.isDisposed()) {
Control[] labels = diskspaceComp.getChildren();
for (int i = 0; i < labels.length; i++)
labels[i].dispose();
// build labels
Iterator it = partitions.values().iterator();
while (it.hasNext()) {
Partition part = (Partition) it.next();
boolean filesTooBig = part.bytesToConsume > part.freeSpace;
String s = MessageText.getString("OpenTorrentWindow.diskUsage",
new String[] {
DisplayFormatters.formatByteCountToKiBEtc(part.bytesToConsume),
DisplayFormatters.formatByteCountToKiBEtc(part.freeSpace)
});
Label l;
l = new Label(diskspaceComp, SWT.NONE);
l.setForeground(filesTooBig ? Colors.colorError : null);
l.setText(part.root.getPath());
l.setLayoutData(new GridData(SWT.END, SWT.TOP, false, false));
l = new Label(diskspaceComp, SWT.NONE);
l.setForeground(filesTooBig ? Colors.colorError : null);
l.setLayoutData(new GridData(SWT.END, SWT.TOP, false, false));
l.setText(s);
}
// hack to force resize :(
diskspaceComp.layout(true);
soExpandItemSaveTo.relayout();
}
diskFreeInfoRefreshRunning = false;
}
}
private boolean
okPressed(
String dataDirPassed)
{
File filePassed = new File(dataDirPassed);
File fileDefSavePath = new File(
COConfigurationManager.getStringParameter(PARAM_DEFSAVEPATH));
if (filePassed.equals(fileDefSavePath) && !fileDefSavePath.isDirectory()) {
FileUtil.mkdirs(fileDefSavePath);
}
boolean isPathInvalid = dataDirPassed.length() == 0 || filePassed.isFile();
if (!isPathInvalid && !filePassed.isDirectory()) {
MessageBoxShell mb = new MessageBoxShell(SWT.YES | SWT.NO
| SWT.ICON_QUESTION, "OpenTorrentWindow.mb.askCreateDir",
new String[] {
filePassed.toString()
});
mb.setParent(shell);
mb.open(null);
int doCreate = mb.waitUntilClosed();
if (doCreate == SWT.YES)
isPathInvalid = !FileUtil.mkdirs(filePassed);
else {
cmbDataDir.setFocus();
return false;
}
}
if (isPathInvalid) {
MessageBoxShell mb = new MessageBoxShell(SWT.OK | SWT.ICON_ERROR,
"OpenTorrentWindow.mb.noGlobalDestDir", new String[] {
filePassed.toString()
});
mb.setParent(shell);
mb.open(null);
cmbDataDir.setFocus();
return false;
}
String sExistingFiles = "";
int iNumExistingFiles = 0;
File torrentOptionsDataDir = new File(torrentOptions.getDataDir());
// Need to make directory now, or single file torrent will take the
// "dest dir" as their filename. ie:
// 1) Add single file torrent with named "hi.exe"
// 2) type a non-existant directory c:\test\moo
// 3) unselect the torrent
// 4) change the global def directory to a real one
// 5) click ok. "hi.exe" will be written as moo in c:\test
if ( !torrentOptions.isSimpleTorrent()){
torrentOptionsDataDir = torrentOptionsDataDir.getParentFile(); // for non-simple this points to the top folder in downoad
}
if (!torrentOptionsDataDir.isDirectory() && !FileUtil.mkdirs(torrentOptionsDataDir)) {
MessageBoxShell mb = new MessageBoxShell(SWT.OK | SWT.ICON_ERROR,
"OpenTorrentWindow.mb.noDestDir", new String[] {
torrentOptionsDataDir.toString(),
torrentOptions.getTorrentName()
});
mb.setParent(shell);
mb.open(null);
return false;
}
if (!torrentOptions.isValid) {
MessageBoxShell mb = new MessageBoxShell(SWT.OK | SWT.ICON_ERROR,
"OpenTorrentWindow.mb.notValid", new String[] {
torrentOptions.getTorrentName()
});
mb.setParent(shell);
mb.open(null);
return false;
}
TorrentOpenFileOptions[] files = torrentOptions.getFiles();
for (int j = 0; j < files.length; j++) {
TorrentOpenFileOptions fileInfo = files[j];
if (fileInfo.getDestFileFullName().exists()) {
sExistingFiles += fileInfo.orgFullName + " - "
+ torrentOptions.getTorrentName() + "\n";
iNumExistingFiles++;
if (iNumExistingFiles > 5) {
// this has the potential effect of adding 5 files from the first
// torrent and then 1 file from each of the remaining torrents
break;
}
}
}
if (sExistingFiles.length() > 0) {
if (iNumExistingFiles > 5) {
sExistingFiles += MessageText.getString(
"OpenTorrentWindow.mb.existingFiles.partialList", new String[] {
"" + iNumExistingFiles
}) + "\n";
}
MessageBoxShell mb = new MessageBoxShell(SWT.OK | SWT.CANCEL
| SWT.ICON_WARNING, "OpenTorrentWindow.mb.existingFiles",
new String[] {
sExistingFiles
});
mb.setParent(shell);
mb.open(null);
if (mb.waitUntilClosed() != SWT.OK) {
return false;
}
}
String sDefaultPath = COConfigurationManager.getStringParameter(PARAM_DEFSAVEPATH);
if (!torrentOptions.getParentDir().equals(sDefaultPath)) {
// Move sDestDir to top of list
// First, check to see if sDestDir is already in the list
File fDestDir = new File(torrentOptions.getParentDir());
int iDirPos = -1;
for (int i = 0; i < dirList.size(); i++) {
String sDirName = dirList.get(i);
File dir = new File(sDirName);
if (dir.equals(fDestDir)) {
iDirPos = i;
break;
}
}
// If already in list, remove it
if (iDirPos > 0 && iDirPos < dirList.size())
dirList.remove(iDirPos);
// and add it to the top
dirList.add(0, torrentOptions.getParentDir());
// Limit
if (dirList.size() > 15)
dirList.remove(dirList.size() - 1);
// Temporary list cleanup
try {
for (int j = 0; j < dirList.size(); j++) {
File dirJ = new File(dirList.get(j));
for (int i = 0; i < dirList.size(); i++) {
try {
if (i == j)
continue;
File dirI = new File(dirList.get(i));
if (dirI.equals(dirJ)) {
dirList.remove(i);
// dirList shifted up, fix indexes
if (j > i)
j--;
i--;
}
} catch (Exception e) {
// Ignore
}
}
}
} catch (Exception e) {
// Ignore
}
COConfigurationManager.setParameter("saveTo_list", dirList);
COConfigurationManager.save();
}
if (COConfigurationManager.getBooleanParameter("DefaultDir.AutoUpdate")) {
COConfigurationManager.setParameter(PARAM_DEFSAVEPATH,
torrentOptions.getParentDir());
}
return true;
}
private void
dispose()
{
tvFiles.delete();
}
}
public interface
OpenTorrentInstanceListener
{
public void
instanceChanged(
OpenTorrentInstance instance );
}
private class
IntAdapter
extends GenericParameterAdapter
{
public int
getIntValue(
String key )
{
return( 0 );
}
public int
getIntValue(
String key,
int def )
{
return( def );
}
public boolean
resetIntDefault(
String key )
{
return( false );
}
}
}