Code

First patch for Bug 209199: Update Win32 Save As dialog to include a Title edit box...
authorjeff_schiller <jeff_schiller@users.sourceforge.net>
Thu, 11 Sep 2008 07:39:53 +0000 (07:39 +0000)
committerjeff_schiller <jeff_schiller@users.sourceforge.net>
Thu, 11 Sep 2008 07:39:53 +0000 (07:39 +0000)
src/file.cpp
src/ui/dialog/filedialog.cpp
src/ui/dialog/filedialog.h
src/ui/dialog/filedialogimpl-gtkmm.cpp
src/ui/dialog/filedialogimpl-gtkmm.h
src/ui/dialog/filedialogimpl-win32.cpp
src/ui/dialog/filedialogimpl-win32.h

index b620e9c9e745c60272069c7f6274b47c8952da6d..ac8c0a40e1a5285c513e45ad9e3c2b4af1c6623d 100644 (file)
@@ -67,6 +67,7 @@
 #include "inkscape.h"
 #include "uri.h"
 #include "id-clash.h"
+#include "dialogs/rdf.h"
 
 #ifdef WITH_GNOME_VFS
 # include <libgnomevfs/gnome-vfs.h>
@@ -749,13 +750,15 @@ sp_file_save_dialog(Gtk::Window &parentWindow, SPDocument *doc, bool is_copy)
     } else {
         dialog_title = (char const *) _("Select file to save to");
     }
+    gchar* doc_title = doc->root->title();
     Inkscape::UI::Dialog::FileSaveDialog *saveDialog =
         Inkscape::UI::Dialog::FileSaveDialog::create(
             parentWindow,
             save_loc,
             Inkscape::UI::Dialog::SVG_TYPES,
             dialog_title,
-            default_extension
+            default_extension,
+            doc_title ? doc_title : ""
             );
 
     saveDialog->setSelectionType(extension);
@@ -766,6 +769,11 @@ sp_file_save_dialog(Gtk::Window &parentWindow, SPDocument *doc, bool is_copy)
         return success;
     }
 
+    // set new title here (call RDF to ensure metadata and title element are updated)
+    rdf_set_work_entity(doc, rdf_find_entity("title"), saveDialog->getDocTitle().c_str());
+    // free up old string
+    if(doc_title) g_free(doc_title);
+
     Glib::ustring fileName = saveDialog->getFilename();
     Inkscape::Extension::Extension *selectionType = saveDialog->getSelectionType();
 
@@ -897,10 +905,10 @@ file_import(SPDocument *in_doc, const Glib::ustring &uri,
         Inkscape::XML::Document *xml_in_doc = sp_document_repr_doc(in_doc);
 
         prevent_id_clashes(doc, in_doc);
-        
+
         SPObject *in_defs = SP_DOCUMENT_DEFS(in_doc);
         Inkscape::XML::Node *last_def = SP_OBJECT_REPR(in_defs)->lastChild();
-        
+
         SPCSSAttr *style = sp_css_attr_from_object(SP_DOCUMENT_ROOT(doc));
 
         // Count the number of top-level items in the imported document.
@@ -945,7 +953,7 @@ file_import(SPDocument *in_doc, const Glib::ustring &uri,
                 if (newgroup) newgroup->appendChild(newitem);
                 else new_obj = place_to_insert->appendChildRepr(newitem);
             }
-            
+
             // don't lose top-level defs or style elements
             else if (SP_OBJECT_REPR(child)->type() == Inkscape::XML::ELEMENT_NODE) {
                 const gchar *tag = SP_OBJECT_REPR(child)->name();
index 08a3230a95877cd718847f6c3129414c7edf7d66..b1ea5dfee7d0648850b6948928bd7be3e50e937c 100644 (file)
@@ -88,7 +88,7 @@ FileOpenDialog *FileOpenDialog::create(Gtk::Window &parentWindow,
 #else
     FileOpenDialog *dialog = new FileOpenDialogImplGtk(parentWindow, path, fileTypes, title);
 #endif
-       
+
        return dialog;
 }
 
@@ -104,16 +104,17 @@ Glib::ustring FileOpenDialog::getFilename()
 /**
  * Public factory method.  Used in file.cpp
  */
-FileSaveDialog *FileSaveDialog::create(Gtk::Window& parentWindow, 
+FileSaveDialog *FileSaveDialog::create(Gtk::Window& parentWindow,
                                                                           const Glib::ustring &path,
                                        FileDialogType fileTypes,
                                        const char *title,
-                                       const Glib::ustring &default_key)
+                                       const Glib::ustring &default_key,
+                                       const gchar *docTitle)
 {
 #ifdef WIN32
-    FileSaveDialog *dialog = new FileSaveDialogImplWin32(parentWindow, path, fileTypes, title, default_key);
+    FileSaveDialog *dialog = new FileSaveDialogImplWin32(parentWindow, path, fileTypes, title, default_key, docTitle);
 #else
-    FileSaveDialog *dialog = new FileSaveDialogImplGtk(parentWindow, path, fileTypes, title, default_key);
+    FileSaveDialog *dialog = new FileSaveDialogImplGtk(parentWindow, path, fileTypes, title, default_key, docTitle);
 #endif
     return dialog;
 }
@@ -123,6 +124,11 @@ Glib::ustring FileSaveDialog::getFilename()
     return myFilename;
 }
 
+Glib::ustring FileSaveDialog::getDocTitle()
+{
+       return myDocTitle;
+}
+
 //void FileSaveDialog::change_path(const Glib::ustring& path)
 //{
 //     myFilename = path;
@@ -162,7 +168,7 @@ void FileSaveDialog::appendExtension(Glib::ustring& path, Inkscape::Extension::O
 /**
  * Public factory method.  Used in file.cpp
  */
- FileExportDialog *FileExportDialog::create(Gtk::Window& parentWindow, 
+ FileExportDialog *FileExportDialog::create(Gtk::Window& parentWindow,
                                                                                   const Glib::ustring &path,
                                            FileDialogType fileTypes,
                                            const char *title,
index b73955b466c0d1d4f438919ab323388fc953c4a4..eda8c4eb48c06295078a79c02bb869a82948fd4d 100644 (file)
@@ -62,8 +62,8 @@ 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);    
-    
+bool isValidImageFile(const Glib::ustring &fileName);
+
 /**
  * This class provides an implementation-independent API for
  * file "Open" dialogs.  Using a standard interface obviates the need
@@ -89,7 +89,7 @@ public:
      * @param fileTypes one of FileDialogTypes
      * @param title the title of the dialog
      */
-    static FileOpenDialog *create(Gtk::Window& parentWindow, 
+    static FileOpenDialog *create(Gtk::Window& parentWindow,
                                   const Glib::ustring &path,
                                   FileDialogType fileTypes,
                                   const char *title);
@@ -117,15 +117,15 @@ public:
     Glib::ustring getFilename();
 
     virtual std::vector<Glib::ustring> getFilenames() = 0;
-    
+
     virtual Glib::ustring getCurrentDirectory() = 0;
-    
+
 protected:
     /**
      * Filename that was given
      */
     Glib::ustring myFilename;
-    
+
 }; //FileOpenDialog
 
 
@@ -158,11 +158,12 @@ public:
      * @param title the title of the dialog
      * @param key a list of file types from which the user can select
      */
-    static FileSaveDialog *create(Gtk::Window& parentWindow, 
+    static FileSaveDialog *create(Gtk::Window& parentWindow,
                                   const Glib::ustring &path,
                                   FileDialogType fileTypes,
                                   const char *title,
-                                  const Glib::ustring &default_key);
+                                  const Glib::ustring &default_key,
+                                  const gchar *docTitle);
 
 
     /**
@@ -191,7 +192,12 @@ public:
      * Get the file name chosen by the user.   Valid after an [OK]
      */
     Glib::ustring getFilename ();
-    
+
+    /**
+     * Get the document title chosen by the user.   Valid after an [OK]
+     */
+    Glib::ustring getDocTitle ();
+
     virtual Glib::ustring getCurrentDirectory() = 0;
 
 protected:
@@ -200,12 +206,17 @@ protected:
      * Filename that was given
      */
     Glib::ustring myFilename;
-    
+
+    /**
+     * Doc Title that was given
+     */
+    Glib::ustring myDocTitle;
+
     /**
      * List of known file extensions.
      */
     std::set<Glib::ustring> knownExtensions;
-    
+
 
     void appendExtension(Glib::ustring& path, Inkscape::Extension::Output* outputExtension);
 
@@ -248,7 +259,7 @@ public:
      * @param title the title of the dialog
      * @param key a list of file types from which the user can select
      */
-    static FileExportDialog *create(Gtk::Window& parentWindow, 
+    static FileExportDialog *create(Gtk::Window& parentWindow,
                                     const Glib::ustring &path,
                                     FileDialogType fileTypes,
                                     const char *title,
@@ -279,28 +290,28 @@ public:
      * Return the selected filename, if any.  If not, return ""
      */
     virtual Glib::ustring getFilename () =0;
-    
+
     /**
      * Return the scope of the export.  One of the enumerated types
-     * in ScopeType     
+     * in ScopeType
      */
     virtual ScopeType getScope() = 0;
-    
+
     /**
      * Return left side of the exported region
      */
     virtual double getSourceX() = 0;
-    
+
     /**
      * Return the top of the exported region
      */
     virtual double getSourceY() = 0;
-    
+
     /**
      * Return the width of the exported region
      */
     virtual double getSourceWidth() = 0;
-    
+
     /**
      * Return the height of the exported region
      */
@@ -346,7 +357,7 @@ public:
      */
     virtual unsigned long getBackground() = 0;
 
-    
+
 
 }; //FileExportDialog
 
index b93e7837acbee80737acae44a23811693a3a5b4f..541eb388baae16d15e7547c5e78e86b2b721a2ac 100644 (file)
@@ -849,9 +849,12 @@ FileSaveDialogImplGtk::FileSaveDialogImplGtk( Gtk::Window &parentWindow,
                                               const Glib::ustring &dir,
                                               FileDialogType fileTypes,
                                               const Glib::ustring &title,
-                                              const Glib::ustring &/*default_key*/ ) :
+                                              const Glib::ustring &/*default_key*/,
+                                              const gchar* docTitle) :
     FileDialogBaseGtk(parentWindow, title, Gtk::FILE_CHOOSER_ACTION_SAVE, fileTypes, "dialogs.save_as")
 {
+    FileSaveDialog::myDocTitle = docTitle;
+
     /* One file at a time */
     set_select_multiple(false);
 
index 94067a921ea289659776da7fe91cd75c84454729..5137b8481add3fbe9865b48033e1c33c6c32c247 100644 (file)
@@ -16,9 +16,9 @@
  *
  * Released under GNU GPL, read the file 'COPYING' for more information
  */
+
 #include "filedialog.h"
+
 //General includes
 #include <unistd.h>
 #include <sys/stat.h>
@@ -54,7 +54,7 @@
 
 //For export dialog
 #include "ui/widget/scalar-unit.h"
+
 namespace Inkscape
 {
 namespace UI
@@ -250,7 +250,7 @@ public:
     Glib::ustring getFilename();
 
     std::vector<Glib::ustring> getFilenames();
-       
+
        Glib::ustring getCurrentDirectory();
 
 private:
@@ -285,11 +285,12 @@ class FileSaveDialogImplGtk : public FileSaveDialog, public FileDialogBaseGtk
 {
 
 public:
-    FileSaveDialogImplGtk(Gtk::Window &parentWindow, 
+    FileSaveDialogImplGtk(Gtk::Window &parentWindow,
                           const Glib::ustring &dir,
                        FileDialogType fileTypes,
                        const Glib::ustring &title,
-                       const Glib::ustring &default_key);
+                       const Glib::ustring &default_key,
+                       const gchar* docTitle);
 
     virtual ~FileSaveDialogImplGtk();
 
@@ -381,10 +382,10 @@ public:
 
     /**
      * Return the scope of the export.  One of the enumerated types
-     * in ScopeType     
+     * in ScopeType
      */
     ScopeType getScope()
-        { 
+        {
         if (pageButton.get_active())
             return SCOPE_PAGE;
         else if (selectionButton.get_active())
@@ -395,25 +396,25 @@ public:
             return SCOPE_DOCUMENT;
 
         }
-    
+
     /**
      * Return left side of the exported region
      */
     double getSourceX()
         { return sourceX0Spinner.getValue(); }
-    
+
     /**
      * Return the top of the exported region
      */
     double getSourceY()
         { return sourceY1Spinner.getValue(); }
-    
+
     /**
      * Return the width of the exported region
      */
     double getSourceWidth()
         { return sourceWidthSpinner.getValue(); }
-    
+
     /**
      * Return the height of the exported region
      */
index 1f714c3db413b7cee5decf2e519e3beba50eb13a..ab0a8ec6333e9edc42459e2219bdcaafbeb43ac5 100644 (file)
@@ -108,7 +108,7 @@ FileDialogBaseWin32::FileDialogBaseWin32(Gtk::Window &parent,
 
        _filter_index = 1;
        _filter_count = 0;
-       
+
     _title = (wchar_t*)g_utf8_to_utf16(title, -1, NULL, NULL, NULL);
        g_assert(_title != NULL);
 
@@ -166,7 +166,7 @@ FileOpenDialogImplWin32::FileOpenDialogImplWin32(Gtk::Window &parent,
     _preview_image_width = 0;
     _preview_image_height = 0;
     _preview_emf_image = false;
-       
+
        _mutex = NULL;
 
     createFilterMenu();
@@ -274,10 +274,10 @@ void FileOpenDialogImplWin32::createFilterMenu()
                     all_image_files.filter_length +
                     all_image_files.name_length + 3 + 1;
      // Add 3 for 2*2 \0s and a *, and 1 for a trailing \0
-        
+
        _filter = new wchar_t[filter_length];
     wchar_t *filterptr = _filter;
-       
+
     for(list<Filter>::iterator filter_iterator = filter_list.begin();
         filter_iterator != filter_list.end(); filter_iterator++)
     {
@@ -303,7 +303,7 @@ void FileOpenDialogImplWin32::createFilterMenu()
         _extension_map[extension_index++] = filter.mod;
     }
     *(filterptr++) = L'\0';
-       
+
        _filter_count = extension_index;
     _filter_index = 2; // Select the 2nd filter in the list - 2 is NOT the 3rd
 }
@@ -314,7 +314,7 @@ void FileOpenDialogImplWin32::GetOpenFileName_thread()
 
     g_assert(this != NULL);
        g_assert(_mutex != NULL);
-    
+
     WCHAR* current_directory_string = (WCHAR*)g_utf8_to_utf16(
         _current_directory.data(), _current_directory.length(),
                NULL, NULL, NULL);
@@ -1010,7 +1010,7 @@ MyGetEnhMetaFileW( const WCHAR *filename )
         if (hmf) {
             // Convert Windows Metafile to Enhanced Metafile
             DWORD nSize = GetMetaFileBitsEx( hmf, 0, NULL );
-            
+
             if (nSize) {
                 BYTE *lpvData = new BYTE[nSize];
                 if (lpvData) {
@@ -1447,9 +1447,13 @@ FileSaveDialogImplWin32::FileSaveDialogImplWin32(Gtk::Window &parent,
             const Glib::ustring &dir,
             FileDialogType fileTypes,
             const char *title,
-            const Glib::ustring &/*default_key*/) :
-    FileDialogBaseWin32(parent, dir, title, fileTypes, "dialogs.save_as")
+            const Glib::ustring &/*default_key*/,
+            const char *docTitle) :
+    FileDialogBaseWin32(parent, dir, title, fileTypes, "dialogs.save_as"),
+        _title_label(NULL),
+        _title_edit(NULL)
 {
+    FileSaveDialog::myDocTitle = docTitle;
     createFilterMenu();
 }
 
@@ -1560,9 +1564,11 @@ void FileSaveDialogImplWin32::GetSaveFileName_thread()
     ofn.nMaxFileTitle = 0;
     ofn.lpstrInitialDir = current_directory_string;
     ofn.lpstrTitle = _title;
-    ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;
+    ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST | OFN_EXPLORER | OFN_ENABLEHOOK;
     ofn.lpstrFilter = _filter;
     ofn.nFilterIndex = _filter_index;
+    ofn.lpfnHook = GetSaveFileName_hookproc;
+    ofn.lCustData = (LPARAM)this;
 
     _result = GetSaveFileNameW(&ofn) != 0;
 
@@ -1590,7 +1596,7 @@ FileSaveDialogImplWin32::show()
 
     _result = false;
     _main_loop = g_main_loop_new(g_main_context_default(), FALSE);
-       
+
        if(_main_loop != NULL)
        {
            if(Glib::Thread::create(sigc::mem_fun(*this, &FileSaveDialogImplWin32::GetSaveFileName_thread), true))
@@ -1599,7 +1605,7 @@ FileSaveDialogImplWin32::show()
            if(_result)
                appendExtension(myFilename, (Inkscape::Extension::Output*)_extension);
        }
-       
+
     return _result;
 }
 
@@ -1609,6 +1615,87 @@ void FileSaveDialogImplWin32::setSelectionType( Inkscape::Extension::Extension *
 
 }
 
+UINT_PTR CALLBACK FileSaveDialogImplWin32::GetSaveFileName_hookproc(
+    HWND hdlg, UINT uiMsg, WPARAM, LPARAM lParam)
+{
+    FileSaveDialogImplWin32 *pImpl = (FileSaveDialogImplWin32*)
+        GetWindowLongPtr(hdlg, GWLP_USERDATA);
+
+    switch(uiMsg)
+    {
+    case WM_INITDIALOG:
+        {
+            HWND hParentWnd = GetParent(hdlg);
+            HINSTANCE hInstance = GetModuleHandle(NULL);
+
+            // get size/pos of typical combo box
+            RECT rEDT1, rCB1, rROOT, rST;
+            GetWindowRect(GetDlgItem(hParentWnd, cmb1), &rCB1);
+            GetWindowRect(GetDlgItem(hParentWnd, cmb13), &rEDT1);
+            GetWindowRect(GetDlgItem(hParentWnd, stc2), &rST);
+            GetWindowRect(hdlg, &rROOT);
+            int ydelta = rCB1.top - rEDT1.top;
+
+            // Make the window a bit longer
+            RECT rcRect;
+            GetWindowRect(hParentWnd, &rcRect);
+            MoveWindow(hParentWnd, rcRect.left, rcRect.top, rcRect.right - rcRect.left,
+                       rcRect.bottom - rcRect.top + ydelta, FALSE);
+
+            // It is not necessary to delete stock objects by calling DeleteObject
+            HGDIOBJ dlgFont = GetStockObject(DEFAULT_GUI_FONT);
+
+            // Set the pointer to the object
+            OPENFILENAMEW *ofn = (OPENFILENAMEW*)lParam;
+            SetWindowLongPtr(hdlg, GWLP_USERDATA, ofn->lCustData);
+            SetWindowLongPtr(hParentWnd, GWLP_USERDATA, ofn->lCustData);
+            pImpl = (FileSaveDialogImplWin32*)ofn->lCustData;
+
+            // Create the Title label and edit control
+            pImpl->_title_label = CreateWindowEx(NULL, "STATIC", "Title:",
+                                        WS_VISIBLE|WS_CHILD,
+                                        CW_USEDEFAULT, CW_USEDEFAULT, rCB1.left-rST.left, rST.bottom-rST.top,
+                                        hParentWnd, NULL, hInstance, NULL);
+            if(pImpl->_title_label) {
+              if(dlgFont) SendMessage(pImpl->_title_label, WM_SETFONT, (WPARAM)dlgFont, MAKELPARAM(FALSE, 0));
+              SetWindowPos(pImpl->_title_label, NULL, rST.left-rROOT.left, rST.top+ydelta-rROOT.top,
+                           rCB1.left-rST.left, rST.bottom-rST.top, SWP_SHOWWINDOW|SWP_NOZORDER);
+            }
+
+            pImpl->_title_edit = CreateWindowEx(WS_EX_CLIENTEDGE, "EDIT", "",
+                                        WS_VISIBLE|WS_CHILD|WS_TABSTOP|ES_AUTOHSCROLL,
+                                        CW_USEDEFAULT, CW_USEDEFAULT, rCB1.right-rCB1.left, rCB1.bottom-rCB1.top,
+                                        hParentWnd, NULL, hInstance, NULL);
+            if(pImpl->_title_edit) {
+              if(dlgFont) SendMessage(pImpl->_title_edit, WM_SETFONT, (WPARAM)dlgFont, MAKELPARAM(FALSE, 0));
+              SetWindowPos(pImpl->_title_edit, NULL, rCB1.left-rROOT.left, rCB1.top+ydelta-rROOT.top,
+                           rCB1.right-rCB1.left, rCB1.bottom-rCB1.top, SWP_SHOWWINDOW|SWP_NOZORDER);
+              // TODO: make sure this works for Unicode
+              SetWindowText(pImpl->_title_edit, pImpl->myDocTitle.c_str());
+            }
+        }
+        break;
+    case WM_DESTROY:
+      {
+        if(pImpl->_title_edit) {
+          int length = GetWindowTextLength(pImpl->_title_edit)+1;
+          char* temp_title = new char[length];
+          GetWindowText(pImpl->_title_edit, temp_title, length);
+          pImpl->myDocTitle = temp_title;
+          delete[] temp_title;
+          DestroyWindow(pImpl->_title_label);
+          pImpl->_title_label = NULL;
+          DestroyWindow(pImpl->_title_edit);
+          pImpl->_title_edit = NULL;
+        }
+      }
+      break;
+    }
+
+    // Use default dialog behaviour
+    return 0;
+}
+
 }
 }
 }
index 71fccca013fc517e855d9785b8bbd8801a26eac1..3a0c3775bf4d276ebfcec5bde6ead81d73beaa22 100644 (file)
@@ -57,7 +57,7 @@ public:
 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
@@ -89,10 +89,10 @@ protected:
     /// 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.
-    int _filter_index;
-       
+    unsigned int _filter_index;
+
        /// The number of filters registered
-       int _filter_count;
+       unsigned int _filter_count;
 
     /// An array of the extensions associated with the
     /// file types of each filter. So the Nth entry of
@@ -100,7 +100,7 @@ protected:
     /// 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;
 };
@@ -209,11 +209,11 @@ private:
 
     /// 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
@@ -280,7 +280,7 @@ private:
     /// @return Returns true if the image loaded successfully
     bool set_emf_preview();
 
-    /// This flag is set true when a meta file is previewed 
+    /// This flag is set true when a meta file is previewed
     bool _preview_emf_image;
 
     /// Renders the unshrunk preview image to a windows HTBITMAP
@@ -309,7 +309,8 @@ public:
                        const Glib::ustring &dir,
                        FileDialogType fileTypes,
                        const char *title,
-                       const Glib::ustring &default_key);
+                       const Glib::ustring &default_key,
+                       const char *docTitle);
 
     /// Destructor
     virtual ~FileSaveDialogImplWin32();
@@ -333,6 +334,9 @@ public:
     virtual void setSelectionType( Inkscape::Extension::Extension *key );
 
 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();
@@ -341,6 +345,10 @@ private:
     /// 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);
+
 };