From 0d2a2b601b1994333886dff8f53d82a714c4042f Mon Sep 17 00:00:00 2001 From: Robert Roebling Date: Tue, 19 Jan 1999 16:33:16 +0000 Subject: [PATCH] New DnD and Clipboard code Rearranged wxApp to do the same in the same order upon program start-up on wxGTK and wxMSW ODBC tweaks exchanged wxDataFormat for wxIPCFormat git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@1427 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- include/wx/defs.h | 4 + include/wx/gtk/app.h | 28 +-- include/wx/gtk/clipbrd.h | 22 +- include/wx/gtk/dataobj.h | 261 +++++++++++++++++------ include/wx/gtk/dnd.h | 46 +++-- include/wx/gtk1/app.h | 28 +-- include/wx/gtk1/clipbrd.h | 22 +- include/wx/gtk1/dataobj.h | 261 +++++++++++++++++------ include/wx/gtk1/dnd.h | 46 +++-- include/wx/ipcbase.h | 32 ++- include/wx/msw/dde.h | 20 +- include/wx/sckipc.h | 8 +- samples/controls/controls.cpp | 15 +- samples/db/dbtest.cpp | 18 +- samples/db/dbtest.h | 2 +- samples/dnd/dnd.cpp | 3 +- src/common/sckipc.cpp | 24 +-- src/gtk/app.cpp | 214 +++++++++---------- src/gtk/clipbrd.cpp | 203 +++++++----------- src/gtk/dataobj.cpp | 378 +++++++++++++++++++++++++++++++++- src/gtk/dialog.cpp | 11 +- src/gtk/dnd.cpp | 214 ++++++++++++------- src/gtk/frame.cpp | 11 +- src/gtk1/app.cpp | 214 +++++++++---------- src/gtk1/clipbrd.cpp | 203 +++++++----------- src/gtk1/dataobj.cpp | 378 +++++++++++++++++++++++++++++++++- src/gtk1/dialog.cpp | 11 +- src/gtk1/dnd.cpp | 214 ++++++++++++------- src/gtk1/frame.cpp | 11 +- src/msw/dde.cpp | 16 +- 30 files changed, 2010 insertions(+), 908 deletions(-) diff --git a/include/wx/defs.h b/include/wx/defs.h index eb288dc3d6..1bc6681f55 100644 --- a/include/wx/defs.h +++ b/include/wx/defs.h @@ -738,6 +738,8 @@ typedef enum // Don't do parent client adjustments (for implementation only) #define wxSIZE_NO_ADJUSTMENTS 0x0008 +#ifndef __WXGTK__ + enum wxDataFormat { wxDF_INVALID = 0, @@ -760,6 +762,8 @@ enum wxDataFormat wxDF_PRIVATE = 20 }; +#endif + /* Virtual keycodes */ enum wxKeyCode diff --git a/include/wx/gtk/app.h b/include/wx/gtk/app.h index 60ff70c269..7aa8552586 100644 --- a/include/wx/gtk/app.h +++ b/include/wx/gtk/app.h @@ -61,15 +61,16 @@ class wxApp: public wxEvtHandler static void SetInitializerFunction(wxAppInitializerFunction fn) { m_appInitFn = fn; } static wxAppInitializerFunction GetInitializerFunction() { return m_appInitFn; } - /* this may have to be overwritten when special, non-default visuals have - to be set. it is also platform dependent as only X knows about displays - and visuals. */ - virtual bool InitVisual(); - - virtual bool OnInit(); + /* override for altering the way wxGTK intializes the GUI (palette/visual/colorcube). + * under wxMSW, OnInitGui() does nothing by default. when overriding this method, + * the code in it is likely to be platform dependent, otherwise use OnInit(). */ virtual bool OnInitGui(); - virtual int OnRun(); - virtual int OnExit(); + + /* override to create top level frame, display splash screen etc. */ + virtual bool OnInit() { return FALSE; } + + virtual int OnRun() { return MainLoop(); } + virtual int OnExit() { return 0; } wxWindow *GetTopWindow(); void SetTopWindow( wxWindow *win ); @@ -105,14 +106,15 @@ class wxApp: public wxEvtHandler void SetPrintMode(int WXUNUSED(mode) ) {}; int GetPrintMode() const { return wxPRINT_POSTSCRIPT; }; - // override this function to create default log target of arbitrary - // user-defined classv (default implementation creates a wxLogGui object) + /* override this function to create default log target of arbitrary + * user-defined classv (default implementation creates a wxLogGui object) */ virtual wxLog *CreateLogTarget(); - // GTK implementation + /* GTK implementation */ - static void CommonInit(); - static void CommonCleanUp(); + static bool Initialize(); + static bool InitialzeVisual(); + static void CleanUp(); bool ProcessIdle(); void DeletePendingObjects(); diff --git a/include/wx/gtk/clipbrd.h b/include/wx/gtk/clipbrd.h index ace437d5d9..55a9e8f462 100644 --- a/include/wx/gtk/clipbrd.h +++ b/include/wx/gtk/clipbrd.h @@ -51,35 +51,29 @@ public: wxClipboard(); ~wxClipboard(); - // open the clipboard before SetData() and GetData() + /* open the clipboard before SetData() and GetData() */ virtual bool Open(); - // close the clipboard after SetData() and GetData() + /* close the clipboard after SetData() and GetData() */ virtual void Close(); - // can be called several times - virtual bool SetData( wxDataObject *data ); + /* set the clipboard data. the clipboard will delete the broker later */ + virtual bool SetData( wxDataBroker *data ); - // format available on the clipboard ? - // supply ID if private format, the same as wxPrivateDataObject::SetId() - virtual bool IsSupportedFormat( wxDataFormat format, const wxString &id = "" ); - - // fill data with data on the clipboard (if available) + /* fill data with data on the clipboard (if available) */ virtual bool GetData( wxDataObject *data ); - // clears wxTheClipboard and the system's clipboard if possible + /* clears wxTheClipboard and the system's clipboard if possible */ virtual void Clear(); - // implementation - - GdkAtom GetTargetAtom( wxDataFormat format, const wxString &id = "" ); + /* implementation */ bool m_open; bool m_ownsClipboard; bool m_ownsPrimarySelection; - wxList m_dataObjects; + wxDataBroker *m_dataBroker; GtkWidget *m_clipboardWidget; bool m_formatSupported; diff --git a/include/wx/gtk/dataobj.h b/include/wx/gtk/dataobj.h index 1be5b043dd..2a9bc78242 100644 --- a/include/wx/gtk/dataobj.h +++ b/include/wx/gtk/dataobj.h @@ -23,6 +23,8 @@ // classes //------------------------------------------------------------------------- +class wxDataFormat; +class wxDataBroker; class wxDataObject; class wxTextDataObject; class wxBitmapDataObject; @@ -30,28 +32,133 @@ class wxPrivateDataObject; class wxFileDataObject; //------------------------------------------------------------------------- -// wxDataObject +// wxDataFormat //------------------------------------------------------------------------- -class wxDataObject: public wxObject +enum wxDataType { - DECLARE_ABSTRACT_CLASS( wxDataObject ) + wxDF_INVALID = 0, + wxDF_TEXT = 1, /* CF_TEXT */ + wxDF_BITMAP = 2, /* CF_BITMAP */ + wxDF_METAFILE = 3, /* CF_METAFILEPICT */ + wxDF_SYLK = 4, + wxDF_DIF = 5, + wxDF_TIFF = 6, + wxDF_OEMTEXT = 7, /* CF_OEMTEXT */ + wxDF_DIB = 8, /* CF_DIB */ + wxDF_PALETTE = 9, + wxDF_PENDATA = 10, + wxDF_RIFF = 11, + wxDF_WAVE = 12, + wxDF_UNICODETEXT = 13, + wxDF_ENHMETAFILE = 14, + wxDF_FILENAME = 15, /* CF_HDROP */ + wxDF_LOCALE = 16, + wxDF_PRIVATE = 20 +}; +class wxDataFormat : public wxObject +{ + DECLARE_CLASS( wxDataFormat ) + public: + + wxDataFormat( wxDataType type ); + wxDataFormat( const wxString &id ); + wxDataFormat( wxDataFormat &format ); + wxDataFormat( const GdkAtom atom ); + + int GetType() const; + wxString GetId() const; + void SetId( const wxString &id ); + GdkAtom GetAtom(); + +private: - wxDataObject() {} - ~wxDataObject() {} + int m_type; + wxString m_id; + bool m_hasAtom; + GdkAtom m_atom; +}; - virtual wxDataFormat GetFormat() const = 0; +//------------------------------------------------------------------------- +// wxDataBroker handles data and ormat negotiation for clipboard and DnD +//------------------------------------------------------------------------- + +class wxDataBroker : public wxObject +{ + DECLARE_CLASS( wxDataBroker ) + +public: + + /* constructor */ + wxDataBroker(); - // implementation + /* add data object */ + void Add( wxDataObject *dataObject, bool preferred = FALSE ); + +private: + + /* OLE implementation, the methods don't need to be overridden */ - GdkAtom m_formatAtom; + /* get number of supported formats */ + virtual size_t GetFormatCount() const; + + /* return nth supported format */ + virtual wxDataFormat &GetNthFormat( size_t nth ) const; + + /* return preferrd/best supported format */ + virtual wxDataFormat &GetPreferredFormat() const; + + /* search through m_dataObjects, return TRUE if found */ + virtual bool IsSupportedFormat( wxDataFormat &format ) const; + + /* search through m_dataObjects and call child's GetSize() */ + virtual size_t GetSize( wxDataFormat& format ) const; + + /* search through m_dataObjects and call child's WriteData(dest) */ + virtual void WriteData( wxDataFormat& format, void *dest ) const; + + /* implementation */ + +public: + + wxList m_dataObjects; + size_t m_preferred; }; -// ---------------------------------------------------------------------------- +//---------------------------------------------------------------------------- +// wxDataObject to be placed in wxDataBroker +//---------------------------------------------------------------------------- + +class wxDataObject : public wxObject +{ + DECLARE_DYNAMIC_CLASS( wxDataObject ) + +public: + + /* constructor */ + wxDataObject(); + + /* destructor */ + ~wxDataObject(); + + /* write data to dest */ + virtual void WriteData( void *dest ) const = 0; + + /* get size of data */ + virtual size_t GetSize() const = 0; + + /* implementation */ + + virtual wxDataFormat &GetFormat() const; + + wxDataFormat *m_format; +}; + +//---------------------------------------------------------------------------- // wxTextDataObject is a specialization of wxDataObject for text data -// ---------------------------------------------------------------------------- +//---------------------------------------------------------------------------- class wxTextDataObject : public wxDataObject { @@ -59,27 +166,38 @@ class wxTextDataObject : public wxDataObject public: - wxTextDataObject() {} - wxTextDataObject( const wxString& strText ) - : m_strText(strText) { } + /* default constructor. call SetText() later or override + WriteData() and GetSize() for working on-demand */ + wxTextDataObject(); - virtual wxDataFormat GetFormat() const - { return wxDF_TEXT; } - - void SetText( const wxString& strText) - { m_strText = strText; } + /* constructor */ + wxTextDataObject( const wxString& data ); + + /* set current text data */ + void SetText( const wxString& data ); - wxString GetText() const - { return m_strText; } + /* get current text data */ + wxString GetText() const; -private: - wxString m_strText; + /* by default calls WriteString() with string set by constructor or + by SetText(). can be overridden for working on-demand */ + virtual void WriteData( void *dest ) const; + + /* by default, returns length of string as set by constructor or + by SetText(). can be overridden for working on-demand */ + virtual size_t GetSize() const; + + /* write string to dest */ + void WriteString( const wxString &str, void *dest ) const; + + /* implementation */ + wxString m_data; }; -// ---------------------------------------------------------------------------- +//---------------------------------------------------------------------------- // wxFileDataObject is a specialization of wxDataObject for file names -// ---------------------------------------------------------------------------- +//---------------------------------------------------------------------------- class wxFileDataObject : public wxDataObject { @@ -87,25 +205,30 @@ class wxFileDataObject : public wxDataObject public: - wxFileDataObject(void) {} - - virtual wxDataFormat GetFormat() const - { return wxDF_FILENAME; } + /* default constructor */ + wxFileDataObject(); - void AddFile( const wxString &file ) - { m_files += file; m_files += (char)0; } + /* add file name to list */ + void AddFile( const wxString &file ); - wxString GetFiles() const - { return m_files; } + /* get all filename as one string. each file name is 0 terminated, + the list is double zero terminated */ + wxString GetFiles() const; -private: - wxString m_files; + /* write list of filenames */ + virtual void WriteData( void *dest ) const; + + /* return length of list of filenames */ + virtual size_t GetSize() const; + /* implementation */ + + wxString m_files; }; -// ---------------------------------------------------------------------------- +//---------------------------------------------------------------------------- // wxBitmapDataObject is a specialization of wxDataObject for bitmaps -// ---------------------------------------------------------------------------- +//---------------------------------------------------------------------------- class wxBitmapDataObject : public wxDataObject { @@ -113,26 +236,28 @@ class wxBitmapDataObject : public wxDataObject public: - wxBitmapDataObject(void) {} + /* see wxTextDataObject for explanation */ + + wxBitmapDataObject(); + wxBitmapDataObject( const wxBitmap& bitmap ); - wxBitmapDataObject( const wxBitmap& bitmap ) { m_bitmap = bitmap; } + void SetBitmap( const wxBitmap &bitmap ); + wxBitmap GetBitmap() const; - virtual wxDataFormat GetFormat() const - { return wxDF_BITMAP; } - - void SetBitmap( const wxBitmap &bitmap ) - { m_bitmap = bitmap; } - - wxBitmap GetBitmap() const - { return m_bitmap; } + virtual void WriteData( void *dest ) const; + virtual size_t GetSize() const; + + void WriteBitmap( const wxBitmap &bitmap, void *dest ) const; -private: + // implementation + wxBitmap m_bitmap; + }; -// ---------------------------------------------------------------------------- +//---------------------------------------------------------------------------- // wxPrivateDataObject is a specialization of wxDataObject for app specific data -// ---------------------------------------------------------------------------- +//---------------------------------------------------------------------------- class wxPrivateDataObject : public wxDataObject { @@ -140,33 +265,35 @@ class wxPrivateDataObject : public wxDataObject public: + /* see wxTextDataObject for explanation of functions */ + wxPrivateDataObject(); - ~wxPrivateDataObject(); - virtual wxDataFormat GetFormat() const - { return wxDF_PRIVATE; } - - // the string ID identifies the format of clipboard or DnD data. a word - // processor would e.g. add a wxTextDataObject and a wxPrivateDataObject - // to the clipboard - the latter with the Id "WXWORD_FORMAT". + /* the string Id identifies the format of clipboard or DnD data. a word + * processor would e.g. add a wxTextDataObject and a wxPrivateDataObject + * to the clipboard - the latter with the Id "application/wxword", an + * image manipulation program would put a wxBitmapDataObject and a + * wxPrivateDataObject to the clipboard - the latter with "image/png". */ - void SetId( const wxString& id ) - { m_id = id; } + void SetId( const wxString& id ); - wxString GetId() const - { return m_id; } + /* get id */ + wxString GetId() const; - // will make internal copy + /* set data. will make internal copy. */ void SetData( const char *data, size_t size ); - size_t GetDataSize() const - { return m_size; } - - char* GetData() const - { return m_data; } + /* returns pointer to data */ + char* GetData() const; + + virtual void WriteData( void *dest ) const; + virtual size_t GetSize() const; + + void WriteData( const char *data, void *dest ) const; -private: + // implementation + size_t m_size; char* m_data; wxString m_id; diff --git a/include/wx/gtk/dnd.h b/include/wx/gtk/dnd.h index f980749d13..998f656c59 100644 --- a/include/wx/gtk/dnd.h +++ b/include/wx/gtk/dnd.h @@ -65,12 +65,14 @@ class wxDropTarget: public wxObject // Override these to indicate what kind of data you support: virtual size_t GetFormatCount() const = 0; - virtual wxDataFormat GetFormat(size_t n) const = 0; + virtual wxDataFormat &GetFormat(size_t n) const; // implementation void RegisterWidget( GtkWidget *widget ); void UnregisterWidget( GtkWidget *widget ); + + wxDataFormat *m_format; }; //------------------------------------------------------------------------- @@ -81,14 +83,13 @@ class wxTextDropTarget: public wxDropTarget { public: - wxTextDropTarget() {}; + wxTextDropTarget(); virtual bool OnDrop( long x, long y, const void *data, size_t size ); virtual bool OnDropText( long x, long y, const char *psz ); protected: virtual size_t GetFormatCount() const; - virtual wxDataFormat GetFormat(size_t n) const; }; //------------------------------------------------------------------------- @@ -105,10 +106,10 @@ public: // the string ID identifies the format of clipboard or DnD data. a word // processor would e.g. add a wxTextDataObject and a wxPrivateDataObject - // to the clipboard - the latter with the Id "WXWORD_FORMAT". + // to the clipboard - the latter with the Id "application/wxword" or + // "image/png". - void SetId( const wxString& id ) - { m_id = id; } + void SetId( const wxString& id ); wxString GetId() { return m_id; } @@ -116,20 +117,19 @@ public: private: virtual size_t GetFormatCount() const; - virtual wxDataFormat GetFormat(size_t n) const; wxString m_id; }; -// ---------------------------------------------------------------------------- +//---------------------------------------------------------------------------- // A drop target which accepts files (dragged from File Manager or Explorer) -// ---------------------------------------------------------------------------- +//---------------------------------------------------------------------------- class wxFileDropTarget: public wxDropTarget { public: - wxFileDropTarget() {}; + wxFileDropTarget(); virtual bool OnDrop( long x, long y, const void *data, size_t size ); virtual bool OnDropFiles( long x, long y, @@ -138,7 +138,6 @@ class wxFileDropTarget: public wxDropTarget protected: virtual size_t GetFormatCount() const; - virtual wxDataFormat GetFormat(size_t n) const; }; //------------------------------------------------------------------------- @@ -150,7 +149,7 @@ enum wxDragResult wxDragError, // error prevented the d&d operation from completing wxDragNone, // drag target didn't accept the data wxDragCopy, // the data was successfully copied - wxDragMove, // the data was successfully moved + wxDragMove, // the data was successfully moved (MSW only) wxDragCancel // the operation was cancelled by user (not an error) }; @@ -158,17 +157,30 @@ class wxDropSource: public wxObject { public: + /* constructor. set data later with SetData() */ wxDropSource( wxWindow *win ); - wxDropSource( wxDataObject &data, wxWindow *win ); + + /* constructor for setting one data object */ + wxDropSource( wxDataObject *data, wxWindow *win ); + + /* constructor for setting several data objects via wxDataBroker */ + wxDropSource( wxDataBroker *data, wxWindow *win ); ~wxDropSource(void); - void SetData( wxDataObject &data ); + /* set one dataobject */ + void SetData( wxDataBroker *data ); + + /* set severa dataobjects via wxDataBroker */ + void SetData( wxDataObject *data ); + + /* start drag action */ wxDragResult DoDragDrop( bool bAllowMove = FALSE ); - virtual bool GiveFeedback( wxDragResult WXUNUSED(effect), bool WXUNUSED(bScrolling) ) { return TRUE; }; + /* override to give feedback */ + virtual bool GiveFeedback( wxDragResult WXUNUSED(effect), bool WXUNUSED(bScrolling) ) { return TRUE; } - // implementation + /* GTK implementation */ void RegisterWindow(void); void UnregisterWindow(void); @@ -176,7 +188,7 @@ class wxDropSource: public wxObject GtkWidget *m_widget; wxWindow *m_window; wxDragResult m_retValue; - wxDataObject *m_data; + wxDataBroker *m_data; wxCursor m_defaultCursor; wxCursor m_goaheadCursor; diff --git a/include/wx/gtk1/app.h b/include/wx/gtk1/app.h index 60ff70c269..7aa8552586 100644 --- a/include/wx/gtk1/app.h +++ b/include/wx/gtk1/app.h @@ -61,15 +61,16 @@ class wxApp: public wxEvtHandler static void SetInitializerFunction(wxAppInitializerFunction fn) { m_appInitFn = fn; } static wxAppInitializerFunction GetInitializerFunction() { return m_appInitFn; } - /* this may have to be overwritten when special, non-default visuals have - to be set. it is also platform dependent as only X knows about displays - and visuals. */ - virtual bool InitVisual(); - - virtual bool OnInit(); + /* override for altering the way wxGTK intializes the GUI (palette/visual/colorcube). + * under wxMSW, OnInitGui() does nothing by default. when overriding this method, + * the code in it is likely to be platform dependent, otherwise use OnInit(). */ virtual bool OnInitGui(); - virtual int OnRun(); - virtual int OnExit(); + + /* override to create top level frame, display splash screen etc. */ + virtual bool OnInit() { return FALSE; } + + virtual int OnRun() { return MainLoop(); } + virtual int OnExit() { return 0; } wxWindow *GetTopWindow(); void SetTopWindow( wxWindow *win ); @@ -105,14 +106,15 @@ class wxApp: public wxEvtHandler void SetPrintMode(int WXUNUSED(mode) ) {}; int GetPrintMode() const { return wxPRINT_POSTSCRIPT; }; - // override this function to create default log target of arbitrary - // user-defined classv (default implementation creates a wxLogGui object) + /* override this function to create default log target of arbitrary + * user-defined classv (default implementation creates a wxLogGui object) */ virtual wxLog *CreateLogTarget(); - // GTK implementation + /* GTK implementation */ - static void CommonInit(); - static void CommonCleanUp(); + static bool Initialize(); + static bool InitialzeVisual(); + static void CleanUp(); bool ProcessIdle(); void DeletePendingObjects(); diff --git a/include/wx/gtk1/clipbrd.h b/include/wx/gtk1/clipbrd.h index ace437d5d9..55a9e8f462 100644 --- a/include/wx/gtk1/clipbrd.h +++ b/include/wx/gtk1/clipbrd.h @@ -51,35 +51,29 @@ public: wxClipboard(); ~wxClipboard(); - // open the clipboard before SetData() and GetData() + /* open the clipboard before SetData() and GetData() */ virtual bool Open(); - // close the clipboard after SetData() and GetData() + /* close the clipboard after SetData() and GetData() */ virtual void Close(); - // can be called several times - virtual bool SetData( wxDataObject *data ); + /* set the clipboard data. the clipboard will delete the broker later */ + virtual bool SetData( wxDataBroker *data ); - // format available on the clipboard ? - // supply ID if private format, the same as wxPrivateDataObject::SetId() - virtual bool IsSupportedFormat( wxDataFormat format, const wxString &id = "" ); - - // fill data with data on the clipboard (if available) + /* fill data with data on the clipboard (if available) */ virtual bool GetData( wxDataObject *data ); - // clears wxTheClipboard and the system's clipboard if possible + /* clears wxTheClipboard and the system's clipboard if possible */ virtual void Clear(); - // implementation - - GdkAtom GetTargetAtom( wxDataFormat format, const wxString &id = "" ); + /* implementation */ bool m_open; bool m_ownsClipboard; bool m_ownsPrimarySelection; - wxList m_dataObjects; + wxDataBroker *m_dataBroker; GtkWidget *m_clipboardWidget; bool m_formatSupported; diff --git a/include/wx/gtk1/dataobj.h b/include/wx/gtk1/dataobj.h index 1be5b043dd..2a9bc78242 100644 --- a/include/wx/gtk1/dataobj.h +++ b/include/wx/gtk1/dataobj.h @@ -23,6 +23,8 @@ // classes //------------------------------------------------------------------------- +class wxDataFormat; +class wxDataBroker; class wxDataObject; class wxTextDataObject; class wxBitmapDataObject; @@ -30,28 +32,133 @@ class wxPrivateDataObject; class wxFileDataObject; //------------------------------------------------------------------------- -// wxDataObject +// wxDataFormat //------------------------------------------------------------------------- -class wxDataObject: public wxObject +enum wxDataType { - DECLARE_ABSTRACT_CLASS( wxDataObject ) + wxDF_INVALID = 0, + wxDF_TEXT = 1, /* CF_TEXT */ + wxDF_BITMAP = 2, /* CF_BITMAP */ + wxDF_METAFILE = 3, /* CF_METAFILEPICT */ + wxDF_SYLK = 4, + wxDF_DIF = 5, + wxDF_TIFF = 6, + wxDF_OEMTEXT = 7, /* CF_OEMTEXT */ + wxDF_DIB = 8, /* CF_DIB */ + wxDF_PALETTE = 9, + wxDF_PENDATA = 10, + wxDF_RIFF = 11, + wxDF_WAVE = 12, + wxDF_UNICODETEXT = 13, + wxDF_ENHMETAFILE = 14, + wxDF_FILENAME = 15, /* CF_HDROP */ + wxDF_LOCALE = 16, + wxDF_PRIVATE = 20 +}; +class wxDataFormat : public wxObject +{ + DECLARE_CLASS( wxDataFormat ) + public: + + wxDataFormat( wxDataType type ); + wxDataFormat( const wxString &id ); + wxDataFormat( wxDataFormat &format ); + wxDataFormat( const GdkAtom atom ); + + int GetType() const; + wxString GetId() const; + void SetId( const wxString &id ); + GdkAtom GetAtom(); + +private: - wxDataObject() {} - ~wxDataObject() {} + int m_type; + wxString m_id; + bool m_hasAtom; + GdkAtom m_atom; +}; - virtual wxDataFormat GetFormat() const = 0; +//------------------------------------------------------------------------- +// wxDataBroker handles data and ormat negotiation for clipboard and DnD +//------------------------------------------------------------------------- + +class wxDataBroker : public wxObject +{ + DECLARE_CLASS( wxDataBroker ) + +public: + + /* constructor */ + wxDataBroker(); - // implementation + /* add data object */ + void Add( wxDataObject *dataObject, bool preferred = FALSE ); + +private: + + /* OLE implementation, the methods don't need to be overridden */ - GdkAtom m_formatAtom; + /* get number of supported formats */ + virtual size_t GetFormatCount() const; + + /* return nth supported format */ + virtual wxDataFormat &GetNthFormat( size_t nth ) const; + + /* return preferrd/best supported format */ + virtual wxDataFormat &GetPreferredFormat() const; + + /* search through m_dataObjects, return TRUE if found */ + virtual bool IsSupportedFormat( wxDataFormat &format ) const; + + /* search through m_dataObjects and call child's GetSize() */ + virtual size_t GetSize( wxDataFormat& format ) const; + + /* search through m_dataObjects and call child's WriteData(dest) */ + virtual void WriteData( wxDataFormat& format, void *dest ) const; + + /* implementation */ + +public: + + wxList m_dataObjects; + size_t m_preferred; }; -// ---------------------------------------------------------------------------- +//---------------------------------------------------------------------------- +// wxDataObject to be placed in wxDataBroker +//---------------------------------------------------------------------------- + +class wxDataObject : public wxObject +{ + DECLARE_DYNAMIC_CLASS( wxDataObject ) + +public: + + /* constructor */ + wxDataObject(); + + /* destructor */ + ~wxDataObject(); + + /* write data to dest */ + virtual void WriteData( void *dest ) const = 0; + + /* get size of data */ + virtual size_t GetSize() const = 0; + + /* implementation */ + + virtual wxDataFormat &GetFormat() const; + + wxDataFormat *m_format; +}; + +//---------------------------------------------------------------------------- // wxTextDataObject is a specialization of wxDataObject for text data -// ---------------------------------------------------------------------------- +//---------------------------------------------------------------------------- class wxTextDataObject : public wxDataObject { @@ -59,27 +166,38 @@ class wxTextDataObject : public wxDataObject public: - wxTextDataObject() {} - wxTextDataObject( const wxString& strText ) - : m_strText(strText) { } + /* default constructor. call SetText() later or override + WriteData() and GetSize() for working on-demand */ + wxTextDataObject(); - virtual wxDataFormat GetFormat() const - { return wxDF_TEXT; } - - void SetText( const wxString& strText) - { m_strText = strText; } + /* constructor */ + wxTextDataObject( const wxString& data ); + + /* set current text data */ + void SetText( const wxString& data ); - wxString GetText() const - { return m_strText; } + /* get current text data */ + wxString GetText() const; -private: - wxString m_strText; + /* by default calls WriteString() with string set by constructor or + by SetText(). can be overridden for working on-demand */ + virtual void WriteData( void *dest ) const; + + /* by default, returns length of string as set by constructor or + by SetText(). can be overridden for working on-demand */ + virtual size_t GetSize() const; + + /* write string to dest */ + void WriteString( const wxString &str, void *dest ) const; + + /* implementation */ + wxString m_data; }; -// ---------------------------------------------------------------------------- +//---------------------------------------------------------------------------- // wxFileDataObject is a specialization of wxDataObject for file names -// ---------------------------------------------------------------------------- +//---------------------------------------------------------------------------- class wxFileDataObject : public wxDataObject { @@ -87,25 +205,30 @@ class wxFileDataObject : public wxDataObject public: - wxFileDataObject(void) {} - - virtual wxDataFormat GetFormat() const - { return wxDF_FILENAME; } + /* default constructor */ + wxFileDataObject(); - void AddFile( const wxString &file ) - { m_files += file; m_files += (char)0; } + /* add file name to list */ + void AddFile( const wxString &file ); - wxString GetFiles() const - { return m_files; } + /* get all filename as one string. each file name is 0 terminated, + the list is double zero terminated */ + wxString GetFiles() const; -private: - wxString m_files; + /* write list of filenames */ + virtual void WriteData( void *dest ) const; + + /* return length of list of filenames */ + virtual size_t GetSize() const; + /* implementation */ + + wxString m_files; }; -// ---------------------------------------------------------------------------- +//---------------------------------------------------------------------------- // wxBitmapDataObject is a specialization of wxDataObject for bitmaps -// ---------------------------------------------------------------------------- +//---------------------------------------------------------------------------- class wxBitmapDataObject : public wxDataObject { @@ -113,26 +236,28 @@ class wxBitmapDataObject : public wxDataObject public: - wxBitmapDataObject(void) {} + /* see wxTextDataObject for explanation */ + + wxBitmapDataObject(); + wxBitmapDataObject( const wxBitmap& bitmap ); - wxBitmapDataObject( const wxBitmap& bitmap ) { m_bitmap = bitmap; } + void SetBitmap( const wxBitmap &bitmap ); + wxBitmap GetBitmap() const; - virtual wxDataFormat GetFormat() const - { return wxDF_BITMAP; } - - void SetBitmap( const wxBitmap &bitmap ) - { m_bitmap = bitmap; } - - wxBitmap GetBitmap() const - { return m_bitmap; } + virtual void WriteData( void *dest ) const; + virtual size_t GetSize() const; + + void WriteBitmap( const wxBitmap &bitmap, void *dest ) const; -private: + // implementation + wxBitmap m_bitmap; + }; -// ---------------------------------------------------------------------------- +//---------------------------------------------------------------------------- // wxPrivateDataObject is a specialization of wxDataObject for app specific data -// ---------------------------------------------------------------------------- +//---------------------------------------------------------------------------- class wxPrivateDataObject : public wxDataObject { @@ -140,33 +265,35 @@ class wxPrivateDataObject : public wxDataObject public: + /* see wxTextDataObject for explanation of functions */ + wxPrivateDataObject(); - ~wxPrivateDataObject(); - virtual wxDataFormat GetFormat() const - { return wxDF_PRIVATE; } - - // the string ID identifies the format of clipboard or DnD data. a word - // processor would e.g. add a wxTextDataObject and a wxPrivateDataObject - // to the clipboard - the latter with the Id "WXWORD_FORMAT". + /* the string Id identifies the format of clipboard or DnD data. a word + * processor would e.g. add a wxTextDataObject and a wxPrivateDataObject + * to the clipboard - the latter with the Id "application/wxword", an + * image manipulation program would put a wxBitmapDataObject and a + * wxPrivateDataObject to the clipboard - the latter with "image/png". */ - void SetId( const wxString& id ) - { m_id = id; } + void SetId( const wxString& id ); - wxString GetId() const - { return m_id; } + /* get id */ + wxString GetId() const; - // will make internal copy + /* set data. will make internal copy. */ void SetData( const char *data, size_t size ); - size_t GetDataSize() const - { return m_size; } - - char* GetData() const - { return m_data; } + /* returns pointer to data */ + char* GetData() const; + + virtual void WriteData( void *dest ) const; + virtual size_t GetSize() const; + + void WriteData( const char *data, void *dest ) const; -private: + // implementation + size_t m_size; char* m_data; wxString m_id; diff --git a/include/wx/gtk1/dnd.h b/include/wx/gtk1/dnd.h index f980749d13..998f656c59 100644 --- a/include/wx/gtk1/dnd.h +++ b/include/wx/gtk1/dnd.h @@ -65,12 +65,14 @@ class wxDropTarget: public wxObject // Override these to indicate what kind of data you support: virtual size_t GetFormatCount() const = 0; - virtual wxDataFormat GetFormat(size_t n) const = 0; + virtual wxDataFormat &GetFormat(size_t n) const; // implementation void RegisterWidget( GtkWidget *widget ); void UnregisterWidget( GtkWidget *widget ); + + wxDataFormat *m_format; }; //------------------------------------------------------------------------- @@ -81,14 +83,13 @@ class wxTextDropTarget: public wxDropTarget { public: - wxTextDropTarget() {}; + wxTextDropTarget(); virtual bool OnDrop( long x, long y, const void *data, size_t size ); virtual bool OnDropText( long x, long y, const char *psz ); protected: virtual size_t GetFormatCount() const; - virtual wxDataFormat GetFormat(size_t n) const; }; //------------------------------------------------------------------------- @@ -105,10 +106,10 @@ public: // the string ID identifies the format of clipboard or DnD data. a word // processor would e.g. add a wxTextDataObject and a wxPrivateDataObject - // to the clipboard - the latter with the Id "WXWORD_FORMAT". + // to the clipboard - the latter with the Id "application/wxword" or + // "image/png". - void SetId( const wxString& id ) - { m_id = id; } + void SetId( const wxString& id ); wxString GetId() { return m_id; } @@ -116,20 +117,19 @@ public: private: virtual size_t GetFormatCount() const; - virtual wxDataFormat GetFormat(size_t n) const; wxString m_id; }; -// ---------------------------------------------------------------------------- +//---------------------------------------------------------------------------- // A drop target which accepts files (dragged from File Manager or Explorer) -// ---------------------------------------------------------------------------- +//---------------------------------------------------------------------------- class wxFileDropTarget: public wxDropTarget { public: - wxFileDropTarget() {}; + wxFileDropTarget(); virtual bool OnDrop( long x, long y, const void *data, size_t size ); virtual bool OnDropFiles( long x, long y, @@ -138,7 +138,6 @@ class wxFileDropTarget: public wxDropTarget protected: virtual size_t GetFormatCount() const; - virtual wxDataFormat GetFormat(size_t n) const; }; //------------------------------------------------------------------------- @@ -150,7 +149,7 @@ enum wxDragResult wxDragError, // error prevented the d&d operation from completing wxDragNone, // drag target didn't accept the data wxDragCopy, // the data was successfully copied - wxDragMove, // the data was successfully moved + wxDragMove, // the data was successfully moved (MSW only) wxDragCancel // the operation was cancelled by user (not an error) }; @@ -158,17 +157,30 @@ class wxDropSource: public wxObject { public: + /* constructor. set data later with SetData() */ wxDropSource( wxWindow *win ); - wxDropSource( wxDataObject &data, wxWindow *win ); + + /* constructor for setting one data object */ + wxDropSource( wxDataObject *data, wxWindow *win ); + + /* constructor for setting several data objects via wxDataBroker */ + wxDropSource( wxDataBroker *data, wxWindow *win ); ~wxDropSource(void); - void SetData( wxDataObject &data ); + /* set one dataobject */ + void SetData( wxDataBroker *data ); + + /* set severa dataobjects via wxDataBroker */ + void SetData( wxDataObject *data ); + + /* start drag action */ wxDragResult DoDragDrop( bool bAllowMove = FALSE ); - virtual bool GiveFeedback( wxDragResult WXUNUSED(effect), bool WXUNUSED(bScrolling) ) { return TRUE; }; + /* override to give feedback */ + virtual bool GiveFeedback( wxDragResult WXUNUSED(effect), bool WXUNUSED(bScrolling) ) { return TRUE; } - // implementation + /* GTK implementation */ void RegisterWindow(void); void UnregisterWindow(void); @@ -176,7 +188,7 @@ class wxDropSource: public wxObject GtkWidget *m_widget; wxWindow *m_window; wxDragResult m_retValue; - wxDataObject *m_data; + wxDataBroker *m_data; wxCursor m_defaultCursor; wxCursor m_goaheadCursor; diff --git a/include/wx/ipcbase.h b/include/wx/ipcbase.h index 1ceda4baa2..6bb4d924c7 100644 --- a/include/wx/ipcbase.h +++ b/include/wx/ipcbase.h @@ -20,6 +20,28 @@ #include "wx/object.h" #include "wx/string.h" +enum wxIPCFormat +{ + wxIPC_INVALID = 0, + wxIPC_TEXT = 1, /* CF_TEXT */ + wxIPC_BITMAP = 2, /* CF_BITMAP */ + wxIPC_METAFILE = 3, /* CF_METAFILEPICT */ + wxIPC_SYLK = 4, + wxIPC_DIF = 5, + wxIPC_TIFF = 6, + wxIPC_OEMTEXT = 7, /* CF_OEMTEXT */ + wxIPC_DIB = 8, /* CF_DIB */ + wxIPC_PALETTE = 9, + wxIPC_PENDATA = 10, + wxIPC_RIFF = 11, + wxIPC_WAVE = 12, + wxIPC_UNICODETEXT = 13, + wxIPC_ENHMETAFILE = 14, + wxIPC_FILENAME = 15, /* CF_HDROP */ + wxIPC_LOCALE = 16, + wxIPC_PRIVATE = 20 +}; + class WXDLLEXPORT wxDDEServerBase; class WXDLLEXPORT wxDDEClientBase; @@ -31,15 +53,15 @@ class WXDLLEXPORT wxConnectionBase: public wxObject inline ~wxConnectionBase(void) {} // Calls that CLIENT can make - virtual bool Execute(char *data, int size = -1, wxDataFormat format = wxDF_TEXT ) = 0; - virtual bool Execute(const wxString& str) { return Execute((char *)(const char *)str, -1, wxDF_TEXT); } - virtual char *Request(const wxString& item, int *size = (int *) NULL, wxDataFormat format = wxDF_TEXT) = 0; - virtual bool Poke(const wxString& item, char *data, int size = -1, wxDataFormat format = wxDF_TEXT) = 0; + virtual bool Execute(char *data, int size = -1, wxIPCFormat format = wxIPC_TEXT ) = 0; + virtual bool Execute(const wxString& str) { return Execute((char *)(const char *)str, -1, wxIPC_TEXT); } + virtual char *Request(const wxString& item, int *size = (int *) NULL, wxIPCFormat format = wxIPC_TEXT) = 0; + virtual bool Poke(const wxString& item, char *data, int size = -1, wxIPCFormat format = wxIPC_TEXT) = 0; virtual bool StartAdvise(const wxString& item) = 0; virtual bool StopAdvise(const wxString& item) = 0; // Calls that SERVER can make - virtual bool Advise(const wxString& item, char *data, int size = -1, wxDataFormat format = wxDF_TEXT) = 0; + virtual bool Advise(const wxString& item, char *data, int size = -1, wxIPCFormat format = wxIPC_TEXT) = 0; // Calls that both can make virtual bool Disconnect(void) = 0; diff --git a/include/wx/msw/dde.h b/include/wx/msw/dde.h index 183c55243c..4a8a878319 100644 --- a/include/wx/msw/dde.h +++ b/include/wx/msw/dde.h @@ -54,28 +54,28 @@ public: ~wxDDEConnection(void); // Calls that CLIENT can make - virtual bool Execute(char *data, int size = -1, wxDataFormat format = wxDF_TEXT); - virtual bool Execute(const wxString& str) { return Execute((char *)(const char *)str, -1, wxDF_TEXT); } - virtual char *Request(const wxString& item, int *size = NULL, wxDataFormat format = wxDF_TEXT); - virtual bool Poke(const wxString& item, char *data, int size = -1, wxDataFormat format = wxDF_TEXT); + virtual bool Execute(char *data, int size = -1, wxIPCFormat format = wxIPC_TEXT); + virtual bool Execute(const wxString& str) { return Execute((char *)(const char *)str, -1, wxIPC_TEXT); } + virtual char *Request(const wxString& item, int *size = NULL, wxIPCFormat format = wxIPC_TEXT); + virtual bool Poke(const wxString& item, char *data, int size = -1, wxIPCFormat format = wxIPC_TEXT); virtual bool StartAdvise(const wxString& item); virtual bool StopAdvise(const wxString& item); // Calls that SERVER can make - virtual bool Advise(const wxString& item, char *data, int size = -1, wxDataFormat format = wxDF_TEXT); + virtual bool Advise(const wxString& item, char *data, int size = -1, wxIPCFormat format = wxIPC_TEXT); // Calls that both can make virtual bool Disconnect(void); // Callbacks to SERVER - override at will - virtual bool OnExecute(const wxString& topic, char *data, int size, wxDataFormat format) { return FALSE; }; - virtual char *OnRequest(const wxString& topic, const wxString& item, int *size, wxDataFormat format) { return NULL; }; - virtual bool OnPoke(const wxString& topic, const wxString& item, char *data, int size, wxDataFormat format) { return FALSE; }; + virtual bool OnExecute(const wxString& topic, char *data, int size, wxIPCFormat format) { return FALSE; }; + virtual char *OnRequest(const wxString& topic, const wxString& item, int *size, wxIPCFormat format) { return NULL; }; + virtual bool OnPoke(const wxString& topic, const wxString& item, char *data, int size, wxIPCFormat format) { return FALSE; }; virtual bool OnStartAdvise(const wxString& topic, const wxString& item) { return FALSE; }; virtual bool OnStopAdvise(const wxString& topic, const wxString& item) { return FALSE; }; // Callbacks to CLIENT - override at will - virtual bool OnAdvise(const wxString& topic, const wxString& item, char *data, int size, wxDataFormat format) { return FALSE; }; + virtual bool OnAdvise(const wxString& topic, const wxString& item, char *data, int size, wxIPCFormat format) { return FALSE; }; // Callbacks to BOTH @@ -92,7 +92,7 @@ public: WXHCONV m_hConv; char* m_sendingData; int m_dataSize; - wxDataFormat m_dataType; + wxIPCFormat m_dataType; }; class WXDLLEXPORT wxDDEServer: public wxServerBase diff --git a/include/wx/sckipc.h b/include/wx/sckipc.h index 19a6fe2e1f..f0a80d8cbb 100644 --- a/include/wx/sckipc.h +++ b/include/wx/sckipc.h @@ -74,17 +74,17 @@ public: // Calls that CLIENT can make bool Execute(char *data, int size = -1, - wxDataFormat format = wxDF_TEXT); + wxIPCFormat format = wxIPC_TEXT); char *Request(const wxString& item, int *size = NULL, - wxDataFormat format = wxDF_TEXT); + wxIPCFormat format = wxIPC_TEXT); bool Poke(const wxString& item, char *data, int size = -1, - wxDataFormat format = wxDF_TEXT); + wxIPCFormat format = wxIPC_TEXT); bool StartAdvise(const wxString& item); bool StopAdvise(const wxString& item); // Calls that SERVER can make bool Advise(const wxString& item, char *data, int size = -1, - wxDataFormat format = wxDF_TEXT); + wxIPCFormat format = wxIPC_TEXT); // Calls that both can make bool Disconnect(); diff --git a/samples/controls/controls.cpp b/samples/controls/controls.cpp index 41860f5bb5..4e2621c15c 100644 --- a/samples/controls/controls.cpp +++ b/samples/controls/controls.cpp @@ -438,13 +438,6 @@ void MyPanel::OnPasteFromClipboard( wxCommandEvent &WXUNUSED(event) ) { #ifdef __WXGTK__ - if (!wxTheClipboard->IsSupportedFormat( wxDF_TEXT )) - { - *m_text << "The clipboard doesn't contain any data in the requested format." << "\n"; - - return; - } - if (!wxTheClipboard->Open()) { *m_text << "Error opening the clipboard." << "\n"; @@ -485,8 +478,6 @@ void MyPanel::OnCopyToClipboard( wxCommandEvent &WXUNUSED(event) ) if (text.IsEmpty()) return; - wxTextDataObject *data = new wxTextDataObject( text ); - if (!wxTheClipboard->Open()) { *m_text << "Error opening the clipboard." << "\n"; @@ -498,7 +489,11 @@ void MyPanel::OnCopyToClipboard( wxCommandEvent &WXUNUSED(event) ) *m_text << "Successfully opened the clipboard." << "\n"; } - if (!wxTheClipboard->SetData( data )) + wxTextDataObject *data = new wxTextDataObject( text ); + wxDataBroker *broker = new wxDataBroker(); + broker->Add( data ); + + if (!wxTheClipboard->SetData( broker )) { *m_text << "Error while copying to the clipboard." << "\n"; } diff --git a/samples/db/dbtest.cpp b/samples/db/dbtest.cpp index 445fc8fb18..fb6d2dc30d 100644 --- a/samples/db/dbtest.cpp +++ b/samples/db/dbtest.cpp @@ -622,10 +622,7 @@ CeditorDlg::CeditorDlg(wxWindow *parent) : wxPanel (parent, 1, 1, 460, 455) // The constructed where clause below has a sub-query within it "SELECT MIN(NAME) FROM %s" // to achieve a single row (in this case the first name in alphabetical order). - Contact->whereStr.Printf("NAME = 'Robert'",Contact->tableName); -/* Contact->whereStr.Printf("NAME = (SELECT MIN(NAME) FROM %s)",Contact->tableName); -*/ // NOTE: (const char*) returns a pointer which may not be valid later, so this is short term use only Contact->where = (char*) (const char*) Contact->whereStr; @@ -786,12 +783,9 @@ void CeditorDlg::OnCommand(wxWindow& win, wxCommandEvent& event) } // Previous record not available, retrieve first record in table - Contact->whereStr = "NAME = 'Robert' "; -/* Contact->whereStr = "NAME = (SELECT MIN(NAME) FROM "; Contact->whereStr += Contact->tableName; Contact->whereStr += ")"; -*/ Contact->where = (char*) (const char*) Contact->whereStr; if (!Contact->Query()) { @@ -842,10 +836,9 @@ void CeditorDlg::OnCommand(wxWindow& win, wxCommandEvent& event) if (strcmp(qryWhere, (const char*) Contact->qryWhereStr)) { Contact->orderBy = "NAME"; -/* Contact->whereStr = "NAME = (SELECT MIN(NAME) FROM "; Contact->whereStr += CONTACT_TABLE_NAME; -*/ + // Append the query where string (if there is one) Contact->qryWhereStr = qryWhere; if (strlen(qryWhere)) @@ -885,12 +878,11 @@ void CeditorDlg::OnCommand(wxWindow& win, wxCommandEvent& event) // Query the first record in the table Contact->orderBy = "NAME"; - Contact->whereStr = "NAME = 'Robert' "; -/* + Contact->whereStr = "NAME = (SELECT MIN(NAME) FROM "; Contact->whereStr += CONTACT_TABLE_NAME; Contact->whereStr += ")"; -*/ + Contact->where = (char*) (const char*) Contact->whereStr; if (!Contact->Query()) { @@ -1210,10 +1202,8 @@ bool CeditorDlg::GetNextRec() { wxString w; -/* + w = "NAME = (SELECT MIN(NAME) FROM "; -*/ - w = "NAME = (SELECT NAME FROM "; w += Contact->tableName; w += " WHERE NAME > '"; w += Contact->Name; diff --git a/samples/db/dbtest.h b/samples/db/dbtest.h index 0a58f99fe0..516204e389 100644 --- a/samples/db/dbtest.h +++ b/samples/db/dbtest.h @@ -26,7 +26,7 @@ enum DialogModes {mView,mCreate,mEdit,mSearch}; // Name of the table to be created/opened -const char CONTACT_TABLE_NAME[] = "CONTACTS"; +const char CONTACT_TABLE_NAME[] = "contacts"; // Nuber of columns in the above table const int CONTACT_NO_COLS = 12; // 0-11 diff --git a/samples/dnd/dnd.cpp b/samples/dnd/dnd.cpp index 66bf027609..7c66964f3e 100644 --- a/samples/dnd/dnd.cpp +++ b/samples/dnd/dnd.cpp @@ -309,8 +309,7 @@ void DnDFrame::OnLeftDown(wxMouseEvent &WXUNUSED(event) ) { // start drag operation - wxTextDataObject data(m_strText); - wxDropSource dragSource(data, this); + wxDropSource dragSource( new wxTextDataObject (m_strText), this ); const char *pc; switch ( dragSource.DoDragDrop(TRUE) ) diff --git a/src/common/sckipc.cpp b/src/common/sckipc.cpp index 718211b7dc..0003b97093 100644 --- a/src/common/sckipc.cpp +++ b/src/common/sckipc.cpp @@ -211,7 +211,7 @@ bool wxTCPConnection::Disconnect (void) return TRUE; } -bool wxTCPConnection::Execute (char *data, int size, wxDataFormat format) +bool wxTCPConnection::Execute (char *data, int size, wxIPCFormat format) { if (!m_sock->IsConnected()) return FALSE; @@ -229,7 +229,7 @@ bool wxTCPConnection::Execute (char *data, int size, wxDataFormat format) return TRUE; } -char *wxTCPConnection::Request (const wxString& item, int *size, wxDataFormat format) +char *wxTCPConnection::Request (const wxString& item, int *size, wxIPCFormat format) { if (!m_sock->IsConnected()) return NULL; @@ -258,7 +258,7 @@ char *wxTCPConnection::Request (const wxString& item, int *size, wxDataFormat fo } } -bool wxTCPConnection::Poke (const wxString& item, char *data, int size, wxDataFormat format) +bool wxTCPConnection::Poke (const wxString& item, char *data, int size, wxIPCFormat format) { if (!m_sock->IsConnected()) return FALSE; @@ -314,7 +314,7 @@ bool wxTCPConnection::StopAdvise (const wxString& item) // Calls that SERVER can make bool wxTCPConnection::Advise (const wxString& item, - char *data, int size, wxDataFormat format) + char *data, int size, wxIPCFormat format) { if (!m_sock->IsConnected()) return FALSE; @@ -358,9 +358,9 @@ void Client_OnRequest(wxSocketBase& sock, wxSocketBase::wxRequestEvent evt, case IPC_EXECUTE: { char *data; size_t size; - wxDataFormat format; + wxIPCFormat format; - format = (wxDataFormat)codeci->Read8(); + format = (wxIPCFormat)codeci->Read8(); size = codeci->Read32(); data = new char[size]; codeci->Read(data, size); @@ -373,10 +373,10 @@ void Client_OnRequest(wxSocketBase& sock, wxSocketBase::wxRequestEvent evt, case IPC_ADVISE: { char *data; size_t size; - wxDataFormat format; + wxIPCFormat format; item = codeci->ReadString(); - format = (wxDataFormat)codeci->Read8(); + format = (wxIPCFormat)codeci->Read8(); size = codeci->Read32(); data = new char[size]; codeci->Read(data, size); @@ -409,12 +409,12 @@ void Client_OnRequest(wxSocketBase& sock, wxSocketBase::wxRequestEvent evt, break; } case IPC_POKE: { - wxDataFormat format; + wxIPCFormat format; size_t size; char *data; item = codeci->ReadString(); - format = (wxDataFormat)codeci->Read8(); + format = (wxIPCFormat)codeci->Read8(); size = codeci->Read32(); data = new char[size]; codeci->Read(data, size); @@ -426,10 +426,10 @@ void Client_OnRequest(wxSocketBase& sock, wxSocketBase::wxRequestEvent evt, break; } case IPC_REQUEST: { - wxDataFormat format; + wxIPCFormat format; item = codeci->ReadString(); - format = (wxDataFormat)codeci->Read8(); + format = (wxIPCFormat)codeci->Read8(); int user_size = -1; char *user_data = connection->OnRequest (topic_name, item, &user_size, format); diff --git a/src/gtk/app.cpp b/src/gtk/app.cpp index 65db013776..7b938e7667 100644 --- a/src/gtk/app.cpp +++ b/src/gtk/app.cpp @@ -19,6 +19,7 @@ #include "wx/memory.h" #include "wx/font.h" #include "wx/settings.h" +#include "wx/dialog.h" #if wxUSE_WX_RESOURCES #include "wx/resource.h" #endif @@ -158,11 +159,14 @@ gint wxapp_idle_callback( gpointer WXUNUSED(data) ) wxApp::wxApp() { - m_idleTag = 0; + wxTheApp = this; + m_topWindow = (wxWindow *) NULL; m_exitOnFrameDelete = TRUE; + + m_idleTag = gtk_idle_add( wxapp_idle_callback, (gpointer) NULL ); + m_colorCube = (unsigned char*) NULL; - wxTheApp = this; } wxApp::~wxApp(void) @@ -172,35 +176,36 @@ wxApp::~wxApp(void) if (m_colorCube) free(m_colorCube); } -bool wxApp::InitVisual() +bool wxApp::OnInitGui() { /* Nothing to do for 15, 16, 24, 32 bit displays */ GdkVisual *visual = gdk_visual_get_system(); if (visual->depth > 8) return TRUE; - - /* this initiates the standard palette as defined by GdkImlib - in the GNOME libraries. it ensures that all GNOME applications - use the same 64 colormap entries on 8-bit displays so you - can use several rather graphics-heavy applications at the - same time */ - /* - GdkColormap *cmap = gdk_colormap_new( gdk_visual_get_system(), TRUE ); + /* this initiates the standard palette as defined by GdkImlib + in the GNOME libraries. it ensures that all GNOME applications + use the same 64 colormap entries on 8-bit displays so you + can use several rather graphics-heavy applications at the + same time. + NOTE: this doesn't really seem to work this way... */ - for (int i = 0; i < 64; i++) - { - GdkColor col; - col.red = g_palette[i*3 + 0] << 8; - col.green = g_palette[i*3 + 1] << 8; - col.blue = g_palette[i*3 + 2] << 8; - col.pixel = 0; + /* + GdkColormap *cmap = gdk_colormap_new( gdk_visual_get_system(), TRUE ); - gdk_color_alloc( cmap, &col ); - } + for (int i = 0; i < 64; i++) + { + GdkColor col; + col.red = g_palette[i*3 + 0] << 8; + col.green = g_palette[i*3 + 1] << 8; + col.blue = g_palette[i*3 + 2] << 8; + col.pixel = 0; + + gdk_color_alloc( cmap, &col ); + } - gtk_widget_set_default_colormap( cmap ); - */ + gtk_widget_set_default_colormap( cmap ); + */ /* initialize color cube for 8-bit color reduction dithering */ @@ -235,27 +240,11 @@ bool wxApp::InitVisual() } } } - - return TRUE; -} -bool wxApp::OnInitGui(void) -{ - m_idleTag = gtk_idle_add( wxapp_idle_callback, NULL ); return TRUE; } -bool wxApp::OnInit(void) -{ - return TRUE; -} - -int wxApp::OnRun(void) -{ - return MainLoop(); -} - bool wxApp::ProcessIdle(void) { wxIdleEvent event; @@ -330,11 +319,6 @@ bool wxApp::SendIdleEvents( wxWindow* win ) return needMore ; } -int wxApp::OnExit(void) -{ - return 0; -} - int wxApp::MainLoop(void) { gtk_main(); @@ -389,39 +373,43 @@ void wxApp::SetTopWindow( wxWindow *win ) m_topWindow = win; } -void wxApp::CommonInit(void) +bool wxApp::Initialize(void) { - wxSystemSettings::Init(); + wxBuffer = new char[BUFSIZ + 512]; + + wxClassInfo::InitializeClasses(); + + wxSystemSettings::Init(); - wxTheFontNameDirectory = new wxFontNameDirectory; - wxTheFontNameDirectory->Initialize(); + wxTheFontNameDirectory = new wxFontNameDirectory; + wxTheFontNameDirectory->Initialize(); - wxTheColourDatabase = new wxColourDatabase(wxKEY_STRING); - wxTheColourDatabase->Initialize(); + wxTheColourDatabase = new wxColourDatabase( wxKEY_STRING ); + wxTheColourDatabase->Initialize(); - wxInitializeStockLists(); - wxInitializeStockObjects(); + wxInitializeStockLists(); + wxInitializeStockObjects(); #if wxUSE_WX_RESOURCES - wxTheResourceCache = new wxResourceCache(wxKEY_STRING); + wxTheResourceCache = new wxResourceCache( wxKEY_STRING ); - wxInitializeResourceSystem(); + wxInitializeResourceSystem(); #endif - wxImage::InitStandardHandlers(); + wxImage::InitStandardHandlers(); -// g_globalCursor = new wxCursor; + /* no global cursor under X + g_globalCursor = new wxCursor; */ + + wxModule::RegisterModules(); + if (!wxModule::InitializeModules()) return FALSE; + + return TRUE; } -void wxApp::CommonCleanUp(void) +void wxApp::CleanUp(void) { - if (wxTheColourDatabase) delete wxTheColourDatabase; - wxTheColourDatabase = (wxColourDatabase*) NULL; - - if (wxTheFontNameDirectory) delete wxTheFontNameDirectory; - wxTheFontNameDirectory = (wxFontNameDirectory*) NULL; - - wxDeleteStockObjects(); + wxModule::CleanUpModules(); #if wxUSE_WX_RESOURCES wxFlushResources(); @@ -432,16 +420,47 @@ void wxApp::CommonCleanUp(void) wxCleanUpResourceSystem(); #endif + if (wxTheColourDatabase) delete wxTheColourDatabase; + wxTheColourDatabase = (wxColourDatabase*) NULL; + + if (wxTheFontNameDirectory) delete wxTheFontNameDirectory; + wxTheFontNameDirectory = (wxFontNameDirectory*) NULL; + + wxDeleteStockObjects(); + wxDeleteStockLists(); wxImage::CleanUpHandlers(); + delete wxTheApp; + wxTheApp = (wxApp*) NULL; + + /* check for memory leaks */ +#if (defined(__WXDEBUG__) && wxUSE_MEMORY_TRACING) || wxUSE_DEBUG_CONTEXT + if (wxDebugContext::CountObjectsLeft() > 0) + { + wxLogDebug("There were memory leaks.\n"); + wxDebugContext::Dump(); + wxDebugContext::PrintStatistics(); + } +#endif + + /* do this as the very last thing because everything else can log messages */ + wxLog::DontCreateOnDemand(); + + wxLog *oldLog = wxLog::SetActiveTarget( (wxLog*) NULL ); + if (oldLog) delete oldLog; + wxSystemSettings::Done(); + + wxClassInfo::CleanUpClasses(); + + delete[] wxBuffer; } wxLog *wxApp::CreateLogTarget() { - return new wxLogGui; + return new wxLogGui; } //----------------------------------------------------------------------------- @@ -450,10 +469,11 @@ wxLog *wxApp::CreateLogTarget() int wxEntry( int argc, char *argv[] ) { - wxBuffer = new char[BUFSIZ + 512]; + gtk_set_locale(); - wxClassInfo::InitializeClasses(); + gtk_init( &argc, &argv ); + if (!wxApp::Initialize()) return 0; if (!wxTheApp) { @@ -485,22 +505,11 @@ int wxEntry( int argc, char *argv[] ) wxStripExtension( name ); wxTheApp->SetAppName( name ); - gtk_set_locale(); - - gtk_init( &argc, &argv ); - - if (!wxTheApp->InitVisual()) return 0; - - wxApp::CommonInit(); - if (!wxTheApp->OnInitGui()) return 0; - wxModule::RegisterModules(); - if (!wxModule::InitializeModules()) return FALSE; - - // Here frames insert themselves automatically - // into wxTopLevelWindows by getting created - // in OnInit(). + /* Here frames insert themselves automatically + * into wxTopLevelWindows by getting created + * in OnInit(). */ if (!wxTheApp->OnInit()) return 0; @@ -510,34 +519,31 @@ int wxEntry( int argc, char *argv[] ) if (wxTheApp->Initialized()) retValue = wxTheApp->OnRun(); - wxTheApp->DeletePendingObjects(); - - wxTheApp->OnExit(); - - wxModule::CleanUpModules(); - - wxApp::CommonCleanUp(); - - delete wxTheApp; - wxTheApp = (wxApp*) NULL; - - wxClassInfo::CleanUpClasses(); - - delete[] wxBuffer; - -#if (defined(__WXDEBUG__) && wxUSE_MEMORY_TRACING) || wxUSE_DEBUG_CONTEXT - - if (wxDebugContext::CountObjectsLeft() > 0) + wxWindow *topWindow = wxTheApp->GetTopWindow(); + if (topWindow) { - wxLogDebug("There were memory leaks.\n"); - wxDebugContext::Dump(); - wxDebugContext::PrintStatistics(); + /* Forcibly delete the window. */ + if (topWindow->IsKindOf(CLASSINFO(wxFrame)) || + topWindow->IsKindOf(CLASSINFO(wxDialog)) ) + { + topWindow->Close( TRUE ); + wxTheApp->DeletePendingObjects(); + } + else + { + delete topWindow; + wxTheApp->SetTopWindow( (wxWindow*) NULL ); + } } -#endif + wxTheApp->OnExit(); - wxLog *oldLog = wxLog::SetActiveTarget( (wxLog*) NULL ); - if (oldLog) delete oldLog; + /* flush the logged messages if any */ + wxLog *log = wxLog::GetActiveTarget(); + if (log != NULL && log->HasPendingMessages()) + log->Flush(); + + wxApp::CleanUp(); return retValue; } diff --git a/src/gtk/clipbrd.cpp b/src/gtk/clipbrd.cpp index 4314ac726b..11096c3a4c 100644 --- a/src/gtk/clipbrd.cpp +++ b/src/gtk/clipbrd.cpp @@ -104,12 +104,12 @@ selection_received( GtkWidget *WXUNUSED(widget), // make sure we got the data in the correct format - if (data_object->m_formatAtom != selection_data->target) return; + if (data_object->GetFormat().GetAtom() != selection_data->target) return; // make sure we got the data in the correct form (selection type). // if so, copy data to target object - switch (data_object->GetFormat()) + switch (data_object->GetFormat().GetType()) { case wxDF_TEXT: { @@ -179,10 +179,13 @@ selection_clear_clip( GtkWidget *WXUNUSED(widget), GdkEventSelection *event ) if ((!wxTheClipboard->m_ownsPrimarySelection) && (!wxTheClipboard->m_ownsClipboard)) { - // the clipboard is no longer in our hands. we can the - // clipboard data. - - wxTheClipboard->m_dataObjects.Clear(); + /* the clipboard is no longer in our hands. we can the clipboard data. */ + + if (wxTheClipboard->m_dataBroker) + { + delete wxTheClipboard->m_dataBroker; + wxTheClipboard->m_dataBroker = (wxDataBroker*) NULL; + } } return TRUE; @@ -197,19 +200,21 @@ selection_handler( GtkWidget *WXUNUSED(widget), GtkSelectionData *selection_data { if (!wxTheClipboard) return; - wxNode *node = wxTheClipboard->m_dataObjects.First(); + if (!wxTheClipboard->m_dataBroker) return; + + wxNode *node = wxTheClipboard->m_dataBroker->m_dataObjects.First(); while (node) { wxDataObject *data_object = (wxDataObject *)node->Data(); - if (data_object->m_formatAtom != selection_data->target) + if (data_object->GetFormat().GetAtom() != selection_data->target) { node = node->Next(); break; } - switch (data_object->GetFormat()) + switch (data_object->GetFormat().GetType()) { case wxDF_TEXT: { @@ -243,14 +248,14 @@ selection_handler( GtkWidget *WXUNUSED(widget), GtkSelectionData *selection_data { wxPrivateDataObject *private_object = (wxPrivateDataObject*) data_object; - if (private_object->GetDataSize() == 0) return; + if (private_object->GetSize() == 0) return; gtk_selection_data_set( selection_data, GDK_SELECTION_TYPE_STRING, 8*sizeof(gchar), (unsigned char*) private_object->GetData(), - (int) private_object->GetDataSize() ); + (int) private_object->GetSize() ); } default: @@ -274,7 +279,7 @@ wxClipboard::wxClipboard() m_ownsClipboard = FALSE; m_ownsPrimarySelection = FALSE; - m_dataObjects.DeleteContents( TRUE ); + m_dataBroker = (wxDataBroker*) NULL; m_receivedData = (wxDataObject*) NULL; @@ -303,7 +308,7 @@ wxClipboard::~wxClipboard() void wxClipboard::Clear() { - if (m_dataObjects.GetCount()) + if (m_dataBroker) { /* As we have data we also own the clipboard. Once we no longer own it, clear_selection is called which will set m_data to zero */ @@ -318,7 +323,11 @@ void wxClipboard::Clear() gtk_selection_owner_set( (GtkWidget*) NULL, GDK_SELECTION_PRIMARY, GDK_CURRENT_TIME ); } - m_dataObjects.Clear(); + if (m_dataBroker) + { + delete m_dataBroker; + m_dataBroker = (wxDataBroker*) NULL; + } } m_targetRequested = 0; @@ -335,79 +344,67 @@ bool wxClipboard::Open() return TRUE; } -bool wxClipboard::SetData( wxDataObject *data ) +bool wxClipboard::SetData( wxDataBroker *data ) { wxCHECK_MSG( data, FALSE, "data is invalid" ); - wxNode *node = m_dataObjects.First(); - - while (node) - { - wxDataObject *d = (wxDataObject*)node->Data(); - - if (d->GetFormat() == data->GetFormat()) - { - m_dataObjects.DeleteNode( node ); - - break; - } - - node = node->Next(); - } + Clear(); + + m_dataBroker = data; - m_dataObjects.Append( data ); + if (!m_dataBroker) return FALSE; wxCHECK_MSG( m_open, FALSE, "clipboard not open" ); - if (data->GetFormat() == wxDF_PRIVATE) + wxNode *node = m_dataBroker->m_dataObjects.First(); + while (node) { - wxPrivateDataObject* pd = (wxPrivateDataObject*) data; + wxDataObject *dobj = (wxDataObject*)node->Data(); - wxCHECK_MSG( !pd->GetId().IsEmpty(), FALSE, "private clipboard format requires ID string" ); + GdkAtom format = dobj->GetFormat().GetAtom(); - data->m_formatAtom = GetTargetAtom( data->GetFormat(), pd->GetId() ); - } - else - { - data->m_formatAtom = GetTargetAtom( data->GetFormat() ); - } - - // This should happen automatically + if (format != (GdkAtom) 0) + { + /* This should happen automatically */ - m_ownsClipboard = FALSE; - m_ownsPrimarySelection = FALSE; + m_ownsClipboard = FALSE; + m_ownsPrimarySelection = FALSE; - // Add handlers if someone requests data + /* Add handlers if someone requests data */ - gtk_selection_add_handler( m_clipboardWidget, + gtk_selection_add_handler( m_clipboardWidget, g_clipboardAtom, - data->m_formatAtom, + format, selection_handler, - NULL ); + (gpointer) NULL ); - gtk_selection_add_handler( m_clipboardWidget, + gtk_selection_add_handler( m_clipboardWidget, GDK_SELECTION_PRIMARY, - data->m_formatAtom, + format, selection_handler, - NULL ); + (gpointer) NULL ); - // Tell the world we offer clipboard data + /* Tell the world we offer clipboard data */ - if (!gtk_selection_owner_set( m_clipboardWidget, + if (!gtk_selection_owner_set( m_clipboardWidget, g_clipboardAtom, GDK_CURRENT_TIME )) - { - return FALSE; - } - m_ownsClipboard = TRUE; + { + return FALSE; + } + m_ownsClipboard = TRUE; - if (!gtk_selection_owner_set( m_clipboardWidget, + if (!gtk_selection_owner_set( m_clipboardWidget, GDK_SELECTION_PRIMARY, GDK_CURRENT_TIME )) - { - return FALSE; + { + return FALSE; + } + m_ownsPrimarySelection = TRUE; + } + + node = node->Next(); } - m_ownsPrimarySelection = TRUE; return TRUE; } @@ -419,13 +416,23 @@ void wxClipboard::Close() m_open = FALSE; } -bool wxClipboard::IsSupportedFormat( wxDataFormat format, const wxString &id ) +bool wxClipboard::GetData( wxDataObject *data ) { - m_targetRequested = GetTargetAtom( format, id ); + wxCHECK_MSG( m_open, FALSE, "clipboard not open" ); + + m_receivedData = data; + + wxCHECK_MSG( m_receivedData, FALSE, "invalid data object" ); + + /* STEP ONE: check if there is such data in the clipboard */ + + m_targetRequested = data->GetFormat().GetAtom(); + wxCHECK_MSG( m_targetRequested, FALSE, "invalid clipboard format" ); + if (m_targetRequested == 0) return FALSE; - // add handler for target (= format) query + /* add handler for target (= format) query */ gtk_signal_connect( GTK_OBJECT(m_clipboardWidget), "selection_received", @@ -434,8 +441,8 @@ bool wxClipboard::IsSupportedFormat( wxDataFormat format, const wxString &id ) m_formatSupported = FALSE; - // perform query. this will set m_formatSupported to - // TRUE if m_targetRequested is supported + /* perform query. this will set m_formatSupported to + * TRUE if m_targetRequested is supported */ gtk_selection_convert( m_clipboardWidget, g_clipboardAtom, @@ -448,34 +455,8 @@ bool wxClipboard::IsSupportedFormat( wxDataFormat format, const wxString &id ) if (!m_formatSupported) return FALSE; - return TRUE; -} - -bool wxClipboard::GetData( wxDataObject *data ) -{ - wxCHECK_MSG( m_open, FALSE, "clipboard not open" ); - - m_receivedData = data; - - wxCHECK_MSG( m_receivedData, FALSE, "invalid data object" ); + /* STEP TWO: get the data from the clipboard */ - if (m_receivedData->GetFormat() == wxDF_PRIVATE) - { - wxPrivateDataObject* pd = (wxPrivateDataObject*) m_receivedData; - - wxCHECK_MSG( !pd->GetId().IsEmpty(), FALSE, "private clipboard format requires ID string" ); - - m_targetRequested = GetTargetAtom( m_receivedData->GetFormat(), pd->GetId() ); - } - else - { - m_targetRequested = GetTargetAtom( m_receivedData->GetFormat() ); - } - - data->m_formatAtom = m_targetRequested; - - wxCHECK_MSG( m_targetRequested, FALSE, "unsupported clipboard format" ); - m_formatSupported = FALSE; gtk_signal_connect( GTK_OBJECT(m_clipboardWidget), @@ -492,45 +473,13 @@ bool wxClipboard::GetData( wxDataObject *data ) GTK_SIGNAL_FUNC( selection_received ), (gpointer) this ); + /* this is a true error as we checked for the presence of such data before */ + wxCHECK_MSG( m_formatSupported, FALSE, "error retrieving data from clipboard" ); return TRUE; } -GdkAtom wxClipboard::GetTargetAtom( wxDataFormat format, const wxString &id ) -{ - // What is X representation of that format? - - switch (format) - { - case wxDF_TEXT: - { - return GDK_TARGET_STRING; - // g_textAtom - } - - case wxDF_BITMAP: - { - return GDK_TARGET_BITMAP; - break; - } - - case wxDF_PRIVATE: - { - // we create our own X representation - - return gdk_atom_intern( WXSTRINGCAST( id ), FALSE ); - } - - default: - { - return (GdkAtom) 0; - } - } - - return (GdkAtom) 0; -} - //----------------------------------------------------------------------------- // wxClipboardModule //----------------------------------------------------------------------------- diff --git a/src/gtk/dataobj.cpp b/src/gtk/dataobj.cpp index 353633fc7c..59dac39832 100644 --- a/src/gtk/dataobj.cpp +++ b/src/gtk/dataobj.cpp @@ -13,6 +13,230 @@ #include "wx/dataobj.h" #include "wx/app.h" +#include "wx/debug.h" + +#include "gdk/gdk.h" + +//------------------------------------------------------------------------- +// wxDataFormat +//------------------------------------------------------------------------- + +IMPLEMENT_CLASS(wxDataFormat, wxObject) + +wxDataFormat::wxDataFormat( wxDataType type ) +{ + m_type = type; + + if (m_type == wxDF_TEXT) + { + m_id = "STRING"; + } + else + if (m_type == wxDF_BITMAP) + { + m_id = "BITMAP"; + } + else + if (m_type == wxDF_FILENAME) + { + m_id = "file:ALL"; + } + else + { + wxFAIL_MSG( "invalid dataformat" ) + } + + m_hasAtom = FALSE; +} + +wxDataFormat::wxDataFormat( const wxString &id ) +{ + m_type = wxDF_PRIVATE; + m_id = id; + m_hasAtom = FALSE; +} + +wxDataFormat::wxDataFormat( wxDataFormat &format ) +{ + m_type = format.GetType(); + m_id = format.GetId(); + m_hasAtom = TRUE; + m_atom = format.GetAtom(); +} + +wxDataFormat::wxDataFormat( const GdkAtom atom ) +{ + m_hasAtom = TRUE; + + m_atom = atom; + + if (m_atom == GDK_TARGET_STRING) + { + m_type = wxDF_TEXT; + } else + if (m_atom == GDK_TARGET_BITMAP) + { + m_type = wxDF_BITMAP; + } else + { + m_type = wxDF_PRIVATE; + m_id = gdk_atom_name( m_atom ); + + if (m_id == "file:ALL") + { + m_type = wxDF_FILENAME; + } + } +} + +int wxDataFormat::GetType() const +{ + return m_type; +} + +wxString wxDataFormat::GetId() const +{ + return m_id; +} + +void wxDataFormat::SetId( const wxString &id ) +{ + m_type = wxDF_PRIVATE; + m_id = id; + m_hasAtom = FALSE; +} + +GdkAtom wxDataFormat::GetAtom() +{ + if (!m_hasAtom) + { + m_hasAtom = TRUE; + + if (m_type == wxDF_TEXT) + { + m_atom = GDK_TARGET_STRING; + } + else + if (m_type == wxDF_BITMAP) + { + m_atom = GDK_TARGET_BITMAP; + } + else + if (m_type == wxDF_PRIVATE) + { + m_atom = gdk_atom_intern( WXSTRINGCAST( m_id ), FALSE ); + } + else + if (m_type == wxDF_FILENAME) + { + m_atom = gdk_atom_intern( "file:ALL", FALSE ); + } + else + { + m_hasAtom = FALSE; + m_atom = (GdkAtom) 0; + } + } + + return m_atom; +} + +//------------------------------------------------------------------------- +// wxDataBroker +//------------------------------------------------------------------------- + +IMPLEMENT_CLASS(wxDataBroker,wxObject) + +wxDataBroker::wxDataBroker() +{ + m_dataObjects.DeleteContents(TRUE); + m_preferred = 0; +} + +void wxDataBroker::Add( wxDataObject *dataObject, bool preferred ) +{ + if (preferred) m_preferred = m_dataObjects.GetCount(); + m_dataObjects.Append( dataObject ); +} + +size_t wxDataBroker::GetFormatCount() const +{ + return m_dataObjects.GetCount(); +} + +wxDataFormat &wxDataBroker::GetPreferredFormat() const +{ + wxNode *node = m_dataObjects.Nth( m_preferred ); + + wxASSERT( node ); + + wxDataObject* data_obj = (wxDataObject*)node->Data(); + + return data_obj->GetFormat(); +} + +wxDataFormat &wxDataBroker::GetNthFormat( size_t nth ) const +{ + wxNode *node = m_dataObjects.Nth( nth ); + + wxASSERT( node ); + + wxDataObject* data_obj = (wxDataObject*)node->Data(); + + return data_obj->GetFormat(); +} + +bool wxDataBroker::IsSupportedFormat( wxDataFormat &format ) const +{ + wxNode *node = m_dataObjects.First(); + while (node) + { + wxDataObject *dobj = (wxDataObject*)node->Data(); + + if (dobj->GetFormat().GetAtom() == format.GetAtom()) + { + return TRUE; + } + + node = node->Next(); + } + + return FALSE; +} + +size_t wxDataBroker::GetSize( wxDataFormat& format ) const +{ + wxNode *node = m_dataObjects.First(); + while (node) + { + wxDataObject *dobj = (wxDataObject*)node->Data(); + + if (dobj->GetFormat().GetAtom() == format.GetAtom()) + { + return dobj->GetSize(); + } + + node = node->Next(); + } + + return 0; +} + +void wxDataBroker::WriteData( wxDataFormat& format, void *dest ) const +{ + wxNode *node = m_dataObjects.First(); + while (node) + { + wxDataObject *dobj = (wxDataObject*)node->Data(); + + if (dobj->GetFormat().GetAtom() == format.GetAtom()) + { + return dobj->WriteData( dest ); + } + + node = node->Next(); + } +} //------------------------------------------------------------------------- // wxDataObject @@ -20,24 +244,141 @@ IMPLEMENT_ABSTRACT_CLASS( wxDataObject, wxObject ) +wxDataObject::wxDataObject() +{ + m_format = (wxDataFormat*) NULL; +} + +wxDataObject::~wxDataObject() +{ + if (m_format) delete m_format; +} + +wxDataFormat &wxDataObject::GetFormat() const +{ + wxASSERT( m_format ); + + return (*m_format); +} + // ---------------------------------------------------------------------------- // wxTextDataObject // ---------------------------------------------------------------------------- IMPLEMENT_DYNAMIC_CLASS( wxTextDataObject, wxDataObject ) +wxTextDataObject::wxTextDataObject() +{ + m_format = new wxDataFormat( wxDF_TEXT ); +} + +wxTextDataObject::wxTextDataObject( const wxString& data ) +{ + m_format = new wxDataFormat( wxDF_TEXT ); + + m_data = data; +} + +void wxTextDataObject::SetText( const wxString& data ) +{ + m_data = data; +} + +wxString wxTextDataObject::GetText() const +{ + return m_data; +} + +void wxTextDataObject::WriteData( void *dest ) const +{ + WriteString( m_data, dest ); +} + +size_t wxTextDataObject::GetSize() const +{ + return m_data.Len() + 1; +} + +void wxTextDataObject::WriteString( const wxString &str, void *dest ) const +{ + memcpy( dest, m_data.c_str(), GetSize() ); +} + // ---------------------------------------------------------------------------- // wxFileDataObject // ---------------------------------------------------------------------------- IMPLEMENT_DYNAMIC_CLASS( wxFileDataObject, wxDataObject ) +wxFileDataObject::wxFileDataObject(void) +{ + m_format = new wxDataFormat( wxDF_FILENAME ); +} + +void wxFileDataObject::AddFile( const wxString &file ) +{ + m_files += file; + m_files += (char)0; +} + +wxString wxFileDataObject::GetFiles() const +{ + return m_files; +} + +void wxFileDataObject::WriteData( void *dest ) const +{ + memcpy( dest, m_files.c_str(), GetSize() ); +} + +size_t wxFileDataObject::GetSize() const +{ + return m_files.Len() + 1; +} + // ---------------------------------------------------------------------------- // wxBitmapDataObject // ---------------------------------------------------------------------------- IMPLEMENT_DYNAMIC_CLASS( wxBitmapDataObject, wxDataObject ) +wxBitmapDataObject::wxBitmapDataObject() +{ + m_format = new wxDataFormat( wxDF_BITMAP ); +} + +wxBitmapDataObject::wxBitmapDataObject( const wxBitmap& bitmap ) +{ + m_format = new wxDataFormat( wxDF_BITMAP ); + + m_bitmap = bitmap; +} + +void wxBitmapDataObject::SetBitmap( const wxBitmap &bitmap ) +{ + m_bitmap = bitmap; +} + +wxBitmap wxBitmapDataObject::GetBitmap() const +{ + return m_bitmap; +} + +void wxBitmapDataObject::WriteData( void *dest ) const +{ + WriteBitmap( m_bitmap, dest ); +} + +size_t wxBitmapDataObject::GetSize() const +{ + return 0; +} + +void wxBitmapDataObject::WriteBitmap( const wxBitmap &bitmap, void *dest ) const +{ + memcpy( dest, m_bitmap.GetPixmap(), GetSize() ); +} + // ---------------------------------------------------------------------------- // wxPrivateDataObject // ---------------------------------------------------------------------------- @@ -46,9 +387,13 @@ IMPLEMENT_DYNAMIC_CLASS( wxPrivateDataObject, wxDataObject ) wxPrivateDataObject::wxPrivateDataObject() { + m_id = "application/"; + m_id += wxTheApp->GetAppName(); + + m_format = new wxDataFormat( m_id ); + m_size = 0; m_data = (char*) NULL; - m_id = wxTheApp->GetAppName(); } wxPrivateDataObject::~wxPrivateDataObject() @@ -56,6 +401,17 @@ wxPrivateDataObject::~wxPrivateDataObject() if (m_data) delete[] m_data; } +void wxPrivateDataObject::SetId( const wxString& id ) +{ + m_id = id; + m_format->SetId( m_id ); +} + +wxString wxPrivateDataObject::GetId() const +{ + return m_id; +} + void wxPrivateDataObject::SetData( const char *data, size_t size ) { m_size = size; @@ -67,3 +423,23 @@ void wxPrivateDataObject::SetData( const char *data, size_t size ) memcpy( m_data, data, size ); } +char* wxPrivateDataObject::GetData() const +{ + return m_data; +} + +void wxPrivateDataObject::WriteData( void *dest ) const +{ + WriteData( m_data, dest ); +} + +size_t wxPrivateDataObject::GetSize() const +{ + return m_size; +} + +void wxPrivateDataObject::WriteData( const char *data, void *dest ) const +{ + memcpy( dest, data, GetSize() ); +} + diff --git a/src/gtk/dialog.cpp b/src/gtk/dialog.cpp index ceba496548..f4a3d74144 100644 --- a/src/gtk/dialog.cpp +++ b/src/gtk/dialog.cpp @@ -134,7 +134,16 @@ bool wxDialog::Create( wxWindow *parent, wxDialog::~wxDialog() { wxTopLevelWindows.DeleteObject( this ); - if (wxTopLevelWindows.Number() == 0) wxTheApp->ExitMainLoop(); + + if (wxTheApp->GetTopWindow() == this) + { + wxTheApp->SetTopWindow( (wxWindow*) NULL ); + } + + if (wxTopLevelWindows.Number() == 0) + { + wxTheApp->ExitMainLoop(); + } } void wxDialog::SetTitle( const wxString& title ) diff --git a/src/gtk/dnd.cpp b/src/gtk/dnd.cpp index 4ac5d9bc3c..17c1d18258 100644 --- a/src/gtk/dnd.cpp +++ b/src/gtk/dnd.cpp @@ -171,8 +171,7 @@ void wxDropTarget::RegisterWidget( GtkWidget *widget ) break; case wxDF_PRIVATE: wxPrivateDropTarget *pdt = (wxPrivateDropTarget *)this; - strcpy( buf, "applications/" ); - strcat( buf, WXSTRINGCAST pdt->GetID() ); + strcpy( buf, WXSTRINGCAST pdt->GetID() ); format.target = buf; valid++; default: @@ -533,10 +532,17 @@ static void gtk_target_callback( GtkWidget *widget, wxDropTarget::wxDropTarget() { + m_format = (wxDataFormat*) NULL; } wxDropTarget::~wxDropTarget() { + if (m_format) delete m_format; +} + +wxDataFormat &wxDropTarget::GetFormat(size_t n) const +{ + return (*m_format); } void wxDropTarget::UnregisterWidget( GtkWidget *widget ) @@ -556,8 +562,7 @@ void wxDropTarget::RegisterWidget( GtkWidget *widget ) for ( size_t i = 0; i < GetFormatCount(); i++ ) { - wxDataFormat df = GetFormat( i ); - switch (df) + switch (GetFormat(i).GetType()) { case wxDF_TEXT: { @@ -577,7 +582,6 @@ void wxDropTarget::RegisterWidget( GtkWidget *widget ) { if (i > 0) formats += ";"; wxPrivateDropTarget *pdt = (wxPrivateDropTarget *)this; - formats += "applications/"; formats += pdt->GetId(); valid++; break; @@ -605,6 +609,11 @@ void wxDropTarget::RegisterWidget( GtkWidget *widget ) // wxTextDropTarget // ---------------------------------------------------------------------------- +wxTextDropTarget::wxTextDropTarget() +{ + m_format = new wxDataFormat( wxDF_TEXT ); +} + bool wxTextDropTarget::OnDrop( long x, long y, const void *data, size_t WXUNUSED(size) ) { OnDropText( x, y, (const char*)data ); @@ -625,11 +634,6 @@ size_t wxTextDropTarget::GetFormatCount() const return 1; } -wxDataFormat wxTextDropTarget::GetFormat(size_t WXUNUSED(n)) const -{ - return wxDF_TEXT; -} - // ---------------------------------------------------------------------------- // wxPrivateDropTarget // ---------------------------------------------------------------------------- @@ -637,22 +641,29 @@ wxDataFormat wxTextDropTarget::GetFormat(size_t WXUNUSED(n)) const wxPrivateDropTarget::wxPrivateDropTarget() { m_id = wxTheApp->GetAppName(); + m_format = new wxDataFormat( m_id ); } -size_t wxPrivateDropTarget::GetFormatCount() const +void wxPrivateDropTarget::SetId( const wxString& id ) { - return 1; + m_id = id; + m_format->SetId( id ); } -wxDataFormat wxPrivateDropTarget::GetFormat(size_t WXUNUSED(n)) const +size_t wxPrivateDropTarget::GetFormatCount() const { - return wxDF_PRIVATE; + return 1; } // ---------------------------------------------------------------------------- // wxFileDropTarget // ---------------------------------------------------------------------------- +wxFileDropTarget::wxFileDropTarget() +{ + m_format = new wxDataFormat( wxDF_FILENAME ); +} + bool wxFileDropTarget::OnDropFiles( long x, long y, size_t nFiles, const char * const aszFiles[] ) { printf( "Got %d dropped files.\n", (int)nFiles ); @@ -698,11 +709,6 @@ size_t wxFileDropTarget::GetFormatCount() const return 1; } -wxDataFormat wxFileDropTarget::GetFormat(size_t WXUNUSED(n)) const -{ - return wxDF_FILENAME; -} - //------------------------------------------------------------------------- // wxDropSource //------------------------------------------------------------------------- @@ -712,64 +718,76 @@ shape_motion (GtkWidget *widget, GdkEventMotion * /*event*/); //----------------------------------------------------------------------------- -// drag request +// "drag_request_event" +//----------------------------------------------------------------------------- -void gtk_drag_callback( GtkWidget *widget, GdkEvent *event, wxDropSource *source ) +void gtk_drag_callback( GtkWidget *widget, GdkEventDragRequest *event, wxDropSource *source ) { - wxDataObject *data = source->m_data; - - switch (data->GetFormat()) + wxDataBroker *data = source->m_data; + + if (!data) return; + + wxNode *node = data->m_dataObjects.First(); { - case wxDF_PRIVATE: - { - wxPrivateDataObject *pdo = (wxPrivateDataObject*) data; - - gtk_widget_dnd_data_set( widget, - event, - (unsigned char*) pdo->GetData(), - (int) pdo->GetDataSize() ); - - break; - } - case wxDF_TEXT: + wxDataObject *dobj = (wxDataObject*) node->Data(); + + if ((strcmp(event->data_type,"file:ALL") == 0) && + (dobj->GetFormat().GetType() == wxDF_FILENAME)) { - wxTextDataObject *text_object = (wxTextDataObject*) data; + wxFileDataObject *file_object = (wxFileDataObject*) dobj; - wxString text = text_object->GetText(); + wxString text = file_object->GetFiles(); char *s = WXSTRINGCAST text; gtk_widget_dnd_data_set( widget, - event, + (GdkEvent*)event, (unsigned char*) s, (int) text.Length()+1 ); - break; + source->m_retValue = wxDragCopy; + + return; } - case wxDF_FILENAME: + if ((strcmp(event->data_type,"text/plain") == 0) && + (dobj->GetFormat().GetType() == wxDF_TEXT)) { - wxFileDataObject *file_object = (wxFileDataObject*) data; + wxTextDataObject *text_object = (wxTextDataObject*) dobj; - wxString text = file_object->GetFiles(); + wxString text = text_object->GetText(); char *s = WXSTRINGCAST text; gtk_widget_dnd_data_set( widget, - event, + (GdkEvent*)event, (unsigned char*) s, (int) text.Length()+1 ); - break; + source->m_retValue = wxDragCopy; + + return; } - default: + if (dobj->GetFormat().GetType() == wxDF_PRIVATE) { - return; + wxPrivateDataObject *pdo = (wxPrivateDataObject*) dobj; + + if (pdo->GetId() == event->data_type) + { + gtk_widget_dnd_data_set( widget, + (GdkEvent*)event, + (unsigned char*) pdo->GetData(), + (int) pdo->GetSize() ); + + source->m_retValue = wxDragCopy; + + return; + } } + + node = node->Next(); } - - source->m_retValue = wxDragCopy; } wxDropSource::wxDropSource( wxWindow *win ) @@ -780,14 +798,14 @@ wxDropSource::wxDropSource( wxWindow *win ) m_widget = win->m_widget; if (win->m_wxwindow) m_widget = win->m_wxwindow; - m_data = (wxDataObject *) NULL; + m_data = (wxDataBroker*) NULL; m_retValue = wxDragCancel; m_defaultCursor = wxCursor( wxCURSOR_NO_ENTRY ); m_goaheadCursor = wxCursor( wxCURSOR_HAND ); } -wxDropSource::wxDropSource( wxDataObject &data, wxWindow *win ) +wxDropSource::wxDropSource( wxDataObject *data, wxWindow *win ) { g_blockEventsOnDrag = TRUE; @@ -796,20 +814,60 @@ wxDropSource::wxDropSource( wxDataObject &data, wxWindow *win ) if (win->m_wxwindow) m_widget = win->m_wxwindow; m_retValue = wxDragCancel; - m_data = &data; + if (data) + { + m_data = new wxDataBroker(); + m_data->Add( data ); + } + else + { + m_data = (wxDataBroker*) NULL; + } m_defaultCursor = wxCursor( wxCURSOR_NO_ENTRY ); m_goaheadCursor = wxCursor( wxCURSOR_HAND ); } -void wxDropSource::SetData( wxDataObject &data ) +wxDropSource::wxDropSource( wxDataBroker *data, wxWindow *win ) +{ + g_blockEventsOnDrag = TRUE; + + m_window = win; + m_widget = win->m_widget; + if (win->m_wxwindow) m_widget = win->m_wxwindow; + m_retValue = wxDragCancel; + + m_data = data; + + m_defaultCursor = wxCursor( wxCURSOR_NO_ENTRY ); + m_goaheadCursor = wxCursor( wxCURSOR_HAND ); +} + +void wxDropSource::SetData( wxDataObject *data ) +{ + if (m_data) delete m_data; + + if (data) + { + m_data = new wxDataBroker(); + m_data->Add( data ); + } + else + { + m_data = (wxDataBroker*) NULL; + } +} + +void wxDropSource::SetData( wxDataBroker *data ) { - m_data = &data; + if (m_data) delete m_data; + + m_data = data; } wxDropSource::~wxDropSource(void) { -// if (m_data) delete m_data; + if (m_data) delete m_data; g_blockEventsOnDrag = FALSE; } @@ -926,29 +984,33 @@ void wxDropSource::RegisterWindow(void) wxString formats; - wxDataFormat df = m_data->GetFormat(); - - switch (df) + wxNode *node = m_data->m_dataObjects.First(); + while (node) { - case wxDF_TEXT: - { - formats += "text/plain"; - break; - } - case wxDF_FILENAME: - { - formats += "file:ALL"; - break; - } - case wxDF_PRIVATE: - { - wxPrivateDataObject* pdo = (wxPrivateDataObject*) m_data; - formats += "applications/"; - formats += pdo->GetId(); - break; + wxDataObject* dobj = (wxDataObject*) node->Data(); + + switch (dobj->GetFormat().GetType()) + { + case wxDF_TEXT: + { + formats += "text/plain"; + break; + } + case wxDF_FILENAME: + { + formats += "file:ALL"; + break; + } + case wxDF_PRIVATE: + { + wxPrivateDataObject* pdo = (wxPrivateDataObject*) m_data; + formats += pdo->GetId(); + break; + } + default: + break; } - default: - break; + node = node->Next(); } char *str = WXSTRINGCAST formats; diff --git a/src/gtk/frame.cpp b/src/gtk/frame.cpp index 707f419dec..993bbbf75b 100644 --- a/src/gtk/frame.cpp +++ b/src/gtk/frame.cpp @@ -193,7 +193,16 @@ wxFrame::~wxFrame() if (m_frameToolBar) delete m_frameToolBar; wxTopLevelWindows.DeleteObject( this ); - if (wxTopLevelWindows.Number() == 0) wxTheApp->ExitMainLoop(); + + if (wxTheApp->GetTopWindow() == this) + { + wxTheApp->SetTopWindow( (wxWindow*) NULL ); + } + + if (wxTopLevelWindows.Number() == 0) + { + wxTheApp->ExitMainLoop(); + } } bool wxFrame::Show( bool show ) diff --git a/src/gtk1/app.cpp b/src/gtk1/app.cpp index 65db013776..7b938e7667 100644 --- a/src/gtk1/app.cpp +++ b/src/gtk1/app.cpp @@ -19,6 +19,7 @@ #include "wx/memory.h" #include "wx/font.h" #include "wx/settings.h" +#include "wx/dialog.h" #if wxUSE_WX_RESOURCES #include "wx/resource.h" #endif @@ -158,11 +159,14 @@ gint wxapp_idle_callback( gpointer WXUNUSED(data) ) wxApp::wxApp() { - m_idleTag = 0; + wxTheApp = this; + m_topWindow = (wxWindow *) NULL; m_exitOnFrameDelete = TRUE; + + m_idleTag = gtk_idle_add( wxapp_idle_callback, (gpointer) NULL ); + m_colorCube = (unsigned char*) NULL; - wxTheApp = this; } wxApp::~wxApp(void) @@ -172,35 +176,36 @@ wxApp::~wxApp(void) if (m_colorCube) free(m_colorCube); } -bool wxApp::InitVisual() +bool wxApp::OnInitGui() { /* Nothing to do for 15, 16, 24, 32 bit displays */ GdkVisual *visual = gdk_visual_get_system(); if (visual->depth > 8) return TRUE; - - /* this initiates the standard palette as defined by GdkImlib - in the GNOME libraries. it ensures that all GNOME applications - use the same 64 colormap entries on 8-bit displays so you - can use several rather graphics-heavy applications at the - same time */ - /* - GdkColormap *cmap = gdk_colormap_new( gdk_visual_get_system(), TRUE ); + /* this initiates the standard palette as defined by GdkImlib + in the GNOME libraries. it ensures that all GNOME applications + use the same 64 colormap entries on 8-bit displays so you + can use several rather graphics-heavy applications at the + same time. + NOTE: this doesn't really seem to work this way... */ - for (int i = 0; i < 64; i++) - { - GdkColor col; - col.red = g_palette[i*3 + 0] << 8; - col.green = g_palette[i*3 + 1] << 8; - col.blue = g_palette[i*3 + 2] << 8; - col.pixel = 0; + /* + GdkColormap *cmap = gdk_colormap_new( gdk_visual_get_system(), TRUE ); - gdk_color_alloc( cmap, &col ); - } + for (int i = 0; i < 64; i++) + { + GdkColor col; + col.red = g_palette[i*3 + 0] << 8; + col.green = g_palette[i*3 + 1] << 8; + col.blue = g_palette[i*3 + 2] << 8; + col.pixel = 0; + + gdk_color_alloc( cmap, &col ); + } - gtk_widget_set_default_colormap( cmap ); - */ + gtk_widget_set_default_colormap( cmap ); + */ /* initialize color cube for 8-bit color reduction dithering */ @@ -235,27 +240,11 @@ bool wxApp::InitVisual() } } } - - return TRUE; -} -bool wxApp::OnInitGui(void) -{ - m_idleTag = gtk_idle_add( wxapp_idle_callback, NULL ); return TRUE; } -bool wxApp::OnInit(void) -{ - return TRUE; -} - -int wxApp::OnRun(void) -{ - return MainLoop(); -} - bool wxApp::ProcessIdle(void) { wxIdleEvent event; @@ -330,11 +319,6 @@ bool wxApp::SendIdleEvents( wxWindow* win ) return needMore ; } -int wxApp::OnExit(void) -{ - return 0; -} - int wxApp::MainLoop(void) { gtk_main(); @@ -389,39 +373,43 @@ void wxApp::SetTopWindow( wxWindow *win ) m_topWindow = win; } -void wxApp::CommonInit(void) +bool wxApp::Initialize(void) { - wxSystemSettings::Init(); + wxBuffer = new char[BUFSIZ + 512]; + + wxClassInfo::InitializeClasses(); + + wxSystemSettings::Init(); - wxTheFontNameDirectory = new wxFontNameDirectory; - wxTheFontNameDirectory->Initialize(); + wxTheFontNameDirectory = new wxFontNameDirectory; + wxTheFontNameDirectory->Initialize(); - wxTheColourDatabase = new wxColourDatabase(wxKEY_STRING); - wxTheColourDatabase->Initialize(); + wxTheColourDatabase = new wxColourDatabase( wxKEY_STRING ); + wxTheColourDatabase->Initialize(); - wxInitializeStockLists(); - wxInitializeStockObjects(); + wxInitializeStockLists(); + wxInitializeStockObjects(); #if wxUSE_WX_RESOURCES - wxTheResourceCache = new wxResourceCache(wxKEY_STRING); + wxTheResourceCache = new wxResourceCache( wxKEY_STRING ); - wxInitializeResourceSystem(); + wxInitializeResourceSystem(); #endif - wxImage::InitStandardHandlers(); + wxImage::InitStandardHandlers(); -// g_globalCursor = new wxCursor; + /* no global cursor under X + g_globalCursor = new wxCursor; */ + + wxModule::RegisterModules(); + if (!wxModule::InitializeModules()) return FALSE; + + return TRUE; } -void wxApp::CommonCleanUp(void) +void wxApp::CleanUp(void) { - if (wxTheColourDatabase) delete wxTheColourDatabase; - wxTheColourDatabase = (wxColourDatabase*) NULL; - - if (wxTheFontNameDirectory) delete wxTheFontNameDirectory; - wxTheFontNameDirectory = (wxFontNameDirectory*) NULL; - - wxDeleteStockObjects(); + wxModule::CleanUpModules(); #if wxUSE_WX_RESOURCES wxFlushResources(); @@ -432,16 +420,47 @@ void wxApp::CommonCleanUp(void) wxCleanUpResourceSystem(); #endif + if (wxTheColourDatabase) delete wxTheColourDatabase; + wxTheColourDatabase = (wxColourDatabase*) NULL; + + if (wxTheFontNameDirectory) delete wxTheFontNameDirectory; + wxTheFontNameDirectory = (wxFontNameDirectory*) NULL; + + wxDeleteStockObjects(); + wxDeleteStockLists(); wxImage::CleanUpHandlers(); + delete wxTheApp; + wxTheApp = (wxApp*) NULL; + + /* check for memory leaks */ +#if (defined(__WXDEBUG__) && wxUSE_MEMORY_TRACING) || wxUSE_DEBUG_CONTEXT + if (wxDebugContext::CountObjectsLeft() > 0) + { + wxLogDebug("There were memory leaks.\n"); + wxDebugContext::Dump(); + wxDebugContext::PrintStatistics(); + } +#endif + + /* do this as the very last thing because everything else can log messages */ + wxLog::DontCreateOnDemand(); + + wxLog *oldLog = wxLog::SetActiveTarget( (wxLog*) NULL ); + if (oldLog) delete oldLog; + wxSystemSettings::Done(); + + wxClassInfo::CleanUpClasses(); + + delete[] wxBuffer; } wxLog *wxApp::CreateLogTarget() { - return new wxLogGui; + return new wxLogGui; } //----------------------------------------------------------------------------- @@ -450,10 +469,11 @@ wxLog *wxApp::CreateLogTarget() int wxEntry( int argc, char *argv[] ) { - wxBuffer = new char[BUFSIZ + 512]; + gtk_set_locale(); - wxClassInfo::InitializeClasses(); + gtk_init( &argc, &argv ); + if (!wxApp::Initialize()) return 0; if (!wxTheApp) { @@ -485,22 +505,11 @@ int wxEntry( int argc, char *argv[] ) wxStripExtension( name ); wxTheApp->SetAppName( name ); - gtk_set_locale(); - - gtk_init( &argc, &argv ); - - if (!wxTheApp->InitVisual()) return 0; - - wxApp::CommonInit(); - if (!wxTheApp->OnInitGui()) return 0; - wxModule::RegisterModules(); - if (!wxModule::InitializeModules()) return FALSE; - - // Here frames insert themselves automatically - // into wxTopLevelWindows by getting created - // in OnInit(). + /* Here frames insert themselves automatically + * into wxTopLevelWindows by getting created + * in OnInit(). */ if (!wxTheApp->OnInit()) return 0; @@ -510,34 +519,31 @@ int wxEntry( int argc, char *argv[] ) if (wxTheApp->Initialized()) retValue = wxTheApp->OnRun(); - wxTheApp->DeletePendingObjects(); - - wxTheApp->OnExit(); - - wxModule::CleanUpModules(); - - wxApp::CommonCleanUp(); - - delete wxTheApp; - wxTheApp = (wxApp*) NULL; - - wxClassInfo::CleanUpClasses(); - - delete[] wxBuffer; - -#if (defined(__WXDEBUG__) && wxUSE_MEMORY_TRACING) || wxUSE_DEBUG_CONTEXT - - if (wxDebugContext::CountObjectsLeft() > 0) + wxWindow *topWindow = wxTheApp->GetTopWindow(); + if (topWindow) { - wxLogDebug("There were memory leaks.\n"); - wxDebugContext::Dump(); - wxDebugContext::PrintStatistics(); + /* Forcibly delete the window. */ + if (topWindow->IsKindOf(CLASSINFO(wxFrame)) || + topWindow->IsKindOf(CLASSINFO(wxDialog)) ) + { + topWindow->Close( TRUE ); + wxTheApp->DeletePendingObjects(); + } + else + { + delete topWindow; + wxTheApp->SetTopWindow( (wxWindow*) NULL ); + } } -#endif + wxTheApp->OnExit(); - wxLog *oldLog = wxLog::SetActiveTarget( (wxLog*) NULL ); - if (oldLog) delete oldLog; + /* flush the logged messages if any */ + wxLog *log = wxLog::GetActiveTarget(); + if (log != NULL && log->HasPendingMessages()) + log->Flush(); + + wxApp::CleanUp(); return retValue; } diff --git a/src/gtk1/clipbrd.cpp b/src/gtk1/clipbrd.cpp index 4314ac726b..11096c3a4c 100644 --- a/src/gtk1/clipbrd.cpp +++ b/src/gtk1/clipbrd.cpp @@ -104,12 +104,12 @@ selection_received( GtkWidget *WXUNUSED(widget), // make sure we got the data in the correct format - if (data_object->m_formatAtom != selection_data->target) return; + if (data_object->GetFormat().GetAtom() != selection_data->target) return; // make sure we got the data in the correct form (selection type). // if so, copy data to target object - switch (data_object->GetFormat()) + switch (data_object->GetFormat().GetType()) { case wxDF_TEXT: { @@ -179,10 +179,13 @@ selection_clear_clip( GtkWidget *WXUNUSED(widget), GdkEventSelection *event ) if ((!wxTheClipboard->m_ownsPrimarySelection) && (!wxTheClipboard->m_ownsClipboard)) { - // the clipboard is no longer in our hands. we can the - // clipboard data. - - wxTheClipboard->m_dataObjects.Clear(); + /* the clipboard is no longer in our hands. we can the clipboard data. */ + + if (wxTheClipboard->m_dataBroker) + { + delete wxTheClipboard->m_dataBroker; + wxTheClipboard->m_dataBroker = (wxDataBroker*) NULL; + } } return TRUE; @@ -197,19 +200,21 @@ selection_handler( GtkWidget *WXUNUSED(widget), GtkSelectionData *selection_data { if (!wxTheClipboard) return; - wxNode *node = wxTheClipboard->m_dataObjects.First(); + if (!wxTheClipboard->m_dataBroker) return; + + wxNode *node = wxTheClipboard->m_dataBroker->m_dataObjects.First(); while (node) { wxDataObject *data_object = (wxDataObject *)node->Data(); - if (data_object->m_formatAtom != selection_data->target) + if (data_object->GetFormat().GetAtom() != selection_data->target) { node = node->Next(); break; } - switch (data_object->GetFormat()) + switch (data_object->GetFormat().GetType()) { case wxDF_TEXT: { @@ -243,14 +248,14 @@ selection_handler( GtkWidget *WXUNUSED(widget), GtkSelectionData *selection_data { wxPrivateDataObject *private_object = (wxPrivateDataObject*) data_object; - if (private_object->GetDataSize() == 0) return; + if (private_object->GetSize() == 0) return; gtk_selection_data_set( selection_data, GDK_SELECTION_TYPE_STRING, 8*sizeof(gchar), (unsigned char*) private_object->GetData(), - (int) private_object->GetDataSize() ); + (int) private_object->GetSize() ); } default: @@ -274,7 +279,7 @@ wxClipboard::wxClipboard() m_ownsClipboard = FALSE; m_ownsPrimarySelection = FALSE; - m_dataObjects.DeleteContents( TRUE ); + m_dataBroker = (wxDataBroker*) NULL; m_receivedData = (wxDataObject*) NULL; @@ -303,7 +308,7 @@ wxClipboard::~wxClipboard() void wxClipboard::Clear() { - if (m_dataObjects.GetCount()) + if (m_dataBroker) { /* As we have data we also own the clipboard. Once we no longer own it, clear_selection is called which will set m_data to zero */ @@ -318,7 +323,11 @@ void wxClipboard::Clear() gtk_selection_owner_set( (GtkWidget*) NULL, GDK_SELECTION_PRIMARY, GDK_CURRENT_TIME ); } - m_dataObjects.Clear(); + if (m_dataBroker) + { + delete m_dataBroker; + m_dataBroker = (wxDataBroker*) NULL; + } } m_targetRequested = 0; @@ -335,79 +344,67 @@ bool wxClipboard::Open() return TRUE; } -bool wxClipboard::SetData( wxDataObject *data ) +bool wxClipboard::SetData( wxDataBroker *data ) { wxCHECK_MSG( data, FALSE, "data is invalid" ); - wxNode *node = m_dataObjects.First(); - - while (node) - { - wxDataObject *d = (wxDataObject*)node->Data(); - - if (d->GetFormat() == data->GetFormat()) - { - m_dataObjects.DeleteNode( node ); - - break; - } - - node = node->Next(); - } + Clear(); + + m_dataBroker = data; - m_dataObjects.Append( data ); + if (!m_dataBroker) return FALSE; wxCHECK_MSG( m_open, FALSE, "clipboard not open" ); - if (data->GetFormat() == wxDF_PRIVATE) + wxNode *node = m_dataBroker->m_dataObjects.First(); + while (node) { - wxPrivateDataObject* pd = (wxPrivateDataObject*) data; + wxDataObject *dobj = (wxDataObject*)node->Data(); - wxCHECK_MSG( !pd->GetId().IsEmpty(), FALSE, "private clipboard format requires ID string" ); + GdkAtom format = dobj->GetFormat().GetAtom(); - data->m_formatAtom = GetTargetAtom( data->GetFormat(), pd->GetId() ); - } - else - { - data->m_formatAtom = GetTargetAtom( data->GetFormat() ); - } - - // This should happen automatically + if (format != (GdkAtom) 0) + { + /* This should happen automatically */ - m_ownsClipboard = FALSE; - m_ownsPrimarySelection = FALSE; + m_ownsClipboard = FALSE; + m_ownsPrimarySelection = FALSE; - // Add handlers if someone requests data + /* Add handlers if someone requests data */ - gtk_selection_add_handler( m_clipboardWidget, + gtk_selection_add_handler( m_clipboardWidget, g_clipboardAtom, - data->m_formatAtom, + format, selection_handler, - NULL ); + (gpointer) NULL ); - gtk_selection_add_handler( m_clipboardWidget, + gtk_selection_add_handler( m_clipboardWidget, GDK_SELECTION_PRIMARY, - data->m_formatAtom, + format, selection_handler, - NULL ); + (gpointer) NULL ); - // Tell the world we offer clipboard data + /* Tell the world we offer clipboard data */ - if (!gtk_selection_owner_set( m_clipboardWidget, + if (!gtk_selection_owner_set( m_clipboardWidget, g_clipboardAtom, GDK_CURRENT_TIME )) - { - return FALSE; - } - m_ownsClipboard = TRUE; + { + return FALSE; + } + m_ownsClipboard = TRUE; - if (!gtk_selection_owner_set( m_clipboardWidget, + if (!gtk_selection_owner_set( m_clipboardWidget, GDK_SELECTION_PRIMARY, GDK_CURRENT_TIME )) - { - return FALSE; + { + return FALSE; + } + m_ownsPrimarySelection = TRUE; + } + + node = node->Next(); } - m_ownsPrimarySelection = TRUE; return TRUE; } @@ -419,13 +416,23 @@ void wxClipboard::Close() m_open = FALSE; } -bool wxClipboard::IsSupportedFormat( wxDataFormat format, const wxString &id ) +bool wxClipboard::GetData( wxDataObject *data ) { - m_targetRequested = GetTargetAtom( format, id ); + wxCHECK_MSG( m_open, FALSE, "clipboard not open" ); + + m_receivedData = data; + + wxCHECK_MSG( m_receivedData, FALSE, "invalid data object" ); + + /* STEP ONE: check if there is such data in the clipboard */ + + m_targetRequested = data->GetFormat().GetAtom(); + wxCHECK_MSG( m_targetRequested, FALSE, "invalid clipboard format" ); + if (m_targetRequested == 0) return FALSE; - // add handler for target (= format) query + /* add handler for target (= format) query */ gtk_signal_connect( GTK_OBJECT(m_clipboardWidget), "selection_received", @@ -434,8 +441,8 @@ bool wxClipboard::IsSupportedFormat( wxDataFormat format, const wxString &id ) m_formatSupported = FALSE; - // perform query. this will set m_formatSupported to - // TRUE if m_targetRequested is supported + /* perform query. this will set m_formatSupported to + * TRUE if m_targetRequested is supported */ gtk_selection_convert( m_clipboardWidget, g_clipboardAtom, @@ -448,34 +455,8 @@ bool wxClipboard::IsSupportedFormat( wxDataFormat format, const wxString &id ) if (!m_formatSupported) return FALSE; - return TRUE; -} - -bool wxClipboard::GetData( wxDataObject *data ) -{ - wxCHECK_MSG( m_open, FALSE, "clipboard not open" ); - - m_receivedData = data; - - wxCHECK_MSG( m_receivedData, FALSE, "invalid data object" ); + /* STEP TWO: get the data from the clipboard */ - if (m_receivedData->GetFormat() == wxDF_PRIVATE) - { - wxPrivateDataObject* pd = (wxPrivateDataObject*) m_receivedData; - - wxCHECK_MSG( !pd->GetId().IsEmpty(), FALSE, "private clipboard format requires ID string" ); - - m_targetRequested = GetTargetAtom( m_receivedData->GetFormat(), pd->GetId() ); - } - else - { - m_targetRequested = GetTargetAtom( m_receivedData->GetFormat() ); - } - - data->m_formatAtom = m_targetRequested; - - wxCHECK_MSG( m_targetRequested, FALSE, "unsupported clipboard format" ); - m_formatSupported = FALSE; gtk_signal_connect( GTK_OBJECT(m_clipboardWidget), @@ -492,45 +473,13 @@ bool wxClipboard::GetData( wxDataObject *data ) GTK_SIGNAL_FUNC( selection_received ), (gpointer) this ); + /* this is a true error as we checked for the presence of such data before */ + wxCHECK_MSG( m_formatSupported, FALSE, "error retrieving data from clipboard" ); return TRUE; } -GdkAtom wxClipboard::GetTargetAtom( wxDataFormat format, const wxString &id ) -{ - // What is X representation of that format? - - switch (format) - { - case wxDF_TEXT: - { - return GDK_TARGET_STRING; - // g_textAtom - } - - case wxDF_BITMAP: - { - return GDK_TARGET_BITMAP; - break; - } - - case wxDF_PRIVATE: - { - // we create our own X representation - - return gdk_atom_intern( WXSTRINGCAST( id ), FALSE ); - } - - default: - { - return (GdkAtom) 0; - } - } - - return (GdkAtom) 0; -} - //----------------------------------------------------------------------------- // wxClipboardModule //----------------------------------------------------------------------------- diff --git a/src/gtk1/dataobj.cpp b/src/gtk1/dataobj.cpp index 353633fc7c..59dac39832 100644 --- a/src/gtk1/dataobj.cpp +++ b/src/gtk1/dataobj.cpp @@ -13,6 +13,230 @@ #include "wx/dataobj.h" #include "wx/app.h" +#include "wx/debug.h" + +#include "gdk/gdk.h" + +//------------------------------------------------------------------------- +// wxDataFormat +//------------------------------------------------------------------------- + +IMPLEMENT_CLASS(wxDataFormat, wxObject) + +wxDataFormat::wxDataFormat( wxDataType type ) +{ + m_type = type; + + if (m_type == wxDF_TEXT) + { + m_id = "STRING"; + } + else + if (m_type == wxDF_BITMAP) + { + m_id = "BITMAP"; + } + else + if (m_type == wxDF_FILENAME) + { + m_id = "file:ALL"; + } + else + { + wxFAIL_MSG( "invalid dataformat" ) + } + + m_hasAtom = FALSE; +} + +wxDataFormat::wxDataFormat( const wxString &id ) +{ + m_type = wxDF_PRIVATE; + m_id = id; + m_hasAtom = FALSE; +} + +wxDataFormat::wxDataFormat( wxDataFormat &format ) +{ + m_type = format.GetType(); + m_id = format.GetId(); + m_hasAtom = TRUE; + m_atom = format.GetAtom(); +} + +wxDataFormat::wxDataFormat( const GdkAtom atom ) +{ + m_hasAtom = TRUE; + + m_atom = atom; + + if (m_atom == GDK_TARGET_STRING) + { + m_type = wxDF_TEXT; + } else + if (m_atom == GDK_TARGET_BITMAP) + { + m_type = wxDF_BITMAP; + } else + { + m_type = wxDF_PRIVATE; + m_id = gdk_atom_name( m_atom ); + + if (m_id == "file:ALL") + { + m_type = wxDF_FILENAME; + } + } +} + +int wxDataFormat::GetType() const +{ + return m_type; +} + +wxString wxDataFormat::GetId() const +{ + return m_id; +} + +void wxDataFormat::SetId( const wxString &id ) +{ + m_type = wxDF_PRIVATE; + m_id = id; + m_hasAtom = FALSE; +} + +GdkAtom wxDataFormat::GetAtom() +{ + if (!m_hasAtom) + { + m_hasAtom = TRUE; + + if (m_type == wxDF_TEXT) + { + m_atom = GDK_TARGET_STRING; + } + else + if (m_type == wxDF_BITMAP) + { + m_atom = GDK_TARGET_BITMAP; + } + else + if (m_type == wxDF_PRIVATE) + { + m_atom = gdk_atom_intern( WXSTRINGCAST( m_id ), FALSE ); + } + else + if (m_type == wxDF_FILENAME) + { + m_atom = gdk_atom_intern( "file:ALL", FALSE ); + } + else + { + m_hasAtom = FALSE; + m_atom = (GdkAtom) 0; + } + } + + return m_atom; +} + +//------------------------------------------------------------------------- +// wxDataBroker +//------------------------------------------------------------------------- + +IMPLEMENT_CLASS(wxDataBroker,wxObject) + +wxDataBroker::wxDataBroker() +{ + m_dataObjects.DeleteContents(TRUE); + m_preferred = 0; +} + +void wxDataBroker::Add( wxDataObject *dataObject, bool preferred ) +{ + if (preferred) m_preferred = m_dataObjects.GetCount(); + m_dataObjects.Append( dataObject ); +} + +size_t wxDataBroker::GetFormatCount() const +{ + return m_dataObjects.GetCount(); +} + +wxDataFormat &wxDataBroker::GetPreferredFormat() const +{ + wxNode *node = m_dataObjects.Nth( m_preferred ); + + wxASSERT( node ); + + wxDataObject* data_obj = (wxDataObject*)node->Data(); + + return data_obj->GetFormat(); +} + +wxDataFormat &wxDataBroker::GetNthFormat( size_t nth ) const +{ + wxNode *node = m_dataObjects.Nth( nth ); + + wxASSERT( node ); + + wxDataObject* data_obj = (wxDataObject*)node->Data(); + + return data_obj->GetFormat(); +} + +bool wxDataBroker::IsSupportedFormat( wxDataFormat &format ) const +{ + wxNode *node = m_dataObjects.First(); + while (node) + { + wxDataObject *dobj = (wxDataObject*)node->Data(); + + if (dobj->GetFormat().GetAtom() == format.GetAtom()) + { + return TRUE; + } + + node = node->Next(); + } + + return FALSE; +} + +size_t wxDataBroker::GetSize( wxDataFormat& format ) const +{ + wxNode *node = m_dataObjects.First(); + while (node) + { + wxDataObject *dobj = (wxDataObject*)node->Data(); + + if (dobj->GetFormat().GetAtom() == format.GetAtom()) + { + return dobj->GetSize(); + } + + node = node->Next(); + } + + return 0; +} + +void wxDataBroker::WriteData( wxDataFormat& format, void *dest ) const +{ + wxNode *node = m_dataObjects.First(); + while (node) + { + wxDataObject *dobj = (wxDataObject*)node->Data(); + + if (dobj->GetFormat().GetAtom() == format.GetAtom()) + { + return dobj->WriteData( dest ); + } + + node = node->Next(); + } +} //------------------------------------------------------------------------- // wxDataObject @@ -20,24 +244,141 @@ IMPLEMENT_ABSTRACT_CLASS( wxDataObject, wxObject ) +wxDataObject::wxDataObject() +{ + m_format = (wxDataFormat*) NULL; +} + +wxDataObject::~wxDataObject() +{ + if (m_format) delete m_format; +} + +wxDataFormat &wxDataObject::GetFormat() const +{ + wxASSERT( m_format ); + + return (*m_format); +} + // ---------------------------------------------------------------------------- // wxTextDataObject // ---------------------------------------------------------------------------- IMPLEMENT_DYNAMIC_CLASS( wxTextDataObject, wxDataObject ) +wxTextDataObject::wxTextDataObject() +{ + m_format = new wxDataFormat( wxDF_TEXT ); +} + +wxTextDataObject::wxTextDataObject( const wxString& data ) +{ + m_format = new wxDataFormat( wxDF_TEXT ); + + m_data = data; +} + +void wxTextDataObject::SetText( const wxString& data ) +{ + m_data = data; +} + +wxString wxTextDataObject::GetText() const +{ + return m_data; +} + +void wxTextDataObject::WriteData( void *dest ) const +{ + WriteString( m_data, dest ); +} + +size_t wxTextDataObject::GetSize() const +{ + return m_data.Len() + 1; +} + +void wxTextDataObject::WriteString( const wxString &str, void *dest ) const +{ + memcpy( dest, m_data.c_str(), GetSize() ); +} + // ---------------------------------------------------------------------------- // wxFileDataObject // ---------------------------------------------------------------------------- IMPLEMENT_DYNAMIC_CLASS( wxFileDataObject, wxDataObject ) +wxFileDataObject::wxFileDataObject(void) +{ + m_format = new wxDataFormat( wxDF_FILENAME ); +} + +void wxFileDataObject::AddFile( const wxString &file ) +{ + m_files += file; + m_files += (char)0; +} + +wxString wxFileDataObject::GetFiles() const +{ + return m_files; +} + +void wxFileDataObject::WriteData( void *dest ) const +{ + memcpy( dest, m_files.c_str(), GetSize() ); +} + +size_t wxFileDataObject::GetSize() const +{ + return m_files.Len() + 1; +} + // ---------------------------------------------------------------------------- // wxBitmapDataObject // ---------------------------------------------------------------------------- IMPLEMENT_DYNAMIC_CLASS( wxBitmapDataObject, wxDataObject ) +wxBitmapDataObject::wxBitmapDataObject() +{ + m_format = new wxDataFormat( wxDF_BITMAP ); +} + +wxBitmapDataObject::wxBitmapDataObject( const wxBitmap& bitmap ) +{ + m_format = new wxDataFormat( wxDF_BITMAP ); + + m_bitmap = bitmap; +} + +void wxBitmapDataObject::SetBitmap( const wxBitmap &bitmap ) +{ + m_bitmap = bitmap; +} + +wxBitmap wxBitmapDataObject::GetBitmap() const +{ + return m_bitmap; +} + +void wxBitmapDataObject::WriteData( void *dest ) const +{ + WriteBitmap( m_bitmap, dest ); +} + +size_t wxBitmapDataObject::GetSize() const +{ + return 0; +} + +void wxBitmapDataObject::WriteBitmap( const wxBitmap &bitmap, void *dest ) const +{ + memcpy( dest, m_bitmap.GetPixmap(), GetSize() ); +} + // ---------------------------------------------------------------------------- // wxPrivateDataObject // ---------------------------------------------------------------------------- @@ -46,9 +387,13 @@ IMPLEMENT_DYNAMIC_CLASS( wxPrivateDataObject, wxDataObject ) wxPrivateDataObject::wxPrivateDataObject() { + m_id = "application/"; + m_id += wxTheApp->GetAppName(); + + m_format = new wxDataFormat( m_id ); + m_size = 0; m_data = (char*) NULL; - m_id = wxTheApp->GetAppName(); } wxPrivateDataObject::~wxPrivateDataObject() @@ -56,6 +401,17 @@ wxPrivateDataObject::~wxPrivateDataObject() if (m_data) delete[] m_data; } +void wxPrivateDataObject::SetId( const wxString& id ) +{ + m_id = id; + m_format->SetId( m_id ); +} + +wxString wxPrivateDataObject::GetId() const +{ + return m_id; +} + void wxPrivateDataObject::SetData( const char *data, size_t size ) { m_size = size; @@ -67,3 +423,23 @@ void wxPrivateDataObject::SetData( const char *data, size_t size ) memcpy( m_data, data, size ); } +char* wxPrivateDataObject::GetData() const +{ + return m_data; +} + +void wxPrivateDataObject::WriteData( void *dest ) const +{ + WriteData( m_data, dest ); +} + +size_t wxPrivateDataObject::GetSize() const +{ + return m_size; +} + +void wxPrivateDataObject::WriteData( const char *data, void *dest ) const +{ + memcpy( dest, data, GetSize() ); +} + diff --git a/src/gtk1/dialog.cpp b/src/gtk1/dialog.cpp index ceba496548..f4a3d74144 100644 --- a/src/gtk1/dialog.cpp +++ b/src/gtk1/dialog.cpp @@ -134,7 +134,16 @@ bool wxDialog::Create( wxWindow *parent, wxDialog::~wxDialog() { wxTopLevelWindows.DeleteObject( this ); - if (wxTopLevelWindows.Number() == 0) wxTheApp->ExitMainLoop(); + + if (wxTheApp->GetTopWindow() == this) + { + wxTheApp->SetTopWindow( (wxWindow*) NULL ); + } + + if (wxTopLevelWindows.Number() == 0) + { + wxTheApp->ExitMainLoop(); + } } void wxDialog::SetTitle( const wxString& title ) diff --git a/src/gtk1/dnd.cpp b/src/gtk1/dnd.cpp index 4ac5d9bc3c..17c1d18258 100644 --- a/src/gtk1/dnd.cpp +++ b/src/gtk1/dnd.cpp @@ -171,8 +171,7 @@ void wxDropTarget::RegisterWidget( GtkWidget *widget ) break; case wxDF_PRIVATE: wxPrivateDropTarget *pdt = (wxPrivateDropTarget *)this; - strcpy( buf, "applications/" ); - strcat( buf, WXSTRINGCAST pdt->GetID() ); + strcpy( buf, WXSTRINGCAST pdt->GetID() ); format.target = buf; valid++; default: @@ -533,10 +532,17 @@ static void gtk_target_callback( GtkWidget *widget, wxDropTarget::wxDropTarget() { + m_format = (wxDataFormat*) NULL; } wxDropTarget::~wxDropTarget() { + if (m_format) delete m_format; +} + +wxDataFormat &wxDropTarget::GetFormat(size_t n) const +{ + return (*m_format); } void wxDropTarget::UnregisterWidget( GtkWidget *widget ) @@ -556,8 +562,7 @@ void wxDropTarget::RegisterWidget( GtkWidget *widget ) for ( size_t i = 0; i < GetFormatCount(); i++ ) { - wxDataFormat df = GetFormat( i ); - switch (df) + switch (GetFormat(i).GetType()) { case wxDF_TEXT: { @@ -577,7 +582,6 @@ void wxDropTarget::RegisterWidget( GtkWidget *widget ) { if (i > 0) formats += ";"; wxPrivateDropTarget *pdt = (wxPrivateDropTarget *)this; - formats += "applications/"; formats += pdt->GetId(); valid++; break; @@ -605,6 +609,11 @@ void wxDropTarget::RegisterWidget( GtkWidget *widget ) // wxTextDropTarget // ---------------------------------------------------------------------------- +wxTextDropTarget::wxTextDropTarget() +{ + m_format = new wxDataFormat( wxDF_TEXT ); +} + bool wxTextDropTarget::OnDrop( long x, long y, const void *data, size_t WXUNUSED(size) ) { OnDropText( x, y, (const char*)data ); @@ -625,11 +634,6 @@ size_t wxTextDropTarget::GetFormatCount() const return 1; } -wxDataFormat wxTextDropTarget::GetFormat(size_t WXUNUSED(n)) const -{ - return wxDF_TEXT; -} - // ---------------------------------------------------------------------------- // wxPrivateDropTarget // ---------------------------------------------------------------------------- @@ -637,22 +641,29 @@ wxDataFormat wxTextDropTarget::GetFormat(size_t WXUNUSED(n)) const wxPrivateDropTarget::wxPrivateDropTarget() { m_id = wxTheApp->GetAppName(); + m_format = new wxDataFormat( m_id ); } -size_t wxPrivateDropTarget::GetFormatCount() const +void wxPrivateDropTarget::SetId( const wxString& id ) { - return 1; + m_id = id; + m_format->SetId( id ); } -wxDataFormat wxPrivateDropTarget::GetFormat(size_t WXUNUSED(n)) const +size_t wxPrivateDropTarget::GetFormatCount() const { - return wxDF_PRIVATE; + return 1; } // ---------------------------------------------------------------------------- // wxFileDropTarget // ---------------------------------------------------------------------------- +wxFileDropTarget::wxFileDropTarget() +{ + m_format = new wxDataFormat( wxDF_FILENAME ); +} + bool wxFileDropTarget::OnDropFiles( long x, long y, size_t nFiles, const char * const aszFiles[] ) { printf( "Got %d dropped files.\n", (int)nFiles ); @@ -698,11 +709,6 @@ size_t wxFileDropTarget::GetFormatCount() const return 1; } -wxDataFormat wxFileDropTarget::GetFormat(size_t WXUNUSED(n)) const -{ - return wxDF_FILENAME; -} - //------------------------------------------------------------------------- // wxDropSource //------------------------------------------------------------------------- @@ -712,64 +718,76 @@ shape_motion (GtkWidget *widget, GdkEventMotion * /*event*/); //----------------------------------------------------------------------------- -// drag request +// "drag_request_event" +//----------------------------------------------------------------------------- -void gtk_drag_callback( GtkWidget *widget, GdkEvent *event, wxDropSource *source ) +void gtk_drag_callback( GtkWidget *widget, GdkEventDragRequest *event, wxDropSource *source ) { - wxDataObject *data = source->m_data; - - switch (data->GetFormat()) + wxDataBroker *data = source->m_data; + + if (!data) return; + + wxNode *node = data->m_dataObjects.First(); { - case wxDF_PRIVATE: - { - wxPrivateDataObject *pdo = (wxPrivateDataObject*) data; - - gtk_widget_dnd_data_set( widget, - event, - (unsigned char*) pdo->GetData(), - (int) pdo->GetDataSize() ); - - break; - } - case wxDF_TEXT: + wxDataObject *dobj = (wxDataObject*) node->Data(); + + if ((strcmp(event->data_type,"file:ALL") == 0) && + (dobj->GetFormat().GetType() == wxDF_FILENAME)) { - wxTextDataObject *text_object = (wxTextDataObject*) data; + wxFileDataObject *file_object = (wxFileDataObject*) dobj; - wxString text = text_object->GetText(); + wxString text = file_object->GetFiles(); char *s = WXSTRINGCAST text; gtk_widget_dnd_data_set( widget, - event, + (GdkEvent*)event, (unsigned char*) s, (int) text.Length()+1 ); - break; + source->m_retValue = wxDragCopy; + + return; } - case wxDF_FILENAME: + if ((strcmp(event->data_type,"text/plain") == 0) && + (dobj->GetFormat().GetType() == wxDF_TEXT)) { - wxFileDataObject *file_object = (wxFileDataObject*) data; + wxTextDataObject *text_object = (wxTextDataObject*) dobj; - wxString text = file_object->GetFiles(); + wxString text = text_object->GetText(); char *s = WXSTRINGCAST text; gtk_widget_dnd_data_set( widget, - event, + (GdkEvent*)event, (unsigned char*) s, (int) text.Length()+1 ); - break; + source->m_retValue = wxDragCopy; + + return; } - default: + if (dobj->GetFormat().GetType() == wxDF_PRIVATE) { - return; + wxPrivateDataObject *pdo = (wxPrivateDataObject*) dobj; + + if (pdo->GetId() == event->data_type) + { + gtk_widget_dnd_data_set( widget, + (GdkEvent*)event, + (unsigned char*) pdo->GetData(), + (int) pdo->GetSize() ); + + source->m_retValue = wxDragCopy; + + return; + } } + + node = node->Next(); } - - source->m_retValue = wxDragCopy; } wxDropSource::wxDropSource( wxWindow *win ) @@ -780,14 +798,14 @@ wxDropSource::wxDropSource( wxWindow *win ) m_widget = win->m_widget; if (win->m_wxwindow) m_widget = win->m_wxwindow; - m_data = (wxDataObject *) NULL; + m_data = (wxDataBroker*) NULL; m_retValue = wxDragCancel; m_defaultCursor = wxCursor( wxCURSOR_NO_ENTRY ); m_goaheadCursor = wxCursor( wxCURSOR_HAND ); } -wxDropSource::wxDropSource( wxDataObject &data, wxWindow *win ) +wxDropSource::wxDropSource( wxDataObject *data, wxWindow *win ) { g_blockEventsOnDrag = TRUE; @@ -796,20 +814,60 @@ wxDropSource::wxDropSource( wxDataObject &data, wxWindow *win ) if (win->m_wxwindow) m_widget = win->m_wxwindow; m_retValue = wxDragCancel; - m_data = &data; + if (data) + { + m_data = new wxDataBroker(); + m_data->Add( data ); + } + else + { + m_data = (wxDataBroker*) NULL; + } m_defaultCursor = wxCursor( wxCURSOR_NO_ENTRY ); m_goaheadCursor = wxCursor( wxCURSOR_HAND ); } -void wxDropSource::SetData( wxDataObject &data ) +wxDropSource::wxDropSource( wxDataBroker *data, wxWindow *win ) +{ + g_blockEventsOnDrag = TRUE; + + m_window = win; + m_widget = win->m_widget; + if (win->m_wxwindow) m_widget = win->m_wxwindow; + m_retValue = wxDragCancel; + + m_data = data; + + m_defaultCursor = wxCursor( wxCURSOR_NO_ENTRY ); + m_goaheadCursor = wxCursor( wxCURSOR_HAND ); +} + +void wxDropSource::SetData( wxDataObject *data ) +{ + if (m_data) delete m_data; + + if (data) + { + m_data = new wxDataBroker(); + m_data->Add( data ); + } + else + { + m_data = (wxDataBroker*) NULL; + } +} + +void wxDropSource::SetData( wxDataBroker *data ) { - m_data = &data; + if (m_data) delete m_data; + + m_data = data; } wxDropSource::~wxDropSource(void) { -// if (m_data) delete m_data; + if (m_data) delete m_data; g_blockEventsOnDrag = FALSE; } @@ -926,29 +984,33 @@ void wxDropSource::RegisterWindow(void) wxString formats; - wxDataFormat df = m_data->GetFormat(); - - switch (df) + wxNode *node = m_data->m_dataObjects.First(); + while (node) { - case wxDF_TEXT: - { - formats += "text/plain"; - break; - } - case wxDF_FILENAME: - { - formats += "file:ALL"; - break; - } - case wxDF_PRIVATE: - { - wxPrivateDataObject* pdo = (wxPrivateDataObject*) m_data; - formats += "applications/"; - formats += pdo->GetId(); - break; + wxDataObject* dobj = (wxDataObject*) node->Data(); + + switch (dobj->GetFormat().GetType()) + { + case wxDF_TEXT: + { + formats += "text/plain"; + break; + } + case wxDF_FILENAME: + { + formats += "file:ALL"; + break; + } + case wxDF_PRIVATE: + { + wxPrivateDataObject* pdo = (wxPrivateDataObject*) m_data; + formats += pdo->GetId(); + break; + } + default: + break; } - default: - break; + node = node->Next(); } char *str = WXSTRINGCAST formats; diff --git a/src/gtk1/frame.cpp b/src/gtk1/frame.cpp index 707f419dec..993bbbf75b 100644 --- a/src/gtk1/frame.cpp +++ b/src/gtk1/frame.cpp @@ -193,7 +193,16 @@ wxFrame::~wxFrame() if (m_frameToolBar) delete m_frameToolBar; wxTopLevelWindows.DeleteObject( this ); - if (wxTopLevelWindows.Number() == 0) wxTheApp->ExitMainLoop(); + + if (wxTheApp->GetTopWindow() == this) + { + wxTheApp->SetTopWindow( (wxWindow*) NULL ); + } + + if (wxTopLevelWindows.Number() == 0) + { + wxTheApp->ExitMainLoop(); + } } bool wxFrame::Show( bool show ) diff --git a/src/msw/dde.cpp b/src/msw/dde.cpp index c46f04c233..5cdd617036 100644 --- a/src/msw/dde.cpp +++ b/src/msw/dde.cpp @@ -420,7 +420,7 @@ bool wxDDEConnection::Disconnect(void) return (DdeDisconnect((HCONV) m_hConv) != 0); } -bool wxDDEConnection::Execute(char *data, int size, wxDataFormat format) +bool wxDDEConnection::Execute(char *data, int size, wxIPCFormat format) { DWORD result; if (size < 0) @@ -432,7 +432,7 @@ bool wxDDEConnection::Execute(char *data, int size, wxDataFormat format) NULL, format, XTYP_EXECUTE, 5000, &result) ? TRUE : FALSE); } -char *wxDDEConnection::Request(const wxString& item, int *size, wxDataFormat format) +char *wxDDEConnection::Request(const wxString& item, int *size, wxIPCFormat format) { DWORD result; HSZ atom = DDEGetAtom(item); @@ -452,7 +452,7 @@ char *wxDDEConnection::Request(const wxString& item, int *size, wxDataFormat for else return NULL; } -bool wxDDEConnection::Poke(const wxString& item, char *data, int size, wxDataFormat format) +bool wxDDEConnection::Poke(const wxString& item, char *data, int size, wxIPCFormat format) { DWORD result; if (size < 0) @@ -484,7 +484,7 @@ bool wxDDEConnection::StopAdvise(const wxString& item) } // Calls that SERVER can make -bool wxDDEConnection::Advise(const wxString& item, char *data, int size, wxDataFormat format) +bool wxDDEConnection::Advise(const wxString& item, char *data, int size, wxIPCFormat format) { if (size < 0) size = strlen(data); @@ -579,7 +579,7 @@ DWORD /* lData2 */) { DWORD len = DdeGetData(hData, (LPBYTE)(connection->m_bufPtr), connection->m_bufSize, 0); DdeFreeDataHandle(hData); - if (connection->OnExecute(connection->m_topicName, connection->m_bufPtr, (int)len, (wxDataFormat) wFmt)) + if (connection->OnExecute(connection->m_topicName, connection->m_bufPtr, (int)len, (wxIPCFormat) wFmt)) return (DDERETURN)DDE_FACK; else return (DDERETURN)DDE_FNOTPROCESSED; @@ -598,7 +598,7 @@ DWORD /* lData2 */) CP_WINANSI); int user_size = -1; - char *data = connection->OnRequest(connection->m_topicName, wxString(item_name), &user_size, (wxDataFormat) wFmt); + char *data = connection->OnRequest(connection->m_topicName, wxString(item_name), &user_size, (wxIPCFormat) wFmt); if (data) { if (user_size < 0) user_size = strlen(data); @@ -622,7 +622,7 @@ DWORD /* lData2 */) CP_WINANSI); DWORD len = DdeGetData(hData, (LPBYTE)(connection->m_bufPtr), connection->m_bufSize, 0); DdeFreeDataHandle(hData); - connection->OnPoke(connection->m_topicName, wxString(item_name), connection->m_bufPtr, (int)len, (wxDataFormat) wFmt); + connection->OnPoke(connection->m_topicName, wxString(item_name), connection->m_bufPtr, (int)len, (wxIPCFormat) wFmt); return (DDERETURN)DDE_FACK; } else return (DDERETURN)DDE_FNOTPROCESSED; break; @@ -684,7 +684,7 @@ DWORD /* lData2 */) DWORD len = DdeGetData(hData, (LPBYTE)(connection->m_bufPtr), connection->m_bufSize, 0); DdeFreeDataHandle(hData); - if (connection->OnAdvise(connection->m_topicName, wxString(item_name), connection->m_bufPtr, (int)len, (wxDataFormat) wFmt)) + if (connection->OnAdvise(connection->m_topicName, wxString(item_name), connection->m_bufPtr, (int)len, (wxIPCFormat) wFmt)) return (DDERETURN)DDE_FACK; else return (DDERETURN)DDE_FNOTPROCESSED; -- 2.45.2