001/* 002 * Copyright 2010-2015 Institut Pasteur. 003 * 004 * This file is part of Icy. 005 * 006 * Icy is free software: you can redistribute it and/or modify 007 * it under the terms of the GNU General Public License as published by 008 * the Free Software Foundation, either version 3 of the License, or 009 * (at your option) any later version. 010 * 011 * Icy is distributed in the hope that it will be useful, 012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 014 * GNU General Public License for more details. 015 * 016 * You should have received a copy of the GNU General Public License 017 * along with Icy. If not, see <http://www.gnu.org/licenses/>. 018 */ 019package icy.gui.preferences; 020 021import icy.gui.dialog.ConfirmDialog; 022import icy.plugin.PluginDescriptor; 023import icy.plugin.PluginInstaller; 024import icy.plugin.PluginInstaller.PluginInstallerListener; 025import icy.plugin.PluginLoader; 026import icy.plugin.PluginRepositoryLoader; 027import icy.plugin.PluginRepositoryLoader.PluginRepositoryLoaderListener; 028import icy.preferences.RepositoryPreferences.RepositoryInfo; 029import icy.system.thread.ThreadUtil; 030 031import java.util.ArrayList; 032import java.util.List; 033 034/** 035 * @author Stephane 036 */ 037public class PluginOnlinePreferencePanel extends PluginListPreferencePanel implements PluginRepositoryLoaderListener, 038 PluginInstallerListener 039{ 040 private enum PluginOnlineState 041 { 042 NULL, INSTALLING, REMOVING, HAS_INSTALL, INSTALLED, INSTALLED_FAULTY, OLDER, NEWER 043 } 044 045 /** 046 * 047 */ 048 private static final long serialVersionUID = 7737976340704271890L; 049 050 public static final String NODE_NAME = "Online Plugin"; 051 052 PluginOnlinePreferencePanel(PreferenceFrame parent) 053 { 054 super(parent, NODE_NAME, PluginPreferencePanel.NODE_NAME); 055 056 PluginRepositoryLoader.addListener(this); 057 PluginInstaller.addListener(this); 058 059 // remove last column not used here 060 table.removeColumn(table.getColumn(columnIds[4])); 061 062 repositoryPanel.setVisible(true); 063 action1Button.setText("Delete"); 064 action1Button.setVisible(true); 065 action2Button.setText("Install"); 066 action2Button.setVisible(true); 067 068 updateButtonsState(); 069 updateRepositories(); 070 } 071 072 @Override 073 protected void closed() 074 { 075 super.closed(); 076 077 PluginRepositoryLoader.removeListener(this); 078 PluginInstaller.removeListener(this); 079 } 080 081 private PluginOnlineState getPluginOnlineState(PluginDescriptor plugin) 082 { 083 if (plugin == null) 084 return PluginOnlineState.NULL; 085 086 if ((PluginInstaller.isInstallingPlugin(plugin))) 087 return PluginOnlineState.INSTALLING; 088 if ((PluginInstaller.isDesinstallingPlugin(plugin))) 089 return PluginOnlineState.REMOVING; 090 091 // has a local version ? 092 if (plugin.isInstalled()) 093 { 094 // get local version 095 final PluginDescriptor localPlugin = PluginLoader.getPlugin(plugin.getClassName()); 096 097 if (localPlugin != null) 098 { 099 if (plugin.equals(localPlugin)) 100 return PluginOnlineState.INSTALLED; 101 if (plugin.isOlder(localPlugin)) 102 return PluginOnlineState.OLDER; 103 if (plugin.isNewer(localPlugin)) 104 return PluginOnlineState.NEWER; 105 } 106 107 // local version not loaded --> faulty 108 return PluginOnlineState.INSTALLED_FAULTY; 109 } 110 111 return PluginOnlineState.HAS_INSTALL; 112 } 113 114 @Override 115 protected void doAction1() 116 { 117 final List<PluginDescriptor> selectedPlugins = getSelectedPlugins(); 118 final List<PluginDescriptor> toRemove = new ArrayList<PluginDescriptor>(); 119 120 for (PluginDescriptor plugin : selectedPlugins) 121 { 122 final PluginOnlineState state = getPluginOnlineState(plugin); 123 124 // remove plugin 125 if ((state == PluginOnlineState.INSTALLED) || (state == PluginOnlineState.INSTALLED_FAULTY)) 126 toRemove.add(plugin); 127 } 128 129 // nothing to remove 130 if (toRemove.isEmpty()) 131 return; 132 133 // get dependants plugins 134 final List<PluginDescriptor> dependants = PluginInstaller.getLocalDependenciesFrom(toRemove); 135 // delete the one we plan to remove 136 dependants.removeAll(toRemove); 137 138 String message = "<html>"; 139 140 if (!dependants.isEmpty()) 141 { 142 message = message + "The following plugin(s) won't work anymore :<br>"; 143 144 for (PluginDescriptor depPlug : dependants) 145 message = message + depPlug.getName() + " " + depPlug.getVersion() + "<br>"; 146 147 message = message + "<br>"; 148 } 149 150 message = message + "Are you sure you want to remove selected plugin(s) ?</html>"; 151 152 if (ConfirmDialog.confirm(message)) 153 { 154 // remove plugins 155 for (PluginDescriptor plugin : toRemove) 156 PluginInstaller.desinstall(plugin, false, true); 157 } 158 159 // refresh state 160 refreshTableData(); 161 } 162 163 @Override 164 protected void doAction2() 165 { 166 final List<PluginDescriptor> selectedPlugins = getSelectedPlugins(); 167 168 for (PluginDescriptor plugin : selectedPlugins) 169 { 170 final PluginOnlineState state = getPluginOnlineState(plugin); 171 172 if ((state == PluginOnlineState.HAS_INSTALL) || (state == PluginOnlineState.NEWER) 173 || (state == PluginOnlineState.OLDER)) 174 { 175 final boolean doInstall; 176 177 if (state == PluginOnlineState.OLDER) 178 doInstall = ConfirmDialog 179 .confirm("You'll replace your plugin by an older version !\nAre you sure you want to continue ?"); 180 else 181 doInstall = true; 182 183 // install plugin 184 if (doInstall) 185 PluginInstaller.install(plugin, true); 186 } 187 } 188 189 // refresh state 190 refreshTableData(); 191 } 192 193 @Override 194 protected void repositoryChanged() 195 { 196 refreshPlugins(); 197 } 198 199 @Override 200 protected void reloadPlugins() 201 { 202 PluginRepositoryLoader.reload(); 203 // so we display the empty list during reload 204 pluginsChanged(); 205 } 206 207 @Override 208 protected String getStateValue(PluginDescriptor plugin) 209 { 210 switch (getPluginOnlineState(plugin)) 211 { 212 case INSTALLING: 213 return "installing..."; 214 215 case REMOVING: 216 return "removing..."; 217 218 case NEWER: 219 return "update available"; 220 221 case OLDER: 222 return "outdated"; 223 224 case INSTALLED: 225 return "installed"; 226 227 case INSTALLED_FAULTY: 228 return "faulty"; 229 } 230 231 return ""; 232 } 233 234 @Override 235 protected List<PluginDescriptor> getPlugins() 236 { 237 // loading... 238 if (!PluginRepositoryLoader.isLoaded()) 239 return new ArrayList<PluginDescriptor>(); 240 241 // get selected repository 242 final Object selectedItem = repository.getSelectedItem(); 243 244 // load plugins from repository 245 if (selectedItem != null) 246 return PluginRepositoryLoader.getPlugins((RepositoryInfo) selectedItem); 247 248 return PluginRepositoryLoader.getPlugins(); 249 } 250 251 @Override 252 protected void updateButtonsStateInternal() 253 { 254 super.updateButtonsStateInternal(); 255 256 final List<PluginDescriptor> selectedPlugins = getSelectedPlugins(); 257 final boolean selected = (selectedPlugins.size() > 0); 258 259 if (PluginRepositoryLoader.isLoaded()) 260 { 261 refreshButton.setText("Reload list"); 262 refreshButton.setEnabled(true); 263 repository.setEnabled(true); 264 } 265 else 266 { 267 refreshButton.setText("Reloading..."); 268 refreshButton.setEnabled(false); 269 repository.setEnabled(false); 270 } 271 272 if (!selected) 273 { 274 action1Button.setEnabled(false); 275 action2Button.setEnabled(false); 276 return; 277 } 278 279 PluginOnlineState state; 280 281 state = PluginOnlineState.NULL; 282 for (PluginDescriptor plugin : selectedPlugins) 283 { 284 switch (getPluginOnlineState(plugin)) 285 { 286 case REMOVING: 287 if (state == PluginOnlineState.NULL) 288 state = PluginOnlineState.REMOVING; 289 break; 290 291 case INSTALLED: 292 case INSTALLED_FAULTY: 293 if ((state == PluginOnlineState.NULL) || (state == PluginOnlineState.REMOVING)) 294 state = PluginOnlineState.INSTALLED; 295 break; 296 } 297 } 298 299 // some online plugins are already installed ? 300 switch (state) 301 { 302 case REMOVING: 303 // special case where plugins are currently begin removed 304 action1Button.setText("Deleting..."); 305 action1Button.setEnabled(false); 306 break; 307 308 case INSTALLED: 309 action1Button.setText("Delete"); 310 action1Button.setEnabled(true); 311 break; 312 313 case NULL: 314 action1Button.setText("Delete"); 315 action1Button.setEnabled(false); 316 break; 317 } 318 319 state = PluginOnlineState.NULL; 320 for (PluginDescriptor plugin : selectedPlugins) 321 { 322 switch (getPluginOnlineState(plugin)) 323 { 324 case INSTALLING: 325 if (state == PluginOnlineState.NULL) 326 state = PluginOnlineState.INSTALLING; 327 break; 328 329 case OLDER: 330 if ((state == PluginOnlineState.NULL) || (state == PluginOnlineState.INSTALLING)) 331 state = PluginOnlineState.OLDER; 332 break; 333 334 case NEWER: 335 if ((state == PluginOnlineState.NULL) || (state == PluginOnlineState.INSTALLING) 336 || (state == PluginOnlineState.OLDER)) 337 state = PluginOnlineState.NEWER; 338 break; 339 340 case HAS_INSTALL: 341 state = PluginOnlineState.HAS_INSTALL; 342 break; 343 } 344 } 345 346 switch (state) 347 { 348 case INSTALLING: 349 action2Button.setText("Installing..."); 350 action2Button.setEnabled(false); 351 break; 352 353 case HAS_INSTALL: 354 action2Button.setText("Install"); 355 action2Button.setEnabled(true); 356 break; 357 358 case OLDER: 359 action2Button.setText("Revert"); 360 action2Button.setEnabled(true); 361 break; 362 363 case NEWER: 364 action2Button.setText("Update"); 365 action2Button.setEnabled(true); 366 break; 367 368 case NULL: 369 action2Button.setText("Install"); 370 action2Button.setEnabled(false); 371 break; 372 } 373 } 374 375 @Override 376 public void pluginRepositeryLoaderChanged(PluginDescriptor plugin) 377 { 378 if (plugin != null) 379 { 380 final int ind = getPluginModelIndex(plugin.getClassName()); 381 382 if (ind != -1) 383 { 384 ThreadUtil.invokeNow(new Runnable() 385 { 386 @Override 387 public void run() 388 { 389 try 390 { 391 tableModel.fireTableRowsUpdated(ind, ind); 392 } 393 catch (Exception e) 394 { 395 // ignore possible exception here 396 } 397 } 398 }); 399 } 400 } 401 else 402 pluginsChanged(); 403 } 404 405 @Override 406 public void pluginInstalled(PluginDescriptor plugin, boolean success) 407 { 408 refreshTableData(); 409 } 410 411 @Override 412 public void pluginRemoved(PluginDescriptor plugin, boolean success) 413 { 414 refreshTableData(); 415 } 416}