summaryrefslogtreecommitdiffstats
path: root/src/ui/dialog/filedialogimpl-win32.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/ui/dialog/filedialogimpl-win32.h')
-rw-r--r--src/ui/dialog/filedialogimpl-win32.h392
1 files changed, 392 insertions, 0 deletions
diff --git a/src/ui/dialog/filedialogimpl-win32.h b/src/ui/dialog/filedialogimpl-win32.h
new file mode 100644
index 0000000..b115c61
--- /dev/null
+++ b/src/ui/dialog/filedialogimpl-win32.h
@@ -0,0 +1,392 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/** @file
+ * @brief Implementation of native file dialogs for Win32
+ */
+/* Authors:
+ * Joel Holdsworth
+ * The Inkscape Organization
+ *
+ * Copyright (C) 2004-2008 The Inkscape Organization
+ *
+ * Released under GNU GPL v2+, read the file 'COPYING' for more information.
+ */
+
+#include <glibmm.h>
+
+#ifdef _WIN32
+
+#include "filedialogimpl-gtkmm.h"
+
+#include "inkgc/gc-core.h"
+
+#include <memory>
+#include <mutex>
+#include <windows.h>
+
+
+namespace Inkscape
+{
+namespace UI
+{
+namespace Dialog
+{
+
+/*#########################################################################
+### F I L E D I A L O G B A S E C L A S S
+#########################################################################*/
+
+/// This class is the base implementation of a MS Windows
+/// file dialog.
+class FileDialogBaseWin32
+{
+protected:
+ /// Abstract Constructor
+ /// @param parent The parent window for the dialog
+ /// @param dir The directory to begin browsing from
+ /// @param title The title caption for the dialog in UTF-8
+ /// @param type The dialog type
+ /// @param preferenceBase The preferences key
+ FileDialogBaseWin32(Gtk::Window &parent, const Glib::ustring &dir,
+ const char *title, FileDialogType type,
+ gchar const *preferenceBase);
+
+ /// Destructor
+ ~FileDialogBaseWin32();
+
+public:
+
+ /// Gets the currently selected extension. Valid after an [OK]
+ /// @return Returns a pointer to the selected extension, or NULL
+ /// if the selected filter requires an automatic type detection
+ Inkscape::Extension::Extension* getSelectionType();
+
+ /// Get the path of the current directory
+ Glib::ustring getCurrentDirectory();
+
+
+protected:
+ /// The dialog type
+ FileDialogType dialogType;
+
+ /// A pointer to the GTK main-loop context object. This
+ /// is used to keep the rest of the inkscape UI running
+ /// while the file dialog is displayed
+ GMainLoop *_main_loop;
+
+ /// The result of the call to GetOpenFileName. If true
+ /// the user clicked OK, if false the user clicked cancel
+ bool _result;
+
+ /// The parent window
+ Gtk::Window &parent;
+
+ /// The windows handle of the parent window
+ HWND _ownerHwnd;
+
+ /// The path of the directory that is currently being
+ /// browsed
+ Glib::ustring _current_directory;
+
+ /// The title of the dialog in UTF-16
+ wchar_t *_title;
+
+ /// The path of the currently selected file in UTF-16
+ wchar_t _path_string[_MAX_PATH];
+
+ /// The filter string for GetOpenFileName in UTF-16
+ wchar_t *_filter;
+
+ /// The index of the currently selected filter.
+ /// This value must be greater than or equal to 1,
+ /// and less than or equal to _filter_count.
+ unsigned int _filter_index;
+
+ /// The number of filters registered
+ unsigned int _filter_count;
+
+ /// An array of the extensions associated with the
+ /// file types of each filter. So the Nth entry of
+ /// this array corresponds to the extension of the Nth
+ /// filter in the list. NULL if no specific extension is
+ /// specified/
+ Inkscape::Extension::Extension **_extension_map;
+
+ /// The currently selected extension. Valid after an [OK]
+ Inkscape::Extension::Extension *_extension;
+};
+
+
+/*#########################################################################
+### F I L E O P E N
+#########################################################################*/
+
+/// An Inkscape compatible wrapper around MS Windows GetOpenFileName API
+class FileOpenDialogImplWin32 : public FileOpenDialog, public FileDialogBaseWin32
+{
+public:
+ /// Constructor
+ /// @param parent The parent window for the dialog
+ /// @param dir The directory to begin browsing from
+ /// @param title The title caption for the dialog in UTF-8
+ /// @param type The dialog type
+ FileOpenDialogImplWin32(Gtk::Window &parent,
+ const Glib::ustring &dir,
+ FileDialogType fileTypes,
+ const char *title);
+
+ /// Destructor
+ virtual ~FileOpenDialogImplWin32();
+
+ /// Shows the file dialog, and blocks until a file
+ /// has been selected.
+ /// @return Returns true if the user selected a
+ /// file, or false if the user pressed cancel.
+ bool show();
+
+ /// Gets a list of the selected file names
+ /// @return Returns an STL vector filled with the
+ /// GTK names of the selected files
+ std::vector<Glib::ustring> getFilenames();
+
+ /// Get the path of the current directory
+ virtual Glib::ustring getCurrentDirectory()
+ { return FileDialogBaseWin32::getCurrentDirectory(); }
+
+ /// Gets the currently selected extension. Valid after an [OK]
+ /// @return Returns a pointer to the selected extension, or NULL
+ /// if the selected filter requires an automatic type detection
+ virtual Inkscape::Extension::Extension* getSelectionType()
+ { return FileDialogBaseWin32::getSelectionType(); }
+
+
+ /// Add a custom file filter menu item
+ /// @param name - Name of the filter (such as "Javscript")
+ /// @param pattern - File filtering pattern (such as "*.js")
+ /// Use the FileDialogType::CUSTOM_TYPE in constructor to not include other file types
+ virtual void addFilterMenu(Glib::ustring name, Glib::ustring pattern);
+
+private:
+
+ /// Create filter menu for this type of dialog
+ void createFilterMenu();
+
+ /// The handle of the preview pane window
+ HWND _preview_wnd;
+
+ /// The handle of the file dialog window
+ HWND _file_dialog_wnd;
+
+ /// A pointer to the standard window proc of the
+ /// unhooked file dialog
+ WNDPROC _base_window_proc;
+
+ /// The handle of the bitmap of the "show preview"
+ /// toggle button
+ HBITMAP _show_preview_button_bitmap;
+
+ /// The handle of the toolbar's window
+ HWND _toolbar_wnd;
+
+ /// This flag is set true when the preview should be
+ /// shown, or false when it should be hidden
+ static bool _show_preview;
+
+
+ /// The current width of the preview pane in pixels
+ int _preview_width;
+
+ /// The current height of the preview pane in pixels
+ int _preview_height;
+
+ /// The handle of the windows to display within the
+ /// preview pane, or NULL if no image should be displayed
+ HBITMAP _preview_bitmap;
+
+ /// The windows shell icon for the selected file
+ HICON _preview_file_icon;
+
+ /// The size of the preview file in kilobytes
+ unsigned long _preview_file_size;
+
+
+ /// The width of the document to be shown in the preview panel
+ double _preview_document_width;
+
+ /// The width of the document to be shown in the preview panel
+ double _preview_document_height;
+
+ /// The width of the rendered preview image in pixels
+ int _preview_image_width;
+
+ /// The height of the rendered preview image in pixels
+ int _preview_image_height;
+
+ /// A GDK Pixbuf of the rendered preview to be displayed
+ Glib::RefPtr<Gdk::Pixbuf> _preview_bitmap_image;
+
+ /// This flag is set true if a file has been selected
+ bool _file_selected;
+
+ /// This flag is set true when the GetOpenFileName call
+ /// has returned
+ bool _finished;
+
+ /// This mutex is used to ensure that the worker thread
+ /// that calls GetOpenFileName cannot collide with the
+ /// main Inkscape thread
+ std::unique_ptr<std::mutex> _mutex;
+
+ /// The controller function for the thread which calls
+ /// GetOpenFileName
+ void GetOpenFileName_thread();
+
+ /// Registers the Windows Class of the preview panel window
+ static void register_preview_wnd_class();
+
+ /// A message proc which is called by the standard dialog
+ /// proc
+ static UINT_PTR CALLBACK GetOpenFileName_hookproc(HWND hdlg, UINT uiMsg, WPARAM wParam, LPARAM lParam);
+
+ /// A message proc which wraps the standard dialog proc,
+ /// but intercepts some calls
+ static LRESULT CALLBACK file_dialog_subclass_proc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
+
+ /// The message proc for the preview panel window
+ static LRESULT CALLBACK preview_wnd_proc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
+
+ /// Lays out the controls in the file dialog given it's
+ /// current size
+ /// GetOpenFileName thread only.
+ void layout_dialog();
+
+ /// Enables or disables the file preview.
+ /// GetOpenFileName thread only.
+ void enable_preview(bool enable);
+
+ /// This function is called in the App thread when a file had
+ /// been selected
+ void file_selected();
+
+ /// Loads and renders the unshrunk preview image.
+ /// Main app thread only.
+ void load_preview();
+
+ /// Frees all the allocated objects associated with the file
+ /// currently being previewed
+ /// Main app thread only.
+ void free_preview();
+
+ /// Loads preview for an SVG or SVGZ file.
+ /// Main app thread only.
+ /// @return Returns true if the SVG loaded successfully
+ bool set_svg_preview();
+
+ /// A callback to allow this class to dispose of the
+ /// memory block of the rendered SVG bitmap
+ /// @buffer buffer The buffer to free
+ static void destroy_svg_rendering(const guint8 *buffer);
+
+ /// Loads the preview for a raster image
+ /// Main app thread only.
+ /// @return Returns true if the image loaded successfully
+ bool set_image_preview();
+
+ /// Loads the preview for a meta file
+ /// Main app thread only.
+ /// @return Returns true if the image loaded successfully
+ bool set_emf_preview();
+
+ /// This flag is set true when a meta file is previewed
+ bool _preview_emf_image;
+
+ /// Renders the unshrunk preview image to a windows HTBITMAP
+ /// which can be painted in the preview pain.
+ /// Main app thread only.
+ void render_preview();
+
+ /// Formats the caption in UTF-16 for the preview image
+ /// @param caption The buffer to format the caption string into
+ /// @param caption_size The number of wchar_ts in the caption buffer
+ /// @return Returns the number of characters in caption string
+ int format_caption(wchar_t *caption, int caption_size);
+};
+
+
+/*#########################################################################
+### F I L E S A V E
+#########################################################################*/
+
+/// An Inkscape compatible wrapper around MS Windows GetSaveFileName API
+class FileSaveDialogImplWin32 : public FileSaveDialog, public FileDialogBaseWin32
+{
+
+public:
+ FileSaveDialogImplWin32(Gtk::Window &parent,
+ const Glib::ustring &dir,
+ FileDialogType fileTypes,
+ const char *title,
+ const Glib::ustring &default_key,
+ const char *docTitle,
+ const Inkscape::Extension::FileSaveMethod save_method);
+
+ /// Destructor
+ virtual ~FileSaveDialogImplWin32();
+
+ /// Shows the file dialog, and blocks until a file
+ /// has been selected.
+ /// @return Returns true if the user selected a
+ /// file, or false if the user pressed cancel.
+ bool show();
+
+ /// Get the path of the current directory
+ virtual Glib::ustring getCurrentDirectory()
+ { return FileDialogBaseWin32::getCurrentDirectory(); }
+
+ /// Gets the currently selected extension. Valid after an [OK]
+ /// @return Returns a pointer to the selected extension, or NULL
+ /// if the selected filter requires an automatic type detection
+ virtual Inkscape::Extension::Extension* getSelectionType()
+ { return FileDialogBaseWin32::getSelectionType(); }
+
+ virtual void setSelectionType( Inkscape::Extension::Extension *key );
+
+ virtual void addFileType(Glib::ustring name, Glib::ustring pattern);
+
+private:
+ /// A handle to the title label and edit box
+ HWND _title_label;
+ HWND _title_edit;
+
+ /// Create a filter menu for this type of dialog
+ void createFilterMenu();
+
+ // SaveAs or SaveAsCopy
+ Inkscape::Extension::FileSaveMethod save_method;
+
+ /// The controller function for the thread which calls
+ /// GetSaveFileName
+ void GetSaveFileName_thread();
+
+ /// A message proc which is called by the standard dialog
+ /// proc
+ static UINT_PTR CALLBACK GetSaveFileName_hookproc(HWND hdlg, UINT uiMsg, WPARAM wParam, LPARAM lParam);
+
+};
+
+
+}
+}
+}
+
+#endif
+
+/*
+ Local Variables:
+ mode:c++
+ c-file-style:"stroustrup"
+ c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
+ indent-tabs-mode:nil
+ fill-column:99
+ End:
+*/
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :