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

# · Java · 631 lines · 494 code · 80 blank · 57 comment · 64 complexity · 8e8cf15507d7bf0878719a33c8a7148e MD5 · raw file

  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.*;
  34. import org.gjt.sp.util.Log;
  35. //}}}
  36. class InstallPanel extends JPanel
  37. {
  38. //{{{ InstallPanel constructor
  39. InstallPanel(PluginManager window, boolean updates)
  40. {
  41. super(new BorderLayout(12,12));
  42. this.window = window;
  43. this.updates = updates;
  44. setBorder(new EmptyBorder(12,12,12,12));
  45. JSplitPane split = new JSplitPane(JSplitPane.VERTICAL_SPLIT,true);
  46. /* Setup the table */
  47. table = new JTable(pluginModel = new PluginTableModel());
  48. table.setShowGrid(false);
  49. table.setIntercellSpacing(new Dimension(0,0));
  50. table.setRowHeight(table.getRowHeight() + 2);
  51. table.setPreferredScrollableViewportSize(new Dimension(500,200));
  52. table.setRequestFocusEnabled(false);
  53. table.getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
  54. table.setDefaultRenderer(Object.class, new TextRenderer(
  55. (DefaultTableCellRenderer)table.getDefaultRenderer(Object.class)));
  56. TableColumn col1 = table.getColumnModel().getColumn(0);
  57. TableColumn col2 = table.getColumnModel().getColumn(1);
  58. TableColumn col3 = table.getColumnModel().getColumn(2);
  59. TableColumn col4 = table.getColumnModel().getColumn(3);
  60. TableColumn col5 = table.getColumnModel().getColumn(4);
  61. col1.setPreferredWidth(30);
  62. col1.setMinWidth(30);
  63. col1.setMaxWidth(30);
  64. col1.setResizable(false);
  65. col2.setPreferredWidth(180);
  66. col3.setPreferredWidth(130);
  67. col4.setPreferredWidth(70);
  68. col5.setPreferredWidth(70);
  69. JTableHeader header = table.getTableHeader();
  70. header.setReorderingAllowed(false);
  71. header.addMouseListener(new HeaderMouseHandler());
  72. JScrollPane scrollpane = new JScrollPane(table);
  73. scrollpane.getViewport().setBackground(table.getBackground());
  74. split.setTopComponent(scrollpane);
  75. /* Create description */
  76. JScrollPane infoPane = new JScrollPane(new PluginInfoBox());
  77. infoPane.setPreferredSize(new Dimension(500,100));
  78. split.setBottomComponent(infoPane);
  79. split.setDividerLocation(200);
  80. add(BorderLayout.CENTER,split);
  81. /* Create buttons */
  82. Box buttons = new Box(BoxLayout.X_AXIS);
  83. buttons.add(new InstallButton());
  84. buttons.add(Box.createHorizontalStrut(12));
  85. buttons.add(new SelectallButton());
  86. buttons.add(Box.createGlue());
  87. buttons.add(new SizeLabel());
  88. add(BorderLayout.SOUTH,buttons);
  89. } //}}}
  90. //{{{ updateModel() method
  91. public void updateModel()
  92. {
  93. pluginModel.update();
  94. } //}}}
  95. //{{{ Private members
  96. //{{{ Variables
  97. private JTable table;
  98. private PluginTableModel pluginModel;
  99. private PluginManager window;
  100. private boolean updates;
  101. //}}}
  102. //{{{ formatSize() method
  103. private String formatSize(int size)
  104. {
  105. NumberFormat df = NumberFormat.getInstance();
  106. df.setMaximumFractionDigits(1);
  107. df.setMinimumFractionDigits(0);
  108. String sizeText;
  109. if (size < 1048576)
  110. sizeText = size/1024 + "KB";
  111. else
  112. sizeText = df.format(size/1048576d) + "MB";
  113. return sizeText;
  114. } //}}}
  115. //}}}
  116. //{{{ Inner classes
  117. //{{{ PluginTableModel class
  118. class PluginTableModel extends AbstractTableModel
  119. {
  120. private ArrayList entries = new ArrayList();
  121. private int sortType = EntryCompare.CATEGORY;
  122. //{{{ getColumnClass() method
  123. public Class getColumnClass(int columnIndex)
  124. {
  125. switch (columnIndex)
  126. {
  127. case 0: return Boolean.class;
  128. case 1:
  129. case 2:
  130. case 3:
  131. case 4: return Object.class;
  132. default: throw new Error("Column out of range");
  133. }
  134. } //}}}
  135. //{{{ getColumnCount() method
  136. public int getColumnCount()
  137. {
  138. return 5;
  139. } //}}}
  140. //{{{ getColumnName() method
  141. public String getColumnName(int column)
  142. {
  143. switch (column)
  144. {
  145. case 0: return " ";
  146. case 1: return " "+jEdit.getProperty("install-plugins.info.name");
  147. case 2: return " "+jEdit.getProperty("install-plugins.info.category");
  148. case 3: return " "+jEdit.getProperty("install-plugins.info.version");
  149. case 4: return " "+jEdit.getProperty("install-plugins.info.size");
  150. default: throw new Error("Column out of range");
  151. }
  152. } //}}}
  153. //{{{ getEntry() method
  154. public Entry getEntry(int rowIndex)
  155. {
  156. return (Entry)entries.get(rowIndex);
  157. } //}}}
  158. //{{{ getRowCount() method
  159. public int getRowCount()
  160. {
  161. return entries.size();
  162. } //}}}
  163. //{{{ getValueAt() method
  164. public Object getValueAt(int rowIndex,int columnIndex)
  165. {
  166. Entry entry = (Entry)entries.get(rowIndex);
  167. switch (columnIndex)
  168. {
  169. case 0: return new Boolean(entry.install);
  170. case 1: return entry.name;
  171. case 2: return entry.set;
  172. case 3: return entry.version;
  173. case 4: return formatSize(entry.size);
  174. default: throw new Error("Column out of range");
  175. }
  176. } //}}}
  177. //{{{ isCellEditable() method
  178. public boolean isCellEditable(int rowIndex, int columnIndex)
  179. {
  180. return (columnIndex == 0);
  181. } //}}}
  182. //{{{ setSelectAll() method
  183. public void setSelectAll(boolean b)
  184. {
  185. int length = getRowCount();
  186. for (int i = 0; i < length; i++)
  187. {
  188. if (b)
  189. setValueAt(new Boolean(true),i,0);
  190. else
  191. {
  192. Entry entry = getEntry(i);
  193. entry.parents = new LinkedList();
  194. entry.install = false;
  195. }
  196. }
  197. fireTableChanged(new TableModelEvent(this));
  198. } //}}}
  199. //{{{ setSortType() method
  200. public void setSortType(int type)
  201. {
  202. sortType = type;
  203. sort(type);
  204. } //}}}
  205. //{{{ setValueAt() method
  206. public void setValueAt(Object aValue, int row, int column)
  207. {
  208. if (column != 0) return;
  209. Entry entry = getEntry(row);
  210. Vector deps = entry.plugin.getCompatibleBranch().deps;
  211. boolean value = ((Boolean)aValue).booleanValue();
  212. if (!value)
  213. {
  214. if (entry.parents.size() > 0)
  215. {
  216. String[] args = {
  217. entry.name,
  218. entry.getParentString()
  219. };
  220. int result = GUIUtilities.confirm(
  221. window,"plugin-manager.dependency",
  222. args,JOptionPane.OK_CANCEL_OPTION,
  223. JOptionPane.WARNING_MESSAGE);
  224. if (result != JOptionPane.OK_OPTION)
  225. return;
  226. Iterator parentsIter = entry.parents.iterator();
  227. while(parentsIter.hasNext())
  228. {
  229. ((Entry)parentsIter.next()).install = false;
  230. }
  231. fireTableRowsUpdated(0,getRowCount() - 1);
  232. }
  233. }
  234. for (int i = 0; i < deps.size(); i++)
  235. {
  236. PluginList.Dependency dep = (PluginList.Dependency)deps.elementAt(i);
  237. if (dep.what.equals("plugin"))
  238. {
  239. for (int j = 0; j < entries.size(); j++)
  240. {
  241. Entry temp = (Entry)entries.get(j);
  242. if (temp.plugin == dep.plugin)
  243. {
  244. if (value)
  245. {
  246. temp.parents.add(entry);
  247. setValueAt(new Boolean(true),j,0);
  248. }
  249. else
  250. temp.parents.remove(entry);
  251. }
  252. }
  253. }
  254. }
  255. entry.install = Boolean.TRUE.equals(aValue);
  256. fireTableCellUpdated(row,column);
  257. } //}}}
  258. //{{{ sort() method
  259. public void sort(int type)
  260. {
  261. Collections.sort(entries,new EntryCompare(type));
  262. fireTableChanged(new TableModelEvent(this));
  263. }
  264. //}}}
  265. //{{{ update() method
  266. public void update()
  267. {
  268. PluginList pluginList = window.getPluginList();
  269. if (pluginList == null) return;
  270. entries = new ArrayList();
  271. for(int i = 0; i < pluginList.pluginSets.size(); i++)
  272. {
  273. PluginList.PluginSet set = (PluginList.PluginSet)
  274. pluginList.pluginSets.get(i);
  275. for(int j = 0; j < set.plugins.size(); j++)
  276. {
  277. PluginList.Plugin plugin = (PluginList.Plugin)
  278. pluginList.pluginHash.get(set.plugins.get(j));
  279. PluginList.Branch branch = plugin.getCompatibleBranch();
  280. String installedVersion =
  281. plugin.getInstalledVersion();
  282. if (updates)
  283. {
  284. if(branch != null
  285. && branch.canSatisfyDependencies()
  286. && installedVersion != null
  287. && MiscUtilities.compareStrings(branch.version,
  288. installedVersion,false) > 0)
  289. {
  290. entries.add(new Entry(plugin,set.name));
  291. }
  292. }
  293. else
  294. {
  295. if(installedVersion == null && plugin.canBeInstalled())
  296. entries.add(new Entry(plugin,set.name));
  297. }
  298. }
  299. }
  300. sort(sortType);
  301. fireTableChanged(new TableModelEvent(this));
  302. } //}}}
  303. } //}}}
  304. //{{{ Entry class
  305. class Entry
  306. {
  307. String name, version, author, date, description, set;
  308. int size;
  309. boolean install;
  310. PluginList.Plugin plugin;
  311. LinkedList parents = new LinkedList();
  312. Entry(PluginList.Plugin plugin, String set)
  313. {
  314. PluginList.Branch branch = plugin.getCompatibleBranch();
  315. boolean downloadSource = jEdit.getBooleanProperty("plugin-manager.downloadSource");
  316. int size = (downloadSource) ? branch.downloadSourceSize : branch.downloadSize;
  317. this.name = plugin.name;
  318. this.author = plugin.author;
  319. this.version = branch.version;
  320. this.size = size;
  321. this.date = branch.date;
  322. this.description = plugin.description;
  323. this.set = set;
  324. this.install = false;
  325. this.plugin = plugin;
  326. }
  327. String getParentString()
  328. {
  329. StringBuffer buf = new StringBuffer();
  330. Iterator iter = parents.iterator();
  331. while(iter.hasNext())
  332. {
  333. buf.append(((Entry)iter.next()).name);
  334. if(iter.hasNext())
  335. buf.append('\n');
  336. }
  337. return buf.toString();
  338. }
  339. } //}}}
  340. //{{{ PluginInfoBox class
  341. class PluginInfoBox extends JTextArea implements ListSelectionListener
  342. {
  343. public PluginInfoBox()
  344. {
  345. setEditable(false);
  346. setLineWrap(true);
  347. setWrapStyleWord(true);
  348. table.getSelectionModel().addListSelectionListener(this);
  349. }
  350. public void valueChanged(ListSelectionEvent e)
  351. {
  352. String text = "";
  353. if (table.getSelectedRowCount() == 1)
  354. {
  355. Entry entry = pluginModel.getEntry(table.getSelectedRow());
  356. text = jEdit.getProperty("install-plugins.info",
  357. new String[] {entry.author,entry.date,entry.description});
  358. }
  359. setText(text);
  360. setCaretPosition(0);
  361. }
  362. } //}}}
  363. //{{{ SizeLabel class
  364. class SizeLabel extends JLabel implements TableModelListener
  365. {
  366. private int size;
  367. public SizeLabel()
  368. {
  369. size = 0;
  370. setText(jEdit.getProperty("install-plugins.totalSize")+formatSize(size));
  371. pluginModel.addTableModelListener(this);
  372. }
  373. public void tableChanged(TableModelEvent e)
  374. {
  375. if (e.getType() == TableModelEvent.UPDATE)
  376. {
  377. size = 0;
  378. int length = pluginModel.getRowCount();
  379. for (int i = 0; i < length; i++)
  380. {
  381. Entry entry = pluginModel.getEntry(i);
  382. if (entry.install)
  383. size += entry.size;
  384. }
  385. setText(jEdit.getProperty("install-plugins.totalSize")+formatSize(size));
  386. }
  387. }
  388. } //}}}
  389. //{{{ SelectallButton class
  390. class SelectallButton extends JCheckBox implements ActionListener, TableModelListener
  391. {
  392. public SelectallButton()
  393. {
  394. super(jEdit.getProperty("install-plugins.select-all"));
  395. addActionListener(this);
  396. pluginModel.addTableModelListener(this);
  397. setEnabled(false);
  398. }
  399. public void actionPerformed(ActionEvent evt)
  400. {
  401. pluginModel.setSelectAll(isSelected());
  402. }
  403. public void tableChanged(TableModelEvent e)
  404. {
  405. setEnabled(pluginModel.getRowCount() != 0);
  406. if (e.getType() == TableModelEvent.UPDATE)
  407. {
  408. int length = pluginModel.getRowCount();
  409. for (int i = 0; i < length; i++)
  410. if (!((Boolean)pluginModel.getValueAt(i,0)).booleanValue())
  411. {
  412. setSelected(false);
  413. return;
  414. }
  415. if (length > 0)
  416. setSelected(true);
  417. }
  418. }
  419. } //}}}
  420. //{{{ InstallButton class
  421. class InstallButton extends JButton implements ActionListener, TableModelListener
  422. {
  423. public InstallButton()
  424. {
  425. super(jEdit.getProperty("install-plugins.install"));
  426. pluginModel.addTableModelListener(this);
  427. addActionListener(this);
  428. setEnabled(false);
  429. }
  430. public void actionPerformed(ActionEvent evt)
  431. {
  432. boolean downloadSource = jEdit.getBooleanProperty(
  433. "plugin-manager.downloadSource");
  434. boolean installUser = jEdit.getBooleanProperty(
  435. "plugin-manager.installUser");
  436. Roster roster = new Roster();
  437. String installDirectory;
  438. if(installUser)
  439. {
  440. installDirectory = MiscUtilities.constructPath(
  441. jEdit.getSettingsDirectory(),"jars");
  442. }
  443. else
  444. {
  445. installDirectory = MiscUtilities.constructPath(
  446. jEdit.getJEditHome(),"jars");
  447. }
  448. int length = pluginModel.getRowCount();
  449. int instcount = 0;
  450. for (int i = 0; i < length; i++)
  451. {
  452. Entry entry = pluginModel.getEntry(i);
  453. if (entry.install)
  454. {
  455. entry.plugin.install(roster,installDirectory,downloadSource);
  456. if (updates)
  457. entry.plugin.getCompatibleBranch().satisfyDependencies(
  458. roster,installDirectory,downloadSource);
  459. instcount++;
  460. }
  461. }
  462. if(roster.isEmpty())
  463. return;
  464. boolean cancel = false;
  465. if (updates && roster.getOperationCount() > instcount)
  466. if (GUIUtilities.confirm(window,
  467. "install-plugins.depend",
  468. null,
  469. JOptionPane.OK_CANCEL_OPTION,
  470. JOptionPane.WARNING_MESSAGE) == JOptionPane.CANCEL_OPTION)
  471. cancel = true;
  472. if (!cancel)
  473. {
  474. new PluginManagerProgress(window,roster);
  475. roster.performOperationsInAWTThread(window);
  476. pluginModel.update();
  477. }
  478. }
  479. public void tableChanged(TableModelEvent e)
  480. {
  481. if (e.getType() == TableModelEvent.UPDATE)
  482. {
  483. int length = pluginModel.getRowCount();
  484. for (int i = 0; i < length; i++)
  485. if (((Boolean)pluginModel.getValueAt(i,0)).booleanValue())
  486. {
  487. setEnabled(true);
  488. return;
  489. }
  490. setEnabled(false);
  491. }
  492. }
  493. } //}}}
  494. //{{{ EntryCompare class
  495. static class EntryCompare implements Comparator
  496. {
  497. public static final int NAME = 0;
  498. public static final int CATEGORY = 1;
  499. private int type;
  500. public EntryCompare(int type)
  501. {
  502. this.type = type;
  503. }
  504. public int compare(Object o1, Object o2)
  505. {
  506. Entry e1 = (Entry)o1;
  507. Entry e2 = (Entry)o2;
  508. if (type == NAME)
  509. return e1.name.compareToIgnoreCase(e2.name);
  510. else
  511. {
  512. int result;
  513. if ((result = e1.set.compareToIgnoreCase(e2.set)) == 0)
  514. return e1.name.compareToIgnoreCase(e2.name);
  515. return result;
  516. }
  517. }
  518. } //}}}
  519. //{{{ HeaderMouseHandler()
  520. class HeaderMouseHandler extends MouseAdapter
  521. {
  522. public void mouseClicked(MouseEvent evt)
  523. {
  524. switch(table.getTableHeader().columnAtPoint(evt.getPoint()))
  525. {
  526. case 1:
  527. pluginModel.sort(EntryCompare.NAME);
  528. break;
  529. case 2:
  530. pluginModel.sort(EntryCompare.CATEGORY);
  531. break;
  532. default:
  533. }
  534. }
  535. } //}}}
  536. //{{{ TextRenderer
  537. class TextRenderer extends DefaultTableCellRenderer
  538. {
  539. private DefaultTableCellRenderer tcr;
  540. public TextRenderer(DefaultTableCellRenderer tcr)
  541. {
  542. this.tcr = tcr;
  543. }
  544. public Component getTableCellRendererComponent(JTable table, Object value,
  545. boolean isSelected, boolean hasFocus, int row, int column)
  546. {
  547. return tcr.getTableCellRendererComponent(table,value,isSelected,false,row,column);
  548. }
  549. } //}}}
  550. //}}}
  551. }