/* AbiSource Application Framework * Copyright (C) 1998 AbiSource, Inc. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA. */ #include #include "ut_string.h" #include "ut_assert.h" #include "ut_debugmsg.h" #include "xap_App.h" #include "xap_Win32App.h" #include "xap_Win32Frame.h" #include "xap_Strings.h" #include "xap_Dialog_Id.h" #include "xap_Dlg_Zoom.h" #include "xap_Win32Dlg_Zoom.h" #include "xap_Win32PreviewWidget.h" #include "gr_Win32Graphics.h" #include "xap_Win32Resources.rc2" /*****************************************************************/ XAP_Dialog * XAP_Win32Dialog_Zoom::static_constructor(XAP_DialogFactory * pFactory, XAP_Dialog_Id id) { XAP_Win32Dialog_Zoom * p = new XAP_Win32Dialog_Zoom(pFactory,id); return p; } XAP_Win32Dialog_Zoom::XAP_Win32Dialog_Zoom(XAP_DialogFactory * pDlgFactory, XAP_Dialog_Id id) : XAP_Dialog_Zoom(pDlgFactory,id) { m_pPreviewWidget = NULL; m_bEditPctChanged = false; m_bEditPctEnabled = false; } XAP_Win32Dialog_Zoom::~XAP_Win32Dialog_Zoom(void) { DELETEP(m_pPreviewWidget); } /*****************************************************************/ void XAP_Win32Dialog_Zoom::runModal(XAP_Frame * pFrame) { m_pFrame = pFrame; /* This dialog is non-persistent. This dialog should do the following: - Construct itself to represent the base-class zoomTypes z_200, z_100, z_75, z_PageWidth, z_WholePage, and z_Percent. The Unix one looks just like Microsoft Word 97, with the preview and all (even though it's not hooked up yet). - Set zoom type to match "m_zoomType" and value of radio button to match "m_zoomPercent". On "OK" (or during user-interaction) the dialog should: - Save the zoom type to "m_zoomType". - Save the value in the Percent spin button box to "m_zoomPercent". On "Cancel" the dialog should: - Just quit, the data items will be ignored by the caller. */ // raise the dialog XAP_Win32App * pWin32App = static_cast(m_pApp); XAP_Win32Frame * pWin32Frame = static_cast(pFrame); LPCTSTR lpTemplate = NULL; UT_ASSERT(m_id == XAP_DIALOG_ID_ZOOM); lpTemplate = MAKEINTRESOURCE(XAP_RID_DIALOG_ZOOM); int result = DialogBoxParam(pWin32App->getInstance(),lpTemplate, pWin32Frame->getTopLevelWindow(), (DLGPROC)s_dlgProc,(LPARAM)this); UT_ASSERT((result != -1)); } BOOL CALLBACK XAP_Win32Dialog_Zoom::s_dlgProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam) { // This is a static function. XAP_Win32Dialog_Zoom * pThis; switch (msg) { case WM_INITDIALOG: pThis = (XAP_Win32Dialog_Zoom *)lParam; SetWindowLong(hWnd,DWL_USER,lParam); return pThis->_onInitDialog(hWnd,wParam,lParam); case WM_COMMAND: pThis = (XAP_Win32Dialog_Zoom *)GetWindowLong(hWnd,DWL_USER); if (pThis) return pThis->_onCommand(hWnd,wParam,lParam); else return 0; case WM_NOTIFY: pThis = (XAP_Win32Dialog_Zoom *)GetWindowLong(hWnd,DWL_USER); switch (((LPNMHDR)lParam)->code) { case UDN_DELTAPOS: return pThis->_onDeltaPos((NM_UPDOWN *)lParam); default: return 0; } case WM_VSCROLL: pThis = (XAP_Win32Dialog_Zoom *)GetWindowLong(hWnd,DWL_USER); pThis->_updatePreviewZoomPercent((UT_uint32)HIWORD(wParam)); return 1; default: return 0; } } #define _DS(c,s) SetDlgItemText(hWnd,XAP_RID_DIALOG_##c,pSS->getValue(XAP_STRING_ID_##s)) BOOL XAP_Win32Dialog_Zoom::_onInitDialog(HWND hWnd, WPARAM wParam, LPARAM lParam) { const XAP_StringSet * pSS = m_pApp->getStringSet(); SetWindowText(hWnd, pSS->getValue(XAP_STRING_ID_DLG_Zoom_ZoomTitle)); // localize controls _DS(ZOOM_TEXT_ZOOMTO, DLG_Zoom_RadioFrameCaption); _DS(ZOOM_RADIO_200, DLG_Zoom_200); _DS(ZOOM_RADIO_100, DLG_Zoom_100); _DS(ZOOM_RADIO_75, DLG_Zoom_75); _DS(ZOOM_RADIO_WIDTH, DLG_Zoom_PageWidth); _DS(ZOOM_RADIO_WHOLE, DLG_Zoom_WholePage); _DS(ZOOM_RADIO_PCT, DLG_Zoom_Percent); _DS(ZOOM_TEXT_PREVIEW, DLG_Zoom_PreviewFrame); _DS(ZOOM_BTN_OK, DLG_OK); _DS(ZOOM_BTN_CANCEL, DLG_Cancel); // set initial state CheckDlgButton(hWnd, XAP_RID_DIALOG_ZOOM_RADIO_200 + m_zoomType, BST_CHECKED); SetDlgItemInt(hWnd, XAP_RID_DIALOG_ZOOM_EDIT_PCT, (UINT) m_zoomPercent, FALSE); m_bEditPctEnabled = ((XAP_RID_DIALOG_ZOOM_RADIO_200 + m_zoomType) == XAP_RID_DIALOG_ZOOM_RADIO_PCT); EnableWindow(GetDlgItem(hWnd,XAP_RID_DIALOG_ZOOM_EDIT_PCT),m_bEditPctEnabled); SendMessage(GetDlgItem(hWnd,XAP_RID_DIALOG_ZOOM_SPIN_PCT),UDM_SETRANGE, (WPARAM)0,(LPARAM)MAKELONG(XAP_DLG_ZOOM_MAXIMUM_ZOOM,XAP_DLG_ZOOM_MINIMUM_ZOOM)); // use the owner-draw-control dialog-item (aka window) specified in the // dialog resource file as a parent to the window/widget that we create // here and thus have complete control of. m_pPreviewWidget = new XAP_Win32PreviewWidget(static_cast(m_pApp), GetDlgItem(hWnd, XAP_RID_DIALOG_ZOOM_PREVIEW), 0); // instantiate the XP preview object using the win32 preview widget (window) // we just created. we seem to have a mish-mash of terms here, sorry. UT_uint32 w,h; m_pPreviewWidget->getWindowSize(&w,&h); _createPreviewFromGC(m_pPreviewWidget->getGraphics(),w,h); m_pPreviewWidget->setPreview(m_zoomPreview); // we need this to call draw() on WM_PAINTs _updatePreviewZoomPercent(getZoomPercent()); return 1; // 1 == we did not call SetFocus() } // TODO: move this to UTIL/WIN static int _getRBOffset(HWND hWnd, int nIDFirstButton, int nIDLastButton) { UT_ASSERT(hWnd && IsWindow(hWnd)); UT_ASSERT(nIDFirstButton < nIDLastButton); for (int i = nIDFirstButton; i <= nIDLastButton; i++) if (BST_CHECKED == IsDlgButtonChecked(hWnd, i)) return (i - nIDFirstButton); UT_ASSERT(UT_SHOULD_NOT_HAPPEN); return -1; } BOOL XAP_Win32Dialog_Zoom::_onCommand(HWND hWnd, WPARAM wParam, LPARAM lParam) { WORD wNotifyCode = HIWORD(wParam); WORD wId = LOWORD(wParam); HWND hWndCtrl = (HWND)lParam; UT_sint32 n, newValue; switch (wId) { case XAP_RID_DIALOG_ZOOM_RADIO_200: m_bEditPctEnabled = (IsDlgButtonChecked(hWnd,XAP_RID_DIALOG_ZOOM_RADIO_PCT)==BST_CHECKED); EnableWindow(GetDlgItem(hWnd,XAP_RID_DIALOG_ZOOM_EDIT_PCT),m_bEditPctEnabled); _updatePreviewZoomPercent(200); return 1; case XAP_RID_DIALOG_ZOOM_RADIO_100: m_bEditPctEnabled = (IsDlgButtonChecked(hWnd,XAP_RID_DIALOG_ZOOM_RADIO_PCT)==BST_CHECKED); EnableWindow(GetDlgItem(hWnd,XAP_RID_DIALOG_ZOOM_EDIT_PCT),m_bEditPctEnabled); _updatePreviewZoomPercent(100); return 1; case XAP_RID_DIALOG_ZOOM_RADIO_75: m_bEditPctEnabled = (IsDlgButtonChecked(hWnd,XAP_RID_DIALOG_ZOOM_RADIO_PCT)==BST_CHECKED); EnableWindow(GetDlgItem(hWnd,XAP_RID_DIALOG_ZOOM_EDIT_PCT),m_bEditPctEnabled); _updatePreviewZoomPercent(75); return 1; case XAP_RID_DIALOG_ZOOM_RADIO_WIDTH: m_bEditPctEnabled = (IsDlgButtonChecked(hWnd,XAP_RID_DIALOG_ZOOM_RADIO_PCT)==BST_CHECKED); EnableWindow(GetDlgItem(hWnd,XAP_RID_DIALOG_ZOOM_EDIT_PCT),m_bEditPctEnabled); if( m_pFrame ) { newValue = m_pFrame->getCurrentView()->calculateZoomPercentForPageWidth(); _updatePreviewZoomPercent(newValue); } return 1; case XAP_RID_DIALOG_ZOOM_RADIO_WHOLE: m_bEditPctEnabled = (IsDlgButtonChecked(hWnd,XAP_RID_DIALOG_ZOOM_RADIO_PCT)==BST_CHECKED); EnableWindow(GetDlgItem(hWnd,XAP_RID_DIALOG_ZOOM_EDIT_PCT),m_bEditPctEnabled); if( m_pFrame ) { newValue = m_pFrame->getCurrentView()->calculateZoomPercentForWholePage(); _updatePreviewZoomPercent(newValue); } return 1; case XAP_RID_DIALOG_ZOOM_RADIO_PCT: m_bEditPctEnabled = (IsDlgButtonChecked(hWnd,XAP_RID_DIALOG_ZOOM_RADIO_PCT)==BST_CHECKED); EnableWindow(GetDlgItem(hWnd,XAP_RID_DIALOG_ZOOM_EDIT_PCT),m_bEditPctEnabled); if (m_bEditPctEnabled) if (_getValueFromEditPct(hWnd,&newValue)) _updatePreviewZoomPercent(newValue); return 1; case XAP_RID_DIALOG_ZOOM_EDIT_PCT: switch (wNotifyCode) { case EN_CHANGE: m_bEditPctChanged = true; return 1; case EN_KILLFOCUS: if (m_bEditPctChanged) if (_getValueFromEditPct(hWnd,&newValue)) _updatePreviewZoomPercent(newValue); m_bEditPctChanged = false; return 1; default: return 1; } case IDCANCEL: // also XAP_RID_DIALOG_ZOOM_BTN_CANCEL m_answer = a_CANCEL; EndDialog(hWnd,0); return 1; case IDOK: // also XAP_RID_DIALOG_ZOOM_BTN_OK n = _getRBOffset(hWnd, XAP_RID_DIALOG_ZOOM_RADIO_200, XAP_RID_DIALOG_ZOOM_RADIO_PCT); UT_ASSERT(n >= 0); m_zoomType = (XAP_Frame::tZoomType) n; if (_getValueFromEditPct(hWnd,&newValue)) m_zoomPercent = newValue; EndDialog(hWnd,0); return 1; default: // we did not handle this notification UT_DEBUGMSG(("WM_Command for id %ld\n",wId)); return 0; // return zero to let windows take care of it. } } BOOL XAP_Win32Dialog_Zoom::_onDeltaPos(NM_UPDOWN * pnmud) { // respond to WM_NOTIFY/UDN_DELTAPOS message // return TRUE to prevent the change from happening // return FALSE to allow it to occur // we may alter the change by changing the fields in pnmud. UT_ASSERT(pnmud->hdr.idFrom == XAP_RID_DIALOG_ZOOM_SPIN_PCT); UT_DEBUGMSG(("onDeltaPos: [idFrom %d][iPos %d][iDelta %d]\n", pnmud->hdr.idFrom,pnmud->iPos,pnmud->iDelta)); int iNew = pnmud->iPos + pnmud->iDelta; if ((pnmud->iPos < XAP_DLG_ZOOM_MINIMUM_ZOOM) || (iNew < XAP_DLG_ZOOM_MINIMUM_ZOOM)) { // bogus current position or bogus delta, force it back to minimum. pnmud->iDelta = XAP_DLG_ZOOM_MINIMUM_ZOOM - pnmud->iPos; return FALSE; } if ((pnmud->iPos > XAP_DLG_ZOOM_MAXIMUM_ZOOM) || (iNew > XAP_DLG_ZOOM_MAXIMUM_ZOOM)) { // arbitrary upper limit (XAP_DLG_ZOOM_MAXIMUM_ZOOM) // i did this because massive scaling of fonts // causes problems for virtual memory (when they // get rendered at huge sizes). // MSWORD97 also applies this limit. pnmud->iDelta = XAP_DLG_ZOOM_MAXIMUM_ZOOM - pnmud->iPos; return FALSE; } return FALSE; } BOOL XAP_Win32Dialog_Zoom::_getValueFromEditPct(HWND hWnd, int * pNewValue) { BOOL bOK; int newValue = GetDlgItemInt(hWnd, XAP_RID_DIALOG_ZOOM_EDIT_PCT, &bOK, FALSE); if (!bOK) return FALSE; // valid number, but out of range clip to MIN or MAX range; if (newValue < XAP_DLG_ZOOM_MINIMUM_ZOOM) newValue = XAP_DLG_ZOOM_MINIMUM_ZOOM; if (newValue > XAP_DLG_ZOOM_MAXIMUM_ZOOM) newValue = XAP_DLG_ZOOM_MAXIMUM_ZOOM; *pNewValue = newValue; return TRUE; }