PageRenderTime 43ms CodeModel.GetById 9ms RepoModel.GetById 0ms app.codeStats 0ms

/projects/netbeans-7.3/cnd.script/src/org/netbeans/modules/cnd/makefile/wizard/MakefileWizard.java

https://gitlab.com/essere.lab.public/qualitas.class-corpus
Java | 1091 lines | 727 code | 126 blank | 238 comment | 123 complexity | e071494a216c1a035f81b24989f27eed MD5 | raw file
  1. /*
  2. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
  3. *
  4. * Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
  5. *
  6. * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
  7. * Other names may be trademarks of their respective owners.
  8. *
  9. * The contents of this file are subject to the terms of either the GNU
  10. * General Public License Version 2 only ("GPL") or the Common
  11. * Development and Distribution License("CDDL") (collectively, the
  12. * "License"). You may not use this file except in compliance with the
  13. * License. You can obtain a copy of the License at
  14. * http://www.netbeans.org/cddl-gplv2.html
  15. * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
  16. * specific language governing permissions and limitations under the
  17. * License. When distributing the software, include this License Header
  18. * Notice in each file and include the License file at
  19. * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
  20. * particular file as subject to the "Classpath" exception as provided
  21. * by Oracle in the GPL Version 2 section of the License file that
  22. * accompanied this code. If applicable, add the following below the
  23. * License Header, with the fields enclosed by brackets [] replaced by
  24. * your own identifying information:
  25. * "Portions Copyrighted [year] [name of copyright owner]"
  26. *
  27. * Contributor(s):
  28. *
  29. * The Original Software is NetBeans. The Initial Developer of the Original
  30. * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
  31. * Microsystems, Inc. All Rights Reserved.
  32. *
  33. * If you wish your version of this file to be governed by only the CDDL
  34. * or only the GPL Version 2, indicate your decision by adding
  35. * "[Contributor] elects to include this software in this distribution
  36. * under the [CDDL or GPL Version 2] license." If you do not indicate a
  37. * single choice of license, a recipient has the option to distribute
  38. * your version of this file under either the CDDL, the GPL Version 2 or
  39. * to extend the choice of license to its licensees as provided above.
  40. * However, if you add GPL Version 2 code and therefore, elected the GPL
  41. * Version 2 license, then the option applies only if the new code is
  42. * made subject to such option by the copyright holder.
  43. */
  44. package org.netbeans.modules.cnd.makefile.wizard;
  45. import java.beans.PropertyChangeEvent;
  46. import java.beans.PropertyChangeListener;
  47. import java.io.File;
  48. import java.io.IOException;
  49. import java.text.MessageFormat;
  50. import java.util.ArrayList;
  51. import java.util.Collections;
  52. import java.util.HashSet;
  53. import java.util.Iterator;
  54. import java.util.LinkedList;
  55. import java.util.List;
  56. import java.util.ListIterator;
  57. import java.util.NoSuchElementException;
  58. import java.util.Set;
  59. import java.util.Vector;
  60. import javax.swing.JButton;
  61. import javax.swing.JPanel;
  62. import javax.swing.event.ChangeEvent;
  63. import javax.swing.event.ChangeListener;
  64. import org.netbeans.modules.cnd.builds.MakeExecSupport;
  65. import org.netbeans.modules.cnd.utils.CndPathUtilitities;
  66. import org.netbeans.modules.cnd.utils.cache.CndFileUtils;
  67. import org.openide.DialogDescriptor;
  68. import org.openide.WizardDescriptor;
  69. import org.openide.cookies.OpenCookie;
  70. import org.openide.filesystems.FileObject;
  71. import org.openide.loaders.DataFolder;
  72. import org.openide.loaders.DataObject;
  73. import org.openide.loaders.TemplateWizard;
  74. import org.openide.util.NbBundle;
  75. public class MakefileWizard implements TemplateWizard.Iterator {
  76. /** Holds list of event listeners */
  77. private static Vector<MakefileWizardListener> listenerList = null;
  78. protected TemplateWizard wd;
  79. /** Current array of panels */
  80. protected Object[] panels;
  81. /** Store a pointer to the current panel */
  82. private WizardDescriptor.Panel currentPanel;
  83. /** Array of panels for all types except
  84. * MakefileData.COMPLEX_MAKEFILE_TYPE.
  85. */
  86. protected Object[] normalPanels;
  87. /** LinkedList of panels for MakefileData.COMPLEX_MAKEFILE_TYPE */
  88. protected LinkedList<Object> complexPanels;
  89. /** Makefile data */
  90. private MakefileData makefileData;
  91. /** The MakefileWizard */
  92. private static MakefileWizard makefileWizard;
  93. /** Wizard title */
  94. private String title;
  95. /** Index into the array */
  96. private int index;
  97. /** The index into the displayed steps (different than index) */
  98. private int virtIndex;
  99. /** Index into complexPanels where new panels should be added */
  100. private int addIdx;
  101. /** The Next button is needed to reset the default button */
  102. private JButton nextButton;
  103. /** The Finish button is needed to change the label to Last */
  104. private JButton finishButton;
  105. /** The cancel button */
  106. private JButton cancelButton;
  107. /** Save the Finish button's original label */
  108. private String finishLabel;
  109. /** Save the Finish button's original mnemonic too */
  110. private int finishMnemonic;
  111. /** Are we doing Last updates to keep it enabled? */
  112. private boolean finishEnabled;
  113. /** Tells if we have output the Compilation Preferences yet */
  114. private boolean haveCompilerFlags;
  115. /** template wizard property change listener ... */
  116. private PropertyChangeListener listener = null;
  117. private WizardDescriptor.Panel targetChooserDescriptorPanel;
  118. private WizardDescriptor.Panel baseDirectoryDescriptorPanel;
  119. private WizardDescriptor.Panel targetNameDescriptorPanel;
  120. private WizardDescriptor.Panel makefileSourcesDescriptorPanel;
  121. private WizardDescriptor.Panel selectPreferencesDescriptorPanel;
  122. //private WizardDescriptor.Panel compilerTypeDescriptorPanel;
  123. private WizardDescriptor.Panel platformTypeDescriptorPanel;
  124. private WizardDescriptor.Panel createTargetsDescriptorPanel;
  125. private WizardDescriptor.Panel buildOutputDescriptorPanel;
  126. private WizardDescriptor.Panel makefileIncludesDescriptorPanel;
  127. private WizardDescriptor.Panel standardLibsDescriptorPanel;
  128. private WizardDescriptor.Panel userLibsDescriptorPanel;
  129. private WizardDescriptor.Panel compilerOptionsDescriptorPanel;
  130. private WizardDescriptor.Panel basicFlagsDescriptorPanel;
  131. private WizardDescriptor.Panel compilerPathDescriptorPanel;
  132. //private WizardDescriptor.Panel makeTargetDescriptorPanel;
  133. //private WizardDescriptor.Panel customTargetDescriptorPanel;
  134. private WizardDescriptor.Panel makefileReviewDescriptorPanel;
  135. /**
  136. * Constructor Note: A panel object gets created for each panel in this
  137. * constructor. However, the object creation is very light-weight
  138. * (mainly just creating the subtitle) and the real creation is deffered
  139. * until the panel is displayed for the first time.
  140. */
  141. public MakefileWizard() {
  142. makefileWizard = this;
  143. String aTitle = NbBundle.getBundle(MakefileWizard.class).
  144. getString("LBL_MakefileWizardTitle"); // NOI18N
  145. setTitle(aTitle);
  146. makefileData = new MakefileData();
  147. }
  148. private void initPanels() {
  149. // Panels used in both SIMPLE_* and COMPLEX_* targets
  150. targetChooserDescriptorPanel = wd.targetChooser();
  151. baseDirectoryDescriptorPanel = new MakefileWizardDescriptorPanel(new BaseDirectoryPanel(this), "base_directory"); // NOI18N
  152. targetNameDescriptorPanel = new MakefileWizardDescriptorPanel(new TargetNamePanel(this), "target_name"); // NOI18N
  153. makefileSourcesDescriptorPanel = new MakefileWizardDescriptorPanel(new MakefileSourcesPanel(this), "source_files"); // NOI18N
  154. //compilerTypeDescriptorPanel = new MakefileWizardDescriptorPanel(new CompilerTypePanel(this));
  155. selectPreferencesDescriptorPanel = new MakefileWizardDescriptorPanel(new SelectPreferencesPanel(this), "compiling_preference"); // NOI18N
  156. // Panels used by just the COMPLEX_* targets
  157. createTargetsDescriptorPanel = new MakefileWizardDescriptorPanel(new CreateTargetsPanel(this), "list_of_targets"); // NOI18N
  158. platformTypeDescriptorPanel = new MakefileWizardDescriptorPanel(new PlatformTypePanel(this), "type_and_platform"); // NOI18N
  159. buildOutputDescriptorPanel = new MakefileWizardDescriptorPanel(new BuildOutputPanel(this), "build_output"); // NOI18N
  160. makefileIncludesDescriptorPanel = new MakefileWizardDescriptorPanel(new MakefileIncludesPanel(this), "include_directories"); // NOI18N
  161. standardLibsDescriptorPanel = new MakefileWizardDescriptorPanel(new StandardLibsPanel(this), "standard_libraries"); // NOI18N
  162. userLibsDescriptorPanel = new MakefileWizardDescriptorPanel(new UserLibsPanel(this), "libraries"); // NOI18N
  163. basicFlagsDescriptorPanel = new MakefileWizardDescriptorPanel(new BasicFlagsPanel(this), "basic_options"); // NOI18N
  164. compilerPathDescriptorPanel = new MakefileWizardDescriptorPanel(new CompilerPathPanel(this), "compiler_paths"); // NOI18N
  165. //makeTargetDescriptorPanel = new MakefileWizardDescriptorPanel(new MakeTargetPanel(this));
  166. //customTargetDescriptorPanel = new MakefileWizardDescriptorPanel(new CustomTargetPanel(this));
  167. compilerOptionsDescriptorPanel = new MakefileWizardDescriptorPanel(new CompilerOptionsPanel(this), "advanced_options"); // NOI18N
  168. // The review/summary panel
  169. makefileReviewDescriptorPanel = new MakefileWizardDescriptorPanel(new MakefileReviewPanel(this), "review_makefile"); // NOI18N
  170. normalPanels = new WizardDescriptor.Panel[]{
  171. targetChooserDescriptorPanel,
  172. //compilerTypeDescriptorPanel,
  173. platformTypeDescriptorPanel,
  174. targetNameDescriptorPanel,
  175. makefileSourcesDescriptorPanel,
  176. selectPreferencesDescriptorPanel,
  177. makefileReviewDescriptorPanel
  178. };
  179. // Use a LinkedList for complexPanels because we add new panels to the
  180. // middle when new targets are added.
  181. complexPanels = new LinkedList<Object>();
  182. complexPanels.addLast(targetChooserDescriptorPanel);
  183. complexPanels.addLast(platformTypeDescriptorPanel);
  184. complexPanels.addLast(baseDirectoryDescriptorPanel);
  185. complexPanels.addLast(createTargetsDescriptorPanel);
  186. complexPanels.addLast(makefileReviewDescriptorPanel);
  187. panels = complexToArray();
  188. currentPanel = targetChooserDescriptorPanel;
  189. addIdx = 4;
  190. haveCompilerFlags = false;
  191. nextButton = null;
  192. finishButton = null;
  193. cancelButton = null;
  194. finishEnabled = false;
  195. }
  196. public TemplateWizard getTemplateWizard() {
  197. return wd;
  198. }
  199. /** Getter for the data associated with a panel */
  200. final public MakefileData getMakefileData() {
  201. return makefileData;
  202. }
  203. /** Setter for the title string */
  204. final public void setTitle(String title) {
  205. this.title = title;
  206. }
  207. /** Getter for Next button */
  208. public JButton getNextButton() {
  209. return nextButton;
  210. }
  211. /** Getter for Finish button */
  212. public JButton getFinishButton() {
  213. return finishButton;
  214. }
  215. /** Getter for Cancel button */
  216. public JButton getCancelButton() {
  217. return cancelButton;
  218. }
  219. /** Getter for Finish label */
  220. public String getFinishLabel() {
  221. return finishLabel;
  222. }
  223. /** Getter for Finish mnemonic */
  224. public int getFinishMnemonic() {
  225. return finishMnemonic;
  226. }
  227. /** Used to determine the current target's TargetData */
  228. public int getCurrentTargetKey() {
  229. int key = -1;
  230. if (makefileData.getMakefileType() <
  231. MakefileData.COMPLEX_MAKEFILE_TYPE) {
  232. key = 0;
  233. } else {
  234. for (int i = 0; i < panels.length; i++) {
  235. if (panels[i] instanceof StepHeader) {
  236. key = ((StepHeader) panels[i]).getKey();
  237. }
  238. if (i == index) {
  239. break;
  240. }
  241. }
  242. }
  243. return key;
  244. }
  245. /** The current panel.
  246. */
  247. public WizardDescriptor.Panel<WizardDescriptor> current() {
  248. @SuppressWarnings("unchecked")
  249. WizardDescriptor.Panel<WizardDescriptor> res = currentPanel;
  250. return res;
  251. }
  252. /** Current name of the panel */
  253. public String name() {
  254. Object[] args = {
  255. Integer.valueOf(index + 1),
  256. Integer.valueOf(panels.length)
  257. };
  258. MessageFormat mf = new MessageFormat(
  259. NbBundle.getBundle(WizardDescriptor.class).getString("CTL_ArrayIteratorName")); // NOI18N
  260. return mf.format(args);
  261. }
  262. /** Updates button state */
  263. public void updateStateHack() {
  264. //wd.updateState();
  265. // FIXUP: HACK - updateState is now protected in WizardDescriptor. Calling
  266. // FIXUP: setTitleFormat() has the sideeffect of calling updateState, so this works for now....
  267. if (wd != null) {
  268. wd.setTitleFormat(new MessageFormat("{0}")); // NOI18N
  269. }
  270. }
  271. /** Updates button state */
  272. public void updateState() {
  273. fireChangeEvent();
  274. }
  275. /**
  276. * Create the steps array for setting the Steps area in the wizard. Also,
  277. * set the virtIndex. The virtIndex is similar to index except it doesn't
  278. * count contracted panels. Its the index the WizardDescriptor uses to
  279. * correctly highlight the current step in the wizard.
  280. */
  281. private String[] getSteps() {
  282. String[] steps = new String[panels.length + 1];
  283. StepHeader hdr = null;
  284. int j = 1;
  285. int doingTarget = 0;
  286. int expand = 0;
  287. int aVirtIndex = 0;
  288. // Add templateChooser to 0th position...
  289. steps[0] = wd.templateChooser().getComponent().getName();
  290. for (int i = 0; i < panels.length; i++) {
  291. if (panels[i] instanceof StepHeader) {
  292. if (i < index) {
  293. aVirtIndex++;
  294. }
  295. hdr = (StepHeader) panels[i];
  296. steps[j++] = hdr.getTitle();
  297. doingTarget = hdr.getNum();
  298. if (index >= i && index <= (i + hdr.getNum())) {
  299. expand = hdr.getNum();
  300. }
  301. } else if (doingTarget-- > 0) {
  302. if (expand-- > 0) {
  303. if (i < index) {
  304. aVirtIndex++;
  305. }
  306. steps[j++] = NbBundle.getMessage(getClass(),
  307. "FMT_TARGET_PANEL", " ", // NOI18N
  308. ((WizardDescriptor.Panel) panels[i]).getComponent().getName());
  309. }
  310. } else {
  311. steps[j++] = ((WizardDescriptor.Panel) panels[i]).getComponent().getName();
  312. if (i < index) {
  313. aVirtIndex++;
  314. }
  315. }
  316. }
  317. // Now copy the overallocated steps array to nue
  318. String[] nue = new String[j];
  319. System.arraycopy(steps, 0, nue, 0, j);
  320. this.virtIndex = aVirtIndex;
  321. return nue;
  322. }
  323. /**
  324. * Set the current Makefile type. This has the side affect of changing the
  325. * array of panels wizard uses and the steps shown.
  326. */
  327. public void updatePanels(int type) {
  328. if (type >= MakefileData.COMPLEX_MAKEFILE_TYPE) {
  329. panels = complexToArray();
  330. } else {
  331. panels = normalPanels;
  332. }
  333. ((JPanel) currentPanel.getComponent()).putClientProperty(
  334. WizardDescriptor.PROP_CONTENT_DATA, getSteps()); // NOI18N
  335. updateState();
  336. }
  337. /**
  338. * Is there a next panel?
  339. *
  340. * @return true if so
  341. */
  342. public boolean hasNext() {
  343. return (index) < (panels.length - 1);
  344. }
  345. /**
  346. * Is there a previous panel?
  347. *
  348. * @return true if so
  349. */
  350. public boolean hasPrevious() {
  351. return index > 0;
  352. }
  353. /**
  354. * Moves to the next panel. If the index points to a StepHeader then
  355. * skip that and show the next panel.
  356. *
  357. * @exception NoSuchElementException if the panel does not exist
  358. */
  359. public synchronized void nextPanel() {
  360. if (panels[++index] instanceof StepHeader) {
  361. index++;
  362. }
  363. currentPanel = (WizardDescriptor.Panel) panels[index];
  364. updatePanels(makefileData.getMakefileType());
  365. ((JPanel) currentPanel.getComponent()).putClientProperty(
  366. WizardDescriptor.PROP_CONTENT_SELECTED_INDEX,
  367. Integer.valueOf(virtIndex));
  368. }
  369. /**
  370. * Moves to previous panel.
  371. * @exception NoSuchElementException if the panel does not exist
  372. */
  373. public synchronized void previousPanel() {
  374. if (index == 0) {
  375. throw new NoSuchElementException();
  376. }
  377. if (panels[--index] instanceof StepHeader) {
  378. index--;
  379. }
  380. currentPanel = (WizardDescriptor.Panel) panels[index];
  381. updatePanels(makefileData.getMakefileType());
  382. ((JPanel) currentPanel.getComponent()).putClientProperty(
  383. WizardDescriptor.PROP_CONTENT_SELECTED_INDEX,
  384. Integer.valueOf(virtIndex));
  385. }
  386. /**
  387. * Convert the LinkedList of complexPanels to an array of
  388. * MakefileWizardPanel
  389. */
  390. private Object[] complexToArray() {
  391. Object[] p = new Object[complexPanels.size()];
  392. ListIterator iter = complexPanels.listIterator();
  393. for (int i = 0; i < complexPanels.size(); i++) {
  394. p[i] = iter.next();
  395. }
  396. return p;
  397. }
  398. /** Does a target with this key exist? */
  399. public boolean targetExists(int key) {
  400. for (int i = 0; i < complexPanels.size(); i++) {
  401. Object o = complexPanels.get(i);
  402. if (o instanceof StepHeader && ((StepHeader) o).getKey() == key) {
  403. return true;
  404. }
  405. }
  406. return false;
  407. }
  408. /** Create new panels for a target, based on the target type */
  409. public int addTarget(int type, String name, int key) {
  410. boolean needCompilerFlags = false;
  411. int count = 0;
  412. switch (type) {
  413. case TargetData.COMPLEX_EXECUTABLE:
  414. needCompilerFlags = true;
  415. count = 6;
  416. complexPanels.add(addIdx++, new TargetHeader(name, type, count - 1, key));
  417. complexPanels.add(addIdx++, buildOutputDescriptorPanel);
  418. complexPanels.add(addIdx++, makefileSourcesDescriptorPanel);
  419. complexPanels.add(addIdx++, makefileIncludesDescriptorPanel);
  420. complexPanels.add(addIdx++, standardLibsDescriptorPanel);
  421. complexPanels.add(addIdx++, userLibsDescriptorPanel);
  422. break;
  423. case TargetData.COMPLEX_ARCHIVE:
  424. needCompilerFlags = true;
  425. count = 4;
  426. complexPanels.add(addIdx++, new TargetHeader(name, type, count - 1, key));
  427. complexPanels.add(addIdx++, buildOutputDescriptorPanel);
  428. complexPanels.add(addIdx++, makefileSourcesDescriptorPanel);
  429. complexPanels.add(addIdx++, makefileIncludesDescriptorPanel);
  430. break;
  431. case TargetData.COMPLEX_SHAREDLIB:
  432. needCompilerFlags = true;
  433. count = 5;
  434. complexPanels.add(addIdx++, new TargetHeader(name, type, count - 1, key));
  435. complexPanels.add(addIdx++, buildOutputDescriptorPanel);
  436. complexPanels.add(addIdx++, makefileSourcesDescriptorPanel);
  437. complexPanels.add(addIdx++, makefileIncludesDescriptorPanel);
  438. complexPanels.add(addIdx++, userLibsDescriptorPanel);
  439. break;
  440. case TargetData.COMPLEX_MAKE_TARGET:
  441. complexPanels.add(addIdx++, new TargetHeader(name, type, 1, key));
  442. //complexPanels.add(addIdx++, makeTargetDescriptorPanel);
  443. complexPanels.add(addIdx++, new MakefileWizardDescriptorPanel(new MakeTargetPanel(this), "recursive_make")); // NOI18N
  444. break;
  445. case TargetData.COMPLEX_CUSTOM_TARGET:
  446. complexPanels.add(addIdx++, new TargetHeader(name, type, 1, key));
  447. //complexPanels.add(addIdx++, customTargetPanel);
  448. complexPanels.add(addIdx++, new MakefileWizardDescriptorPanel(new CustomTargetPanel(this), "custom_make")); // NOI18N
  449. break;
  450. }
  451. if (needCompilerFlags && !haveCompilerFlags) {
  452. complexPanels.add(addIdx,
  453. new StepHeader(NbBundle.getBundle(getClass()).
  454. getString("FMT_COMP_PREFS"), 3, -1)); // NOI18N
  455. complexPanels.add(addIdx + 1, basicFlagsDescriptorPanel);
  456. complexPanels.add(addIdx + 2, compilerOptionsDescriptorPanel);
  457. complexPanels.add(addIdx + 3, compilerPathDescriptorPanel);
  458. haveCompilerFlags = true;
  459. count += 4;
  460. }
  461. updatePanels(type);
  462. return count; // number of panels added
  463. }
  464. /** Delete the panels for the specified target */
  465. public void deleteTarget(int key) {
  466. deleteTarget(key, true);
  467. }
  468. /** Delete the panels for the specified target */
  469. public void deleteTarget(int key, boolean doUpdate) {
  470. boolean changed = false;
  471. for (int i = 0; i < complexPanels.size(); i++) {
  472. if (complexPanels.get(i) instanceof TargetHeader) {
  473. TargetHeader hdr = (TargetHeader) complexPanels.get(i);
  474. if (key == hdr.getKey()) {
  475. for (int j = 0; j <= hdr.getNum(); j++) {
  476. complexPanels.remove(i);
  477. changed = true;
  478. }
  479. addIdx -= hdr.getNum() + 1;
  480. break;
  481. }
  482. }
  483. }
  484. if (changed && doUpdate) {
  485. updatePanels(getMakefileData().getMakefileType());
  486. }
  487. }
  488. /** Change the panel name for the specified target */
  489. public void changeTarget(int key, String name, int type) {
  490. boolean changed = false;
  491. for (int i = 0; i < complexPanels.size(); i++) {
  492. if (complexPanels.get(i) instanceof TargetHeader) {
  493. TargetHeader hdr = (TargetHeader) complexPanels.get(i);
  494. if (key == hdr.getKey()) {
  495. if (type != hdr.getType()) {
  496. // Changing type of target - delete old target and create new
  497. deleteTarget(key, false);
  498. int saveIdx = addIdx;
  499. addIdx = i; // control where target is added
  500. int count = addTarget(type, name, key);
  501. addIdx = saveIdx + count;
  502. } else {
  503. // Just change the name of the target
  504. hdr.setName(name);
  505. hdr.setTitle(NbBundle.getMessage(getClass(),
  506. "FMT_TARGET_CREATE", name)); // NOI18N
  507. }
  508. changed = true;
  509. break;
  510. }
  511. }
  512. }
  513. if (changed) {
  514. updatePanels(getMakefileData().getMakefileType());
  515. }
  516. }
  517. /** Toplevel validation method. Gathers warnings from all panels */
  518. public ArrayList validateAllData() {
  519. ArrayList<String> msgs = new ArrayList<String>();
  520. int key = -1;
  521. for (int i = 0; i < panels.length; i++) {
  522. if (panels[i] instanceof WizardDescriptor.Panel &&
  523. ((WizardDescriptor.Panel) panels[i]).getComponent() instanceof MakefileWizardPanel) {
  524. ((MakefileWizardPanel) ((WizardDescriptor.Panel) panels[i]).getComponent()).validateData(msgs, key);
  525. } else if (panels[i] instanceof StepHeader) {
  526. key = ((StepHeader) panels[i]).getKey();
  527. }
  528. }
  529. return msgs;
  530. }
  531. private final transient Set<ChangeListener> listeners = new HashSet<ChangeListener>(1); // Set<ChangeListener>
  532. public final void addChangeListener(ChangeListener l) {
  533. synchronized (listeners) {
  534. listeners.add(l);
  535. }
  536. }
  537. public final void removeChangeListener(ChangeListener l) {
  538. synchronized (listeners) {
  539. listeners.remove(l);
  540. }
  541. }
  542. protected final void fireChangeEvent() {
  543. Iterator it;
  544. synchronized (listeners) {
  545. it = new HashSet<ChangeListener>(listeners).iterator();
  546. }
  547. ChangeEvent ev = new ChangeEvent(this);
  548. while (it.hasNext()) {
  549. ((ChangeListener) it.next()).stateChanged(ev);
  550. }
  551. }
  552. // Wizard methods
  553. public boolean onFinish() {
  554. MakefileGenerator gen = new MakefileGenerator(makefileData);
  555. /*
  556. * Remove any unused targets. A target is unused if its index > 0 and
  557. * the first target is a simple target.
  558. */
  559. List<TargetData> tlist = getMakefileData().getTargetList();
  560. if (tlist.size() > 1) {
  561. TargetData target = tlist.get(1);
  562. if (!target.isComplex()) {
  563. for (int i = tlist.size() - 1; i > 0; i--) {
  564. tlist.remove(i);
  565. }
  566. }
  567. }
  568. boolean status = gen.generate();
  569. return status;
  570. }
  571. /**
  572. * Returns whether the wizard has been completed and the code should
  573. * be generated.
  574. */
  575. public void executeWizard() {
  576. listener = new PropertyChangeListener() {
  577. public void propertyChange(PropertyChangeEvent event) {
  578. if (index == 0) {
  579. // FIXUP: don't know how to disable finish button on target chooser panel
  580. // FIXUP: this hack will just disable the finish button if on first panel...
  581. finishButton.setEnabled(false);
  582. }
  583. if (event.getPropertyName().
  584. equals(DialogDescriptor.PROP_VALUE)) {
  585. Object option = event.getNewValue();
  586. if (option == WizardDescriptor.FINISH_OPTION || option == WizardDescriptor.CANCEL_OPTION) {
  587. //boolean done = false;
  588. if (option == WizardDescriptor.FINISH_OPTION) {
  589. if (hasNext()) {
  590. // Go to the Review panel
  591. index = panels.length - 2;
  592. nextPanel();
  593. nextButton.setEnabled(false);
  594. } else {
  595. //done = onFinish();
  596. }
  597. updateStateHack();
  598. } else {
  599. // nothing. The iterator will call 'instantiate' where the makefile is created
  600. }
  601. }
  602. }
  603. }
  604. };
  605. index = 0;
  606. currentPanel = (WizardDescriptor.Panel) panels[index];
  607. //wd = new MakefileWizardDescriptor(this);
  608. /*
  609. wd.putProperty(WizardDescriptor.PROP_AUTO_WIZARD_STYLE, // NOI18N
  610. new Boolean(true));
  611. wd.putProperty(WizardDescriptor.PROP_CONTENT_DISPLAYED, // NOI18N
  612. new Boolean(true));
  613. wd.setTitleFormat(new MessageFormat("{0}")); // NOI18N
  614. wd.setTitle(title);
  615. */
  616. setupWizardButtons(wd);
  617. updatePanels(getMakefileData().getMakefileType()); //FIXUP
  618. ((JPanel) (currentPanel.getComponent())).putClientProperty(WizardDescriptor.PROP_CONTENT_SELECTED_INDEX, 0);
  619. wd.addPropertyChangeListener(listener);
  620. /*
  621. dialog = DialogDisplayer.getDefault().createDialog(wd);
  622. dialog.show();
  623. dialog.dispose();
  624. */
  625. }
  626. public void unexecuteWizard() {
  627. if (listener != null) {
  628. wd.removePropertyChangeListener(listener);
  629. listener = null;
  630. }
  631. }
  632. /**
  633. * We need to do several things with the buttons. First off, we want to
  634. * find the JButton for the Next and Finish buttons. We need the Next
  635. * button because we want to make another button default in some panels
  636. * but we need to return the 'default' status to the Next button at some
  637. * later point. We need the Finish button so we can change its label to
  638. * "Last" until we reach the review panel. We also want to reset the
  639. * closing buttons so only the Cancel button does a close.
  640. */
  641. private void setupWizardButtons(WizardDescriptor wd) {
  642. Object[] options = wd.getOptions(); // save original buttons
  643. wd.setOptions(new Object[]{
  644. WizardDescriptor.NEXT_OPTION, WizardDescriptor.FINISH_OPTION, WizardDescriptor.CANCEL_OPTION});
  645. Object[] objs = wd.getOptions();
  646. if (objs != null && objs.length == 3) {
  647. nextButton = (JButton) objs[0];
  648. finishButton = (JButton) objs[1];
  649. finishLabel = finishButton.getText();
  650. finishMnemonic = finishButton.getMnemonic();
  651. // finishButton.setText(NbBundle.getBundle(MakefileWizard.class).
  652. // getString("BTN_Last")); // NOI18N
  653. // finishButton.setMnemonic(NbBundle.getBundle(MakefileWizard.class).
  654. // getString("MNEM_Last").charAt(0)); // NOI18N
  655. cancelButton = (JButton) objs[2];
  656. }
  657. wd.setOptions(options); // restor original buttons
  658. setFinishClosingEnabled(false);
  659. }
  660. private void unsetupWizardButtons(WizardDescriptor wd) {
  661. setFinishClosingEnabled(true);
  662. // finishButton.setText(finishLabel);
  663. // finishButton.setMnemonic(finishMnemonic);
  664. }
  665. /**
  666. * Will enable the finish button to close the dialog or not.
  667. * The cancel button always closes the dialog.
  668. */
  669. public void setFinishClosingEnabled(boolean b) {
  670. if (b) {
  671. wd.setClosingOptions(new Object[]{finishButton, cancelButton});
  672. } else {
  673. wd.setClosingOptions(new Object[]{cancelButton});
  674. }
  675. }
  676. /**
  677. * We need to reenable often because each button press disables the
  678. * Finish button.
  679. */
  680. public void setFinishEnabled(boolean tf) {
  681. //wd.setFinishEnabled(tf); // FIXUP
  682. finishButton.setEnabled(tf); // FIXUP ???
  683. }
  684. final public static MakefileWizard getMakefileWizard() {
  685. return makefileWizard;
  686. }
  687. //
  688. // The following is the static portion of the class.
  689. //
  690. public static void showWizard() {
  691. makefileWizard = new MakefileWizard();
  692. makefileWizard.executeWizard();
  693. }
  694. /**
  695. * The StepHeader represents a group of panels which are collapsed to a
  696. * single line in the complexPanels steps list until one of those panels
  697. * is stepped into.
  698. */
  699. private class StepHeader {
  700. /** The line displayed in the Steps panel */
  701. private String title;
  702. /** The number of panels making up this step */
  703. private int num;
  704. /** A lookup key to map the StepHeader to a TargetData */
  705. private int key;
  706. /** The constructor */
  707. public StepHeader(String title, int num, int key) {
  708. this.title = title;
  709. this.num = num;
  710. this.key = key;
  711. }
  712. /** Getter for the title */
  713. public String getTitle() {
  714. return title;
  715. }
  716. /** Setter for the title */
  717. protected void setTitle(String title) {
  718. this.title = title;
  719. }
  720. /** Getter for the num */
  721. public int getNum() {
  722. return num;
  723. }
  724. /** Setter for the num */
  725. protected void setNum(int num) {
  726. this.num = num;
  727. }
  728. /** Getter for the key */
  729. public int getKey() {
  730. return key;
  731. }
  732. /** Setter for the key */
  733. protected void setKey(int key) {
  734. this.key = key;
  735. }
  736. }
  737. /**
  738. * The TargetHeader represents a target in the complexPanels list of steps.
  739. * Each target may have multiple panels but these panels are not shown
  740. * unless the wizard is ``stepped-into'' the TargetHeader.
  741. */
  742. private class TargetHeader extends MakefileWizard.StepHeader {
  743. /** The name is used to create the title */
  744. private String name;
  745. /** The type of the target this header is for */
  746. private int type;
  747. /** Constructor */
  748. public TargetHeader(String name, int type, int num, int key) {
  749. super(null, num, key);
  750. this.name = name;
  751. this.type = type;
  752. this.setTitle(NbBundle.getMessage(getClass(),
  753. "FMT_TARGET_CREATE", name)); // NOI18N
  754. }
  755. public String getName() {
  756. return name;
  757. }
  758. public void setName(String name) {
  759. this.name = name;
  760. }
  761. public int getType() {
  762. return type;
  763. }
  764. public void setType(int type) {
  765. this.type = type;
  766. }
  767. }
  768. public void initialize(TemplateWizard wiz) {
  769. wd = wiz;
  770. initPanels();
  771. executeWizard();
  772. }
  773. public void uninitialize(TemplateWizard wiz) {
  774. unexecuteWizard();
  775. unsetupWizardButtons(wiz);
  776. wd = null;
  777. }
  778. @SuppressWarnings("fallthrough")
  779. public Set<DataObject> instantiate(TemplateWizard wiz) throws IOException {
  780. DataFolder targetFolder = wiz.getTargetFolder();
  781. DataObject template = wiz.getTemplate();
  782. String makefileName;
  783. int pos = getMakefileData().getMakefileName().lastIndexOf(File.separatorChar);
  784. if (pos >= 0) {
  785. makefileName = getMakefileData().getMakefileName().substring(pos + 1);
  786. } else {
  787. makefileName = getMakefileData().getMakefileName();
  788. }
  789. DataObject result;
  790. result = template.createFromTemplate(targetFolder, makefileName);
  791. if (result != null) {
  792. MakeExecSupport mes = result.getCookie(MakeExecSupport.class);
  793. if (mes != null) {
  794. // Add known targets to node
  795. // Add "all", "clean", and user defined targets...
  796. mes.addMakeTargets("all"); // NOI18N
  797. List<TargetData> tlist = getMakefileData().getTargetList();
  798. for (int i = 0; i < tlist.size(); i++) {
  799. TargetData t = tlist.get(i);
  800. switch (t.getTargetType()) {
  801. case TargetData.SIMPLE_EXECUTABLE:
  802. case TargetData.SIMPLE_ARCHIVE:
  803. case TargetData.SIMPLE_SHAREDLIB:
  804. case TargetData.COMPLEX_EXECUTABLE:
  805. case TargetData.COMPLEX_ARCHIVE:
  806. case TargetData.COMPLEX_SHAREDLIB:
  807. if (t.getOutputDirectory() != null && t.getOutputDirectory().length() > 0) {
  808. mes.addMakeTargets(t.getOutputDirectory() + "/" + t.getName()); // NOI18N
  809. } else {
  810. mes.addMakeTargets(t.getName()); // NOI18N
  811. }
  812. break;
  813. case TargetData.COMPLEX_MAKE_TARGET:
  814. case TargetData.COMPLEX_CUSTOM_TARGET:
  815. mes.addMakeTargets(t.getName());
  816. break;
  817. }
  818. }
  819. mes.addMakeTargets("clean"); // NOI18N
  820. // Set build (base) directory
  821. String makefileDir = getMakefileData().getMakefileDirName();
  822. String baseDir = getMakefileData().getBaseDirectory();
  823. String buildDirectory;
  824. if (makefileDir.equals(baseDir)) {
  825. buildDirectory = ("."); // NOI18N
  826. } else {
  827. buildDirectory = CndPathUtilitities.getRelativePath(makefileDir, baseDir);
  828. }
  829. mes.setBuildDirectory(buildDirectory);
  830. String fullMakefilePath = result.getPrimaryFile().getFileSystem().getDisplayName() + File.separator + result.getPrimaryFile().getPath();
  831. String fullBuildDirectoryPath = buildDirectory;
  832. int aIndex = fullMakefilePath.lastIndexOf(File.separatorChar);
  833. if (aIndex >= 0) {
  834. fullBuildDirectoryPath = CndPathUtilitities.toAbsolutePath(fullMakefilePath.substring(0, aIndex), fullBuildDirectoryPath);
  835. }
  836. // Send creation event
  837. ArrayList<String> targets = new ArrayList<String>();
  838. ArrayList<String> executables = new ArrayList<String>();
  839. for (int i = 0; i < tlist.size(); i++) {
  840. TargetData t = tlist.get(i);
  841. String outputDirectory = t.getOutputDirectory();
  842. if (outputDirectory == null || outputDirectory.length() == 0) {
  843. outputDirectory = "."; // NOI18N
  844. }
  845. switch (t.getTargetType()) {
  846. case TargetData.COMPLEX_EXECUTABLE:
  847. case TargetData.SIMPLE_EXECUTABLE:
  848. String fullTargetPath = null;
  849. if (t.getName().charAt(0) == File.separatorChar) {
  850. fullTargetPath = t.getName();
  851. } else if (outputDirectory.charAt(0) == File.separatorChar) {
  852. fullTargetPath = outputDirectory + File.separator + t.getName();
  853. } else {
  854. fullTargetPath = fullBuildDirectoryPath + File.separator + outputDirectory + File.separator + t.getName();
  855. }
  856. executables.add(fullTargetPath);
  857. // fall through...
  858. case TargetData.SIMPLE_ARCHIVE:
  859. case TargetData.SIMPLE_SHAREDLIB:
  860. case TargetData.COMPLEX_ARCHIVE:
  861. case TargetData.COMPLEX_SHAREDLIB:
  862. targets.add(t.getName());
  863. break;
  864. case TargetData.COMPLEX_MAKE_TARGET:
  865. case TargetData.COMPLEX_CUSTOM_TARGET:
  866. mes.addMakeTargets(t.getName());
  867. break;
  868. }
  869. }
  870. MakefileWizardEvent wizardEvent = new MakefileWizardEvent(
  871. this,
  872. MakefileWizardEvent.MAKEFILE_NEW,
  873. fullMakefilePath,
  874. getMakefileData().getBaseDirectory(),
  875. "make", // NOI18N
  876. targets.toArray(new String[targets.size()]),
  877. executables.toArray(new String[executables.size()]));
  878. fireMakefileWizardEvent(wizardEvent);
  879. }
  880. }
  881. boolean done = onFinish();
  882. if (done) {
  883. OpenCookie open = result.getCookie(OpenCookie.class);
  884. if (open != null) {
  885. open.open();
  886. }
  887. } else {
  888. System.err.println("errors generating makefile..."); // FIXUP // NOI18N
  889. }
  890. return Collections.<DataObject>singleton(result);
  891. }
  892. /*
  893. * Returns relative (to mounted filesystem) path to fileobject fo. Recursive.
  894. * Same funtionality as folder.getNameExt, which is now deprecated.
  895. */
  896. private String dirPath(FileObject fo, String path) {
  897. if (fo.getParent() != null && fo.getParent().getName() != null && fo.getParent().getName().length() > 0) {
  898. path = fo.getParent().getName() + File.separatorChar + path;
  899. return dirPath(fo.getParent(), path);
  900. }
  901. return path;
  902. }
  903. /** Set initial data in dialog */
  904. public void initDirPaths() {
  905. // Get dir folder and makefile name from targetChooser panel (default wizard panel)
  906. String fullFolderName = null;
  907. try {
  908. DataFolder targetFolder = getTemplateWizard().getTargetFolder();
  909. FileObject fo = targetFolder.getPrimaryFile();
  910. fullFolderName = CndFileUtils.toFile(fo).getPath();
  911. } catch (IOException ioe) {
  912. // FIXUP
  913. }
  914. getMakefileData().setBaseDirectory(fullFolderName);
  915. getMakefileData().setMakefileDirName(fullFolderName);
  916. }
  917. private String uniqDefaultName(String dir, String makefileName) {
  918. String name = makefileName;
  919. File f = new File(dir + File.separator + name);
  920. int n = 1;
  921. while (f.exists()) {
  922. name = makefileName + "_" + n++; // NOI18N
  923. f = new File(dir + File.separator + name);
  924. }
  925. return name;
  926. }
  927. /** Update MakefileData if the data was changed */
  928. public void initMakefileName() {
  929. // Create and set makefile name based on name from targetChooser panel and basedirectory
  930. MakefileData md = getMakefileData();
  931. String makefileName = getTemplateWizard().getTargetName();
  932. String dir = CndPathUtilitities.trimSlashes(md.getMakefileDirName());
  933. if (makefileName == null) {
  934. makefileName = uniqDefaultName(dir, "Makefile"); // NOI18N
  935. }
  936. String fullMakefileName = dir + File.separator + makefileName;
  937. String useMakefileName = null;
  938. if (dir.equals(md.getBaseDirectory()) || ".".equals(dir) || dir.length() == 0) // NOI18N
  939. {
  940. useMakefileName = makefileName;
  941. } else {
  942. useMakefileName = fullMakefileName;
  943. }
  944. md.setMakefileName(useMakefileName);
  945. }
  946. /** ---------------------------------------------------- */
  947. protected static void fireMakefileWizardEvent(MakefileWizardEvent e) {
  948. Vector<MakefileWizardListener> listeners = getListenerList();
  949. for (int i = listeners.size() - 1; i >= 0; i--) {
  950. (listeners.elementAt(i)).makefileCreated(e);
  951. }
  952. }
  953. private static Vector<MakefileWizardListener> getListenerList() {
  954. if (listenerList == null) {
  955. listenerList = new Vector<MakefileWizardListener>(0);
  956. }
  957. return listenerList;
  958. }
  959. public static void addMakefileWizardListener(MakefileWizardListener l) {
  960. getListenerList().add(l);
  961. }
  962. public static void removeMakefileWizardListener(MakefileWizardListener l) {
  963. getListenerList().remove(l);
  964. }
  965. }