/* 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 #include "ut_png.h" #include "ut_svg.h" #include "ut_misc.h" #include "ut_string.h" #include "ut_assert.h" #include "ut_bytebuf.h" #include "ut_debugmsg.h" #include "ut_string_class.h" #include "ut_Win32LocaleString.h" #include "xap_App.h" #include "xap_Strings.h" #include "xap_Win32App.h" #include "xap_Win32FrameImpl.h" #include "xap_Dialog_Id.h" #include "xap_Dlg_FileOpenSaveAs.h" #include "xap_Win32Dlg_FileOpenSaveAs.h" #include "gr_Win32Image.h" #include "gr_Win32Graphics.h" #include "ap_Win32App.h" #include "ie_types.h" #include "ie_imp.h" #include "ie_impGraphic.h" #include "fg_Graphic.h" #include "xap_Win32Resources.rc2" #define MAX_DLG_INS_PICT_STRING 1030 /*****************************************************************/ XAP_Dialog * XAP_Win32Dialog_FileOpenSaveAs::static_constructor(XAP_DialogFactory * pFactory, XAP_Dialog_Id id) { XAP_Win32Dialog_FileOpenSaveAs * p = new XAP_Win32Dialog_FileOpenSaveAs(pFactory,id); return p; } XAP_Win32Dialog_FileOpenSaveAs::XAP_Win32Dialog_FileOpenSaveAs(XAP_DialogFactory * pDlgFactory, XAP_Dialog_Id id) : XAP_Dialog_FileOpenSaveAs(pDlgFactory,id) { m_szDefaultExtension[0] = 0; } XAP_Win32Dialog_FileOpenSaveAs::~XAP_Win32Dialog_FileOpenSaveAs(void) { } /*****************************************************************/ /*! Check for the presence of a file suffix in a list of suffixes \param haystack List of suffixes in the form "*a; *b; *c" \param needle Suffix to check for */ static bool SuffixInList(const char *haystack, const char *needle) { int l = strlen(needle); const char *s = strstr(haystack, needle); if (s) if (s[l] == 0 || s[l] == ';') return true; return false; } /*! Retrieve the default extension to use if user does not provide one \param indx -- index into the filter list */ wchar_t * XAP_Win32Dialog_FileOpenSaveAs::_getDefaultExtension(UT_uint32 indx) { static wchar_t abw_sfx[] = L"abw"; char defaultExtension[DEFAULT_EXT_SIZE + 1]; UT_Win32LocaleString def_ext; UT_uint32 end = g_strv_length((gchar **) m_szDescriptions); if(indx >= end) { if(m_id == XAP_DIALOG_ID_FILE_SAVE_IMAGE) return L"png"; return abw_sfx; } // copy at most DEFAULT_EXT_SIZE characters from the suffix; strncpy(defaultExtension, m_szSuffixes[indx] + 2, DEFAULT_EXT_SIZE); defaultExtension[DEFAULT_EXT_SIZE] = 0; // make sure that we get rid off the semicolon if it got copied char * semicolon = strchr(defaultExtension, ';'); if(semicolon) *semicolon = 0; UT_DEBUGMSG(("Default sfx [%s], (from [%s]\n", m_szDefaultExtension,m_szSuffixes[indx])); def_ext.fromASCII (defaultExtension); wcscpy (m_szDefaultExtension, def_ext.c_str()); return m_szDefaultExtension; } /*! Build a Windows filter list from Abi's filetypes \param sFilter Build the list in this string */ void XAP_Win32Dialog_FileOpenSaveAs::_buildFilterList(UT_String& sFilter) { UT_String sAllSuffixes; const XAP_StringSet* pSS = XAP_App::getApp()->getStringSet(); UT_ASSERT(g_strv_length((gchar **) m_szSuffixes) == g_strv_length((gchar **) m_szDescriptions)); // measure one list, they should all be the same length UT_uint32 end = g_strv_length((gchar **) m_szDescriptions); for (UT_uint32 i = 0; i < end; i++) { // HACK for inconsistent UTF-8 api sFilter += m_szDescriptions[i]; sFilter += '\004'; // include the trailing 0 sFilter += m_szSuffixes[i]; sFilter += '\004'; // include the trailing 0 // extract one suffix at a time const char *s1 = m_szSuffixes[i]; while (1) { const char *s2 = s1; while (*s2 && *s2 != ';') ++s2; UT_String sSuffix(s1, s2-s1); // build a complete list with no repeats if (!SuffixInList(sAllSuffixes.c_str(), sSuffix.c_str())) { if (!sAllSuffixes.empty()) sAllSuffixes += "; "; sAllSuffixes += sSuffix; } if (*s2 == 0) break; UT_ASSERT(s2[0] == ';' && s2[1] == ' '); s1 = s2 + 2; } } // all supported files filter sFilter += m_id == XAP_DIALOG_ID_INSERT_PICTURE ? pSS->getValue(XAP_STRING_ID_DLG_FOSA_ALLIMAGES) : pSS->getValue(XAP_STRING_ID_DLG_FOSA_ALLDOCS); sFilter += '\004'; // include the trailing 0 sFilter += sAllSuffixes; sFilter += '\004'; // include the trailing 0 // all files filter sFilter += pSS->getValue(XAP_STRING_ID_DLG_FOSA_ALL); sFilter += '\004'; // include the trailing 0 sFilter += "*.*"; sFilter += '\004'; // include the trailing 0 sFilter += '\004'; // double 0 at the end } /*****************************************************************/ /*! Gets the Windows File/Save common dialog box. To be able to get the places bar containing icons for commonly-used folders when we use hooking we need to use the new OPENFILENAME structure as defined in WINNT5 or better. To keep backward compability, first try with the new size of the structure, if it does not work it means the the common dialog box DLL installed in the system does not support the new features, and then we use the old one. In this situation, we user does not have a places bar capable common dialog box DLL anyway. */ BOOL XAP_Win32Dialog_FileOpenSaveAs::GetSaveFileName_Hooked(OPENFILENAME_WIN50* lpofn, BOOL bSave) { BOOL bRslt; lpofn->lStructSize = sizeof(OPENFILENAME_WIN50); // Size of the new structure lpofn->pvReserved = NULL; lpofn->dwReserved = 0; lpofn->FlagsEx = 0; if (bSave) bRslt = GetSaveFileNameW((OPENFILENAMEW *)lpofn); else bRslt = GetOpenFileNameW((OPENFILENAMEW *)lpofn); if (!bRslt) // Error { DWORD dwError = CommDlgExtendedError(); if (dwError==CDERR_STRUCTSIZE) // This system does not support the place bar { // Try with the old one lpofn->lStructSize = sizeof(OPENFILENAMEW); if (bSave) bRslt = GetSaveFileNameW((OPENFILENAMEW *)lpofn); else bRslt = GetOpenFileNameW((OPENFILENAMEW *)lpofn); } } return bRslt; } /*****************************************************************/ void XAP_Win32Dialog_FileOpenSaveAs::runModal(XAP_Frame * pFrame) { UT_return_if_fail(pFrame); UT_return_if_fail(pFrame->getFrameImpl()); XAP_Win32App* pWin32App = static_cast(XAP_App::getApp()); HWND hFrame = static_cast(pFrame->getFrameImpl())->getTopLevelWindow(); wchar_t szFile[MAX_DLG_INS_PICT_STRING]; // buffer for filename wchar_t szDir[MAX_DLG_INS_PICT_STRING]; // buffer for directory UT_String sFilter; OPENFILENAME_WIN50 ofn; // common dialog box structure UT_Win32LocaleString filter; ZeroMemory(szFile,sizeof(szFile)); ZeroMemory(szDir,sizeof(szDir)); ZeroMemory(&ofn, sizeof(OPENFILENAME_WIN50)); _buildFilterList(sFilter); filter.fromUTF8(sFilter.c_str()/*, sFilter.size()*/); LPWSTR f_cur=(LPWSTR)filter.c_str(); // \004 is a placeholder for \000 inside string while (*f_cur) { if (*f_cur == 4) *f_cur=0; f_cur++; } ofn.lStructSize = sizeof(OPENFILENAMEW); // Old size ofn.hwndOwner = hFrame; ofn.lpstrFile = szFile; ofn.nMaxFile = sizeof(szFile); ofn.lpstrFilter = filter.c_str(); ofn.nFilterIndex = 1; ofn.lpstrFileTitle = NULL; ofn.nMaxFileTitle = 0; ofn.lpstrInitialDir = NULL; ofn.Flags = OFN_PATHMUSTEXIST | OFN_NOCHANGEDIR | OFN_HIDEREADONLY; ofn.lpstrDefExt = _getDefaultExtension(0); ofn.lCustData = (DWORD)(size_t)this; // use the persistence info and/or the suggested filename // to properly seed the dialog. if (!m_szInitialPathname || !*m_szInitialPathname) { // the caller did not supply initial pathname // (or supplied an empty one). see if we have // some persistent info. UT_ASSERT(!m_bSuggestName); if (m_szPersistPathname) { // we have a pathname from a previous use, // extract the directory portion and start // the dialog there (but without a filename). // use directory(m_szPersistPathname) UT_Win32LocaleString path; path.fromUTF8 (m_szPersistPathname); wcscpy(szDir,path.c_str()); wchar_t * pLastSlash = wcsrchr(szDir, L'/'); if (pLastSlash) pLastSlash[1] = 0; ofn.lpstrInitialDir = szDir; } else { // no initial pathname given and we don't have // a pathname from a previous use, so just let // it come up in the current working directory. // since we set OFN_NOCHANGEDIR we don't have to // to worry about where this is. } } else { // we have an initial pathname (the name of the document // in the frame that we were invoked on). if the caller // wanted us to suggest a name, use the initial // pathname as is. if not, use the directory portion of // it. either way, we need to cut the pathname into two // parts -- directory and file -- for the common dlg. UT_Win32LocaleString uri; const char * szURI = g_filename_from_uri(m_szInitialPathname, NULL, NULL); if(!szURI) szURI = g_strdup(m_szInitialPathname); uri.fromUTF8 (szURI); wcscpy(szDir,uri.c_str()); wchar_t * pLastSlash = wcsrchr(szDir, L'\\'); if (!pLastSlash) pLastSlash = wcsrchr(szDir, L'/'); if (pLastSlash) pLastSlash[1] = 0; ofn.lpstrInitialDir = szDir; if (m_bSuggestName) { if (pLastSlash) wcscpy(szFile, uri.c_str() + (pLastSlash-szDir+1)); else wcscpy(szFile, uri.c_str()); // if the file name has an extension, remove it // (if we don't, and the document is of a different // type than the one initially selected in the dialogue // and the user just clicks OK, we get type - extension // mismatch) wchar_t * dot = wcsrchr(szFile, L'.'); if(dot) *dot = 0; } FREEP(szURI); } // display the appropriate dialog box. BOOL bDialogResult; if( m_nDefaultFileType != XAP_DIALOG_FILEOPENSAVEAS_FILE_TYPE_AUTO ) { // Find the index of the type we were given UT_uint32 iCounter, iNumTypes = g_strv_length((gchar **) m_nTypeList); for( iCounter = 0; iCounter < iNumTypes; iCounter++ ) { if( m_nTypeList[ iCounter ] == m_nDefaultFileType ) { ofn.nFilterIndex = iCounter + 1; break; } } } const XAP_StringSet* pSS = XAP_App::getApp()->getStringSet(); UT_Win32LocaleString title; switch (m_id) { case XAP_DIALOG_ID_FILE_OPEN: title.fromUTF8 (pSS->getValue(XAP_STRING_ID_DLG_FOSA_OpenTitle)); ofn.lpstrTitle = title.c_str(); ofn.Flags |= OFN_FILEMUSTEXIST; ofn.nFilterIndex = g_strv_length((gchar **) m_szDescriptions) + 1; bDialogResult = GetOpenFileNameW((OPENFILENAMEW *)&ofn); break; case XAP_DIALOG_ID_PRINTTOFILE: title.fromUTF8 (pSS->getValue(XAP_STRING_ID_DLG_FOSA_PrintToFileTitle)); ofn.lpstrTitle = title.c_str(); ofn.Flags |= OFN_OVERWRITEPROMPT; bDialogResult = GetSaveFileNameW((OPENFILENAMEW *)&ofn); break; case XAP_DIALOG_ID_FILE_SAVEAS: case XAP_DIALOG_ID_FILE_SAVE_IMAGE: title.fromUTF8 (pSS->getValue(XAP_STRING_ID_DLG_FOSA_SaveAsTitle)); ofn.lpstrTitle = title.c_str(); ofn.lpfnHook = (LPOFNHOOKPROC) s_hookSaveAsProc; ofn.Flags |= OFN_OVERWRITEPROMPT; ofn.Flags |= OFN_EXPLORER; ofn.Flags |= OFN_ENABLEHOOK; bDialogResult = GetSaveFileName_Hooked(&ofn, TRUE); break; case XAP_DIALOG_ID_INSERT_PICTURE: title.fromUTF8 (pSS->getValue(XAP_STRING_ID_DLG_IP_Title)); ofn.lpstrTitle = title.c_str(); ofn.hInstance = pWin32App->getInstance(); ofn.lpTemplateName = MAKEINTRESOURCEW(XAP_RID_DIALOG_INSERT_PICTURE); ofn.lpfnHook = (LPOFNHOOKPROC) s_hookInsertPicProc; ofn.nFilterIndex = g_strv_length((gchar **) m_szDescriptions) + 1; ofn.Flags |= OFN_EXPLORER; ofn.Flags |= OFN_ENABLETEMPLATE; ofn.Flags |= OFN_ENABLEHOOK; bDialogResult = GetSaveFileName_Hooked(&ofn, FALSE); break; case XAP_DIALOG_ID_FILE_IMPORT: title.fromUTF8 (pSS->getValue(XAP_STRING_ID_DLG_FOSA_ImportTitle)); ofn.lpstrTitle = title.c_str(); ofn.nFilterIndex = g_strv_length((gchar **) m_szDescriptions) + 1; ofn.Flags |= OFN_FILEMUSTEXIST; bDialogResult = GetOpenFileNameW((OPENFILENAMEW *)&ofn); break; case XAP_DIALOG_ID_INSERTMATHML: title.fromUTF8 (pSS->getValue(XAP_STRING_ID_DLG_FOSA_InsertMath)); ofn.lpstrTitle = title.c_str(); ofn.nFilterIndex = g_strv_length((gchar **) m_szDescriptions) + 1; ofn.Flags |= OFN_FILEMUSTEXIST; bDialogResult = GetOpenFileNameW((OPENFILENAMEW *)&ofn); break; case XAP_DIALOG_ID_FILE_EXPORT: title.fromUTF8 (pSS->getValue(XAP_STRING_ID_DLG_FOSA_ExportTitle)); ofn.lpstrTitle = title.c_str(); ofn.lpfnHook = (LPOFNHOOKPROC) s_hookSaveAsProc; ofn.Flags |= OFN_OVERWRITEPROMPT; ofn.Flags |= OFN_EXPLORER; ofn.Flags |= OFN_ENABLEHOOK; bDialogResult = GetSaveFileName_Hooked(&ofn, TRUE); break; case XAP_DIALOG_ID_INSERT_FILE: title.fromUTF8 (pSS->getValue(XAP_STRING_ID_DLG_FOSA_InsertTitle)); ofn.lpstrTitle = title.c_str(); ofn.Flags |= OFN_FILEMUSTEXIST; ofn.nFilterIndex = g_strv_length((gchar **) m_szDescriptions) + 1; bDialogResult = GetOpenFileNameW((OPENFILENAMEW *)&ofn); break; default: UT_ASSERT_HARMLESS(UT_SHOULD_NOT_HAPPEN); break; } // TODO how do cancels get reported... // TODO verify that current-working-directory is not changed... if (bDialogResult != FALSE) { UT_uint32 end = g_strv_length((gchar **) m_szSuffixes); UT_Win32LocaleString sfile; sfile.fromLocale (szFile); if ((m_id == XAP_DIALOG_ID_FILE_SAVEAS) && (UT_pathSuffix(sfile.utf8_str().utf8_str()).empty())) { // add suffix based on selected file type // if selected file is "all documents" or "all" // default to .abw, since that is how it will get saved UT_ASSERT(ofn.nFilterIndex > 0); std::string suffix; char abw_sfx[] = ".abw"; if(ofn.nFilterIndex <= end) suffix = UT_pathSuffix(m_szSuffixes[ofn.nFilterIndex - 1]); else suffix = abw_sfx; UT_ASSERT(!suffix.empty()); UT_uint32 length = strlen(sfile.utf8_str().utf8_str()) + suffix.size() + 1; m_szFinalPathname = (char *)UT_calloc(length,sizeof(char)); if (m_szFinalPathname) { char * p = m_szFinalPathname; strcpy(p,sfile.utf8_str().utf8_str()); strcat(p,suffix.c_str()); } } else { char *uri = UT_go_filename_to_uri(sfile.utf8_str().utf8_str()); if(uri) { if(!(m_szFinalPathname = g_strdup(uri))) { UT_ASSERT_HARMLESS(UT_SHOULD_NOT_HAPPEN); m_szFinalPathname = NULL; } FREEP(uri); } else { UT_ASSERT_HARMLESS(UT_SHOULD_NOT_HAPPEN); m_szFinalPathname = NULL; } } m_answer = a_OK; // Set filetype to auto if a generic filter was set if (ofn.nFilterIndex > g_strv_length((gchar **) m_szSuffixes)) m_nFileType = XAP_DIALOG_FILEOPENSAVEAS_FILE_TYPE_AUTO; else m_nFileType = ofn.nFilterIndex; } else { m_answer = a_CANCEL; UT_DEBUGMSG(("Didn't get a file: reason=0x%x\n", CommDlgExtendedError())); } } /*! Used for SaveAs case of FileOpenSaveAs dialog \param hDlg \param msg \param wParam \param lParam Static routine */ UINT CALLBACK XAP_Win32Dialog_FileOpenSaveAs::s_hookSaveAsProc(HWND hDlg, UINT msg, WPARAM /*wParam*/, LPARAM lParam) { XAP_Win32Dialog_FileOpenSaveAs* pThis; static wchar_t buff[MAX_DLG_INS_PICT_STRING]; switch(msg) { case WM_NOTIFY: { const OFNOTIFYW * pNotify = reinterpret_cast(lParam); switch (pNotify->hdr.code) { case CDN_TYPECHANGE: { UT_DEBUGMSG(("SaveAs filetype changed to %d\n", pNotify->lpOFN->nFilterIndex)); pThis = (XAP_Win32Dialog_FileOpenSaveAs*)pNotify->lpOFN->lCustData; wchar_t * ext = pThis->_getDefaultExtension(pNotify->lpOFN->nFilterIndex - 1); // for some reason the lpstrFile member of the struct will not be set properly // so we have to retrieve the text directly from the control (I could swear that // this used to work, and have no idea what changed) GetDlgItemTextW(GetParent(hDlg), edt1, buff, MAX_DLG_INS_PICT_STRING); wcscpy(buff,pNotify->lpOFN->lpstrFile); //was once commented wchar_t * dot = wcschr(buff, L'.'); if(dot) { *(dot+1) = 0; } else if(*buff) { UT_ASSERT(wcslen(buff) < MAX_DLG_INS_PICT_STRING); dot = buff + wcslen(buff); *dot = L'.'; *(dot+1) = 0; } if(dot) { UT_ASSERT(wcslen(buff) + wcslen(pNotify->lpOFN->lpstrDefExt) < MAX_DLG_INS_PICT_STRING); if(ext) wcscat(buff,ext); else *dot = 0; CommDlg_OpenSave_SetControlText(GetParent(hDlg), edt1, buff); } CommDlg_OpenSave_SetDefExt(GetParent(hDlg), ext); } break; } } break; default: return false; } return false; } /*! Used for Insert Picture case of FileOpenSaveAs dialog \param hDlg \param msg \param wParam \param lParam Static routine */ UINT CALLBACK XAP_Win32Dialog_FileOpenSaveAs::s_hookInsertPicProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) { XAP_Win32Dialog_FileOpenSaveAs* pThis = (XAP_Win32Dialog_FileOpenSaveAs *) GetWindowLongPtrW(hDlg,GWLP_USERDATA); bool bPreviewImage = ( IsDlgButtonChecked( hDlg, XAP_RID_DIALOG_INSERT_PICTURE_CHECK_ACTIVATE_PREVIEW ) == BST_CHECKED ); switch(msg) { case WM_PAINT: if (bPreviewImage) pThis->_previewPicture(hDlg); return false; case WM_NOTIFY: // Only bother if Preview Image is selected if (!bPreviewImage) return false; switch ( ((OFNOTIFYW*) lParam)->hdr.code ) { case CDN_FOLDERCHANGE: UT_DEBUGMSG(("Folder Changed File Name Cleared\n")); SetDlgItemTextW( GetParent(hDlg), edt1, NULL ); SetDlgItemTextW( hDlg, XAP_RID_DIALOG_INSERT_PICTURE_TEXT_HEIGHT, NULL ); SetDlgItemTextW( hDlg, XAP_RID_DIALOG_INSERT_PICTURE_TEXT_WIDTH, NULL ); return true; case CDN_SELCHANGE: UT_return_val_if_fail(pThis,false); return pThis->_previewPicture(hDlg); } return false; case WM_COMMAND: // Check box to Activate Image Preview UT_DEBUGMSG(("WM_COMMAND Received: wParam = %ld, lParam = %ld\n",wParam,lParam)); if ( HIWORD(wParam) == BN_CLICKED ) { switch ( LOWORD(wParam) ) { case XAP_RID_DIALOG_INSERT_PICTURE_CHECK_ACTIVATE_PREVIEW: UT_return_val_if_fail(pThis,false); if (bPreviewImage) { ShowWindow( GetDlgItem(hDlg,XAP_RID_DIALOG_INSERT_PICTURE_TEXT_HEIGHT), SW_SHOW ); ShowWindow( GetDlgItem(hDlg,XAP_RID_DIALOG_INSERT_PICTURE_TEXT_WIDTH), SW_SHOW ); pThis->_previewPicture(hDlg); return true; } else { ShowWindow( GetDlgItem(hDlg,XAP_RID_DIALOG_INSERT_PICTURE_TEXT_HEIGHT), SW_HIDE ); ShowWindow( GetDlgItem(hDlg,XAP_RID_DIALOG_INSERT_PICTURE_TEXT_WIDTH), SW_HIDE ); return pThis->_initPreviewDlg(hDlg); } } } return false; case WM_INITDIALOG: pThis = (XAP_Win32Dialog_FileOpenSaveAs *)reinterpret_cast(lParam)->lCustData; SetWindowLongPtrW(hDlg, GWLP_USERDATA, (LONG_PTR) pThis); return pThis->_initPreviewDlg(hDlg); default: return false; } // Default Dialog handles all other issues return false; } UINT XAP_Win32Dialog_FileOpenSaveAs::_previewPicture(HWND hDlg) { HWND hFOSADlg = GetParent(hDlg); HWND hThumbnail = GetDlgItem(hDlg,XAP_RID_DIALOG_INSERT_PICTURE_IMAGE_PREVIEW); UT_Win32LocaleString str; const XAP_StringSet* pSS = XAP_App::getApp()->getStringSet(); UT_return_val_if_fail(pSS, false); // Check if File Name is for a file wchar_t buf[MAX_DLG_INS_PICT_STRING]; SendMessageW( hFOSADlg, CDM_GETFILEPATH, sizeof(buf), (LPARAM) buf ); // If a Directory stop if ( GetFileAttributesW( buf ) == FILE_ATTRIBUTE_DIRECTORY ) { return false; } str.fromLocale (buf); UT_DEBUGMSG(("File Selected is %s\n", str.utf8_str().utf8_str())); // Build an Import Graphic based on file type UT_Error errorCode = UT_ERROR; FG_Graphic *pfg = NULL; char *uri = UT_go_filename_to_uri(str.utf8_str().utf8_str()); if(uri) errorCode = IE_ImpGraphic::loadGraphic(uri, IEGFT_Unknown, &pfg); if (errorCode) { return false; } double scale_factor = 0.0; UT_sint32 scaled_width,scaled_height; UT_sint32 iImageWidth,iImageHeight; RECT r; GetClientRect (hThumbnail, &r); InvalidateRect(hThumbnail, &r, true); iImageWidth = pfg->getWidth(); iImageHeight = pfg->getHeight(); // Update Height and Width Strings str.fromUTF8 (pSS->getValue(XAP_STRING_ID_DLG_IP_Height_Label)); swprintf( buf, L"%s %d", str.c_str(), iImageHeight ); SetDlgItemTextW( hDlg, XAP_RID_DIALOG_INSERT_PICTURE_TEXT_HEIGHT, buf ); str.fromUTF8 (pSS->getValue(XAP_STRING_ID_DLG_IP_Width_Label)); swprintf( buf, L"%s %d", str.c_str(), iImageWidth ); SetDlgItemTextW( hDlg, XAP_RID_DIALOG_INSERT_PICTURE_TEXT_WIDTH, buf ); // Reset String for Height and Width if (r.right >= iImageWidth && r.bottom >= iImageHeight) scale_factor = 1.0; else scale_factor = UT_MIN( (double) r.right/iImageWidth, (double) r.bottom/iImageHeight ); scaled_width = (int) (scale_factor * iImageWidth); scaled_height = (int) (scale_factor * iImageHeight); GR_Win32Image* pImage = new GR_Win32Image(NULL); pImage->convertFromBuffer(pfg->getBuffer(), pfg->getMimeType(), scaled_width, scaled_height); PAINTSTRUCT ps; HDC hdc = BeginPaint(hThumbnail, &ps); FillRect(hdc, &r, GetSysColorBrush(COLOR_BTNFACE)); GR_Win32AllocInfo ai(hdc,hThumbnail); GR_Win32Graphics *pGr = (GR_Win32Graphics *)XAP_App::getApp()->newGraphics(ai); UT_return_val_if_fail(pGr, false); pGr->drawImage(pImage, pGr->tlu((r.right - scaled_width ) / 2), pGr->tlu((r.bottom - scaled_height) / 2)); EndPaint(hThumbnail,&ps); DELETEP(pfg); DELETEP(pImage); DELETEP(pGr); return true; } UINT XAP_Win32Dialog_FileOpenSaveAs::_initPreviewDlg(HWND hDlg) { HWND hFOSADlg = GetParent(hDlg); UT_Win32LocaleString str; setHandle (hDlg); const XAP_StringSet* pSS = XAP_App::getApp()->getStringSet(); UT_return_val_if_fail(pSS, false); setDlgItemText( XAP_RID_DIALOG_INSERT_PICTURE_IMAGE_PREVIEW, pSS->getValue(XAP_STRING_ID_DLG_IP_No_Picture_Label)); setDlgItemText( XAP_RID_DIALOG_INSERT_PICTURE_CHECK_ACTIVATE_PREVIEW, pSS->getValue(XAP_STRING_ID_DLG_IP_Activate_Label)); setDlgItemText( XAP_RID_DIALOG_INSERT_PICTURE_TEXT_HEIGHT, pSS->getValue(XAP_STRING_ID_DLG_IP_Height_Label)); setDlgItemText( XAP_RID_DIALOG_INSERT_PICTURE_TEXT_WIDTH, pSS->getValue(XAP_STRING_ID_DLG_IP_Width_Label)); str.fromUTF8 (pSS->getValue(XAP_STRING_ID_DLG_IP_Button_Label)); SetDlgItemTextW( hFOSADlg, IDOK, str.c_str()); return true; }