aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDirk Fauth2013-08-08 03:13:21 (EDT)
committerDirk Fauth2013-08-08 03:13:21 (EDT)
commit36859a7c0632ee7f904ee987aaa349a60a3f21ef (patch)
treeb8400ad0a4ed3457abe584a7181c4f0cd8836ad7
parentb8217f19aee8eb3c3ad45d7bfe70742c5145e629 (diff)
downloadorg.eclipse.nebula-36859a7c0632ee7f904ee987aaa349a60a3f21ef.zip
org.eclipse.nebula-36859a7c0632ee7f904ee987aaa349a60a3f21ef.tar.gz
org.eclipse.nebula-36859a7c0632ee7f904ee987aaa349a60a3f21ef.tar.bz2
Bug 414632 - Add the possibility to connect a GanttSection with data and
render section details instead or additional to the section bar.
-rw-r--r--widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/AbstractColorManager.java11
-rw-r--r--widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/AbstractLanguageManager.java4
-rw-r--r--widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/AbstractSettings.java28
-rw-r--r--widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/AdvancedTooltipDialog.java170
-rw-r--r--widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/GanttComposite.java522
-rw-r--r--widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/GanttSection.java19
-rw-r--r--widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/HorizontalScrollbarHandler.java8
-rw-r--r--widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/IColorManager.java25
-rw-r--r--widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/ILanguageManager.java8
-rw-r--r--widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/ISectionDetailContentReplacer.java16
-rw-r--r--widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/ISectionDetailMoreClickListener.java27
-rw-r--r--widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/ISettings.java65
-rw-r--r--widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/Utils.java26
-rw-r--r--widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/themes/ColorThemeGrayBlue.java13
-rw-r--r--widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/themes/ColorThemeHighContrastBlack.java13
-rw-r--r--widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/themes/ColorThemeSilver.java13
-rw-r--r--widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/themes/ColorThemeWindowsBlue.java13
-rw-r--r--widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/utils/TextPainterHelper.java238
18 files changed, 891 insertions, 328 deletions
diff --git a/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/AbstractColorManager.java b/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/AbstractColorManager.java
index fec6bea..0e4b4ba 100644
--- a/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/AbstractColorManager.java
+++ b/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/AbstractColorManager.java
@@ -334,4 +334,15 @@ public abstract class AbstractColorManager implements IColorManager {
return ColorCache.getColor(255, 0, 0);
}
+ public Color getSectionDetailAreaForegroundColor(GanttSection section) {
+ return getWeekdayBackgroundColorTop();
+ }
+
+ public Color getSectionDetailAreaBackgroundColor(GanttSection section) {
+ return getWeekdayBackgroundColorBottom();
+ }
+
+ public boolean drawSectionDetailGradientTopDown() {
+ return true;
+ }
}
diff --git a/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/AbstractLanguageManager.java b/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/AbstractLanguageManager.java
index 8360374..3c66024 100644
--- a/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/AbstractLanguageManager.java
+++ b/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/AbstractLanguageManager.java
@@ -95,4 +95,8 @@ public abstract class AbstractLanguageManager implements ILanguageManager {
public String getPrintPageText() {
return "Page";
}
+
+ public String getSectionDetailMoreText() {
+ return "More";
+ }
}
diff --git a/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/AbstractSettings.java b/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/AbstractSettings.java
index f3a9e8e..a038f4e 100644
--- a/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/AbstractSettings.java
+++ b/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/AbstractSettings.java
@@ -546,4 +546,32 @@ public abstract class AbstractSettings implements ISettings {
public boolean printFooter() {
return true;
}
+
+ public boolean drawSectionBar() {
+ return true;
+ }
+
+ public boolean drawSectionDetails() {
+ return false;
+ }
+
+ public int getSectionDetailWidth() {
+ return 100;
+ }
+
+ public String getSectionDetailTitle() {
+ return "\\b\\s8\\ce#name#";
+ }
+
+ public String getSectionDetailText() {
+ return "\\ceEvents: #ne#";
+ }
+
+ public ISectionDetailContentReplacer getSectionDetailContentReplacer() {
+ return null;
+ }
+
+ public boolean showSectionDetailMore() {
+ return false;
+ }
}
diff --git a/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/AdvancedTooltipDialog.java b/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/AdvancedTooltipDialog.java
index 14b976f..f30754a 100644
--- a/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/AdvancedTooltipDialog.java
+++ b/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/AdvancedTooltipDialog.java
@@ -12,13 +12,11 @@
package org.eclipse.nebula.widgets.ganttchart;
import java.util.StringTokenizer;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
+import org.eclipse.nebula.widgets.ganttchart.utils.TextPainterHelper;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;
-import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Image;
@@ -97,7 +95,7 @@ public class AdvancedTooltipDialog {
gc.setForeground(colorManager.getAdvancedTooltipTextColor());
gc.setFont(bold);
final Point point = gc.stringExtent(title);
- drawText(gc, title, x, y);
+ TextPainterHelper.drawText(gc, title, x, y);
// gc.drawString(title, x, y, true);
gc.setFont(old);
@@ -144,12 +142,12 @@ public class AdvancedTooltipDialog {
// first we space it vertically
textY += 13;
- final StringTokenizer tokenizer = new StringTokenizer(content, "\n");
+ final StringTokenizer tokenizer = new StringTokenizer(content, "\n"); //$NON-NLS-1$
int widestLine = 0;
while (tokenizer.hasMoreTokens()) {
final String token = tokenizer.nextToken();
- final Point extent = drawText(gc, token, x, textY);
+ final Point extent = TextPainterHelper.drawText(gc, token, x, textY);
textY += extent.y;
widestLine = Math.max(widestLine, extent.x);
}
@@ -331,166 +329,6 @@ public class AdvancedTooltipDialog {
}
- private static Point drawText(final GC gc, final String text, final int x, final int y) {
- Pattern pattern = Pattern.compile("(\\\\(ce|c[0-9]{9}|s[0-9]{1,3}|[xbi]))*[^\\\\]*");
-
- try {
- final Font old = gc.getFont();
- Font used = null;
- final String oldName = old.getFontData()[0].getName();
- final int oldSize = (int) old.getFontData()[0].height;
-
- int curX = x;
- boolean bold = false;
- boolean italic = false;
- int size = oldSize;
- Color fg = ColorCache.getBlack();
-
- int maxWidth = 0;
- int maxHeight = 0;
-
- Matcher matcher = pattern.matcher(text);
-
- while (matcher.find()) {
- String token = matcher.group();
-
- if (isNormalize(token)) {
- bold = false;
- italic = false;
- size = oldSize;
- fg = ColorCache.getBlack();
- }
- else {
- final int newSize = getSize(token);
- if (newSize != size && newSize != -1) {
- size = newSize;
- }
-
- final boolean newBold = isBold(token);
- if (bold && !newBold) {
- bold = true;
- }
- else {
- bold = newBold;
- }
-
- final boolean newItalic = isItalic(token);
- if (italic && !newItalic) {
- italic = true;
- }
- else {
- italic = newItalic;
- }
-
- final Color newColor = getColor(token);
- if (newColor != null && !newColor.equals(fg)) {
- fg = newColor;
- }
- }
-
- if (fg != null) {
- gc.setForeground(fg);
- }
-
- token = cleanUp(token);
-
- int style = SWT.NORMAL;
- if (bold) {
- style |= SWT.BOLD;
- }
- if (italic) {
- style |= SWT.ITALIC;
- }
-
- used = new Font(Display.getDefault(), oldName, size, style); // NOPMD
- gc.setFont(used);
-
- if (token.length() != 0) {
- gc.drawText(token, curX, y, true);
- final int extX = gc.textExtent(token).x;
- final int extY = gc.textExtent(token).y;
- curX += extX;
-
- maxWidth = Math.max(maxWidth, curX);
- maxHeight = Math.max(maxHeight, extY);
- }
-
- used.dispose();
- }
-
- gc.setFont(old);
- return new Point(maxWidth - x, maxHeight);
- }
- catch (Exception err) {
- SWT.error(SWT.ERROR_UNSPECIFIED, err);
- }
-
- return null;
- }
-
- private static String cleanUp(final String string) {
- String str = string;
- str = str.replaceAll("\\\\ce", "");
- str = str.replaceAll("\\\\c[0-9]{9}", "");
- str = str.replaceAll("\\\\s[0-9]{1,3}", "");
- str = str.replaceAll("\\\\x", "");
- str = str.replaceAll("\\\\b", "");
- str = str.replaceAll("\\\\i", "");
- return str;
- }
-
- private static boolean isNormalize(final String str) {
- return str.indexOf("\\x") > -1;
- }
-
- private static boolean isBold(final String str) {
- return str.indexOf("\\b") > -1;
- }
-
- private static boolean isItalic(final String str) {
- return str.indexOf("\\i") > -1;
- }
-
- private static int getSize(final String str) {
- Pattern pattern = Pattern.compile("\\\\s[0-9]{1,3}");
- Matcher matcher = pattern.matcher(str);
- if (matcher.find()) {
- String sizeString = matcher.group();
- sizeString = sizeString.substring(2);
-
- try {
- return Integer.parseInt(sizeString);
- } catch (Exception badParse) {
- SWT.error(SWT.ERROR_UNSPECIFIED, badParse);
- }
- }
-
- return -1;
- }
-
- private static Color getColor(final String str) {
- final int start = str.indexOf("\\c");
- if (start == -1) {
- return null;
- }
-
- if (str.indexOf("\\ce") != -1) {
- return ColorCache.getBlack();
- }
-
- try {
- final int red = Integer.parseInt(str.substring(start + 2, start + 5));
- final int green = Integer.parseInt(str.substring(start + 5, start + 8));
- final int blue = Integer.parseInt(str.substring(start + 8, start + 11));
-
- return ColorCache.getColor(red, green, blue);
- } catch (Exception err) {
- SWT.error(SWT.ERROR_UNSPECIFIED, err);
- }
-
- return ColorCache.getBlack();
- }
-
public static void kill() {
if (_shell != null && !_shell.isDisposed()) {
_shell.dispose();
diff --git a/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/GanttComposite.java b/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/GanttComposite.java
index dda24d6..d7db698 100644
--- a/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/GanttComposite.java
+++ b/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/GanttComposite.java
@@ -23,12 +23,14 @@ import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
+import java.util.StringTokenizer;
import org.eclipse.nebula.widgets.ganttchart.dnd.VerticalDragDropManager;
import org.eclipse.nebula.widgets.ganttchart.undoredo.GanttUndoRedoManager;
import org.eclipse.nebula.widgets.ganttchart.undoredo.commands.ClusteredCommand;
import org.eclipse.nebula.widgets.ganttchart.undoredo.commands.EventMoveCommand;
import org.eclipse.nebula.widgets.ganttchart.undoredo.commands.IUndoRedoCommand;
+import org.eclipse.nebula.widgets.ganttchart.utils.TextPainterHelper;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.KeyListener;
@@ -335,6 +337,10 @@ public final class GanttComposite extends Canvas implements MouseListener, Mouse
private IZoomHandler zoomHandler;
+ private Map sectionDetailMoreIcons = null;
+
+ private List sectionDetailMoreClickListener = new ArrayList();
+
static {
final String osProperty = System.getProperty("os.name");
if (osProperty != null) {
@@ -448,6 +454,11 @@ public final class GanttComposite extends Canvas implements MouseListener, Mouse
this.holidays = holidays;
this.zoomHandler = this;
+
+ if (_settings.showSectionDetailMore()) {
+ this.sectionDetailMoreIcons = new HashMap();
+ }
+
}
// midnight "thread" (we need to redraw the screen once at Midnight as the date line will otherwise be incorrect)
@@ -1103,10 +1114,17 @@ public final class GanttComposite extends Canvas implements MouseListener, Mouse
// if we use sections, our bounds for everything will be the size of the client area minus the section bar on the left
if (drawSections) {
+ int sectionWidth = 0;
+ if (_settings.drawSectionBar()) {
+ sectionWidth += _settings.getSectionBarWidth();
+ }
+ if (_settings.drawSectionDetails()) {
+ sectionWidth += _settings.getSectionDetailWidth();
+ }
if (_settings.getSectionSide() == SWT.LEFT) {
- bounds = new Rectangle(_settings.getSectionBarWidth(), bounds.y, bounds.width - _settings.getSectionBarWidth(), bounds.height);
+ bounds = new Rectangle(sectionWidth, bounds.y, bounds.width - sectionWidth, bounds.height);
} else {
- bounds = new Rectangle(0, bounds.y, bounds.width - _settings.getSectionBarWidth(), bounds.height);
+ bounds = new Rectangle(0, bounds.y, bounds.width - sectionWidth, bounds.height);
}
}
@@ -1150,7 +1168,7 @@ public final class GanttComposite extends Canvas implements MouseListener, Mouse
else {
//draw the background for the bottom of the gantt chart as on Win7 it would be transparent
final int dayWidth = (_currentView == ISettings.VIEW_WEEK || _currentView == ISettings.VIEW_D_DAY ? _dayWidth : _monthDayWidth);
- final int maxX = bounds.width + dayWidth; // we need to draw beyond 1 day as the days at the edge of the viewport also needs to be filled in case a half-day is visible there
+ int maxX = bounds.width + dayWidth; // we need to draw beyond 1 day as the days at the edge of the viewport also needs to be filled in case a half-day is visible there
int startX = bounds.x;
int offset = _vScrollPos;
@@ -1158,6 +1176,17 @@ public final class GanttComposite extends Canvas implements MouseListener, Mouse
offset = getHeaderHeight();
}
+ if (hasGanttSections()) {
+ if (_settings.drawSectionBar()) {
+ startX -= _settings.getSectionBarWidth();
+ maxX += _settings.getSectionBarWidth();
+ }
+ if (_settings.drawSectionDetails()) {
+ startX -= _settings.getSectionDetailWidth();
+ maxX += _settings.getSectionDetailWidth();
+ }
+ }
+
final int startY = bounds.y - offset;
final int heightY = bounds.height;
@@ -1757,7 +1786,11 @@ public final class GanttComposite extends Canvas implements MouseListener, Mouse
Point extent = null;
if (gs.needsNameUpdate() || gs.getNameExtent() == null) {
- extent = gc.textExtent(gs.getName(), SWT.DRAW_DELIMITER);
+ if (_settings.drawSectionBar()) {
+ extent = gc.textExtent(gs.getName(), SWT.DRAW_DELIMITER);
+ } else {
+ extent = new Point(0, 0);
+ }
gs.setNameExtent(extent);
gs.setNeedsNameUpdate(false);
} else {
@@ -1768,6 +1801,7 @@ public final class GanttComposite extends Canvas implements MouseListener, Mouse
if (gs.getTextOrientation() == SWT.HORIZONTAL) {
strHeight = extent.y;
}
+
final int gsHeight = gs.getEventsHeight(_settings);
int height = Math.max(gsHeight, strHeight);
@@ -1991,8 +2025,8 @@ public final class GanttComposite extends Canvas implements MouseListener, Mouse
// drawing in the middle, also speeds it up as we only draw it once
if (_savingChartImage && rightSide && !force) { return; }
- int xMax = _settings.getSectionBarWidth() - 1;
-
+ int barWidth = _settings.drawSectionBar() ? _settings.getSectionBarWidth() - 1 : 3;
+
final int horiSpacer = 3;
// calculate max width if any section is horizontal
@@ -2001,38 +2035,62 @@ public final class GanttComposite extends Canvas implements MouseListener, Mouse
if (gs.getTextOrientation() == SWT.HORIZONTAL) {
Point p = null;
if (gs.needsNameUpdate() || gs.getNameExtent() == null) {
- p = gc.textExtent(gs.getName(), SWT.DRAW_DELIMITER);
+ if (_settings.drawSectionBar()) {
+ p = gc.textExtent(gs.getName(), SWT.DRAW_DELIMITER);
+ } else {
+ p = new Point(0, 0);
+ }
gs.setNameExtent(p);
gs.setNeedsNameUpdate(false);
} else {
p = gs.getNameExtent();
}
- xMax = Math.max(xMax, p.x + (horiSpacer * 2));
+ barWidth = Math.max(barWidth, p.x + (horiSpacer * 2));
}
}
- int lineLoc = getHeaderHeight() == 0 ? bounds.y : (bounds.y + getHeaderHeight());
+ int xMax = barWidth;
+
+ if (_settings.drawSectionDetails() && rightSide) {
+ xMax += _settings.getSectionDetailWidth();
+ }
+
+ int lineLoc = getHeaderHeight() == 0 ? bounds.y : (bounds.y + getHeaderHeight()) -1;
int yStart = lineLoc;
yStart -= _vScrollPos;
- int x = 0;
+ int sectionBarX = 0;
if (rightSide) {
if (forceUsageOfBounds) {
- x = bounds.width - xMax;
+ sectionBarX = bounds.width - xMax;
} else {
- x = super.getClientArea().width - xMax;
+ sectionBarX = super.getClientArea().width - xMax;
}
} else {
- x = 0;
+ sectionBarX = 0;
}
int neg = 0;
if (rightSide) {
- neg = -_settings.getSectionBarWidth();
+ neg = -xMax;
}
+ //take space for section details into account
+ int sectionDetailX = 0;
+ if (_settings.drawSectionDetails()) {
+ if (rightSide) {
+ sectionDetailX = sectionBarX + _settings.getSectionBarWidth();
+ }
+ else {
+ sectionDetailX = sectionBarX;
+ sectionBarX += _settings.getSectionDetailWidth();
+ }
+ }
+
+ int sectionStartXPos = (rightSide ? sectionBarX : sectionDetailX) - 1;
+
final GanttSection bottomSection = (GanttSection) _ganttSections.get(_ganttSections.size() - 1);
if (drawCornerOnly) {
@@ -2044,17 +2102,18 @@ public final class GanttComposite extends Canvas implements MouseListener, Mouse
gc.setBackground(_colorManager.getNonActiveSessionBarColorRight());
int bottomPos = _settings.drawGanttSectionBarToBottom() ? _mainBounds.y + _mainBounds.height : lineLoc;
+
// if we're only drawing a corner, do not draw to the bottom regardless of settings or we'll paint over the text and section markers etc.
// this fix to bugzilla #304804 - Thanks Wim!
if (drawCornerOnly) {
bottomPos = getHeaderHeight();//lineLoc - _vScrollPos;
}
-
- gc.fillGradientRectangle(x, 0, xMax + 1, bottomPos, false);
+
+ gc.fillGradientRectangle(sectionStartXPos, 0, xMax + 1 + sectionBarX, bottomPos, false);
gc.setForeground(_colorManager.getTopHorizontalLinesColor());
// vertical
- gc.drawLine(x + xMax + neg, 0, x + xMax + neg, bottomSection.getBounds().y + bottomSection.getBounds().height - 1);
+ gc.drawLine(sectionBarX + xMax + neg, 0, sectionBarX + xMax + neg, bottomSection.getBounds().y + bottomSection.getBounds().height - 1);
if (!drawCornerOnly) {
@@ -2065,32 +2124,45 @@ public final class GanttComposite extends Canvas implements MouseListener, Mouse
gc.setForeground(_colorManager.getActiveSessionBarColorLeft());
gc.setBackground(_colorManager.getActiveSessionBarColorRight());
- gc.fillGradientRectangle(x, yStart, xMax, gsHeight, false);
+ gc.fillGradientRectangle(sectionBarX, yStart, xMax, gsHeight, false);
+
+ //draw section details
+ if (_settings.drawSectionDetails()) {
+ gc.setForeground(_colorManager.getSectionDetailAreaForegroundColor(gs));
+ gc.setBackground(_colorManager.getSectionDetailAreaBackgroundColor(gs));
+
+ gc.fillGradientRectangle(sectionDetailX, yStart, sectionDetailX + sectionBarX, gsHeight, _colorManager.drawSectionDetailGradientTopDown());
+
+ drawSectionDetails(gc, sectionDetailX, yStart, gs);
+ }
+
gc.setForeground(_textColor);
+ int xStart = (barWidth / 2);
+
+ Point extent = null;
+ if (gs.needsNameUpdate() || gs.getNameExtent() == null) {
+ extent = gc.textExtent(gs.getName(), SWT.DRAW_DELIMITER);
+ gs.setNameExtent(extent);
+ gs.setNeedsNameUpdate(false);
+ } else {
+ extent = gs.getNameExtent();
+ }
+
+ // zero length name causes exceptions, set it to 1
+ if (extent.x == 0) {
+ extent.x = 1;
+ }
+
if (gs.getTextOrientation() == SWT.VERTICAL) {
// draw vertical text (I tried using Transform.rotate stuff here earlier, but it's so incredibly slow that we can't use it)
// and not only that, but the kerning on vertical text is completely whacked with letter overlapping, so right now it's unusable
Image image = null;
- int xStart = (xMax / 2);
// only create the images if we don't have one from before, or if the name has changed since last time
if (gs.getNameImage() == null || gs.needsNameUpdate()) {
- Point extent = null;
- if (gs.needsNameUpdate() || gs.getNameExtent() == null) {
- extent = gc.textExtent(gs.getName(), SWT.DRAW_DELIMITER);
- gs.setNameExtent(extent);
- gs.setNeedsNameUpdate(false);
- } else {
- extent = gs.getNameExtent();
- }
-
- // zero length name causes exceptions, set it to 1
- if (extent.x == 0) {
- extent.x = 1;
- }
Image textImage = new Image(getDisplay(), extent.x, xMax - 2);
GC gcTemp = new GC(textImage);
@@ -2116,12 +2188,13 @@ public final class GanttComposite extends Canvas implements MouseListener, Mouse
xStart -= (image.getBounds().width / 2) - 2;
final int textLocY = (gsHeight / 2) - (image.getBounds().height / 2);
- gc.drawImage(image, x + xStart - 1, yStart + textLocY);
+ gc.drawImage(image, sectionBarX + xStart - 1, yStart + textLocY);
} else if (gs.getTextOrientation() == SWT.HORIZONTAL) {
- gc.drawText(gs.getName(), horiSpacer, yStart + (gsHeight / 2) - (gs.getNameExtent().y / 2), true);
+ xStart -= (extent.x / 2);
+ gc.drawText(gs.getName(), sectionBarX + xStart, yStart + (gsHeight / 2) - (gs.getNameExtent().y / 2), true);
}
- yStart += gsHeight - 1;
+ yStart += gsHeight-1;
int width = bounds.x + bounds.width;
if (rightSide && !forceUsageOfBounds) {
@@ -2132,8 +2205,6 @@ public final class GanttComposite extends Canvas implements MouseListener, Mouse
if (!columnOnly) {
gc.setForeground(_colorManager.getTopHorizontalLinesColor());
- //System.out.println(bounds + " " + width);
-
if (i != _ganttSections.size() - 1 && _settings.getSectionBarDividerHeight() != 0) {
gc.setForeground(_colorManager.getSessionBarDividerColorLeft());
gc.setBackground(_colorManager.getSessionBarDividerColorRight());
@@ -2145,6 +2216,7 @@ public final class GanttComposite extends Canvas implements MouseListener, Mouse
gc.drawLine(0, yStart - 1, width, yStart - 1);
} else {
// the last line
+ yStart += 1;
gc.drawLine(0, yStart, width, yStart);
yStart += _settings.getSectionBarDividerHeight();
}
@@ -2156,13 +2228,79 @@ public final class GanttComposite extends Canvas implements MouseListener, Mouse
gc.setForeground(_colorManager.getTopHorizontalLinesColor());
// horizontal
if (_settings.drawHeader()) {
- gc.drawLine(x, bounds.y, x + xMax, bounds.y);
+ gc.drawLine(sectionStartXPos, bounds.y, sectionBarX + xMax, bounds.y);
}
- gc.drawLine(x, lineLoc - _vScrollPos, x + xMax, lineLoc - _vScrollPos);
+ gc.drawLine(sectionStartXPos, lineLoc - _vScrollPos, sectionBarX + xMax, lineLoc - _vScrollPos);
}
+
+ private void drawSectionDetails(GC gc, int x, int y, GanttSection section) {
+ String title = _settings.getSectionDetailTitle();
+ String content = _settings.getSectionDetailText();
+
+ ISectionDetailContentReplacer sdcr = _settings.getSectionDetailContentReplacer();
+ if (sdcr != null) {
+ title = sdcr.replaceSectionDetailPlaceHolder(section, title) ;
+ content = sdcr.replaceSectionDetailPlaceHolder(section, content);
+ }
+ else {
+ title = title != null ? title.replaceAll("#name#", section.getName()) : "";
+ if (content != null) {
+ content = content.replaceAll("#name#", section.getName());
+ content = content.replaceAll("#ne#", "" + section.getEvents().size());
+ }
+ }
+
+ int xPos = x + 4;
+ int yPos = y + 2;
+ Point titleEndPos = new Point(xPos, yPos);
+ if (title != null && title.length() > 0) {
+ titleEndPos = TextPainterHelper.drawText(gc, title, xPos, yPos);
+ }
+
+ if (content != null && content.length() > 0) {
+ // first we space it vertically
+ xPos += 8;
+
+ yPos += titleEndPos.y * 1.5;
+
+ final StringTokenizer tokenizer = new StringTokenizer(content, "\n"); //$NON-NLS-1$
+
+ while (tokenizer.hasMoreTokens()) {
+ final String token = tokenizer.nextToken();
+ final Point extent = TextPainterHelper.drawText(gc, token, xPos, yPos);
+ yPos += extent.y;
+ }
+ }
+
+ if (_settings.showSectionDetailMore() && section.getData() != null) {
+ Point moreExtent = gc.textExtent(_languageManager.getSectionDetailMoreText());
+ yPos += moreExtent.y * 0.3;
+ gc.drawText(_languageManager.getSectionDetailMoreText(), xPos, yPos, true);
+
+ Rectangle plusRectangle = new Rectangle(
+ xPos + moreExtent.x + 8,
+ yPos + (moreExtent.y / 2) - 3,
+ 8, 8);
+
+ this.sectionDetailMoreIcons.put(section, plusRectangle);
+ gc.drawRectangle(plusRectangle);
+ gc.drawLine(
+ plusRectangle.x + 4,
+ plusRectangle.y + 2,
+ plusRectangle.x + 4,
+ plusRectangle.y + 6);
+ gc.drawLine(
+ plusRectangle.x + 2,
+ plusRectangle.y + 4,
+ plusRectangle.x + 6,
+ plusRectangle.y + 4);
+
+ }
+ }
+
private void drawHorizontalLines(final GC gc, final Rectangle bounds) {
gc.setForeground(_lineColor);
@@ -2989,7 +3127,14 @@ public final class GanttComposite extends Canvas implements MouseListener, Mouse
int extra = 0;
if (!_ganttSections.isEmpty() && _settings.getSectionSide() == SWT.LEFT) {
- extra += _settings.getSectionBarWidth();
+ int sectionWidth = 0;
+ if (_settings.drawSectionBar()) {
+ sectionWidth += _settings.getSectionBarWidth();
+ }
+ if (_settings.drawSectionDetails()) {
+ sectionWidth += _settings.getSectionDetailWidth();
+ }
+ extra += sectionWidth;
}
yHeight -= offset;
@@ -3027,7 +3172,14 @@ public final class GanttComposite extends Canvas implements MouseListener, Mouse
int extra = 0;
if (!_ganttSections.isEmpty() && _settings.getSectionSide() == SWT.LEFT) {
- extra += _settings.getSectionBarWidth();
+ int sectionWidth = 0;
+ if (_settings.drawSectionBar()) {
+ sectionWidth += _settings.getSectionBarWidth();
+ }
+ if (_settings.drawSectionDetails()) {
+ sectionWidth += _settings.getSectionDetailWidth();
+ }
+ extra += sectionWidth;
}
int offset = 0;
@@ -3341,7 +3493,8 @@ public final class GanttComposite extends Canvas implements MouseListener, Mouse
// still calculate name extent, we need it to determine correct scrollbars for fixed scrollbars among other things
if (ge.getNameExtent() == null || ge.isNameChanged()) {
final String toDraw = getStringForEvent(ge);
- ge.setNameExtent(gc.stringExtent(toDraw));
+// ge.setNameExtent(gc.stringExtent(toDraw));
+ ge.setNameExtent(gc.textExtent(toDraw));
ge.setParsedString(toDraw);
ge.setNameChanged(false);
}
@@ -3424,7 +3577,8 @@ public final class GanttComposite extends Canvas implements MouseListener, Mouse
// if the name has changed, update various cached variables
if (ge.isNameChanged()) {
final String toDraw = getStringForEvent(ge);
- ge.setNameExtent(gc.stringExtent(toDraw));
+// ge.setNameExtent(gc.stringExtent(toDraw));
+ ge.setNameExtent(gc.textExtent(toDraw));
ge.setParsedString(toDraw);
ge.setNameChanged(false);
}
@@ -6003,6 +6157,18 @@ public final class GanttComposite extends Canvas implements MouseListener, Mouse
}
}
+ if (this.sectionDetailMoreIcons != null) {
+ for (Iterator it = this.sectionDetailMoreIcons.entrySet().iterator(); it.hasNext(); ) {
+ Map.Entry entry = (Map.Entry) it.next();
+ if (isInside(event.x, event.y, (Rectangle)entry.getValue())) {
+ for (Iterator listenerIt = this.sectionDetailMoreClickListener.iterator(); listenerIt.hasNext(); ) {
+ ISectionDetailMoreClickListener listener = (ISectionDetailMoreClickListener) listenerIt.next();
+ listener.openAdvancedDetails((GanttSection)entry.getKey());
+ }
+ }
+ }
+ }
+
if (needsRedraw) {
redraw();
}
@@ -6614,69 +6780,71 @@ public final class GanttComposite extends Canvas implements MouseListener, Mouse
final int x = me.x;
final int y = me.y;
- // check if cursor is inside the area of an event
- for (int i = 0; i < _ganttEvents.size(); i++) {
- final GanttEvent event = (GanttEvent) _ganttEvents.get(i);
- if (isInside(me.x, me.y, new Rectangle(event.getX(), event.getY(), event.getWidth(), event.getHeight()))) {
- insideAnyEvent = true;
-
- if (event.isScope()) {
- continue;
- }
-
- if (_hiddenLayers.contains(event.getLayerInt())) {
- continue;
- }
-
- final Rectangle rect = new Rectangle(event.getX(), event.getY(), event.getWidth(), event.getHeight());
-
- boolean onRightBorder = false;
- boolean onLeftBorder = false;
-
- // n pixels left or right of either border = show resize
- // mouse cursor
- if (x >= (rect.x + rect.width - _settings.getResizeBorderSensitivity()) && y >= rect.y && x <= (rect.x + rect.width + _settings.getResizeBorderSensitivity()) && y <= (rect.y + rect.height)) {
- onRightBorder = true;
- } else if (x >= (rect.x - _settings.getResizeBorderSensitivity()) && y >= rect.y && x <= (rect.x + _settings.getResizeBorderSensitivity()) && y <= (rect.y + rect.height)) {
- onLeftBorder = true;
- }
-
- // right border resize cursor (not images!)
- if (me.stateMask == 0 || me.stateMask == _settings.getDragAllModifierKey()) {
- if (resizeOK && event.isResizable()) {
- if ((event.isCheckpoint() && _settings.allowCheckpointResizing()) || !event.isCheckpoint() && !event.isImage()) {
- if (onRightBorder) {
- this.setCursor(Constants.CURSOR_SIZEE);
- _cursor = SWT.CURSOR_SIZEE;
- return;
- } else if (onLeftBorder) {
- this.setCursor(Constants.CURSOR_SIZEW);
- _cursor = SWT.CURSOR_SIZEW;
- return;
- }
- }
- }
-
- // move cursor
- if (dndOK && event.isMoveable()) {
- this.setCursor(Constants.CURSOR_SIZEALL);
- _cursor = SWT.CURSOR_SIZEALL;
- return;
- }
- } else {
- if ((dndOK || event.isMoveable()) && _cursor == SWT.CURSOR_SIZEALL && isInMoveArea(event, me.x)) {
- handleMove(me, event, Constants.TYPE_MOVE, true);
- return;
- }
-
- if (!event.isCheckpoint() && (resizeOK || event.isResizable()) && (_cursor == SWT.CURSOR_SIZEE || _cursor == SWT.CURSOR_SIZEW)) {
- // handleResize(me, event, onLeftBorder);
- handleMove(me, event, onLeftBorder ? Constants.TYPE_RESIZE_LEFT : Constants.TYPE_RESIZE_RIGHT, true);
- return;
- }
- }
- break;
- }
+ if (_mainBounds == null || me.x >= _mainBounds.x) {
+ // check if cursor is inside the area of an event
+ for (int i = 0; i < _ganttEvents.size(); i++) {
+ final GanttEvent event = (GanttEvent) _ganttEvents.get(i);
+ if (isInside(me.x, me.y, new Rectangle(event.getX(), event.getY(), event.getWidth(), event.getHeight()))) {
+ insideAnyEvent = true;
+
+ if (event.isScope()) {
+ continue;
+ }
+
+ if (_hiddenLayers.contains(event.getLayerInt())) {
+ continue;
+ }
+
+ final Rectangle rect = new Rectangle(event.getX(), event.getY(), event.getWidth(), event.getHeight());
+
+ boolean onRightBorder = false;
+ boolean onLeftBorder = false;
+
+ // n pixels left or right of either border = show resize
+ // mouse cursor
+ if (x >= (rect.x + rect.width - _settings.getResizeBorderSensitivity()) && y >= rect.y && x <= (rect.x + rect.width + _settings.getResizeBorderSensitivity()) && y <= (rect.y + rect.height)) {
+ onRightBorder = true;
+ } else if (x >= (rect.x - _settings.getResizeBorderSensitivity()) && y >= rect.y && x <= (rect.x + _settings.getResizeBorderSensitivity()) && y <= (rect.y + rect.height)) {
+ onLeftBorder = true;
+ }
+
+ // right border resize cursor (not images!)
+ if (me.stateMask == 0 || me.stateMask == _settings.getDragAllModifierKey()) {
+ if (resizeOK && event.isResizable()) {
+ if ((event.isCheckpoint() && _settings.allowCheckpointResizing()) || !event.isCheckpoint() && !event.isImage()) {
+ if (onRightBorder) {
+ this.setCursor(Constants.CURSOR_SIZEE);
+ _cursor = SWT.CURSOR_SIZEE;
+ return;
+ } else if (onLeftBorder) {
+ this.setCursor(Constants.CURSOR_SIZEW);
+ _cursor = SWT.CURSOR_SIZEW;
+ return;
+ }
+ }
+ }
+
+ // move cursor
+ if (dndOK && event.isMoveable()) {
+ this.setCursor(Constants.CURSOR_SIZEALL);
+ _cursor = SWT.CURSOR_SIZEALL;
+ return;
+ }
+ } else {
+ if ((dndOK || event.isMoveable()) && _cursor == SWT.CURSOR_SIZEALL && isInMoveArea(event, me.x)) {
+ handleMove(me, event, Constants.TYPE_MOVE, true);
+ return;
+ }
+
+ if (!event.isCheckpoint() && (resizeOK || event.isResizable()) && (_cursor == SWT.CURSOR_SIZEE || _cursor == SWT.CURSOR_SIZEW)) {
+ // handleResize(me, event, onLeftBorder);
+ handleMove(me, event, onLeftBorder ? Constants.TYPE_RESIZE_LEFT : Constants.TYPE_RESIZE_RIGHT, true);
+ return;
+ }
+ }
+ break;
+ }
+ }
}
if (hasGanttPhases()) {
@@ -6741,8 +6909,20 @@ public final class GanttComposite extends Canvas implements MouseListener, Mouse
}
}
+ boolean isInsideSectionDetailMore = false;
+ if (this.sectionDetailMoreIcons != null) {
+ for (Iterator it = this.sectionDetailMoreIcons.values().iterator(); it.hasNext(); ) {
+ Rectangle rect = (Rectangle) it.next();
+ if (isInside(me.x, me.y, rect)) {
+ isInsideSectionDetailMore = true;
+ this.setCursor(Constants.CURSOR_HAND);
+ _cursor = SWT.CURSOR_HAND;
+ }
+ }
+ }
+
// clear mouse cursor if need be
- if (!insideAnyEvent && !_dragging && !_resizing && _cursor != SWT.NONE) {
+ if (!insideAnyEvent && !isInsideSectionDetailMore && !_dragging && !_resizing && _cursor != SWT.NONE) {
this.setCursor(Constants.CURSOR_NONE);
_cursor = SWT.NONE;
}
@@ -7342,7 +7522,14 @@ public final class GanttComposite extends Canvas implements MouseListener, Mouse
int xDrawStart = 0;
int xDrawEnd = _mainBounds.width;
if (hasGanttSections() && _settings.getSectionSide() == SWT.LEFT) {
- xDrawStart = _settings.getSectionBarWidth();
+ int sectionWidth = 0;
+ if (_settings.drawSectionBar()) {
+ sectionWidth += _settings.getSectionBarWidth();
+ }
+ if (_settings.drawSectionDetails()) {
+ sectionWidth += _settings.getSectionDetailWidth();
+ }
+ xDrawStart = sectionWidth;
xDrawEnd = _mainBounds.width + xDrawStart;
}
@@ -7826,12 +8013,14 @@ public final class GanttComposite extends Canvas implements MouseListener, Mouse
if (me.stateMask != 0) return;
- for (int i = 0; i < _ganttEvents.size(); i++) {
- GanttEvent event = (GanttEvent) _ganttEvents.get(i);
- if (isInside(me.x, me.y, new Rectangle(event.getX(), event.getY(), event.getWidth(), event.getHeight()))) {
- showTooltip(event, me);
- return;
- }
+ if (_mainBounds == null || me.x >= _mainBounds.x) {
+ for (int i = 0; i < _ganttEvents.size(); i++) {
+ GanttEvent event = (GanttEvent) _ganttEvents.get(i);
+ if (isInside(me.x, me.y, new Rectangle(event.getX(), event.getY(), event.getWidth(), event.getHeight()))) {
+ showTooltip(event, me);
+ return;
+ }
+ }
}
}
@@ -8055,6 +8244,18 @@ public final class GanttComposite extends Canvas implements MouseListener, Mouse
}
/**
+ * Returns the chart as an image with the visible horizontal area
+ * but showing all information in the chart vertically.
+ *
+ * @return Image of the chart
+ */
+ public Image getVerticallyFullImage() {
+ Rectangle verticallyFullBounds = new Rectangle(
+ _visibleBounds.x, 0, _visibleBounds.width, _bottomMostY);
+ return getImage(verticallyFullBounds);
+ }
+
+ /**
* Returns the image that is the entire chart, regardless of what is currently visible. If chart contains no events,
* {@link #getImage()} is called from within.
* <p>
@@ -8084,45 +8285,57 @@ public final class GanttComposite extends Canvas implements MouseListener, Mouse
if (geRight == null || geLeft == null) { return getImage(); }
- /*System.err.println();
-
- System.err.println("Now: " + mCalendar.getTime() + " " + getXForDate(mCalendar));
- System.err.println("Left bounds: " + geLeft.getActualBounds());*/
// set calendar to earliest date
final boolean drawSections = hasGanttSections();
int extraX = 0;
int extraW = 0;
if (drawSections) {
- if (_settings.getSectionSide() == SWT.LEFT) {
- extraX = -_settings.getSectionBarWidth();
- extraW = _settings.getSectionBarWidth();
- } else {
- extraW = _settings.getSectionBarWidth();
- }
-
+ if (_settings.drawSectionBar()) {
+ if (_settings.getSectionSide() == SWT.LEFT) {
+ extraX -= _settings.getSectionBarWidth();
+ }
+ extraW += _settings.getSectionBarWidth();
+ }
+ if (_settings.drawSectionDetails()) {
+ if (_settings.getSectionSide() == SWT.LEFT) {
+ extraX -= _settings.getSectionDetailWidth();
+ }
+ else {
+ extraW += _settings.getSectionDetailWidth()/2;
+ }
+ }
}
- _mainCalendar = getDateAt(geLeft.getActualBounds().x + extraX);//(Calendar) geLeft.getEarliestStartDate().clone();
- //mCalendar.add(Calendar.DATE, -(geLeft.getNameExtent().x + mSettings.getTextSpacerConnected() + getDayWidth()) / getDayWidth());
- //System.err.println("Post: " + mCalendar.getTime() + " Should be < " + geLeft.getEarliestStartDate().getTime());
- //System.err.println(" ---- " + geLeft.getEarliestStartX() + " " + geLeft.getActualBounds().x);
+ int leftBound = geLeft.getActualBounds().x;
+ if (_settings.getPeriodStart() != null) {
+ leftBound = Math.min(leftBound, getStartingXFor(_settings.getPeriodStart()));
+ }
+
+ //add spacing of 3 days to the left
+ int dw = getDayWidth();
+ extraX -= dw * 3;
+
+ _mainCalendar = getDateAt(leftBound + extraX);
- //fullBounds.x = geLeft.getActualBounds().x;
Rectangle rBounds = geRight.getActualBounds();
- //System.err.println(rBounds);
-
- // space it out 1 day
- if (drawSections && _settings.getSectionSide() == SWT.RIGHT) {
- extraW += getDayWidth();
+ int rightBound = rBounds.x + rBounds.width + extraW;
+ if (_settings.getPeriodEnd() != null) {
+ rightBound = Math.max(rightBound, getStartingXFor(_settings.getPeriodEnd()));
}
- fullBounds.width = rBounds.x + rBounds.width - geLeft.getActualBounds().x + extraW;
+ //the zoom level has impact on the start position of the gantt rendering
+ //therefore we need to take that into account
+ if (_currentView == ISettings.VIEW_YEAR) {
+ extraW += _mainCalendar.get(Calendar.DAY_OF_MONTH) * dw;
+ }
+
+ //add spacing of 3 days to the right
+ extraW += dw * 3;
+
+ fullBounds.width = rightBound - leftBound - extraX + extraW;
fullBounds.height = _bottomMostY;
- // System.err.println(fullBounds);
- // System.err.println(getRightMostPixel() + " " + getLeftMostPixel());
-
// set chart bounds to be the fake bounds
_mainBounds = fullBounds;
@@ -8167,17 +8380,6 @@ public final class GanttComposite extends Canvas implements MouseListener, Mouse
return null;
}
- /*private int getFullDrawSpan() {
- GanttEvent geRight = getEvent(false);
- GanttEvent geLeft = getEvent(true);
-
- if (geRight == null || geLeft == null) {
- return 0;
- }
-
- return geRight.getActualBounds().x + getRightMostPixel()
- }
- */
/**
* Returns the chart as an image for the given bounds.
*
@@ -8185,16 +8387,6 @@ public final class GanttComposite extends Canvas implements MouseListener, Mouse
* @return Image of chart
*/
public Image getImage(Rectangle bounds) {
- /* if (true) {
- Image full = getFullImage();
-
- Image buffer = new Image(getDisplay(), new Rectangle(0, 0, bounds.width, bounds.height));
- GC foo = new GC(buffer);
- foo.drawImage(full, bounds.x, bounds.y, bounds.width, bounds.height, 0, 0, bounds.width, bounds.height);
- foo.dispose();
- return buffer;
- }
- */
checkWidget();
setRedraw(false);
@@ -8225,7 +8417,7 @@ public final class GanttComposite extends Canvas implements MouseListener, Mouse
return null;
}
-
+
private List getEventsDependingOn(GanttEvent ge) {
if (_ganttConnections.isEmpty()) { return new ArrayList(); }
@@ -8763,4 +8955,12 @@ public final class GanttComposite extends Canvas implements MouseListener, Mouse
public void setZoomHandler(IZoomHandler zoomHandler) {
this.zoomHandler = zoomHandler;
}
+
+ public void addSelectionDetailClickListener(ISectionDetailMoreClickListener listener) {
+ this.sectionDetailMoreClickListener.add(listener);
+ }
+
+ public void removeSelectionDetailClickListener(ISectionDetailMoreClickListener listener) {
+ this.sectionDetailMoreClickListener.remove(listener);
+ }
}
diff --git a/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/GanttSection.java b/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/GanttSection.java
index e2e8f99..49ac95d 100644
--- a/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/GanttSection.java
+++ b/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/GanttSection.java
@@ -36,6 +36,7 @@ import org.eclipse.swt.graphics.Rectangle;
*/
public class GanttSection implements IFillBackgroundColors {
+ private Object _data;
private String _name;
private GanttComposite _parent;
private List _ganttEvents;
@@ -154,6 +155,24 @@ public class GanttSection implements IFillBackgroundColors {
}
/**
+ * Returns the currently set data object.
+ *
+ * @return Data object
+ */
+ public Object getData() {
+ return _data;
+ }
+
+ /**
+ * Sets the current data object.
+ *
+ * @param data Data object
+ */
+ public void setData(final Object data) {
+ this._data = data;
+ }
+
+ /**
* Sets the name of this section. This method does not force a redraw.
*
* @param name GanttSection name
diff --git a/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/HorizontalScrollbarHandler.java b/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/HorizontalScrollbarHandler.java
index e3b8936..7f3d8c4 100644
--- a/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/HorizontalScrollbarHandler.java
+++ b/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/HorizontalScrollbarHandler.java
@@ -191,7 +191,13 @@ class HorizontalScrollbarHandler implements Listener {
int rangeBonus = 0;
// take sections into account
- int gSectionWidth = _gc.getSettings().getSectionBarWidth();
+ int gSectionWidth = 0;
+ if (_gc.getSettings().drawSectionBar()) {
+ gSectionWidth += _gc.getSettings().getSectionBarWidth();
+ }
+ if (_gc.getSettings().drawSectionDetails()) {
+ gSectionWidth += _gc.getSettings().getSectionDetailWidth();
+ }
if (_gc.isShowingGanttSections()) {
if (_gc.getSettings().getSectionSide() == SWT.LEFT) {
xStart = gSectionWidth;
diff --git a/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/IColorManager.java b/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/IColorManager.java
index 8b3bd50..7a67ffd 100644
--- a/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/IColorManager.java
+++ b/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/IColorManager.java
@@ -500,4 +500,29 @@ public interface IColorManager extends IFillBackgroundColors {
*/
Color getPeriodLineColor();
+ /**
+ * The foreground color used to draw the gradient background of the section detail area
+ * of the given GanttSection. This way it is possible to implement highlighting in the
+ * detail area based on the set data value.
+ * @param section The GanttSection for which the foreground color is requested.
+ * @return Color
+ */
+ Color getSectionDetailAreaForegroundColor(GanttSection section);
+
+ /**
+ * The background color used to draw the gradient background of the section detail area
+ * of the given GanttSection. This way it is possible to implement highlighting in the
+ * detail area based on the set data value.
+ * @param section The GanttSection for which the background color is requested.
+ * @return Color
+ */
+ Color getSectionDetailAreaBackgroundColor(GanttSection section);
+
+ /**
+ * Specify the direction of the gradient background of the section detail area.
+ *
+ * @return <code>true</code> if the gradient should sweep from top to bottom,
+ * else sweeps from left to right
+ */
+ boolean drawSectionDetailGradientTopDown();
}
diff --git a/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/ILanguageManager.java b/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/ILanguageManager.java
index 1485130..f0a7af4 100644
--- a/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/ILanguageManager.java
+++ b/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/ILanguageManager.java
@@ -165,4 +165,12 @@ public interface ILanguageManager {
* @return Text
*/
String getPrintPageText();
+
+ /**
+ * The default text that gets rendered before the plus icon
+ * in the section detail area.
+ *
+ * @return Text
+ */
+ String getSectionDetailMoreText();
}
diff --git a/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/ISectionDetailContentReplacer.java b/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/ISectionDetailContentReplacer.java
new file mode 100644
index 0000000..f6c0ca7
--- /dev/null
+++ b/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/ISectionDetailContentReplacer.java
@@ -0,0 +1,16 @@
+/*******************************************************************************
+ * Copyright (c) 2013 Dirk Fauth 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:
+ * Dirk Fauth <dirk.fauth@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.nebula.widgets.ganttchart;
+
+public interface ISectionDetailContentReplacer {
+
+ String replaceSectionDetailPlaceHolder(GanttSection section, String sectionDetailPattern);
+}
diff --git a/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/ISectionDetailMoreClickListener.java b/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/ISectionDetailMoreClickListener.java
new file mode 100644
index 0000000..e34a29a
--- /dev/null
+++ b/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/ISectionDetailMoreClickListener.java
@@ -0,0 +1,27 @@
+/*******************************************************************************
+ * Copyright (c) 2013 Dirk Fauth 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:
+ * Dirk Fauth <dirk.fauth@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.nebula.widgets.ganttchart;
+
+/**
+ * This interface is used to implement a listener that gets informed when the plus
+ * icon in a section detail area is clicked to show more detail information.
+ * Usually it is intended to open a subdialog to show more detail information.
+ */
+public interface ISectionDetailMoreClickListener {
+
+ /**
+ * Make the advanced detail information of a GanttSection visible.
+ * Usually this should be done by opening a dialog that contains
+ * that information.
+ * @param section The section whos detail informations should be showed.
+ */
+ void openAdvancedDetails(GanttSection section);
+}
diff --git a/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/ISettings.java b/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/ISettings.java
index 80619af..137ebc9 100644
--- a/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/ISettings.java
+++ b/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/ISettings.java
@@ -1092,8 +1092,20 @@ public interface ISettings {
*/
public int getMinZoomLevel();
+ /**
+ * Specify a period start. Returning another value than <code>null</code> will result in rendering
+ * an additional line to the chart indicating a period start in the gantt itself.
+ *
+ * @return
+ */
public Calendar getPeriodStart();
+ /**
+ * Specify a period end. Returning another value than <code>null</code> will result in rendering
+ * an additional line to the chart indicating a period end in the gantt itself.
+ *
+ * @return
+ */
public Calendar getPeriodEnd();
/**
@@ -1153,4 +1165,57 @@ public interface ISettings {
* <code>false</code> if not
*/
public boolean printFooter();
+
+ /**
+ * Configure whether the section bar should be rendered. It only makes sense
+ * to not render the section bar if the section details are enabled.
+ *
+ * @return <code>true</code> if the section bar should
+ * be rendered, <code>false</code> if not
+ */
+ public boolean drawSectionBar();
+
+ /**
+ * Configure whether there should be an additional area to the section bar
+ * that shows additional section detail information.
+ *
+ * @return <code>true</code> if additional section detail information should
+ * be rendered, <code>false</code> if not
+ */
+ public boolean drawSectionDetails();
+
+ /**
+ * @return The width of the section detail area.
+ */
+ public int getSectionDetailWidth();
+
+ /**
+ * The section detail area title that should be rendered in the section detail area.
+ *
+ * @return String or null. Default is a bold black text showing the section name.
+ */
+ public String getSectionDetailTitle();
+
+ /**
+ * The detail information that should be rendered in the section detail area.
+ *
+ * @return String or null. Default is to show the number of events in that section.
+ */
+ public String getSectionDetailText();
+
+ /**
+ * Returns the custom section detail generator which generates the section detail
+ * out of custom data for a GanttSection.
+ *
+ * @return
+ */
+ public ISectionDetailContentReplacer getSectionDetailContentReplacer();
+
+ /**
+ *
+ * @return <code>true</code> if there should be a "more [+]" shown in the section
+ * detail area which allows to register a listener against to show more
+ * informations by e.g. opening a dialog.
+ */
+ public boolean showSectionDetailMore();
}
diff --git a/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/Utils.java b/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/Utils.java
index ad1d1f2..4cf044d 100644
--- a/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/Utils.java
+++ b/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/Utils.java
@@ -45,6 +45,32 @@ public class Utils {
}
/**
+ * Takes a font and gives it the typeface of the given style.
+ *
+ * @param font Font to modify
+ * @param style the new style for the given font (e.g. SWT.BOLD|SWT.ITALIC)
+ * @param size New font size
+ * @return Font with the given typeface and size
+ */
+ public static Font applyFontData(final Font font, int style, int size) {
+ if (font == null) {
+ return null;
+ }
+
+ final FontData[] fontDataArray = font.getFontData();
+ if (fontDataArray == null) {
+ return null;
+ }
+ for (int index = 0; index < fontDataArray.length; index++) {
+ final FontData fData = fontDataArray[index];
+ fData.setStyle(style);
+ fData.setHeight(size);
+ }
+
+ return new Font(Display.getDefault(), fontDataArray);
+ }
+
+ /**
* Applies a certain font size to a font.
*
* @param font Font to modify
diff --git a/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/themes/ColorThemeGrayBlue.java b/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/themes/ColorThemeGrayBlue.java
index b330593..83bc34c 100644
--- a/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/themes/ColorThemeGrayBlue.java
+++ b/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/themes/ColorThemeGrayBlue.java
@@ -12,6 +12,7 @@
package org.eclipse.nebula.widgets.ganttchart.themes;
import org.eclipse.nebula.widgets.ganttchart.ColorCache;
+import org.eclipse.nebula.widgets.ganttchart.GanttSection;
import org.eclipse.nebula.widgets.ganttchart.IColorManager;
import org.eclipse.swt.graphics.Color;
@@ -333,4 +334,16 @@ public class ColorThemeGrayBlue implements IColorManager {
return ColorCache.getColor(255, 0, 0);
}
+ public Color getSectionDetailAreaForegroundColor(GanttSection section) {
+ return getWeekdayBackgroundColorTop();
+ }
+
+ public Color getSectionDetailAreaBackgroundColor(GanttSection section) {
+ return getWeekdayBackgroundColorBottom();
+ }
+
+ public boolean drawSectionDetailGradientTopDown() {
+ return true;
+ }
+
}
diff --git a/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/themes/ColorThemeHighContrastBlack.java b/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/themes/ColorThemeHighContrastBlack.java
index 4f838f8..e1656b2 100644
--- a/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/themes/ColorThemeHighContrastBlack.java
+++ b/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/themes/ColorThemeHighContrastBlack.java
@@ -12,6 +12,7 @@
package org.eclipse.nebula.widgets.ganttchart.themes;
import org.eclipse.nebula.widgets.ganttchart.ColorCache;
+import org.eclipse.nebula.widgets.ganttchart.GanttSection;
import org.eclipse.nebula.widgets.ganttchart.IColorManager;
import org.eclipse.swt.graphics.Color;
@@ -333,4 +334,16 @@ public class ColorThemeHighContrastBlack implements IColorManager {
return ColorCache.getColor(255, 0, 0);
}
+ public Color getSectionDetailAreaForegroundColor(GanttSection section) {
+ return getWeekdayBackgroundColorTop();
+ }
+
+ public Color getSectionDetailAreaBackgroundColor(GanttSection section) {
+ return getWeekdayBackgroundColorBottom();
+ }
+
+ public boolean drawSectionDetailGradientTopDown() {
+ return true;
+ }
+
}
diff --git a/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/themes/ColorThemeSilver.java b/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/themes/ColorThemeSilver.java
index 529b035..13451ed 100644
--- a/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/themes/ColorThemeSilver.java
+++ b/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/themes/ColorThemeSilver.java
@@ -12,6 +12,7 @@
package org.eclipse.nebula.widgets.ganttchart.themes;
import org.eclipse.nebula.widgets.ganttchart.ColorCache;
+import org.eclipse.nebula.widgets.ganttchart.GanttSection;
import org.eclipse.nebula.widgets.ganttchart.IColorManager;
import org.eclipse.swt.graphics.Color;
@@ -333,4 +334,16 @@ public class ColorThemeSilver implements IColorManager {
return ColorCache.getColor(255, 0, 0);
}
+ public Color getSectionDetailAreaForegroundColor(GanttSection section) {
+ return getWeekdayBackgroundColorTop();
+ }
+
+ public Color getSectionDetailAreaBackgroundColor(GanttSection section) {
+ return getWeekdayBackgroundColorBottom();
+ }
+
+ public boolean drawSectionDetailGradientTopDown() {
+ return true;
+ }
+
}
diff --git a/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/themes/ColorThemeWindowsBlue.java b/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/themes/ColorThemeWindowsBlue.java
index a26d9f4..b815a0f 100644
--- a/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/themes/ColorThemeWindowsBlue.java
+++ b/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/themes/ColorThemeWindowsBlue.java
@@ -12,6 +12,7 @@
package org.eclipse.nebula.widgets.ganttchart.themes;
import org.eclipse.nebula.widgets.ganttchart.ColorCache;
+import org.eclipse.nebula.widgets.ganttchart.GanttSection;
import org.eclipse.nebula.widgets.ganttchart.IColorManager;
import org.eclipse.swt.graphics.Color;
@@ -336,4 +337,16 @@ public class ColorThemeWindowsBlue implements IColorManager {
return ColorCache.getColor(255, 0, 0);
}
+ public Color getSectionDetailAreaForegroundColor(GanttSection section) {
+ return getWeekdayBackgroundColorTop();
+ }
+
+ public Color getSectionDetailAreaBackgroundColor(GanttSection section) {
+ return getWeekdayBackgroundColorBottom();
+ }
+
+ public boolean drawSectionDetailGradientTopDown() {
+ return true;
+ }
+
}
diff --git a/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/utils/TextPainterHelper.java b/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/utils/TextPainterHelper.java
new file mode 100644
index 0000000..b1a167e
--- /dev/null
+++ b/widgets/ganttchart/org.eclipse.nebula.widgets.ganttchart/src/org/eclipse/nebula/widgets/ganttchart/utils/TextPainterHelper.java
@@ -0,0 +1,238 @@
+package org.eclipse.nebula.widgets.ganttchart.utils;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.eclipse.nebula.widgets.ganttchart.ColorCache;
+import org.eclipse.nebula.widgets.ganttchart.Utils;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.graphics.GC;
+import org.eclipse.swt.graphics.Point;
+
+/**
+ * Helper class to draw texts with markups within the GanttChart.
+ * Currently used for rendering tooltips and section details.
+ * Following markups are supported:
+ * <ul>
+ * <li>\\ce - render the following text in black</li>
+ * <li>\\c[0-9]{9} - render the following text in the specified rbg color (Note that there need to be nine digits)</li>
+ * <li>\\s[0-9]{1,3} - render the following text with the specified font size</li>
+ * <li>\\i - render the following text italic</li>
+ * <li>\\b - render the following text bold</li>
+ * <li>\\x - normalize, which means to reset the previous assigned markups and render with the default font and color</li>
+ * </ul>
+ */
+@SuppressWarnings("nls")
+public class TextPainterHelper {
+
+ /**
+ * Will draw the given text to the given GC. Before drawing the containing
+ * markups will be interpreted to apply color and font settings.
+ * @param gc The GC to draw the text to
+ * @param text The text to draw
+ * @param x The x coordinate where the text should be drawed to the GC
+ * @param y The y coordinate where the text should be drawed to the GC
+ * @return The end point of the drawed text.
+ */
+ public static Point drawText(final GC gc, final String text, final int x, final int y) {
+ Pattern pattern = Pattern.compile("(\\\\(ce|c[0-9]{9}|s[0-9]{1,3}|[xbi]))*[^\\\\]*");
+
+ try {
+ final Font old = gc.getFont();
+ final int oldSize = (int) old.getFontData()[0].height;
+
+ int curX = x;
+ boolean bold = false;
+ boolean italic = false;
+ int size = oldSize;
+ Color fg = ColorCache.getBlack();
+
+ int maxWidth = 0;
+ int maxHeight = 0;
+
+ Matcher matcher = pattern.matcher(text);
+
+ while (matcher.find()) {
+ String token = matcher.group();
+
+ if (isNormalize(token)) {
+ bold = false;
+ italic = false;
+ size = oldSize;
+ fg = ColorCache.getBlack();
+ }
+ else {
+ final int newSize = getSize(token);
+ if (newSize != size && newSize != -1) {
+ size = newSize;
+ }
+
+ final boolean newBold = isBold(token);
+ if (bold && !newBold) {
+ bold = true;
+ }
+ else {
+ bold = newBold;
+ }
+
+ final boolean newItalic = isItalic(token);
+ if (italic && !newItalic) {
+ italic = true;
+ }
+ else {
+ italic = newItalic;
+ }
+
+ final Color newColor = getColor(token);
+ if (newColor != null && !newColor.equals(fg)) {
+ fg = newColor;
+ }
+ }
+
+ if (fg != null) {
+ gc.setForeground(fg);
+ }
+
+ token = cleanUp(token);
+
+ int style = SWT.NORMAL;
+ if (bold) {
+ style |= SWT.BOLD;
+ }
+ if (italic) {
+ style |= SWT.ITALIC;
+ }
+
+ Font used = Utils.applyFontData(old, style, size);
+ gc.setFont(used);
+
+ if (token.length() != 0) {
+ gc.drawText(token, curX, y, true);
+ final int extX = gc.textExtent(token).x;
+ final int extY = gc.textExtent(token).y;
+ curX += extX;
+
+ maxWidth = Math.max(maxWidth, curX);
+ maxHeight = Math.max(maxHeight, extY);
+ }
+
+ used.dispose();
+ }
+
+ gc.setFont(old);
+ return new Point(maxWidth - x, maxHeight);
+ }
+ catch (Exception err) {
+ SWT.error(SWT.ERROR_UNSPECIFIED, err);
+ }
+
+ return null;
+ }
+
+ /**
+ * Removes all markups out of the given string. Needed to render
+ * after all markups have been resolved.
+ * @param string The string whose markups should be removed.
+ * @return The given string without any further markups.
+ */
+ public static String cleanUp(final String string) {
+ String str = string;
+ str = str.replaceAll("\\\\ce", "");
+ str = str.replaceAll("\\\\c[0-9]{9}", "");
+ str = str.replaceAll("\\\\s[0-9]{1,3}", "");
+ str = str.replaceAll("\\\\x", "");
+ str = str.replaceAll("\\\\b", "");
+ str = str.replaceAll("\\\\i", "");
+ return str;
+ }
+
+ /**
+ * Checks for the existence of the normalize markup.
+ * The normalize markup can be used to reset all former assigned
+ * markups for the following text to render.
+ * The normalize markup is \\x
+ * @param str The string to check for the normalize markup
+ * @return <code>true</code> if the given string contains the
+ * normalize markup
+ */
+ public static boolean isNormalize(final String str) {
+ return str.indexOf("\\x") > -1;
+ }
+
+ /**
+ * Checks for the existence of the bold markup.
+ * The bold markup is \\b
+ * @param str The string to check for the bold markup
+ * @return <code>true</code> if the given string contains the
+ * bold markup
+ */
+ public static boolean isBold(final String str) {
+ return str.indexOf("\\b") > -1;
+ }
+
+ /**
+ * Checks for the existence of the italic markup.
+ * The italic markup is \\i
+ * @param str The string to check for the italic markup
+ * @return <code>true</code> if the given string contains the
+ * italic markup
+ */
+ public static boolean isItalic(final String str) {
+ return str.indexOf("\\i") > -1;
+ }
+
+ /**
+ * Gets the font size out of a size markup in the given string.
+ * A size markup is specified \\s[0-9]{1,3}
+ * @param str The string containing the size markup
+ * @return The font size to use for rendering
+ */
+ public static int getSize(final String str) {
+ Pattern pattern = Pattern.compile("\\\\s[0-9]{1,3}");
+ Matcher matcher = pattern.matcher(str);
+ if (matcher.find()) {
+ String sizeString = matcher.group();
+ sizeString = sizeString.substring(2);
+
+ try {
+ return Integer.parseInt(sizeString);
+ } catch (Exception badParse) {
+ SWT.error(SWT.ERROR_UNSPECIFIED, badParse);
+ }
+ }
+
+ return -1;
+ }
+
+ /**
+ * Gets the color for a color markup in the given string.
+ * A color markup is either \\ce for black or \\c[0-9]{9}
+ * to specify a custom color by rgb code
+ * @param str The string containing a color markup
+ * @return The Color that is specified by the color markup
+ */
+ public static Color getColor(final String str) {
+ final int start = str.indexOf("\\c");
+ if (start == -1) {
+ return null;
+ }
+
+ if (str.indexOf("\\ce") != -1) {
+ return ColorCache.getBlack();
+ }
+
+ try {
+ final int red = Integer.parseInt(str.substring(start + 2, start + 5));
+ final int green = Integer.parseInt(str.substring(start + 5, start + 8));
+ final int blue = Integer.parseInt(str.substring(start + 8, start + 11));
+
+ return ColorCache.getColor(red, green, blue);
+ } catch (Exception err) {
+ SWT.error(SWT.ERROR_UNSPECIFIED, err);
+ }
+
+ return ColorCache.getBlack();
+ }
+}