index 4dfa36b488620648294f880433aeca0bb27c8ebd..d6624828cf3f9ed6da91acd41261ce097f7ecca4 100644 (file)
#include <display/nr-arena-item.h>
#include <display/nr-arena.h>
#include "sp-item.h"
-#include "canvas-arena.h"
+#include "display/canvas-arena.h"
#include "filedialog.h"
#include "filedialogimpl-win32.h"
parent(parent),
_current_directory(dir)
{
- //_mutex = NULL;
_main_loop = NULL;
+ _filter_index = 1;
+ _filter_count = 0;
+
_title = (wchar_t*)g_utf8_to_utf16(title, -1, NULL, NULL, NULL);
+ g_assert(_title != NULL);
Glib::RefPtr<const Gdk::Window> parentWindow = parent.get_window();
g_assert(parentWindow->gobj() != NULL);
_preview_document_height = 0;
_preview_image_width = 0;
_preview_image_height = 0;
+ _preview_emf_image = false;
+
+ _mutex = NULL;
createFilterMenu();
}
if (imod->deactivated()) continue;
// Type
- filter.name = g_utf8_to_utf16(imod->get_filetypename(),
+ filter.name = g_utf8_to_utf16(_(imod->get_filetypename()),
-1, NULL, &filter.name_length, NULL);
// Extension
-1, NULL, &all_image_files.name_length, NULL);
all_image_files.filter = g_utf8_to_utf16(all_image_files_filter.data(),
-1, NULL, &all_image_files.filter_length, NULL);
+ all_image_files.mod = NULL;
filter_list.push_front(all_image_files);
- _extension_map[extension_index++] = NULL;
// Filter Inkscape Files
all_inkscape_files.name = g_utf8_to_utf16(all_inkscape_files_filter_name,
-1, NULL, &all_inkscape_files.name_length, NULL);
all_inkscape_files.filter = g_utf8_to_utf16(all_inkscape_files_filter.data(),
-1, NULL, &all_inkscape_files.filter_length, NULL);
+ all_inkscape_files.mod = NULL;
filter_list.push_front(all_inkscape_files);
- _extension_map[extension_index++] = NULL;
// Filter All Files
all_files.name = g_utf8_to_utf16(all_files_filter_name,
-1, NULL, &all_files.name_length, NULL);
all_files.filter = NULL;
all_files.filter_length = 0;
+ all_files.mod = NULL;
filter_list.push_front(all_files);
- _extension_map[extension_index++] = NULL;
filter_length += all_files.name_length + 3 +
all_inkscape_files.filter_length +
all_image_files.filter_length +
all_image_files.name_length + 3 + 1;
// Add 3 for 2*2 \0s and a *, and 1 for a trailing \0
-
-
- _filter = new wchar_t[filter_length];
+
+ _filter = new wchar_t[filter_length];
wchar_t *filterptr = _filter;
-
+
for(list<Filter>::iterator filter_iterator = filter_list.begin();
filter_iterator != filter_list.end(); filter_iterator++)
{
const Filter &filter = *filter_iterator;
- memcpy(filterptr, filter.name, filter.name_length * 2);
+ wcsncpy(filterptr, (wchar_t*)filter.name, filter.name_length);
filterptr += filter.name_length;
g_free(filter.name);
if(filter.filter != NULL)
{
- memcpy(filterptr, filter.filter, filter.filter_length * 2);
+ wcsncpy(filterptr, (wchar_t*)filter.filter, filter.filter_length);
filterptr += filter.filter_length;
g_free(filter.filter);
}
_extension_map[extension_index++] = filter.mod;
}
*(filterptr++) = L'\0';
-
- _filterIndex = 2;
+
+ _filter_count = extension_index;
+ _filter_index = 2; // Select the 2nd filter in the list - 2 is NOT the 3rd
}
void FileOpenDialogImplWin32::GetOpenFileName_thread()
OPENFILENAMEEXW ofn;
g_assert(this != NULL);
- //g_assert(_mutex != NULL);
- g_assert(_main_loop != NULL);
-
+ g_assert(_mutex != NULL);
+
WCHAR* current_directory_string = (WCHAR*)g_utf8_to_utf16(
- _current_directory.data(), -1, NULL, NULL, NULL);
+ _current_directory.data(), _current_directory.length(),
+ NULL, NULL, NULL);
memset(&ofn, 0, sizeof(ofn));
ofn.lpstrTitle = _title;
ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST | OFN_EXPLORER | OFN_ENABLEHOOK | OFN_HIDEREADONLY | OFN_ENABLESIZING;
ofn.lpstrFilter = _filter;
- ofn.nFilterIndex = _filterIndex;
+ ofn.nFilterIndex = _filter_index;
ofn.lpfnHook = GetOpenFileName_hookproc;
ofn.lCustData = (LPARAM)this;
_result = GetOpenFileNameW(&ofn) != 0;
- _filterIndex = ofn.nFilterIndex;
- _extension = _extension_map[ofn.nFilterIndex];
-
- myFilename = utf16_to_ustring(_path_string, _MAX_PATH);
+ g_assert(ofn.nFilterIndex >= 1 && ofn.nFilterIndex <= _filter_count);
+ _filter_index = ofn.nFilterIndex;
+ _extension = _extension_map[ofn.nFilterIndex - 1];
// Copy the selected file name, converting from UTF-16 to UTF-8
myFilename = utf16_to_ustring(_path_string, _MAX_PATH);
_mutex->lock();
_finished = true;
_mutex->unlock();
- //g_main_loop_quit(_main_loop);
-
-
}
void FileOpenDialogImplWin32::register_preview_wnd_class()
pImpl->_file_dialog_wnd = hParentWnd;
pImpl->_preview_wnd =
- CreateWindow(PreviewWindowClassName, "",
+ CreateWindowA(PreviewWindowClassName, "",
WS_CHILD | WS_VISIBLE,
0, 0, 100, 100, hParentWnd, NULL, hInstance, NULL);
SetWindowLongPtr(pImpl->_preview_wnd, GWLP_USERDATA, ofn->lCustData);
pImpl->_file_selected = true;
pImpl->_mutex->unlock();
-
- //pImpl->file_selected();
}
}
break;
@@ -559,7 +559,6 @@ LRESULT CALLBACK FileOpenDialogImplWin32::preview_wnd_proc(HWND hwnd, UINT uMsg,
pImpl->_mutex->lock();
- //FillRect(dc, &client_rect, (HBRUSH)(COLOR_HOTLIGHT+1));
if(pImpl->_path_string[0] == 0)
{
FillRect(dc, &rcClient, (HBRUSH)(COLOR_3DFACE + 1));
// Prepare to render a preview
const Glib::ustring svg = ".svg";
const Glib::ustring svgz = ".svgz";
+ const Glib::ustring emf = ".emf";
+ const Glib::ustring wmf = ".wmf";
const Glib::ustring path = utf16_to_ustring(_path_string);
bool success = false;
if ((dialogType == SVG_TYPES || dialogType == IMPORT_TYPES) &&
(hasSuffix(path, svg) || hasSuffix(path, svgz)))
success = set_svg_preview();
+ else if (hasSuffix(path, emf) || hasSuffix(path, wmf))
+ success = set_emf_preview();
else if (isValidImageFile(path))
success = set_image_preview();
else {
_preview_file_icon = NULL;
_preview_bitmap_image.clear();
+ _preview_emf_image = false;
_mutex->unlock();
}
NR::Maybe<NR::Rect> maybeArea(area);
sp_document_ensure_up_to_date (svgDoc);
sp_item_invoke_bbox((SPItem *) svgDoc->root, &maybeArea,
- sp_item_i2r_affine((SPItem *)(svgDoc->root)), TRUE);
+ from_2geom(sp_item_i2r_affine((SPItem *)(svgDoc->root))), TRUE);
NRArena *const arena = NRArena::create();
arena, key, SP_ITEM_SHOW_DISPLAY);
NRGC gc(NULL);
- nr_matrix_set_scale(&gc.transform, scaleFactor, scaleFactor);
+ gc.transform = NR::Matrix(NR::scale(scaleFactor, scaleFactor));
nr_arena_item_invoke_update (root, NULL, &gc,
NR_ARENA_ITEM_STATE_ALL, NR_ARENA_ITEM_STATE_NONE);
{
const Glib::ustring path = utf16_to_ustring(_path_string, _MAX_PATH);
+ bool successful = false;
+
_mutex->lock();
- _preview_bitmap_image = Gdk::Pixbuf::create_from_file(path);
- if(!_preview_bitmap_image) return false;
- _preview_image_width = _preview_bitmap_image->get_width();
- _preview_document_width = _preview_image_width;
- _preview_image_height = _preview_bitmap_image->get_height();
- _preview_document_height = _preview_image_height;
+ try {
+ _preview_bitmap_image = Gdk::Pixbuf::create_from_file(path);
+ if (_preview_bitmap_image) {
+ _preview_image_width = _preview_bitmap_image->get_width();
+ _preview_document_width = _preview_image_width;
+ _preview_image_height = _preview_bitmap_image->get_height();
+ _preview_document_height = _preview_image_height;
+ successful = true;
+ }
+ }
+ catch (const Gdk::PixbufError&) {}
+ catch (const Glib::FileError&) {}
_mutex->unlock();
- return true;
+ return successful;
+}
+
+// Aldus Placeable Header ===================================================
+// Since we are a 32bit app, we have to be sure this structure compiles to
+// be identical to a 16 bit app's version. To do this, we use the #pragma
+// to adjust packing, we use a WORD for the hmf handle, and a SMALL_RECT
+// for the bbox rectangle.
+#pragma pack( push )
+#pragma pack( 2 )
+typedef struct
+{
+ DWORD dwKey;
+ WORD hmf;
+ SMALL_RECT bbox;
+ WORD wInch;
+ DWORD dwReserved;
+ WORD wCheckSum;
+} APMHEADER, *PAPMHEADER;
+#pragma pack( pop )
+
+
+static HENHMETAFILE
+MyGetEnhMetaFileW( const WCHAR *filename )
+{
+ // Try open as Enhanced Metafile
+ HENHMETAFILE hemf = GetEnhMetaFileW(filename);
+
+ if (!hemf) {
+ // Try open as Windows Metafile
+ HMETAFILE hmf = GetMetaFileW(filename);
+
+ METAFILEPICT mp;
+ HDC hDC;
+
+ if (!hmf) {
+ WCHAR szTemp[MAX_PATH];
+
+ DWORD dw = GetShortPathNameW( filename, szTemp, MAX_PATH );
+ if (dw) {
+ hmf = GetMetaFileW( szTemp );
+ }
+ }
+
+ if (hmf) {
+ // Convert Windows Metafile to Enhanced Metafile
+ DWORD nSize = GetMetaFileBitsEx( hmf, 0, NULL );
+
+ if (nSize) {
+ BYTE *lpvData = new BYTE[nSize];
+ if (lpvData) {
+ DWORD dw = GetMetaFileBitsEx( hmf, nSize, lpvData );
+ if (dw) {
+ // Fill out a METAFILEPICT structure
+ mp.mm = MM_ANISOTROPIC;
+ mp.xExt = 1000;
+ mp.yExt = 1000;
+ mp.hMF = NULL;
+ // Get a reference DC
+ hDC = GetDC( NULL );
+ // Make an enhanced metafile from the windows metafile
+ hemf = SetWinMetaFileBits( nSize, lpvData, hDC, &mp );
+ // Clean up
+ ReleaseDC( NULL, hDC );
+ DeleteMetaFile( hmf );
+ }
+ delete[] lpvData;
+ }
+ else {
+ DeleteMetaFile( hmf );
+ }
+ }
+ else {
+ DeleteMetaFile( hmf );
+ }
+ }
+ else {
+ // Try open as Aldus Placeable Metafile
+ HANDLE hFile;
+ hFile = CreateFileW( filename, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
+
+ if (hFile != INVALID_HANDLE_VALUE) {
+ DWORD nSize = GetFileSize( hFile, NULL );
+ if (nSize) {
+ BYTE *lpvData = new BYTE[nSize];
+ if (lpvData) {
+ DWORD dw = ReadFile( hFile, lpvData, nSize, &nSize, NULL );
+ if (dw) {
+ if ( ((PAPMHEADER)lpvData)->dwKey == 0x9ac6cdd7l ) {
+ // Fill out a METAFILEPICT structure
+ mp.mm = MM_ANISOTROPIC;
+ mp.xExt = ((PAPMHEADER)lpvData)->bbox.Right - ((PAPMHEADER)lpvData)->bbox.Left;
+ mp.xExt = ( mp.xExt * 2540l ) / (DWORD)(((PAPMHEADER)lpvData)->wInch);
+ mp.yExt = ((PAPMHEADER)lpvData)->bbox.Bottom - ((PAPMHEADER)lpvData)->bbox.Top;
+ mp.yExt = ( mp.yExt * 2540l ) / (DWORD)(((PAPMHEADER)lpvData)->wInch);
+ mp.hMF = NULL;
+ // Get a reference DC
+ hDC = GetDC( NULL );
+ // Create an enhanced metafile from the bits
+ hemf = SetWinMetaFileBits( nSize, lpvData+sizeof(APMHEADER), hDC, &mp );
+ // Clean up
+ ReleaseDC( NULL, hDC );
+ }
+ }
+ delete[] lpvData;
+ }
+ }
+ CloseHandle( hFile );
+ }
+ }
+ }
+
+ return hemf;
+}
+
+
+bool FileOpenDialogImplWin32::set_emf_preview()
+{
+ _mutex->lock();
+
+ BOOL ok = FALSE;
+
+ DWORD w = 0;
+ DWORD h = 0;
+
+ HENHMETAFILE hemf = MyGetEnhMetaFileW( _path_string );
+
+ if (hemf)
+ {
+ ENHMETAHEADER emh;
+ ZeroMemory(&emh, sizeof(emh));
+ ok = GetEnhMetaFileHeader(hemf, sizeof(emh), &emh) != 0;
+
+ w = (emh.rclFrame.right - emh.rclFrame.left);
+ h = (emh.rclFrame.bottom - emh.rclFrame.top);
+
+ DeleteEnhMetaFile(hemf);
+ }
+
+ if (ok)
+ {
+ const int PreviewSize = 512;
+
+ // Get the size of the document
+ const double emfWidth = w;
+ const double emfHeight = h;
+
+ // Find the minimum scale to fit the image inside the preview area
+ const double scaleFactorX = PreviewSize / emfWidth;
+ const double scaleFactorY = PreviewSize / emfHeight;
+ const double scaleFactor = (scaleFactorX > scaleFactorY) ? scaleFactorY : scaleFactorX;
+
+ // Now get the resized values
+ const double scaledEmfWidth = scaleFactor * emfWidth;
+ const double scaledEmfHeight = scaleFactor * emfHeight;
+
+ _preview_document_width = scaledEmfWidth;
+ _preview_document_height = scaledEmfHeight;
+ _preview_image_width = emfWidth;
+ _preview_image_height = emfHeight;
+
+ _preview_emf_image = true;
+ }
+
+ _mutex->unlock();
+
+ return ok;
}
void FileOpenDialogImplWin32::render_preview()
// Do we have anything to render?
_mutex->lock();
- if(!_preview_bitmap_image)
+ if(!_preview_bitmap_image && !_preview_emf_image)
{
_mutex->unlock();
return;
context->stroke_preserve();
// Draw the image
-
if(_preview_bitmap_image) // Is the image a pixbuf?
{
// Set the transformation
// Finish drawing
surface->finish();
+
+ if (_preview_emf_image) {
+ HENHMETAFILE hemf = MyGetEnhMetaFileW(_path_string);
+ if (hemf) {
+ RECT rc;
+ rc.top = svgY+2;
+ rc.left = svgX+2;
+ rc.bottom = scaledSvgHeight-2;
+ rc.right = scaledSvgWidth-2;
+ PlayEnhMetaFile(hMemDC, hemf, &rc);
+ DeleteEnhMetaFile(hemf);
+ }
+ }
+
SelectObject(hMemDC, hOldBitmap) ;
DeleteDC(hMemDC);
FileOpenDialogImplWin32::show()
{
// We can only run one worker thread at a time
- //if(_mutex != NULL) return false;
+ if(_mutex != NULL) return false;
if(!Glib::thread_supported())
Glib::thread_init();
Sleep(10);
}
- //g_main_loop_run(_main_loop);
}
// Tidy up
const Glib::ustring &/*default_key*/) :
FileDialogBaseWin32(parent, dir, title, fileTypes, "dialogs.save_as")
{
- _main_loop = NULL;
-
createFilterMenu();
}
Inkscape::Extension::db.get_output_list(extension_list);
int filter_count = 0;
- int filter_length = 0;
+ int filter_length = 1;
for (Inkscape::Extension::DB::OutputList::iterator current_item = extension_list.begin();
current_item != extension_list.end(); current_item++)
// Type
filter.name = g_utf8_to_utf16(
- omod->get_filetypename(), -1, NULL, &filter.name_length, NULL);
+ _(omod->get_filetypename()), -1, NULL, &filter.name_length, NULL);
filter.mod = omod;
{
const Filter &filter = *filter_iterator;
- memcpy(filterptr, filter.name, filter.name_length * 2);
+ wcsncpy(filterptr, (wchar_t*)filter.name, filter.name_length);
filterptr += filter.name_length;
g_free(filter.name);
*(filterptr++) = L'\0';
*(filterptr++) = L'*';
- memcpy(filterptr, filter.filter, filter.filter_length * 2);
+ wcsncpy(filterptr, (wchar_t*)filter.filter, filter.filter_length);
filterptr += filter.filter_length;
g_free(filter.filter);
}
*(filterptr++) = 0;
- _filterIndex = 0;
+ _filter_count = extension_index;
+ _filter_index = 1; // A value of 1 selects the 1st filter - NOT the 2nd
}
void FileSaveDialogImplWin32::GetSaveFileName_thread()
OPENFILENAMEEXW ofn;
g_assert(this != NULL);
- //g_assert(_mutex != NULL);
g_assert(_main_loop != NULL);
- gunichar2* current_directory_string = g_utf8_to_utf16(
- _current_directory.data(), -1, NULL, NULL, NULL);
+ WCHAR* current_directory_string = (WCHAR*)g_utf8_to_utf16(
+ _current_directory.data(), _current_directory.length(),
+ NULL, NULL, NULL);
// Copy the selected file name, converting from UTF-8 to UTF-16
memset(_path_string, 0, sizeof(_path_string));
ofn.hwndOwner = _ownerHwnd;
ofn.lpstrFile = _path_string;
ofn.nMaxFile = _MAX_PATH;
- ofn.nFilterIndex = _filterIndex;
+ ofn.nFilterIndex = _filter_index;
ofn.lpstrFileTitle = NULL;
ofn.nMaxFileTitle = 0;
- ofn.lpstrInitialDir = (wchar_t*)current_directory_string;
+ ofn.lpstrInitialDir = current_directory_string;
ofn.lpstrTitle = _title;
ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;
ofn.lpstrFilter = _filter;
- ofn.nFilterIndex = _filterIndex;
+ ofn.nFilterIndex = _filter_index;
_result = GetSaveFileNameW(&ofn) != 0;
- _filterIndex = ofn.nFilterIndex;
- _extension = _extension_map[ofn.nFilterIndex];
+ g_assert(ofn.nFilterIndex >= 1 && ofn.nFilterIndex <= _filter_count);
+ _filter_index = ofn.nFilterIndex;
+ _extension = _extension_map[ofn.nFilterIndex - 1];
// Copy the selected file name, converting from UTF-16 to UTF-8
myFilename = utf16_to_ustring(_path_string, _MAX_PATH);
- //_mutex->lock();
- //_finished = true;
- //_mutex->unlock();
-
-
// Tidy up
g_free(current_directory_string);
bool
FileSaveDialogImplWin32::show()
{
- // We can only run one worker thread at a time
- //if(_mutex != NULL) return false;
-
if(!Glib::thread_supported())
Glib::thread_init();
_result = false;
- //_finished = false;
- //_mutex = new Glib::Mutex();
_main_loop = g_main_loop_new(g_main_context_default(), FALSE);
-
- if(Glib::Thread::create(sigc::mem_fun(*this, &FileSaveDialogImplWin32::GetSaveFileName_thread), true))
- {
- /*while(1)
- {
- // While the dialog runs - keep the main UI alive
- g_main_context_iteration(g_main_context_default(), FALSE);
-
- if(_mutex->trylock())
- {
- if(_finished) break;
- _mutex->unlock();
- }
-
- Sleep(10);
- }*/
- g_main_loop_run(_main_loop);
- }
- //delete _mutex;
- //_mutex = NULL;
-
- if(_result)
- appendExtension(myFilename, (Inkscape::Extension::Output*)_extension);
-
+
+ if(_main_loop != NULL)
+ {
+ if(Glib::Thread::create(sigc::mem_fun(*this, &FileSaveDialogImplWin32::GetSaveFileName_thread), true))
+ g_main_loop_run(_main_loop);
+
+ if(_result)
+ appendExtension(myFilename, (Inkscape::Extension::Output*)_extension);
+ }
+
return _result;
}