summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: e04817c)
raw | patch | inline | side by side (parent: e04817c)
author | joelholdsworth <joelholdsworth@users.sourceforge.net> | |
Sat, 23 Feb 2008 12:56:59 +0000 (12:56 +0000) | ||
committer | joelholdsworth <joelholdsworth@users.sourceforge.net> | |
Sat, 23 Feb 2008 12:56:59 +0000 (12:56 +0000) |
src/dialogs/filedialog-win32.cpp | [deleted file] | patch | blob | history |
src/file.cpp | patch | blob | history | |
src/inkscape.rc | patch | blob | history | |
src/inkview.rc | patch | blob | history | |
src/ui/dialog/filedialog.cpp | patch | blob | history | |
src/ui/dialog/filedialog.h | patch | blob | history | |
src/ui/dialog/filedialogimpl-gtkmm.cpp | patch | blob | history | |
src/ui/dialog/filedialogimpl-gtkmm.h | patch | blob | history | |
src/ui/dialog/filedialogimpl-win32.cpp | [new file with mode: 0644] | patch | blob |
src/ui/dialog/filedialogimpl-win32.h | [new file with mode: 0644] | patch | blob |
diff --git a/src/dialogs/filedialog-win32.cpp b/src/dialogs/filedialog-win32.cpp
+++ /dev/null
@@ -1,381 +0,0 @@
-
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
-#include "filedialog.h"
-
-//#include "extension/internal/win32.h"
-
-#include <windows.h>
-
-#include <glib.h>
-
-#include <extension/extension.h>
-#include <extension/db.h>
-
-#define UNSAFE_SCRATCH_BUFFER_SIZE 4096
-
-namespace Inkscape
-{
-namespace UI
-{
-namespace Dialogs
-{
-
-/*#################################
-# U T I L I T Y
-#################################*/
-static gboolean
-win32_is_os_wide()
-{
- static gboolean initialized = FALSE;
- static gboolean is_wide = FALSE;
- static OSVERSIONINFOA osver;
-
- if ( !initialized )
- {
- BOOL result;
-
- initialized = TRUE;
-
- memset (&osver, 0, sizeof(OSVERSIONINFOA));
- osver.dwOSVersionInfoSize = sizeof(OSVERSIONINFOA);
- result = GetVersionExA (&osver);
- if (result)
- {
- if (osver.dwPlatformId == VER_PLATFORM_WIN32_NT)
- is_wide = TRUE;
- }
- // If we can't even call to get the version, fall back to ANSI API
- }
-
- return is_wide;
-}
-
-/*#################################
-# F I L E O P E N
-#################################*/
-
-struct FileOpenNativeData_def {
- char *dir;
- FileDialogType fileTypes;
- char *title;
-};
-
-FileOpenDialog::FileOpenDialog(
- const char *dir, FileDialogType fileTypes, const char *title) {
-
- nativeData = (FileOpenNativeData *)
- g_malloc(sizeof (FileOpenNativeData));
- if ( !nativeData ) {
- // do we want exceptions?
- return;
- }
-
- if ( !dir )
- dir = "";
- nativeData->dir = g_strdup(dir);
- nativeData->fileTypes = fileTypes;
- nativeData->title = g_strdup(title);
-
- extension = NULL;
- filename = NULL;
-}
-
-
-
-FileOpenDialog::~FileOpenDialog() {
-
- //do any cleanup here
- if ( nativeData ) {
- g_free(nativeData->dir);
- g_free(nativeData->title);
- g_free(nativeData);
- }
-
- if (filename) g_free(filename);
- extension = NULL;
-}
-
-
-
-bool
-FileOpenDialog::show() {
-
- if ( !nativeData ) {
- //error
- return FALSE;
- }
-
- gint retval = FALSE;
-
-
- //Jon's UNICODE patch
- if ( win32_is_os_wide() ) {
- gunichar2 fnbufW[UNSAFE_SCRATCH_BUFFER_SIZE * sizeof(gunichar2)] = {0};
- gunichar2* dirW =
- g_utf8_to_utf16( nativeData->dir, -1, NULL, NULL, NULL );
- gunichar2 *filterW = (gunichar2 *) L"";
- if ( nativeData->fileTypes == SVG_TYPES )
- filterW = (gunichar2 *) L"SVG files\0*.svg;*.svgz\0All files\0*\0";
- else if ( nativeData->fileTypes == IMPORT_TYPES )
- filterW = (gunichar2 *) L"Image files\0*.svg;*.png;*.jpg;*.jpeg;*.bmp;*.gif;*.tiff;*.xpm\0"
- L"SVG files\0*.svg\0"
- L"All files\0*\0";
- gunichar2* titleW =
- g_utf8_to_utf16( nativeData->title, -1, NULL, NULL, NULL );
- OPENFILENAMEW ofn = {
- sizeof (OPENFILENAMEW),
- NULL, // hwndOwner
- NULL, // hInstance
- (const WCHAR *)filterW, // lpstrFilter
- NULL, // lpstrCustomFilter
- 0, // nMaxCustFilter
- 1, // nFilterIndex
- (WCHAR *)fnbufW, // lpstrFile
- sizeof (fnbufW) / sizeof(WCHAR), // nMaxFile
- NULL, // lpstrFileTitle
- 0, // nMaxFileTitle
- (const WCHAR *)dirW, // lpstrInitialDir
- (const WCHAR *)titleW, // lpstrTitle
- OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST | OFN_HIDEREADONLY | OFN_NOCHANGEDIR, // Flags
- 0, // nFileOffset
- 0, // nFileExtension
- NULL, // lpstrDefExt
- 0, // lCustData
- NULL, // lpfnHook
- NULL // lpTemplateName
- };
-
- retval = GetOpenFileNameW (&ofn);
- if (retval)
- filename = g_utf16_to_utf8( fnbufW, -1, NULL, NULL, NULL );
-
- g_free( dirW );
- g_free( titleW );
-
- } else {
- gchar *dir = nativeData->dir;
- gchar *title = nativeData->title;
- gchar fnbuf[UNSAFE_SCRATCH_BUFFER_SIZE] = {0};
-
- gchar *filter = "";
- if ( nativeData->fileTypes == SVG_TYPES )
- filter = "SVG files\0*.svg;*.svgz\0All files\0*\0";
- else if ( nativeData->fileTypes == IMPORT_TYPES )
- filter = "Image files\0*.svg;*.png;*.jpg;*.jpeg;*.bmp;*.gif;*.tiff;*.xpm\0"
- "SVG files\0*.svg\0"
- "All files\0*\0";
-
- OPENFILENAMEA ofn = {
- sizeof (OPENFILENAMEA),
- NULL, // hwndOwner
- NULL, // hInstance
- (const CHAR *)filter, // lpstrFilter
- NULL, // lpstrCustomFilter
- 0, // nMaxCustFilter
- 1, // nFilterIndex
- fnbuf, // lpstrFile
- sizeof (fnbuf), // nMaxFile
- NULL, // lpstrFileTitle
- 0, // nMaxFileTitle
- (const CHAR *)dir, // lpstrInitialDir
- (const CHAR *)title, // lpstrTitle
- OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST | OFN_HIDEREADONLY | OFN_NOCHANGEDIR, // Flags
- 0, // nFileOffset
- 0, // nFileExtension
- NULL, // lpstrDefExt
- 0, // lCustData
- NULL, // lpfnHook
- NULL // lpTemplateName
- };
-
- retval = GetOpenFileNameA (&ofn);
- if ( retval ) {
- filename = g_strdup( fnbuf );
- /* ### We need to try something like this instead:
- GError *err = NULL;
- filename = g_filename_to_utf8(fnbuf, -1, NULL, NULL, &err);
- if ( !filename && err ) {
- g_warning("Charset conversion in show()[%d]%s\n",
- err->code, err->message);
- }
- */
- }
- }
-
- if ( !retval ) {
- //int errcode = CommDlgExtendedError();
- return FALSE;
- }
-
- return TRUE;
-
-}
-
-
-
-/*#################################
-# F I L E S A V E
-#################################*/
-
-struct FileSaveNativeData_def {
- OPENFILENAME ofn;
- gchar filter[UNSAFE_SCRATCH_BUFFER_SIZE];
- gchar fnbuf[4096];
-};
-
-
-
-FileSaveDialog::FileSaveDialog(
- const char *dir, FileDialogType fileTypes, const char *title, const char * default_key) {
-
- nativeData = (FileSaveNativeData *)
- g_malloc(sizeof (FileSaveNativeData));
- if ( !nativeData ) {
- //do we want exceptions?
- return;
- }
-
- extension = NULL;
- filename = NULL;
-
- int default_item = 0;
-
- GSList* extension_list = Inkscape::Extension::db.get_output_list();
- g_assert (extension_list != NULL);
-
- /* Make up the filter string for the save dialogue using the list
- ** of available output types.
- */
-
- gchar *p = nativeData->filter;
- int N = UNSAFE_SCRATCH_BUFFER_SIZE;
-
- int n = 1;
- for (GSList* i = g_slist_next (extension_list); i != NULL; i = g_slist_next(i)) {
-
- Inkscape::Extension::DB::IOExtensionDescription* d =
- reinterpret_cast<Inkscape::Extension::DB::IOExtensionDescription*>(i->data);
-
- if (!d->sensitive)
- continue;
-
- int w = snprintf (p, N, "%s", d->name);
- N -= w + 1;
- p += w + 1;
-
- w = snprintf (p, N, "*");
- N -= w + 1;
- p += w + 1;
-
- g_assert (N >= 0);
-
- /* Look to see if this extension is the default */
- if (default_key &&
- d->extension->get_id() &&
- strcmp (default_key, d->extension->get_id()) == 0) {
- default_item = n;
- extension = d->extension;
- }
-
- n++;
- }
-
- *p = '\0';
-
- nativeData->fnbuf[0] = '\0';
-
- if (dir) {
- /* We must check that dir is not something like
- ** c:\foo\ (ie with a trailing \). If it is,
- ** GetSaveFileName will give an error.
- */
- int n = strlen(dir);
- if (n > 0 && dir[n - 1] != '\\') {
- strncpy(nativeData->fnbuf, dir, sizeof(nativeData->fnbuf));
- }
- }
-
- OPENFILENAME ofn = {
- sizeof (OPENFILENAME),
- NULL, // hwndOwner
- NULL, // hInstance
- nativeData->filter, // lpstrFilter
- NULL, // lpstrCustomFilter
- 0, // nMaxCustFilter
- default_item, // nFilterIndex
- nativeData->fnbuf, // lpstrFile
- sizeof (nativeData->fnbuf), // nMaxFile
- NULL, // lpstrFileTitle
- 0, // nMaxFileTitle
- (const CHAR *)dir, // lpstrInitialDir
- (const CHAR *)title, // lpstrTitle
- OFN_HIDEREADONLY | OFN_NOCHANGEDIR, // Flags
- 0, // nFileOffset
- 0, // nFileExtension
- NULL, // lpstrDefExt
- 0, // lCustData
- NULL, // lpfnHook
- NULL // lpTemplateName
- };
-
- nativeData->ofn = ofn;
-}
-
-FileSaveDialog::~FileSaveDialog() {
-
- //do any cleanup here
- g_free(nativeData);
- if (filename) g_free(filename);
- extension = NULL;
-}
-
-bool
-FileSaveDialog::show() {
-
- if (!nativeData)
- return FALSE;
- int retval = GetSaveFileName (&(nativeData->ofn));
- if (!retval) {
- //int errcode = CommDlgExtendedError();
- return FALSE;
- }
-
- GSList* extension_list = Inkscape::Extension::db.get_output_list();
- g_assert (extension_list != NULL);
-
- /* Work out which extension corresponds to the user's choice of
- ** file type.
- */
- int n = nativeData->ofn.nFilterIndex - 1;
- GSList* i = g_slist_next (extension_list);
-
- while (n > 0 && i) {
- n--;
- i = g_slist_next(i);
- }
-
- Inkscape::Extension::DB::IOExtensionDescription* d =
- reinterpret_cast<Inkscape::Extension::DB::IOExtensionDescription*>(i->data);
-
- extension = d->extension;
-
- filename = g_strdup (nativeData->fnbuf);
- return TRUE;
-}
-
-
-
-
-
-
-
-
-} //namespace Dialogs
-} //namespace UI
-} //namespace Inkscape
-
-
-
-
diff --git a/src/file.cpp b/src/file.cpp
index c3e7e7583998a89df4d358d6ed57ca219306c5d8..b41d61426f831c51ba496679f2f8a87b52320904 100644 (file)
--- a/src/file.cpp
+++ b/src/file.cpp
g_message("---------------");
}
g_message("---------------");
}
-static Inkscape::UI::Dialog::FileOpenDialog *openDialogInstance = NULL;
-
/**
* Display an file Open selector. Open a document if OK is pressed.
* Can select single or multiple files for opening.
/**
* Display an file Open selector. Open a document if OK is pressed.
* Can select single or multiple files for opening.
void
sp_file_open_dialog(Gtk::Window &parentWindow, gpointer /*object*/, gpointer /*data*/)
{
void
sp_file_open_dialog(Gtk::Window &parentWindow, gpointer /*object*/, gpointer /*data*/)
{
-
//# Get the current directory for finding files
//# Get the current directory for finding files
- Glib::ustring open_path;
- char *attr = (char *)prefs_get_string_attribute("dialogs.open", "path");
- if (attr)
- open_path = attr;
-
-
+ static Glib::ustring open_path;
+
+ if(open_path.empty())
+ {
+ gchar const *attr = prefs_get_string_attribute("dialogs.open", "path");
+ if (attr)
+ open_path = attr;
+ }
+
//# Test if the open_path directory exists
if (!Inkscape::IO::file_test(open_path.c_str(),
(GFileTest)(G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR)))
open_path = "";
//# Test if the open_path directory exists
if (!Inkscape::IO::file_test(open_path.c_str(),
(GFileTest)(G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR)))
open_path = "";
-
+
//# If no open path, default to our home directory
//# If no open path, default to our home directory
- if (open_path.size() < 1)
- {
+ if (open_path.empty())
+ {
open_path = g_get_home_dir();
open_path.append(G_DIR_SEPARATOR_S);
open_path = g_get_home_dir();
open_path.append(G_DIR_SEPARATOR_S);
- }
-
+ }
+
//# Create a dialog if we don't already have one
//# Create a dialog if we don't already have one
- if (!openDialogInstance) {
- openDialogInstance =
+ Inkscape::UI::Dialog::FileOpenDialog *openDialogInstance =
Inkscape::UI::Dialog::FileOpenDialog::create(
Inkscape::UI::Dialog::FileOpenDialog::create(
- parentWindow,
- open_path,
+ parentWindow, open_path,
Inkscape::UI::Dialog::SVG_TYPES,
Inkscape::UI::Dialog::SVG_TYPES,
- (char const *)_("Select file to open"));
- }
-
-
+ _("Select file to open"));
+
//# Show the dialog
bool const success = openDialogInstance->show();
//# Show the dialog
bool const success = openDialogInstance->show();
+
+ //# Save the folder the user selected for later
+ open_path = openDialogInstance->getCurrentDirectory();
+
if (!success)
if (!success)
+ {
+ delete openDialogInstance;
return;
return;
-
+ }
+
//# User selected something. Get name and type
Glib::ustring fileName = openDialogInstance->getFilename();
//# User selected something. Get name and type
Glib::ustring fileName = openDialogInstance->getFilename();
+
Inkscape::Extension::Extension *selection =
openDialogInstance->getSelectionType();
Inkscape::Extension::Extension *selection =
openDialogInstance->getSelectionType();
-
- //# Code to check & open iff multiple files.
- std::vector<Glib::ustring> flist=openDialogInstance->getFilenames();
-
+
+ //# Code to check & open if multiple files.
+ std::vector<Glib::ustring> flist = openDialogInstance->getFilenames();
+
+ //# We no longer need the file dialog object - delete it
+ delete openDialogInstance;
+ openDialogInstance = NULL;
+
//# Iterate through filenames if more than 1
if (flist.size() > 1)
//# Iterate through filenames if more than 1
if (flist.size() > 1)
+ {
+ for (unsigned int i = 0; i < flist.size(); i++)
{
{
- for (unsigned int i=1 ; i<flist.size() ; i++)
- {
- Glib::ustring fName = flist[i];
-
- if (Glib::file_test(fileName, Glib::FILE_TEST_IS_DIR)) {
- Glib::ustring newFileName = Glib::filename_to_utf8(fName);
+ fileName = flist[i];
+
+ Glib::ustring newFileName = Glib::filename_to_utf8(fileName);
if ( newFileName.size() > 0 )
if ( newFileName.size() > 0 )
- fName = newFileName;
+ fileName = newFileName;
else
g_warning( "ERROR CONVERTING OPEN FILENAME TO UTF-8" );
#ifdef INK_DUMP_FILENAME_CONV
else
g_warning( "ERROR CONVERTING OPEN FILENAME TO UTF-8" );
#ifdef INK_DUMP_FILENAME_CONV
- g_message("Opening File %s\n",fileName);
+ g_message("Opening File %s\n", fileName.c_str());
#endif
sp_file_open(fileName, selection);
#endif
sp_file_open(fileName, selection);
- }
}
}
+
return;
}
return;
}
- if (fileName.size() > 0) {
-
+ if (!fileName.empty())
+ {
Glib::ustring newFileName = Glib::filename_to_utf8(fileName);
if ( newFileName.size() > 0)
Glib::ustring newFileName = Glib::filename_to_utf8(fileName);
if ( newFileName.size() > 0)
if ( save_loc_local.size() > 0)
save_loc = save_loc_local;
if ( save_loc_local.size() > 0)
save_loc = save_loc_local;
-
+
//# Show the SaveAs dialog
char const * dialog_title;
if (is_copy) {
//# Show the SaveAs dialog
char const * dialog_title;
if (is_copy) {
parentWindow,
save_loc,
Inkscape::UI::Dialog::SVG_TYPES,
parentWindow,
save_loc,
Inkscape::UI::Dialog::SVG_TYPES,
- (char const *) _("Select file to save to"),
+ dialog_title,
default_extension
);
default_extension
);
-
- saveDialog->change_title(dialog_title);
+
saveDialog->setSelectionType(extension);
saveDialog->setSelectionType(extension);
-
- // allow easy access to the user's own templates folder
- gchar *templates = profile_path ("templates");
- if (Inkscape::IO::file_test(templates, (GFileTest)(G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR))) {
- dynamic_cast<Gtk::FileChooser *>(saveDialog)->add_shortcut_folder(templates);
- }
- g_free (templates);
-
+
bool success = saveDialog->show();
if (!success) {
delete saveDialog;
bool success = saveDialog->show();
if (!success) {
delete saveDialog;
diff --git a/src/inkscape.rc b/src/inkscape.rc
index 3e5b61548451bdfc51861a844034775ecf8bedfc..d48b68c431aa34da9ce9f13a192657832f13334e 100644 (file)
--- a/src/inkscape.rc
+++ b/src/inkscape.rc
VALUE "Translation", 1033, 437
END
END
VALUE "Translation", 1033, 437
END
END
+
+1000 BITMAP "./show-preview.bmp"
+
diff --git a/src/inkview.rc b/src/inkview.rc
index 245bdc68b740afbf43680c071af2045cf9b662fb..9f643eb4c910b3efcac151a1c851a96cdd841734 100644 (file)
--- a/src/inkview.rc
+++ b/src/inkview.rc
VALUE "Translation", 1033, 437\r
END\r
END\r
VALUE "Translation", 1033, 437\r
END\r
END\r
+\r
+1000 BITMAP "./show-preview.bmp"\r
index c3ca49c992de5178430774de6971eb3a92665989..103b624858750712004b3a8ec20b8e9f0e28f80c 100644 (file)
#include "filedialog.h"
#include "filedialogimpl-gtkmm.h"
#include "filedialog.h"
#include "filedialogimpl-gtkmm.h"
+#include "filedialogimpl-win32.h"
#include "gc-core.h"
#include <dialogs/dialog-events.h>
#include "gc-core.h"
#include <dialogs/dialog-events.h>
namespace Dialog
{
namespace Dialog
{
+/*#########################################################################
+### U T I L I T Y
+#########################################################################*/
+
+bool hasSuffix(const Glib::ustring &str, const Glib::ustring &ext)
+{
+ int strLen = str.length();
+ int extLen = ext.length();
+ if (extLen > strLen)
+ return false;
+ int strpos = strLen-1;
+ for (int extpos = extLen-1 ; extpos>=0 ; extpos--, strpos--)
+ {
+ Glib::ustring::value_type ch = str[strpos];
+ if (ch != ext[extpos])
+ {
+ if ( ((ch & 0xff80) != 0) ||
+ static_cast<Glib::ustring::value_type>( g_ascii_tolower( static_cast<gchar>(0x07f & ch) ) ) != ext[extpos] )
+ {
+ return false;
+ }
+ }
+ }
+ return true;
+}
+
+bool isValidImageFile(const Glib::ustring &fileName)
+{
+ std::vector<Gdk::PixbufFormat>formats = Gdk::Pixbuf::get_formats();
+ for (unsigned int i=0; i<formats.size(); i++)
+ {
+ Gdk::PixbufFormat format = formats[i];
+ std::vector<Glib::ustring>extensions = format.get_extensions();
+ for (unsigned int j=0; j<extensions.size(); j++)
+ {
+ Glib::ustring ext = extensions[j];
+ if (hasSuffix(fileName, ext))
+ return true;
+ }
+ }
+ return false;
+}
+
/*#########################################################################
### F I L E O P E N
#########################################################################*/
/*#########################################################################
### F I L E O P E N
#########################################################################*/
FileOpenDialog *FileOpenDialog::create(Gtk::Window &parentWindow,
const Glib::ustring &path,
FileDialogType fileTypes,
FileOpenDialog *FileOpenDialog::create(Gtk::Window &parentWindow,
const Glib::ustring &path,
FileDialogType fileTypes,
- const Glib::ustring &title)
+ const char *title)
{
{
+#ifdef WIN32
+ FileOpenDialog *dialog = new FileOpenDialogImplWin32(parentWindow, path, fileTypes, title);
+#else
FileOpenDialog *dialog = new FileOpenDialogImplGtk(parentWindow, path, fileTypes, title);
FileOpenDialog *dialog = new FileOpenDialogImplGtk(parentWindow, path, fileTypes, title);
- return dialog;
+#endif
+
+ return dialog;
+}
+
+Glib::ustring FileOpenDialog::getFilename()
+{
+ return myFilename;
}
//########################################################################
}
//########################################################################
FileSaveDialog *FileSaveDialog::create(Gtk::Window& parentWindow,
const Glib::ustring &path,
FileDialogType fileTypes,
FileSaveDialog *FileSaveDialog::create(Gtk::Window& parentWindow,
const Glib::ustring &path,
FileDialogType fileTypes,
- const Glib::ustring &title,
+ const char *title,
const Glib::ustring &default_key)
{
const Glib::ustring &default_key)
{
+#ifdef WIN32
+ FileSaveDialog *dialog = new FileSaveDialogImplWin32(parentWindow, path, fileTypes, title, default_key);
+#else
FileSaveDialog *dialog = new FileSaveDialogImplGtk(parentWindow, path, fileTypes, title, default_key);
FileSaveDialog *dialog = new FileSaveDialogImplGtk(parentWindow, path, fileTypes, title, default_key);
+#endif
return dialog;
}
return dialog;
}
+Glib::ustring FileSaveDialog::getFilename()
+{
+ return myFilename;
+}
+
+//void FileSaveDialog::change_path(const Glib::ustring& path)
+//{
+// myFilename = path;
+//}
+
+void FileSaveDialog::appendExtension(Glib::ustring& path, Inkscape::Extension::Output* outputExtension)
+{
+ try {
+ bool appendExtension = true;
+ Glib::ustring utf8Name = Glib::filename_to_utf8( path );
+ Glib::ustring::size_type pos = utf8Name.rfind('.');
+ if ( pos != Glib::ustring::npos ) {
+ Glib::ustring trail = utf8Name.substr( pos );
+ Glib::ustring foldedTrail = trail.casefold();
+ if ( (trail == ".")
+ | (foldedTrail != Glib::ustring( outputExtension->get_extension() ).casefold()
+ && ( knownExtensions.find(foldedTrail) != knownExtensions.end() ) ) ) {
+ utf8Name = utf8Name.erase( pos );
+ } else {
+ appendExtension = false;
+ }
+ }
+
+ if (appendExtension) {
+ utf8Name = utf8Name + outputExtension->get_extension();
+ myFilename = Glib::filename_from_utf8( utf8Name );
+ }
+ } catch ( Glib::ConvertError& e ) {
+ // ignore
+ }
+}
+
//########################################################################
//# F I L E E X P O R T
//########################################################################
//########################################################################
//# F I L E E X P O R T
//########################################################################
FileExportDialog *FileExportDialog::create(Gtk::Window& parentWindow,
const Glib::ustring &path,
FileDialogType fileTypes,
FileExportDialog *FileExportDialog::create(Gtk::Window& parentWindow,
const Glib::ustring &path,
FileDialogType fileTypes,
- const Glib::ustring &title,
+ const char *title,
const Glib::ustring &default_key)
{
FileExportDialog *dialog = new FileExportDialogImpl(parentWindow, path, fileTypes, title, default_key);
const Glib::ustring &default_key)
{
FileExportDialog *dialog = new FileExportDialogImpl(parentWindow, path, fileTypes, title, default_key);
index 75c6f008073c4517a4dd1c17fd88c6c6f4eb129c..a3d5c0ea9133a59f45017878abd459373d7b3fdc 100644 (file)
#include <glibmm.h>
#include <vector>
#include <glibmm.h>
#include <vector>
+#include <set>
#include <gtkmm.h>
namespace Inkscape {
namespace Extension {
class Extension;
#include <gtkmm.h>
namespace Inkscape {
namespace Extension {
class Extension;
+class Output;
}
}
}
}
-
-
-
namespace Inkscape
{
namespace UI
namespace Inkscape
{
namespace UI
namespace Dialog
{
namespace Dialog
{
-
-
/**
* Used for setting filters and options, and
* reading them back from user selections.
/**
* Used for setting filters and options, and
* reading them back from user selections.
SVG_NAMESPACE_WITH_EXTENSIONS
} FileDialogSelectionType;
SVG_NAMESPACE_WITH_EXTENSIONS
} FileDialogSelectionType;
+
/**
/**
- * Architecture-specific data
+ * Return true if the string ends with the given suffix
*/
*/
-typedef struct FileOpenNativeData_def FileOpenNativeData;
+bool hasSuffix(const Glib::ustring &str, const Glib::ustring &ext);
+/**
+ * Return true if the image is loadable by Gdk, else false
+ */
+bool isValidImageFile(const Glib::ustring &fileName);
+
/**
* This class provides an implementation-independent API for
* file "Open" dialogs. Using a standard interface obviates the need
/**
* This class provides an implementation-independent API for
* file "Open" dialogs. Using a standard interface obviates the need
static FileOpenDialog *create(Gtk::Window& parentWindow,
const Glib::ustring &path,
FileDialogType fileTypes,
static FileOpenDialog *create(Gtk::Window& parentWindow,
const Glib::ustring &path,
FileDialogType fileTypes,
- const Glib::ustring &title);
+ const char *title);
/**
/**
* Show an OpenFile file selector.
* @return the selected path if user selected one, else NULL
*/
* Show an OpenFile file selector.
* @return the selected path if user selected one, else NULL
*/
- virtual bool show() =0;
+ virtual bool show() = 0;
/**
* Return the 'key' (filetype) of the selection, if any
/**
* Return the 'key' (filetype) of the selection, if any
*/
virtual Inkscape::Extension::Extension * getSelectionType() = 0;
*/
virtual Inkscape::Extension::Extension * getSelectionType() = 0;
- virtual Glib::ustring getFilename () =0;
-
- virtual std::vector<Glib::ustring> getFilenames () = 0;
+ Glib::ustring getFilename();
+ virtual std::vector<Glib::ustring> getFilenames() = 0;
+
+ virtual Glib::ustring getCurrentDirectory() = 0;
+
+protected:
+ /**
+ * Filename that was given
+ */
+ Glib::ustring myFilename;
+
}; //FileOpenDialog
}; //FileOpenDialog
* @param key a list of file types from which the user can select
*/
static FileSaveDialog *create(Gtk::Window& parentWindow,
* @param key a list of file types from which the user can select
*/
static FileSaveDialog *create(Gtk::Window& parentWindow,
- const Glib::ustring &path,
+ const Glib::ustring &path,
FileDialogType fileTypes,
FileDialogType fileTypes,
- const Glib::ustring &title,
+ const char *title,
const Glib::ustring &default_key);
const Glib::ustring &default_key);
virtual void setSelectionType( Inkscape::Extension::Extension * key ) = 0;
virtual void setSelectionType( Inkscape::Extension::Extension * key ) = 0;
- virtual Glib::ustring getFilename () =0;
-
/**
/**
- * Change the window title.
+ * Get the file name chosen by the user. Valid after an [OK]
*/
*/
- virtual void change_title(const Glib::ustring& title) =0;
+ Glib::ustring getFilename ();
+
+ virtual Glib::ustring getCurrentDirectory() = 0;
+protected:
+
+ /**
+ * Filename that was given
+ */
+ Glib::ustring myFilename;
+
/**
/**
- * Change the default save path location.
+ * List of known file extensions.
*/
*/
- virtual void change_path(const Glib::ustring& path) =0;
+ std::set<Glib::ustring> knownExtensions;
+
+
+ void appendExtension(Glib::ustring& path, Inkscape::Extension::Output* outputExtension);
}; //FileSaveDialog
}; //FileSaveDialog
* @param key a list of file types from which the user can select
*/
static FileExportDialog *create(Gtk::Window& parentWindow,
* @param key a list of file types from which the user can select
*/
static FileExportDialog *create(Gtk::Window& parentWindow,
- const Glib::ustring &path,
+ const Glib::ustring &path,
FileDialogType fileTypes,
FileDialogType fileTypes,
- const Glib::ustring &title,
+ const char *title,
const Glib::ustring &default_key);
const Glib::ustring &default_key);
index a1773d39a317c36775d91815e5fe0141a5e62cf5..1405e11aa0700c4f62f116c6ab210ee0acbabff4 100644 (file)
}
}
-
-/**
- * Return true if the string ends with the given suffix
- */
-static bool
-hasSuffix(Glib::ustring &str, Glib::ustring &ext)
-{
- int strLen = str.length();
- int extLen = ext.length();
- if (extLen > strLen)
- return false;
- int strpos = strLen-1;
- for (int extpos = extLen-1 ; extpos>=0 ; extpos--, strpos--)
- {
- Glib::ustring::value_type ch = str[strpos];
- if (ch != ext[extpos])
- {
- if ( ((ch & 0xff80) != 0) ||
- static_cast<Glib::ustring::value_type>( g_ascii_tolower( static_cast<gchar>(0x07f & ch) ) ) != ext[extpos] )
- {
- return false;
- }
- }
- }
- return true;
-}
-
-
-/**
- * Return true if the image is loadable by Gdk, else false
- */
-static bool
-isValidImageFile(Glib::ustring &fileName)
-{
- std::vector<Gdk::PixbufFormat>formats = Gdk::Pixbuf::get_formats();
- for (unsigned int i=0; i<formats.size(); i++)
- {
- Gdk::PixbufFormat format = formats[i];
- std::vector<Glib::ustring>extensions = format.get_extensions();
- for (unsigned int j=0; j<extensions.size(); j++)
- {
- Glib::ustring ext = extensions[j];
- if (hasSuffix(fileName, ext))
- return true;
- }
- }
- return false;
-}
-
bool SVGPreview::set(Glib::ustring &fileName, int dialogType)
{
bool SVGPreview::set(Glib::ustring &fileName, int dialogType)
{
return;
}
return;
}
- svgPreview.set(fileName, dialogType);
+ svgPreview.set(fileName, _dialogType);
}
}
const Glib::ustring &dir,
FileDialogType fileTypes,
const Glib::ustring &title) :
const Glib::ustring &dir,
FileDialogType fileTypes,
const Glib::ustring &title) :
- FileDialogBaseGtk(parentWindow, title, fileTypes, "dialogs.open")
+ FileDialogBaseGtk(parentWindow, title, Gtk::FILE_CHOOSER_ACTION_OPEN, fileTypes, "dialogs.open")
{
{
myFilename = "";
/* Set our dialog type (open, import, etc...)*/
myFilename = "";
/* Set our dialog type (open, import, etc...)*/
- dialogType = fileTypes;
+ _dialogType = fileTypes;
/* Set the pwd and/or the filename */
/* Set the pwd and/or the filename */
Glib::ustring
FileOpenDialogImplGtk::getFilename (void)
{
Glib::ustring
FileOpenDialogImplGtk::getFilename (void)
{
- return g_strdup(myFilename.c_str());
+ return myFilename;
}
}
return result;
}
return result;
}
-
+Glib::ustring FileOpenDialogImplGtk::getCurrentDirectory()
+{
+ return get_current_folder();
+}
myFilename = "";
/* Set our dialog type (save, export, etc...)*/
myFilename = "";
/* Set our dialog type (save, export, etc...)*/
- dialogType = fileTypes;
+ _dialogType = fileTypes;
/* Set the pwd and/or the filename */
if (dir.size() > 0)
/* Set the pwd and/or the filename */
if (dir.size() > 0)
expander->set_expanded(true);
}
expander->set_expanded(true);
}
-
+ // allow easy access to the user's own templates folder
+ gchar *templates = profile_path ("templates");
+ if (Inkscape::IO::file_test(templates, (GFileTest)(G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR)))
+ add_shortcut_folder(templates);
+ g_free (templates);
+
+
//if (extension == NULL)
// checkbox.set_sensitive(FALSE);
//if (extension == NULL)
// checkbox.set_sensitive(FALSE);
@@ -1179,22 +1139,17 @@ void FileSaveDialogImplGtk::setSelectionType( Inkscape::Extension::Extension * k
}
}
}
}
-
-/**
- * Get the file name chosen by the user. Valid after an [OK]
- */
-Glib::ustring
-FileSaveDialogImplGtk::getFilename()
+Glib::ustring FileSaveDialogImplGtk::getCurrentDirectory()
{
{
- return myFilename;
+ return get_current_folder();
}
}
-void
+/*void
FileSaveDialogImplGtk::change_title(const Glib::ustring& title)
{
FileSaveDialogImplGtk::change_title(const Glib::ustring& title)
{
- this->set_title(title);
-}
+ set_title(title);
+}*/
/**
* Change the default save path location.
/**
* Change the default save path location.
void
FileSaveDialogImplGtk::change_path(const Glib::ustring& path)
{
void
FileSaveDialogImplGtk::change_path(const Glib::ustring& path)
{
- myFilename = path;
+ myFilename = path;
+
if (Glib::file_test(myFilename, Glib::FILE_TEST_IS_DIR)) {
//fprintf(stderr,"set_current_folder(%s)\n",myFilename.c_str());
set_current_folder(myFilename);
if (Glib::file_test(myFilename, Glib::FILE_TEST_IS_DIR)) {
//fprintf(stderr,"set_current_folder(%s)\n",myFilename.c_str());
set_current_folder(myFilename);
Inkscape::Extension::Output* newOut = extension ? dynamic_cast<Inkscape::Extension::Output*>(extension) : 0;
if ( fileTypeCheckbox.get_active() && newOut ) {
Inkscape::Extension::Output* newOut = extension ? dynamic_cast<Inkscape::Extension::Output*>(extension) : 0;
if ( fileTypeCheckbox.get_active() && newOut ) {
- try {
- bool appendExtension = true;
- Glib::ustring utf8Name = Glib::filename_to_utf8( myFilename );
- Glib::ustring::size_type pos = utf8Name.rfind('.');
- if ( pos != Glib::ustring::npos ) {
- Glib::ustring trail = utf8Name.substr( pos );
- Glib::ustring foldedTrail = trail.casefold();
- if ( (trail == ".")
- | (foldedTrail != Glib::ustring( newOut->get_extension() ).casefold()
- && ( knownExtensions.find(foldedTrail) != knownExtensions.end() ) ) ) {
- utf8Name = utf8Name.erase( pos );
- } else {
- appendExtension = false;
- }
- }
-
- if (appendExtension) {
- utf8Name = utf8Name + newOut->get_extension();
- myFilename = Glib::filename_from_utf8( utf8Name );
- change_path(myFilename);
- }
- } catch ( Glib::ConvertError& e ) {
- // ignore
- }
+ // Append the file extension if it's not already present
+ appendExtension(myFilename, newOut);
}
}
}
}
myFilename = "";
/* Set our dialog type (save, export, etc...)*/
myFilename = "";
/* Set our dialog type (save, export, etc...)*/
- dialogType = fileTypes;
+ _dialogType = fileTypes;
/* Set the pwd and/or the filename */
if (dir.size()>0)
/* Set the pwd and/or the filename */
if (dir.size()>0)
index e5058d0c207f6f2def2584381753bd7ff2b26c94..5bac9aa5b088ff5dc3342618b1b1edf10a04a370 100644 (file)
#include <unistd.h>
#include <sys/stat.h>
#include <errno.h>
#include <unistd.h>
#include <sys/stat.h>
#include <errno.h>
-#include <set>
#include <libxml/parser.h>
#include <libxml/tree.h>
#include <libxml/parser.h>
#include <libxml/tree.h>
*
*/
FileDialogBaseGtk(Gtk::Window& parentWindow, const Glib::ustring &title,
*
*/
FileDialogBaseGtk(Gtk::Window& parentWindow, const Glib::ustring &title,
- FileDialogType type, gchar const* preferenceBase) :
- Gtk::FileChooserDialog(parentWindow, title),
+ Gtk::FileChooserAction dialogType, FileDialogType type, gchar const* preferenceBase) :
+ Gtk::FileChooserDialog(parentWindow, title, dialogType),
preferenceBase(preferenceBase ? preferenceBase : "unknown"),
preferenceBase(preferenceBase ? preferenceBase : "unknown"),
- dialogType(type)
+ _dialogType(type)
{
internalSetup();
}
{
internalSetup();
}
/**
*
*/
/**
*
*/
- FileDialogBaseGtk(Gtk::Window& parentWindow, const Glib::ustring &title,
+ FileDialogBaseGtk(Gtk::Window& parentWindow, const char *title,
Gtk::FileChooserAction dialogType, FileDialogType type, gchar const* preferenceBase) :
Gtk::FileChooserDialog(parentWindow, title, dialogType),
preferenceBase(preferenceBase ? preferenceBase : "unknown"),
Gtk::FileChooserAction dialogType, FileDialogType type, gchar const* preferenceBase) :
Gtk::FileChooserDialog(parentWindow, title, dialogType),
preferenceBase(preferenceBase ? preferenceBase : "unknown"),
- dialogType(type)
+ _dialogType(type)
{
internalSetup();
}
{
internalSetup();
}
/**
* What type of 'open' are we? (open, import, place, etc)
*/
/**
* What type of 'open' are we? (open, import, place, etc)
*/
- FileDialogType dialogType;
+ FileDialogType _dialogType;
/**
* Our svg preview widget
*/
SVGPreview svgPreview;
/**
* Our svg preview widget
*/
SVGPreview svgPreview;
- //# Child widgets
+ /**
+ * Child widgets
+ */
Gtk::CheckButton previewCheckbox;
private:
Gtk::CheckButton previewCheckbox;
private:
Glib::ustring getFilename();
Glib::ustring getFilename();
- std::vector<Glib::ustring> getFilenames ();
+ std::vector<Glib::ustring> getFilenames();
+
+ Glib::ustring getCurrentDirectory();
private:
private:
*/
Inkscape::Extension::Extension *extension;
*/
Inkscape::Extension::Extension *extension;
- /**
- * Filename that was given
- */
- Glib::ustring myFilename;
-
};
};
Inkscape::Extension::Extension *getSelectionType();
virtual void setSelectionType( Inkscape::Extension::Extension * key );
Inkscape::Extension::Extension *getSelectionType();
virtual void setSelectionType( Inkscape::Extension::Extension * key );
- Glib::ustring getFilename();
+ Glib::ustring getCurrentDirectory();
- void change_title(const Glib::ustring& title);
+private:
+ //void change_title(const Glib::ustring& title);
void change_path(const Glib::ustring& path);
void updateNameAndExtension();
void change_path(const Glib::ustring& path);
void updateNameAndExtension();
-private:
-
/**
* Fix to allow the user to type the file name
*/
/**
* Fix to allow the user to type the file name
*/
* Callback for user input into fileNameEntry
*/
void fileNameEntryChangedCallback();
* Callback for user input into fileNameEntry
*/
void fileNameEntryChangedCallback();
-
- /**
- * Filename that was given
- */
- Glib::ustring myFilename;
-
- /**
- * List of known file extensions.
- */
- std::set<Glib::ustring> knownExtensions;
};
};
diff --git a/src/ui/dialog/filedialogimpl-win32.cpp b/src/ui/dialog/filedialogimpl-win32.cpp
--- /dev/null
@@ -0,0 +1,1461 @@
+/**\r
+ * Implementation of the file dialog interfaces defined in filedialog.h for Win32\r
+ *\r
+ * Authors:\r
+ * Joel Holdsworth\r
+ * The Inkscape Organization\r
+ *\r
+ * Copyright (C) 2004-2007 The Inkscape Organization\r
+ *\r
+ * Released under GNU GPL, read the file 'COPYING' for more information\r
+ */\r
+ \r
+#ifdef HAVE_CONFIG_H\r
+# include <config.h>\r
+#endif\r
+\r
+#ifdef WIN32\r
+ \r
+//General includes\r
+#include <list>\r
+#include <unistd.h>\r
+#include <sys/stat.h>\r
+#include <errno.h>\r
+#include <set>\r
+#include <gdk/gdkwin32.h>\r
+#include <glib/gstdio.h>\r
+#include <glibmm/i18n.h>\r
+#include <gtkmm/window.h>\r
+\r
+//Inkscape includes\r
+#include "inkscape.h"\r
+#include "prefs-utils.h"\r
+#include <dialogs/dialog-events.h>\r
+#include <extension/input.h>\r
+#include <extension/output.h>\r
+#include <extension/db.h>\r
+\r
+#include <libnr/nr-pixops.h>\r
+#include <libnr/nr-translate-scale-ops.h>\r
+#include <display/nr-arena-item.h>\r
+#include <display/nr-arena.h>\r
+#include "sp-item.h"\r
+#include "canvas-arena.h"\r
+\r
+#include "filedialog.h"\r
+#include "filedialogimpl-win32.h"\r
+\r
+#include <zlib.h>\r
+#include <cairomm/win32_surface.h>\r
+#include <cairomm/context.h>\r
+\r
+using namespace std;\r
+using namespace Glib;\r
+using namespace Cairo;\r
+using namespace Gdk::Cairo;\r
+\r
+namespace Inkscape\r
+{\r
+namespace UI\r
+{\r
+namespace Dialog\r
+{\r
+\r
+const int PreviewWidening = 150;\r
+const char PreviewWindowClassName[] = "PreviewWnd";\r
+const unsigned long MaxPreviewFileSize = 1344; // kB\r
+\r
+#define IDC_SHOW_PREVIEW 1000\r
+\r
+// Windows 2000 version of OPENFILENAMEW\r
+struct OPENFILENAMEEXW : public OPENFILENAMEW { \r
+ void * pvReserved;\r
+ DWORD dwReserved;\r
+ DWORD FlagsEx;\r
+};\r
+\r
+struct Filter\r
+{\r
+ gunichar2* name;\r
+ glong name_length;\r
+ gunichar2* filter;\r
+ glong filter_length;\r
+ Inkscape::Extension::Extension* mod;\r
+};\r
+\r
+ustring utf16_to_ustring(const wchar_t *utf16string, int utf16length = -1)\r
+{\r
+ gchar *utf8string = g_utf16_to_utf8((const gunichar2*)utf16string,\r
+ utf16length, NULL, NULL, NULL);\r
+ ustring result(utf8string);\r
+ g_free(utf8string);\r
+ \r
+ return result;\r
+}\r
+\r
+/*#########################################################################\r
+### F I L E D I A L O G B A S E C L A S S\r
+#########################################################################*/\r
+\r
+FileDialogBaseWin32::FileDialogBaseWin32(Gtk::Window &parent, \r
+ const Glib::ustring &dir, const gchar *title,\r
+ FileDialogType type, gchar const* /*preferenceBase*/) :\r
+ dialogType(type),\r
+ parent(parent),\r
+ _current_directory(dir)\r
+{\r
+ //_mutex = NULL;\r
+ _main_loop = NULL;\r
+ \r
+ _title = (wchar_t*)g_utf8_to_utf16(title, -1, NULL, NULL, NULL);\r
+ \r
+ Glib::RefPtr<const Gdk::Window> parentWindow = parent.get_window();\r
+ g_assert(parentWindow->gobj() != NULL);\r
+ _ownerHwnd = (HWND)gdk_win32_drawable_get_handle((GdkDrawable*)parentWindow->gobj());\r
+}\r
+\r
+FileDialogBaseWin32::~FileDialogBaseWin32()\r
+{\r
+ g_free(_title);\r
+}\r
+\r
+Inkscape::Extension::Extension *FileDialogBaseWin32::getSelectionType()\r
+{\r
+ return _extension;\r
+}\r
+\r
+Glib::ustring FileDialogBaseWin32::getCurrentDirectory()\r
+{\r
+ return _current_directory;\r
+}\r
+\r
+/*#########################################################################\r
+### F I L E O P E N\r
+#########################################################################*/\r
+\r
+bool FileOpenDialogImplWin32::_show_preview = true;\r
+\r
+/**\r
+ * Constructor. Not called directly. Use the factory.\r
+ */\r
+FileOpenDialogImplWin32::FileOpenDialogImplWin32(Gtk::Window &parent, \r
+ const Glib::ustring &dir,\r
+ FileDialogType fileTypes,\r
+ const gchar *title) :\r
+ FileDialogBaseWin32(parent, dir, title, fileTypes, "dialogs.open")\r
+{\r
+ // Initalize to Autodetect\r
+ _extension = NULL;\r
+\r
+ // Set our dialog type (open, import, etc...)\r
+ dialogType = fileTypes;\r
+ \r
+ _show_preview_button_bitmap = NULL;\r
+ _preview_wnd = NULL;\r
+ _file_dialog_wnd = NULL;\r
+ _base_window_proc = NULL;\r
+ \r
+ _preview_file_size = 0;\r
+ _preview_bitmap = NULL;\r
+ _preview_file_icon = NULL;\r
+ _preview_document_width = 0;\r
+ _preview_document_height = 0;\r
+ _preview_image_width = 0;\r
+ _preview_image_height = 0;\r
+ \r
+ createFilterMenu();\r
+}\r
+\r
+\r
+/**\r
+ * Destructor\r
+ */\r
+FileOpenDialogImplWin32::~FileOpenDialogImplWin32()\r
+{\r
+ if(_filter != NULL)\r
+ delete[] _filter;\r
+ if(_extension_map != NULL)\r
+ delete[] _extension_map;\r
+}\r
+\r
+void FileOpenDialogImplWin32::createFilterMenu()\r
+{\r
+ list<Filter> filter_list;\r
+\r
+ // Compose the filter string\r
+ Inkscape::Extension::DB::InputList extension_list;\r
+ Inkscape::Extension::db.get_input_list(extension_list);\r
+ \r
+ ustring all_inkscape_files_filter, all_image_files_filter;\r
+ Filter all_files, all_inkscape_files, all_image_files;\r
+\r
+ const gchar *all_files_filter_name = _("All Files");\r
+ const gchar *all_inkscape_files_filter_name = ("All Inkscape Files");\r
+ const gchar *all_image_files_filter_name = _("All Image Files");\r
+ \r
+ // Calculate the amount of memory required\r
+ int filter_count = 3; // 3 - one for All Files, All Images and All Inkscape Files\r
+ int filter_length = 1;\r
+ \r
+ for (Inkscape::Extension::DB::InputList::iterator current_item = extension_list.begin();\r
+ current_item != extension_list.end(); current_item++)\r
+ {\r
+ Filter filter;\r
+ \r
+ Inkscape::Extension::Input *imod = *current_item;\r
+ if (imod->deactivated()) continue;\r
+ \r
+ // Type\r
+ filter.name = g_utf8_to_utf16(imod->get_filetypename(),\r
+ -1, NULL, &filter.name_length, NULL);\r
+ \r
+ // Extension\r
+ const gchar *file_extension_name = imod->get_extension();\r
+ filter.filter = g_utf8_to_utf16(file_extension_name,\r
+ -1, NULL, &filter.filter_length, NULL);\r
+ \r
+ filter.mod = imod;\r
+ filter_list.push_back(filter);\r
+ \r
+ filter_length += filter.name_length +\r
+ filter.filter_length + 3; // Add 3 for two \0s and a *\r
+ \r
+ // Add to the "All Inkscape Files" Entry\r
+ if(all_inkscape_files_filter.length() > 0)\r
+ all_inkscape_files_filter += ";*";\r
+ all_inkscape_files_filter += file_extension_name;\r
+ if( strncmp("image", imod->get_mimetype(), 5) == 0)\r
+ {\r
+ // Add to the "All Image Files" Entry\r
+ if(all_image_files_filter.length() > 0)\r
+ all_image_files_filter += ";*";\r
+ all_image_files_filter += file_extension_name;\r
+ }\r
+ \r
+ filter_count++;\r
+ }\r
+ \r
+ int extension_index = 0;\r
+ _extension_map = new Inkscape::Extension::Extension*[filter_count];\r
+ \r
+ // Filter Image Files\r
+ all_image_files.name = g_utf8_to_utf16(all_image_files_filter_name,\r
+ -1, NULL, &all_image_files.name_length, NULL);\r
+ all_image_files.filter = g_utf8_to_utf16(all_image_files_filter.data(),\r
+ -1, NULL, &all_image_files.filter_length, NULL);\r
+ filter_list.push_front(all_image_files);\r
+ _extension_map[extension_index++] = NULL;\r
+ \r
+ // Filter Inkscape Files\r
+ all_inkscape_files.name = g_utf8_to_utf16(all_inkscape_files_filter_name,\r
+ -1, NULL, &all_inkscape_files.name_length, NULL);\r
+ all_inkscape_files.filter = g_utf8_to_utf16(all_inkscape_files_filter.data(),\r
+ -1, NULL, &all_inkscape_files.filter_length, NULL);\r
+ filter_list.push_front(all_inkscape_files);\r
+ _extension_map[extension_index++] = NULL;\r
+ \r
+ // Filter All Files\r
+ all_files.name = g_utf8_to_utf16(all_files_filter_name,\r
+ -1, NULL, &all_files.name_length, NULL);\r
+ all_files.filter = NULL;\r
+ all_files.filter_length = 0;\r
+ filter_list.push_front(all_files);\r
+ _extension_map[extension_index++] = NULL;\r
+ \r
+ filter_length += all_files.name_length + 3 +\r
+ all_inkscape_files.filter_length + \r
+ all_inkscape_files.name_length + 3 +\r
+ all_image_files.filter_length +\r
+ all_image_files.name_length + 3 + 1;\r
+ // Add 3 for 2*2 \0s and a *, and 1 for a trailing \0\r
+ \r
+ \r
+ _filter = new wchar_t[filter_length];\r
+ wchar_t *filterptr = _filter;\r
+ \r
+ for(list<Filter>::iterator filter_iterator = filter_list.begin();\r
+ filter_iterator != filter_list.end(); filter_iterator++)\r
+ {\r
+ const Filter &filter = *filter_iterator;\r
+ \r
+ memcpy(filterptr, filter.name, filter.name_length * 2);\r
+ filterptr += filter.name_length;\r
+ g_free(filter.name);\r
+ \r
+ *(filterptr++) = L'\0';\r
+ *(filterptr++) = L'*';\r
+ \r
+ if(filter.filter != NULL)\r
+ {\r
+ memcpy(filterptr, filter.filter, filter.filter_length * 2);\r
+ filterptr += filter.filter_length; \r
+ g_free(filter.filter);\r
+ }\r
+ \r
+ *(filterptr++) = L'\0';\r
+ \r
+ // Associate this input extension with the file type name\r
+ _extension_map[extension_index++] = filter.mod;\r
+ }\r
+ *(filterptr++) = L'\0';\r
+ \r
+ _filterIndex = 2;\r
+}\r
+\r
+void FileOpenDialogImplWin32::GetOpenFileName_thread()\r
+{\r
+ OPENFILENAMEEXW ofn;\r
+\r
+ g_assert(this != NULL);\r
+ //g_assert(_mutex != NULL);\r
+ g_assert(_main_loop != NULL); \r
+ \r
+ WCHAR* current_directory_string = (WCHAR*)g_utf8_to_utf16(\r
+ _current_directory.data(), -1, NULL, NULL, NULL);\r
+ \r
+ memset(&ofn, 0, sizeof(ofn));\r
+ \r
+ // Copy the selected file name, converting from UTF-8 to UTF-16\r
+ memset(_path_string, 0, sizeof(_path_string));\r
+ gunichar2* utf16_path_string = g_utf8_to_utf16(\r
+ myFilename.data(), -1, NULL, NULL, NULL);\r
+ wcsncpy(_path_string, (wchar_t*)utf16_path_string, _MAX_PATH);\r
+ g_free(utf16_path_string);\r
+ \r
+ ofn.lStructSize = sizeof(ofn);\r
+ ofn.hwndOwner = _ownerHwnd;\r
+ ofn.lpstrFile = _path_string;\r
+ ofn.nMaxFile = _MAX_PATH;\r
+ ofn.lpstrFileTitle = NULL;\r
+ ofn.nMaxFileTitle = 0;\r
+ ofn.lpstrInitialDir = current_directory_string;\r
+ ofn.lpstrTitle = _title;\r
+ ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST | OFN_EXPLORER | OFN_ENABLEHOOK | OFN_HIDEREADONLY | OFN_ENABLESIZING;\r
+ ofn.lpstrFilter = _filter;\r
+ ofn.nFilterIndex = _filterIndex;\r
+ ofn.lpfnHook = GetOpenFileName_hookproc;\r
+ ofn.lCustData = (LPARAM)this;\r
+ \r
+ _result = GetOpenFileNameW(&ofn) != 0;\r
+ \r
+ _filterIndex = ofn.nFilterIndex;\r
+ _extension = _extension_map[ofn.nFilterIndex];\r
+\r
+ myFilename = utf16_to_ustring(_path_string, _MAX_PATH);\r
+ \r
+ // Copy the selected file name, converting from UTF-16 to UTF-8\r
+ myFilename = utf16_to_ustring(_path_string, _MAX_PATH);\r
+ \r
+ // Tidy up\r
+ g_free(current_directory_string);\r
+ \r
+ _mutex->lock();\r
+ _finished = true;\r
+ _mutex->unlock();\r
+ //g_main_loop_quit(_main_loop);\r
+ \r
+\r
+}\r
+\r
+void FileOpenDialogImplWin32::register_preview_wnd_class()\r
+{\r
+ HINSTANCE hInstance = GetModuleHandle(NULL);\r
+ const WNDCLASSA PreviewWndClass = \r
+ {\r
+ CS_HREDRAW | CS_VREDRAW,\r
+ preview_wnd_proc,\r
+ 0,\r
+ 0,\r
+ hInstance,\r
+ NULL,\r
+ LoadCursor(hInstance, IDC_ARROW),\r
+ (HBRUSH)(COLOR_BTNFACE + 1),\r
+ NULL,\r
+ PreviewWindowClassName\r
+ };\r
+\r
+ RegisterClassA(&PreviewWndClass);\r
+}\r
+\r
+UINT_PTR CALLBACK FileOpenDialogImplWin32::GetOpenFileName_hookproc(\r
+ HWND hdlg, UINT uiMsg, WPARAM, LPARAM lParam)\r
+{\r
+ FileOpenDialogImplWin32 *pImpl = (FileOpenDialogImplWin32*)\r
+ GetWindowLongPtr(hdlg, GWLP_USERDATA);\r
+ \r
+ switch(uiMsg)\r
+ {\r
+ case WM_INITDIALOG:\r
+ {\r
+ HWND hParentWnd = GetParent(hdlg);\r
+ HINSTANCE hInstance = GetModuleHandle(NULL);\r
+ \r
+ // Make the window a bit wider\r
+ RECT rcRect;\r
+ GetWindowRect(hParentWnd, &rcRect);\r
+ MoveWindow(hParentWnd, rcRect.left, rcRect.top,\r
+ rcRect.right - rcRect.left + PreviewWidening,\r
+ rcRect.bottom - rcRect.top,\r
+ FALSE);\r
+ \r
+ // Set the pointer to the object\r
+ OPENFILENAMEW *ofn = (OPENFILENAMEW*)lParam;\r
+ SetWindowLongPtr(hdlg, GWLP_USERDATA, ofn->lCustData);\r
+ SetWindowLongPtr(hParentWnd, GWLP_USERDATA, ofn->lCustData);\r
+ pImpl = (FileOpenDialogImplWin32*)ofn->lCustData;\r
+ \r
+ // Subclass the parent\r
+ pImpl->_base_window_proc = (WNDPROC)GetWindowLongPtr(hParentWnd, GWL_WNDPROC);\r
+ SetWindowLongPtr(hParentWnd, GWL_WNDPROC, (LONG_PTR)file_dialog_subclass_proc);\r
+ \r
+ // Add a button to the toolbar\r
+ pImpl->_toolbar_wnd = FindWindowEx(hParentWnd, NULL, "ToolbarWindow32", NULL);\r
+\r
+ pImpl->_show_preview_button_bitmap = LoadBitmap(\r
+ hInstance, MAKEINTRESOURCE(IDC_SHOW_PREVIEW));\r
+ TBADDBITMAP tbAddBitmap = {NULL, (UINT)pImpl->_show_preview_button_bitmap}; \r
+ const int iBitmapIndex = SendMessage(pImpl->_toolbar_wnd,\r
+ TB_ADDBITMAP, 1, (LPARAM)&tbAddBitmap);\r
+ \r
+ TBBUTTON tbButton;\r
+ memset(&tbButton, 0, sizeof(TBBUTTON));\r
+ tbButton.iBitmap = iBitmapIndex;\r
+ tbButton.idCommand = IDC_SHOW_PREVIEW;\r
+ tbButton.fsState = (pImpl->_show_preview ? TBSTATE_CHECKED : 0)\r
+ | TBSTATE_ENABLED;\r
+ tbButton.fsStyle = TBSTYLE_CHECK;\r
+ tbButton.iString = (INT_PTR)_("Show Preview");\r
+ SendMessage(pImpl->_toolbar_wnd, TB_ADDBUTTONS, 1, (LPARAM)&tbButton); \r
+ \r
+ // Create preview pane\r
+ register_preview_wnd_class();\r
+\r
+ pImpl->_mutex->lock();\r
+ \r
+ pImpl->_file_dialog_wnd = hParentWnd;\r
+ \r
+ pImpl->_preview_wnd = \r
+ CreateWindow(PreviewWindowClassName, "",\r
+ WS_CHILD | WS_VISIBLE,\r
+ 0, 0, 100, 100, hParentWnd, NULL, hInstance, NULL);\r
+ SetWindowLongPtr(pImpl->_preview_wnd, GWLP_USERDATA, ofn->lCustData);\r
+ \r
+ pImpl->_mutex->unlock();\r
+ \r
+ pImpl->layout_dialog();\r
+ }\r
+ break;\r
+ \r
+ case WM_NOTIFY:\r
+ {\r
+ \r
+ OFNOTIFY *pOFNotify = reinterpret_cast<OFNOTIFY*>(lParam);\r
+ switch(pOFNotify->hdr.code)\r
+ {\r
+ case CDN_SELCHANGE:\r
+ {\r
+ if(pImpl != NULL)\r
+ {\r
+ // Get the file name\r
+ pImpl->_mutex->lock();\r
+ \r
+ SendMessage(pOFNotify->hdr.hwndFrom, CDM_GETFILEPATH,\r
+ sizeof(pImpl->_path_string) / sizeof(wchar_t),\r
+ (LPARAM)pImpl->_path_string);\r
+ \r
+ pImpl->_file_selected = true;\r
+ \r
+ pImpl->_mutex->unlock();\r
+ \r
+ //pImpl->file_selected();\r
+ }\r
+ }\r
+ break;\r
+ }\r
+ }\r
+ break;\r
+ \r
+ case WM_CLOSE:\r
+ pImpl->_mutex->lock();\r
+ pImpl->_preview_file_size = 0;\r
+ \r
+ pImpl->_file_dialog_wnd = NULL;\r
+ DestroyWindow(pImpl->_preview_wnd);\r
+ pImpl->_preview_wnd = NULL;\r
+ DeleteObject(pImpl->_show_preview_button_bitmap);\r
+ pImpl->_show_preview_button_bitmap = NULL;\r
+ pImpl->_mutex->unlock();\r
+\r
+ break;\r
+ }\r
+ \r
+ // Use default dialog behaviour\r
+ return 0;\r
+}\r
+\r
+LRESULT CALLBACK FileOpenDialogImplWin32::file_dialog_subclass_proc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)\r
+{\r
+ FileOpenDialogImplWin32 *pImpl = (FileOpenDialogImplWin32*)\r
+ GetWindowLongPtr(hwnd, GWLP_USERDATA);\r
+\r
+ LRESULT lResult = CallWindowProc(pImpl->_base_window_proc, hwnd, uMsg, wParam, lParam);\r
+ \r
+ switch(uMsg)\r
+ {\r
+ case WM_SHOWWINDOW:\r
+ if(wParam != 0)\r
+ pImpl->layout_dialog();\r
+ break;\r
+ \r
+ case WM_SIZE:\r
+ pImpl->layout_dialog();\r
+ break;\r
+ \r
+ case WM_COMMAND:\r
+ if(wParam == IDC_SHOW_PREVIEW)\r
+ {\r
+ const bool enable = SendMessage(pImpl->_toolbar_wnd,\r
+ TB_ISBUTTONCHECKED, IDC_SHOW_PREVIEW, 0) != 0;\r
+ pImpl->enable_preview(enable);\r
+ }\r
+ break;\r
+ }\r
+ \r
+ return lResult;\r
+}\r
+\r
+LRESULT CALLBACK FileOpenDialogImplWin32::preview_wnd_proc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)\r
+{\r
+ const int CaptionPadding = 4;\r
+ const int IconSize = 32;\r
+ \r
+ FileOpenDialogImplWin32 *pImpl = (FileOpenDialogImplWin32*)\r
+ GetWindowLongPtr(hwnd, GWLP_USERDATA);\r
+\r
+ LRESULT lResult = 0;\r
+ \r
+ switch(uMsg)\r
+ {\r
+ case WM_ERASEBKGND:\r
+ // Do nothing to erase the background\r
+ // - otherwise there'll be flicker\r
+ lResult = 1;\r
+ break;\r
+ \r
+ case WM_PAINT:\r
+ {\r
+ // Get the client rect\r
+ RECT rcClient;\r
+ GetClientRect(hwnd, &rcClient);\r
+ \r
+ // Prepare to paint\r
+ PAINTSTRUCT paint_struct;\r
+ HDC dc = BeginPaint(hwnd, &paint_struct);\r
+ \r
+ HFONT hCaptionFont = (HFONT)SendMessage(GetParent(hwnd),\r
+ WM_GETFONT, 0, 0);\r
+ HFONT hOldFont = (HFONT)SelectObject(dc, hCaptionFont);\r
+ SetBkMode(dc, TRANSPARENT);\r
+ \r
+ pImpl->_mutex->lock();\r
+ \r
+ //FillRect(dc, &client_rect, (HBRUSH)(COLOR_HOTLIGHT+1));\r
+ if(pImpl->_path_string[0] == 0)\r
+ {\r
+ FillRect(dc, &rcClient, (HBRUSH)(COLOR_3DFACE + 1));\r
+ DrawText(dc, _("No file selected"), -1, &rcClient,\r
+ DT_CENTER | DT_VCENTER | DT_NOPREFIX);\r
+ }\r
+ else if(pImpl->_preview_bitmap != NULL)\r
+ {\r
+ BITMAP bitmap;\r
+ GetObject(pImpl->_preview_bitmap, sizeof(bitmap), &bitmap);\r
+ const int destX = (rcClient.right - bitmap.bmWidth) / 2;\r
+ \r
+ // Render the image\r
+ HDC hSrcDC = CreateCompatibleDC(dc);\r
+ HBITMAP hOldBitmap = (HBITMAP)SelectObject(hSrcDC, pImpl->_preview_bitmap);\r
+ \r
+ BitBlt(dc, destX, 0, bitmap.bmWidth, bitmap.bmHeight,\r
+ hSrcDC, 0, 0, SRCCOPY);\r
+ \r
+ SelectObject(hSrcDC, hOldBitmap);\r
+ DeleteDC(hSrcDC);\r
+ \r
+ // Fill in the background area\r
+ HRGN hEraseRgn = CreateRectRgn(rcClient.left, rcClient.top,\r
+ rcClient.right, rcClient.bottom);\r
+ HRGN hImageRgn = CreateRectRgn(destX, 0,\r
+ destX + bitmap.bmWidth, bitmap.bmHeight);\r
+ CombineRgn(hEraseRgn, hEraseRgn, hImageRgn, RGN_DIFF);\r
+ \r
+ FillRgn(dc, hEraseRgn, GetSysColorBrush(COLOR_3DFACE));\r
+ \r
+ DeleteObject(hImageRgn);\r
+ DeleteObject(hEraseRgn);\r
+ \r
+ // Draw the caption on\r
+ RECT rcCaptionRect = {rcClient.left,\r
+ rcClient.top + bitmap.bmHeight + CaptionPadding,\r
+ rcClient.right, rcClient.bottom};\r
+ \r
+ WCHAR szCaption[_MAX_FNAME + 32]; \r
+ const int iLength = pImpl->format_caption(\r
+ szCaption, sizeof(szCaption) / sizeof(WCHAR));\r
+ \r
+ DrawTextW(dc, szCaption, iLength, &rcCaptionRect,\r
+ DT_CENTER | DT_TOP | DT_NOPREFIX | DT_PATH_ELLIPSIS);\r
+ }\r
+ else if(pImpl->_preview_file_icon != NULL)\r
+ {\r
+ FillRect(dc, &rcClient, (HBRUSH)(COLOR_3DFACE + 1));\r
+ \r
+ // Draw the files icon\r
+ const int destX = (rcClient.right - IconSize) / 2;\r
+ DrawIconEx(dc, destX, 0, pImpl->_preview_file_icon,\r
+ IconSize, IconSize, 0, NULL,\r
+ DI_NORMAL | DI_COMPAT);\r
+ \r
+ // Draw the caption on\r
+ RECT rcCaptionRect = {rcClient.left,\r
+ rcClient.top + IconSize + CaptionPadding,\r
+ rcClient.right, rcClient.bottom};\r
+ \r
+ WCHAR szFileName[_MAX_FNAME], szCaption[_MAX_FNAME + 32];\r
+ _wsplitpath(pImpl->_path_string, NULL, NULL, szFileName, NULL);\r
+ \r
+ const int iLength = snwprintf(szCaption,\r
+ sizeof(szCaption), L"%s\n%d kB",\r
+ szFileName, pImpl->_preview_file_size);\r
+ \r
+ DrawTextW(dc, szCaption, iLength, &rcCaptionRect,\r
+ DT_CENTER | DT_TOP | DT_NOPREFIX | DT_PATH_ELLIPSIS);\r
+ }\r
+ else\r
+ {\r
+ // Can't show anything!\r
+ FillRect(dc, &rcClient, (HBRUSH)(COLOR_3DFACE + 1));\r
+ }\r
+ \r
+ pImpl->_mutex->unlock();\r
+ \r
+ // Finish painting\r
+ SelectObject(dc, hOldFont);\r
+ EndPaint(hwnd, &paint_struct);\r
+ }\r
+ \r
+ break;\r
+ \r
+ case WM_DESTROY:\r
+ pImpl->free_preview();\r
+ break;\r
+ \r
+ default:\r
+ lResult = DefWindowProc(hwnd, uMsg, wParam, lParam);\r
+ break;\r
+ }\r
+\r
+ return lResult;\r
+}\r
+\r
+void FileOpenDialogImplWin32::enable_preview(bool enable)\r
+{\r
+ _show_preview = enable;\r
+\r
+ // Relayout the dialog\r
+ ShowWindow(_preview_wnd, enable ? SW_SHOW : SW_HIDE);\r
+ layout_dialog();\r
+ \r
+ // Load or unload the preview\r
+ if(enable)\r
+ {\r
+ _mutex->lock();\r
+ _file_selected = true;\r
+ _mutex->unlock();\r
+ }\r
+ else free_preview();\r
+}\r
+\r
+void FileOpenDialogImplWin32::layout_dialog()\r
+{\r
+ union RECTPOINTS\r
+ {\r
+ RECT r;\r
+ POINT p[2];\r
+ }; \r
+ \r
+ const float MaxExtentScale = 2.0f / 3.0f;\r
+ \r
+ RECT rcClient;\r
+ GetClientRect(_file_dialog_wnd, &rcClient);\r
+\r
+ // Re-layout the dialog\r
+ HWND hFileListWnd = GetDlgItem(_file_dialog_wnd, lst2);\r
+ HWND hFolderComboWnd = GetDlgItem(_file_dialog_wnd, cmb2);\r
+ \r
+ \r
+ RECT rcFolderComboRect;\r
+ RECTPOINTS rcFileList;\r
+ GetWindowRect(hFileListWnd, &rcFileList.r);\r
+ GetWindowRect(hFolderComboWnd, &rcFolderComboRect);\r
+ const int iPadding = rcFileList.r.top - rcFolderComboRect.bottom;\r
+ MapWindowPoints(NULL, _file_dialog_wnd, rcFileList.p, 2);\r
+ \r
+ RECT rcPreview;\r
+ RECT rcBody = {rcFileList.r.left, rcFileList.r.top,\r
+ rcClient.right - iPadding, rcFileList.r.bottom};\r
+ rcFileList.r.right = rcBody.right;\r
+ \r
+ if(_show_preview)\r
+ {\r
+ rcPreview.top = rcBody.top;\r
+ rcPreview.left = rcClient.right - (rcBody.bottom - rcBody.top);\r
+ const int iMaxExtent = (int)(MaxExtentScale * (float)(rcBody.left + rcBody.right)) + iPadding / 2;\r
+ if(rcPreview.left < iMaxExtent) rcPreview.left = iMaxExtent;\r
+ rcPreview.bottom = rcBody.bottom;\r
+ rcPreview.right = rcBody.right;\r
+ \r
+ // Re-layout the preview box\r
+ _mutex->lock();\r
+\r
+ _preview_width = rcPreview.right - rcPreview.left;\r
+ _preview_height = rcPreview.bottom - rcPreview.top;\r
+\r
+ _mutex->unlock();\r
+ \r
+ render_preview();\r
+ \r
+ MoveWindow(_preview_wnd, rcPreview.left, rcPreview.top,\r
+ _preview_width, _preview_height, TRUE);\r
+ \r
+ rcFileList.r.right = rcPreview.left - iPadding;\r
+ }\r
+ \r
+ // Re-layout the file list box\r
+ MoveWindow(hFileListWnd, rcFileList.r.left, rcFileList.r.top,\r
+ rcFileList.r.right - rcFileList.r.left,\r
+ rcFileList.r.bottom - rcFileList.r.top, TRUE);\r
+ \r
+ // Re-layout the toolbar\r
+ RECTPOINTS rcToolBar;\r
+ GetWindowRect(_toolbar_wnd, &rcToolBar.r);\r
+ MapWindowPoints(NULL, _file_dialog_wnd, rcToolBar.p, 2);\r
+ MoveWindow(_toolbar_wnd, rcToolBar.r.left, rcToolBar.r.top, \r
+ rcToolBar.r.right - rcToolBar.r.left, rcToolBar.r.bottom - rcToolBar.r.top, TRUE); \r
+}\r
+\r
+void FileOpenDialogImplWin32::file_selected()\r
+{\r
+ // Destroy any previous previews\r
+ free_preview();\r
+ \r
+\r
+ // Determine if the file exists\r
+ DWORD attributes = GetFileAttributesW(_path_string);\r
+ if(attributes == 0xFFFFFFFF ||\r
+ attributes == FILE_ATTRIBUTE_DIRECTORY)\r
+ {\r
+ InvalidateRect(_preview_wnd, NULL, FALSE);\r
+ return;\r
+ }\r
+\r
+ // Check the file exists and get the file size\r
+ HANDLE file_handle = CreateFileW(_path_string, GENERIC_READ,\r
+ FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);\r
+ if(file_handle == INVALID_HANDLE_VALUE) return; \r
+ const DWORD file_size = GetFileSize(file_handle, NULL);\r
+ if (file_size == INVALID_FILE_SIZE) return;\r
+ _preview_file_size = file_size / 1024;\r
+ CloseHandle(file_handle);\r
+ \r
+ if(_show_preview) load_preview(); \r
+}\r
+ \r
+void FileOpenDialogImplWin32::load_preview()\r
+{\r
+ // Destroy any previous previews\r
+ free_preview();\r
+ \r
+ // Try to get the file icon\r
+ SHFILEINFOW fileInfo;\r
+ if(SUCCEEDED(SHGetFileInfoW(_path_string, 0, &fileInfo,\r
+ sizeof(fileInfo), SHGFI_ICON | SHGFI_LARGEICON)))\r
+ _preview_file_icon = fileInfo.hIcon;\r
+ \r
+ // Will this file be too big?\r
+ if(_preview_file_size > MaxPreviewFileSize)\r
+ {\r
+ InvalidateRect(_preview_wnd, NULL, FALSE);\r
+ return;\r
+ }\r
+\r
+ // Prepare to render a preview\r
+ const Glib::ustring svg = ".svg";\r
+ const Glib::ustring svgz = ".svgz";\r
+ const Glib::ustring path = utf16_to_ustring(_path_string);\r
+ \r
+ bool success = false;\r
+ \r
+ _preview_document_width = _preview_document_height = 0;\r
+ \r
+ if ((dialogType == SVG_TYPES || dialogType == IMPORT_TYPES) &&\r
+ (hasSuffix(path, svg) || hasSuffix(path, svgz)))\r
+ success = set_svg_preview();\r
+ else if (isValidImageFile(path))\r
+ success = set_image_preview();\r
+ else {\r
+ // Show no preview\r
+ }\r
+ \r
+ if(success) render_preview();\r
+ \r
+ InvalidateRect(_preview_wnd, NULL, FALSE);\r
+}\r
+\r
+void FileOpenDialogImplWin32::free_preview()\r
+{\r
+ _mutex->lock();\r
+ if(_preview_bitmap != NULL)\r
+ DeleteObject(_preview_bitmap);\r
+ _preview_bitmap = NULL;\r
+ \r
+ if(_preview_file_icon != NULL)\r
+ DestroyIcon(_preview_file_icon);\r
+ _preview_file_icon = NULL;\r
+ \r
+ _preview_bitmap_image.clear();\r
+ _mutex->unlock();\r
+}\r
+\r
+bool FileOpenDialogImplWin32::set_svg_preview()\r
+{\r
+ const int PreviewSize = 512;\r
+\r
+ gchar *utf8string = g_utf16_to_utf8((const gunichar2*)_path_string,\r
+ _MAX_PATH, NULL, NULL, NULL);\r
+ SPDocument *svgDoc = sp_document_new (utf8string, true);\r
+ g_free(utf8string);\r
+ \r
+ // Check the document loaded properly \r
+ if(svgDoc == NULL) return false;\r
+ if(svgDoc->root == NULL)\r
+ {\r
+ sp_document_unref(svgDoc);\r
+ return false;\r
+ }\r
+ \r
+ // Get the size of the document\r
+ const double svgWidth = sp_document_width(svgDoc);\r
+ const double svgHeight = sp_document_height(svgDoc);\r
+ \r
+ // Find the minimum scale to fit the image inside the preview area\r
+ const double scaleFactorX = PreviewSize / svgWidth;\r
+ const double scaleFactorY = PreviewSize / svgHeight;\r
+ const double scaleFactor = (scaleFactorX > scaleFactorY) ? scaleFactorY : scaleFactorX;\r
+ \r
+ // Now get the resized values\r
+ const double scaledSvgWidth = scaleFactor * svgWidth;\r
+ const double scaledSvgHeight = scaleFactor * svgHeight;\r
+ \r
+ NR::Rect area(NR::Point(0, 0), NR::Point(scaledSvgWidth, scaledSvgHeight));\r
+ NRRectL areaL = {0, 0, scaledSvgWidth, scaledSvgHeight};\r
+ NRRectL bbox = {0, 0, scaledSvgWidth, scaledSvgHeight};\r
+ \r
+ // write object bbox to area\r
+ NR::Maybe<NR::Rect> maybeArea(area);\r
+ sp_document_ensure_up_to_date (svgDoc);\r
+ sp_item_invoke_bbox((SPItem *) svgDoc->root, &maybeArea,\r
+ sp_item_i2r_affine((SPItem *)(svgDoc->root)), TRUE);\r
+ \r
+ NRArena *const arena = NRArena::create();\r
+ \r
+ unsigned const key = sp_item_display_key_new(1);\r
+ \r
+ NRArenaItem *root = sp_item_invoke_show((SPItem*)(svgDoc->root),\r
+ arena, key, SP_ITEM_SHOW_DISPLAY);\r
+ \r
+ NRGC gc(NULL);\r
+ nr_matrix_set_scale(&gc.transform, scaleFactor, scaleFactor);\r
+ \r
+ nr_arena_item_invoke_update (root, NULL, &gc,\r
+ NR_ARENA_ITEM_STATE_ALL, NR_ARENA_ITEM_STATE_NONE);\r
+ \r
+ // Prepare a GDI compatible NRPixBlock\r
+ NRPixBlock pixBlock;\r
+ pixBlock.size = NR_PIXBLOCK_SIZE_BIG;\r
+ pixBlock.mode = NR_PIXBLOCK_MODE_R8G8B8;\r
+ pixBlock.empty = 1;\r
+ pixBlock.visible_area.x0 = pixBlock.area.x0 = 0;\r
+ pixBlock.visible_area.y0 = pixBlock.area.y0 = 0;\r
+ pixBlock.visible_area.x1 = pixBlock.area.x1 = scaledSvgWidth;\r
+ pixBlock.visible_area.y1 = pixBlock.area.y1 = scaledSvgHeight;\r
+ pixBlock.rs = 4 * ((3 * (int)scaledSvgWidth + 3) / 4);\r
+ pixBlock.data.px = g_try_new (unsigned char, pixBlock.rs * scaledSvgHeight);\r
+ \r
+ // Fail if the pixblock failed to allocate\r
+ if(pixBlock.data.px == NULL)\r
+ {\r
+ sp_document_unref(svgDoc);\r
+ return false;\r
+ }\r
+ \r
+ memset(pixBlock.data.px, 0xFF, pixBlock.rs * scaledSvgHeight);\r
+ \r
+ memcpy(&root->bbox, &areaL, sizeof(areaL));\r
+ \r
+ // Render the image\r
+ nr_arena_item_invoke_render(NULL, root, &bbox, &pixBlock, /*0*/NR_ARENA_ITEM_RENDER_NO_CACHE);\r
+ \r
+ // Tidy up\r
+ sp_document_unref(svgDoc);\r
+ sp_item_invoke_hide((SPItem*)(svgDoc->root), key);\r
+ nr_arena_item_unref(root);\r
+ nr_object_unref((NRObject *) arena);\r
+ \r
+ // Create the GDK pixbuf\r
+ _mutex->lock();\r
+ \r
+ _preview_bitmap_image = Gdk::Pixbuf::create_from_data(\r
+ pixBlock.data.px, Gdk::COLORSPACE_RGB, false, 8,\r
+ (int)scaledSvgWidth, (int)scaledSvgHeight, pixBlock.rs,\r
+ sigc::ptr_fun(destroy_svg_rendering));\r
+\r
+ _preview_document_width = scaledSvgWidth;\r
+ _preview_document_height = scaledSvgHeight;\r
+ _preview_image_width = svgWidth;\r
+ _preview_image_height = svgHeight;\r
+ \r
+ _mutex->unlock();\r
+ \r
+ return true;\r
+}\r
+\r
+void FileOpenDialogImplWin32::destroy_svg_rendering(const guint8 *buffer)\r
+{\r
+ g_assert(buffer != NULL);\r
+ g_free((void*)buffer);\r
+}\r
+ \r
+bool FileOpenDialogImplWin32::set_image_preview()\r
+{\r
+ const Glib::ustring path = utf16_to_ustring(_path_string, _MAX_PATH);\r
+ \r
+ _mutex->lock();\r
+ _preview_bitmap_image = Gdk::Pixbuf::create_from_file(path);\r
+ if(!_preview_bitmap_image) return false;\r
+ \r
+ _preview_image_width = _preview_bitmap_image->get_width();\r
+ _preview_document_width = _preview_image_width;\r
+ _preview_image_height = _preview_bitmap_image->get_height();\r
+ _preview_document_height = _preview_image_height;\r
+ \r
+ _mutex->unlock();\r
+\r
+ return true;\r
+}\r
+\r
+void FileOpenDialogImplWin32::render_preview()\r
+{\r
+ double x, y;\r
+ const double blurRadius = 8;\r
+ const double halfBlurRadius = blurRadius / 2;\r
+ const int shaddowOffsetX = 0;\r
+ const int shaddowOffsetY = 2;\r
+ const int pagePadding = 5;\r
+ const double shaddowAlpha = 0.75;\r
+ \r
+ // Is the preview showing?\r
+ if(!_show_preview)\r
+ return;\r
+ \r
+ // Do we have anything to render?\r
+ _mutex->lock();\r
+ \r
+ if(!_preview_bitmap_image)\r
+ {\r
+ _mutex->unlock();\r
+ return;\r
+ }\r
+ \r
+ // Tidy up any previous bitmap renderings\r
+ if(_preview_bitmap != NULL)\r
+ DeleteObject(_preview_bitmap);\r
+ _preview_bitmap = NULL;\r
+ \r
+ // Calculate the size of the caption\r
+ int captionHeight = 0;\r
+\r
+ if(_preview_wnd != NULL)\r
+ {\r
+ RECT rcCaptionRect;\r
+ WCHAR szCaption[_MAX_FNAME + 32]; \r
+ const int iLength = format_caption(szCaption,\r
+ sizeof(szCaption) / sizeof(WCHAR));\r
+ \r
+ HDC dc = GetDC(_preview_wnd);\r
+ DrawTextW(dc, szCaption, iLength, &rcCaptionRect,\r
+ DT_CENTER | DT_TOP | DT_NOPREFIX | DT_PATH_ELLIPSIS | DT_CALCRECT);\r
+ ReleaseDC(_preview_wnd, dc);\r
+ \r
+ captionHeight = rcCaptionRect.bottom - rcCaptionRect.top;\r
+ }\r
+ \r
+ // Find the minimum scale to fit the image inside the preview area\r
+ const double scaleFactorX =\r
+ ((double)_preview_width - pagePadding * 2 - blurRadius) / _preview_document_width;\r
+ const double scaleFactorY =\r
+ ((double)_preview_height - pagePadding * 2\r
+ - shaddowOffsetY - halfBlurRadius - captionHeight) / _preview_document_height;\r
+ double scaleFactor = (scaleFactorX > scaleFactorY) ? scaleFactorY : scaleFactorX;\r
+ scaleFactor = (scaleFactor > 1.0) ? 1.0 : scaleFactor; \r
+ \r
+ // Now get the resized values\r
+ const double scaledSvgWidth = scaleFactor * _preview_document_width;\r
+ const double scaledSvgHeight = scaleFactor * _preview_document_height;\r
+ \r
+ const int svgX = pagePadding + halfBlurRadius;\r
+ const int svgY = pagePadding;\r
+ \r
+ const int frameX = svgX - pagePadding;\r
+ const int frameY = svgY - pagePadding;\r
+ const int frameWidth = scaledSvgWidth + pagePadding * 2;\r
+ const int frameHeight = scaledSvgHeight + pagePadding * 2;\r
+ \r
+ const int totalWidth = (int)ceil(frameWidth + blurRadius);\r
+ const int totalHeight = (int)ceil(frameHeight + blurRadius);\r
+ \r
+ // Prepare the drawing surface\r
+ HDC hDC = GetDC(_preview_wnd);\r
+ HDC hMemDC = CreateCompatibleDC(hDC);\r
+ _preview_bitmap = CreateCompatibleBitmap(hDC, totalWidth, totalHeight);\r
+ HBITMAP hOldBitmap = (HBITMAP)SelectObject(hMemDC, _preview_bitmap);\r
+ Cairo::RefPtr<Win32Surface> surface = Win32Surface::create(hMemDC);\r
+ Cairo::RefPtr<Context> context = Context::create(surface);\r
+\r
+ // Paint the background to match the dialog colour\r
+ const COLORREF background = GetSysColor(COLOR_3DFACE); \r
+ context->set_source_rgb(\r
+ GetRValue(background) / 255.0,\r
+ GetGValue(background) / 255.0,\r
+ GetBValue(background) / 255.0);\r
+ context->paint();\r
+ \r
+ //----- Draw the drop shaddow -----//\r
+ \r
+ // Left Edge\r
+ x = frameX + shaddowOffsetX - halfBlurRadius;\r
+ Cairo::RefPtr<LinearGradient> leftEdgeFade = LinearGradient::create(\r
+ x, 0.0, x + blurRadius, 0.0);\r
+ leftEdgeFade->add_color_stop_rgba (0, 0, 0, 0, 0);\r
+ leftEdgeFade->add_color_stop_rgba (1, 0, 0, 0, shaddowAlpha);\r
+ context->set_source(leftEdgeFade);\r
+ context->rectangle (x, frameY + shaddowOffsetY + halfBlurRadius,\r
+ blurRadius, frameHeight - blurRadius);\r
+ context->fill();\r
+ \r
+ // Right Edge\r
+ x = frameX + frameWidth + shaddowOffsetX - halfBlurRadius;\r
+ Cairo::RefPtr<LinearGradient> rightEdgeFade = LinearGradient::create(\r
+ x, 0.0, x + blurRadius, 0.0);\r
+ rightEdgeFade->add_color_stop_rgba (0, 0, 0, 0, shaddowAlpha);\r
+ rightEdgeFade->add_color_stop_rgba (1, 0, 0, 0, 0);\r
+ context->set_source(rightEdgeFade);\r
+ context->rectangle (frameX + frameWidth + shaddowOffsetX - halfBlurRadius,\r
+ frameY + shaddowOffsetY + halfBlurRadius,\r
+ blurRadius, frameHeight - blurRadius);\r
+ context->fill();\r
+ \r
+ // Top Edge\r
+ y = frameY + shaddowOffsetY - halfBlurRadius;\r
+ Cairo::RefPtr<LinearGradient> topEdgeFade = LinearGradient::create(\r
+ 0.0, y, 0.0, y + blurRadius);\r
+ topEdgeFade->add_color_stop_rgba (0, 0, 0, 0, 0);\r
+ topEdgeFade->add_color_stop_rgba (1, 0, 0, 0, shaddowAlpha);\r
+ context->set_source(topEdgeFade);\r
+ context->rectangle (frameX + shaddowOffsetX + halfBlurRadius, y,\r
+ frameWidth - blurRadius, blurRadius);\r
+ context->fill();\r
+ \r
+ // Bottom Edge\r
+ y = frameY + frameHeight + shaddowOffsetY - halfBlurRadius;\r
+ Cairo::RefPtr<LinearGradient> bottomEdgeFade = LinearGradient::create(\r
+ 0.0, y, 0.0, y + blurRadius);\r
+ bottomEdgeFade->add_color_stop_rgba (0, 0, 0, 0, shaddowAlpha);\r
+ bottomEdgeFade->add_color_stop_rgba (1, 0, 0, 0, 0);\r
+ context->set_source(bottomEdgeFade);\r
+ context->rectangle (frameX + shaddowOffsetX + halfBlurRadius, y,\r
+ frameWidth - blurRadius, blurRadius);\r
+ context->fill();\r
+ \r
+ // Top Left Corner\r
+ x = frameX + shaddowOffsetX - halfBlurRadius;\r
+ y = frameY + shaddowOffsetY - halfBlurRadius;\r
+ Cairo::RefPtr<RadialGradient> topLeftCornerFade = RadialGradient::create(\r
+ x + blurRadius, y + blurRadius, 0, x + blurRadius, y + blurRadius, blurRadius);\r
+ topLeftCornerFade->add_color_stop_rgba (0, 0, 0, 0, shaddowAlpha);\r
+ topLeftCornerFade->add_color_stop_rgba (1, 0, 0, 0, 0);\r
+ context->set_source(topLeftCornerFade);\r
+ context->rectangle (x, y, blurRadius, blurRadius);\r
+ context->fill();\r
+ \r
+ // Top Right Corner\r
+ x = frameX + frameWidth + shaddowOffsetX - halfBlurRadius;\r
+ y = frameY + shaddowOffsetY - halfBlurRadius;\r
+ Cairo::RefPtr<RadialGradient> topRightCornerFade = RadialGradient::create(\r
+ x, y + blurRadius, 0, x, y + blurRadius, blurRadius);\r
+ topRightCornerFade->add_color_stop_rgba (0, 0, 0, 0, shaddowAlpha);\r
+ topRightCornerFade->add_color_stop_rgba (1, 0, 0, 0, 0);\r
+ context->set_source(topRightCornerFade);\r
+ context->rectangle (x, y, blurRadius, blurRadius);\r
+ context->fill();\r
+ \r
+ // Bottom Left Corner\r
+ x = frameX + shaddowOffsetX - halfBlurRadius;\r
+ y = frameY + frameHeight + shaddowOffsetY - halfBlurRadius;\r
+ Cairo::RefPtr<RadialGradient> bottomLeftCornerFade = RadialGradient::create(\r
+ x + blurRadius, y, 0, x + blurRadius, y, blurRadius);\r
+ bottomLeftCornerFade->add_color_stop_rgba (0, 0, 0, 0, shaddowAlpha);\r
+ bottomLeftCornerFade->add_color_stop_rgba (1, 0, 0, 0, 0);\r
+ context->set_source(bottomLeftCornerFade);\r
+ context->rectangle (x, y, blurRadius, blurRadius);\r
+ context->fill();\r
+ \r
+ // Bottom Right Corner\r
+ x = frameX + frameWidth + shaddowOffsetX - halfBlurRadius;\r
+ y = frameY + frameHeight + shaddowOffsetY - halfBlurRadius;\r
+ Cairo::RefPtr<RadialGradient> bottomRightCornerFade = RadialGradient::create(\r
+ x, y, 0, x, y, blurRadius);\r
+ bottomRightCornerFade->add_color_stop_rgba (0, 0, 0, 0, shaddowAlpha);\r
+ bottomRightCornerFade->add_color_stop_rgba (1, 0, 0, 0, 0);\r
+ context->set_source(bottomRightCornerFade);\r
+ context->rectangle (frameX + frameWidth + shaddowOffsetX - halfBlurRadius,\r
+ frameY + frameHeight + shaddowOffsetY - halfBlurRadius,\r
+ blurRadius, blurRadius);\r
+ context->fill();\r
+ \r
+ // Draw the frame\r
+ context->set_line_width(1);\r
+ context->rectangle (frameX, frameY, frameWidth, frameHeight);\r
+ \r
+ context->set_source_rgb(1.0, 1.0, 1.0);\r
+ context->fill_preserve();\r
+ context->set_source_rgb(0.25, 0.25, 0.25);\r
+ context->stroke_preserve();\r
+ \r
+ // Draw the image\r
+ \r
+ if(_preview_bitmap_image) // Is the image a pixbuf?\r
+ {\r
+ // Set the transformation\r
+ const Matrix matrix = {\r
+ scaleFactor, 0,\r
+ 0, scaleFactor,\r
+ svgX, svgY };\r
+ context->set_matrix (matrix);\r
+ \r
+ // Render the image\r
+ set_source_pixbuf (context, _preview_bitmap_image, 0, 0);\r
+ context->paint();\r
+ \r
+ // Reset the transformation\r
+ context->set_identity_matrix();\r
+ }\r
+ \r
+ // Draw the inner frame\r
+ context->set_source_rgb(0.75, 0.75, 0.75);\r
+ context->rectangle (svgX, svgY, scaledSvgWidth, scaledSvgHeight);\r
+ context->stroke();\r
+ \r
+ _mutex->unlock();\r
+\r
+ // Finish drawing\r
+ surface->finish();\r
+ SelectObject(hMemDC, hOldBitmap) ;\r
+ DeleteDC(hMemDC);\r
+ \r
+ // Refresh the preview pane\r
+ InvalidateRect(_preview_wnd, NULL, FALSE);\r
+}\r
+\r
+int FileOpenDialogImplWin32::format_caption(wchar_t *caption, int caption_size)\r
+{\r
+ wchar_t szFileName[_MAX_FNAME];\r
+ _wsplitpath(_path_string, NULL, NULL, szFileName, NULL);\r
+ \r
+ return snwprintf(caption, caption_size,\r
+ L"%s\n%d kB\n%d \xD7 %d", szFileName, _preview_file_size,\r
+ (int)_preview_document_width, (int)_preview_document_height);\r
+}\r
+\r
+/**\r
+ * Show this dialog modally. Return true if user hits [OK]\r
+ */\r
+bool\r
+FileOpenDialogImplWin32::show()\r
+{\r
+ // We can only run one worker thread at a time\r
+ //if(_mutex != NULL) return false;\r
+ \r
+ if(!Glib::thread_supported())\r
+ Glib::thread_init();\r
+ \r
+ _result = false;\r
+ _finished = false;\r
+ _file_selected = false;\r
+ _mutex = new Glib::Mutex();\r
+ _main_loop = g_main_loop_new(g_main_context_default(), FALSE);\r
+ \r
+ if(Glib::Thread::create(sigc::mem_fun(*this, &FileOpenDialogImplWin32::GetOpenFileName_thread), true))\r
+ {\r
+ while(1)\r
+ {\r
+ g_main_context_iteration(g_main_context_default(), FALSE);\r
+ \r
+ if(_mutex->trylock())\r
+ {\r
+ // Read mutexed data\r
+ const bool finished = _finished;\r
+ const bool is_file_selected = _file_selected;\r
+ _file_selected = false;\r
+ _mutex->unlock();\r
+ \r
+ if(finished) break;\r
+ if(is_file_selected) file_selected();\r
+ }\r
+ \r
+ Sleep(10);\r
+ }\r
+ //g_main_loop_run(_main_loop);\r
+ }\r
+ \r
+ // Tidy up \r
+ delete _mutex;\r
+ _mutex = NULL;\r
+ \r
+ return _result;\r
+}\r
+\r
+/**\r
+ * To Get Multiple filenames selected at-once.\r
+ */\r
+std::vector<Glib::ustring>FileOpenDialogImplWin32::getFilenames()\r
+{\r
+ std::vector<Glib::ustring> result;\r
+ result.push_back(getFilename());\r
+ return result;\r
+}\r
+\r
+\r
+/*#########################################################################\r
+### F I L E S A V E\r
+#########################################################################*/\r
+\r
+/**\r
+ * Constructor\r
+ */\r
+FileSaveDialogImplWin32::FileSaveDialogImplWin32(Gtk::Window &parent, \r
+ const Glib::ustring &dir,\r
+ FileDialogType fileTypes,\r
+ const char *title,\r
+ const Glib::ustring &/*default_key*/) :\r
+ FileDialogBaseWin32(parent, dir, title, fileTypes, "dialogs.save_as")\r
+{\r
+ _main_loop = NULL;\r
+\r
+ createFilterMenu();\r
+}\r
+\r
+FileSaveDialogImplWin32::~FileSaveDialogImplWin32()\r
+{\r
+}\r
+\r
+void FileSaveDialogImplWin32::createFilterMenu()\r
+{\r
+ list<Filter> filter_list;\r
+\r
+ knownExtensions.clear();\r
+\r
+ // Compose the filter string\r
+ Glib::ustring all_inkscape_files_filter, all_image_files_filter;\r
+ Inkscape::Extension::DB::OutputList extension_list;\r
+ Inkscape::Extension::db.get_output_list(extension_list);\r
+\r
+ int filter_count = 0;\r
+ int filter_length = 0;\r
+ \r
+ for (Inkscape::Extension::DB::OutputList::iterator current_item = extension_list.begin();\r
+ current_item != extension_list.end(); current_item++)\r
+ {\r
+ Inkscape::Extension::Output *omod = *current_item;\r
+ if (omod->deactivated()) continue;\r
+ \r
+ filter_count++;\r
+ \r
+ Filter filter;\r
+ \r
+ // Extension\r
+ const gchar *filter_extension = omod->get_extension(); \r
+ filter.filter = g_utf8_to_utf16(\r
+ filter_extension, -1, NULL, &filter.filter_length, NULL); \r
+ knownExtensions.insert( Glib::ustring(filter_extension).casefold() );\r
+ \r
+ // Type\r
+ filter.name = g_utf8_to_utf16(\r
+ omod->get_filetypename(), -1, NULL, &filter.name_length, NULL);\r
+ \r
+ filter.mod = omod;\r
+ \r
+ filter_length += filter.name_length +\r
+ filter.filter_length + 3; // Add 3 for two \0s and a *\r
+ \r
+ filter_list.push_back(filter);\r
+ }\r
+ \r
+ int extension_index = 0;\r
+ _extension_map = new Inkscape::Extension::Extension*[filter_count];\r
+ \r
+ _filter = new wchar_t[filter_length];\r
+ wchar_t *filterptr = _filter;\r
+ \r
+ for(list<Filter>::iterator filter_iterator = filter_list.begin();\r
+ filter_iterator != filter_list.end(); filter_iterator++)\r
+ {\r
+ const Filter &filter = *filter_iterator;\r
+ \r
+ memcpy(filterptr, filter.name, filter.name_length * 2);\r
+ filterptr += filter.name_length;\r
+ g_free(filter.name);\r
+ \r
+ *(filterptr++) = L'\0';\r
+ *(filterptr++) = L'*';\r
+\r
+ memcpy(filterptr, filter.filter, filter.filter_length * 2);\r
+ filterptr += filter.filter_length;\r
+ g_free(filter.filter);\r
+ \r
+ *(filterptr++) = L'\0';\r
+ \r
+ // Associate this input extension with the file type name\r
+ _extension_map[extension_index++] = filter.mod;\r
+ }\r
+ *(filterptr++) = 0;\r
+ \r
+ _filterIndex = 0;\r
+}\r
+\r
+void FileSaveDialogImplWin32::GetSaveFileName_thread()\r
+{\r
+ OPENFILENAMEEXW ofn;\r
+ \r
+ g_assert(this != NULL);\r
+ //g_assert(_mutex != NULL);\r
+ g_assert(_main_loop != NULL); \r
+\r
+ gunichar2* current_directory_string = g_utf8_to_utf16(\r
+ _current_directory.data(), -1, NULL, NULL, NULL);\r
+ \r
+ // Copy the selected file name, converting from UTF-8 to UTF-16\r
+ memset(_path_string, 0, sizeof(_path_string));\r
+ gunichar2* utf16_path_string = g_utf8_to_utf16(\r
+ myFilename.data(), -1, NULL, NULL, NULL);\r
+ wcsncpy(_path_string, (wchar_t*)utf16_path_string, _MAX_PATH);\r
+ g_free(utf16_path_string);\r
+ \r
+ ZeroMemory(&ofn, sizeof(ofn));\r
+ ofn.lStructSize = sizeof(ofn);\r
+ ofn.hwndOwner = _ownerHwnd;\r
+ ofn.lpstrFile = _path_string;\r
+ ofn.nMaxFile = _MAX_PATH;\r
+ ofn.nFilterIndex = _filterIndex;\r
+ ofn.lpstrFileTitle = NULL;\r
+ ofn.nMaxFileTitle = 0;\r
+ ofn.lpstrInitialDir = (wchar_t*)current_directory_string;\r
+ ofn.lpstrTitle = _title;\r
+ ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;\r
+ ofn.lpstrFilter = _filter;\r
+ ofn.nFilterIndex = _filterIndex;\r
+ \r
+ _result = GetSaveFileNameW(&ofn) != 0;\r
+ \r
+ _filterIndex = ofn.nFilterIndex;\r
+ _extension = _extension_map[ofn.nFilterIndex];\r
+ \r
+ // Copy the selected file name, converting from UTF-16 to UTF-8\r
+ myFilename = utf16_to_ustring(_path_string, _MAX_PATH);\r
+ \r
+ //_mutex->lock();\r
+ //_finished = true;\r
+ //_mutex->unlock();\r
+ \r
+ \r
+ // Tidy up\r
+ g_free(current_directory_string);\r
+ \r
+ g_main_loop_quit(_main_loop);\r
+}\r
+\r
+/**\r
+ * Show this dialog modally. Return true if user hits [OK]\r
+ */\r
+bool\r
+FileSaveDialogImplWin32::show()\r
+{\r
+ // We can only run one worker thread at a time\r
+ //if(_mutex != NULL) return false;\r
+\r
+ if(!Glib::thread_supported())\r
+ Glib::thread_init();\r
+ \r
+ _result = false;\r
+ //_finished = false;\r
+ //_mutex = new Glib::Mutex();\r
+ _main_loop = g_main_loop_new(g_main_context_default(), FALSE);\r
+ \r
+ if(Glib::Thread::create(sigc::mem_fun(*this, &FileSaveDialogImplWin32::GetSaveFileName_thread), true))\r
+ {\r
+ /*while(1)\r
+ {\r
+ // While the dialog runs - keep the main UI alive\r
+ g_main_context_iteration(g_main_context_default(), FALSE);\r
+ \r
+ if(_mutex->trylock())\r
+ {\r
+ if(_finished) break;\r
+ _mutex->unlock();\r
+ }\r
+ \r
+ Sleep(10);\r
+ }*/\r
+ g_main_loop_run(_main_loop);\r
+ }\r
+ //delete _mutex;\r
+ //_mutex = NULL;\r
+ \r
+ if(_result)\r
+ appendExtension(myFilename, (Inkscape::Extension::Output*)_extension);\r
+ \r
+ return _result; \r
+}\r
+\r
+void FileSaveDialogImplWin32::setSelectionType( Inkscape::Extension::Extension * /*key*/ )\r
+{\r
+ // If no pointer to extension is passed in, look up based on filename extension.\r
+ \r
+}\r
+\r
+}\r
+}\r
+}\r
+\r
+#endif\r
+\r
+/*\r
+ Local Variables:\r
+ mode:c++\r
+ c-file-style:"stroustrup"\r
+ c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))\r
+ indent-tabs-mode:nil\r
+ fill-column:99\r
+ End:\r
+*/\r
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :\r
diff --git a/src/ui/dialog/filedialogimpl-win32.h b/src/ui/dialog/filedialogimpl-win32.h
--- /dev/null
@@ -0,0 +1,348 @@
+/**\r
+ * Implementation of the file dialog interfaces defined in filedialog.h for Win32\r
+ *\r
+ * Authors:\r
+ * Joel Holdsworth\r
+ * The Inkscape Organization\r
+ *\r
+ * Copyright (C) 2004-2007 The Inkscape Organization\r
+ *\r
+ * Released under GNU GPL, read the file 'COPYING' for more information\r
+ */\r
+ \r
+#ifdef WIN32\r
+\r
+#include "gc-core.h"\r
+#include <windows.h>\r
+\r
+namespace Inkscape\r
+{\r
+namespace UI\r
+{\r
+namespace Dialog\r
+{\r
+\r
+/*#########################################################################\r
+### F I L E D I A L O G B A S E C L A S S\r
+#########################################################################*/\r
+\r
+/// This class is the base implementation of a MS Windows\r
+/// file dialog.\r
+class FileDialogBaseWin32\r
+{\r
+protected:\r
+ /// Abstract Constructor\r
+ /// @param parent The parent window for the dialog\r
+ /// @param dir The directory to begin browing from\r
+ /// @param title The title caption for the dialog in UTF-8\r
+ /// @param type The dialog type\r
+ /// @param preferenceBase The preferences key\r
+ FileDialogBaseWin32(Gtk::Window &parent, const Glib::ustring &dir,\r
+ const char *title, FileDialogType type,\r
+ gchar const *preferenceBase);\r
+\r
+ /// Destructor\r
+ ~FileDialogBaseWin32();\r
+ \r
+public:\r
+\r
+ /// Gets the currently selected extension. Valid after an [OK]\r
+ /// @return Returns a pointer to the selected extension, or NULL\r
+ /// if the selected filter requires an automatic type detection\r
+ Inkscape::Extension::Extension* getSelectionType();\r
+ \r
+ /// Get the path of the current directory\r
+ Glib::ustring getCurrentDirectory();\r
+ \r
+protected:\r
+ /// The dialog type\r
+ FileDialogType dialogType;\r
+ \r
+ /// This mutex is used to ensure that the worker thread\r
+ /// that calls GetOpenFileName cannot collide with the\r
+ /// main Inkscape thread\r
+ Glib::Mutex *_mutex;\r
+ \r
+ /// This flag is set true when the GetOpenFileName call\r
+ /// has returned\r
+ bool _finished;\r
+ \r
+ /// A pointer to the GTK main-loop context object. This\r
+ /// is used to keep the rest of the inkscape UI running\r
+ /// while the file dialog is displayed\r
+ GMainLoop *_main_loop;\r
+ \r
+ /// The result of the call to GetOpenFileName. If true\r
+ /// the user clicked OK, if false the user clicked cancel\r
+ bool _result;\r
+ \r
+ /// The parent window\r
+ Gtk::Window &parent;\r
+ \r
+ /// The windows handle of the parent window\r
+ HWND _ownerHwnd;\r
+ \r
+ /// The path of the directory that is currently being\r
+ /// browsed\r
+ Glib::ustring _current_directory;\r
+ \r
+ /// The title of the dialog in UTF-16\r
+ wchar_t *_title;\r
+ \r
+ /// The path of the currently selected file in UTF-16\r
+ wchar_t _path_string[_MAX_PATH];\r
+ \r
+ /// The filter string for GetOpenFileName in UTF-16\r
+ wchar_t *_filter;\r
+ \r
+ /// The index of the currently selected filter\r
+ int _filterIndex;\r
+ \r
+ /// An array of the extensions associated with the\r
+ /// file types of each filter. So the Nth entry of\r
+ /// this array corresponds to the extension of the Nth\r
+ /// filter in the list. NULL if no specific extension is\r
+ /// specified/\r
+ Inkscape::Extension::Extension **_extension_map;\r
+\r
+ /// The currently selected extension. Valid after an [OK]\r
+ Inkscape::Extension::Extension *_extension;\r
+};\r
+\r
+\r
+/*#########################################################################\r
+### F I L E O P E N\r
+#########################################################################*/\r
+\r
+/// An Inkscape compatible wrapper around MS Windows GetOpenFileName API\r
+class FileOpenDialogImplWin32 : public FileOpenDialog, public FileDialogBaseWin32\r
+{\r
+public:\r
+ /// Constructor\r
+ /// @param parent The parent window for the dialog\r
+ /// @param dir The directory to begin browing from\r
+ /// @param title The title caption for the dialog in UTF-8\r
+ /// @param type The dialog type\r
+ FileOpenDialogImplWin32(Gtk::Window &parent, \r
+ const Glib::ustring &dir,\r
+ FileDialogType fileTypes,\r
+ const char *title);\r
+\r
+ /// Destructor\r
+ virtual ~FileOpenDialogImplWin32();\r
+\r
+ /// Shows the file dialog, and blocks until a file\r
+ /// has been selected.\r
+ /// @return Returns true if the the user selected a\r
+ /// file, or false if the user pressed cancel.\r
+ bool show();\r
+\r
+ /// Gets a list of the selected file names\r
+ /// @return Returns an STL vector filled with the\r
+ /// GTK names of the selected files\r
+ std::vector<Glib::ustring> getFilenames();\r
+ \r
+ /// Get the path of the current directory\r
+ virtual Glib::ustring getCurrentDirectory()\r
+ { return FileDialogBaseWin32::getCurrentDirectory(); }\r
+\r
+ /// Gets the currently selected extension. Valid after an [OK]\r
+ /// @return Returns a pointer to the selected extension, or NULL\r
+ /// if the selected filter requires an automatic type detection\r
+ virtual Inkscape::Extension::Extension* getSelectionType()\r
+ { return FileDialogBaseWin32::getSelectionType(); }\r
+\r
+private:\r
+\r
+ /// Create a filter menu for this type of dialog\r
+ void createFilterMenu();\r
+ \r
+ /// The handle of the preview pane window\r
+ HWND _preview_wnd;\r
+ \r
+ /// The handle of the file dialog window\r
+ HWND _file_dialog_wnd;\r
+ \r
+ /// A pointer to the standard window proc of the\r
+ /// unhooked file dialog\r
+ WNDPROC _base_window_proc;\r
+ \r
+ /// The handle of the bitmap of the "show preview"\r
+ /// toggle button\r
+ HBITMAP _show_preview_button_bitmap;\r
+ \r
+ /// The handle of the toolbar's window\r
+ HWND _toolbar_wnd;\r
+ \r
+ /// This flag is set true when the preview should be\r
+ /// shown, or false when it should be hidden\r
+ static bool _show_preview;\r
+ \r
+ \r
+ /// The current width of the preview pane in pixels\r
+ int _preview_width;\r
+ \r
+ /// The current height of the preview pane in pixels\r
+ int _preview_height;\r
+ \r
+ /// The handle of the windows to display within the\r
+ /// preview pane, or NULL if no image should be displayed\r
+ HBITMAP _preview_bitmap;\r
+ \r
+ /// The windows shell icon for the selected file\r
+ HICON _preview_file_icon;\r
+ \r
+ /// The size of the preview file in kilobytes\r
+ unsigned long _preview_file_size;\r
+\r
+ \r
+ /// The width of the document to be shown in the preview panel\r
+ double _preview_document_width;\r
+ \r
+ /// The width of the document to be shown in the preview panel\r
+ double _preview_document_height;\r
+ \r
+ /// The width of the rendered preview image in pixels\r
+ int _preview_image_width;\r
+ \r
+ /// The height of the rendered preview image in pixels\r
+ int _preview_image_height;\r
+\r
+ /// A GDK Pixbuf of the rendered preview to be displayed\r
+ Glib::RefPtr<Gdk::Pixbuf> _preview_bitmap_image;\r
+ \r
+ /// This flag is set true if a file has been selected\r
+ bool _file_selected;\r
+ \r
+ \r
+ /// The controller function for the thread which calls\r
+ /// GetOpenFileName\r
+ void GetOpenFileName_thread();\r
+ \r
+ /// Registers the Windows Class of the preview panel window\r
+ static void register_preview_wnd_class();\r
+ \r
+ /// A message proc which is called by the standard dialog\r
+ /// proc\r
+ static UINT_PTR CALLBACK GetOpenFileName_hookproc(HWND hdlg, UINT uiMsg, WPARAM wParam, LPARAM lParam);\r
+ \r
+ /// A message proc which wraps the standard dialog proc,\r
+ /// but intercepts some calls\r
+ static LRESULT CALLBACK file_dialog_subclass_proc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);\r
+ \r
+ /// The message proc for the preview panel window\r
+ static LRESULT CALLBACK preview_wnd_proc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);\r
+ \r
+ /// Lays out the controls in the file dialog given it's\r
+ /// current size\r
+ /// GetOpenFileName thread only.\r
+ void layout_dialog();\r
+ \r
+ /// Enables or disables the file preview.\r
+ /// GetOpenFileName thread only.\r
+ void enable_preview(bool enable);\r
+ \r
+ /// This function is called in the App thread when a file had\r
+ /// been selected\r
+ void file_selected();\r
+ \r
+ /// Loads and renders the unshrunk preview image.\r
+ /// Main app thread only.\r
+ void load_preview();\r
+ \r
+ /// Frees all the allocated objects associated with the file\r
+ /// currently being previewed\r
+ /// Main app thread only.\r
+ void free_preview();\r
+ \r
+ /// Loads preview for an SVG or SVGZ file.\r
+ /// Main app thread only.\r
+ /// @return Returns true if the SVG loaded successfully\r
+ bool set_svg_preview();\r
+ \r
+ /// A callback to allow this class to dispose of the\r
+ /// memory block of the rendered SVG bitmap\r
+ /// @buffer buffer The buffer to free\r
+ static void destroy_svg_rendering(const guint8 *buffer);\r
+ \r
+ /// Loads the preview for a raster image\r
+ /// Main app thread only.\r
+ /// @return Returns true if the image loaded successfully\r
+ bool set_image_preview();\r
+ \r
+ /// Renders the unshrunk preview image to a windows HTBITMAP\r
+ /// which can be painted in the preview pain.\r
+ /// Main app thread only.\r
+ void render_preview();\r
+ \r
+ /// Formats the caption in UTF-16 for the preview image\r
+ /// @param caption The buffer to format the caption string into\r
+ /// @param caption_size The number of wchar_ts in the caption buffer \r
+ /// @return Returns the number of characters in caption string\r
+ int format_caption(wchar_t *caption, int caption_size);\r
+};\r
+\r
+\r
+/*#########################################################################\r
+### F I L E S A V E\r
+#########################################################################*/\r
+\r
+/// An Inkscape compatible wrapper around MS Windows GetSaveFileName API\r
+class FileSaveDialogImplWin32 : public FileSaveDialog, public FileDialogBaseWin32\r
+{\r
+\r
+public:\r
+ FileSaveDialogImplWin32(Gtk::Window &parent, \r
+ const Glib::ustring &dir,\r
+ FileDialogType fileTypes,\r
+ const char *title,\r
+ const Glib::ustring &default_key);\r
+\r
+ /// Destructor\r
+ virtual ~FileSaveDialogImplWin32();\r
+\r
+ /// Shows the file dialog, and blocks until a file\r
+ /// has been selected.\r
+ /// @return Returns true if the the user selected a\r
+ /// file, or false if the user pressed cancel.\r
+ bool show();\r
+ \r
+ /// Get the path of the current directory\r
+ virtual Glib::ustring getCurrentDirectory()\r
+ { return FileDialogBaseWin32::getCurrentDirectory(); }\r
+\r
+ /// Gets the currently selected extension. Valid after an [OK]\r
+ /// @return Returns a pointer to the selected extension, or NULL\r
+ /// if the selected filter requires an automatic type detection\r
+ virtual Inkscape::Extension::Extension* getSelectionType()\r
+ { return FileDialogBaseWin32::getSelectionType(); }\r
+\r
+ virtual void setSelectionType( Inkscape::Extension::Extension *key );\r
+ \r
+private:\r
+\r
+ /**\r
+ * Create a filter menu for this type of dialog\r
+ */\r
+ void createFilterMenu();\r
+\r
+ void GetSaveFileName_thread();\r
+};\r
+\r
+\r
+}\r
+}\r
+}\r
+\r
+#endif\r
+\r
+/*\r
+ Local Variables:\r
+ mode:c++\r
+ c-file-style:"stroustrup"\r
+ c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))\r
+ indent-tabs-mode:nil\r
+ fill-column:99\r
+ End:\r
+*/\r
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :\r