PageRenderTime 501ms CodeModel.GetById 11ms RepoModel.GetById 0ms app.codeStats 0ms

/jEdit/tags/jedit-4-2-pre14/org/gjt/sp/jedit/pluginmgr/InstallPanel.java

#
Java | 699 lines | 553 code | 88 blank | 58 comment | 76 complexity | 816f78f6636ae61007b5adb459bbf1c0 MD5 | raw file
Possible License(s): BSD-3-Clause, AGPL-1.0, Apache-2.0, LGPL-2.0, LGPL-3.0, GPL-2.0, CC-BY-SA-3.0, LGPL-2.1, GPL-3.0, MPL-2.0-no-copyleft-exception, IPL-1.0
  1. /*
  2. * InstallPanel.java - For installing plugins
  3. * :tabSize=8:indentSize=8:noTabs=false:
  4. * :folding=explicit:collapseFolds=1:
  5. *
  6. * Copyright (C) 2002 Kris Kopicki
  7. *
  8. * This program is free software; you can redistribute it and/or
  9. * modify it under the terms of the GNU General Public License
  10. * as published by the Free Software Foundation; either version 2
  11. * of the License, or any later version.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with this program; if not, write to the Free Software
  20. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  21. */
  22. package org.gjt.sp.jedit.pluginmgr;
  23. //{{{ Imports
  24. import javax.swing.border.*;
  25. import javax.swing.event.*;
  26. import javax.swing.table.*;
  27. import javax.swing.*;
  28. import java.awt.event.*;
  29. import java.awt.*;
  30. import java.text.NumberFormat;
  31. import java.util.*;
  32. import org.gjt.sp.jedit.gui.*;
  33. import org.gjt.sp.jedit.io.VFSManager;
  34. import org.gjt.sp.jedit.*;
  35. import org.gjt.sp.util.Log;
  36. //}}}
  37. class InstallPanel extends JPanel
  38. {
  39. //{{{ InstallPanel constructor
  40. InstallPanel(PluginManager window, boolean updates)
  41. {
  42. super(new BorderLayout(12,12));
  43. this.window = window;
  44. this.updates = updates;
  45. setBorder(new EmptyBorder(12,12,12,12));
  46. final JSplitPane split = new JSplitPane(
  47. JSplitPane.VERTICAL_SPLIT,true);
  48. /* Setup the table */
  49. table = new JTable(pluginModel = new PluginTableModel());
  50. table.setShowGrid(false);
  51. table.setIntercellSpacing(new Dimension(0,0));
  52. table.setRowHeight(table.getRowHeight() + 2);
  53. table.setPreferredScrollableViewportSize(new Dimension(500,200));
  54. table.setRequestFocusEnabled(false);
  55. table.getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
  56. table.setDefaultRenderer(Object.class, new TextRenderer(
  57. (DefaultTableCellRenderer)table.getDefaultRenderer(Object.class)));
  58. TableColumn col1 = table.getColumnModel().getColumn(0);
  59. TableColumn col2 = table.getColumnModel().getColumn(1);
  60. TableColumn col3 = table.getColumnModel().getColumn(2);
  61. TableColumn col4 = table.getColumnModel().getColumn(3);
  62. TableColumn col5 = table.getColumnModel().getColumn(4);
  63. col1.setPreferredWidth(30);
  64. col1.setMinWidth(30);
  65. col1.setMaxWidth(30);
  66. col1.setResizable(false);
  67. col2.setPreferredWidth(180);
  68. col3.setPreferredWidth(130);
  69. col4.setPreferredWidth(70);
  70. col5.setPreferredWidth(70);
  71. JTableHeader header = table.getTableHeader();
  72. header.setReorderingAllowed(false);
  73. header.addMouseListener(new HeaderMouseHandler());
  74. JScrollPane scrollpane = new JScrollPane(table);
  75. scrollpane.getViewport().setBackground(table.getBackground());
  76. split.setTopComponent(scrollpane);
  77. /* Create description */
  78. JScrollPane infoPane = new JScrollPane(
  79. infoBox = new PluginInfoBox());
  80. infoPane.setPreferredSize(new Dimension(500,100));
  81. split.setBottomComponent(infoPane);
  82. SwingUtilities.invokeLater(new Runnable()
  83. {
  84. public void run()
  85. {
  86. split.setDividerLocation(0.75);
  87. }
  88. });
  89. add(BorderLayout.CENTER,split);
  90. /* Create buttons */
  91. Box buttons = new Box(BoxLayout.X_AXIS);
  92. buttons.add(new InstallButton());
  93. buttons.add(Box.createHorizontalStrut(12));
  94. buttons.add(new SelectallButton());
  95. buttons.add(Box.createGlue());
  96. buttons.add(new SizeLabel());
  97. add(BorderLayout.SOUTH,buttons);
  98. } //}}}
  99. //{{{ updateModel() method
  100. public void updateModel()
  101. {
  102. pluginModel.clear();
  103. infoBox.setText(jEdit.getProperty("plugin-manager.list-download"));
  104. VFSManager.runInAWTThread(new Runnable()
  105. {
  106. public void run()
  107. {
  108. infoBox.setText(null);
  109. pluginModel.update();
  110. }
  111. });
  112. } //}}}
  113. //{{{ Private members
  114. //{{{ Variables
  115. private JTable table;
  116. private PluginTableModel pluginModel;
  117. private PluginManager window;
  118. private PluginInfoBox infoBox;
  119. private boolean updates;
  120. //}}}
  121. //{{{ formatSize() method
  122. private String formatSize(int size)
  123. {
  124. NumberFormat df = NumberFormat.getInstance();
  125. df.setMaximumFractionDigits(1);
  126. df.setMinimumFractionDigits(0);
  127. String sizeText;
  128. if (size < 1048576)
  129. sizeText = size/1024 + "KB";
  130. else
  131. sizeText = df.format(size/1048576d) + "MB";
  132. return sizeText;
  133. } //}}}
  134. //}}}
  135. //{{{ Inner classes
  136. //{{{ PluginTableModel class
  137. class PluginTableModel extends AbstractTableModel
  138. {
  139. private ArrayList entries = new ArrayList();
  140. private int sortType = EntryCompare.CATEGORY;
  141. //{{{ getColumnClass() method
  142. public Class getColumnClass(int columnIndex)
  143. {
  144. switch (columnIndex)
  145. {
  146. case 0: return Boolean.class;
  147. case 1:
  148. case 2:
  149. case 3:
  150. case 4: return Object.class;
  151. default: throw new Error("Column out of range");
  152. }
  153. } //}}}
  154. //{{{ getColumnCount() method
  155. public int getColumnCount()
  156. {
  157. return 5;
  158. } //}}}
  159. //{{{ getColumnName() method
  160. public String getColumnName(int column)
  161. {
  162. switch (column)
  163. {
  164. case 0: return " ";
  165. case 1: return " "+jEdit.getProperty("install-plugins.info.name");
  166. case 2: return " "+jEdit.getProperty("install-plugins.info.category");
  167. case 3: return " "+jEdit.getProperty("install-plugins.info.version");
  168. case 4: return " "+jEdit.getProperty("install-plugins.info.size");
  169. default: throw new Error("Column out of range");
  170. }
  171. } //}}}
  172. //{{{ getRowCount() method
  173. public int getRowCount()
  174. {
  175. return entries.size();
  176. } //}}}
  177. //{{{ getValueAt() method
  178. public Object getValueAt(int rowIndex,int columnIndex)
  179. {
  180. Object obj = entries.get(rowIndex);
  181. if(obj instanceof String)
  182. {
  183. if(columnIndex == 1)
  184. return obj;
  185. else
  186. return null;
  187. }
  188. else
  189. {
  190. Entry entry = (Entry)obj;
  191. switch (columnIndex)
  192. {
  193. case 0:
  194. return Boolean.valueOf(
  195. entry.install);
  196. case 1:
  197. return entry.name;
  198. case 2:
  199. return entry.set;
  200. case 3:
  201. return entry.version;
  202. case 4:
  203. return formatSize(entry.size);
  204. default:
  205. throw new Error("Column out of range");
  206. }
  207. }
  208. } //}}}
  209. //{{{ isCellEditable() method
  210. public boolean isCellEditable(int rowIndex, int columnIndex)
  211. {
  212. return (columnIndex == 0);
  213. } //}}}
  214. //{{{ setSelectAll() method
  215. public void setSelectAll(boolean b)
  216. {
  217. if(isDownloadingList())
  218. return;
  219. int length = getRowCount();
  220. for (int i = 0; i < length; i++)
  221. {
  222. if (b)
  223. setValueAt(Boolean.TRUE,i,0);
  224. else
  225. {
  226. Entry entry = (Entry)entries.get(i);
  227. entry.parents = new LinkedList();
  228. entry.install = false;
  229. }
  230. }
  231. fireTableChanged(new TableModelEvent(this));
  232. } //}}}
  233. //{{{ setSortType() method
  234. public void setSortType(int type)
  235. {
  236. sortType = type;
  237. sort(type);
  238. } //}}}
  239. //{{{ setValueAt() method
  240. public void setValueAt(Object aValue, int row, int column)
  241. {
  242. if (column != 0) return;
  243. Object obj = entries.get(row);
  244. if(obj instanceof String)
  245. return;
  246. Entry entry = (Entry)obj;
  247. Vector deps = entry.plugin.getCompatibleBranch().deps;
  248. boolean value = ((Boolean)aValue).booleanValue();
  249. if (!value)
  250. {
  251. if (entry.parents.size() > 0)
  252. {
  253. String[] args = {
  254. entry.name,
  255. entry.getParentString()
  256. };
  257. int result = GUIUtilities.confirm(
  258. window,"plugin-manager.dependency",
  259. args,JOptionPane.OK_CANCEL_OPTION,
  260. JOptionPane.WARNING_MESSAGE);
  261. if (result != JOptionPane.OK_OPTION)
  262. return;
  263. Iterator parentsIter = entry.parents.iterator();
  264. while(parentsIter.hasNext())
  265. {
  266. ((Entry)parentsIter.next()).install = false;
  267. }
  268. fireTableRowsUpdated(0,getRowCount() - 1);
  269. }
  270. }
  271. for (int i = 0; i < deps.size(); i++)
  272. {
  273. PluginList.Dependency dep = (PluginList.Dependency)deps.elementAt(i);
  274. if (dep.what.equals("plugin"))
  275. {
  276. for (int j = 0; j < entries.size(); j++)
  277. {
  278. Entry temp = (Entry)entries.get(j);
  279. if (temp.plugin == dep.plugin)
  280. {
  281. if (value)
  282. {
  283. temp.parents.add(entry);
  284. setValueAt(Boolean.TRUE,j,0);
  285. }
  286. else
  287. temp.parents.remove(entry);
  288. }
  289. }
  290. }
  291. }
  292. entry.install = Boolean.TRUE.equals(aValue);
  293. fireTableCellUpdated(row,column);
  294. } //}}}
  295. //{{{ sort() method
  296. public void sort(int type)
  297. {
  298. if(isDownloadingList())
  299. return;
  300. Collections.sort(entries,new EntryCompare(type));
  301. fireTableChanged(new TableModelEvent(this));
  302. }
  303. //}}}
  304. //{{{ isDownloadingList() method
  305. private boolean isDownloadingList()
  306. {
  307. return (entries.size() == 1 && entries.get(0) instanceof String);
  308. } //}}}
  309. //{{{ clear() method
  310. public void clear()
  311. {
  312. entries = new ArrayList();
  313. fireTableChanged(new TableModelEvent(this));
  314. } //}}}
  315. //{{{ update() method
  316. public void update()
  317. {
  318. PluginList pluginList = window.getPluginList();
  319. if (pluginList == null) return;
  320. entries = new ArrayList();
  321. for(int i = 0; i < pluginList.pluginSets.size(); i++)
  322. {
  323. PluginList.PluginSet set = (PluginList.PluginSet)
  324. pluginList.pluginSets.get(i);
  325. for(int j = 0; j < set.plugins.size(); j++)
  326. {
  327. PluginList.Plugin plugin = (PluginList.Plugin)
  328. pluginList.pluginHash.get(set.plugins.get(j));
  329. PluginList.Branch branch = plugin.getCompatibleBranch();
  330. String installedVersion =
  331. plugin.getInstalledVersion();
  332. if (updates)
  333. {
  334. if(branch != null
  335. && branch.canSatisfyDependencies()
  336. && installedVersion != null
  337. && MiscUtilities.compareStrings(branch.version,
  338. installedVersion,false) > 0)
  339. {
  340. entries.add(new Entry(plugin,set.name));
  341. }
  342. }
  343. else
  344. {
  345. if(installedVersion == null && plugin.canBeInstalled())
  346. entries.add(new Entry(plugin,set.name));
  347. }
  348. }
  349. }
  350. sort(sortType);
  351. fireTableChanged(new TableModelEvent(this));
  352. } //}}}
  353. } //}}}
  354. //{{{ Entry class
  355. class Entry
  356. {
  357. String name, version, author, date, description, set;
  358. int size;
  359. boolean install;
  360. PluginList.Plugin plugin;
  361. LinkedList parents = new LinkedList();
  362. Entry(PluginList.Plugin plugin, String set)
  363. {
  364. PluginList.Branch branch = plugin.getCompatibleBranch();
  365. boolean downloadSource = jEdit.getBooleanProperty("plugin-manager.downloadSource");
  366. int size = (downloadSource) ? branch.downloadSourceSize : branch.downloadSize;
  367. this.name = plugin.name;
  368. this.author = plugin.author;
  369. this.version = branch.version;
  370. this.size = size;
  371. this.date = branch.date;
  372. this.description = plugin.description;
  373. this.set = set;
  374. this.install = false;
  375. this.plugin = plugin;
  376. }
  377. String getParentString()
  378. {
  379. StringBuffer buf = new StringBuffer();
  380. Iterator iter = parents.iterator();
  381. while(iter.hasNext())
  382. {
  383. buf.append(((Entry)iter.next()).name);
  384. if(iter.hasNext())
  385. buf.append('\n');
  386. }
  387. return buf.toString();
  388. }
  389. } //}}}
  390. //{{{ PluginInfoBox class
  391. class PluginInfoBox extends JTextArea implements ListSelectionListener
  392. {
  393. public PluginInfoBox()
  394. {
  395. setEditable(false);
  396. setLineWrap(true);
  397. setWrapStyleWord(true);
  398. table.getSelectionModel().addListSelectionListener(this);
  399. }
  400. public void valueChanged(ListSelectionEvent e)
  401. {
  402. String text = "";
  403. if (table.getSelectedRowCount() == 1)
  404. {
  405. Entry entry = (Entry)pluginModel.entries
  406. .get(table.getSelectedRow());
  407. text = jEdit.getProperty("install-plugins.info",
  408. new String[] {entry.author,entry.date,entry.description});
  409. }
  410. setText(text);
  411. setCaretPosition(0);
  412. }
  413. } //}}}
  414. //{{{ SizeLabel class
  415. class SizeLabel extends JLabel implements TableModelListener
  416. {
  417. private int size;
  418. public SizeLabel()
  419. {
  420. size = 0;
  421. setText(jEdit.getProperty("install-plugins.totalSize")+formatSize(size));
  422. pluginModel.addTableModelListener(this);
  423. }
  424. public void tableChanged(TableModelEvent e)
  425. {
  426. if (e.getType() == TableModelEvent.UPDATE)
  427. {
  428. if(pluginModel.isDownloadingList())
  429. return;
  430. size = 0;
  431. int length = pluginModel.getRowCount();
  432. for (int i = 0; i < length; i++)
  433. {
  434. Entry entry = (Entry)pluginModel
  435. .entries.get(i);
  436. if (entry.install)
  437. size += entry.size;
  438. }
  439. setText(jEdit.getProperty("install-plugins.totalSize")+formatSize(size));
  440. }
  441. }
  442. } //}}}
  443. //{{{ SelectallButton class
  444. class SelectallButton extends JCheckBox implements ActionListener, TableModelListener
  445. {
  446. public SelectallButton()
  447. {
  448. super(jEdit.getProperty("install-plugins.select-all"));
  449. addActionListener(this);
  450. pluginModel.addTableModelListener(this);
  451. setEnabled(false);
  452. }
  453. public void actionPerformed(ActionEvent evt)
  454. {
  455. pluginModel.setSelectAll(isSelected());
  456. }
  457. public void tableChanged(TableModelEvent e)
  458. {
  459. if(pluginModel.isDownloadingList())
  460. return;
  461. setEnabled(pluginModel.getRowCount() != 0);
  462. if (e.getType() == TableModelEvent.UPDATE)
  463. {
  464. int length = pluginModel.getRowCount();
  465. for (int i = 0; i < length; i++)
  466. if (!((Boolean)pluginModel.getValueAt(i,0)).booleanValue())
  467. {
  468. setSelected(false);
  469. return;
  470. }
  471. if (length > 0)
  472. setSelected(true);
  473. }
  474. }
  475. } //}}}
  476. //{{{ InstallButton class
  477. class InstallButton extends JButton implements ActionListener, TableModelListener
  478. {
  479. public InstallButton()
  480. {
  481. super(jEdit.getProperty("install-plugins.install"));
  482. pluginModel.addTableModelListener(this);
  483. addActionListener(this);
  484. setEnabled(false);
  485. }
  486. public void actionPerformed(ActionEvent evt)
  487. {
  488. if(pluginModel.isDownloadingList())
  489. return;
  490. boolean downloadSource = jEdit.getBooleanProperty(
  491. "plugin-manager.downloadSource");
  492. boolean installUser = jEdit.getBooleanProperty(
  493. "plugin-manager.installUser");
  494. Roster roster = new Roster();
  495. String installDirectory;
  496. if(installUser)
  497. {
  498. installDirectory = MiscUtilities.constructPath(
  499. jEdit.getSettingsDirectory(),"jars");
  500. }
  501. else
  502. {
  503. installDirectory = MiscUtilities.constructPath(
  504. jEdit.getJEditHome(),"jars");
  505. }
  506. int length = pluginModel.getRowCount();
  507. int instcount = 0;
  508. for (int i = 0; i < length; i++)
  509. {
  510. Entry entry = (Entry)pluginModel.entries.get(i);
  511. if (entry.install)
  512. {
  513. entry.plugin.install(roster,installDirectory,downloadSource);
  514. if (updates)
  515. entry.plugin.getCompatibleBranch().satisfyDependencies(
  516. roster,installDirectory,downloadSource);
  517. instcount++;
  518. }
  519. }
  520. if(roster.isEmpty())
  521. return;
  522. boolean cancel = false;
  523. if (updates && roster.getOperationCount() > instcount)
  524. if (GUIUtilities.confirm(window,
  525. "install-plugins.depend",
  526. null,
  527. JOptionPane.OK_CANCEL_OPTION,
  528. JOptionPane.WARNING_MESSAGE) == JOptionPane.CANCEL_OPTION)
  529. cancel = true;
  530. if (!cancel)
  531. {
  532. new PluginManagerProgress(window,roster);
  533. roster.performOperationsInAWTThread(window);
  534. pluginModel.update();
  535. }
  536. }
  537. public void tableChanged(TableModelEvent e)
  538. {
  539. if(pluginModel.isDownloadingList())
  540. return;
  541. if (e.getType() == TableModelEvent.UPDATE)
  542. {
  543. int length = pluginModel.getRowCount();
  544. for (int i = 0; i < length; i++)
  545. if (((Boolean)pluginModel.getValueAt(i,0)).booleanValue())
  546. {
  547. setEnabled(true);
  548. return;
  549. }
  550. setEnabled(false);
  551. }
  552. }
  553. } //}}}
  554. //{{{ EntryCompare class
  555. static class EntryCompare implements Comparator
  556. {
  557. public static final int NAME = 0;
  558. public static final int CATEGORY = 1;
  559. private int type;
  560. public EntryCompare(int type)
  561. {
  562. this.type = type;
  563. }
  564. public int compare(Object o1, Object o2)
  565. {
  566. InstallPanel.Entry e1 = (InstallPanel.Entry)o1;
  567. InstallPanel.Entry e2 = (InstallPanel.Entry)o2;
  568. if (type == NAME)
  569. return e1.name.compareToIgnoreCase(e2.name);
  570. else
  571. {
  572. int result;
  573. if ((result = e1.set.compareToIgnoreCase(e2.set)) == 0)
  574. return e1.name.compareToIgnoreCase(e2.name);
  575. return result;
  576. }
  577. }
  578. } //}}}
  579. //{{{ HeaderMouseHandler class
  580. class HeaderMouseHandler extends MouseAdapter
  581. {
  582. public void mouseClicked(MouseEvent evt)
  583. {
  584. switch(table.getTableHeader().columnAtPoint(evt.getPoint()))
  585. {
  586. case 1:
  587. pluginModel.sort(EntryCompare.NAME);
  588. break;
  589. case 2:
  590. pluginModel.sort(EntryCompare.CATEGORY);
  591. break;
  592. default:
  593. }
  594. }
  595. } //}}}
  596. //{{{ TextRenderer
  597. class TextRenderer extends DefaultTableCellRenderer
  598. {
  599. private DefaultTableCellRenderer tcr;
  600. public TextRenderer(DefaultTableCellRenderer tcr)
  601. {
  602. this.tcr = tcr;
  603. }
  604. public Component getTableCellRendererComponent(JTable table, Object value,
  605. boolean isSelected, boolean hasFocus, int row, int column)
  606. {
  607. return tcr.getTableCellRendererComponent(table,value,isSelected,false,row,column);
  608. }
  609. } //}}}
  610. //}}}
  611. }