Office-Support: allows viewing details of items from Excel and Word documents and selecting the Excel sheet to work on
Change-Id: Ifa0c0099e1e4e3d36c98e2ce1f2db47235115ff0
Signed-off-by: Dusan Kalanj <kalanj@chalmers.se>
diff --git a/org.eclipse.capra.ui.office/plugin.properties b/org.eclipse.capra.ui.office/plugin.properties
new file mode 100644
index 0000000..d34f04c
--- /dev/null
+++ b/org.eclipse.capra.ui.office/plugin.properties
@@ -0,0 +1,12 @@
+###############################################################################
+# Copyright (c) 2016 Chalmers | University of Gothenburg, rt-labs and others.
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+#
+# Contributors:
+# Chalmers | University of Gothenburg and rt-labs - initial API and implementation and/or initial documentation
+###############################################################################
+
+req_fieldName=REQ
\ No newline at end of file
diff --git a/org.eclipse.capra.ui.office/plugin.xml b/org.eclipse.capra.ui.office/plugin.xml
index b07b22f..bae6627 100644
--- a/org.eclipse.capra.ui.office/plugin.xml
+++ b/org.eclipse.capra.ui.office/plugin.xml
@@ -18,12 +18,12 @@
id="org.eclipse.capra.ui.views"
name="Capra Views">
</category>
- <view
- category="org.eclipse.capra.ui.views"
- class="org.eclipse.capra.ui.office.views.OfficeView"
- icon="icons/selectionView.png"
- id="org.eclipse.capra.ui.views.OfficeView"
- name="Office Selection View">
+ <view
+ category="org.eclipse.capra.ui.views"
+ class="org.eclipse.capra.ui.office.views.OfficeView"
+ icon="icons/selectionView.png"
+ id="org.eclipse.capra.ui.views.OfficeView"
+ name="Office Selection View">
</view>
</extension>
<extension
@@ -40,41 +40,49 @@
id="org.eclipse.capra.ui.office.openfile"
name="Open File">
</command>
+ <command
+ id="org.eclipse.capra.ui.office.selectsheet"
+ name="Select Sheet">
+ </command>
+ <command
+ id="org.eclipse.capra.ui.office.setcharactercount"
+ name="Character Count">
+ </command>
</extension>
<extension
point="org.eclipse.ui.handlers">
<handler
- class="org.eclipse.capra.ui.office.handlers.ClearSelectionHandler"
- commandId="org.eclipse.capra.ui.office.clearselection">
+ class="org.eclipse.capra.ui.office.handlers.ClearSelectionHandler"
+ commandId="org.eclipse.capra.ui.office.clearselection">
</handler>
<handler
- class="org.eclipse.capra.ui.office.handlers.ShowObjectDetailsHandler"
- commandId="org.eclipse.capra.ui.office.showdetails">
+ class="org.eclipse.capra.ui.office.handlers.ShowObjectDetailsHandler"
+ commandId="org.eclipse.capra.ui.office.showdetails">
</handler>
<handler
- class="org.eclipse.capra.ui.office.handlers.OpenFileHandler"
- commandId="org.eclipse.capra.ui.office.openfile">
+ class="org.eclipse.capra.ui.office.handlers.OpenFileHandler"
+ commandId="org.eclipse.capra.ui.office.openfile">
+ </handler>
+ <handler
+ class="org.eclipse.capra.ui.office.handlers.SelectSheetHandler"
+ commandId="org.eclipse.capra.ui.office.selectsheet">
</handler>
</extension>
<extension
point="org.eclipse.ui.menus">
<menuContribution
- locationURI="popup:org.eclipse.capra.ui.views.OfficeView?after=additions">
+ locationURI="menu:org.eclipse.capra.ui.views.OfficeView?after=additions">
<command
commandId="org.eclipse.capra.ui.office.openfile"
label="Open File"
style="push"
- tooltip="Triggers the file selection dialog.">
+ tooltip="Triggers the file selection dialog">
</command>
- <separator
- name="org.eclipse.capra.generic.tracecreation.separator1"
- visible="true">
- </separator>
<command
- commandId="org.eclipse.capra.ui.office.showdetails"
- label="Show Details"
+ commandId="org.eclipse.capra.ui.office.selectsheet"
+ label="Select Sheet"
style="push"
- tooltip="Shows the details of the selected row">
+ tooltip="Select which sheet in the Excel workbook to display">
</command>
<command
commandId="org.eclipse.capra.ui.office.clearselection"
@@ -82,10 +90,33 @@
style="push"
tooltip="Clears the current selection of elements">
</command>
- <separator
- name="org.eclipse.capra.generic.tracecreation.separator1"
- visible="true">
- </separator>
+ <menu
+ label="Options">
+ <command
+ commandId="org.eclipse.capra.ui.office.setcharactercount"
+ label="Character Count"
+ style="push"
+ tooltip="Set number of characters that are shown per line">
+ </command>
+ </menu>
+ </menuContribution>
+ <menuContribution
+ locationURI="popup:net.sourceforge.plantuml.eclipse.views.PlantUmlView?after=additions">
+ <menu
+ label="Capra"
+ id="org.eclipse.capra.ui.contextsubmenu">
+ <command
+ commandId="org.eclipse.capra.ui.office.showdetails"
+ label="Show Details"
+ style="push"
+ tooltip="Shows the details of the selected row">
+ <visibleWhen>
+ <iterate ifEmpty="false">
+ <instanceof value="org.eclipse.capra.ui.office.objects.CapraOfficeObject"/>
+ </iterate>
+ </visibleWhen> -->
+ </command>
+ </menu>
</menuContribution>
</extension>
<extension
diff --git a/org.eclipse.capra.ui.office/src/org/eclipse/capra/ui/office/exceptions/CapraOfficeFileNotSupportedException.java b/org.eclipse.capra.ui.office/src/org/eclipse/capra/ui/office/exceptions/CapraOfficeFileNotSupportedException.java
new file mode 100644
index 0000000..10c7e9c
--- /dev/null
+++ b/org.eclipse.capra.ui.office/src/org/eclipse/capra/ui/office/exceptions/CapraOfficeFileNotSupportedException.java
@@ -0,0 +1,37 @@
+/*******************************************************************************
+ * Copyright (c) 2016 Chalmers | University of Gothenburg, rt-labs and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Chalmers | University of Gothenburg and rt-labs - initial API and implementation and/or initial documentation
+ *******************************************************************************/
+
+package org.eclipse.capra.ui.office.exceptions;
+
+/**
+ * An exception that is to be thrown when a non-supported file is dragged (or
+ * selected in the file dialog) into the Office view.
+ *
+ * @author Dusan Kalanj
+ *
+ */
+public class CapraOfficeFileNotSupportedException extends Exception {
+
+ private static final long serialVersionUID = -7730053652692861930L;
+ private static String EXCEPTION_MESSAGE = "%s file type is not supported.";
+
+ /**
+ * A default constructor.
+ *
+ * @param fileType
+ * the type of the non-supported file that was dragged/put into
+ * the Office view
+ */
+ public CapraOfficeFileNotSupportedException(String fileType) {
+ super(String.format(EXCEPTION_MESSAGE, fileType));
+ }
+
+}
diff --git a/org.eclipse.capra.ui.office/src/org/eclipse/capra/ui/office/exceptions/CapraOfficeObjectNotFound.java b/org.eclipse.capra.ui.office/src/org/eclipse/capra/ui/office/exceptions/CapraOfficeObjectNotFound.java
new file mode 100644
index 0000000..40b9f32
--- /dev/null
+++ b/org.eclipse.capra.ui.office/src/org/eclipse/capra/ui/office/exceptions/CapraOfficeObjectNotFound.java
@@ -0,0 +1,36 @@
+/*******************************************************************************
+ * Copyright (c) 2016 Chalmers | University of Gothenburg, rt-labs and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Chalmers | University of Gothenburg and rt-labs - initial API and implementation and/or initial documentation
+ *******************************************************************************/
+
+package org.eclipse.capra.ui.office.exceptions;
+
+/**
+ * An exception that is to be thrown when an office object can't be tracked back
+ * to its native environment.
+ *
+ * @author Dusan Kalanj
+ *
+ */
+public class CapraOfficeObjectNotFound extends Exception {
+
+ private static final long serialVersionUID = -3973348630832482778L;
+ private static String EXCEPTION_MESSAGE = "Could not find the object with ID %s in its document. Maybe the file has been edited or moved.";
+
+ /**
+ * A default constructor.
+ *
+ * @param id
+ * the id of the object that couldn't be found
+ */
+ public CapraOfficeObjectNotFound(String id) {
+ super(String.format(EXCEPTION_MESSAGE, id));
+ }
+
+}
diff --git a/org.eclipse.capra.ui.office/src/org/eclipse/capra/ui/office/handlers/SelectSheetHandler.java b/org.eclipse.capra.ui.office/src/org/eclipse/capra/ui/office/handlers/SelectSheetHandler.java
new file mode 100644
index 0000000..8c17250
--- /dev/null
+++ b/org.eclipse.capra.ui.office/src/org/eclipse/capra/ui/office/handlers/SelectSheetHandler.java
@@ -0,0 +1,33 @@
+/*******************************************************************************
+ * Copyright (c) 2016 Chalmers | University of Gothenburg, rt-labs and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Chalmers | University of Gothenburg and rt-labs - initial API and implementation and/or initial documentation
+ *******************************************************************************/
+
+package org.eclipse.capra.ui.office.handlers;
+
+import org.eclipse.capra.ui.office.views.OfficeView;
+import org.eclipse.core.commands.AbstractHandler;
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+
+/**
+ * A handler for displaying a dialog that prompts the user to select which Excel
+ * sheet to display.
+ *
+ * @author Dusan Kalanj
+ *
+ */
+public class SelectSheetHandler extends AbstractHandler {
+
+ @Override
+ public Object execute(ExecutionEvent event) throws ExecutionException {
+ OfficeView.getOpenedView().selectSheet();
+ return null;
+ }
+}
diff --git a/org.eclipse.capra.ui.office/src/org/eclipse/capra/ui/office/objects/CapraExcelRow.java b/org.eclipse.capra.ui.office/src/org/eclipse/capra/ui/office/objects/CapraExcelRow.java
index fa4ea8c..eacd6fe 100644
--- a/org.eclipse.capra.ui.office/src/org/eclipse/capra/ui/office/objects/CapraExcelRow.java
+++ b/org.eclipse.capra.ui.office/src/org/eclipse/capra/ui/office/objects/CapraExcelRow.java
@@ -1,68 +1,215 @@
+/*******************************************************************************
+ * Copyright (c) 2016 Chalmers | University of Gothenburg, rt-labs and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Chalmers | University of Gothenburg and rt-labs - initial API and implementation and/or initial documentation
+ *******************************************************************************/
+
package org.eclipse.capra.ui.office.objects;
+import java.awt.Desktop;
import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.Arrays;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
+import org.apache.poi.hssf.usermodel.HSSFCell;
+import org.apache.poi.hssf.usermodel.HSSFRow;
+import org.apache.poi.hssf.usermodel.HSSFSheet;
+import org.apache.poi.hssf.usermodel.HSSFWorkbook;
+import org.apache.poi.hssf.util.CellReference;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.DataFormatter;
import org.apache.poi.ss.usermodel.Row;
+import org.apache.poi.ss.usermodel.Sheet;
+import org.apache.poi.xssf.usermodel.XSSFSheet;
+import org.apache.poi.xssf.usermodel.XSSFWorkbook;
+import org.eclipse.capra.ui.office.exceptions.CapraOfficeObjectNotFound;
+import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTSelection;
+import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTSheetView;
+import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTSheetViews;
+import com.google.common.io.Files;
+
+/**
+ * This class extends the CapraOfficeObject and provides an object to describe a
+ * single MS Excel row.
+ *
+ * @author Dusan Kalanj
+ *
+ */
public class CapraExcelRow extends CapraOfficeObject {
/**
+ * RegEx of characters (tabs, newlines, carriage returns and invisible
+ * control characters) to be replaced with white-spaces in the Office View.
+ */
+ private static final String LINE_BREAKS_AND_CONTROL_REQE = "[\r\n\t\\p{C}]+";
+
+ private static final DataFormatter FORMATTER = new DataFormatter();
+
+ /**
* Delimiter between excel cells as displayed in the Office View.
*/
- private static final String cellDelimiter = " | ";
+ private static final String CELL_DELIMITER = " | ";
/**
- * Regex of characters to be replaced with white-spaces in the Office View.
+ * Delimiter between sheetId and rowId as used in the uri.
*/
- private static final String replaceRegex = "[\r\n\t\\p{C}]+";
+ private static final String ID_DELIMITER = "-";
- public CapraExcelRow() {
- super();
- }
+ /**
+ * A constant that is used if the row index isn't found when opening object
+ * details.
+ */
+ private static final int NO_ROW_INDEX = -1;
- public CapraExcelRow(String data, String uri) {
- super(data, uri);
- }
+ /**
+ * A constant that is used if the last cell in the row isn't found.
+ */
+ private static final String NO_LAST_CELL_REFERENCE = "-1";
/**
* A constructor that generates a new instance of CapraExcelRow where the
* parent properties are extracted from the provided Excel row and File
* object that contains the row.
+ *
+ * @param officeFile
+ * a File object representing the Office document
+ * @param row
+ * an Excel row, extracted from an Excel document
+ *
*/
- public CapraExcelRow(Row row, File officeFile, DataFormatter formatter) {
- int rowNum = row.getRowNum();
+ public CapraExcelRow(File officeFile, Row row) {
+ super();
+ String rowId = FORMATTER.formatCellValue(row.getCell(0));
StringBuilder rowBuilder = new StringBuilder();
- rowBuilder.append("Row " + (rowNum + 1) + ": ");
+ rowBuilder.append("ID " + rowId + ": ");
boolean firstCellSet = false;
- for (int j = 0; j < row.getLastCellNum(); j++) {
+ for (int j = 1; j < row.getLastCellNum(); j++) {
Cell cell = row.getCell(j);
- String cellValue = formatter.formatCellValue(cell);
+ String cellValue = FORMATTER.formatCellValue(cell);
if (!cellValue.isEmpty()) {
if (!firstCellSet) {
rowBuilder.append(cellValue);
firstCellSet = true;
} else {
- rowBuilder.append(cellDelimiter + cellValue);
+ rowBuilder.append(CELL_DELIMITER + cellValue);
}
}
}
if (firstCellSet) {
- Pattern p = Pattern.compile(replaceRegex);
+ Pattern p = Pattern.compile(LINE_BREAKS_AND_CONTROL_REQE);
Matcher m = p.matcher(rowBuilder);
String rowContent = (m.replaceAll(" ")).trim();
- String rowUri = CapraOfficeObject.createUri(officeFile, rowNum);
+ String rowUriEnd = row.getSheet().getSheetName() + ID_DELIMITER + rowId;
+ String rowUri = CapraOfficeObject.createUri(officeFile, rowUriEnd);
this.setData(rowContent);
this.setUri(rowUri);
}
}
+
+ @Override
+ public void showOfficeObjectInNativeEnvironment() throws CapraOfficeObjectNotFound {
+
+ String fileType = Files.getFileExtension(getFile().getAbsolutePath());
+ String rowId = getRowId();
+ String sheetName = getSheetName();
+
+ Sheet sheet;
+
+ try (FileInputStream in = new FileInputStream(getFile())) {
+ if (fileType.equals(CapraOfficeObject.XLSX)) {
+ sheet = new XSSFWorkbook(in).getSheet(sheetName);
+ } else {
+ sheet = new HSSFWorkbook(in).getSheet(sheetName);
+ }
+ } catch (IOException e) {
+ e.printStackTrace();
+ return;
+ }
+
+ DataFormatter formatter = new DataFormatter();
+ int rowIndex = NO_ROW_INDEX;
+ String lastCellReference = NO_LAST_CELL_REFERENCE;
+ for (int i = 0; i <= sheet.getLastRowNum(); i++) {
+ Row row = sheet.getRow(i);
+ if (row != null) {
+ String currRowID = formatter.formatCellValue(row.getCell(0));
+ if (currRowID.equals(rowId)) {
+ rowIndex = i;
+ lastCellReference = CellReference.convertNumToColString(row.getLastCellNum()) + (rowIndex + 1);
+ break;
+ }
+ }
+ }
+
+ if (rowIndex == NO_ROW_INDEX || lastCellReference == NO_LAST_CELL_REFERENCE)
+ throw new CapraOfficeObjectNotFound(getRowId());
+
+ int firstDisplayedRowIndex = (rowIndex - 2 > 0) ? rowIndex - 2 : 1;
+ if (fileType.equals(CapraOfficeObject.XLSX)) {
+ XSSFSheet xssfSheet = XSSFSheet.class.cast(sheet);
+ int sheetIndex = xssfSheet.getWorkbook().getSheetIndex(xssfSheet);
+ xssfSheet.getWorkbook().setActiveSheet(sheetIndex);
+
+ CTSheetViews ctSheetViews = xssfSheet.getCTWorksheet().getSheetViews();
+ CTSheetView ctSheetView = ctSheetViews.getSheetViewArray(ctSheetViews.sizeOfSheetViewArray() - 1);
+ ctSheetView.setTopLeftCell("A" + firstDisplayedRowIndex);
+
+ CTSelection ctSelection = ctSheetView.addNewSelection();
+ ctSelection.setActiveCell("A" + (rowIndex + 1));
+ ctSelection.setSqref(Arrays.asList("A" + (rowIndex + 1) + ":" + lastCellReference));
+
+ } else {
+ HSSFSheet hssfSheet = HSSFSheet.class.cast(sheet);
+ hssfSheet.setActive(true);
+ hssfSheet.showInPane((short) (rowIndex), (short) 0);
+
+ HSSFRow row = hssfSheet.getRow(rowIndex);
+ HSSFCell cell = row.getCell(0);
+ cell.setAsActiveCell(); // TODO doesn't work - bug (but xls doesn't
+ // necessarily even have to be supported)
+ }
+
+ try (FileOutputStream out = new FileOutputStream(getFile())) {
+ sheet.getWorkbook().write(out);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+
+ // TODO If Excel is already open, then this doesn't trigger. Is there a
+ // way to refresh the application?
+ try {
+ Desktop.getDesktop().open(getFile());
+ } catch (IOException e) {
+ e.printStackTrace();
+ return;
+ }
+ }
+
+ public String getSheetName() {
+ String itemId = getId();
+ int lastIndexOfDelimiter = itemId.lastIndexOf(ID_DELIMITER);
+ return itemId.substring(0, lastIndexOfDelimiter);
+ }
+
+ public String getRowId() {
+ String itemId = getId();
+ int lastIndexOfDelimiter = itemId.lastIndexOf(ID_DELIMITER);
+ return itemId.substring(lastIndexOfDelimiter + 1);
+ }
}
diff --git a/org.eclipse.capra.ui.office/src/org/eclipse/capra/ui/office/objects/CapraOfficeObject.java b/org.eclipse.capra.ui.office/src/org/eclipse/capra/ui/office/objects/CapraOfficeObject.java
index f595765..b7d223f 100644
--- a/org.eclipse.capra.ui.office/src/org/eclipse/capra/ui/office/objects/CapraOfficeObject.java
+++ b/org.eclipse.capra.ui.office/src/org/eclipse/capra/ui/office/objects/CapraOfficeObject.java
@@ -11,7 +11,11 @@
package org.eclipse.capra.ui.office.objects;
+import java.awt.Desktop;
import java.io.File;
+import java.io.IOException;
+
+import org.eclipse.capra.ui.office.exceptions.CapraOfficeObjectNotFound;
/**
* This class provides a custom object for describing the contents of MS Excel
@@ -23,6 +27,13 @@
public class CapraOfficeObject {
/**
+ * The MS Office file-types that are supported by the plugin.
+ */
+ public static final String DOCX = "docx";
+ public static final String XLS = "xls";
+ public static final String XLSX = "xlsx";
+
+ /**
* The description of the object (row in Excel, requirement in Word)
*/
private String data = "";
@@ -33,10 +44,6 @@
private String uri = "";
/**
- * The delimiter separating the filePath from the objectId in uri
- */
-
- /**
* A constructor that generates an empty instance of OfficeObject.
*/
public CapraOfficeObject() {
@@ -52,17 +59,6 @@
}
/**
- * A constructor that generates a new instance of OfficeObject with defined
- * data and uri properties, the latter being constructed from the file-path
- * and objectId.
- */
- public CapraOfficeObject(String data, File officeFile, String objectId) {
- // TODO here data can be extracted by reading the object in its file
- this.data = data;
- this.uri = createUri(officeFile, objectId);
- }
-
- /**
* Returns the uri of the OfficeObject
*/
public String getUri() {
@@ -99,11 +95,11 @@
}
/**
- * Returns the file-path of the file that contains the OfficeObject
+ * Returns the File reference of the file that contains the OfficeObject
*/
- public String getFilePath() {
+ public File getFile() {
int lastDelimiterIndex = uri.lastIndexOf(File.separator);
- return uri.substring(0, lastDelimiterIndex);
+ return new File(uri.substring(0, lastDelimiterIndex));
}
/**
@@ -131,6 +127,23 @@
}
/**
+ * Opens the OfficeObject in its native environment. If object is of class
+ * OfficeObject (parent object), then the method does nothing but return an
+ * error string
+ *
+ * @return an OK or ERROR message
+ * @throws CapraOfficeObjectNotFound
+ */
+ public void showOfficeObjectInNativeEnvironment() throws CapraOfficeObjectNotFound {
+ try {
+ Desktop.getDesktop().open(getFile());
+ } catch (IOException e) {
+ e.printStackTrace();
+ throw new CapraOfficeObjectNotFound(getId());
+ }
+ }
+
+ /**
* Generates a uri given the file-path of the file that contains the object
* and an objectID
*
diff --git a/org.eclipse.capra.ui.office/src/org/eclipse/capra/ui/office/objects/CapraWordRequirement.java b/org.eclipse.capra.ui.office/src/org/eclipse/capra/ui/office/objects/CapraWordRequirement.java
index 240f066..eab10a7 100644
--- a/org.eclipse.capra.ui.office/src/org/eclipse/capra/ui/office/objects/CapraWordRequirement.java
+++ b/org.eclipse.capra.ui.office/src/org/eclipse/capra/ui/office/objects/CapraWordRequirement.java
@@ -1,3 +1,14 @@
+/*******************************************************************************
+ * Copyright (c) 2016 Chalmers | University of Gothenburg, rt-labs and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Chalmers | University of Gothenburg and rt-labs - initial API and implementation and/or initial documentation
+ *******************************************************************************/
+
package org.eclipse.capra.ui.office.objects;
import java.io.File;
@@ -8,51 +19,52 @@
import javax.xml.parsers.DocumentBuilderFactory;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
+import org.eclipse.capra.ui.office.utils.OfficeProperties;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTP;
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
+/**
+ * This class extends the CapraOfficeObject and provides an object to describe a
+ * single MS Word requirement, which is defined with a specific field.
+ *
+ * @author Dusan Kalanj
+ *
+ */
public class CapraWordRequirement extends CapraOfficeObject {
/**
- * Start and end XML tags of MS Word field commands
+ * RegEx of characters (tabs, newlines, carriage returns and invisible
+ * control characters) to be replaced with white-spaces in the Office View.
*/
- private static final String wordFieldTag = "w:instrText";
-
- /**
- * Regex of characters to be replaced with white-spaces in the Office View.
- */
- private static final String replaceRegex = "[\r\n\t\\p{C}]+";
+ private static final String LINE_BREAKS_AND_CONTROL_REGEX = "[\r\n\t\\p{C}]+";
/**
* Regex of characters to be used as delimiters when splitting the field
* contents.
*/
- private static final String splitFieldRegex = "(\")|(\\\\\\*)";
+ private static final String WORD_FIELD_SPLIT_DELIMITERS = "(\")|(\\\\\\*)";
+
+ /**
+ * Start and end XML tags of MS Word field commands
+ */
+ private static final String REQ_FIELD_TAG = "w:instrText";
/**
* The name of the requirement field as defined in Word.
*/
- // TODO define in properties?
- private static final String fieldName = "REQ";
-
- public CapraWordRequirement() {
- super();
- }
-
- public CapraWordRequirement(String data, String uri) {
- super(data, uri);
- }
+ private static final String REQ_FIELD_NAME = OfficeProperties.getInstance().getProperty("req_fieldName");
/**
* A constructor that generates a new instance of CapraWordRequirement where
* the parent properties are extracted from the provided Word paragraph and
* File object that contains containing the paragraph.
*/
- public CapraWordRequirement(XWPFParagraph paragraph, File officeFile, int objectID) {
+ public CapraWordRequirement(XWPFParagraph paragraph, File officeFile) {
// TODO This solution assumes that there is only one requirement per
// paragraph. Should it be different?
+ super();
String rText = "";
String rId = "";
@@ -66,21 +78,22 @@
return;
}
- NodeList nodeList = doc.getElementsByTagName(wordFieldTag);
+ NodeList nodeList = doc.getElementsByTagName(REQ_FIELD_TAG);
if (nodeList.getLength() > 0) {
// TODO Use a for loop if the solution needs to parse multiple
// requirements in a single paragraph. In that case,
// paragraph.getText() should be replaced with something from the
// org.w3c.dom.Document class.
- String[] parts = nodeList.item(0).getTextContent().split(splitFieldRegex);
- if (Arrays.asList(parts).contains(fieldName) && parts.length > 2) {
+ String[] parts = nodeList.item(0).getTextContent().split(WORD_FIELD_SPLIT_DELIMITERS);
+ if (Arrays.asList(parts).contains(REQ_FIELD_NAME) && parts.length > 2) {
rText = paragraph.getText();
rId = parts[2].trim();
}
}
- rText = rText.replaceAll(replaceRegex, " ").trim();
+ rText = rText.replaceAll(LINE_BREAKS_AND_CONTROL_REGEX, " ").trim();
if (!rText.isEmpty()) {
+ rText = "ID " + rId + ": " + rText;
String pUri = CapraOfficeObject.createUri(officeFile, rId);
this.setData(rText);
diff --git a/org.eclipse.capra.ui.office/src/org/eclipse/capra/ui/office/utils/OfficeProperties.java b/org.eclipse.capra.ui.office/src/org/eclipse/capra/ui/office/utils/OfficeProperties.java
new file mode 100644
index 0000000..481977e
--- /dev/null
+++ b/org.eclipse.capra.ui.office/src/org/eclipse/capra/ui/office/utils/OfficeProperties.java
@@ -0,0 +1,59 @@
+/*******************************************************************************
+ * Copyright (c) 2016 Chalmers | University of Gothenburg, rt-labs and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Chalmers | University of Gothenburg and rt-labs - initial API and implementation and/or initial documentation
+ *******************************************************************************/
+
+package org.eclipse.capra.ui.office.utils;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Properties;
+
+/**
+ * This singleton class provides access to the plugin.properties file.
+ *
+ * @author Dusan Kalanj
+ *
+ */
+public class OfficeProperties {
+
+ private static OfficeProperties officeProperties = new OfficeProperties();
+
+ private Properties properties;
+
+ private OfficeProperties() {
+ this.properties = new Properties();
+
+ try (InputStream is = this.getClass().getClassLoader().getResourceAsStream("plugin.properties")){
+ properties.load(is);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * Provides an instance of OfficeProperties class.
+ *
+ * @return instance of OfficeProperties
+ */
+ public static OfficeProperties getInstance() {
+ return officeProperties;
+ }
+
+ /**
+ * Returns the property String that corresponds to the provided key.
+ *
+ * @param key
+ * key of the property to be accessed
+ * @return value of the property that is defined by the provided key
+ */
+ public String getProperty(String key) {
+ return properties.getProperty(key);
+ }
+}
diff --git a/org.eclipse.capra.ui.office/src/org/eclipse/capra/ui/office/utils/OfficeTransferType.java b/org.eclipse.capra.ui.office/src/org/eclipse/capra/ui/office/utils/OfficeTransferType.java
index 6b174c3..e87911c 100644
--- a/org.eclipse.capra.ui.office/src/org/eclipse/capra/ui/office/utils/OfficeTransferType.java
+++ b/org.eclipse.capra.ui.office/src/org/eclipse/capra/ui/office/utils/OfficeTransferType.java
@@ -93,9 +93,8 @@
ArrayList<CapraOfficeObject> officeObjects = (ArrayList<CapraOfficeObject>) object;
- try {
- ByteArrayOutputStream out = new ByteArrayOutputStream();
- DataOutputStream writeOut = new DataOutputStream(out);
+ try (ByteArrayOutputStream out = new ByteArrayOutputStream();
+ DataOutputStream writeOut = new DataOutputStream(out)) {
for (int i = 0; i < officeObjects.size(); i++) {
CapraOfficeObject currOfficeObject = officeObjects.get(i);
@@ -110,11 +109,10 @@
}
byte[] bufferOut = out.toByteArray();
- writeOut.close();
super.javaToNative(bufferOut, transferData);
} catch (IOException e) {
-
+ e.printStackTrace();
}
}
@@ -133,9 +131,8 @@
ArrayList<CapraOfficeObject> officeObjects = new ArrayList<CapraOfficeObject>();
- try {
- ByteArrayInputStream in = new ByteArrayInputStream(buffer);
- DataInputStream readIn = new DataInputStream(in);
+ try (ByteArrayInputStream in = new ByteArrayInputStream(buffer);
+ DataInputStream readIn = new DataInputStream(in)) {
while (readIn.available() > 0) {
@@ -154,9 +151,9 @@
officeObjects.add(currOfficeObject);
}
- readIn.close();
- } catch (IOException ex) {
+ } catch (IOException e) {
+ e.printStackTrace();
return null;
}
diff --git a/org.eclipse.capra.ui.office/src/org/eclipse/capra/ui/office/views/OfficeView.java b/org.eclipse.capra.ui.office/src/org/eclipse/capra/ui/office/views/OfficeView.java
index e526eb2..fa062d9 100644
--- a/org.eclipse.capra.ui.office/src/org/eclipse/capra/ui/office/views/OfficeView.java
+++ b/org.eclipse.capra.ui.office/src/org/eclipse/capra/ui/office/views/OfficeView.java
@@ -19,14 +19,15 @@
import org.apache.poi.hssf.OldExcelFormatException;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
-import org.apache.poi.openxml4j.opc.OPCPackage;
-import org.apache.poi.ss.usermodel.DataFormatter;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
+import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.apache.xmlbeans.SchemaTypeLoaderException;
+import org.eclipse.capra.ui.office.exceptions.CapraOfficeFileNotSupportedException;
+import org.eclipse.capra.ui.office.exceptions.CapraOfficeObjectNotFound;
import org.eclipse.capra.ui.office.objects.CapraExcelRow;
import org.eclipse.capra.ui.office.objects.CapraOfficeObject;
import org.eclipse.capra.ui.office.objects.CapraWordRequirement;
@@ -82,23 +83,23 @@
public static final String ID = "org.eclipse.capra.ui.views.OfficeView";
/**
- * A constant that is used for checking whether the ID of the object is
- * provided or not
+ * A constant that is used to specify that the user should be prompted to
+ * select a sheet when opening an excel document.
*/
- public static final String OBJECT_ID_NOT_SPECIFIED = "-1";
+ public static final boolean SHEET_SELECT_REQUIRED = true;
/**
- * The MS Office file-types that are supported by the plugin.
+ * A constant that is used to specify that the user doesn't have to be
+ * prompted to select a sheet and the currently active sheet will be
+ * displayed.
*/
- public static final String DOCX = "docx";
- public static final String XLS = "xls";
- public static final String XLSX = "xlsx";
+ public static final boolean SHEET_SELECT_NOT_REQUIRED = false;
/**
- * This file-type is not supported, but is needed to display the correct
- * error message.
+ * The caption that is shown when a message dialog appears describing an
+ * error.
*/
- public static final String DOC = "doc";
+ private static final String ERROR_TITLE = "Error";
/**
* The actual view that contains the contents of the documents.
@@ -165,7 +166,13 @@
@Override
public boolean performDrop(Object data) {
- dropToSelection(data);
+ try {
+ dropToSelection(data);
+ } catch (CapraOfficeFileNotSupportedException e) {
+ e.printStackTrace();
+ showMessage(viewer.getControl().getShell(), SWT.ERROR, ERROR_TITLE, e.getMessage());
+ return false;
+ }
return true;
}
@@ -242,111 +249,92 @@
*
* @param data
* the object that was dragged into the view
+ * @throws CapraOfficeFileNotSupportedException
*/
- public void dropToSelection(Object data) {
+ private void dropToSelection(Object data) throws CapraOfficeFileNotSupportedException {
- File officeFile = null;
+ File file = null;
if (data instanceof String[])
- officeFile = new File(((String[]) data)[0]);
+ file = new File(((String[]) data)[0]);
- if (officeFile != null)
- parseFile(officeFile, OBJECT_ID_NOT_SPECIFIED);
+ if (file == null)
+ return;
+
+ String fileExtension = Files.getFileExtension(file.getName());
+
+ if (fileExtension.equals(CapraOfficeObject.XLSX) || fileExtension.equals(CapraOfficeObject.XLS))
+ parseExcelDocument(file, SHEET_SELECT_NOT_REQUIRED);
+ else if (fileExtension.equals(CapraOfficeObject.DOCX))
+ parseWordDocument(file);
else
- showMessage(viewer.getControl().getShell(), SWT.ERROR, "Error", "Not an Excel or Word file.");
+ throw new CapraOfficeFileNotSupportedException(fileExtension);
viewer.refresh();
}
/**
- * Calls the appropriate parse method (according to the file extension),
- * which displays the data in the Office view.
- *
- * @param officeFile
- * the File object that points to the file that is to be parsed
- * @param objectID
- * if provided, only the object with this ID will be displayed
- */
- private void parseFile(File officeFile, String objectID) {
-
- String fileType = Files.getFileExtension(officeFile.getAbsolutePath());
-
- if (fileType.equals(XLSX) || fileType.equals(XLS)) {
- getOpenedView().clearSelection();
- parseExcelDocument(officeFile, objectID);
-
- } else if (fileType.equals(DOCX)) {
- getOpenedView().clearSelection();
- parseWordDocument(officeFile, objectID);
-
- } else if (fileType.equals(DOC)) {
- showMessage(viewer.getControl().getShell(), SWT.ERROR, "Error",
- ".doc file format not supported, use .docx");
-
- } else {
- showMessage(viewer.getControl().getShell(), SWT.ERROR, "Error", "Not an Excel or Word file.");
- }
- }
-
- /**
* Extracts the data from the Excel document and adds it to the view.
*
* @param officeFile
* the File object pointing to the Excel document that was
* dragged into the view.
- * @param objectID
- * the row ID; if "-1" (the value of constant
- * OBJECT_ID_NOT_SPECIFIED), the whole document will print out,
- * otherwise only the selected row
+ * @param sheetSelect
+ * true if the user has to be prompted to select a sheet, false
+ * otherwise
*/
- private void parseExcelDocument(File officeFile, String objectID) {
+ private void parseExcelDocument(File officeFile, boolean sheetSelect) {
String fileType = Files.getFileExtension(officeFile.getAbsolutePath());
- Sheet sheet;
+ Workbook workBook;
try {
- if (fileType.equals(XLSX)) {
- sheet = new XSSFWorkbook(OPCPackage.open(officeFile)).getSheetAt(0);
- } else {
- sheet = new HSSFWorkbook(new FileInputStream(officeFile)).getSheetAt(0);
- }
+ if (fileType.equals(CapraOfficeObject.XLSX))
+ workBook = new XSSFWorkbook(new FileInputStream(officeFile));
+ else
+ workBook = new HSSFWorkbook(new FileInputStream(officeFile));
} catch (OldExcelFormatException e) {
- showMessage(viewer.getControl().getShell(), SWT.ERROR, "Error", "This version of Excel is not supported.");
+ showMessage(viewer.getControl().getShell(), SWT.ERROR, ERROR_TITLE, e.getMessage());
return;
- } catch (Exception e) {
+ } catch (IOException e) {
e.printStackTrace();
- showMessage(viewer.getControl().getShell(), SWT.ERROR, "Error", "Couldn't open the file.");
return;
}
- DataFormatter formatter = new DataFormatter();
+ String selectedSheetName;
+ if (!sheetSelect)
+ selectedSheetName = workBook.getSheetName(workBook.getActiveSheetIndex());
+ else if (selection.size() > 0) {
+ String activeSheetName = ((CapraExcelRow) selection.get(0)).getSheetName();
+ String[] sNames = new String[workBook.getNumberOfSheets()];
+
+ // Fill sNames with sheetNames, with the active sheet at index 0
+ int counter = 0;
+ sNames[counter++] = activeSheetName;
+ for (int i = 0; i < sNames.length; i++) {
+ String sName = workBook.getSheetName(i);
+ if (sName.equals(activeSheetName))
+ continue;
+ sNames[counter++] = workBook.getSheetName(i);
+ }
+
+ selectedSheetName = new SelectSheetDialog(viewer.getControl().getShell(),
+ SWT.DIALOG_TRIM | SWT.APPLICATION_MODAL, sNames).open();
+ } else {
+ return;
+ }
+
+ Sheet sheet = workBook.getSheet(selectedSheetName);
getOpenedView().clearSelection();
- // TODO Currently, the first block of code is only accessed
- // if the method is triggered via OfficeHandler. Does this have to
- // change if the handler is not allowed to have a dependency on UI?
- // Also, the solution assumes that the location of the row is also the
- // rowId, should that be different? Should the ID be defined, for
- // example, in the first cell?
- if (!objectID.equals(OBJECT_ID_NOT_SPECIFIED)) {
- Row row = sheet.getRow(Integer.parseInt(objectID));
+ for (int i = 0; i <= sheet.getLastRowNum(); i++) {
+ Row row = sheet.getRow(i);
if (row != null) {
- CapraExcelRow cRow = new CapraExcelRow(row, officeFile, formatter);
-
+ CapraExcelRow cRow = new CapraExcelRow(officeFile, row);
if (!cRow.getData().isEmpty())
selection.add(cRow);
}
- } else {
- for (int i = 0; i <= sheet.getLastRowNum(); i++) {
- Row row = sheet.getRow(i);
- if (row != null) {
- CapraExcelRow cRow = new CapraExcelRow(row, officeFile, formatter);
-
- if (!cRow.getData().isEmpty())
- selection.add(cRow);
- }
- }
}
}
@@ -356,79 +344,40 @@
* @param officeFile
* the File object pointing of the Word document that was dragged
* into the view.
- * @param objectID
- * the paragraph/requirement ID; if "-1" (the value of constant
- * OBJECT_ID_NOT_SPECIFIED), the whole document will print out,
- * otherwise only the selected object
*/
- private void parseWordDocument(File officeFile, String objectID) {
+ private void parseWordDocument(File officeFile) {
List<XWPFParagraph> paragraphs;
try {
FileInputStream fs = new FileInputStream(officeFile);
- // TODO The following line always triggers an exception!
XWPFDocument xwpfDoc = new XWPFDocument(fs);
+ fs.close();
paragraphs = (xwpfDoc).getParagraphs();
- // If poi 3.15 is used, it allows closing the XWPFDocument. If 3.9
- // is used it is not possible.
- // xwpfDoc.close();
} catch (IOException e) {
e.printStackTrace();
- showMessage(viewer.getControl().getShell(), SWT.ERROR, "Error", "Couldn't open the file.");
+ showMessage(viewer.getControl().getShell(), SWT.ERROR, ERROR_TITLE, e.getMessage());
return;
} catch (SchemaTypeLoaderException e) {
- // TODO This is the exception for the error!
e.printStackTrace();
- showMessage(viewer.getControl().getShell(), SWT.ERROR, "Error", "Couldn't open the file.");
+ showMessage(viewer.getControl().getShell(), SWT.ERROR, ERROR_TITLE, e.getMessage());
return;
}
+ getOpenedView().clearSelection();
+
for (int i = 0; i < paragraphs.size(); i++) {
XWPFParagraph paragraph = paragraphs.get(i);
if (paragraph != null) {
- CapraWordRequirement cRequirement = new CapraWordRequirement(paragraph, officeFile, i);
-
- // TODO Currently, this condition is only true if the method
- // is triggered via OfficeHandler. Does this have to change
- // if the handler is not allowed to have a dependency on UI?
- if (!objectID.equals(OBJECT_ID_NOT_SPECIFIED)) {
- if (cRequirement.getId().equals(objectID)) {
- selection.add(cRequirement);
- break;
- }
- } else if (!cRequirement.getData().isEmpty())
+ CapraWordRequirement cRequirement = new CapraWordRequirement(paragraph, officeFile);
+ if (!cRequirement.getData().isEmpty())
selection.add(cRequirement);
}
}
}
/**
- * Shows only the selected OfficeObject in the Office Selection View.
- *
- * @param uri
- * the uri of the row/word_requirement, containing the file path
- * and the index of the row/word_requirement
- */
- public void showSingleOfficeObjectInOfficeView(String uri) {
-
- if (uri.isEmpty())
- return;
-
- File officeFile = new File(CapraOfficeObject.getFilePathFromUri(uri));
- String objectID = CapraOfficeObject.getIdFromUri(uri);
-
- // Check if the file (still) exists.
- if (officeFile.exists())
- parseFile(officeFile, objectID);
- else
- showMessage(viewer.getControl().getShell(), SWT.ERROR, "Error", "Resource not found.");
-
- viewer.refresh();
- }
-
- /**
- * Shows the dialog with the information about the selected element in the
- * view.
+ * Shows the details of the object in its native environment (MS Word or MS
+ * Excel).
*
* @param event
* Should be of type DoubleClickEvent or ExecutionEvent, hold the
@@ -437,7 +386,6 @@
* Shell which will be the parent of the dialog window.
*/
public void showObjectDetails(Object event, Shell parentShell) {
-
CapraOfficeObject officeObject;
if (event instanceof DoubleClickEvent) { // If called with double click
@@ -452,24 +400,19 @@
officeObject = (CapraOfficeObject) selection.getFirstElement();
} catch (ExecutionException e) {
e.printStackTrace();
- officeObject = null;
+ return;
}
} else {
- officeObject = null;
+ return;
}
- String caption;
- String message;
-
- if (officeObject == null) {
- caption = "Notification";
- message = "No information to show.";
- } else {
- caption = "Row " + officeObject.getId();
- message = officeObject.getData();
+ try {
+ officeObject.showOfficeObjectInNativeEnvironment();
+ } catch (CapraOfficeObjectNotFound e) {
+ e.printStackTrace();
+ showMessage(viewer.getControl().getShell(), SWT.ERROR, ERROR_TITLE, e.getMessage());
}
- showMessage(parentShell, SWT.OK, caption, message);
}
/**
@@ -481,16 +424,55 @@
}
/**
- * Opens a file-chooser dialog and calls the parseFile method, which
+ * Opens a file-chooser dialog and calls the parseOfficeFile method, which
* displays the contents of the selected file in the TableViewer (if the
* file is of type xlsx, xls or docx).
*/
public void openFile() {
FileDialog fd = new FileDialog(viewer.getControl().getShell(), SWT.OK);
- File officeFile = new File(fd.open());
+ String filePath = fd.open();
- parseFile(officeFile, OBJECT_ID_NOT_SPECIFIED);
+ if (filePath != null && !filePath.isEmpty()) {
+ File file = new File(filePath);
+ if (file != null) {
+ try {
+ dropToSelection(new String[] { file.getAbsolutePath() });
+ } catch (CapraOfficeFileNotSupportedException e) {
+ e.printStackTrace();
+ showMessage(viewer.getControl().getShell(), SWT.ERROR, ERROR_TITLE, e.getMessage());
+ }
+ viewer.refresh();
+ }
+ }
+ }
+
+ /**
+ * Opens a pop-up window that allows the user to select which excel sheet
+ * should be displayed.
+ */
+ public void selectSheet() {
+
+ if (selection.isEmpty()) {
+ // TODO custom exception
+ return;
+ }
+
+ if (selection.get(0).getClass().equals(CapraWordRequirement.class)) {
+ // TODO custom exception - although this check won't be necessary
+ // since the select sheet option will be hidden (not yet
+ // implemented) when the selection is empty or when Word file is
+ // displayed. Therefore also the first check won't necessary.
+ return;
+ }
+
+ File currentFile = ((CapraExcelRow) selection.get(0)).getFile();
+
+ if (!Files.getFileExtension(currentFile.getAbsolutePath()).equals(CapraOfficeObject.XLSX)
+ && !Files.getFileExtension(currentFile.getAbsolutePath()).equals(CapraOfficeObject.XLS))
+ return;
+
+ parseExcelDocument(currentFile, SHEET_SELECT_REQUIRED);
viewer.refresh();
}
diff --git a/org.eclipse.capra.ui.office/src/org/eclipse/capra/ui/office/views/SelectSheetDialog.java b/org.eclipse.capra.ui.office/src/org/eclipse/capra/ui/office/views/SelectSheetDialog.java
new file mode 100644
index 0000000..902fd37
--- /dev/null
+++ b/org.eclipse.capra.ui.office/src/org/eclipse/capra/ui/office/views/SelectSheetDialog.java
@@ -0,0 +1,180 @@
+package org.eclipse.capra.ui.office.views;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Dialog;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Listener;
+import org.eclipse.swt.widgets.Menu;
+import org.eclipse.swt.widgets.MenuItem;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.ToolBar;
+import org.eclipse.swt.widgets.ToolItem;
+
+/**
+ * A class that extends Dialog in order to prompt the user for which excel sheet
+ * to display.
+ *
+ * Code adapted from:
+ * http://www.java2s.com/Code/Java/SWT-JFace-Eclipse/Howtocreateyourowndialogclasses.htm
+ *
+ * @author Dusan Kalanj
+ *
+ */
+public class SelectSheetDialog extends Dialog {
+
+ /**
+ * Strings that are displayed in the Dialog.
+ */
+ private static final String PROMPT_MESSAGE = "Please select the sheet to display.";
+ private static final String SELECT_TIP = "Click here to select the sheet.";
+ private static final String OK = "OK";
+ private static final String CANCEL = "Cancel";
+
+ /**
+ * Top margin between elements in the dialog.
+ */
+ private static final int VERTICAL_INDENT = 10;
+
+ private String[] sheetNames;
+ private String selectedSheetName;
+
+ /**
+ * SelectSheetDialog constructor.
+ *
+ * @param parentShell
+ * the shell that will accommodate the dialog.
+ * @param style
+ * the style used by the dialog
+ * @param currentSheet
+ * the currently displayed sheet
+ * @param totalNumOfSheets
+ * the sheet that was selected in the dialog.
+ */
+ public SelectSheetDialog(Shell parentShell, int style, String[] sheetNames) {
+ super(parentShell, style);
+ this.sheetNames = sheetNames;
+ this.selectedSheetName = sheetNames[0];
+ }
+
+ /**
+ * Opens the dialog and returns the index of the selected sheet.
+ *
+ * @return the number of the sheet to display
+ */
+ public String open() {
+ Shell shell = new Shell(getParent(), getStyle());
+ createContents(shell);
+
+ Rectangle shellBounds = getParent().getBounds();
+
+ shell.setLocation(shellBounds.x + shellBounds.width / 2, shellBounds.y + shellBounds.height / 2);
+ shell.pack();
+ shell.open();
+
+ Display display = getParent().getDisplay();
+ while (!shell.isDisposed()) {
+ if (!display.readAndDispatch()) {
+ display.sleep();
+ }
+ }
+
+ return selectedSheetName;
+ }
+
+ /**
+ * Fills the dialog window with content.
+ *
+ * @param shell
+ * the window of the dialog
+ */
+ private void createContents(final Shell shell) {
+
+ GridLayout gridLayout = new GridLayout(2, true);
+ shell.setLayout(gridLayout);
+
+ Label label = new Label(shell, SWT.NONE);
+ label.setText(PROMPT_MESSAGE);
+ GridData data = new GridData(GridData.FILL_HORIZONTAL);
+ data.horizontalSpan = 2;
+ label.setLayoutData(data);
+
+ final ToolBar toolBar = new ToolBar(shell, SWT.NONE);
+ data = new GridData(SWT.CENTER, SWT.CENTER, true, true, 1, 1);
+ data.verticalIndent = VERTICAL_INDENT;
+ data.horizontalSpan = 2;
+ toolBar.setLayoutData(data);
+ final ToolItem itemDropDown = new ToolItem(toolBar, SWT.DROP_DOWN);
+ final Menu menu = new Menu(shell, SWT.POP_UP);
+
+ itemDropDown.setText(sheetNames[0]);
+ itemDropDown.setToolTipText(SELECT_TIP);
+
+ for (int i = 0; i < sheetNames.length; i++) {
+ MenuItem item = new MenuItem(menu, SWT.PUSH);
+ item.setText(sheetNames[i]);
+ item.addSelectionListener(new SelectionListener() {
+
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ selectedSheetName = item.getText();
+ itemDropDown.setText(selectedSheetName);
+
+ toolBar.pack();
+ }
+
+ @Override
+ public void widgetDefaultSelected(SelectionEvent e) {
+ selectedSheetName = item.getText();
+ itemDropDown.setText(selectedSheetName);
+ toolBar.pack();
+ }
+ });
+ }
+
+ itemDropDown.addListener(SWT.Selection, new Listener() {
+ public void handleEvent(Event event) {
+ Rectangle bounds = itemDropDown.getBounds();
+ Point point = toolBar.toDisplay(bounds.x, bounds.y + bounds.height);
+ menu.setLocation(point);
+ menu.setVisible(true);
+ }
+ });
+
+ Button ok = new Button(shell, SWT.PUSH);
+ ok.setText(OK);
+ data = new GridData(GridData.FILL_HORIZONTAL);
+ data.verticalIndent = VERTICAL_INDENT;
+ data.horizontalSpan = 1;
+ ok.setLayoutData(data);
+ ok.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent event) {
+ shell.close();
+ }
+ });
+
+ Button cancel = new Button(shell, SWT.PUSH);
+ cancel.setText(CANCEL);
+ data = new GridData(GridData.FILL_HORIZONTAL);
+ data.verticalIndent = VERTICAL_INDENT;
+ data.horizontalSpan = 1;
+ cancel.setLayoutData(data);
+ cancel.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent event) {
+ selectedSheetName = sheetNames[0];
+ shell.close();
+ }
+ });
+
+ shell.setDefaultButton(ok);
+ }
+}
diff --git a/org.eclipse.capra.ui/plugin.xml b/org.eclipse.capra.ui/plugin.xml
index 936fec3..97f24c7 100644
--- a/org.eclipse.capra.ui/plugin.xml
+++ b/org.eclipse.capra.ui/plugin.xml
@@ -91,7 +91,8 @@
name="org.eclipse.capra.generic.separator2">
</separator>
<menu
- label="Capra">
+ label="Capra"
+ id="org.eclipse.capra.ui.contextsubmenu">
<command
commandId="org.eclipse.capra.generic.addtoselection"
label="Add to Selection"
diff --git a/org.eclipse.capra.ui/src/org/eclipse/capra/ui/views/SelectionView.java b/org.eclipse.capra.ui/src/org/eclipse/capra/ui/views/SelectionView.java
index b9a3e42..bcabd56 100644
--- a/org.eclipse.capra.ui/src/org/eclipse/capra/ui/views/SelectionView.java
+++ b/org.eclipse.capra.ui/src/org/eclipse/capra/ui/views/SelectionView.java
@@ -135,9 +135,9 @@
class SelectionDropAdapter extends ViewerDropAdapter {
TableViewer view;
- public SelectionDropAdapter(TableViewer viewer) {
+ public SelectionDropAdapter(TableViewer view) {
super(viewer);
- this.view = viewer;
+ this.view = view;
}
@Override