diff --git a/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/pdf/Messages.java b/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/pdf/Messages.java
index b3476e9615c671ce04bbdea202ad2192a04c2157..2fe5d0e7945e4497457a86baa0645487df1b2354 100644
--- a/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/pdf/Messages.java
+++ b/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/pdf/Messages.java
@@ -15,6 +15,21 @@ import org.eclipse.osgi.util.NLS;
 
 public class Messages extends NLS {
 	private static final String BUNDLE_NAME = Messages.class.getPackageName() + ".messages"; //$NON-NLS-1$
+	public static String NodeTree_Available;
+	public static String NodeTree_Collapse_Text;
+	public static String NodeTree_Collapse_Tooltip;
+	public static String NodeTree_Column_Diagram;
+	public static String NodeTree_Column_Documentation;
+	public static String NodeTree_Column_Item;
+	public static String NodeTree_Expand_Text;
+	public static String NodeTree_Expand_Tooltip;
+	public static String NodeTree_Filter;
+	public static String NodeTree_Included;
+	public static String NodeTree_NoContent;
+	public static String NodeTree_SubtreeSelection_Text;
+	public static String NodeTree_SubtreeSelection_Tooltip;
+	public static String NodeTree_SubtreeSelection_Tooltip_Filtered;
+	public static String NodeTree_Tooltip;
 	public static String PDFExportPage_AddPageNumbers;
 	public static String PDFExportPage_BrowseButtonText;
 	public static String PDFExportPage_Error_TargetAlreadyExists_IsDir;
diff --git a/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/pdf/NodeTree.java b/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/pdf/NodeTree.java
index 1facf351e5ef59c489e90ae90bb7b4e78f4dd94c..e591653b0b718781e7a9fa1bccc57eebe60927f4 100644
--- a/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/pdf/NodeTree.java
+++ b/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/pdf/NodeTree.java
@@ -72,8 +72,8 @@ import org.simantics.utils.ui.ISelectionUtils;
  */
 public class NodeTree extends Composite {
 
-	public static final String COLUMN_KEY_DIAGRAM = "diagram";
-	public static final String COLUMN_KEY_DOC = "doc";
+	public static final String COLUMN_KEY_DIAGRAM = "diagram"; //$NON-NLS-1$
+	public static final String COLUMN_KEY_DOC = "doc"; //$NON-NLS-1$
 
 	/**
 	 * This exists to make {@link NodeCheckStateProvider} faster
@@ -114,6 +114,8 @@ public class NodeTree extends Composite {
 
 	protected CheckboxTreeViewer   tree;
 
+	protected Button               selectSubtreeToggle;
+
 	/**
 	 * The tree paths that were expanded last time no filter was defined. Will
 	 * be nullified after the expanded paths have been returned when
@@ -174,7 +176,7 @@ public class NodeTree extends Composite {
 
 	private void createFilter(Composite parent) {
 		Label filterLabel = new Label(parent, SWT.NONE);
-		filterLabel.setText("Fi&lter:");
+		filterLabel.setText(Messages.NodeTree_Filter);
 		GridDataFactory.fillDefaults().span(1, 1).applyTo(filterLabel);
 		filter = new Text(parent, SWT.BORDER);
 		GridDataFactory.fillDefaults().span(2, 1).applyTo(filter);
@@ -192,7 +194,7 @@ public class NodeTree extends Composite {
 		tree.getTree().setHeaderVisible(true);
 		tree.setUseHashlookup(true);
 		//GridDataFactory.fillDefaults().grab(true, true).span(3, 1).applyTo(tree.getControl());
-		tree.getControl().setToolTipText("Selects the items to include in the exported document.");
+		tree.getControl().setToolTipText(Messages.NodeTree_Tooltip);
 		tree.setAutoExpandLevel(2);
 		tree.addCheckStateListener(new CheckStateListener());
 		tree.setContentProvider(new NodeTreeContentProvider());
@@ -202,19 +204,19 @@ public class NodeTree extends Composite {
 		tree.setFilters(new ViewerFilter[] { new NodeFilter() });
 
 		TreeViewerColumn c1 = new TreeViewerColumn(tree, SWT.LEFT);
-		c1.getColumn().setText("Item");
+		c1.getColumn().setText(Messages.NodeTree_Column_Item);
 		c1.getColumn().setWidth(200);
 		c1.setLabelProvider(new NodeLabelProvider());
 		treeLayout.setColumnData(c1.getColumn(), new ColumnWeightData(100, 200));
 
 		TreeViewerColumn c2 = new TreeViewerColumn(tree, SWT.CENTER);
-		c2.getColumn().setText("Diagram");
+		c2.getColumn().setText(Messages.NodeTree_Column_Diagram);
 		c2.getColumn().setWidth(130);
 		c2.setLabelProvider(new HasDiagramLabelProvider());
 		treeLayout.setColumnData(c2.getColumn(), new ColumnWeightData(0, 130));
 
 		TreeViewerColumn c3 = new TreeViewerColumn(tree, SWT.CENTER);
-		c3.getColumn().setText("Documentation");
+		c3.getColumn().setText(Messages.NodeTree_Column_Documentation);
 		c3.getColumn().setWidth(130);
 		c3.setLabelProvider(new HasDocLabelProvider());
 		treeLayout.setColumnData(c3.getColumn(), new ColumnWeightData(0, 130));
@@ -225,9 +227,9 @@ public class NodeTree extends Composite {
 		GridDataFactory.fillDefaults().grab(true, false).span(3, 1).applyTo(bar);
 		bar.setLayout(new RowLayout());
 
-		Button selectSubtreeToggle = new Button(bar, SWT.TOGGLE);
-		selectSubtreeToggle.setText("Sub&tree Selection");
-		selectSubtreeToggle.setToolTipText("Enable/Disable Selection of Visible Subtree on Checkbox Click");
+		selectSubtreeToggle = new Button(bar, SWT.TOGGLE);
+		selectSubtreeToggle.setText(Messages.NodeTree_SubtreeSelection_Text);
+		selectSubtreeToggle.setToolTipText(subtreeToggleTooltip(false));
 		selectSubtreeToggle.setSelection(selectSubtreeEnabled);
 		selectSubtreeToggle.addSelectionListener(SelectionListener.widgetSelectedAdapter(e -> {
 			selectSubtreeEnabled = selectSubtreeToggle.getSelection();
@@ -236,8 +238,8 @@ public class NodeTree extends Composite {
 		}));
 
 		Button expand = new Button(bar, SWT.PUSH);
-		expand.setText("&Expand");
-		expand.setToolTipText("Fully Expand Selected Nodes or All Nodes");
+		expand.setText(Messages.NodeTree_Expand_Text);
+		expand.setToolTipText(Messages.NodeTree_Expand_Tooltip);
 		expand.addSelectionListener(SelectionListener.widgetSelectedAdapter(e -> {
 			IStructuredSelection ss = tree.getStructuredSelection();
 			if (ss.isEmpty())
@@ -248,8 +250,8 @@ public class NodeTree extends Composite {
 			scheduleFocusTree();
 		}));
 		Button collapse = new Button(bar, SWT.PUSH);
-		collapse.setText("&Collapse");
-		collapse.setToolTipText("Collapse Selected Nodes or All Nodes");
+		collapse.setText(Messages.NodeTree_Collapse_Text);
+		collapse.setToolTipText(Messages.NodeTree_Collapse_Tooltip);
 		collapse.addSelectionListener(SelectionListener.widgetSelectedAdapter(e -> {
 			IStructuredSelection ss = tree.getStructuredSelection();
 			if (ss.isEmpty())
@@ -310,8 +312,9 @@ public class NodeTree extends Composite {
 				// Filter has been defined after not being previously defined
 				noFilterExpandedPaths = tree.getExpandedTreePaths();
 			}
-			matcher = Pattern.compile(patternString).matcher("");
+			matcher = Pattern.compile(patternString).matcher(""); //$NON-NLS-1$
 		}
+		selectSubtreeToggle.setToolTipText(subtreeToggleTooltip(matcher != null));
 		refreshTree(false);
 		if (restoreExpansions != null)
 			tree.setExpandedTreePaths(restoreExpansions);
@@ -490,14 +493,14 @@ public class NodeTree extends Composite {
 				Node n = (Node) e;
 				if (n.getDiagramResource() != null) {
 					if (selectedNodes.contains(n) && inclusionFilter.test(n, COLUMN_KEY_DIAGRAM)) {
-						cell.setText("Included");
+						cell.setText(Messages.NodeTree_Included);
 						cell.setForeground(includedColor);
 					} else {
-						cell.setText("Available");
+						cell.setText(Messages.NodeTree_Available);
 						cell.setForeground(availableColor);
 					}
 				} else {
-					cell.setText("-");
+					cell.setText(Messages.NodeTree_NoContent);
 					cell.setForeground(noContentColor);
 				}
 			}
@@ -512,14 +515,14 @@ public class NodeTree extends Composite {
 				Node n = (Node) e;
 				if (n.hasProperty(Node.PROP_DOC_RESOURCES)) {
 					if (selectedNodes.contains(n) && inclusionFilter.test(n, COLUMN_KEY_DOC)) {
-						cell.setText("Included");
+						cell.setText(Messages.NodeTree_Included);
 						cell.setForeground(includedColor);
 					} else {
-						cell.setText("Available");
+						cell.setText(Messages.NodeTree_Available);
 						cell.setForeground(availableColor);
 					}
 				} else {
-					cell.setText("-");
+					cell.setText(Messages.NodeTree_NoContent);
 					cell.setForeground(noContentColor);
 				}
 			}
@@ -654,4 +657,9 @@ public class NodeTree extends Composite {
 		}
 	}
 
+	private static String subtreeToggleTooltip(boolean hasFilter) {
+		return hasFilter
+				? Messages.NodeTree_SubtreeSelection_Tooltip_Filtered
+				: Messages.NodeTree_SubtreeSelection_Tooltip;
+	}
 }
\ No newline at end of file
diff --git a/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/pdf/messages.properties b/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/pdf/messages.properties
index a1e4cfc275bc0badd8020c213620bd2dce76686c..2005617e86825dab14d81265325724a621ef75d7 100644
--- a/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/pdf/messages.properties
+++ b/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/pdf/messages.properties
@@ -1,3 +1,18 @@
+NodeTree_Available=Available
+NodeTree_Collapse_Text=&Collapse
+NodeTree_Collapse_Tooltip=Collapse Selected Nodes or All Nodes
+NodeTree_Column_Diagram=Diagram
+NodeTree_Column_Documentation=Documentation
+NodeTree_Column_Item=Item
+NodeTree_Expand_Text=&Expand
+NodeTree_Expand_Tooltip=Fully Expand Selected Nodes or All Nodes
+NodeTree_Filter=Fi&lter:
+NodeTree_Included=Included
+NodeTree_NoContent=-
+NodeTree_SubtreeSelection_Text=Sub&tree Selection
+NodeTree_SubtreeSelection_Tooltip=Enable/Disable Selection of Subtree on Checkbox Click
+NodeTree_SubtreeSelection_Tooltip_Filtered=Enable/Disable Filtered Selection of Subtree on Checkbox Click
+NodeTree_Tooltip=Selects the items to include in the exported document.
 PDFExportPage_AddPageNumbers=Add page &numbers
 PDFExportPage_BrowseButtonText=Browse...
 PDFExportPage_Error_TargetAlreadyExists_IsDir=The target already exists and it is a directory.