Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.

Bug 322525

Summary: computeSize() wrong for DateTime with SWT.DATE style (Hebrew calendar)
Product: [Eclipse Project] Platform Reporter: Silenio Quarti <Silenio_Quarti>
Component: SWTAssignee: Carolyn MacLeod <carolynmacleod4>
Status: RESOLVED FIXED QA Contact:
Severity: normal    
Priority: P3 CC: eclipse.felipe, pwebster
Version: 3.6   
Target Milestone: 3.7 M4   
Hardware: PC   
OS: Windows 7   
Whiteboard:
Attachments:
Description Flags
snapshot of snippet
none
DateTime.java
none
snapshot of snippet output on Hebrew Vista
none
correct snapshot of snippet output on Hebrew Vista
none
Snapshot running on English Vista
none
patch so far
none
patch that works well on XP English
none
snapshot on XP English
none
snap of Hebrew Win7 DateTIme none

Description Silenio Quarti CLA 2010-08-12 09:17:34 EDT
1) Change the locale to Hebrew on Windows 7 (or Vista) and change to calendar type to Hebrew.
2) Run the ControlExample, select the DateTime tab and  check the SWT.DATE style.

Note that the preferred size of the widget is wrong.
Comment 1 Felipe Heidrich CLA 2010-08-12 14:59:19 EDT
FYI: I was able to reproduce the problem on XP too
Comment 2 Carolyn MacLeod CLA 2010-11-02 10:37:58 EDT
Created attachment 182210 [details]
snapshot of snippet

Snippet for testing, with a screen snap of the output on Win XP (English).

import org.eclipse.swt.*;
import org.eclipse.swt.widgets.*;
import org.eclipse.swt.layout.*;

public class DateTimeComputeSizeTest {
	
	public static void main(String[] args) {
		Display display = new Display();
		Shell shell = new Shell(display);
		shell.setLayout(new GridLayout());
		
		DateTime dateTime1 = new DateTime(shell, SWT.DATE);
		DateTime dateTime2 = new DateTime(shell, SWT.BORDER | SWT.DATE);

		DateTime dateTime3 = new DateTime(shell, SWT.TIME);
		DateTime dateTime4 = new DateTime(shell, SWT.BORDER | SWT.TIME);

		DateTime dateTime5 = new DateTime(shell, SWT.CALENDAR);
		DateTime dateTime6 = new DateTime(shell, SWT.BORDER | SWT.CALENDAR);

		Text text = new Text(shell, SWT.BORDER | SWT.MULTI);
		text.setLayoutData(new GridData(200, 100));
		
		shell.pack();
		shell.open();
		
		text.append(dateTime1.getSize() + "\n");
		text.append(dateTime2.getSize() + "\n");
		text.append(dateTime3.getSize() + "\n");
		text.append(dateTime4.getSize() + "\n");
		text.append(dateTime5.getSize() + "\n");
		text.append(dateTime6.getSize() + "\n");
		
		while (!shell.isDisposed()) {
			if (!display.readAndDispatch()) display.sleep();
		}
	}
}
Comment 3 Carolyn MacLeod CLA 2010-11-02 16:52:12 EDT
Created attachment 182255 [details]
DateTime.java

Hacked version of DateTime for testing.

Also, updated snippet:

import org.eclipse.swt.*;
import org.eclipse.swt.widgets.*;
import org.eclipse.swt.layout.*;

public class DateTimeComputeSizeTest {

    public static void main(String[] args) {
        Display display = new Display();
        Shell shell = new Shell(display);
        shell.setLayout(new GridLayout());

        DateTime dateTime1 = new DateTime(shell, SWT.DATE);
        DateTime dateTime2 = new DateTime(shell, SWT.DATE | SWT.SHORT);
        DateTime dateTime3 = new DateTime(shell, SWT.DATE | SWT.MEDIUM);
        DateTime dateTime4 = new DateTime(shell, SWT.DATE | SWT.LONG);
        DateTime dateTime5 = new DateTime(shell, SWT.DATE | SWT.DROP_DOWN);
        DateTime dateTime6 = new DateTime(shell, SWT.DATE | SWT.BORDER);

        DateTime dateTime7 = new DateTime(shell, SWT.TIME);
        DateTime dateTime8 = new DateTime(shell, SWT.TIME | SWT.SHORT);
        DateTime dateTime9 = new DateTime(shell, SWT.TIME | SWT.MEDIUM);
        DateTime dateTime10 = new DateTime(shell, SWT.TIME | SWT.LONG);
        DateTime dateTime11 = new DateTime(shell, SWT.TIME | SWT.BORDER);

        DateTime dateTime12 = new DateTime(shell, SWT.CALENDAR);
        DateTime dateTime13 = new DateTime(shell, SWT.CALENDAR | SWT.BORDER);

        Text text = new Text(shell, SWT.MULTI | SWT.BORDER);
        text.setLayoutData(new GridData(300, 300));

        shell.pack();
        shell.open();

        text.append(dateTime1.getSize() + " - DATE\n");
        text.append(dateTime2.getSize() + " - DATE | SHORT\n");
        text.append(dateTime3.getSize() + " - DATE | MEDIUM\n");
        text.append(dateTime4.getSize() + " - DATE | LONG\n");
        text.append(dateTime5.getSize() + " - DATE | DROP_DOWN\n");
        text.append(dateTime6.getSize() + " - DATE | BORDER\n\n");
        text.append(dateTime7.getSize() + " - TIME\n");
        text.append(dateTime8.getSize() + " - TIME | SHORT\n");
        text.append(dateTime9.getSize() + " - TIME | MEDIUM\n");
        text.append(dateTime10.getSize() + " - TIME | LONG\n");
        text.append(dateTime11.getSize() + " - TIME | BORDER\n\n");
        text.append(dateTime12.getSize() + " - CALENDAR\n");
        text.append(dateTime13.getSize() + " - CALENDAR | BORDER\n\n");

        while (!shell.isDisposed()) {
            if (!display.readAndDispatch()) display.sleep();
        }
    }
}
Comment 4 Felipe Heidrich CLA 2010-11-02 17:05:50 EDT
Also need these constants in OS:
public static final int DATE_AUTOLAYOUT = 0x00000040; //#if(WINVER >= 0x0700)
public static final int DTM_GETIDEALSIZE = DTM_FIRST + 15;
Comment 5 Felipe Heidrich CLA 2010-11-02 17:28:01 EDT
Created attachment 182259 [details]
snapshot of snippet output on Hebrew Vista

CM - The following version of DateTime computeSize tested on Hebrew Vista, with the attached output from the snippet. (Looks good).

public Point computeSize (int wHint, int hHint, boolean changed) {
	checkWidget ();
	int width = 0, height = 0;
	if (wHint == SWT.DEFAULT || hHint == SWT.DEFAULT) {
		if ((style & SWT.CALENDAR) != 0) {
			RECT rect = new RECT ();
			OS.SendMessage(handle, OS.MCM_GETMINREQRECT, 0, rect);
			width = rect.right;
			height = rect.bottom;
		} else {
			if (!OS.IsWinCE && OS.WIN32_VERSION >= OS.VERSION (6, 0)) {
				/* Vista and later: use DTM_GETIDEALSIZE. */
				SIZE size = new SIZE ();
				OS.SendMessage(handle, OS.DTM_GETIDEALSIZE, 0, size);
				width = size.cx;
				height = size.cy;
				System.out.println("DTM_GETIDEALSIZE = " + width + ", " + height);
			} else {
				int /*long*/ newFont, oldFont = 0;
				int /*long*/ hDC = OS.GetDC (handle);
				newFont = OS.SendMessage (handle, OS.WM_GETFONT, 0, 0);
				if (newFont != 0) oldFont = OS.SelectObject (hDC, newFont);
				RECT rect = new RECT ();
				if ((style & SWT.DATE) != 0) {
					int dwFlags = 0;
					TCHAR lpFormat = null;
					if (!OS.IsWinCE && OS.WIN32_VERSION >= OS.VERSION (7, 0)) dwFlags |= OS.DATE_AUTOLAYOUT;
					if ((style & SWT.SHORT) != 0) {
						lpFormat = new TCHAR (0, getCustomShortDateFormat(), true);
					} else {
						dwFlags = (style & SWT.MEDIUM) != 0 ? OS.DATE_SHORTDATE : OS.DATE_LONGDATE;
					}
					if (!OS.IsWinCE && OS.WIN32_MAJOR == 6) dwFlags = OS.DATE_YEARMONTH;
					int size = OS.GetDateFormat(OS.LOCALE_USER_DEFAULT, dwFlags, null, lpFormat, null, 0);
					if (size > 0) {
						TCHAR buffer = new TCHAR (getCodePage (), size);
						OS.GetDateFormat(OS.LOCALE_USER_DEFAULT, dwFlags, null, lpFormat, buffer, buffer.length ());
						System.out.println(buffer.toString());
						OS.DrawText (hDC, buffer, size, rect, OS.DT_CALCRECT | OS.DT_EDITCONTROL);
					}
				} else if ((style & SWT.TIME) != 0) {
					int dwFlags = 0;
					TCHAR lpFormat = null;
					if ((style & SWT.SHORT) != 0) {
						dwFlags = OS.TIME_NOSECONDS;
						//lpFormat = new TCHAR (0, getCustomShortTimeFormat(), true);
					}
					int size = OS.GetTimeFormat(OS.LOCALE_USER_DEFAULT, dwFlags, null, lpFormat, null, 0);
					if (size > 0) {
						TCHAR buffer = new TCHAR (getCodePage (), size);
						OS.GetTimeFormat(OS.LOCALE_USER_DEFAULT, dwFlags, null, lpFormat, buffer, buffer.length ());
						System.out.println(buffer.toString());
						OS.DrawText (hDC, buffer, size, rect, OS.DT_CALCRECT | OS.DT_EDITCONTROL);
					}
				}
				width = rect.right - rect.left;
				height = rect.bottom - rect.top;
				if (newFont != 0) OS.SelectObject (hDC, oldFont);
				OS.ReleaseDC (handle, hDC);
				int upDownWidth = OS.GetSystemMetrics (OS.SM_CXVSCROLL);
				if (!OS.IsWinCE && OS.WIN32_VERSION >= OS.VERSION (6, 0)) {
					// TODO: On Vista, can send DTM_GETDATETIMEPICKERINFO to ask the Edit control what its margins are
//					DATETIMEPICKERINFO info = new DATETIMEPICKERINFO ();
//					OS.SendMessage(handle, OS.DTM_GETDATETIMEPICKERINFO, 0, info);
					if ((style & SWT.DROP_DOWN) != 0) upDownWidth += 16;
				}
				width += upDownWidth + MARGIN;
			}
			int upDownHeight = OS.GetSystemMetrics (OS.SM_CYVSCROLL);
			if (!OS.IsWinCE && OS.WIN32_VERSION >= OS.VERSION (6, 0)) {
				// TODO: On Vista, can send DTM_GETDATETIMEPICKERINFO to ask the Edit control what its margins are
//				DATETIMEPICKERINFO info = new DATETIMEPICKERINFO ();
//				OS.SendMessage(handle, OS.DTM_GETDATETIMEPICKERINFO, 0, info);
				upDownHeight += 7;
			}
			height = Math.max (height, upDownHeight);
		}
	}
	if (width == 0) width = DEFAULT_WIDTH;
	if (height == 0) height = DEFAULT_HEIGHT;
	if (wHint != SWT.DEFAULT) width = wHint;
	if (hHint != SWT.DEFAULT) height = hHint;
	int border = getBorderWidth ();
	width += border * 2;
	height += border * 2;
	return new Point (width, height);
}
Comment 6 Felipe Heidrich CLA 2010-11-02 17:31:14 EDT
Created attachment 182260 [details]
correct snapshot of snippet output on Hebrew Vista

(Sorry - attached wrong snapshot) - CM
Comment 7 Carolyn MacLeod CLA 2010-11-04 10:38:06 EDT
Created attachment 182374 [details]
Snapshot running on English Vista

Snapshot of new snippet output with code from patch plus computeSize in comment 5. Looks good here, also. I suspect this is now fixed for Vista and Windows 7. It doesn't work well on XP, however. I could go back to the old code for English XP, but that code did not work for Hebrew XP.
Comment 8 Carolyn MacLeod CLA 2010-11-04 11:12:15 EDT
Created attachment 182380 [details]
patch so far
Comment 9 Carolyn MacLeod CLA 2010-11-04 13:53:21 EDT
Created attachment 182403 [details]
patch that works well on XP English
Comment 10 Carolyn MacLeod CLA 2010-11-04 13:57:53 EDT
Created attachment 182405 [details]
snapshot on XP English
Comment 11 Carolyn MacLeod CLA 2010-11-04 14:32:10 EDT
Created attachment 182408 [details]
snap of Hebrew Win7 DateTIme

Tested on Windows 7 English and Hebrew. Looks good.
Comment 12 Carolyn MacLeod CLA 2010-11-08 14:47:13 EST
Fixed > 20101108