From 6b3aaa600ecdaede3ecbb5aa2099ad5def0659cd Mon Sep 17 00:00:00 2001 From: nds Date: Wed, 8 Oct 2008 10:39:51 +0000 Subject: [PATCH] Changes for the delivery before 08/10/08. --- SUIT.pro | 6 +- src/CAF/CAF.pro | 5 +- src/HTMLService/HTMLService.pro | 13 +- src/HTMLService/HTMLService_HTML.hxx | 168 +-- src/HTMLService/HTMLService_HTMLImage.hxx | 120 +- src/HTMLService/HTMLService_HTMLParagraph.hxx | 88 +- src/HTMLService/HTMLService_HTMLTable.hxx | 154 +-- src/HTMLService/HTMLService_HTMLTableCell.hxx | 126 +- src/HTMLService/HTMLService_HTMLTableRow.hxx | 100 +- src/HTMLService/HTMLService_HTMLText.hxx | 116 +- src/LogWindow/LogWindow.pro | 20 +- src/OBJECT/OBJECT.pro | 19 +- src/ObjBrowser/ObjBrowser.pro | 20 +- src/Plot2d/Plot2d.pro | 29 +- src/Plot2d/Plot2d_HistogramItem.cxx | 2 +- src/Plot2d/Plot2d_HistogramItem.h | 5 +- src/Plot2d/Plot2d_Object.h | 4 +- src/Plot2d/Plot2d_ViewFrame.h | 1 + src/Prs/Prs.pro | 16 +- src/PyConsole/PyConsole.h | 40 +- src/PyConsole/PyConsole.pro | 19 +- src/PyConsole/PyConsole_Console.cxx | 175 ++- src/PyConsole/PyConsole_Console.h | 60 +- src/PyConsole/PyConsole_Editor.cxx | 175 ++- src/PyConsole/PyConsole_Editor.h | 41 +- src/PyConsole/PyConsole_Interp.cxx | 48 +- src/PyConsole/PyConsole_Interp.h | 6 +- src/PyInterp/PyInterp.h | 44 +- src/PyInterp/PyInterp.pro | 17 +- src/PyInterp/PyInterp_Dispatcher.cxx | 35 +- src/PyInterp/PyInterp_Dispatcher.h | 37 +- src/PyInterp/PyInterp_Interp.cxx | 449 +++++++ src/PyInterp/PyInterp_Interp.h | 116 ++ src/PyInterp/PyInterp_Watcher.h | 14 +- src/PyInterp/PyInterp_base.cxx | 317 ----- src/PyInterp/PyInterp_base.h | 145 --- src/Qtx/Qtx.pro | 18 +- src/Qtx/QtxMRUAction.cxx | 194 ++- src/Qtx/QtxMRUAction.h | 21 + src/Qtx/QtxPagePrefMgr.cxx | 481 ++++++-- src/Qtx/QtxPagePrefMgr.h | 46 +- src/Qtx/QtxPreferenceMgr.cxx | 104 +- src/Qtx/QtxPreferenceMgr.h | 26 +- src/STD/STD.pro | 25 +- src/SUIT/SUIT.pro | 25 +- src/SUIT/SUIT_DataBrowser.cxx | 6 +- src/SUIT/SUIT_DataBrowser.h | 2 +- src/SUIT/SUIT_FileDlg.cxx | 1049 ++++++++++++----- src/SUIT/SUIT_FileDlg.h | 109 +- src/SUIT/SUIT_FileValidator.cxx | 200 +++- src/SUIT/SUIT_FileValidator.h | 25 +- src/SUIT/SUIT_TreeModel.cxx | 13 +- src/SUIT/SUIT_TreeModel.h | 4 +- src/SUITApp/SUITApp.pro | 17 +- src/SVTK/SVTK.pro | 24 +- src/SVTK/SVTK_CubeAxesActor2D.cxx | 2 +- src/SVTK/SVTK_RenderWindowInteractor.cxx | 9 +- src/SVTK/SVTK_RenderWindowInteractor.h | 2 +- src/Style/Style.pro | 17 +- src/TableViewer/TableViewer.pro | 29 +- src/TableViewer/TableViewer_ViewWindow.cxx | 2 +- src/VTKViewer/VTKViewer.pro | 30 +- 62 files changed, 3340 insertions(+), 1890 deletions(-) create mode 100644 src/PyInterp/PyInterp_Interp.cxx create mode 100644 src/PyInterp/PyInterp_Interp.h delete mode 100644 src/PyInterp/PyInterp_base.cxx delete mode 100644 src/PyInterp/PyInterp_base.h diff --git a/SUIT.pro b/SUIT.pro index f6ce44637..76ca8e837 100644 --- a/SUIT.pro +++ b/SUIT.pro @@ -1,6 +1,10 @@ -TEMPLATE = subdirs +unix:TEMPLATE = subdirs +win32:TEMPLATE = vcsubdirs + CONFIG += ordered +win32:CONFIG += embed_manifest_exe + SUBDIRS = src/Qtx \ src/Style \ src/ObjBrowser \ diff --git a/src/CAF/CAF.pro b/src/CAF/CAF.pro index cfaca213c..9bd5d3490 100644 --- a/src/CAF/CAF.pro +++ b/src/CAF/CAF.pro @@ -1,4 +1,5 @@ -TEMPLATE = lib +unix:TEMPLATE = lib +win32:TEMPLATE = vclib DESTDIR = ../../$(CONFIG_ID)/lib MOC_DIR = ../../moc @@ -31,7 +32,7 @@ win32:GUIResources = ..\\..\\resources lrelease.name = LRELASE ${QMAKE_FILE_IN} unix:lrelease.commands = $(QTDIR)/bin/lrelease ${QMAKE_FILE_NAME} -qm $${GUIResources}/${QMAKE_FILE_BASE}.qm -win32:lrelease.commands = $(QTDIR)\\bin\\lrelease ${QMAKE_FILE_NAME} -qm $${GUIResources}\\${QMAKE_FILE_BASE}.qm +win32:lrelease.commands = $(QTDIR)\\bin\\lrelease ${QMAKE_FILE_IN} -qm $${GUIResources}\\${QMAKE_FILE_BASE}.qm unix:lrelease.output = $${GUIResources}/${QMAKE_FILE_BASE}.qm win32:lrelease.output = $${GUIResources}\\${QMAKE_FILE_BASE}.qm lrelease.input = TRANSLATIONS diff --git a/src/HTMLService/HTMLService.pro b/src/HTMLService/HTMLService.pro index 54a1af46c..2655ff5c7 100755 --- a/src/HTMLService/HTMLService.pro +++ b/src/HTMLService/HTMLService.pro @@ -1,4 +1,5 @@ -TEMPLATE = lib +unix:TEMPLATE = lib +win32:TEMPLATE = vclib DESTDIR = ../../$(CONFIG_ID)/lib MOC_DIR = ../../moc @@ -12,11 +13,19 @@ CAS_VIEWER = -L$(CASLIB) -lTKV3d -lTKService INCLUDEPATH += ../../include $${CAS_CPPFLAGS} LIBS += -L../../$(CONFIG_ID)/lib $${CAS_KERNEL} $${CAS_VIEWER} +win32:LIBS *= -L$(QTLIB) +win32:INCLUDEPATH *= $(QTINC) $(QTINC)\QtCore $(QTINC)\QtGui $(QTINC)\QtXml CONFIG -= debug release debug_and_release CONFIG += qt thread debug dll shared -win32:DEFINES += WIN32 +win32:copy_hdr.name = Install ${QMAKE_FILE_IN} +win32:copy_hdr.commands = type ${QMAKE_FILE_IN} > ../../include/${QMAKE_FILE_BASE}.hxx +win32:copy_hdr.output = ../../include/${QMAKE_FILE_BASE}.hxx +win32:copy_hdr.input = HEADERS +win32:QMAKE_EXTRA_COMPILERS += copy_hdr + +win32:DEFINES += WNT WIN32 DEFINES += HTMLSERVICE_EXPORTS $(CASDEFINES) OCC_VERSION_MAJOR=6 OCC_VERSION_MINOR=1 OCC_VERSION_MAINTENANCE=1 LIN LINTEL CSFDB No_exception HAVE_CONFIG_H HAVE_LIMITS_H HAVE_WOK_CONFIG_H OCC_CONVERT_SIGNALS HEADERS = *.hxx diff --git a/src/HTMLService/HTMLService_HTML.hxx b/src/HTMLService/HTMLService_HTML.hxx index 083e6ef0c..d5d174826 100755 --- a/src/HTMLService/HTMLService_HTML.hxx +++ b/src/HTMLService/HTMLService_HTML.hxx @@ -1,84 +1,84 @@ -// File: HTMLService_HTML.hxx -// Created: 12.10.2006 -// Author: Sergey TELKOV -// Copyright (C) AREVA NP 2006 - -#ifndef HTMLSERVICE_HTML_H -#define HTMLSERVICE_HTML_H - -#include - -#include -#include - -#include -#include - -class Quantity_Color; -class Handle(HTMLService_HTML); - -typedef NCollection_Sequence SequenceOfHTMLLine; - -/*! - Class HTMLService_HTML. Base class for HTML generation. -*/ - -class HTMLSERVICE_EXPORT HTMLService_HTML : public MMgt_TShared -{ -public: - enum { Left = 0x01, Right = 0x02, Center = 0x04, - Top = 0x08, Bottom = 0x10, Middle = 0x20, - HAlignment = Left | Right | Center, VAlignment = Top | Bottom | Middle } AlignmentFlags; - -public: - Standard_EXPORT HTMLService_HTML(); - Standard_EXPORT HTMLService_HTML( const Handle(HTMLService_HTML)& ); - Standard_EXPORT ~HTMLService_HTML(); - - Standard_EXPORT TCollection_ExtendedString GetTitle() const; - Standard_EXPORT void SetTitle( const TCollection_ExtendedString& ); - - Standard_EXPORT Standard_Boolean GenerateFile( const TCollection_ExtendedString&, - const Standard_Boolean = Standard_False ) const; - Standard_EXPORT SequenceOfHTMLLine GenerateText( const Standard_Boolean = Standard_False ) const; - - Standard_EXPORT static TCollection_ExtendedString ColorString( const Quantity_Color& ); - Standard_EXPORT static TCollection_ExtendedString AlignString( const Standard_Integer ); - - Standard_EXPORT Standard_Boolean IsVisible() const; - Standard_EXPORT void SetVisible( const Standard_Boolean ); - -protected: - Standard_EXPORT virtual void Generate( SequenceOfHTMLLine& ) const = 0; - Standard_EXPORT virtual void SubItemsHTML( SequenceOfHTMLLine& ) const; - - Standard_EXPORT TCollection_ExtendedString EncloseToTag( const TCollection_ExtendedString&, const TCollection_ExtendedString&, - const TCollection_ExtendedString& = TCollection_ExtendedString() ) const; - - Standard_EXPORT void ClearSubItems(); - Standard_EXPORT void InsertSubItem( const Handle(HTMLService_HTML)& ); - Standard_EXPORT void RemoveSubItem( const Handle(HTMLService_HTML)& ); - - void AppendIndent( SequenceOfHTMLLine& ) const; - void AppendIndent( TCollection_ExtendedString& ) const; - void Concatenate( SequenceOfHTMLLine&, const SequenceOfHTMLLine& ) const; - -private: - void BeginDocument( SequenceOfHTMLLine& ) const; - void EndDocument( SequenceOfHTMLLine& ) const; - -private: - typedef NCollection_Sequence HTMLSequence; - -private: - TCollection_ExtendedString myTitle; - Standard_Boolean myVisible; - HTMLSequence mySubItems; - -public: - DEFINE_STANDARD_RTTI(HTMLService_HTML) -}; - -DEFINE_STANDARD_HANDLE(HTMLService_HTML, MMgt_TShared) - -#endif +// File: HTMLService_HTML.hxx +// Created: 12.10.2006 +// Author: Sergey TELKOV +// Copyright (C) AREVA NP 2006 + +#ifndef HTMLSERVICE_HTML_H +#define HTMLSERVICE_HTML_H + +#include + +#include +#include + +#include +#include + +class Quantity_Color; +class Handle(HTMLService_HTML); + +typedef NCollection_Sequence SequenceOfHTMLLine; + +/*! + Class HTMLService_HTML. Base class for HTML generation. +*/ + +class HTMLService_HTML : public MMgt_TShared +{ +public: + enum { Left = 0x01, Right = 0x02, Center = 0x04, + Top = 0x08, Bottom = 0x10, Middle = 0x20, + HAlignment = Left | Right | Center, VAlignment = Top | Bottom | Middle } AlignmentFlags; + +public: + Standard_EXPORT HTMLService_HTML(); + Standard_EXPORT HTMLService_HTML( const Handle(HTMLService_HTML)& ); + Standard_EXPORT ~HTMLService_HTML(); + + Standard_EXPORT TCollection_ExtendedString GetTitle() const; + Standard_EXPORT void SetTitle( const TCollection_ExtendedString& ); + + Standard_EXPORT Standard_Boolean GenerateFile( const TCollection_ExtendedString&, + const Standard_Boolean = Standard_False ) const; + Standard_EXPORT SequenceOfHTMLLine GenerateText( const Standard_Boolean = Standard_False ) const; + + Standard_EXPORT static TCollection_ExtendedString ColorString( const Quantity_Color& ); + Standard_EXPORT static TCollection_ExtendedString AlignString( const Standard_Integer ); + + Standard_EXPORT Standard_Boolean IsVisible() const; + Standard_EXPORT void SetVisible( const Standard_Boolean ); + +protected: + Standard_EXPORT virtual void Generate( SequenceOfHTMLLine& ) const = 0; + Standard_EXPORT virtual void SubItemsHTML( SequenceOfHTMLLine& ) const; + + Standard_EXPORT TCollection_ExtendedString EncloseToTag( const TCollection_ExtendedString&, const TCollection_ExtendedString&, + const TCollection_ExtendedString& = TCollection_ExtendedString() ) const; + + Standard_EXPORT void ClearSubItems(); + Standard_EXPORT void InsertSubItem( const Handle(HTMLService_HTML)& ); + Standard_EXPORT void RemoveSubItem( const Handle(HTMLService_HTML)& ); + + void AppendIndent( SequenceOfHTMLLine& ) const; + void AppendIndent( TCollection_ExtendedString& ) const; + void Concatenate( SequenceOfHTMLLine&, const SequenceOfHTMLLine& ) const; + +private: + void BeginDocument( SequenceOfHTMLLine& ) const; + void EndDocument( SequenceOfHTMLLine& ) const; + +private: + typedef NCollection_Sequence HTMLSequence; + +private: + TCollection_ExtendedString myTitle; + Standard_Boolean myVisible; + HTMLSequence mySubItems; + +public: + DEFINE_STANDARD_RTTI(HTMLService_HTML) +}; + +DEFINE_STANDARD_HANDLE(HTMLService_HTML, MMgt_TShared) + +#endif diff --git a/src/HTMLService/HTMLService_HTMLImage.hxx b/src/HTMLService/HTMLService_HTMLImage.hxx index 95bae3c1d..ba91de642 100755 --- a/src/HTMLService/HTMLService_HTMLImage.hxx +++ b/src/HTMLService/HTMLService_HTMLImage.hxx @@ -1,60 +1,60 @@ -// File: HTMLService_HTMLImage.hxx -// Created: 13.10.2006 -// Author: Sergey TELKOV -// Copyright (C) AREVA NP 2006 - -#ifndef HTMLSERVICE_HTMLIMAGE_H -#define HTMLSERVICE_HTMLIMAGE_H - -#include -#include - -#include - -/*! - Class HTMLService_HTMLImage. Generator of the HTML image. -*/ - -class HTMLSERVICE_EXPORT HTMLService_HTMLImage : public HTMLService_HTML -{ -public: - enum { SP_Unknown, SP_File, SP_HTTP, SP_FTP } SourceProtocol; - -public: - Standard_EXPORT HTMLService_HTMLImage( const TCollection_ExtendedString& = TCollection_ExtendedString() ); - Standard_EXPORT HTMLService_HTMLImage( const Handle(HTMLService_HTML)&, - const TCollection_ExtendedString& = TCollection_ExtendedString() ); - Standard_EXPORT virtual ~HTMLService_HTMLImage(); - - Standard_EXPORT Standard_Integer GetWidth() const; - Standard_EXPORT Standard_Integer GetHeight() const; - Standard_EXPORT TCollection_ExtendedString GetSource() const; - Standard_EXPORT Standard_Integer GetAlignment() const; - Standard_EXPORT Standard_Integer GetSourceProtocol() const; - - Standard_EXPORT void SetWidth( const Standard_Integer ); - Standard_EXPORT void SetHeight( const Standard_Integer ); - Standard_EXPORT void SetAlignment( const Standard_Integer ); - Standard_EXPORT void SetSource( const TCollection_ExtendedString& ); - Standard_EXPORT void SetSourceProtocol( const Standard_Integer& ); - -protected: - Standard_EXPORT virtual void Generate( SequenceOfHTMLLine& ) const; - -private: - TCollection_ExtendedString SourcePrefix() const; - -private: - Standard_Integer myAlign; - Standard_Integer myWidth; - Standard_Integer myHeight; - TCollection_ExtendedString mySource; - Standard_Integer mySrcProto; - -public: - DEFINE_STANDARD_RTTI(HTMLService_HTMLImage) -}; - -DEFINE_STANDARD_HANDLE(HTMLService_HTMLImage, HTMLService_HTML) - -#endif +// File: HTMLService_HTMLImage.hxx +// Created: 13.10.2006 +// Author: Sergey TELKOV +// Copyright (C) AREVA NP 2006 + +#ifndef HTMLSERVICE_HTMLIMAGE_H +#define HTMLSERVICE_HTMLIMAGE_H + +#include +#include + +#include + +/*! + Class HTMLService_HTMLImage. Generator of the HTML image. +*/ + +class HTMLService_HTMLImage : public HTMLService_HTML +{ +public: + enum { SP_Unknown, SP_File, SP_HTTP, SP_FTP } SourceProtocol; + +public: + Standard_EXPORT HTMLService_HTMLImage( const TCollection_ExtendedString& = TCollection_ExtendedString() ); + Standard_EXPORT HTMLService_HTMLImage( const Handle(HTMLService_HTML)&, + const TCollection_ExtendedString& = TCollection_ExtendedString() ); + Standard_EXPORT virtual ~HTMLService_HTMLImage(); + + Standard_EXPORT Standard_Integer GetWidth() const; + Standard_EXPORT Standard_Integer GetHeight() const; + Standard_EXPORT TCollection_ExtendedString GetSource() const; + Standard_EXPORT Standard_Integer GetAlignment() const; + Standard_EXPORT Standard_Integer GetSourceProtocol() const; + + Standard_EXPORT void SetWidth( const Standard_Integer ); + Standard_EXPORT void SetHeight( const Standard_Integer ); + Standard_EXPORT void SetAlignment( const Standard_Integer ); + Standard_EXPORT void SetSource( const TCollection_ExtendedString& ); + Standard_EXPORT void SetSourceProtocol( const Standard_Integer& ); + +protected: + Standard_EXPORT virtual void Generate( SequenceOfHTMLLine& ) const; + +private: + TCollection_ExtendedString SourcePrefix() const; + +private: + Standard_Integer myAlign; + Standard_Integer myWidth; + Standard_Integer myHeight; + TCollection_ExtendedString mySource; + Standard_Integer mySrcProto; + +public: + DEFINE_STANDARD_RTTI(HTMLService_HTMLImage) +}; + +DEFINE_STANDARD_HANDLE(HTMLService_HTMLImage, HTMLService_HTML) + +#endif diff --git a/src/HTMLService/HTMLService_HTMLParagraph.hxx b/src/HTMLService/HTMLService_HTMLParagraph.hxx index 1b65e5176..a1db35603 100755 --- a/src/HTMLService/HTMLService_HTMLParagraph.hxx +++ b/src/HTMLService/HTMLService_HTMLParagraph.hxx @@ -1,44 +1,44 @@ -// File: HTMLService_HTMLParagraph.hxx -// Created: 13.10.2006 -// Author: Sergey TELKOV -// Copyright (C) AREVA NP 2006 - -#ifndef HTMLSERVICE_HTMLPARAGRAPH_H -#define HTMLSERVICE_HTMLPARAGRAPH_H - -#include -#include - -/*! - Class HTMLService_HTMLParagraph. Generator of the HTML paragraph text. -*/ - -class HTMLSERVICE_EXPORT HTMLService_HTMLParagraph : public HTMLService_HTMLText -{ -public: - Standard_EXPORT HTMLService_HTMLParagraph(); - Standard_EXPORT HTMLService_HTMLParagraph( const Handle(HTMLService_HTML)& ); - Standard_EXPORT virtual ~HTMLService_HTMLParagraph(); - - Standard_EXPORT Standard_Boolean GetNoBreak() const; - Standard_EXPORT void SetNoBreak( const Standard_Boolean& ); - - Standard_EXPORT void Clear(); - Standard_EXPORT void Insert( const Handle(HTMLService_HTML)& ); - Standard_EXPORT void InsertText( const TCollection_ExtendedString& ); - Standard_EXPORT void InsertImage( const TCollection_ExtendedString&, - const Standard_Integer = -1, const Standard_Integer = -1 ); - -protected: - Standard_EXPORT virtual void Generate( SequenceOfHTMLLine& ) const; - -private: - Standard_Boolean myNoBr; - -public: - DEFINE_STANDARD_RTTI(HTMLService_HTMLParagraph) -}; - -DEFINE_STANDARD_HANDLE(HTMLService_HTMLParagraph, HTMLService_HTMLText) - -#endif +// File: HTMLService_HTMLParagraph.hxx +// Created: 13.10.2006 +// Author: Sergey TELKOV +// Copyright (C) AREVA NP 2006 + +#ifndef HTMLSERVICE_HTMLPARAGRAPH_H +#define HTMLSERVICE_HTMLPARAGRAPH_H + +#include +#include + +/*! + Class HTMLService_HTMLParagraph. Generator of the HTML paragraph text. +*/ + +class HTMLService_HTMLParagraph : public HTMLService_HTMLText +{ +public: + Standard_EXPORT HTMLService_HTMLParagraph(); + Standard_EXPORT HTMLService_HTMLParagraph( const Handle(HTMLService_HTML)& ); + Standard_EXPORT virtual ~HTMLService_HTMLParagraph(); + + Standard_EXPORT Standard_Boolean GetNoBreak() const; + Standard_EXPORT void SetNoBreak( const Standard_Boolean& ); + + Standard_EXPORT void Clear(); + Standard_EXPORT void Insert( const Handle(HTMLService_HTML)& ); + Standard_EXPORT void InsertText( const TCollection_ExtendedString& ); + Standard_EXPORT void InsertImage( const TCollection_ExtendedString&, + const Standard_Integer = -1, const Standard_Integer = -1 ); + +protected: + Standard_EXPORT virtual void Generate( SequenceOfHTMLLine& ) const; + +private: + Standard_Boolean myNoBr; + +public: + DEFINE_STANDARD_RTTI(HTMLService_HTMLParagraph) +}; + +DEFINE_STANDARD_HANDLE(HTMLService_HTMLParagraph, HTMLService_HTMLText) + +#endif diff --git a/src/HTMLService/HTMLService_HTMLTable.hxx b/src/HTMLService/HTMLService_HTMLTable.hxx index 840f0aa04..40b3b0b91 100755 --- a/src/HTMLService/HTMLService_HTMLTable.hxx +++ b/src/HTMLService/HTMLService_HTMLTable.hxx @@ -1,77 +1,77 @@ -// File: HTMLService_HTMLTable.hxx -// Created: 12.10.2006 -// Author: Sergey TELKOV -// Copyright (C) AREVA NP 2006 - -#ifndef HTMLSERVICE_HTMLTABLE_H -#define HTMLSERVICE_HTMLTABLE_H - -#include -#include - -#include - -#include - -#include - -/*! - Class HTMLService_HTMLTable. Generator of the HTML Table text. -*/ - -class HTMLSERVICE_EXPORT HTMLService_HTMLTable : public HTMLService_HTML -{ -public: - Standard_EXPORT HTMLService_HTMLTable( const Standard_Integer = 0, const Standard_Integer = 0 ); - Standard_EXPORT HTMLService_HTMLTable( const Handle(HTMLService_HTML)&, const Standard_Integer = 0, const Standard_Integer = 0 ); - Standard_EXPORT virtual ~HTMLService_HTMLTable(); - - Standard_EXPORT Standard_Integer GetNumRows() const; - Standard_EXPORT Standard_Integer GetNumCols() const; - - Standard_EXPORT Handle(HTMLService_HTMLTableRow) GetRow( const Standard_Integer ) const; - Standard_EXPORT Handle(HTMLService_HTMLTableCell) GetCell( const Standard_Integer, const Standard_Integer ) const; - - Standard_EXPORT Standard_Integer GetBorder() const; - Standard_EXPORT Standard_Integer GetCellSpacing() const; - Standard_EXPORT Standard_Integer GetCellPadding() const; - Standard_EXPORT Quantity_Color GetBackgroundColor() const; - Standard_EXPORT Standard_Integer GetWidth( Standard_Boolean* = 0 ) const; - - Standard_EXPORT void SetBorder( const Standard_Integer ); - Standard_EXPORT void SetCellSpacing( const Standard_Integer ); - Standard_EXPORT void SetCellPadding( const Standard_Integer ); - Standard_EXPORT void SetBackgroundColor( const Quantity_Color& ); - Standard_EXPORT void SetWidth( const Standard_Integer, - const Standard_Boolean = Standard_False ); - - Standard_EXPORT void SetRowSpan( const Standard_Integer, const Standard_Integer ); - Standard_EXPORT void SetColumnSpan( const Standard_Integer, const Standard_Integer ); - Standard_EXPORT void SetColumnWidth( const Standard_Integer, const Standard_Integer, - const Standard_Boolean = Standard_False ); - -protected: - Standard_EXPORT virtual void Generate( SequenceOfHTMLLine& ) const; - -private: - void PrepareCells() const; - void Initialize( const Standard_Integer, const Standard_Integer ); - -private: - Handle(TColStd_HArray1OfTransient) myRows; - - Standard_Boolean myUseBC; - Standard_Integer myWidth; - Standard_Integer myBorder; - Standard_Boolean myPercent; - Quantity_Color myBgColor; - Standard_Integer mySpacing; - Standard_Integer myPadding; - -public: - DEFINE_STANDARD_RTTI(HTMLService_HTMLTable) -}; - -DEFINE_STANDARD_HANDLE(HTMLService_HTMLTable, HTMLService_HTML) - -#endif +// File: HTMLService_HTMLTable.hxx +// Created: 12.10.2006 +// Author: Sergey TELKOV +// Copyright (C) AREVA NP 2006 + +#ifndef HTMLSERVICE_HTMLTABLE_H +#define HTMLSERVICE_HTMLTABLE_H + +#include +#include + +#include + +#include + +#include + +/*! + Class HTMLService_HTMLTable. Generator of the HTML Table text. +*/ + +class HTMLService_HTMLTable : public HTMLService_HTML +{ +public: + Standard_EXPORT HTMLService_HTMLTable( const Standard_Integer = 0, const Standard_Integer = 0 ); + Standard_EXPORT HTMLService_HTMLTable( const Handle(HTMLService_HTML)&, const Standard_Integer = 0, const Standard_Integer = 0 ); + Standard_EXPORT virtual ~HTMLService_HTMLTable(); + + Standard_EXPORT Standard_Integer GetNumRows() const; + Standard_EXPORT Standard_Integer GetNumCols() const; + + Standard_EXPORT Handle(HTMLService_HTMLTableRow) GetRow( const Standard_Integer ) const; + Standard_EXPORT Handle(HTMLService_HTMLTableCell) GetCell( const Standard_Integer, const Standard_Integer ) const; + + Standard_EXPORT Standard_Integer GetBorder() const; + Standard_EXPORT Standard_Integer GetCellSpacing() const; + Standard_EXPORT Standard_Integer GetCellPadding() const; + Standard_EXPORT Quantity_Color GetBackgroundColor() const; + Standard_EXPORT Standard_Integer GetWidth( Standard_Boolean* = 0 ) const; + + Standard_EXPORT void SetBorder( const Standard_Integer ); + Standard_EXPORT void SetCellSpacing( const Standard_Integer ); + Standard_EXPORT void SetCellPadding( const Standard_Integer ); + Standard_EXPORT void SetBackgroundColor( const Quantity_Color& ); + Standard_EXPORT void SetWidth( const Standard_Integer, + const Standard_Boolean = Standard_False ); + + Standard_EXPORT void SetRowSpan( const Standard_Integer, const Standard_Integer ); + Standard_EXPORT void SetColumnSpan( const Standard_Integer, const Standard_Integer ); + Standard_EXPORT void SetColumnWidth( const Standard_Integer, const Standard_Integer, + const Standard_Boolean = Standard_False ); + +protected: + Standard_EXPORT virtual void Generate( SequenceOfHTMLLine& ) const; + +private: + void PrepareCells() const; + void Initialize( const Standard_Integer, const Standard_Integer ); + +private: + Handle(TColStd_HArray1OfTransient) myRows; + + Standard_Boolean myUseBC; + Standard_Integer myWidth; + Standard_Integer myBorder; + Standard_Boolean myPercent; + Quantity_Color myBgColor; + Standard_Integer mySpacing; + Standard_Integer myPadding; + +public: + DEFINE_STANDARD_RTTI(HTMLService_HTMLTable) +}; + +DEFINE_STANDARD_HANDLE(HTMLService_HTMLTable, HTMLService_HTML) + +#endif diff --git a/src/HTMLService/HTMLService_HTMLTableCell.hxx b/src/HTMLService/HTMLService_HTMLTableCell.hxx index c90c0caae..57c33d20b 100755 --- a/src/HTMLService/HTMLService_HTMLTableCell.hxx +++ b/src/HTMLService/HTMLService_HTMLTableCell.hxx @@ -1,63 +1,63 @@ -// File: HTMLService_HTMLTableCell.hxx -// Created: 12.10.2006 -// Author: Sergey TELKOV -// Copyright (C) AREVA NP 2006 - -#ifndef HTMLService_HTMLTABLECELL_H -#define HTMLService_HTMLTABLECELL_H - -#include -#include - -#include - -/*! - Class HTMLService_HTMLTableCell. Generator of the HTML Table cell text. -*/ - -class HTMLSERVICE_EXPORT HTMLService_HTMLTableCell : public HTMLService_HTMLParagraph -{ -public: - Standard_EXPORT HTMLService_HTMLTableCell(); - Standard_EXPORT HTMLService_HTMLTableCell( const Handle(HTMLService_HTML)& ); - Standard_EXPORT virtual ~HTMLService_HTMLTableCell(); - - Standard_EXPORT Standard_Integer GetColSpan() const; - Standard_EXPORT Standard_Integer GetRowSpan() const; - Standard_EXPORT Standard_Integer GetAlignment() const; - Standard_EXPORT Standard_Integer GetWidth( Standard_Boolean* = 0 ) const; - - Standard_EXPORT Quantity_Color GetBackgroundColor() const; - Standard_EXPORT Standard_Boolean IsHeaderCell() const; - - Standard_EXPORT void SetColSpan( const Standard_Integer ); - Standard_EXPORT void SetRowSpan( const Standard_Integer ); - Standard_EXPORT void SetAlignment( const Standard_Integer ); - Standard_EXPORT void SetWidth( const Standard_Integer, - const Standard_Boolean = Standard_False ); - Standard_EXPORT void SetBackgroundColor( const Quantity_Color& ); - Standard_EXPORT void SetHeaderCell( const Standard_Boolean ); - -protected: - Standard_EXPORT virtual void Generate( SequenceOfHTMLLine& ) const; - -private: - TCollection_ExtendedString CellString() const; - -private: - Standard_Integer myWidth; - Standard_Integer myAlign; - Standard_Boolean myUseBC; - Standard_Boolean myPercent; - Standard_Integer myColSpan; - Standard_Integer myRowSpan; - Quantity_Color myBgColor; - Standard_Boolean myIsHeader; - -public: - DEFINE_STANDARD_RTTI(HTMLService_HTMLTableCell) -}; - -DEFINE_STANDARD_HANDLE(HTMLService_HTMLTableCell, HTMLService_HTMLParagraph) - -#endif +// File: HTMLService_HTMLTableCell.hxx +// Created: 12.10.2006 +// Author: Sergey TELKOV +// Copyright (C) AREVA NP 2006 + +#ifndef HTMLService_HTMLTABLECELL_H +#define HTMLService_HTMLTABLECELL_H + +#include +#include + +#include + +/*! + Class HTMLService_HTMLTableCell. Generator of the HTML Table cell text. +*/ + +class HTMLService_HTMLTableCell : public HTMLService_HTMLParagraph +{ +public: + Standard_EXPORT HTMLService_HTMLTableCell(); + Standard_EXPORT HTMLService_HTMLTableCell( const Handle(HTMLService_HTML)& ); + Standard_EXPORT virtual ~HTMLService_HTMLTableCell(); + + Standard_EXPORT Standard_Integer GetColSpan() const; + Standard_EXPORT Standard_Integer GetRowSpan() const; + Standard_EXPORT Standard_Integer GetAlignment() const; + Standard_EXPORT Standard_Integer GetWidth( Standard_Boolean* = 0 ) const; + + Standard_EXPORT Quantity_Color GetBackgroundColor() const; + Standard_EXPORT Standard_Boolean IsHeaderCell() const; + + Standard_EXPORT void SetColSpan( const Standard_Integer ); + Standard_EXPORT void SetRowSpan( const Standard_Integer ); + Standard_EXPORT void SetAlignment( const Standard_Integer ); + Standard_EXPORT void SetWidth( const Standard_Integer, + const Standard_Boolean = Standard_False ); + Standard_EXPORT void SetBackgroundColor( const Quantity_Color& ); + Standard_EXPORT void SetHeaderCell( const Standard_Boolean ); + +protected: + Standard_EXPORT virtual void Generate( SequenceOfHTMLLine& ) const; + +private: + TCollection_ExtendedString CellString() const; + +private: + Standard_Integer myWidth; + Standard_Integer myAlign; + Standard_Boolean myUseBC; + Standard_Boolean myPercent; + Standard_Integer myColSpan; + Standard_Integer myRowSpan; + Quantity_Color myBgColor; + Standard_Boolean myIsHeader; + +public: + DEFINE_STANDARD_RTTI(HTMLService_HTMLTableCell) +}; + +DEFINE_STANDARD_HANDLE(HTMLService_HTMLTableCell, HTMLService_HTMLParagraph) + +#endif diff --git a/src/HTMLService/HTMLService_HTMLTableRow.hxx b/src/HTMLService/HTMLService_HTMLTableRow.hxx index 6dd714e27..d626a4f6d 100755 --- a/src/HTMLService/HTMLService_HTMLTableRow.hxx +++ b/src/HTMLService/HTMLService_HTMLTableRow.hxx @@ -1,50 +1,50 @@ -// File: HTMLService_HTMLTableRow.hxx -// Created: 12.10.2006 -// Author: Sergey TELKOV -// Copyright (C) AREVA NP 2006 - -#ifndef HTMLService_HTMLTABLEROW_H -#define HTMLService_HTMLTABLEROW_H - -#include -#include - -#include - -#include - -/*! - Class HTMLService_HTMLTableRow. Generator of the HTML Table row text. -*/ - -class HTMLSERVICE_EXPORT HTMLService_HTMLTableRow : public HTMLService_HTML -{ -public: - Standard_EXPORT HTMLService_HTMLTableRow( const Standard_Integer = 0 ); - Standard_EXPORT HTMLService_HTMLTableRow( const Handle(HTMLService_HTML)&, const Standard_Integer = 0 ); - Standard_EXPORT virtual ~HTMLService_HTMLTableRow(); - - Standard_EXPORT Standard_Integer GetSize() const; - Standard_EXPORT Handle(HTMLService_HTMLTableCell) GetCell( const Standard_Integer ) const; - - Standard_EXPORT Quantity_Color GetBackgroundColor() const; - Standard_EXPORT void SetBackgroundColor( const Quantity_Color& ); - -protected: - Standard_EXPORT virtual void Generate( SequenceOfHTMLLine& ) const; - -private: - void Initialize( const Standard_Integer ); - -private: - Handle(TColStd_HArray1OfTransient) myCells; - Standard_Boolean myUseBC; - Quantity_Color myBgColor; - -public: - DEFINE_STANDARD_RTTI(HTMLService_HTMLTableRow) -}; - -DEFINE_STANDARD_HANDLE(HTMLService_HTMLTableRow, HTMLService_HTML) - -#endif +// File: HTMLService_HTMLTableRow.hxx +// Created: 12.10.2006 +// Author: Sergey TELKOV +// Copyright (C) AREVA NP 2006 + +#ifndef HTMLService_HTMLTABLEROW_H +#define HTMLService_HTMLTABLEROW_H + +#include +#include + +#include + +#include + +/*! + Class HTMLService_HTMLTableRow. Generator of the HTML Table row text. +*/ + +class HTMLService_HTMLTableRow : public HTMLService_HTML +{ +public: + Standard_EXPORT HTMLService_HTMLTableRow( const Standard_Integer = 0 ); + Standard_EXPORT HTMLService_HTMLTableRow( const Handle(HTMLService_HTML)&, const Standard_Integer = 0 ); + Standard_EXPORT virtual ~HTMLService_HTMLTableRow(); + + Standard_EXPORT Standard_Integer GetSize() const; + Standard_EXPORT Handle(HTMLService_HTMLTableCell) GetCell( const Standard_Integer ) const; + + Standard_EXPORT Quantity_Color GetBackgroundColor() const; + Standard_EXPORT void SetBackgroundColor( const Quantity_Color& ); + +protected: + Standard_EXPORT virtual void Generate( SequenceOfHTMLLine& ) const; + +private: + void Initialize( const Standard_Integer ); + +private: + Handle(TColStd_HArray1OfTransient) myCells; + Standard_Boolean myUseBC; + Quantity_Color myBgColor; + +public: + DEFINE_STANDARD_RTTI(HTMLService_HTMLTableRow) +}; + +DEFINE_STANDARD_HANDLE(HTMLService_HTMLTableRow, HTMLService_HTML) + +#endif diff --git a/src/HTMLService/HTMLService_HTMLText.hxx b/src/HTMLService/HTMLService_HTMLText.hxx index 4cd110102..06155bf72 100755 --- a/src/HTMLService/HTMLService_HTMLText.hxx +++ b/src/HTMLService/HTMLService_HTMLText.hxx @@ -1,58 +1,58 @@ -// File: HTMLService_HTMLText.hxx -// Created: 13.10.2006 -// Author: Sergey TELKOV -// Copyright (C) AREVA NP 2006 - -#ifndef HTMLSERVICE_HTMLTEXT_H -#define HTMLSERVICE_HTMLTEXT_H - -#include -#include - -#include - -/*! - Class HTMLService_HTMLText. Generator of the simple HTML text. -*/ - -class HTMLSERVICE_EXPORT HTMLService_HTMLText : public HTMLService_HTML -{ -public: - enum { Normal = 0x00, Bold = 0x01, Italic = 0x02, Underline = 0x04, - StrikeOut = 0x08, Subscript = 0x10, Superscript = 0x20 } FontFlags; - -public: - Standard_EXPORT HTMLService_HTMLText( const TCollection_ExtendedString& = TCollection_ExtendedString(), - const Standard_Integer = Normal ); - Standard_EXPORT HTMLService_HTMLText( const Handle(HTMLService_HTML)&, - const TCollection_ExtendedString& = TCollection_ExtendedString(), - const Standard_Integer = Normal ); - Standard_EXPORT virtual ~HTMLService_HTMLText(); - - Standard_EXPORT TCollection_ExtendedString GetText() const; - Standard_EXPORT Standard_Integer GetFontFlags() const; - Standard_EXPORT Standard_Integer GetHeadingLevel() const; - Standard_EXPORT Quantity_Color GetForegroundColor() const; - - Standard_EXPORT void SetFontFlags( const Standard_Integer ); - Standard_EXPORT void SetHeadingLevel( const Standard_Integer ); - Standard_EXPORT void SetForegroundColor( const Quantity_Color& ); - Standard_EXPORT void SetText( const TCollection_ExtendedString& ); - -protected: - Standard_EXPORT virtual void Generate( SequenceOfHTMLLine& ) const; - -private: - TCollection_ExtendedString myText; - Quantity_Color myColor; - Standard_Integer myHeading; - Standard_Boolean myUseColor; - Standard_Integer myFontFlags; - -public: - DEFINE_STANDARD_RTTI(HTMLService_HTMLText) -}; - -DEFINE_STANDARD_HANDLE(HTMLService_HTMLText, HTMLService_HTML) - -#endif +// File: HTMLService_HTMLText.hxx +// Created: 13.10.2006 +// Author: Sergey TELKOV +// Copyright (C) AREVA NP 2006 + +#ifndef HTMLSERVICE_HTMLTEXT_H +#define HTMLSERVICE_HTMLTEXT_H + +#include +#include + +#include + +/*! + Class HTMLService_HTMLText. Generator of the simple HTML text. +*/ + +class HTMLService_HTMLText : public HTMLService_HTML +{ +public: + enum { Normal = 0x00, Bold = 0x01, Italic = 0x02, Underline = 0x04, + StrikeOut = 0x08, Subscript = 0x10, Superscript = 0x20 } FontFlags; + +public: + Standard_EXPORT HTMLService_HTMLText( const TCollection_ExtendedString& = TCollection_ExtendedString(), + const Standard_Integer = Normal ); + Standard_EXPORT HTMLService_HTMLText( const Handle(HTMLService_HTML)&, + const TCollection_ExtendedString& = TCollection_ExtendedString(), + const Standard_Integer = Normal ); + Standard_EXPORT virtual ~HTMLService_HTMLText(); + + Standard_EXPORT TCollection_ExtendedString GetText() const; + Standard_EXPORT Standard_Integer GetFontFlags() const; + Standard_EXPORT Standard_Integer GetHeadingLevel() const; + Standard_EXPORT Quantity_Color GetForegroundColor() const; + + Standard_EXPORT void SetFontFlags( const Standard_Integer ); + Standard_EXPORT void SetHeadingLevel( const Standard_Integer ); + Standard_EXPORT void SetForegroundColor( const Quantity_Color& ); + Standard_EXPORT void SetText( const TCollection_ExtendedString& ); + +protected: + Standard_EXPORT virtual void Generate( SequenceOfHTMLLine& ) const; + +private: + TCollection_ExtendedString myText; + Quantity_Color myColor; + Standard_Integer myHeading; + Standard_Boolean myUseColor; + Standard_Integer myFontFlags; + +public: + DEFINE_STANDARD_RTTI(HTMLService_HTMLText) +}; + +DEFINE_STANDARD_HANDLE(HTMLService_HTMLText, HTMLService_HTML) + +#endif diff --git a/src/LogWindow/LogWindow.pro b/src/LogWindow/LogWindow.pro index aafb19a4f..653c56df1 100644 --- a/src/LogWindow/LogWindow.pro +++ b/src/LogWindow/LogWindow.pro @@ -1,17 +1,21 @@ -TEMPLATE = lib +unix:TEMPLATE = lib +win32:TEMPLATE = vclib + +win32:QMAKE_MOC=$(QTDIR)\bin\moc.exe DESTDIR = ../../$(CONFIG_ID)/lib MOC_DIR = ../../moc OBJECTS_DIR = ../../$(CONFIG_ID)/obj/$$TARGET INCLUDEPATH = ../../include -win32:LIBS += ../../lib/suit.lib ../../lib/qtx.lib -unix:LIBS += -L../../$(CONFIG_ID)/lib -lSUIT -lQtx +LIBS += -L../../$(CONFIG_ID)/lib -lSUIT -lQtx +win32:LIBS *= -L$(QTLIB) +win32:INCLUDEPATH *= $(QTINC) $(QTINC)\QtCore $(QTINC)\QtGui $(QTINC)\QtXml CONFIG -= debug release debug_and_release CONFIG += qt thread debug dll shared -win32:DEFINES += WIN32 +win32:DEFINES += WNT WIN32 DEFINES += LOGWINDOW_EXPORTS HEADERS = *.h @@ -25,7 +29,7 @@ win32:GUIResources = ..\\..\\resources lrelease.name = LRELASE ${QMAKE_FILE_IN} unix:lrelease.commands = $(QTDIR)/bin/lrelease ${QMAKE_FILE_NAME} -qm $${GUIResources}/${QMAKE_FILE_BASE}.qm -win32:lrelease.commands = $(QTDIR)\\bin\\lrelease ${QMAKE_FILE_NAME} -qm $${GUIResources}\\${QMAKE_FILE_BASE}.qm +win32:lrelease.commands = $(QTDIR)\\bin\\lrelease ${QMAKE_FILE_IN} -qm $${GUIResources}\\${QMAKE_FILE_BASE}.qm unix:lrelease.output = $${GUIResources}/${QMAKE_FILE_BASE}.qm win32:lrelease.output = $${GUIResources}\\${QMAKE_FILE_BASE}.qm lrelease.input = TRANSLATIONS @@ -34,6 +38,12 @@ win32:lrelease.clean = $${GUIResources}\\${QMAKE_FILE_BASE}.qm lrelease.CONFIG += no_link target_predeps QMAKE_EXTRA_COMPILERS += lrelease +win32:copy_hdr.name = Install ${QMAKE_FILE_IN} +win32:copy_hdr.commands = type ${QMAKE_FILE_IN} > ../../include/${QMAKE_FILE_BASE}.h +win32:copy_hdr.output = ../../include/${QMAKE_FILE_BASE}.h +win32:copy_hdr.input = HEADERS +win32:QMAKE_EXTRA_COMPILERS += copy_hdr + includes.files = $$HEADERS includes.path = ../../include diff --git a/src/OBJECT/OBJECT.pro b/src/OBJECT/OBJECT.pro index 86459b714..7b8f30f2a 100644 --- a/src/OBJECT/OBJECT.pro +++ b/src/OBJECT/OBJECT.pro @@ -1,4 +1,7 @@ -TEMPLATE = lib +unix:TEMPLATE = lib +win32:TEMPLATE = vclib + +win32:QMAKE_MOC=$(QTDIR)\bin\moc.exe DESTDIR = ../../$(CONFIG_ID)/lib MOC_DIR = ../../moc @@ -6,15 +9,18 @@ OBJECTS_DIR = ../../$(CONFIG_ID)/obj/$$TARGET CAS_CPPFLAGS = $(CASINC) -CAS_LDPATH = -L$(CASLIB) -lTKV3d +unix:CAS_LDPATH = -L$(CASLIB) -lTKV3d +win32:CAS_LDPATH = -L$(CASLIB) -lTKernel -lTKMath -lTKV3d INCLUDEPATH += ../../include $${CAS_CPPFLAGS} LIBS += $${CAS_LDPATH} +win32:LIBS *= -L$(QTLIB) +win32:INCLUDEPATH *= $(QTINC) $(QTINC)\QtCore $(QTINC)\QtGui $(QTINC)\QtXml CONFIG -= debug release debug_and_release CONFIG += qt thread debug dll shared -win32:DEFINES += WIN32 +win32:DEFINES += WNT WIN32 DEFINES += $(CASDEFINES) OCC_VERSION_MAJOR=6 OCC_VERSION_MINOR=1 OCC_VERSION_MAINTENANCE=1 LIN LINTEL CSFDB No_exception HAVE_CONFIG_H HAVE_LIMITS_H HAVE_WOK_CONFIG_H OCC_CONVERT_SIGNALS HEADERS = *.hxx @@ -24,6 +30,13 @@ HEADERS += *.jxx SOURCES = *.cxx +win32:COPY_FILES = *.hxx *.h +win32:copy_hxx.name = Install(.hxx) ${QMAKE_FILE_IN} +win32:copy_hxx.commands = type ${QMAKE_FILE_IN} > ../../include/${QMAKE_FILE_BASE}.hxx +win32:copy_hxx.output = ../../include/${QMAKE_FILE_BASE}.hxx +win32:copy_hxx.input = COPY_FILES +win32:QMAKE_EXTRA_COMPILERS += copy_hxx + includes.files = $$HEADERS includes.path = ../../include diff --git a/src/ObjBrowser/ObjBrowser.pro b/src/ObjBrowser/ObjBrowser.pro index 61bf93c5b..ff7dd2bd0 100644 --- a/src/ObjBrowser/ObjBrowser.pro +++ b/src/ObjBrowser/ObjBrowser.pro @@ -1,4 +1,7 @@ -TEMPLATE = lib +unix:TEMPLATE = lib +win32:TEMPLATE = vclib + +win32:QMAKE_MOC=$(QTDIR)\bin\moc.exe DESTDIR = ../../$(CONFIG_ID)/lib MOC_DIR = ../../moc @@ -6,12 +9,14 @@ OBJECTS_DIR = ../../$(CONFIG_ID)/obj/$$TARGET INCLUDEPATH += ../../include ../Qtx LIBS += -L../../$(CONFIG_ID)/lib -lQtx +win32:LIBS *= -L$(QTLIB) +win32:INCLUDEPATH *= $(QTINC) $(QTINC)\QtCore $(QTINC)\QtGui $(QTINC)\QtXml CONFIG -= debug release debug_and_release CONFIG += qt thread debug dll shared -win32:DEFINES += WIN32 -DEFINES += LOGWINDOW_EXPORTS +win32:DEFINES += WNT WIN32 +DEFINES += OB_EXPORTS HEADERS = *.h @@ -24,7 +29,7 @@ win32:GUIResources = ..\\..\\resources lrelease.name = LRELASE ${QMAKE_FILE_IN} unix:lrelease.commands = $(QTDIR)/bin/lrelease ${QMAKE_FILE_NAME} -qm $${GUIResources}/${QMAKE_FILE_BASE}.qm -win32:lrelease.commands = $(QTDIR)\\bin\\lrelease ${QMAKE_FILE_NAME} -qm $${GUIResources}\\${QMAKE_FILE_BASE}.qm +win32:lrelease.commands = $(QTDIR)\\bin\\lrelease ${QMAKE_FILE_IN} -qm $${GUIResources}\\${QMAKE_FILE_BASE}.qm unix:lrelease.output = $${GUIResources}/${QMAKE_FILE_BASE}.qm win32:lrelease.output = $${GUIResources}\\${QMAKE_FILE_BASE}.qm lrelease.input = TRANSLATIONS @@ -33,6 +38,13 @@ win32:lrelease.clean = $${GUIResources}\\${QMAKE_FILE_BASE}.qm lrelease.CONFIG += no_link target_predeps QMAKE_EXTRA_COMPILERS += lrelease +win32:copy_hdr.name = Install ${QMAKE_FILE_IN} +win32:copy_hdr.commands = type ${QMAKE_FILE_IN} > ../../include/${QMAKE_FILE_BASE}.h +win32:copy_hdr.output = ../../include/${QMAKE_FILE_BASE}.h +win32:copy_hdr.input = HEADERS +win32:QMAKE_EXTRA_COMPILERS += copy_hdr + + includes.files = $$HEADERS includes.path = ../../include diff --git a/src/Plot2d/Plot2d.pro b/src/Plot2d/Plot2d.pro index 9a06a130f..976b8d7c1 100644 --- a/src/Plot2d/Plot2d.pro +++ b/src/Plot2d/Plot2d.pro @@ -1,4 +1,7 @@ -TEMPLATE = lib +unix:TEMPLATE = lib +win32:TEMPLATE = vclib + +win32:QMAKE_MOC=$(QTDIR)\bin\moc.exe DESTDIR = ../../$(CONFIG_ID)/lib MOC_DIR = ../../moc @@ -7,13 +10,15 @@ OBJECTS_DIR = ../../$(CONFIG_ID)/obj/$$TARGET INCLUDEPATH += ../../include $$(QWTINC) $$(PYTHONINC) INCLUDEPATH += ../Qtx ../SUIT unix:LIBS += -L$$(QWTLIB) -lqwt -win32:LIBS += /LIBPATH:$$(QWTLIB) +win32:LIBS += /LIBPATH:$$(QWTLIB) -lqwt5 LIBS += -L../../$(CONFIG_ID)/lib -lQtx -lSUIT +win32:LIBS *= -L$(QTLIB) +win32:INCLUDEPATH *= $(QTINC) $(QTINC)\QtCore $(QTINC)\QtGui $(QTINC)\QtXml CONFIG -= debug release debug_and_release CONFIG += qt thread debug dll shared -win32:DEFINES += WIN32 +win32:DEFINES += WNT WIN32 QWT_DLL DEFINES += PLOT2D_EXPORTS HEADERS = *.h @@ -26,9 +31,15 @@ TRANSLATIONS = resources/Plot2d_msg_en.ts \ unix:GUIResources = ../../resources win32:GUIResources = ..\\..\\resources +win32:copy_hdr.name = Install headers ${QMAKE_FILE_IN} +win32:copy_hdr.commands = type ${QMAKE_FILE_IN} > ${QMAKE_FILE_OUT} +win32:copy_hdr.output = ../../include/${QMAKE_FILE_BASE}.h +win32:copy_hdr.input = HEADERS +win32:QMAKE_EXTRA_COMPILERS += copy_hdr + lrelease.name = LRELASE ${QMAKE_FILE_IN} -unix:lrelease.commands = $(QTDIR)/bin/lrelease ${QMAKE_FILE_NAME} -qm $${GUIResources}/${QMAKE_FILE_BASE}.qm -win32:lrelease.commands = $(QTDIR)\\bin\\lrelease ${QMAKE_FILE_NAME} -qm $${GUIResources}\\${QMAKE_FILE_BASE}.qm +unix:lrelease.commands = $(QTDIR)/bin/lrelease ${QMAKE_FILE_NAME} -qm ${QMAKE_FILE_OUT} +win32:lrelease.commands = $(QTDIR)\\bin\\lrelease ${QMAKE_FILE_IN} -qm ${QMAKE_FILE_OUT} unix:lrelease.output = $${GUIResources}/${QMAKE_FILE_BASE}.qm win32:lrelease.output = $${GUIResources}\\${QMAKE_FILE_BASE}.qm lrelease.input = TRANSLATIONS @@ -39,6 +50,14 @@ QMAKE_EXTRA_COMPILERS += lrelease ICONS = resources/*.png +win32:SOURCES+=$$ICONS +win32:Resource=$$ICONS +win32:copy_res.name = Install resources ${QMAKE_FILE_IN} +win32:copy_res.commands = type ${QMAKE_FILE_IN} > ${QMAKE_FILE_OUT} +win32:copy_res.output = $${GUIResources}\\${QMAKE_FILE_BASE}.png +win32:copy_res.input = Resource +win32:QMAKE_EXTRA_COMPILERS += copy_res + includes.files = $$HEADERS includes.path = ../../include diff --git a/src/Plot2d/Plot2d_HistogramItem.cxx b/src/Plot2d/Plot2d_HistogramItem.cxx index 5b503c714..9893c8a10 100644 --- a/src/Plot2d/Plot2d_HistogramItem.cxx +++ b/src/Plot2d/Plot2d_HistogramItem.cxx @@ -437,7 +437,7 @@ void Plot2d_HistogramItem::drawRectAndLowers( QPainter* thePainter, { QRect aRect = theRect; // theRect has inversed coordinates on Y axis. The top of the rect is bottom in standard QRect coordinates, and it bottom is the top. - if ( m_bCrossed && theOr == Qt::Horizontal ) + if ( m_bCrossed )//&& theOr == Qt::Horizontal ) aRect.setTop( getCrossedTop( theRect ) ); drawBar( thePainter, Qt::Horizontal, aRect ); diff --git a/src/Plot2d/Plot2d_HistogramItem.h b/src/Plot2d/Plot2d_HistogramItem.h index 37408a165..889e829bb 100644 --- a/src/Plot2d/Plot2d_HistogramItem.h +++ b/src/Plot2d/Plot2d_HistogramItem.h @@ -66,7 +66,6 @@ protected: protected: void init(); - class PrivateData; PrivateData* m_pData; }; @@ -87,11 +86,11 @@ public: void setCrossItems( const bool& theCross ) { m_bCrossed = theCross; } bool isCrossItems() const { return m_bCrossed; } -private: +protected: void drawRectAndLowers( QPainter* , Qt::Orientation, const QRect& ) const; int getCrossedTop( const QRect& ) const; -private: +protected: QList m_BarItems; bool m_bCrossed; }; diff --git a/src/Plot2d/Plot2d_Object.h b/src/Plot2d/Plot2d_Object.h index 3db5b1b91..da2ea362d 100755 --- a/src/Plot2d/Plot2d_Object.h +++ b/src/Plot2d/Plot2d_Object.h @@ -28,12 +28,12 @@ #include #include -typedef struct +struct PLOT2D_EXPORT Plot2d_Point { double x; double y; QString text; -} Plot2d_Point; +}; typedef QList pointList; diff --git a/src/Plot2d/Plot2d_ViewFrame.h b/src/Plot2d/Plot2d_ViewFrame.h index 2637a16ab..ced090ea8 100755 --- a/src/Plot2d/Plot2d_ViewFrame.h +++ b/src/Plot2d/Plot2d_ViewFrame.h @@ -225,6 +225,7 @@ class Plot2d_Plot2d : public QwtPlot Q_OBJECT public: Plot2d_Plot2d( QWidget* parent ); + virtual ~Plot2d_Plot2d() {}; void setLogScale( int axisId, bool log10 ); diff --git a/src/Prs/Prs.pro b/src/Prs/Prs.pro index 06b145539..b4fe7e1fc 100644 --- a/src/Prs/Prs.pro +++ b/src/Prs/Prs.pro @@ -1,19 +1,31 @@ -TEMPLATE = lib +unix:TEMPLATE = lib +win32:TEMPLATE = vclib + +win32:QMAKE_MOC=$(QTDIR)\bin\moc.exe DESTDIR = ../../$(CONFIG_ID)/lib MOC_DIR = ../../moc OBJECTS_DIR = ../../$(CONFIG_ID)/obj/$$TARGET +win32:LIBS *= -L$(QTLIB) +win32:INCLUDEPATH *= $(QTINC) $(QTINC)\QtCore $(QTINC)\QtGui $(QTINC)\QtXml + CONFIG -= debug release debug_and_release CONFIG += qt thread debug dll shared -win32:DEFINES += WIN32 +win32:DEFINES += WNT WIN32 DEFINES += PRS_EXPORTS HEADERS = *.h SOURCES = *.cxx +win32:copy_hdr.name = Install ${QMAKE_FILE_IN} +win32:copy_hdr.commands = type ${QMAKE_FILE_IN} > ../../include/${QMAKE_FILE_BASE}.h +win32:copy_hdr.output = ../../include/${QMAKE_FILE_BASE}.h +win32:copy_hdr.input = HEADERS +win32:QMAKE_EXTRA_COMPILERS += copy_hdr + includes.files = $$HEADERS includes.path = ../../include diff --git a/src/PyConsole/PyConsole.h b/src/PyConsole/PyConsole.h index 10a7106f6..d27c40c0f 100644 --- a/src/PyConsole/PyConsole.h +++ b/src/PyConsole/PyConsole.h @@ -16,39 +16,25 @@ // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // -#if !defined ( _PYTHONCONSOLE_H ) -#define _PYTHONCONSOLE_H +// File : PyConsole.h +// Author : Vadim SANDLER, Open CASCADE S.A.S. (vadim.sandler@opencascade.com) +// + +#if !defined ( PYCONSOLE_H ) +#define PYCONSOLE_H // ======================================================== // set dllexport type for Win platform #ifdef WIN32 - -#ifdef PYCONSOLE_EXPORTS -#define PYCONSOLE_EXPORT __declspec(dllexport) -#else -#define PYCONSOLE_EXPORT __declspec(dllimport) -#endif - +# ifdef PYCONSOLE_EXPORTS +# define PYCONSOLE_EXPORT __declspec(dllexport) +# else +# define PYCONSOLE_EXPORT __declspec(dllimport) +# endif #else // WIN32 - -#define PYCONSOLE_EXPORT - +# define PYCONSOLE_EXPORT #endif // WIN32 -// ======================================================== -// little trick - we do not have debug python libraries -#ifdef _DEBUG - -#undef _DEBUG -//#include -#define _DEBUG - -#else // _DEBUG - -//#include - -#endif // _DEBUG - // ======================================================== // avoid warning messages #ifdef WIN32 @@ -56,4 +42,4 @@ #pragma warning (disable : 4251) #endif -#endif // _PYTHONCONSOLE_H +#endif // PYCONSOLE_H diff --git a/src/PyConsole/PyConsole.pro b/src/PyConsole/PyConsole.pro index a4fd5061b..04e08a5e9 100644 --- a/src/PyConsole/PyConsole.pro +++ b/src/PyConsole/PyConsole.pro @@ -1,4 +1,7 @@ -TEMPLATE = lib +unix:TEMPLATE = lib +win32:TEMPLATE = vclib + +win32:QMAKE_MOC=$(QTDIR)\bin\moc.exe DESTDIR = ../../$(CONFIG_ID)/lib MOC_DIR = ../../moc @@ -6,12 +9,14 @@ OBJECTS_DIR = ../../$(CONFIG_ID)/obj/$$TARGET INCLUDEPATH += ../../include $$(PYTHONINC) unix:LIBS += -L../../$(CONFIG_ID)/lib -L$$(PYTHONLIB) -lpython2.5 -lSUIT -lPyInterp -win32:LIBS += /LIBPATH:$$(PYTHONLIB) ../../lib/pyinterp.lib ../../lib/suit.lib +win32:LIBS += -L../../$(CONFIG_ID)/lib -L$$(PYTHONLIB) -lpython25_d -lSUIT -lPyInterp -lQtx +win32:LIBS *= -L$(QTLIB) +win32:INCLUDEPATH *= $(QTINC) $(QTINC)\QtCore $(QTINC)\QtGui $(QTINC)\QtXml CONFIG -= debug release debug_and_release CONFIG += qt thread debug dll shared -win32:DEFINES += WIN32 +win32:DEFINES += WNT WIN32 HAVE_DEBUG_PYTHON DEFINES += PYCONSOLE_EXPORTS HEADERS = *.h @@ -25,7 +30,7 @@ win32:GUIResources = ..\\..\\resources lrelease.name = LRELASE ${QMAKE_FILE_IN} unix:lrelease.commands = $(QTDIR)/bin/lrelease ${QMAKE_FILE_NAME} -qm $${GUIResources}/${QMAKE_FILE_BASE}.qm -win32:lrelease.commands = $(QTDIR)\\bin\\lrelease ${QMAKE_FILE_NAME} -qm $${GUIResources}\\${QMAKE_FILE_BASE}.qm +win32:lrelease.commands = $(QTDIR)\\bin\\lrelease ${QMAKE_FILE_IN} ${QMAKE_FILE_NAME} -qm $${GUIResources}\\${QMAKE_FILE_BASE}.qm unix:lrelease.output = $${GUIResources}/${QMAKE_FILE_BASE}.qm win32:lrelease.output = $${GUIResources}\\${QMAKE_FILE_BASE}.qm lrelease.input = TRANSLATIONS @@ -34,6 +39,12 @@ win32:lrelease.clean = $${GUIResources}\\${QMAKE_FILE_BASE}.qm lrelease.CONFIG += no_link target_predeps QMAKE_EXTRA_COMPILERS += lrelease +win32:copy_hdr.name = Install ${QMAKE_FILE_IN} +win32:copy_hdr.commands = type ${QMAKE_FILE_IN} > ../../include/${QMAKE_FILE_BASE}.h +win32:copy_hdr.output = ../../include/${QMAKE_FILE_BASE}.h +win32:copy_hdr.input = HEADERS +win32:QMAKE_EXTRA_COMPILERS += copy_hdr + includes.files = $$HEADERS includes.path = ../../include diff --git a/src/PyConsole/PyConsole_Console.cxx b/src/PyConsole/PyConsole_Console.cxx index 85ba6c722..85df7307a 100644 --- a/src/PyConsole/PyConsole_Console.cxx +++ b/src/PyConsole/PyConsole_Console.cxx @@ -16,30 +16,27 @@ // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // -// File : PythonConsole_PyConcole.cxx -// Author : Vadim SANDLER -// Module : SALOME +// File : PyConsole_Console.cxx +// Author : Vadim SANDLER, Open CASCADE S.A.S. (vadim.sandler@opencascade.com) +// /*! - \class PythonConsole + \class PyConsole_Console \brief Python console widget. */ -#include - +#include "PyConsole_Interp.h" /// !!! WARNING !!! THIS INCLUDE MUST BE VERY FIRST !!! #include "PyConsole_Console.h" #include "PyConsole_Editor.h" -#include - -#include -#include -#include -#include -#include -#include +#include -using namespace std; +#include +#include +#include +#include +#include +#include /*! \brief Constructor. @@ -48,9 +45,9 @@ using namespace std; \param parent parent widget \param interp python interpreter */ -PythonConsole::PythonConsole( QWidget* parent, PyInterp_base* interp ) -: QFrame( parent ), -myEditor( 0 ) +PyConsole_Console::PyConsole_Console( QWidget* parent, PyConsole_Interp* interp ) +: QWidget( parent ), + myEditor( 0 ) { // create python interpreter myInterp = interp; @@ -62,7 +59,7 @@ myEditor( 0 ) // create editor console QVBoxLayout* lay = new QVBoxLayout( this ); - lay->setMargin( 5 ); + lay->setMargin( 0 ); myEditor = new PyConsole_Editor( myInterp, this ); myEditor->viewport()->installEventFilter( this ); lay->addWidget( myEditor ); @@ -75,15 +72,15 @@ myEditor( 0 ) Does nothing for the moment. */ -PythonConsole::~PythonConsole() +PyConsole_Console::~PyConsole_Console() { } /*! \brief Execute python command in the interpreter. - \param command - string with command and arguments + \param command string with command and arguments */ -void PythonConsole::exec( const QString& command ) +void PyConsole_Console::exec( const QString& command ) { if ( myEditor ) myEditor->exec( command ); @@ -94,29 +91,45 @@ void PythonConsole::exec( const QString& command ) and wait until it is finished. Block execution of main application until the python command is executed. - \param command - string with command and arguments + \param command string with command and arguments */ -void PythonConsole::execAndWait( const QString& command ) +void PyConsole_Console::execAndWait( const QString& command ) { if ( myEditor ) myEditor->execAndWait( command ); } -bool PythonConsole::isSync() const +/*! + \brief Get synchronous mode flag value. + + \sa setIsSync() + \return True if python console works in synchronous mode +*/ +bool PyConsole_Console::isSync() const { return myEditor->isSync(); } -void PythonConsole::setIsSync( const bool s ) +/*! + \brief Set synchronous mode flag value. + + In synhronous mode the Python commands are executed in the GUI thread + and the GUI is blocked until the command is finished. In the asynchronous + mode each Python command is executed in the separate thread that does not + block the main GUI loop. + + \param on synhronous mode flag +*/ +void PyConsole_Console::setIsSync( const bool on ) { - myEditor->setIsSync( s ); + myEditor->setIsSync( on ); } /*! \brief Change the python console's font. - \param f - new font + \param f new font */ -void PythonConsole::setFont( const QFont& f ) +void PyConsole_Console::setFont( const QFont& f ) { if( myEditor ) myEditor->setFont( f ); @@ -126,7 +139,7 @@ void PythonConsole::setFont( const QFont& f ) \brief Get python console font. \return current python console's font */ -QFont PythonConsole::font() const +QFont PyConsole_Console::font() const { QFont res; if( myEditor ) @@ -135,60 +148,112 @@ QFont PythonConsole::font() const } /*! - Custom event handler + \brief Event handler. + + Handles context menu request event. + + \param o object + \param e event + \return True if the event is processed and further processing should be stopped */ -bool PythonConsole::eventFilter( QObject* o, QEvent* e ) +bool PyConsole_Console::eventFilter( QObject* o, QEvent* e ) { if ( o == myEditor->viewport() && e->type() == QEvent::ContextMenu ) { contextMenuRequest( (QContextMenuEvent*)e ); return true; } - return QFrame::eventFilter( o, e ); + return QWidget::eventFilter( o, e ); } /*! - \brief Process context popup menu event. + \brief Create the context popup menu. + + Fill in the popup menu with the commands. - Show popup menu which includes standard copy/paste operations. - \param event context menu event + \param menu context popup menu */ -void PythonConsole::contextMenuPopup( QMenu* menu ) +void PyConsole_Console::contextMenuPopup( QMenu* menu ) { if ( myEditor->isReadOnly() ) return; - updateActions(); - menu->addAction( myActions[CopyId] ); menu->addAction( myActions[PasteId] ); menu->addAction( myActions[ClearId] ); - menu->addSeparator(); - menu->addAction( myActions[SelectAllId] ); + + Qtx::simplifySeparators( menu ); + + updateActions(); } -void PythonConsole::createActions() +/*! + \brief Set actions to be visible in the context popup menu. + + Actions, which IDs are set in \a flags parameter, will be shown in the + context popup menu. Other actions will not be shown. + + \param flags ORed together actions flags +*/ +void PyConsole_Console::setMenuActions( const int flags ) { - QAction* copyAction = new QAction( tr( "EDIT_COPY_CMD" ), this ); - connect( copyAction, SIGNAL( triggered( bool ) ), myEditor, SLOT( copy() ) ); - myActions.insert( CopyId, copyAction ); + myActions[CopyId]->setVisible( flags & CopyId ); + myActions[PasteId]->setVisible( flags & PasteId ); + myActions[ClearId]->setVisible( flags & ClearId ); + myActions[SelectAllId]->setVisible( flags & SelectAllId ); +} - QAction* pasteAction = new QAction( tr( "EDIT_PASTE_CMD" ), this ); - connect( pasteAction, SIGNAL( triggered( bool ) ), myEditor, SLOT( paste() ) ); - myActions.insert( PasteId, pasteAction ); +/*! + \brief Get menu actions which are currently visible in the context popup menu. + \return ORed together actions flags + \sa setMenuActions() +*/ +int PyConsole_Console::menuActions() const +{ + int ret = 0; + ret = ret | ( myActions[CopyId]->isVisible() ? CopyId : 0 ); + ret = ret | ( myActions[PasteId]->isVisible() ? PasteId : 0 ); + ret = ret | ( myActions[ClearId]->isVisible() ? ClearId : 0 ); + ret = ret | ( myActions[SelectAllId]->isVisible() ? SelectAllId : 0 ); + return ret; +} - QAction* clearAction = new QAction( tr( "EDIT_CLEAR_CMD" ), this ); - connect( clearAction, SIGNAL( triggered( bool ) ), myEditor, SLOT( clear() ) ); - myActions.insert( ClearId, clearAction ); +/*! + \brief Create menu actions. + + Create context popup menu actions. +*/ +void PyConsole_Console::createActions() +{ + QAction* a = new QAction( tr( "EDIT_COPY_CMD" ), this ); + a->setStatusTip( tr( "EDIT_COPY_CMD" ) ); + connect( a, SIGNAL( triggered( bool ) ), myEditor, SLOT( copy() ) ); + myActions.insert( CopyId, a ); + + a = new QAction( tr( "EDIT_PASTE_CMD" ), this ); + a->setStatusTip( tr( "EDIT_PASTE_CMD" ) ); + connect( a, SIGNAL( triggered( bool ) ), myEditor, SLOT( paste() ) ); + myActions.insert( PasteId, a ); - QAction* selAllAction = new QAction( tr( "EDIT_SELECTALL_CMD" ), this ); - connect( selAllAction, SIGNAL( triggered( bool ) ), myEditor, SLOT( selectAll() ) ); - myActions.insert( SelectAllId, selAllAction ); + a = new QAction( tr( "EDIT_CLEAR_CMD" ), this ); + a->setStatusTip( tr( "EDIT_CLEAR_CMD" ) ); + connect( a, SIGNAL( triggered( bool ) ), myEditor, SLOT( clear() ) ); + myActions.insert( ClearId, a ); + + a = new QAction( tr( "EDIT_SELECTALL_CMD" ), this ); + a->setStatusTip( tr( "EDIT_SELECTALL_CMD" ) ); + connect( a, SIGNAL( triggered( bool ) ), myEditor, SLOT( selectAll() ) ); + myActions.insert( SelectAllId, a ); } -void PythonConsole::updateActions() +/*! + \brief Update menu actions. + + Update context popup menu action state. +*/ +void PyConsole_Console::updateActions() { myActions[CopyId]->setEnabled( myEditor->textCursor().hasSelection() ); myActions[PasteId]->setEnabled( !myEditor->isReadOnly() && !QApplication::clipboard()->text().isEmpty() ); diff --git a/src/PyConsole/PyConsole_Console.h b/src/PyConsole/PyConsole_Console.h index b25f4d191..ed1203b83 100644 --- a/src/PyConsole/PyConsole_Console.h +++ b/src/PyConsole/PyConsole_Console.h @@ -16,65 +16,69 @@ // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // -// File : PythonConsole_PyConsole.h -// Author : Vadim SANDLER -// Module : SALOME +// File : PyConsole_Console.h +// Author : Vadim SANDLER, Open CASCADE S.A.S. (vadim.sandler@opencascade.com) +// #ifndef PYCONSOLE_CONSOLE_H #define PYCONSOLE_CONSOLE_H #include "PyConsole.h" -#include -#include - #include +#include +#include -class PyInterp_base; +class PyConsole_Interp; class PyConsole_Editor; -class PYCONSOLE_EXPORT PythonConsole : public QFrame, public SUIT_PopupClient +class PYCONSOLE_EXPORT PyConsole_Console : public QWidget, public SUIT_PopupClient { Q_OBJECT public: + //! Context popup menu actions flags enum { - CopyId = 0x01, - PasteId = 0x02, - ClearId = 0x04, - SelectAllId = 0x08, - All = CopyId | PasteId | ClearId | SelectAllId + CopyId = 0x01, //!< "Copy" menu action + PasteId = 0x02, //!< "Paste" menu action + ClearId = 0x04, //!< "Clear" menu action + SelectAllId = 0x08, //!< "Select All" menu action + All = CopyId | PasteId | ClearId | SelectAllId //!< all menu actions }; public: - PythonConsole( QWidget* parent, PyInterp_base* interp = 0 ); - virtual ~PythonConsole(); + PyConsole_Console( QWidget* parent, PyConsole_Interp* interp = 0 ); + virtual ~PyConsole_Console(); //! \brief Get python interperter - PyInterp_base* getInterp() { return myInterp; } - QFont font() const; - virtual void setFont( const QFont& ); + PyConsole_Interp* getInterp() { return myInterp; } + QFont font() const; + virtual void setFont( const QFont& ); + + bool isSync() const; + void setIsSync( const bool ); - bool isSync() const; - void setIsSync( const bool ); + void exec( const QString& ); + void execAndWait( const QString& ); - void exec( const QString& command ); - void execAndWait( const QString& command ); + virtual bool eventFilter( QObject*, QEvent* ); - virtual bool eventFilter( QObject* o, QEvent* e ); + //! \brief Get popup client symbolic name + virtual QString popupClientType() const { return QString( "PyConsole" ); } + virtual void contextMenuPopup( QMenu* ); - virtual QString popupClientType() const { return QString( "PyConsole" ); } - virtual void contextMenuPopup( QMenu* ); + void setMenuActions( const int ); + int menuActions() const; private: void createActions(); void updateActions(); private: - PyInterp_base* myInterp; //!< python interpreter + PyConsole_Interp* myInterp; //!< python interpreter PyConsole_Editor* myEditor; //!< python console editor widget - QMap myActions; + QMap myActions; //!< menu actions list }; -#endif +#endif // PYCONSOLE_CONSOLE_H diff --git a/src/PyConsole/PyConsole_Editor.cxx b/src/PyConsole/PyConsole_Editor.cxx index 23268097e..fea5d6804 100644 --- a/src/PyConsole/PyConsole_Editor.cxx +++ b/src/PyConsole/PyConsole_Editor.cxx @@ -19,9 +19,9 @@ // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // -// File : PyConsole_Editor.cxx -// Author : Vadim SANDLER -// Module : SALOME +// File : PyConsole_Editor.cxx +// Author : Vadim SANDLER, Open CASCADE S.A.S. (vadim.sandler@opencascade.com) +// /*! \class PyConsole_Editor @@ -92,32 +92,35 @@ - the same for drag-n-drop of multiline text */ -#include "PyConsole_Editor.h" // this include must be first (see PyInterp_base.h)! - +#include "PyConsole_Interp.h" // !!! WARNING !!! THIS INCLUDE MUST BE THE VERY FIRST !!! +#include "PyConsole_Editor.h" #include #include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -using namespace std; +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include static QString READY_PROMPT = ">>> "; static QString DOTS_PROMPT = "... "; #define PROMPT_SIZE myPrompt.length() +#define PRINT_EVENT 65432 + /*! \class ExecCommand - \brief Python command execution request [internal]. - */ + \brief Python command execution request. + \internal +*/ + class ExecCommand : public PyInterp_LockRequest { public: @@ -130,7 +133,7 @@ public: \param theListener widget to get the notification messages \param sync if True the request is processed synchronously */ - ExecCommand( PyInterp_base* theInterp, + ExecCommand( PyInterp_Interp* theInterp, const QString& theCommand, PyConsole_Editor* theListener, bool sync = false ) @@ -147,21 +150,12 @@ protected: { if ( myCommand != "" ) { -// SUIT_Session::SetPythonExecuted( true ); // disable GUI user actions int ret = getInterp()->run( myCommand.toLatin1() ); -// SUIT_Session::SetPythonExecuted(false); // enable GUI user actions if ( ret < 0 ) - myState = PyInterp_Event::ERROR; + myState = PyInterp_Event::ERROR; else if ( ret > 0 ) - myState = PyInterp_Event::INCOMPLETE; - myError = getInterp()->getverr().c_str(); - myOutput = getInterp()->getvout().c_str(); + myState = PyInterp_Event::INCOMPLETE; } - else - { - myError = ""; - myOutput = ""; - } } /*! @@ -170,18 +164,45 @@ protected: */ virtual QEvent* createEvent() const { + if ( IsSync() ) + QCoreApplication::sendPostedEvents( listener(), PRINT_EVENT ); return new PyInterp_Event( myState, (PyInterp_Request*)this ); } -public: - QString myError; //!< Python command error message - QString myOutput; //!< Python command output log - private: QString myCommand; //!< Python command int myState; //!< Python command execution status }; +/*! + \class PrintEvent + \brief Python command output backend event. + \internal +*/ + +class PrintEvent : public QEvent +{ +public: + /*! + \brief Constructor + \param c message text (python trace) + */ + PrintEvent( const char* c ) : QEvent( (QEvent::Type)PRINT_EVENT ), myText( c ) {} + /*! + \brief Get message + \return message text (python trace) + */ + QString text() const { return myText; } + +private: + QString myText; //!< Event message (python trace) +}; + +void staticCallback( void* data, char* c ) +{ + QApplication::postEvent( (PyConsole_Editor*)data, new PrintEvent( c ) ); +} + /*! \brief Constructor. @@ -189,8 +210,8 @@ private: \param theInterp python interper \param theParent parent widget */ -PyConsole_Editor::PyConsole_Editor( PyInterp_base* theInterp, - QWidget* theParent ) +PyConsole_Editor::PyConsole_Editor( PyConsole_Interp* theInterp, + QWidget* theParent ) : QTextEdit( theParent ), myInterp( 0 ), myCmdInHistory( -1 ), @@ -203,10 +224,13 @@ PyConsole_Editor::PyConsole_Editor( PyInterp_base* theInterp, setUndoRedoEnabled( false ); myPrompt = READY_PROMPT; - setLineWrapMode( QTextEdit::NoWrap ); - setWordWrapMode( QTextOption::NoWrap ); + setLineWrapMode( QTextEdit::WidgetWidth ); + setWordWrapMode( QTextOption::WrapAnywhere ); setAcceptRichText( false ); + theInterp->setvoutcb( staticCallback, this ); + theInterp->setverrcb( staticCallback, this ); + // san - This is necessary for troubleless initialization onPyInterpChanged( theInterp ); } @@ -220,14 +244,30 @@ PyConsole_Editor::~PyConsole_Editor() { } +/*! + \brief Get synchronous mode flag value. + + \sa setIsSync() + \return True if python console works in synchronous mode +*/ bool PyConsole_Editor::isSync() const { return myIsSync; } -void PyConsole_Editor::setIsSync( const bool s ) +/*! + \brief Set synchronous mode flag value. + + In synhronous mode the Python commands are executed in the GUI thread + and the GUI is blocked until the command is finished. In the asynchronous + mode each Python command is executed in the separate thread that does not + block the main GUI loop. + + \param on synhronous mode flag +*/ +void PyConsole_Editor::setIsSync( const bool on ) { - myIsSync = s; + myIsSync = on; } /*! @@ -236,7 +276,7 @@ void PyConsole_Editor::setIsSync( const bool s ) \param newBlock if True, then the string is printed on a new line */ void PyConsole_Editor::addText( const QString& str, - const bool newBlock ) + const bool newBlock ) { moveCursor( QTextCursor::End ); if ( newBlock ) @@ -288,14 +328,20 @@ void PyConsole_Editor::exec( const QString& command ) PyInterp_Dispatcher::Get()->Exec( createRequest( cmd ) ); } -PyInterp_Request* PyConsole_Editor::createRequest( const QString& cmd ) +/*! + \brief Create request to the python dispatcher for the command execution. + + \param command python command to be executed + */ +PyInterp_Request* PyConsole_Editor::createRequest( const QString& command ) { - return new ExecCommand( myInterp, cmd, this, isSync() ); + return new ExecCommand( myInterp, command, this, isSync() ); } /*! \brief Execute command in the python interpreter and wait until it is finished. + \param command python command to be executed */ void PyConsole_Editor::execAndWait( const QString& command ) @@ -333,6 +379,9 @@ void PyConsole_Editor::handleReturn() // add command to the history if ( !cmd.trimmed().isEmpty() ) myHistory.push_back( cmd ); + + // IPAL19397 + addText( "", true ); // set read-only mode setReadOnly( true ); @@ -566,7 +615,7 @@ void PyConsole_Editor::keyPressEvent( QKeyEvent* event ) moveCursor( QTextCursor::End ); moveCursor( QTextCursor::StartOfBlock, QTextCursor::KeepAnchor ); textCursor().removeSelectedText(); - addText( myPrompt + ( nextCommand != TOP_HISTORY_PY ? nextCommand : myCurrentCommand ) ); + addText( myPrompt + nextCommand ); // move cursor to the end moveCursor( QTextCursor::End ); } @@ -851,25 +900,24 @@ void PyConsole_Editor::customEvent( QEvent* event ) { switch( event->type() ) { + case PRINT_EVENT: + { + PrintEvent* pe=(PrintEvent*)event; + addText( pe->text() ); + return; + } case PyInterp_Event::OK: case PyInterp_Event::ERROR: { - PyInterp_Event* pe = dynamic_cast( event ); - if ( pe ) - { - ExecCommand* ec = dynamic_cast( pe->GetRequest() ); - if ( ec ) - { - // The next line has appeared dangerous in case if - // Python command execution has produced very large output. - // A more clever approach is needed... - // print python output - addText( ec->myOutput, true ); - addText( ec->myError ); - } - } // clear command buffer myCommandBuffer.truncate( 0 ); + // add caret return line if necessary + QTextBlock par = document()->end().previous(); + QString txt = par.text(); + txt.truncate( txt.length() - 1 ); + // IPAL19397 : addText moved to handleReturn() method + //if ( !txt.isEmpty() ) + // addText( "", true ); // set "ready" prompt myPrompt = READY_PROMPT; addText( myPrompt ); @@ -884,9 +932,16 @@ void PyConsole_Editor::customEvent( QEvent* event ) { // extend command buffer (multi-line command) myCommandBuffer.append( "\n" ); + // add caret return line if necessary + QTextBlock par = document()->end().previous(); + QString txt = par.text(); + txt.truncate( txt.length() - 1 ); + // IPAL19397 : addText moved to handleReturn() method + //if ( !txt.isEmpty() ) + // addText( "", true ); // set "dot" prompt myPrompt = DOTS_PROMPT; - addText( myPrompt, true ); + addText( myPrompt/*, true*/ ); // IPAL19397 // unset busy cursor unsetCursor(); // stop event loop (if running) @@ -918,7 +973,7 @@ void PyConsole_Editor::customEvent( QEvent* event ) Perform initialization actions if the interpreter is changed. \param interp python interpreter is being set */ -void PyConsole_Editor::onPyInterpChanged( PyInterp_base* interp ) +void PyConsole_Editor::onPyInterpChanged( PyConsole_Interp* interp ) { if ( myInterp != interp // Force read-only state and wait cursor when myInterp is NULL diff --git a/src/PyConsole/PyConsole_Editor.h b/src/PyConsole/PyConsole_Editor.h index 12deee059..222708c6e 100644 --- a/src/PyConsole/PyConsole_Editor.h +++ b/src/PyConsole/PyConsole_Editor.h @@ -19,28 +19,27 @@ // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // -// File : PyConsole_Editor.h -// Author : Vadim SANDLER -// Module : SALOME +// File : PyConsole_Editor.h +// Author : Vadim SANDLER, Open CASCADE S.A.S. (vadim.sandler@opencascade.com) +// #ifndef PYCONSOLE_EDITOR_H #define PYCONSOLE_EDITOR_H -#include "PyConsole_Interp.h" // this include must be first (see PyInterp_base.h)! +#include "PyConsole.h" -#include +#include -class QMenu; -class QEventLoop; class PyConsole_Interp; class PyInterp_Request; +class QEventLoop; class PYCONSOLE_EXPORT PyConsole_Editor : public QTextEdit { Q_OBJECT; public: - PyConsole_Editor( PyInterp_base* theInterp, QWidget *theParent = 0 ); + PyConsole_Editor( PyConsole_Interp* theInterp, QWidget *theParent = 0 ); ~PyConsole_Editor(); virtual void addText( const QString& str, const bool newBlock = false ); @@ -59,26 +58,26 @@ protected: virtual void customEvent( QEvent* event); virtual PyInterp_Request* createRequest( const QString& ); - + public slots: void cut(); void paste(); void clear(); void handleReturn(); - void onPyInterpChanged( PyInterp_base* ); + void onPyInterpChanged( PyConsole_Interp* ); private: - PyInterp_base* myInterp; //!< python interpreter + PyConsole_Interp* myInterp; //!< python interpreter - QString myCommandBuffer; //!< python comman buffer - QString myCurrentCommand; //!< currently being printed command - QString myPrompt; //!< current command line prompt - int myCmdInHistory; //!< current history command index - QStringList myHistory; //!< commands history buffer - QEventLoop* myEventLoop; //!< internal event loop - QString myBanner; //!< current banner - QStringList myQueue; //!< python commands queue - bool myIsSync; + QString myCommandBuffer; //!< python comman buffer + QString myCurrentCommand; //!< currently being printed command + QString myPrompt; //!< current command line prompt + int myCmdInHistory; //!< current history command index + QStringList myHistory; //!< commands history buffer + QEventLoop* myEventLoop; //!< internal event loop + QString myBanner; //!< current banner + QStringList myQueue; //!< python commands queue + bool myIsSync; //!< synchronous mode flag }; -#endif +#endif // PYCONSOLE_EDITOR_H diff --git a/src/PyConsole/PyConsole_Interp.cxx b/src/PyConsole/PyConsole_Interp.cxx index b71c02178..234e55973 100644 --- a/src/PyConsole/PyConsole_Interp.cxx +++ b/src/PyConsole/PyConsole_Interp.cxx @@ -30,21 +30,32 @@ \brief Python interpreter to be embedded to the SALOME study's GUI. Python interpreter is created one per SALOME study. - Calls initialize method defined in the base class, which calls redefined - virtual methods initState() & initContext(). + + Call initialize method defined in the base class PyInterp_Interp, + to intialize interpreter after instance creation. + + The method initialize() calls virtuals methods + - initPython() to initialize global Python interpreter + - initState() to initialize embedded interpreter state + - initContext() to initialize interpreter internal context + - initRun() to prepare interpreter for running commands /EDF-CCAR/ When SALOME uses multi Python interpreter feature, every study has its own interpreter and thread state (_tstate = Py_NewInterpreter()). - This is fine because every study has its own modules (sys.modules) stdout and stderr.
+ This is fine because every study has its own modules (sys.modules) stdout and stderr. + But some Python modules must be imported only once. In multi interpreter context Python modules (*.py) are imported several times. - For example, the pyqt module must be imported only once because + For example, the PyQt module must be imported only once because it registers classes in a C module. + It's quite the same with omniorb modules (internals and generated with omniidl). + This problem is handled with "shared modules" defined in salome_shared_modules.py. These "shared modules" are imported only once and only copied in all - the other interpreters.
+ the other interpreters. + But it's not the only problem. Every interpreter has its own __builtin__ module. That's fine but if we have copied some modules and imported others problems may arise with operations that are not allowed @@ -52,14 +63,12 @@ have identical __builtin__ module. */ -using namespace std; - /*! \brief Constructor. Creates new python interpreter. */ -PyConsole_Interp::PyConsole_Interp(): PyInterp_base() +PyConsole_Interp::PyConsole_Interp(): PyInterp_Interp() { } @@ -74,32 +83,15 @@ PyConsole_Interp::~PyConsole_Interp() /*! \brief Initialize internal Python interpreter state. + \return \c true on success */ bool PyConsole_Interp::initState() { // The GIL is acquired and will be held on initState output // It is the caller responsability to release the lock if needed - -/* LLS PyEval_AcquireLock(); _tstate = Py_NewInterpreter(); // create an interpreter and save current state - PySys_SetArgv(PyInterp_base::_argc,PyInterp_base::_argv); // initialize sys.argv -*/ - - PyEval_AcquireLock(); -#ifdef WIN32 - _tstate = PyGILState_GetThisThreadState(); - // if no thread state defined - if ( _tstate ) - PyThreadState_Swap(_tstate); - else -#endif - { - _tstate = Py_NewInterpreter(); // create an interpreter and save current state - PySys_SetArgv(PyInterp_base::_argc,PyInterp_base::_argv); // initialize sys.argv - //if(MYDEBUG) MESSAGE("PythonConsole_PyInterp::initState - this = "< // this include must be first (see PyInterp_base.h)! +#include /// !!! WARNING !!! THIS INCLUDE MUST BE VERY FIRST !!! -class PYCONSOLE_EXPORT PyConsole_Interp : public PyInterp_base +class PYCONSOLE_EXPORT PyConsole_Interp : public PyInterp_Interp { public: PyConsole_Interp(); @@ -41,4 +41,4 @@ protected: virtual bool initContext(); }; -#endif +#endif // PYCONSOLE_INTERP_H diff --git a/src/PyInterp/PyInterp.h b/src/PyInterp/PyInterp.h index 86772a124..eab58424e 100755 --- a/src/PyInterp/PyInterp.h +++ b/src/PyInterp/PyInterp.h @@ -16,38 +16,40 @@ // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // -#if !defined ( _PYINTERP_H ) -#define _PYINTERP_H +// File : PyInterp.h +// Author : Vadim SANDLER, Open CASCADE S.A.S. (vadim.sandler@opencascade.com) +// + +#if !defined ( PYINTERP_H ) +#define PYINTERP_H // ======================================================== // set dllexport type for Win platform #ifdef WIN32 - -#ifdef PYINTERP_EXPORTS -#define PYINTERP_EXPORT __declspec(dllexport) -#else -#define PYINTERP_EXPORT __declspec(dllimport) -#endif - +# ifdef PYINTERP_EXPORTS +# define PYINTERP_EXPORT __declspec(dllexport) +# else +# define PYINTERP_EXPORT __declspec(dllimport) +# endif #else // WIN32 - -#define PYINTERP_EXPORT - +# define PYINTERP_EXPORT #endif // WIN32 // ======================================================== -// little trick - we do not have debug python libraries +// little trick - if we do not have debug python libraries #ifdef _DEBUG - -#undef _DEBUG -#include -#define _DEBUG - -#else // _DEBUG + #ifndef HAVE_DEBUG_PYTHON + #undef _DEBUG + #endif +#endif #include -#endif // _DEBUG +#ifdef _DEBUG + #ifndef HAVE_DEBUG_PYTHON + #define _DEBUG + #endif +#endif // ======================================================== // avoid warning messages @@ -56,4 +58,4 @@ #pragma warning (disable : 4251) #endif -#endif // _PYINTERP_H +#endif // PYINTERP_H diff --git a/src/PyInterp/PyInterp.pro b/src/PyInterp/PyInterp.pro index 8ee7c1f25..bc1afac79 100644 --- a/src/PyInterp/PyInterp.pro +++ b/src/PyInterp/PyInterp.pro @@ -1,4 +1,7 @@ -TEMPLATE = lib +unix:TEMPLATE = lib +win32:TEMPLATE = vclib + +win32:QMAKE_MOC=$(QTDIR)\bin\moc.exe DESTDIR = ../../$(CONFIG_ID)/lib MOC_DIR = ../../moc @@ -6,18 +9,26 @@ OBJECTS_DIR = ../../$(CONFIG_ID)/obj/$$TARGET INCLUDEPATH += ../../include $$(PYTHONINC) unix:LIBS += -L$$(PYTHONLIB) -lpython2.5 -win32:LIBS += /LIBPATH:$$(PYTHONLIB) +win32:LIBS += -L$$(PYTHONLIB) -lpython25_d +win32:LIBS *= -L$(QTLIB) +win32:INCLUDEPATH *= $(QTINC) $(QTINC)\QtCore $(QTINC)\QtGui $(QTINC)\QtXml CONFIG -= debug release debug_and_release CONFIG += qt thread debug dll shared -win32:DEFINES += WIN32 +win32:DEFINES += WNT WIN32 HAVE_DEBUG_PYTHON DEFINES += PYINTERP_EXPORTS HEADERS = *.h SOURCES = *.cxx +win32:copy_hdr.name = Install ${QMAKE_FILE_IN} +win32:copy_hdr.commands = type ${QMAKE_FILE_IN} > ../../include/${QMAKE_FILE_BASE}.h +win32:copy_hdr.output = ../../include/${QMAKE_FILE_BASE}.h +win32:copy_hdr.input = HEADERS +win32:QMAKE_EXTRA_COMPILERS += copy_hdr + includes.files = $$HEADERS includes.path = ../../include diff --git a/src/PyInterp/PyInterp_Dispatcher.cxx b/src/PyInterp/PyInterp_Dispatcher.cxx index 917298417..e3adb001d 100755 --- a/src/PyInterp/PyInterp_Dispatcher.cxx +++ b/src/PyInterp/PyInterp_Dispatcher.cxx @@ -16,20 +16,16 @@ // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // -// SALOME SALOMEGUI : implementation of desktop and GUI kernel -// // File : PyInterp_Dispatcher.cxx // Author : Sergey ANIKIN, OCC // Module : GUI -// $Header$ - -#include "PyInterp_base.h" +#include "PyInterp_Dispatcher.h" // !!! WARNING !!! THIS INCLUDE MUST BE THE VERY FIRST !!! +#include "PyInterp_Interp.h" #include "PyInterp_Watcher.h" -#include "PyInterp_Dispatcher.h" -#include -#include +#include +#include using namespace std; @@ -126,8 +122,9 @@ PyInterp_Dispatcher::~PyInterp_Dispatcher() // Clear the request queue myQueueMutex.lock(); - for ( std::list::iterator it = myQueue.begin(); it != myQueue.end(); ++it ) - PyInterp_Request::Destroy( *it ); + QListIterator it( myQueue ); + while ( it.hasNext() ) + PyInterp_Request::Destroy( it.next() ); myQueue.clear(); myQueueMutex.unlock(); @@ -155,7 +152,7 @@ void PyInterp_Dispatcher::Exec( PyInterp_Request* theRequest ) else // asynchronous processing { myQueueMutex.lock(); - myQueue.push_back( theRequest ); + myQueue.enqueue( theRequest ); if ( theRequest->listener() ) QObject::connect( theRequest->listener(), SIGNAL( destroyed( QObject* ) ), myWatcher, SLOT( onDestroyed( QObject* ) ) ); myQueueMutex.unlock(); @@ -175,7 +172,7 @@ void PyInterp_Dispatcher::run() while( myQueue.size() ) { // MESSAGE("*** PyInterp_Dispatcher::run(): next request taken from the queue") - aRequest = myQueue.front(); + aRequest = myQueue.head(); // let other threads append their requests to the end of the queue myQueueMutex.unlock(); @@ -187,8 +184,8 @@ void PyInterp_Dispatcher::run() // prepare for removal of the first request in the queue myQueueMutex.lock(); // IMPORTANT: the first item could have been removed by objectDestroyed() --> we have to check it - if ( myQueue.front() == aRequest ) // It's still here --> remove it - myQueue.pop_front(); + if ( myQueue.head() == aRequest ) // It's still here --> remove it + myQueue.dequeue(); // MESSAGE("*** PyInterp_Dispatcher::run(): request processed") } @@ -207,12 +204,14 @@ void PyInterp_Dispatcher::objectDestroyed( const QObject* o ) // prepare for modification of the queue myQueueMutex.lock(); - for ( std::list::iterator it = myQueue.begin(); it != myQueue.end(); ++it ) + QMutableListIterator it( myQueue ); + while ( it.hasNext() ) { - if ( o == (*it)->listener() ) + RequestPtr r = it.next(); + if ( o == r->listener() ) { - (*it)->setListener( 0 ); // to prevent event posting - it = myQueue.erase( it ); + r->setListener( 0 ); // to prevent event posting + it.remove(); } } diff --git a/src/PyInterp/PyInterp_Dispatcher.h b/src/PyInterp/PyInterp_Dispatcher.h index 6f6240794..cf46694e4 100755 --- a/src/PyInterp/PyInterp_Dispatcher.h +++ b/src/PyInterp/PyInterp_Dispatcher.h @@ -16,27 +16,23 @@ // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // -// SALOME SALOMEGUI : implementation of desktop and GUI kernel -// // File : PyInterp_Dispatcher.h // Author : Sergey Anikin, OCC // Module : SALOME -#ifndef _PYINTERP_DISPATCHER_H_ -#define _PYINTERP_DISPATCHER_H_ - -#include "PyInterp.h" - -#include -#include +#ifndef PYINTERP_DISPATCHER_H +#define PYINTERP_DISPATCHER_H -#include +#include "PyInterp.h" // !!! WARNING !!! THIS INCLUDE MUST BE THE VERY FIRST !!! -#include +#include +#include +#include +#include class QObject; -class PyInterp_base; +class PyInterp_Interp; class PyInterp_Watcher; class PyInterp_Dispatcher; @@ -73,11 +69,12 @@ protected: virtual void processEvent( QObject* ); -private: - void process(); QObject* listener() const { return myListener; } void setListener( QObject* ); +private: + void process(); + private: QMutex myMutex; bool myIsSync; @@ -87,16 +84,16 @@ private: class PYINTERP_EXPORT PyInterp_LockRequest : public PyInterp_Request { public: - PyInterp_LockRequest( PyInterp_base* interp, QObject* listener = 0, bool sync = false ) + PyInterp_LockRequest( PyInterp_Interp* interp, QObject* listener = 0, bool sync = false ) : PyInterp_Request( listener, sync ), myInterp( interp ) {} protected: - PyInterp_base* getInterp() const { return myInterp; } + PyInterp_Interp* getInterp() const { return myInterp; } - virtual void safeExecute(); + virtual void safeExecute(); private: - PyInterp_base* myInterp; + PyInterp_Interp* myInterp; }; class PYINTERP_EXPORT PyInterp_Event : public QEvent @@ -139,7 +136,7 @@ private: private: typedef PyInterp_Request* RequestPtr; - std::list myQueue; + QQueue myQueue; QMutex myQueueMutex; PyInterp_Watcher* myWatcher; @@ -148,4 +145,4 @@ private: friend class PyInterp_Watcher; }; -#endif +#endif // PYINTERP_DISPATCHER_H diff --git a/src/PyInterp/PyInterp_Interp.cxx b/src/PyInterp/PyInterp_Interp.cxx new file mode 100644 index 000000000..891d02908 --- /dev/null +++ b/src/PyInterp/PyInterp_Interp.cxx @@ -0,0 +1,449 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +// File : PyInterp_Interp.cxx +// Author : Christian CAREMOLI, Paul RASCLE, EDF +// Module : SALOME + +#include "PyInterp_Interp.h" // !!! WARNING !!! THIS INCLUDE MUST BE THE VERY FIRST !!! + +#include +#include + +#include +#include +#include + +#define TOP_HISTORY_PY "--- top of history ---" +#define BEGIN_HISTORY_PY "--- begin of history ---" + +/*! + \class PyLockWrapper + \brief Python GIL wrapper. +*/ + +/*! + \brief Constructor. Automatically acquires GIL. + \param theThreadState python thread state +*/ +PyLockWrapper::PyLockWrapper(PyThreadState* theThreadState): + myThreadState(theThreadState), + mySaveThreadState(0) +{ + if (myThreadState->interp == PyInterp_Interp::_interp) + _savestate = PyGILState_Ensure(); + else + PyEval_AcquireThread(myThreadState); +} + +/*! + \brief Desstructor. Automatically releases GIL. +*/ +PyLockWrapper::~PyLockWrapper() +{ + if (myThreadState->interp == PyInterp_Interp::_interp) + PyGILState_Release(_savestate); + else + PyEval_ReleaseThread(myThreadState); +} + +/*! + \brief Get Python GIL wrapper. + \return GIL lock wrapper (GIL is automatically acquired here) +*/ +PyLockWrapper PyInterp_Interp::GetLockWrapper() +{ + return _tstate; +} + +/* + The following functions are used to hook the Python + interpreter output. +*/ + +static void +PyStdOut_dealloc(PyStdOut *self) +{ + PyObject_Del(self); +} + +static PyObject* +PyStdOut_write(PyStdOut *self, PyObject *args) +{ + char *c; + int l; + if (!PyArg_ParseTuple(args, "t#:write",&c, &l)) + return NULL; + if(self->_cb==NULL) { + if ( self->_iscerr ) + std::cerr << c ; + else + std::cout << c ; + } + else { + self->_cb(self->_data,c); + } + Py_INCREF(Py_None); + return Py_None; +} + +static PyMethodDef PyStdOut_methods[] = { + {"write", (PyCFunction)PyStdOut_write, METH_VARARGS, + PyDoc_STR("write(string) -> None")}, + {NULL, NULL} /* sentinel */ +}; + +static PyMemberDef PyStdOut_memberlist[] = { + {"softspace", T_INT, offsetof(PyStdOut, softspace), 0, + "flag indicating that a space needs to be printed; used by print"}, + {NULL} /* Sentinel */ +}; + +static PyTypeObject PyStdOut_Type = { + /* The ob_type field must be initialized in the module init function + * to be portable to Windows without using C++. */ + PyObject_HEAD_INIT(NULL) + 0, /*ob_size*/ + "PyOut", /*tp_name*/ + sizeof(PyStdOut), /*tp_basicsize*/ + 0, /*tp_itemsize*/ + /* methods */ + (destructor)PyStdOut_dealloc, /*tp_dealloc*/ + 0, /*tp_print*/ + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ + 0, /*tp_compare*/ + 0, /*tp_repr*/ + 0, /*tp_as_number*/ + 0, /*tp_as_sequence*/ + 0, /*tp_as_mapping*/ + 0, /*tp_hash*/ + 0, /*tp_call*/ + 0, /*tp_str*/ + PyObject_GenericGetAttr, /*tp_getattro*/ + /* softspace is writable: we must supply tp_setattro */ + PyObject_GenericSetAttr, /* tp_setattro */ + 0, /*tp_as_buffer*/ + Py_TPFLAGS_DEFAULT, /*tp_flags*/ + 0, /*tp_doc*/ + 0, /*tp_traverse*/ + 0, /*tp_clear*/ + 0, /*tp_richcompare*/ + 0, /*tp_weaklistoffset*/ + 0, /*tp_iter*/ + 0, /*tp_iternext*/ + PyStdOut_methods, /*tp_methods*/ + PyStdOut_memberlist, /*tp_members*/ + 0, /*tp_getset*/ + 0, /*tp_base*/ + 0, /*tp_dict*/ + 0, /*tp_descr_get*/ + 0, /*tp_descr_set*/ + 0, /*tp_dictoffset*/ + 0, /*tp_init*/ + 0, /*tp_alloc*/ + 0, /*tp_new*/ + 0, /*tp_free*/ + 0, /*tp_is_gc*/ +}; + +#define PyStdOut_Check(v) ((v)->ob_type == &PyStdOut_Type) + +static PyStdOut* newPyStdOut( bool iscerr ) +{ + PyStdOut *self; + self = PyObject_New(PyStdOut, &PyStdOut_Type); + if (self == NULL) + return NULL; + self->softspace = 0; + self->_cb = NULL; + self->_iscerr = iscerr; + return self; +} + +/*! + \class PyInterp_Interp + \brief Generic embedded Python interpreter. +*/ + +int PyInterp_Interp::_argc = 1; +char* PyInterp_Interp::_argv[] = {""}; +PyObject* PyInterp_Interp::builtinmodule = NULL; +PyThreadState* PyInterp_Interp::_gtstate = NULL; +PyInterpreterState* PyInterp_Interp::_interp = NULL; + +/*! + \brief Basic constructor. + + After construction the interpreter instance successor classes + must call virtual method initalize(). +*/ +PyInterp_Interp::PyInterp_Interp(): + _tstate(0), _vout(0), _verr(0), _g(0) +{ +} + +/*! + \brief Destructor. +*/ +PyInterp_Interp::~PyInterp_Interp() +{ +} + +/*! + \brief Initialize embedded interpreter. + + This method shoud be called after construction of the interpreter. + The method initialize() calls virtuals methods + - initPython() to initialize global Python interpreter + - initState() to initialize embedded interpreter state + - initContext() to initialize interpreter internal context + - initRun() to prepare interpreter for running commands + which should be implemented in the successor classes, according to the + embedded Python interpreter policy (mono or multi interpreter, etc). +*/ +void PyInterp_Interp::initialize() +{ + _history.clear(); // start a new list of user's commands + _ith = _history.begin(); + + initPython(); + // Here the global lock is released + + initState(); + + PyLockWrapper aLock = GetLockWrapper(); + + initContext(); + + // used to interpret & compile commands + PyObjWrapper m(PyImport_ImportModule("codeop")); + if(!m) { + PyErr_Print(); + return; + } + + // Create python objects to capture stdout and stderr + _vout=(PyObject*)newPyStdOut( false ); // stdout + _verr=(PyObject*)newPyStdOut( true ); // stderr + + // All the initRun outputs are redirected to the standard output (console) + initRun(); +} + +/*! + \brief Initialize Python interpreter. + + Set program name, initialize interpreter, set program arguments, + initiaize threads. + */ +void PyInterp_Interp::initPython() +{ + if (Py_IsInitialized()) + return; + + // Python is not initialized + Py_SetProgramName(_argv[0]); + Py_Initialize(); // Initialize the interpreter + PySys_SetArgv(_argc, _argv); + PyEval_InitThreads(); // Create (and acquire) the interpreter lock + _interp = PyThreadState_Get()->interp; + if (PyType_Ready(&PyStdOut_Type) < 0) { + PyErr_Print(); + } + _gtstate = PyEval_SaveThread(); // Release global thread state +} + +/*! + \brief Get embedded Python interpreter banner. + \return banner string + */ +std::string PyInterp_Interp::getbanner() +{ + // Should we take the lock ? + // PyEval_RestoreThread(_tstate); + std::string aBanner("Python "); + aBanner = aBanner + Py_GetVersion() + " on " + Py_GetPlatform() ; + aBanner = aBanner + "\ntype help to get general information on environment\n"; + //PyEval_SaveThread(); + return aBanner; +} + +/*! + \brief Initialize run command. + + This method is used to prepare interpreter for running + Python commands. + + \return \c true on success and \c false on error +*/ +bool PyInterp_Interp::initRun() +{ + // + // probably all below code isn't required + // + /* + PySys_SetObject("stderr",_verr); + PySys_SetObject("stdout",_vout); + + //PyObject *m = PyImport_GetModuleDict(); + + PySys_SetObject("stdout",PySys_GetObject("__stdout__")); + PySys_SetObject("stderr",PySys_GetObject("__stderr__")); + */ + return true; +} + +/*! + \brief Compile Python command and evaluate it in the + python dictionary context if possible. + \internal + \param command Python command string + \param context Python context (dictionary) + \return -1 on fatal error, 1 if command is incomplete and 0 + if command is executed successfully + */ +static int compile_command(const char *command,PyObject *context) +{ + PyObject *m = PyImport_AddModule("codeop"); + if(!m) { // Fatal error. No way to go on. + PyErr_Print(); + return -1; + } + PyObjWrapper v(PyObject_CallMethod(m,"compile_command","s",command)); + if(!v) { + // Error encountered. It should be SyntaxError, + //so we don't write out traceback + PyObjWrapper exception, value, tb; + PyErr_Fetch(&exception, &value, &tb); + PyErr_NormalizeException(&exception, &value, &tb); + PyErr_Display(exception, value, NULL); + return -1; + } + else if (v == Py_None) { + // Incomplete text we return 1 : we need a complete text to execute + return 1; + } + else { + // Complete and correct text. We evaluate it. + //#if PY_VERSION_HEX < 0x02040000 // python version earlier than 2.4.0 + // PyObjWrapper r(PyEval_EvalCode(v,context,context)); + //#else + PyObjWrapper r(PyEval_EvalCode((PyCodeObject *)(void *)v,context,context)); + //#endif + if(!r) { + // Execution error. We return -1 + PyErr_Print(); + return -1; + } + // The command has been successfully executed. Return 0 + return 0; + } +} + +/*! + \brief Run Python command. + \param command Python command + \return command status +*/ +int PyInterp_Interp::run(const char *command) +{ + beforeRun(); + return simpleRun(command); +} + +/*! + \brief Run Python command (used internally). + \param command Python command + \param addToHistory if \c true (default), the command is added to the commands history + \return command status +*/ +int PyInterp_Interp::simpleRun(const char *command, const bool addToHistory) +{ + if( addToHistory && strcmp(command,"") != 0 ) { + _history.push_back(command); + _ith = _history.end(); + } + + // We come from C++ to enter Python world + // We need to acquire the Python global lock + //PyLockWrapper aLock(_tstate); // san - lock is centralized now + + // Reset redirected outputs before treatment + PySys_SetObject("stderr",_verr); + PySys_SetObject("stdout",_vout); + + int ier = compile_command(command,_g); + + // Outputs are redirected on standards outputs (console) + PySys_SetObject("stdout",PySys_GetObject("__stdout__")); + PySys_SetObject("stderr",PySys_GetObject("__stderr__")); + + return ier; +} + +/*! + \brief Get previous command in the commands history. + \return previous command +*/ +const char * PyInterp_Interp::getPrevious() +{ + if(_ith != _history.begin()){ + _ith--; + return (*_ith).c_str(); + } + else + return BEGIN_HISTORY_PY; +} + +/*! + \brief Get next command in the commands history. + \return next command +*/ +const char * PyInterp_Interp::getNext() +{ + if(_ith != _history.end()){ + _ith++; + } + if (_ith == _history.end()) + return TOP_HISTORY_PY; + else + return (*_ith).c_str(); +} + +/*! + \brief Set Python standard output device hook. + \param cb callback function + \param data callback function parameters +*/ +void PyInterp_Interp::setvoutcb(PyOutChanged* cb, void* data) +{ + ((PyStdOut*)_vout)->_cb=cb; + ((PyStdOut*)_vout)->_data=data; +} + +/*! + \brief Set Python standard error device hook. + \param cb callback function + \param data callback function parameters +*/ +void PyInterp_Interp::setverrcb(PyOutChanged* cb, void* data) +{ + ((PyStdOut*)_verr)->_cb=cb; + ((PyStdOut*)_verr)->_data=data; +} diff --git a/src/PyInterp/PyInterp_Interp.h b/src/PyInterp/PyInterp_Interp.h new file mode 100644 index 000000000..397a79167 --- /dev/null +++ b/src/PyInterp/PyInterp_Interp.h @@ -0,0 +1,116 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +// File : PyInterp_Interp.h +// Author : Christian CAREMOLI, Paul RASCLE, EDF +// Module : SALOME + +#ifndef PYINTERP_INTERP_H +#define PYINTERP_INTERP_H + +#include "PyInterp.h" // !!! WARNING !!! THIS INCLUDE MUST BE THE VERY FIRST !!! + +#include +#include + +class PYINTERP_EXPORT PyLockWrapper +{ + PyThreadState* myThreadState; + PyThreadState* mySaveThreadState; + PyGILState_STATE _savestate; +public: + PyLockWrapper(PyThreadState* theThreadState); + ~PyLockWrapper(); +}; + +typedef void PyOutChanged(void* data,char * c); + +class PYINTERP_EXPORT PyInterp_Interp +{ +public: + static int _argc; + static char* _argv[]; + static PyObject *builtinmodule; + static PyThreadState *_gtstate; + static PyInterpreterState *_interp; + + PyInterp_Interp(); + virtual ~PyInterp_Interp(); + + void initialize(); + + virtual int run(const char *command); + + PyLockWrapper GetLockWrapper(); + + std::string getbanner(); + void setverrcb(PyOutChanged*,void*); + void setvoutcb(PyOutChanged*,void*); + + const char * getPrevious(); + const char * getNext(); + +protected: + PyThreadState * _tstate; + PyObject * _vout; + PyObject * _verr; + PyObject * _g; + PyObject * _codeop; + std::list _history; + std::list::iterator _ith; + + virtual int beforeRun() { return 0; } + int simpleRun(const char* command, const bool addToHistory = true); + + virtual bool initRun(); + virtual void initPython(); + virtual bool initState() = 0; + virtual bool initContext() = 0; +}; + +class PYINTERP_EXPORT PyObjWrapper +{ + PyObject* myObject; +public: + PyObjWrapper(PyObject* theObject) : myObject(theObject) {} + PyObjWrapper() : myObject(0) {} + virtual ~PyObjWrapper() { Py_XDECREF(myObject); } + + operator PyObject*() { return myObject; } + PyObject* operator->() { return myObject; } + PyObject* get() { return myObject; } + bool operator!() { return !myObject; } + bool operator==(PyObject* theObject) { return myObject == theObject; } + PyObject** operator&() { return &myObject; } + PyObjWrapper& operator=(PyObjWrapper* theObjWrapper) + { + Py_XDECREF(myObject); + myObject = theObjWrapper->myObject; + return *this; + } +}; + +typedef struct { + PyObject_HEAD + int softspace; + PyOutChanged* _cb; + void* _data; + bool _iscerr; +} PyStdOut; + +#endif // PYINTERP_INTERP_H diff --git a/src/PyInterp/PyInterp_Watcher.h b/src/PyInterp/PyInterp_Watcher.h index f5d776034..1d50f5bf8 100755 --- a/src/PyInterp/PyInterp_Watcher.h +++ b/src/PyInterp/PyInterp_Watcher.h @@ -16,14 +16,18 @@ // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // -#ifndef _PYINTERP_WATCHER_H_ -#define _PYINTERP_WATCHER_H_ +// File : PyInterp_Watcher.h +// Author : Sergey Anikin, OCC +// Module : SALOME -#include "PyInterp.h" +#ifndef PYINTERP_WATCHER_H +#define PYINTERP_WATCHER_H + +#include "PyInterp.h" // !!! WARNING !!! THIS INCLUDE MUST BE THE VERY FIRST !!! #include "PyInterp_Dispatcher.h" -#include +#include // Private class that keeps track of destructions of request listeners class PYINTERP_EXPORT PyInterp_Watcher : public QObject @@ -38,4 +42,4 @@ public slots: void onDestroyed( QObject* o ) { PyInterp_Dispatcher::Get()->objectDestroyed( o ); } }; -#endif // _PYINTERP_WATCHER_H_ +#endif // PYINTERP_WATCHER_H diff --git a/src/PyInterp/PyInterp_base.cxx b/src/PyInterp/PyInterp_base.cxx deleted file mode 100644 index 1ff7cd241..000000000 --- a/src/PyInterp/PyInterp_base.cxx +++ /dev/null @@ -1,317 +0,0 @@ -// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. -// -// This library is distributed in the hope that it will be useful -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// SALOME SALOMEGUI : implementation of desktop and GUI kernel -// -// File : PyInterp_base.cxx -// Author : Christian CAREMOLI, Paul RASCLE, EDF -// Module : SALOME -// $Header$ - - -#include "PyInterp_base.h" // this include must be first (see PyInterp_base.h)! - -#include - -#include -#include - -using namespace std; - -PyLockWrapper::PyLockWrapper(PyThreadState* theThreadState): - myThreadState(theThreadState), - mySaveThreadState(0) -{ -#if defined(USE_GILSTATE) - if (myThreadState->interp == PyInterp_base::_interp) { - _savestate = PyGILState_Ensure(); - } else { - PyEval_AcquireThread(myThreadState); - } -#else - PyEval_AcquireThread(myThreadState); -#endif -} - -PyLockWrapper::~PyLockWrapper() -{ -#if defined(USE_GILSTATE) - if (myThreadState->interp == PyInterp_base::_interp) { - PyGILState_Release(_savestate); - } else { - PyEval_ReleaseThread(myThreadState); - } -#else - PyEval_ReleaseThread(myThreadState); -#endif -} - -class PyReleaseLock{ -public: - ~PyReleaseLock(){ - PyEval_ReleaseLock(); - } -}; - - -PyLockWrapper PyInterp_base::GetLockWrapper(){ - return _tstate; -} - - -// main python interpreter (static attributes) - -int PyInterp_base::_argc = 1; -char* PyInterp_base::_argv[] = {""}; - -PyObject *PyInterp_base::builtinmodule = NULL; - -PyThreadState *PyInterp_base::_gtstate = NULL; -PyInterpreterState *PyInterp_base::_interp = NULL; - - -/*! - * basic constructor here : herited classes constructors must call initalize() method - * defined here. - */ -PyInterp_base::PyInterp_base(): _tstate(0), _vout(0), _verr(0), _g(0), _atFirst(true) -{ -} - -PyInterp_base::~PyInterp_base() -{ -} - - -/*! - * Must be called by herited classes constructors. initialize() calls virtuals methods - * initstate & initcontext, not defined here in base class. initstate & initcontext methods - * must be implemented in herited classes, following the Python interpreter policy - * (mono or multi interpreter...). - */ -void PyInterp_base::initialize() -{ - _history.clear(); // start a new list of user's commands - _ith = _history.begin(); - - init_python(); - // Here the global lock is released - - initState(); - - PyLockWrapper aLock= GetLockWrapper(); - - initContext(); - - // used to interpret & compile commands - PyObjWrapper m(PyImport_ImportModule("codeop")); - if(!m){ - PyErr_Print(); - return; - } - - // Create cStringIO to capture stdout and stderr - PycString_IMPORT; - if (PycStringIO) { // CTH11627 : additional check - _vout = PycStringIO->NewOutput(128); - _verr = PycStringIO->NewOutput(128); - } - - // All the initRun outputs are redirected to the standard output (console) - initRun(); -} - -void PyInterp_base::init_python() -{ - _atFirst = false; - if (Py_IsInitialized()) - return; - - // Python is not initialized - Py_SetProgramName(_argv[0]); - Py_Initialize(); // Initialize the interpreter - PySys_SetArgv(_argc, _argv); - PyEval_InitThreads(); // Create (and acquire) the interpreter lock - _interp = PyThreadState_Get()->interp; - _gtstate = PyEval_SaveThread(); // Release global thread state -} - -string PyInterp_base::getbanner() -{ - // Should we take the lock ? - // PyEval_RestoreThread(_tstate); - string aBanner("Python "); - aBanner = aBanner + Py_GetVersion() + " on " + Py_GetPlatform() ; - aBanner = aBanner + "\ntype help to get general information on environment\n"; - //PyEval_SaveThread(); - return aBanner; -} - - -int PyInterp_base::initRun() -{ - PySys_SetObject("stderr",_verr); - PySys_SetObject("stdout",_vout); - - PyObjWrapper verr(PyObject_CallMethod(_verr,"reset","")); - PyObjWrapper vout(PyObject_CallMethod(_vout,"reset","")); - - //PyObject *m = PyImport_GetModuleDict(); - - PySys_SetObject("stdout",PySys_GetObject("__stdout__")); - PySys_SetObject("stderr",PySys_GetObject("__stderr__")); - - return 0; -} - - -/*! - * This function compiles a string (command) and then evaluates it in the dictionnary - * context if possible. - * Returns : - * -1 : fatal error - * 1 : incomplete text - * 0 : complete text executed with success - */ -int compile_command(const char *command,PyObject *context) -{ - PyObject *m = PyImport_AddModule("codeop"); - if(!m){ // Fatal error. No way to go on. - PyErr_Print(); - return -1; - } - PyObjWrapper v(PyObject_CallMethod(m,"compile_command","s",command)); - if(!v){ - // Error encountered. It should be SyntaxError, - //so we don't write out traceback - PyObjWrapper exception, value, tb; - PyErr_Fetch(&exception, &value, &tb); - PyErr_NormalizeException(&exception, &value, &tb); - PyErr_Display(exception, value, NULL); - return -1; - }else if (v == Py_None){ - // Incomplete text we return 1 : we need a complete text to execute - return 1; - }else{ - // Complete and correct text. We evaluate it. - //#if PY_VERSION_HEX < 0x02040000 // python version earlier than 2.4.0 - // PyObjWrapper r(PyEval_EvalCode(v,context,context)); - //#else - PyObjWrapper r(PyEval_EvalCode((PyCodeObject *)(void *)v,context,context)); - //#endif - if(!r){ - // Execution error. We return -1 - PyErr_Print(); - return -1; - } - // The command has been successfully executed. Return 0 - return 0; - } -} - - -int PyInterp_base::run(const char *command) -{ - if(_atFirst){ - int ret = 0; - ret = simpleRun("from Help import *"); - if (ret) { - _atFirst = false; - return ret; - } - ret = simpleRun("import salome"); - if (ret) { - _atFirst = false; - return ret; - } - ret = simpleRun("salome.salome_init(0,1)"); - if (ret) { - _atFirst = false; - return ret; - } - _atFirst = false; - } - return simpleRun(command); -} - - -int PyInterp_base::simpleRun(const char *command) -{ - if( !_atFirst && strcmp(command,"") != 0 ) { - _history.push_back(command); - _ith = _history.end(); - } - - // We come from C++ to enter Python world - // We need to acquire the Python global lock - //PyLockWrapper aLock(_tstate); // san - lock is centralized now - - // Reset redirected outputs before treatment - PySys_SetObject("stderr",_verr); - PySys_SetObject("stdout",_vout); - - PyObjWrapper verr(PyObject_CallMethod(_verr,"reset","")); - PyObjWrapper vout(PyObject_CallMethod(_vout,"reset","")); - - int ier = compile_command(command,_g); - - // Outputs are redirected on standards outputs (console) - PySys_SetObject("stdout",PySys_GetObject("__stdout__")); - PySys_SetObject("stderr",PySys_GetObject("__stderr__")); - - return ier; -} - - -const char * PyInterp_base::getPrevious() -{ - if(_ith != _history.begin()){ - _ith--; - return (*_ith).c_str(); - } - else - return BEGIN_HISTORY_PY; -} - - -const char * PyInterp_base::getNext() -{ - if(_ith != _history.end()){ - _ith++; - } - if (_ith == _history.end()) - return TOP_HISTORY_PY; - else - return (*_ith).c_str(); -} - - -string PyInterp_base::getverr(){ - //PyLockWrapper aLock(_tstate); - PyObjWrapper v(PycStringIO->cgetvalue(_verr)); - string aRet(PyString_AsString(v)); - return aRet; -} - - -string PyInterp_base::getvout(){ - //PyLockWrapper aLock(_tstate); - PyObjWrapper v(PycStringIO->cgetvalue(_vout)); - string aRet(PyString_AsString(v)); - return aRet; -} diff --git a/src/PyInterp/PyInterp_base.h b/src/PyInterp/PyInterp_base.h deleted file mode 100644 index a00056e86..000000000 --- a/src/PyInterp/PyInterp_base.h +++ /dev/null @@ -1,145 +0,0 @@ -// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. -// -// This library is distributed in the hope that it will be useful -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// SALOME SALOMEGUI : implementation of desktop and GUI kernel -// -// File : PyInterp_base.h -// Author : Christian CAREMOLI, Paul RASCLE, EDF -// Module : SALOME - -#ifndef _PYINTERP_BASE_H_ -#define _PYINTERP_BASE_H_ - -#include "PyInterp.h" - -#include -#include -#include - -// include order important! -// pthread then python then qt -//#include // must be before Python.h ! - -#include // must be before qt includes ... -#include // Python include needed for versions before 2.4. Included in Python.h now. -#include // Python include needed for versions before 2.4. Included in Python.h now. - -//#if PY_VERSION_HEX < 0x02040000 // python version earlier than 2.4.0 -//extern "C" PyObject * PyEval_EvalCode(PyObject *co, PyObject *g, PyObject *l); -//#endif - -/* For 2.3, use the PyGILState_ calls */ -#if (PY_VERSION_HEX >= 0x02030000) -#define USE_GILSTATE -#endif - -#define TOP_HISTORY_PY "--- top of history ---" -#define BEGIN_HISTORY_PY "--- begin of history ---" - -class PYINTERP_EXPORT PyLockWrapper -{ - PyThreadState* myThreadState; - PyThreadState* mySaveThreadState; -#if defined(USE_GILSTATE) - PyGILState_STATE _savestate ; -#endif - public: - PyLockWrapper(PyThreadState* theThreadState); - ~PyLockWrapper(); -}; - -class PYINTERP_EXPORT PyInterp_base{ - public: - static int _argc; - static char* _argv[]; - static PyObject *builtinmodule; - static PyThreadState *_gtstate; - static PyInterpreterState *_interp; - - PyInterp_base(); - virtual ~PyInterp_base(); - - virtual void initialize(); - virtual void init_python(); - // init_python() made virtual to: - // 1. Remove dependency on KERNEL in light SALOME configuration - // 2. Allow redefinition of this method in SalomeApp_PyInterp class (it should be empty there and rely on KERNEL_PYTHON) - - virtual int run(const char *command); - - PyLockWrapper GetLockWrapper(); - - std::string getbanner(); - std::string getverr(); - std::string getvout(); - - const char * getPrevious(); - const char * getNext(); - - protected: - PyThreadState * _tstate; - PyObject * _vout; - PyObject * _verr; - PyObject * _g; - PyObject * _codeop; - std::list _history; - std::list::iterator _ith; - bool _atFirst; - - int simpleRun(const char* command); - int initRun(); - - virtual bool initState() = 0; - virtual bool initContext() = 0; -}; - - -class PYINTERP_EXPORT PyObjWrapper{ - PyObject* myObject; -public: - PyObjWrapper(PyObject* theObject): myObject(theObject) {} - PyObjWrapper(): myObject(0) {} - operator PyObject*(){ - return myObject; - } - PyObject* operator->(){ - return myObject; - } - PyObject* get(){ - return myObject; - } - bool operator!(){ - return !myObject; - } - bool operator==(PyObject* theObject){ - return myObject == theObject; - } - PyObject** operator&(){ - return &myObject; - } - PyObjWrapper& operator=(PyObjWrapper* theObjWrapper){ - Py_XDECREF(myObject); - myObject = theObjWrapper->myObject; - return *this; - } - virtual ~PyObjWrapper(){ - Py_XDECREF(myObject); - } -}; - -#endif diff --git a/src/Qtx/Qtx.pro b/src/Qtx/Qtx.pro index 2d1eaeee6..f0dcfcb17 100644 --- a/src/Qtx/Qtx.pro +++ b/src/Qtx/Qtx.pro @@ -1,20 +1,34 @@ -TEMPLATE = lib +win32:TEMPLATE = vclib +unix:TEMPLATE = lib + +CONFIG += embed_manifest_exe + +win32:QMAKE_MOC=$(QTDIR)\bin\moc.exe DESTDIR = ../../$(CONFIG_ID)/lib MOC_DIR = ../../moc OBJECTS_DIR = ../../$(CONFIG_ID)/obj/$$TARGET +win32:LIBS *= -L$(QTLIB) +win32:INCLUDEPATH *= $(QTINC) $(QTINC)\QtCore $(QTINC)\QtGui $(QTINC)\QtXml + QT += xml CONFIG -= debug release debug_and_release CONFIG += qt thread debug dll shared -win32:DEFINES += WIN32 +win32:DEFINES += WNT WIN32 DEFINES += QTX_EXPORTS HEADERS = *.h SOURCES = *.cxx +win32:copy_hdr.name = Install ${QMAKE_FILE_IN} +win32:copy_hdr.commands = type ${QMAKE_FILE_IN} > ../../include/${QMAKE_FILE_BASE}.h +win32:copy_hdr.output = ../../include/${QMAKE_FILE_BASE}.h +win32:copy_hdr.input = HEADERS +win32:QMAKE_EXTRA_COMPILERS += copy_hdr + includes.files = $$HEADERS includes.path = ../../include diff --git a/src/Qtx/QtxMRUAction.cxx b/src/Qtx/QtxMRUAction.cxx index 6f1b81844..5ee95779f 100755 --- a/src/Qtx/QtxMRUAction.cxx +++ b/src/Qtx/QtxMRUAction.cxx @@ -1,17 +1,17 @@ // Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D -// +// // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either +// License as published by the Free Software Foundation; either // version 2.1 of the License. -// -// This library is distributed in the hope that it will be useful -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// +// This library is distributed in the hope that it will be useful +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // Lesser General Public License for more details. // -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com @@ -36,12 +36,19 @@ \param parent parent object */ QtxMRUAction::QtxMRUAction( QObject* parent ) -: QtxAction( "Most Recently Used", "Most Recently Used", 0, parent ), +: QtxAction( tr( "Most Recently Used" ), tr( "Most Recently Used" ), 0, parent ), myVisCount( 5 ), + myHistoryCount( -1 ), + myLinkType( LinkAuto ), myInsertMode( MoveFirst ) { + myClear = new QAction( tr( "Clear" ), this ); + myClear->setVisible( false ); + setMenu( new QMenu( 0 ) ); + connect( menu(), SIGNAL( aboutToShow() ), this, SLOT( onAboutToShow() ) ); + connect( myClear, SIGNAL( triggered( bool ) ), this, SLOT( onCleared( bool ) ) ); } /*! @@ -53,10 +60,16 @@ QtxMRUAction::QtxMRUAction( QObject* parent ) QtxMRUAction::QtxMRUAction( const QString& text, const QString& menuText, QObject* parent ) : QtxAction( text, menuText, 0, parent ), myVisCount( 5 ), + myHistoryCount( -1 ), + myLinkType( LinkAuto ), myInsertMode( MoveFirst ) { + myClear = new QAction( tr( "Clear" ), this ); + myClear->setVisible( false ); + setMenu( new QMenu( 0 ) ); connect( menu(), SIGNAL( aboutToShow() ), this, SLOT( onAboutToShow() ) ); + connect( myClear, SIGNAL( triggered( bool ) ), this, SLOT( onCleared( bool ) ) ); } /*! @@ -69,11 +82,17 @@ QtxMRUAction::QtxMRUAction( const QString& text, const QString& menuText, QObjec QtxMRUAction::QtxMRUAction( const QString& text, const QIcon& icon, const QString& menuText, QObject* parent ) : QtxAction( text, icon, menuText, 0, parent ), -myVisCount( 5 ), -myInsertMode( MoveFirst ) + myVisCount( 5 ), + myHistoryCount( -1 ), + myLinkType( LinkAuto ), + myInsertMode( MoveFirst ) { + myClear = new QAction( tr( "Clear" ), this ); + myClear->setVisible( false ); + setMenu( new QMenu( 0 ) ); connect( menu(), SIGNAL( aboutToShow() ), this, SLOT( onAboutToShow() ) ); + connect( myClear, SIGNAL( triggered( bool ) ), this, SLOT( onCleared( bool ) ) ); } /*! @@ -102,6 +121,24 @@ void QtxMRUAction::setInsertMode( const int mode ) myInsertMode = mode; } +/*! + \brief Get the type of link menu name. + \return link type (QtxMRUAction::LinkType) +*/ +int QtxMRUAction::linkType() const +{ + return myLinkType; +} + +/*! + \brief Set the type of link menu name. + \param link type (QtxMRUAction::LinkType) +*/ +void QtxMRUAction::setLinkType( const int type ) +{ + myLinkType = type; +} + /*! \brief Get number of MRU items. \return number of MRU items @@ -132,7 +169,7 @@ int QtxMRUAction::visibleCount() const /*! \brief Set number of visible MRU items. - + This method sets the maximum number of MRU items to be displayed in the popup menu (5 by default). @@ -148,6 +185,48 @@ void QtxMRUAction::setVisibleCount( int num ) myVisCount = num; } +/*! + \brief Return visible status of the menu item which clear all MRU items. +*/ +bool QtxMRUAction::isClearPossible() const +{ + return myClear->isVisible(); +} + +/*! + \brief Set visible the menu item which clear all MRU items. +*/ +void QtxMRUAction::setClearPossible( const bool on ) +{ + myClear->setVisible( on ); +} + +/*! + \brief Get number of totally stored MRU items. + \return number of MRU items stored in the preferences + \sa setHistoryCount(), saveLinks(), loadLinks() +*/ +int QtxMRUAction::historyCount() const +{ + return myHistoryCount; +} + +/*! + \brief Set number of totally stored MRU items. + + This option allows setting number of MRU items to be stored + in the preferences file. + + If \a num < 0, then number of stored MRU items is not limited. + + \return number of MRU items stored in the preferences + \sa historyCount(), saveLinks(), loadLinks() +*/ +void QtxMRUAction::setHistoryCount( const int num ) +{ + myHistoryCount = num; +} + /*! \brief Insert MRU item. @@ -202,6 +281,14 @@ void QtxMRUAction::remove( const QString& link ) myLinks.removeAll( link ); } +/*! + \brief Remove all MRU items. +*/ +void QtxMRUAction::clear() +{ + myLinks.clear(); +} + /*! \brief Get MRU item \param idx MRU item index @@ -261,7 +348,7 @@ void QtxMRUAction::loadLinks( QtxResourceMgr* resMgr, const QString& section, co if ( !(*it).startsWith( itemPrefix ) ) continue; - QString link = resMgr->stringValue( section, *it, QString::null ); + QString link = resMgr->stringValue( section, *it, QString() ); if ( link.isEmpty() || map.contains( link ) ) continue; @@ -281,8 +368,16 @@ void QtxMRUAction::saveLinks( QtxResourceMgr* resMgr, const QString& section, co if ( !resMgr || section.isEmpty() ) return; - if ( clear ) - resMgr->remove( section ); + QString itemPrefix( "item_" ); + + if ( clear ) { + QStringList items = resMgr->parameters( section ); + for ( QStringList::const_iterator it = items.begin(); it != items.end(); ++it ) + { + if ( (*it).startsWith( itemPrefix ) ) + resMgr->remove( section, *it ); + } + } QStringList lst; QMap map; @@ -292,14 +387,13 @@ void QtxMRUAction::saveLinks( QtxResourceMgr* resMgr, const QString& section, co map.insert( *itr, 0 ); } - QString itemPrefix( "item_" ); QStringList items = resMgr->parameters( section ); for ( QStringList::const_iterator it = items.begin(); it != items.end(); ++it ) { if ( !(*it).startsWith( itemPrefix ) ) continue; - QString link = resMgr->stringValue( section, *it, QString::null ); + QString link = resMgr->stringValue( section, *it, QString() ); if ( !link.isEmpty() && !map.contains( link ) ) { lst.append( link ); @@ -310,13 +404,15 @@ void QtxMRUAction::saveLinks( QtxResourceMgr* resMgr, const QString& section, co } int counter = 0; - for ( QStringList::const_iterator iter = lst.begin(); iter != lst.end(); ++iter, counter++ ) + for ( QStringList::const_iterator iter = lst.begin(); + iter != lst.end() && ( myHistoryCount < 0 || counter < myHistoryCount ); + ++iter, counter++ ) resMgr->setValue( section, itemPrefix + QString().sprintf( "%03d", counter ), *iter ); } /*! \brief Prepare MRU items popup menu. - + This method is called when the parent menu is shown. Enables or disables sub menu item according to the number of MRU items. */ @@ -336,11 +432,16 @@ void QtxMRUAction::onActivated() if ( !a ) return; - QString link = a->text(); + QString link = a->data().toString(); if ( !link.isEmpty() && myLinks.contains( link ) ) emit activated( link ); } +void QtxMRUAction::onCleared( bool ) +{ + clear(); +} + /*! \brief Update MRU items popup menu. */ @@ -352,9 +453,58 @@ void QtxMRUAction::updateMenu() pm->clear(); + QStringList links; + QMap map; int count = visibleCount() < 0 ? myLinks.count() : visibleCount(); - for ( QStringList::const_iterator it = myLinks.begin(); it != myLinks.end() && count > 0; ++it, count-- ) - pm->addAction( *it, this, SLOT( onActivated() ) ); + int i = insertMode() == AddLast || insertMode() == MoveLast ? qMax( 0, myLinks.count()-count ) : 0; + for ( ; i < myLinks.count() && count > 0; ++i, count-- ) + { + links.append( myLinks[i] ); + if ( linkType() == LinkAuto ) + { + QString shortName = Qtx::file( myLinks[i] ); + if ( map.contains( shortName ) ) + map[shortName]++; + else + map.insert( shortName, 0 ); + } + } + + i = 1; + for ( QStringList::const_iterator it = links.begin(); it != links.end(); ++it, i++ ) + { + QString linkName; + switch( linkType() ) + { + case LinkAuto: + linkName = Qtx::file( *it ); + if ( map.contains( linkName ) && map[linkName] ) + linkName = *it; + break; + case LinkShort: + linkName = Qtx::file( *it ); + break; + case LinkFull: + default: + linkName = *it; + break; + } + + if ( links.count() < 10 ) + linkName = QString( "&%1 %2" ).arg( i ).arg( linkName ); + + pm->addAction( linkName, this, SLOT( onActivated() ) )->setData( *it ); + } + + if ( pm->isEmpty() ) + pm->addAction( tr( "" ) )->setEnabled( false ); + + if ( isClearPossible() ) + { + pm->addSeparator(); + pm->addAction( myClear ); + myClear->setEnabled( !pm->isEmpty() ); + } } /*! diff --git a/src/Qtx/QtxMRUAction.h b/src/Qtx/QtxMRUAction.h index f8a5dd9b0..f07f4fc46 100755 --- a/src/Qtx/QtxMRUAction.h +++ b/src/Qtx/QtxMRUAction.h @@ -44,6 +44,11 @@ public: AddLast //!< if specified item doesn't exist, add it to the end } InsertionMode; + typedef enum { LinkAuto, //!< put the full path of link into the menu if link file names of severals link are same + LinkShort, //!< put the only file name of link into the menu + LinkFull //!< put the full path of link into the menu + } LinkType; + public: QtxMRUAction( QObject* = 0 ); QtxMRUAction( const QString&, const QString&, QObject* = 0 ); @@ -53,12 +58,21 @@ public: int insertMode() const; void setInsertMode( const int ); + int linkType() const; + void setLinkType( const int ); + int count() const; bool isEmpty() const; int visibleCount() const; void setVisibleCount( const int ); + bool isClearPossible() const; + void setClearPossible( const bool ); + + int historyCount() const; + void setHistoryCount( const int ); + void remove( const int ); void remove( const QString& ); void insert( const QString& ); @@ -70,19 +84,26 @@ public: virtual void loadLinks( QtxResourceMgr*, const QString&, const bool = true ); virtual void saveLinks( QtxResourceMgr*, const QString&, const bool = true ) const; +public slots: + void clear(); + signals: void activated( const QString& ); private slots: void onActivated(); void onAboutToShow(); + void onCleared( bool ); private: void updateMenu(); private: QStringList myLinks; //!< most recent used items + QAction* myClear; //!< clear item int myVisCount; //!< number of visible MRU items + int myHistoryCount; //!< number of stored MRU items + int myLinkType; //!< type of link names in menu int myInsertMode; //!< items insertion policy }; diff --git a/src/Qtx/QtxPagePrefMgr.cxx b/src/Qtx/QtxPagePrefMgr.cxx index 5697e4415..27701557e 100644 --- a/src/Qtx/QtxPagePrefMgr.cxx +++ b/src/Qtx/QtxPagePrefMgr.cxx @@ -1,17 +1,17 @@ // Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D -// +// // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either +// License as published by the Free Software Foundation; either // version 2.1 of the License. -// -// This library is distributed in the hope that it will be useful -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// +// This library is distributed in the hope that it will be useful +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // Lesser General Public License for more details. // -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com @@ -38,6 +38,7 @@ #include #include #include +#include #include #include @@ -58,7 +59,7 @@ QtxPagePrefMgr::QtxPagePrefMgr( QtxResourceMgr* resMgr, QWidget* parent ) { myBox = new QtxGridBox( 1, Qt::Horizontal, this, 0 ); QVBoxLayout* base = new QVBoxLayout( this ); - base->setMargin( 0 ); + base->setMargin( 5 ); base->setSpacing( 0 ); base->addWidget( myBox ); } @@ -76,8 +77,6 @@ QtxPagePrefMgr::~QtxPagePrefMgr() */ QSize QtxPagePrefMgr::sizeHint() const { - initialize(); - return QFrame::sizeHint(); } @@ -87,20 +86,20 @@ QSize QtxPagePrefMgr::sizeHint() const */ QSize QtxPagePrefMgr::minimumSizeHint() const { - initialize(); - return QFrame::minimumSizeHint(); } /*! \brief Customize show/hide widget operation. - \param on if \c true the widget is being shown, otherswise + \param on if \c true the widget is being shown, otherswise it is being hidden */ void QtxPagePrefMgr::setVisible( bool on ) { - if ( on && !myInit ) - updateContents(); + if ( on ) + initialize(); + + QApplication::instance()->processEvents(); QFrame::setVisible( on ); } @@ -115,12 +114,9 @@ void QtxPagePrefMgr::updateContents() QList lst = childItems(); for ( QList::const_iterator it = lst.begin(); it != lst.end(); ++it ) { - if ( (*it)->rtti() == QtxPagePrefItem::RTTI() ) - { - QtxPagePrefItem* item = (QtxPagePrefItem*)(*it); - if ( item->widget() && item->widget()->parent() != myBox ) - item->widget()->setParent( myBox ); - } + QtxPagePrefItem* item = dynamic_cast( *it ); + if ( item && item->widget() && item->widget()->parent() != myBox ) + item->widget()->setParent( myBox ); } setWindowIcon( icon() ); @@ -195,18 +191,25 @@ void QtxPagePrefMgr::setOptionValue( const QString& name, const QVariant& val ) */ void QtxPagePrefMgr::initialize() const { - if ( myInit ) - return; + // if ( myInit ) + // return; QtxPagePrefMgr* that = (QtxPagePrefMgr*)this; - - that->updateContents(); + that->initialize( that ); + + // that->myInit = true; +} + +void QtxPagePrefMgr::initialize( QtxPreferenceItem* item ) +{ + if ( !item ) + return; - QList lst = childItems( true ); + QList lst = item->childItems( false ); for ( QList::iterator it = lst.begin(); it != lst.end(); ++it ) - (*it)->updateContents(); + initialize( *it ); - that->myInit = true; + updateContents(); } /*! @@ -215,6 +218,41 @@ void QtxPagePrefMgr::initialize() const preference items. */ +class QtxPagePrefItem::Listener : public QObject +{ +public: + Listener( QtxPagePrefItem* ); + virtual ~Listener(); + + virtual bool eventFilter( QObject*, QEvent* ); + +private: + QtxPagePrefItem* myItem; +}; + +QtxPagePrefItem::Listener::Listener( QtxPagePrefItem* item ) +: QObject( 0 ), + myItem( item ) +{ +} + +QtxPagePrefItem::Listener::~Listener() +{ +} + +bool QtxPagePrefItem::Listener::eventFilter( QObject* o, QEvent* e ) +{ + if ( !myItem || myItem->widget() != o ) + return false; + + if ( e->type() == QEvent::Show || e->type() == QEvent::ShowToParent ) + myItem->widgetShown(); + if ( e->type() == QEvent::Hide || e->type() == QEvent::HideToParent ) + myItem->widgetHided(); + + return false; +} + /*! \brief Constructor. \param title preference item title @@ -225,7 +263,8 @@ void QtxPagePrefMgr::initialize() const QtxPagePrefItem::QtxPagePrefItem( const QString& title, QtxPreferenceItem* parent, const QString& sect, const QString& param ) : QtxPreferenceItem( title, sect, param, parent ), - myWidget( 0 ) + myWidget( 0 ), + myListener( 0 ) { } @@ -235,15 +274,7 @@ QtxPagePrefItem::QtxPagePrefItem( const QString& title, QtxPreferenceItem* paren QtxPagePrefItem::~QtxPagePrefItem() { delete myWidget; -} - -/*! - \brief Get unique item type identifier. - \return item type ID -*/ -int QtxPagePrefItem::rtti() const -{ - return QtxPagePrefItem::RTTI(); + delete myListener; } /*! @@ -256,15 +287,6 @@ QWidget* QtxPagePrefItem::widget() const return myWidget; } -/*! - \brief Specify unique item class identifier. - \return item class ID -*/ -int QtxPagePrefItem::RTTI() -{ - return 1000; -} - /*! \brief Set preference item editor widget. \param wid editor widget @@ -272,7 +294,18 @@ int QtxPagePrefItem::RTTI() */ void QtxPagePrefItem::setWidget( QWidget* wid ) { + if ( myWidget && myListener ) + myWidget->removeEventFilter( myListener ); + myWidget = wid; + + if ( myWidget ) + { + if ( !myListener ) + myListener = new Listener( this ); + myWidget->installEventFilter( myListener ); + } + sendItemChanges(); } @@ -311,7 +344,7 @@ void QtxPagePrefItem::itemChanged( QtxPreferenceItem* /*item*/ ) /*! \brief Store preference item to the resource manager. - + This method should be reimplemented in the subclasses. Base implementation does nothing. @@ -323,7 +356,7 @@ void QtxPagePrefItem::store() /*! \brief Retrieve preference item from the resource manager. - + This method should be reimplemented in the subclasses. Base implementation does nothing. @@ -333,6 +366,29 @@ void QtxPagePrefItem::retrieve() { } +/*! + \brief Invoked when preference item widget is shown. +*/ +void QtxPagePrefItem::widgetShown() +{ +} + +/*! + \brief Invoked when preference item widget is hided. +*/ +void QtxPagePrefItem::widgetHided() +{ +} + +void QtxPagePrefItem::ensureVisible( QtxPreferenceItem* i ) +{ + QtxPreferenceItem::ensureVisible(); + + QtxPagePrefItem* item = dynamic_cast( i ); + if ( item && item->widget() ) + item->widget()->setVisible( true ); +} + /*! \brief Find all child items of the QtxPagePrefItem type. \param list used to return list of child items @@ -343,14 +399,15 @@ void QtxPagePrefItem::pageChildItems( QList& list, const bool QList lst = childItems( rec ); for ( QList::const_iterator it = lst.begin(); it != lst.end(); ++it ) { - if ( (*it)->rtti() == QtxPagePrefItem::RTTI() ) - list.append( (QtxPagePrefItem*)*it ); + QtxPagePrefItem* item = dynamic_cast( *it ); + if ( item ) + list.append( item ); } } /*! \brief Called when contents is changed (item is added, removed or modified). - + Triggers the item update. */ void QtxPagePrefItem::contentChanged() @@ -377,12 +434,19 @@ QtxPageNamedPrefItem::QtxPageNamedPrefItem( const QString& title, QtxPreferenceI myControl( 0 ) { QWidget* main = new QWidget(); - QHBoxLayout* base = new QHBoxLayout( main ); - base->setMargin( 0 ); - base->setSpacing( 5 ); - myLabel = new QLabel( title, main ); - base->addWidget( myLabel ); + // QtxPagePrefGroupItem* aGroup = 0;//dynamic_cast(parent); + // if ( !aGroup ) + // { + QHBoxLayout* base = new QHBoxLayout( main ); + base->setMargin( 0 ); + base->setSpacing( 5 ); + + myLabel = new QLabel( title, main ); + base->addWidget( myLabel ); + // } + // else + // myLabel = new QLabel( title, aGroup->gridBox() ); setWidget( main ); @@ -442,7 +506,43 @@ void QtxPageNamedPrefItem::setControl( QWidget* wid ) myControl = wid; if ( myControl ) - widget()->layout()->addWidget( myControl ); + { + // QtxPagePrefGroupItem* aGroup = 0;//dynamic_cast(parentItem()); + // if ( !aGroup ) + widget()->layout()->addWidget( myControl ); + // else myControl->setParent( aGroup->gridBox() ); + } +} + +void QtxPageNamedPrefItem::adjustLabels( QtxPagePrefItem* parent ) +{ + if ( !parent ) + return; + + QList childList = parent->childItems(); + + QList namedItems; + for ( QList::iterator it = childList.begin(); it != childList.end(); ++it ) + { + QtxPageNamedPrefItem* item = dynamic_cast( *it ); + if ( item ) + namedItems.append( item ); + } + + int sz = 0; + for ( QList::iterator it1 = namedItems.begin(); it1 != namedItems.end(); ++it1 ) + { + QtxPageNamedPrefItem* item = *it1; + if ( item->label() ) + sz = qMax( sz, item->label()->sizeHint().width() ); + } + + for ( QList::iterator it2 = namedItems.begin(); it2 != namedItems.end(); ++it2 ) + { + QtxPageNamedPrefItem* item = *it2; + if ( item->label() ) + item->label()->setMinimumWidth( sz ); + } } /*! @@ -540,6 +640,7 @@ void QtxPagePrefListItem::setFixedSize( const bool on ) */ void QtxPagePrefListItem::updateContents() { + QtxPagePrefItem::updateContents(); updateVisible(); } @@ -581,6 +682,22 @@ void QtxPagePrefListItem::setOptionValue( const QString& name, const QVariant& v QtxPagePrefItem::setOptionValue( name, val ); } +void QtxPagePrefListItem::widgetShown() +{ + updateState(); +} + +void QtxPagePrefListItem::ensureVisible( QtxPreferenceItem* i ) +{ + if ( !i ) + return; + + QtxPreferenceItem::ensureVisible( i ); + + setSelected( i->id() ); + updateState(); +} + /*! \brief Called when the selection in the list box is changed. */ @@ -756,8 +873,16 @@ void QtxPagePrefListItem::setSelected( const int id ) /*! \class QtxPagePrefToolBoxItem + \brief GUI implementation of the tool box container preference item. */ +/*! + \brief Constructor. + \param title preference item title + \param parent parent preference item + \param sect resource file section associated with the preference item + \param param resource file parameter associated with the preference item +*/ QtxPagePrefToolBoxItem::QtxPagePrefToolBoxItem( const QString& title, QtxPreferenceItem* parent, const QString& sect, const QString& param ) : QtxPagePrefItem( title, parent, sect, param ) @@ -765,15 +890,25 @@ QtxPagePrefToolBoxItem::QtxPagePrefToolBoxItem( const QString& title, QtxPrefere setWidget( myToolBox = new QToolBox( 0 ) ); } +/*! + \brief Destructor. +*/ QtxPagePrefToolBoxItem::~QtxPagePrefToolBoxItem() { } +/*! + \brief Update widget contents. +*/ void QtxPagePrefToolBoxItem::updateContents() { + QtxPagePrefItem::updateContents(); updateToolBox(); } +/*! + \brief Update tool box widget. +*/ void QtxPagePrefToolBoxItem::updateToolBox() { QList items; @@ -820,6 +955,18 @@ void QtxPagePrefToolBoxItem::updateToolBox() myToolBox->setCurrentWidget( cur ); } +void QtxPagePrefToolBoxItem::ensureVisible( QtxPreferenceItem* i ) +{ + if ( !i ) + return; + + QtxPreferenceItem::ensureVisible( i ); + + QtxPagePrefItem* item = dynamic_cast( i ); + if ( item && item->widget() ) + myToolBox->setCurrentWidget( item->widget() ); +} + /*! \class QtxPagePrefTabsItem \brief GUI implementation of the tab widget container. @@ -851,6 +998,7 @@ QtxPagePrefTabsItem::~QtxPagePrefTabsItem() */ void QtxPagePrefTabsItem::updateContents() { + QtxPagePrefItem::updateContents(); updateTabs(); } @@ -959,6 +1107,18 @@ void QtxPagePrefTabsItem::setOptionValue( const QString& name, const QVariant& v QtxPagePrefItem::setOptionValue( name, val ); } +void QtxPagePrefTabsItem::ensureVisible( QtxPreferenceItem* i ) +{ + if ( !i ) + return; + + QtxPreferenceItem::ensureVisible( i ); + + QtxPagePrefItem* item = dynamic_cast( i ); + if ( item && item->widget() ) + myTabs->setCurrentWidget( item->widget() ); +} + /*! \brief Update tabs. */ @@ -1047,7 +1207,11 @@ QtxPagePrefFrameItem::~QtxPagePrefFrameItem() */ void QtxPagePrefFrameItem::updateContents() { + QtxPagePrefItem::updateContents(); + updateFrame(); + + QtxPageNamedPrefItem::adjustLabels( this ); } /*! @@ -1130,6 +1294,11 @@ void QtxPagePrefFrameItem::setOrientation( const Qt::Orientation o ) myBox->setOrientation( o ); } +/*! + \brief Check if the frame widget stretching is enabled. + \return \c true if the widget is stretchable + \sa setStretch() +*/ bool QtxPagePrefFrameItem::stretch() const { QSpacerItem* s = 0; @@ -1137,9 +1306,14 @@ bool QtxPagePrefFrameItem::stretch() const for ( int i = 0; l && i < l->count() && !s; i++ ) s = l->itemAt( i )->spacerItem(); - return s ? ( s->expandingDirections() & Qt::Vertical ) != 0 : false; + return s ? (bool)( s->expandingDirections() & Qt::Vertical ) : false; } +/*! + \brief Enable/disable frame widget stretching. + \param on new stretchable state + \sa stretch() +*/ void QtxPagePrefFrameItem::setStretch( const bool on ) { QSpacerItem* s = 0; @@ -1210,6 +1384,13 @@ void QtxPagePrefFrameItem::setOptionValue( const QString& name, const QVariant& QtxPagePrefItem::setOptionValue( name, val ); } +void QtxPagePrefFrameItem::widgetShown() +{ + QtxPagePrefItem::widgetShown(); + + QtxPageNamedPrefItem::adjustLabels( this ); +} + /*! \brief Update frame widget. */ @@ -1250,6 +1431,8 @@ QtxPagePrefGroupItem::QtxPagePrefGroupItem( const QString& title, QtxPreferenceI myGroup->setWidget( myBox ); setWidget( myGroup ); + + updateState(); } /*! @@ -1269,6 +1452,8 @@ QtxPagePrefGroupItem::QtxPagePrefGroupItem( const int cols, const QString& title myGroup->setWidget( myBox ); setWidget( myGroup ); + + updateState(); } /*! @@ -1295,10 +1480,14 @@ void QtxPagePrefGroupItem::setResource( const QString& sect, const QString& para */ void QtxPagePrefGroupItem::updateContents() { + QtxPagePrefItem::updateContents(); + myGroup->setTitle( title() ); updateState(); updateGroup(); + + QtxPageNamedPrefItem::adjustLabels( this ); } /*! @@ -1409,6 +1598,14 @@ void QtxPagePrefGroupItem::store() setBoolean( myGroup->isChecked() ); } +/*! + \brief Return widget contained grid layout of this group. +*/ +QtxGridBox* QtxPagePrefGroupItem::gridBox() const +{ + return myBox; +} + /*! \brief Retrieve preference item from the resource manager. \sa store() @@ -1478,6 +1675,13 @@ void QtxPagePrefGroupItem::setOptionValue( const QString& name, const QVariant& QtxPagePrefItem::setOptionValue( name, val ); } +void QtxPagePrefGroupItem::widgetShown() +{ + QtxPagePrefItem::widgetShown(); + + QtxPageNamedPrefItem::adjustLabels( this ); +} + /*! \brief Update widget state. */ @@ -1516,7 +1720,7 @@ void QtxPagePrefGroupItem::updateGroup() /*! \brief Constructor. - Creates spacer item with zero width and height and expanding + Creates spacer item with zero width and height and expanding on both directions (by height and width). \param parent parent preference item @@ -1530,7 +1734,7 @@ QtxPagePrefSpaceItem::QtxPagePrefSpaceItem( QtxPreferenceItem* parent ) /*! \brief Constructor. - Creates spacer item with zero width and height and expanding + Creates spacer item with zero width and height and expanding according to the specified orientation. \param o spacer orientation @@ -1625,7 +1829,7 @@ void QtxPagePrefSpaceItem::setStretch( Qt::Orientation o, const int sf ) sp.setVerticalStretch( sf ); sp.setVerticalPolicy( sf > 0 ? QSizePolicy::Expanding : QSizePolicy::Fixed ); } - + widget()->setSizePolicy( sp ); } @@ -1693,7 +1897,7 @@ void QtxPagePrefSpaceItem::initialize( const int w, const int h, const int hs, c QSizePolicy sp; sp.setHorizontalPolicy( hs > 0 ? QSizePolicy::Expanding : QSizePolicy::Fixed ); sp.setVerticalPolicy( vs > 0 ? QSizePolicy::Expanding : QSizePolicy::Fixed ); - + sp.setHorizontalStretch( hs ); sp.setVerticalStretch( vs ); @@ -1701,7 +1905,7 @@ void QtxPagePrefSpaceItem::initialize( const int w, const int h, const int hs, c wid->setSizePolicy( sp ); wid->setMinimumSize( w, h ); - + setWidget( wid ); } @@ -1744,7 +1948,7 @@ void QtxPagePrefCheckItem::setTitle( const QString& txt ) myCheck->setText( title() ); } - + /*! \brief Store preference item to the resource manager. \sa retrieve() @@ -1801,7 +2005,7 @@ QtxPagePrefEditItem::QtxPagePrefEditItem( const QString& title, QtxPreferenceIte \param param resource file parameter associated with the preference item */ QtxPagePrefEditItem::QtxPagePrefEditItem( const int type, const QString& title, - QtxPreferenceItem* parent, const QString& sect, + QtxPreferenceItem* parent, const QString& sect, const QString& param ) : QtxPageNamedPrefItem( title, parent, sect, param ), myType( type ) @@ -1929,7 +2133,7 @@ void QtxPagePrefEditItem::updateEditor() /*! \class QtxPagePrefSelectItem - \brief GUI implementation of the resources selector item + \brief GUI implementation of the resources selector item (string, integer or double values list). All items in the list (represented as combo box) should be specified @@ -1939,7 +2143,7 @@ void QtxPagePrefEditItem::updateEditor() /*! \brief Constructor. - + Creates preference item with combo box widget which is not editable (direct value entering is disabled). @@ -1961,7 +2165,7 @@ QtxPagePrefSelectItem::QtxPagePrefSelectItem( const QString& title, QtxPreferenc /*! \brief Constructor. - + Creates preference item with combo box widget which is editable according to the specified input type (integer, double or string values). @@ -2020,7 +2224,7 @@ void QtxPagePrefSelectItem::setInputType( const int type ) QStringList QtxPagePrefSelectItem::strings() const { QStringList res; - for ( int i = 0; i < mySelector->count(); i++ ) + for ( uint i = 0; i < mySelector->count(); i++ ) res.append( mySelector->itemText( i ) ); return res; } @@ -2033,7 +2237,7 @@ QStringList QtxPagePrefSelectItem::strings() const QList QtxPagePrefSelectItem::numbers() const { QList res; - for ( int i = 0; i < mySelector->count(); i++ ) + for ( uint i = 0; i < mySelector->count(); i++ ) { if ( mySelector->hasId( i ) ) res.append( mySelector->id( i ) ); @@ -2059,7 +2263,7 @@ void QtxPagePrefSelectItem::setStrings( const QStringList& lst ) */ void QtxPagePrefSelectItem::setNumbers( const QList& ids ) { - int i = 0; + uint i = 0; for ( QList::const_iterator it = ids.begin(); it != ids.end() && i < mySelector->count(); ++it, i++ ) mySelector->setId( i, *it ); } @@ -2097,7 +2301,7 @@ void QtxPagePrefSelectItem::retrieve() idx = mySelector->index( num ); else { - for ( int i = 0; i < mySelector->count() && idx == -1; i++ ) + for ( uint i = 0; i < mySelector->count() && idx == -1; i++ ) { if ( mySelector->itemText( i ) == txt ) idx = i; @@ -2268,7 +2472,7 @@ QtxPagePrefSpinItem::QtxPagePrefSpinItem( const QString& title, QtxPreferenceIte \param param resource file parameter associated with the preference item */ QtxPagePrefSpinItem::QtxPagePrefSpinItem( const int type, const QString& title, - QtxPreferenceItem* parent, const QString& sect, + QtxPreferenceItem* parent, const QString& sect, const QString& param ) : QtxPageNamedPrefItem( title, parent, sect, param ), myType( type ) @@ -2383,7 +2587,7 @@ QString QtxPagePrefSpinItem::suffix() const } /*! - \brief Get spin box preference item special value text (which is shown + \brief Get spin box preference item special value text (which is shown when the spin box reaches minimum value). \return spin box special value text \sa setSpecialValueText() @@ -2481,7 +2685,7 @@ void QtxPagePrefSpinItem::setSuffix( const QString& txt ) } /*! - \brief Set spin box preference item special value text (which is shown + \brief Set spin box preference item special value text (which is shown when the spin box reaches minimum value). \param txt new spin box special value text \sa specialValueText() @@ -2638,7 +2842,7 @@ void QtxPagePrefSpinItem::updateSpinBox() \param sect resource file section associated with the preference item \param param resource file parameter associated with the preference item */ -QtxPagePrefTextItem::QtxPagePrefTextItem( QtxPreferenceItem* parent, const QString& sect, +QtxPagePrefTextItem::QtxPagePrefTextItem( QtxPreferenceItem* parent, const QString& sect, const QString& param ) : QtxPageNamedPrefItem( QString(), parent, sect, param ) { @@ -2706,7 +2910,10 @@ QtxPagePrefColorItem::QtxPagePrefColorItem( const QString& title, QtxPreferenceI const QString& sect, const QString& param ) : QtxPageNamedPrefItem( title, parent, sect, param ) { - setControl( myColor = new QtxColorButton() ); + // QtxPagePrefGroupItem* aGroup 0; //= dynamic_cast( parent ); + + // setControl( myColor = new QtxColorButton( aGroup ? aGroup->gridBox() : 0 ) ); + setControl( myColor = new QtxColorButton( 0 ) ); myColor->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ); } @@ -2749,7 +2956,7 @@ void QtxPagePrefColorItem::retrieve() \param param resource file parameter associated with the preference item */ QtxPagePrefFontItem::QtxPagePrefFontItem( const int feat, const QString& title, - QtxPreferenceItem* parent, const QString& sect, + QtxPreferenceItem* parent, const QString& sect, const QString& param ) : QtxPageNamedPrefItem( title, parent, sect, param ) { @@ -2984,8 +3191,8 @@ void QtxPagePrefPathItem::setOptionValue( const QString& name, const QVariant& v } /*! - \class QtxPagePrefPathListItem - \brief GUI implementation of resources directory list item. + \class QtxPagePrefPathListItem + \brief GUI implementation of the resources files/directories list item. */ /*! @@ -3111,10 +3318,20 @@ void QtxPagePrefPathListItem::setOptionValue( const QString& name, const QVarian \brief GUI implementation of resources date/time item. */ +/*! + \brief Constructor. + + Creates an item to enter date and time. + + \param title preference item title + \param parent parent preference item + \param sect resource file section associated with the preference item + \param param resource file parameter associated with the preference item +*/ QtxPagePrefDateTimeItem::QtxPagePrefDateTimeItem( const QString& title, QtxPreferenceItem* parent, const QString& sect, const QString& param ) : QtxPageNamedPrefItem( title, parent, sect, param ), -myType( DateTime ) + myType( DateTime ) { setControl( myDateTime = new QDateTimeEdit() ); myDateTime->setCalendarPopup( true ); @@ -3122,10 +3339,22 @@ myType( DateTime ) updateDateTime(); } +/*! + \brief Constructor. + + Creates preference item for editing of the date and/or time value: + the type is specified by parameter \a type. + + \param type preference item input type (QtxPagePrefDateTimeItem::InputType) + \param title preference item title + \param parent parent preference item + \param sect resource file section associated with the preference item + \param param resource file parameter associated with the preference item +*/ QtxPagePrefDateTimeItem::QtxPagePrefDateTimeItem( const int type, const QString& title, QtxPreferenceItem* parent, const QString& sect, const QString& param ) : QtxPageNamedPrefItem( title, parent, sect, param ), -myType( type ) + myType( type ) { setControl( myDateTime = new QDateTimeEdit() ); myDateTime->setCalendarPopup( true ); @@ -3133,15 +3362,28 @@ myType( type ) updateDateTime(); } +/*! + \brief Destructor. +*/ QtxPagePrefDateTimeItem::~QtxPagePrefDateTimeItem() { } +/*! + \brief Get date/time box preference item input type. + \return preference item input type (QtxPagePrefDateTimeItem::InputType) + \sa setInputType() +*/ int QtxPagePrefDateTimeItem::inputType() const { return myType; } +/*! + \brief Set date/time box preference item input type. + \param type new preference item input type (QtxPagePrefDateTimeItem::InputType) + \sa inputType() +*/ void QtxPagePrefDateTimeItem::setInputType( const int type ) { if ( myType == type ) @@ -3151,36 +3393,69 @@ void QtxPagePrefDateTimeItem::setInputType( const int type ) updateDateTime(); } +/*! + \brief Check if the popup calendar menu is enabled. + \return \c true if calendar popup menu is enabled +*/ bool QtxPagePrefDateTimeItem::calendar() const { return myDateTime->calendarPopup(); } +/*! + \brief Enable/disable popup calendar menu. + \param on new flag state +*/ void QtxPagePrefDateTimeItem::setCalendar( const bool on ) { myDateTime->setCalendarPopup( on ); } +/*! + \brief Get maximum date value. + \return maximum date value + \sa setMaximumDate(), minimumDate(), maximumTime(), minimumTime() +*/ QDate QtxPagePrefDateTimeItem::maximumDate() const { return myDateTime->maximumDate(); } +/*! + \brief Get maximum time value. + \return maximum time value + \sa setMaximumTime(), minimumTime(), maximumDate(), minimumDate() +*/ QTime QtxPagePrefDateTimeItem::maximumTime() const { return myDateTime->maximumTime(); } +/*! + \brief Get minimum date value. + \return minimum date value + \sa setMinimumDate(), maximumDate(), maximumTime(), minimumTime() +*/ QDate QtxPagePrefDateTimeItem::minimumDate() const { return myDateTime->minimumDate(); } +/*! + \brief Get minimum time value. + \return maximum time value + \sa setMinimumTime(), maximumTime(), maximumDate(), minimumDate() +*/ QTime QtxPagePrefDateTimeItem::minimumTime() const { return myDateTime->minimumTime(); } +/*! + \brief Set maximum date value. + \param d new maximum date value + \sa maximumDate(), minimumDate(), maximumTime(), minimumTime() +*/ void QtxPagePrefDateTimeItem::setMaximumDate( const QDate& d ) { if ( d.isValid() ) @@ -3189,6 +3464,11 @@ void QtxPagePrefDateTimeItem::setMaximumDate( const QDate& d ) myDateTime->clearMaximumDate(); } +/*! + \brief Set maximum time value. + \param t new maximum time value + \sa maximumTime(), minimumTime(), maximumDate(), minimumDate() +*/ void QtxPagePrefDateTimeItem::setMaximumTime( const QTime& t ) { if ( t.isValid() ) @@ -3197,6 +3477,11 @@ void QtxPagePrefDateTimeItem::setMaximumTime( const QTime& t ) myDateTime->clearMaximumTime(); } +/*! + \brief Set minimum date value. + \param d new minimum date value + \sa minimumDate(), maximumDate(), maximumTime(), minimumTime() +*/ void QtxPagePrefDateTimeItem::setMinimumDate( const QDate& d ) { if ( d.isValid() ) @@ -3205,6 +3490,11 @@ void QtxPagePrefDateTimeItem::setMinimumDate( const QDate& d ) myDateTime->clearMinimumDate(); } +/*! + \brief Set minimum time value. + \param t new minimum time value + \sa minimumTime(), maximumTime(), maximumDate(), minimumDate() +*/ void QtxPagePrefDateTimeItem::setMinimumTime( const QTime& t ) { if ( t.isValid() ) @@ -3213,6 +3503,10 @@ void QtxPagePrefDateTimeItem::setMinimumTime( const QTime& t ) myDateTime->clearMinimumTime(); } +/*! + \brief Store preference item to the resource manager. + \sa retrieve() +*/ void QtxPagePrefDateTimeItem::store() { QString str; @@ -3232,6 +3526,10 @@ void QtxPagePrefDateTimeItem::store() setString( str ); } +/*! + \brief Retrieve preference item from the resource manager. + \sa store() +*/ void QtxPagePrefDateTimeItem::retrieve() { QString str = getString(); @@ -3249,6 +3547,12 @@ void QtxPagePrefDateTimeItem::retrieve() } } +/*! + \brief Get preference item option value. + \param name option name + \return property value or null QVariant if option is not set + \sa setOptionValue() +*/ QVariant QtxPagePrefDateTimeItem::optionValue( const QString& name ) const { if ( name == "input_type" || name == "type" ) @@ -3265,6 +3569,12 @@ QVariant QtxPagePrefDateTimeItem::optionValue( const QString& name ) const return QtxPageNamedPrefItem::optionValue( name ); } +/*! + \brief Set preference item option value. + \param name option name + \param val new property value + \sa optionValue() +*/ void QtxPagePrefDateTimeItem::setOptionValue( const QString& name, const QVariant& val ) { if ( name == "input_type" || name == "type" ) @@ -3296,6 +3606,9 @@ void QtxPagePrefDateTimeItem::setOptionValue( const QString& name, const QVarian QtxPageNamedPrefItem::setOptionValue( name, val ); } +/*! + \brief Update date/time widget. +*/ void QtxPagePrefDateTimeItem::updateDateTime() { QString dispFmt; diff --git a/src/Qtx/QtxPagePrefMgr.h b/src/Qtx/QtxPagePrefMgr.h index 67ceee71e..11ca33aa3 100644 --- a/src/Qtx/QtxPagePrefMgr.h +++ b/src/Qtx/QtxPagePrefMgr.h @@ -1,17 +1,17 @@ // Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D -// +// // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either +// License as published by the Free Software Foundation; either // version 2.1 of the License. -// -// This library is distributed in the hope that it will be useful -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// +// This library is distributed in the hope that it will be useful +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // Lesser General Public License for more details. // -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com @@ -79,6 +79,7 @@ protected: private: void initialize() const; + void initialize( QtxPreferenceItem* ); private: QtxGridBox* myBox; @@ -87,17 +88,15 @@ private: class QTX_EXPORT QtxPagePrefItem : public QtxPreferenceItem { + class Listener; + public: QtxPagePrefItem( const QString&, QtxPreferenceItem* = 0, const QString& = QString(), const QString& = QString() ); virtual ~QtxPagePrefItem(); - virtual int rtti() const; - QWidget* widget() const; - static int RTTI(); - protected: void setWidget( QWidget* ); @@ -110,11 +109,17 @@ protected: virtual void store(); virtual void retrieve(); + virtual void widgetShown(); + virtual void widgetHided(); + + virtual void ensureVisible( QtxPreferenceItem* ); + private: virtual void contentChanged(); private: QPointer myWidget; + Listener* myListener; }; class QTX_EXPORT QtxPageNamedPrefItem : public QtxPagePrefItem @@ -126,6 +131,8 @@ public: virtual void setTitle( const QString& ); + static void adjustLabels( QtxPagePrefItem* ); + protected: QLabel* label() const; QWidget* control() const; @@ -160,6 +167,9 @@ private slots: protected: virtual QVariant optionValue( const QString& ) const; virtual void setOptionValue( const QString&, const QVariant& ); + virtual void ensureVisible( QtxPreferenceItem* ); + + virtual void widgetShown(); private: void updateInfo(); @@ -189,6 +199,9 @@ public: virtual void updateContents(); +protected: + virtual void ensureVisible( QtxPreferenceItem* ); + private: void updateToolBox(); @@ -217,6 +230,7 @@ public: protected: virtual QVariant optionValue( const QString& ) const; virtual void setOptionValue( const QString&, const QVariant& ); + virtual void ensureVisible( QtxPreferenceItem* ); private: void updateTabs(); @@ -253,6 +267,8 @@ protected: virtual QVariant optionValue( const QString& ) const; virtual void setOptionValue( const QString&, const QVariant& ); + virtual void widgetShown(); + private: void updateFrame(); @@ -291,10 +307,14 @@ public: virtual void store(); virtual void retrieve(); + QtxGridBox* gridBox() const; + protected: virtual QVariant optionValue( const QString& ) const; virtual void setOptionValue( const QString&, const QVariant& ); + virtual void widgetShown(); + private: void updateState(); void updateGroup(); @@ -531,7 +551,7 @@ public: protected: virtual QVariant optionValue( const QString& ) const; virtual void setOptionValue( const QString&, const QVariant& ); - + private: QtxPathEdit* myPath; }; diff --git a/src/Qtx/QtxPreferenceMgr.cxx b/src/Qtx/QtxPreferenceMgr.cxx index 1b12db5e6..26ebbf2a3 100644 --- a/src/Qtx/QtxPreferenceMgr.cxx +++ b/src/Qtx/QtxPreferenceMgr.cxx @@ -1,17 +1,17 @@ // Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D -// +// // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either +// License as published by the Free Software Foundation; either // version 2.1 of the License. -// -// This library is distributed in the hope that it will be useful -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// +// This library is distributed in the hope that it will be useful +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // Lesser General Public License for more details. // -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com @@ -121,7 +121,7 @@ void QtxPreferenceItem::Updater::customEvent( QEvent* /*e*/ ) \class QtxPreferenceItem \brief Base class for implementing of all the preference items. - To implement any specific preference item, cubclass from the + To implement any specific preference item, cubclass from the QtxPreferenceItem and redefine store() and retrieve() methods. */ @@ -554,6 +554,11 @@ QtxPreferenceItem* QtxPreferenceItem::findItem( const QString& title, const int return item; } +void QtxPreferenceItem::ensureVisible() +{ + if ( parentItem() ) + parentItem()->ensureVisible( this ); +} /*! \brief Get integer resources value corresponding to the item. @@ -705,7 +710,7 @@ void QtxPreferenceItem::setFont( const QFont& val ) /*! \brief Callback function which is called when the child preference item is added. - + This function can be reimplemented in the subclasses to customize child item addition operation. Base implementation does nothing. @@ -719,7 +724,7 @@ void QtxPreferenceItem::itemAdded( QtxPreferenceItem* /*item*/ ) /*! \brief Callback function which is called when the child preference item is removed. - + This function can be reimplemented in the subclasses to customize child item removal operation. Base implementation does nothing. @@ -733,15 +738,20 @@ void QtxPreferenceItem::itemRemoved( QtxPreferenceItem* /*item*/ ) /*! \brief Callback function which is called when the child preference item is modified. - + This function can be reimplemented in the subclasses to customize child item modifying operation. Base implementation does nothing. \param item child item being modified \sa itemAdded(), itemRemoved() */ -void QtxPreferenceItem::itemChanged( QtxPreferenceItem* /*item*/ ) +void QtxPreferenceItem::itemChanged( QtxPreferenceItem* ) +{ +} + +void QtxPreferenceItem::ensureVisible( QtxPreferenceItem* ) { + ensureVisible(); } /*! @@ -757,7 +767,7 @@ void QtxPreferenceItem::triggerUpdate() This function can be reimplemented in the subclasses. Base implementation does nothing. - + \param name option name \return property value or null QVariant if option is not set \sa setOptionValue() @@ -775,7 +785,7 @@ QVariant QtxPreferenceItem::optionValue( const QString& name ) const This function can be reimplemented in the subclasses. Base implementation does nothing. - + \param name option name \param val new property value \sa optionValue() @@ -848,39 +858,6 @@ QtxPreferenceMgr* QtxPreferenceMgr::preferenceMgr() const return (QtxPreferenceMgr*)this; } -/* - \brief Add new preference item. - \param label label of widget to edit preference item - \param pId parent preference item id - \param type preference item type - \param section resource file section associated to the preference item - \param param resource file parameter associated to the preference item -*/ -/* -int QtxPreferenceMgr::addItem( const QString& label, const int pId, const int type, - const QString& section, const QString& param ) -{ - Item* i = createItem( label, type, pId ); - if ( !i ) - return -1; - - if ( !myItems.contains( i->id() ) ) - { - myItems.insert( i->id(), i ); - - i->setTitle( label ); - i->setResource( section, param ); - - if ( !i->parentItem() && !myChildren.contains( i ) ) - myChildren.append( i ); - - itemAdded( i ); - } - - return i->id(); -} -*/ - /*! \brief Get preference item option value. \param id preference item ID @@ -976,40 +953,13 @@ void QtxPreferenceMgr::fromBackup() /*! \brief Update preferences manager. - + Base implementation does nothing. */ void QtxPreferenceMgr::update() { } -/* - \brief Create preference item. - \param label preference item title - \param type preference item type - \param pId parent preference item ID - \return new item -*/ -/* -QtxPreferenceItem* QtxPreferenceMgr::createItem( const QString& label, const int type, const int pId ) -{ - Item* i = 0; - if ( pId < 0 ) - i = createItem( label, type ); - else - { - Item* pItem = item( pId ); - if ( pItem ) - { - i = pItem->createItem( label, type ); - pItem->insertChild( i ); - } - } - - return i; -} -*/ - /*! \brief Get all resources items values. \param map used as container filled with the resources values (:) @@ -1124,7 +1074,7 @@ void QtxPreferenceMgr::differentValues( const ResourceMap& map1, const ResourceM This method is called from store() and fromBackup() methods. Base implementation does nothing. - + \sa store(), fromBackup() */ void QtxPreferenceMgr::changedResources( const ResourceMap& ) diff --git a/src/Qtx/QtxPreferenceMgr.h b/src/Qtx/QtxPreferenceMgr.h index 0e193db34..1b99d84ad 100644 --- a/src/Qtx/QtxPreferenceMgr.h +++ b/src/Qtx/QtxPreferenceMgr.h @@ -1,17 +1,17 @@ // Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D -// +// // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either +// License as published by the Free Software Foundation; either // version 2.1 of the License. -// -// This library is distributed in the hope that it will be useful -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// +// This library is distributed in the hope that it will be useful +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // Lesser General Public License for more details. // -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com @@ -89,6 +89,8 @@ public: virtual QtxResourceMgr* resourceMgr() const; virtual QtxPreferenceMgr* preferenceMgr() const; + void ensureVisible(); + static int RTTI(); protected: @@ -97,19 +99,21 @@ protected: bool getBoolean( const bool = false ) const; QColor getColor( const QColor& = QColor() ) const; QFont getFont( const QFont& = QFont() ) const; - QString getString( const QString& = QString::null ) const; + QString getString( const QString& = QString() ) const; void setInteger( const int ); void setDouble( const double ); void setBoolean( const bool ); void setColor( const QColor& ); - void setFont( const QFont& ); + void setFont( const QFont& ); void setString( const QString& ); virtual void itemAdded( QtxPreferenceItem* ); virtual void itemRemoved( QtxPreferenceItem* ); virtual void itemChanged( QtxPreferenceItem* ); + virtual void ensureVisible( QtxPreferenceItem* ); + void sendItemChanges(); virtual void triggerUpdate(); @@ -163,7 +167,7 @@ protected: void setResourceValues( QMap& ) const; void setResourceValues( ResourceMap& ) const; - + void differentValues( const QMap&, const QMap&, QMap&, const bool fromFirst = false ) const; void differentValues( const ResourceMap&, const ResourceMap&, diff --git a/src/STD/STD.pro b/src/STD/STD.pro index 5d283c758..06b048327 100644 --- a/src/STD/STD.pro +++ b/src/STD/STD.pro @@ -1,4 +1,7 @@ -TEMPLATE = lib +unix:TEMPLATE = lib +win32:TEMPLATE = vclib + +win32:QMAKE_MOC=$(QTDIR)\bin\moc.exe DESTDIR = ../../$(CONFIG_ID)/lib MOC_DIR = ../../moc @@ -6,11 +9,13 @@ OBJECTS_DIR = ../../$(CONFIG_ID)/obj/$$TARGET INCLUDEPATH = ../../include LIBS += -L../../$(CONFIG_ID)/lib -lSUIT -lQtx +win32:LIBS *= -L$(QTLIB) +win32:INCLUDEPATH *= $(QTINC) $(QTINC)\QtCore $(QTINC)\QtGui $(QTINC)\QtXml CONFIG -= debug release debug_and_release CONFIG += qt thread debug dll shared -win32:DEFINES += WIN32 +win32:DEFINES += WNT WIN32 DEFINES += STD_EXPORTS HEADERS = *.h @@ -25,7 +30,7 @@ win32:GUIResources = ..\\..\\resources lrelease.name = LRELASE ${QMAKE_FILE_IN} unix:lrelease.commands = $(QTDIR)/bin/lrelease ${QMAKE_FILE_NAME} -qm $${GUIResources}/${QMAKE_FILE_BASE}.qm -win32:lrelease.commands = $(QTDIR)\\bin\\lrelease ${QMAKE_FILE_NAME} -qm $${GUIResources}\\${QMAKE_FILE_BASE}.qm +win32:lrelease.commands = $(QTDIR)\\bin\\lrelease ${QMAKE_FILE_IN} -qm $${GUIResources}\\${QMAKE_FILE_BASE}.qm unix:lrelease.output = $${GUIResources}/${QMAKE_FILE_BASE}.qm win32:lrelease.output = $${GUIResources}\\${QMAKE_FILE_BASE}.qm lrelease.input = TRANSLATIONS @@ -34,8 +39,22 @@ win32:lrelease.clean = $${GUIResources}\\${QMAKE_FILE_BASE}.qm lrelease.CONFIG += no_link target_predeps QMAKE_EXTRA_COMPILERS += lrelease +win32:copy_hdr.name = Install ${QMAKE_FILE_IN} +win32:copy_hdr.commands = type ${QMAKE_FILE_IN} > ../../include/${QMAKE_FILE_BASE}.h +win32:copy_hdr.output = ../../include/${QMAKE_FILE_BASE}.h +win32:copy_hdr.input = HEADERS +win32:QMAKE_EXTRA_COMPILERS += copy_hdr + ICONS = resources/*.png +win32:SOURCES+=$$ICONS +win32:Resource=$$ICONS +win32:copy_res.name = Install resources ${QMAKE_FILE_IN} +win32:copy_res.commands = type ${QMAKE_FILE_IN} > ${QMAKE_FILE_OUT} +win32:copy_res.output = $${GUIResources}\\${QMAKE_FILE_BASE}.png +win32:copy_res.input = Resource +win32:QMAKE_EXTRA_COMPILERS += copy_res + includes.files = $$HEADERS includes.path = ../../include diff --git a/src/SUIT/SUIT.pro b/src/SUIT/SUIT.pro index 63f66e07a..61c6078e6 100644 --- a/src/SUIT/SUIT.pro +++ b/src/SUIT/SUIT.pro @@ -1,4 +1,7 @@ -TEMPLATE = lib +unix:TEMPLATE = lib +win32:TEMPLATE = vclib + +win32:QMAKE_MOC=$(QTDIR)\bin\moc.exe DESTDIR = ../../$(CONFIG_ID)/lib MOC_DIR = ../../moc @@ -6,11 +9,13 @@ OBJECTS_DIR = ../../$(CONFIG_ID)/obj/$$TARGET INCLUDEPATH = ../../include LIBS += -L../../$(CONFIG_ID)/lib -lQtx -lObjBrowser +win32:LIBS *= -L$(QTLIB) +win32:INCLUDEPATH *= $(QTINC) $(QTINC)\QtCore $(QTINC)\QtGui $(QTINC)\QtXml CONFIG -= debug release debug_and_release CONFIG += qt thread debug dll shared -win32:DEFINES += WIN32 +win32:DEFINES += WNT WIN32 DEFINES += SUIT_EXPORTS HEADERS = *.h @@ -25,7 +30,7 @@ win32:GUIResources = ..\\..\\resources lrelease.name = LRELASE ${QMAKE_FILE_IN} unix:lrelease.commands = $(QTDIR)/bin/lrelease ${QMAKE_FILE_NAME} -qm $${GUIResources}/${QMAKE_FILE_BASE}.qm -win32:lrelease.commands = $(QTDIR)\\bin\\lrelease ${QMAKE_FILE_NAME} -qm $${GUIResources}\\${QMAKE_FILE_BASE}.qm +win32:lrelease.commands = $(QTDIR)\\bin\\lrelease ${QMAKE_FILE_IN} -qm $${GUIResources}\\${QMAKE_FILE_BASE}.qm unix:lrelease.output = $${GUIResources}/${QMAKE_FILE_BASE}.qm win32:lrelease.output = $${GUIResources}\\${QMAKE_FILE_BASE}.qm lrelease.input = TRANSLATIONS @@ -34,8 +39,22 @@ win32:lrelease.clean = $${GUIResources}\\${QMAKE_FILE_BASE}.qm lrelease.CONFIG += no_link target_predeps QMAKE_EXTRA_COMPILERS += lrelease +win32:copy_hdr.name = Install ${QMAKE_FILE_IN} +win32:copy_hdr.commands = type ${QMAKE_FILE_IN} > ../../include/${QMAKE_FILE_BASE}.h +win32:copy_hdr.output = ../../include/${QMAKE_FILE_BASE}.h +win32:copy_hdr.input = HEADERS +win32:QMAKE_EXTRA_COMPILERS += copy_hdr + ICONS = resources/*.png +win32:SOURCES+=$$ICONS +win32:Resource=$$ICONS +win32:copy_res.name = Install resources ${QMAKE_FILE_IN} +win32:copy_res.commands = type ${QMAKE_FILE_IN} > ${QMAKE_FILE_OUT} +win32:copy_res.output = $${GUIResources}\\${QMAKE_FILE_BASE}.png +win32:copy_res.input = Resource +win32:QMAKE_EXTRA_COMPILERS += copy_res + includes.files = $$HEADERS includes.path = ../../include diff --git a/src/SUIT/SUIT_DataBrowser.cxx b/src/SUIT/SUIT_DataBrowser.cxx index 32c92c013..9dd97b1fe 100644 --- a/src/SUIT/SUIT_DataBrowser.cxx +++ b/src/SUIT/SUIT_DataBrowser.cxx @@ -107,13 +107,15 @@ bool SUIT_DataBrowser::autoUpdate() const automatically when data tree is changed. \param on 'auto-update tree' flag value + \param updateImmediately if \c true, the tree is updated immediately; + otherwise the tree must be updated manually \sa autoUpdate(), updateTree() */ -void SUIT_DataBrowser::setAutoUpdate( const bool on ) +void SUIT_DataBrowser::setAutoUpdate( const bool on, const bool updateImmediately ) { SUIT_ProxyModel* m = qobject_cast( model() ); if ( m ) - m->setAutoUpdate( on ); + m->setAutoUpdate( on, updateImmediately ); } /*! diff --git a/src/SUIT/SUIT_DataBrowser.h b/src/SUIT/SUIT_DataBrowser.h index 25794a685..6cb2b00d4 100644 --- a/src/SUIT/SUIT_DataBrowser.h +++ b/src/SUIT/SUIT_DataBrowser.h @@ -45,7 +45,7 @@ public: void setRoot( SUIT_DataObject* ); bool autoUpdate() const; - void setAutoUpdate( const bool ); + void setAutoUpdate( const bool, const bool = true ); void updateTree( SUIT_DataObject* = 0, const bool = true ); diff --git a/src/SUIT/SUIT_FileDlg.cxx b/src/SUIT/SUIT_FileDlg.cxx index 7d169045c..6d5a1f002 100755 --- a/src/SUIT/SUIT_FileDlg.cxx +++ b/src/SUIT/SUIT_FileDlg.cxx @@ -16,50 +16,58 @@ // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // +// File : SUIT_FileDlg.cxx +// Author : Vadim SANDLER, Open CASCADE S.A.S. (vadim.sandler@opencascade.com) +// /*! - SUIT_FileDlg class is the extension of the Qt's Open/Save file dialog box. - To get the file/directory name(s) call static methods: - - to invoke "Open file" or "Save file" dialog box - static QString getFileName(QWidget* parent, const QString& initial, const QStringList& filters, - const QString& caption, const bool open, const bool showQuickDir = true, - SUIT_FileValidator* validator = 0); - - to invoke "Open files" dialog box (to get the multiple file selection) - static QStringList getOpenFileNames(QWidget* parent, const QString& initial, const QStringList& filters, - const QString& caption, bool showQuickDir = true, - SUIT_FileValidator* validator = 0); - - to invoke "Select directory" dialog box - static QString getExistingDirectory(QWidget* parent, const QString& initial, - const QString& caption, const bool showQuickDir = true); - - The parameters: - - parent parent widget (if 0, the current desktop is used) - - initial starting directory or file name (if null, last visited directory is used) - - filters file filters list; patterns inside the filter can be separated by ';','|' or ' ' - symbols - - caption dialog box's caption: if null, the default one is used - - open open flag - true for "Open File" and false for "Save File" dialog box - - showQuickDir this flag enables/disables "Quick directory list" controls - - validator you can provide custom file validator with this parameter - - Examples: - ... - QStringList flist; - flist.append( "Image files (*.bmp *.gif *.jpg )" ); - flist.append( "All files (*.*)" ); - QMyFileValidator* v = new QMyFileValidator( 0 ); - QString fileName = SUIT_FileDlg::getFileName( 0, QString::null, flist, "Dump view", false, true, v ); - if ( !fileName.isEmpty() ) { - ... writing image to the file - } - ... - QStringList flist; - flist.append( "*.cpp | *.cxx | *.c++" ); - flist.append( "*.h | *.hpp | *.hxx" ); - QString fileName = SUIT_FileDlg::getFileName( desktop(), QString::null, flist, QString::null, true, true ); + \class SUIT_FileDlg + \brief An extension of the Qt Open/Save file dialog box. + + The class SUIT_FileDlg provides a set of static methods which canbe used + for file or directories selection: + - getFileName() for single file opening or saving + - getOpenFileNames() for mulktiple files opening + - getExistingDirectory() for existing directory selection + + Examples: + \code + // select file to dump contents of the view + QStringList filters; + filters << "Image files (*.bmp *.gif *.jpg )" << "All files (*)"; + QString fileName = SUIT_FileDlg::getFileName( desktop(), + QString(), + filters, + "Dump view", + false ); + if ( !fileName.isEmpty() ) { + ... writing image to the file + } + + // select list of files to open in the editor windows + QStringList filters; + filters << "*.cpp | *.cxx | *.c++" << "*.h | *.hpp | *.hxx"; + QStringList fileNames = SUIT_FileDlg::getOpenFileName( desktop(), + QString(), + filters, + QString() ); + if ( !fileNames.isEmpty() ) { + ... open files + } + \endcode + + The class SUIT_FileDlg can be subclassed to implement custom file + dialog boxes. The class provides a set of methods which can be used + in subclasses: + - setCheckPermissions() - to enable/disable check of files/directories + permissions + - setValidator() - to use custom file validator + - addWidgets() - to add custom widgets to the lower part of the + dialog box + - getLastVisitedDirectory() - to get last visited directory + - acceptData() - can be used ti customize user selection validation + + \sa SUIT_FileValidator class. */ #include "SUIT_FileDlg.h" @@ -78,155 +86,147 @@ #include #include #include +#include +#include -#define MIN_COMBO_SIZE 100 +/*! + \brief Defines extension behavior. -/*! If the selected file name has extension which does not match the selected filter - * this extension is ignored (and new one will be added). See below for details. - */ + If the selected file name has extension which does not match the selected filter + and this variable is set to \c true, the file extension is ignored and new one + (from current file filter will be added. + \sa addExtension() +*/ const bool IGNORE_NON_MATCHING_EXTENSION = true; QString SUIT_FileDlg::myLastVisitedPath; -/*! Constructor */ +/*! + \brief Constructor. + \param parent parent widget + \param open if \c true dialog box is used for file opening, otherwise - for saving + \param showQuickDir if \c true the quick directory list widgets will be shown + \param modal if \c true the dialog box will be modal +*/ SUIT_FileDlg::SUIT_FileDlg( QWidget* parent, bool open, bool showQuickDir, bool modal ) : QFileDialog( parent ), -myOpen( open ), -myValidator( 0 ), -myQuickLab( 0 ), -myQuickCombo( 0 ), -myQuickButton( 0 )//, -//myAccepted( false ) + myValidator( 0 ), + myQuickLab( 0 ), + myQuickCombo( 0 ), + myQuickButton( 0 ), + myCheckPermissions( true ) { setModal( modal ); - - const QObjectList& child = children(); - for ( QObjectList::const_iterator anIt = child.begin(); anIt != child.end(); ++anIt ) - { - QPushButton* pb = ::qobject_cast( *anIt ); - if ( pb ) - { - pb->setDefault( false ); - pb->setAutoDefault( false ); - } - } - + setSizeGripEnabled( true ); if ( parent ) setWindowIcon( parent->windowIcon() ); - setSizeGripEnabled( true ); - - QGridLayout* grid = ::qobject_cast( layout() ); - if ( showQuickDir && grid ) - { - // inserting quick dir combo box - myQuickLab = new QLabel( tr( "LAB_QUICK_PATH" ), this ); - myQuickCombo = new QComboBox( this ); - myQuickCombo->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) ); - myQuickCombo->setMinimumSize( MIN_COMBO_SIZE, 0 ); - - myQuickButton = new QPushButton( tr( "BUT_ADD_PATH" ), this ); - connect( myQuickCombo, SIGNAL( activated( const QString& ) ), this, SLOT( quickDir( const QString& ) ) ); - connect( myQuickButton, SIGNAL( clicked() ), this, SLOT( addQuickDir() ) ); + // add quick directories widgets + if ( showQuickDir ) { + myQuickLab = new QLabel( tr( "LAB_QUICK_PATH" ), this ); + myQuickCombo = new QComboBox( this ); + myQuickButton = new QPushButton( tr( "BUT_ADD_PATH" ), this ); + + if ( addWidgets( myQuickLab, myQuickCombo, myQuickButton ) ) { + connect( myQuickCombo, SIGNAL( activated( const QString& ) ), this, SLOT( quickDir( const QString& ) ) ); + connect( myQuickButton, SIGNAL( clicked() ), this, SLOT( addQuickDir() ) ); - int row = grid->rowCount(); - grid->addWidget( myQuickLab, row, 0 ); - grid->addWidget( myQuickCombo, row, 1, 1, 3 ); - grid->addWidget( myQuickButton, row, 5 ); + // retrieve directories list from the resources + QStringList dirList; + + SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr(); + if ( resMgr ) + dirList = resMgr->stringValue( "FileDlg", QString( "QuickDirList" ) ).split( ';', QString::SkipEmptyParts ); - // getting dir list from settings - QString dirs; - SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr(); - if ( resMgr ) - dirs = resMgr->stringValue( "FileDlg", QString( "QuickDirList" ) ); + if ( dirList.isEmpty() ) + dirList << QDir::homePath(); - QStringList dirList = dirs.split( ';' ); - if ( dirList.count() > 0 ) - { for ( int i = 0; i < dirList.count(); i++ ) - myQuickCombo->addItem( dirList[i] ); + myQuickCombo->addItem( dirList[i] ); + } + else { + delete myQuickLab; myQuickLab = 0; + delete myQuickCombo; myQuickCombo = 0; + delete myQuickButton; myQuickButton = 0; } - else - myQuickCombo->addItem( QDir::homePath() ); } - setAcceptMode( myOpen ? AcceptOpen: AcceptSave ); - setWindowTitle( myOpen ? tr( "INF_DESK_DOC_OPEN" ) : tr( "INF_DESK_DOC_SAVE" ) ); + + setAcceptMode( open ? AcceptOpen: AcceptSave ); + setWindowTitle( open ? tr( "INF_DESK_DOC_OPEN" ) : tr( "INF_DESK_DOC_SAVE" ) ); // If last visited path doesn't exist -> switch to the first preferred path - if ( !myLastVisitedPath.isEmpty() ) - { + if ( !myLastVisitedPath.isEmpty() ) { if ( !processPath( myLastVisitedPath ) && showQuickDir ) processPath( myQuickCombo->itemText( 0 ) ); } - else - { - if ( showQuickDir ) - processPath( myQuickCombo->itemText( 0 ) ); + else if ( showQuickDir ) { + processPath( myQuickCombo->itemText( 0 ) ); } // set default file validator - myValidator = new SUIT_FileValidator(this); + myValidator = new SUIT_FileValidator( this ); } -/*! Destructor*/ +/*! + \brief Destructor. +*/ SUIT_FileDlg::~SUIT_FileDlg() { setValidator( 0 ); } -bool SUIT_FileDlg::event( QEvent* e ) -{ - bool res = QFileDialog::event( e ); - if ( e->type() == QEvent::Polish ) - polish(); +/*! + \brief Check if the dialog box is used for opening or saving the file. + \return \c true if dialog is used for file opening and \c false otherwise +*/ +bool SUIT_FileDlg::isOpenDlg() const +{ + return acceptMode() == AcceptOpen; +} - return res; +/*! + \brief Get 'check file permissions' flag. + \return flag value + \sa setCheckPermissions() +*/ +bool SUIT_FileDlg::checkPermissions() const +{ + return myCheckPermissions; } -/*! Redefined from QFileDialog.*/ -void SUIT_FileDlg::polish() +/*! + \brief Set 'check file permissions' flag. + + If this flag is set and file validator is not null, + the validator will check the file permissions also. + + \param checkPerm new flag value + \sa checkPermissions() +*/ +void SUIT_FileDlg::setCheckPermissions( const bool checkPerm ) { -/* - if ( myQuickButton && myQuickLab ) - { - // the following is a workaround for proper layouting of custom widgets - QValueList buttonList; - QValueList labelList; - const QObjectList *list = children(); - QObjectListIt it(*list); - int maxButWidth = myQuickLab->sizeHint().width(); - int maxLabWidth = myQuickButton->sizeHint().width(); - - for (; it.current() ; ++it) { - if ( it.current()->isA( "QLabel" ) ) { - int tempW = ((QLabel*)it.current())->minimumWidth(); - if ( maxLabWidth < tempW ) maxLabWidth = tempW; - labelList.append( (QLabel*)it.current() ); - } - else if( it.current()->isA("QPushButton") ) { - int tempW = ((QPushButton*)it.current())->minimumWidth(); - if ( maxButWidth < tempW ) maxButWidth = tempW; - buttonList.append( (QPushButton*)it.current() ); - } - } - if (maxButWidth > 0) { - QValueList::Iterator bListIt; - for ( bListIt = buttonList.begin(); bListIt != buttonList.end(); ++bListIt ) - (*bListIt)->setFixedWidth( maxButWidth ); - } - if (maxLabWidth > 0) { - QValueList::Iterator lListIt; - for ( lListIt = labelList.begin(); lListIt != labelList.end(); ++lListIt ) - (*lListIt)->setFixedWidth( maxLabWidth ); - } - } + myCheckPermissions = checkPerm; +} + +/*! + \brief Get file validator. + \return current file validator + \sa setValidator() */ +SUIT_FileValidator* SUIT_FileDlg::validator() const +{ + return myValidator; } -/*! Sets validator for file names to open/save - * Deletes previous validator if the dialog owns it. - */ +/*! + \brief Set file validator. + + Destroys previous validator if the dialog owns it. + + \param v new file validator + \sa validator() +*/ void SUIT_FileDlg::setValidator( SUIT_FileValidator* v ) { if ( myValidator && myValidator->parent() == this ) @@ -234,117 +234,267 @@ void SUIT_FileDlg::setValidator( SUIT_FileValidator* v ) myValidator = v; } -/*! Returns the selected file */ +/*! + \brief Adds the specified widgets to the bottom of the file dialog. + + The first widget (usually label) \a l is placed underneath the "file name" + and the "file types" labels. + The widget \a w is placed underneath the file types combobox. + The last widget (usually button) \a b is placed underneath the Cancel push button. + + In general, the widgets can be arbitrary. This method is added to support + the functionality provided by the Qt series 3.x. + + If you don't want to have one of the widgets added, pass 0 in that widget's position. + Every time this function is called, a new row of widgets is added to the bottom of the + file dialog. + + \param l first widget (e.g. text label) + \param w second widget (e.g. combo box) + \param b third widget (e.g. push button) + \return \c true if widgets have been added successfully +*/ +bool SUIT_FileDlg::addWidgets( QWidget* l, QWidget* w, QWidget* b ) +{ + QGridLayout* grid = ::qobject_cast( layout() ); + if ( grid ) { + int row = grid->rowCount(); + int columns = grid->columnCount(); + if ( l ) + grid->addWidget( l, row, 0 ); + if ( w ) +#if QT_VERSION < 0x040303 + grid->addWidget( w, row, 1, 1, columns-3 ); +#else + grid->addWidget( w, row, 1, 1, columns-2 ); +#endif + if ( b ) + grid->addWidget( b, row, columns-1 ); + return true; + } + return false; +} + +/*! + \brief Get list of selected files. + \return selected file names +*/ +QStringList SUIT_FileDlg::selectedFiles() const +{ + QStringList files = QFileDialog::selectedFiles(); + if ( fileMode() != DirectoryOnly && fileMode() != Directory ) { + QMutableListIterator it( files ); + while ( it.hasNext() ) { + QString f = it.next(); + QFileInfo finfo( f ); + if ( !finfo.isDir() ) + it.setValue( addExtension( f ) ); + } + } + return files; +} + +/*! + \brief Get selected file. + \return selected file name or null string if file is not selected +*/ QString SUIT_FileDlg::selectedFile() const { - return mySelectedFile; + QStringList files = selectedFiles(); + return files.count() > 0 ? files[0] : QString(); } -/*! Returns 'true' if this is 'Open File' dialog - * and 'false' if 'Save File' dialog - */ -bool SUIT_FileDlg::isOpenDlg() const +/*! + \brief Get last visited directory. + + Note, that last visited path is memorized only if the + dialog box is accepted. + + \return last visited directory +*/ +QString SUIT_FileDlg::getLastVisitedDirectory() { - return myOpen; + return myLastVisitedPath; } -/*! Closes this dialog and sets the return code to 'Accepted' - * if the selected name is valid ( see 'acceptData()' ) - */ -void SUIT_FileDlg::accept() +/*! + \brief Customize events processing. + \param e event + \return \c true if the event e was recognized and processed +*/ +bool SUIT_FileDlg::event( QEvent* e ) { - /* myAccepted - * flag is used to warkaround the Qt 2.2.2 BUG: - * accept() method is called twice if user presses 'Enter' key - * in file name editor while file name is not acceptable by acceptData() - * (e.g. permission denied) - */ -// if ( !myAccepted ) { - if ( acceptMode() != AcceptOpen ) - { - QString fn; - QStringList lst = QFileDialog::selectedFiles(); - if ( !lst.isEmpty() ) - fn = lst.first(); - mySelectedFile = fn; - addExtension(); - } + bool res = QFileDialog::event( e ); - if ( acceptData() ) - { - // NDS: needs to fill string mySelected file - QString fn; - QStringList lst = QFileDialog::selectedFiles(); - if ( !lst.isEmpty() ) - fn = lst.first(); - mySelectedFile = fn; - // end NDS - myLastVisitedPath = directory().path(); - QFileDialog::accept(); -// myAccepted = true; - } -// } -// myAccepted = !myAccepted; + if ( e->type() == QEvent::Polish ) + polish(); + + return res; } -/*! Closes this dialog and sets the return code to 'Rejected' */ -void SUIT_FileDlg::reject() +/*! + \brief Get line edit which is used to enter file name. + \return line edit widget or0 if it could not be found +*/ +QLineEdit* SUIT_FileDlg::lineEdit() const { - mySelectedFile = QString::null; - QFileDialog::reject(); + QLineEdit* ebox = 0; + QList editBoxes = findChildren(); + QGridLayout* grid = ::qobject_cast( layout() ); + if ( grid ) { + int idx = 10000; + for ( int i = 0; i < editBoxes.count(); i++ ) { + int widx = grid->indexOf( editBoxes[ i ] ); + if ( widx >= 0 ) + idx = qMin( idx, widx ); + } + if ( grid->itemAt( idx ) ) + ebox = qobject_cast( grid->itemAt( idx )->widget() ); + } + return ebox; } -/*! Returns 'true' if selected file is valid. - * The validity is checked by a file validator, - * if there is no validator the file is always - * considered as valid - */ +/*! + \brief Validate user selection. + + The validation is done by calling the corresponding methods + of the validator. If the validator is not set, this method + always returns \c true. + + This method can be re-implemented in the subclasses to customize + the file dialog behavior. + Another solution could be implementing own file validator class. + + \return \c true if user selection (file(s) or directory) is valid + \sa SUIT_FileValidator class, validator(), setValidator() +*/ bool SUIT_FileDlg::acceptData() { - if ( myValidator ) - { - if ( isOpenDlg() ) + QStringList files = selectedFiles(); + if ( files.isEmpty() ) + return false; + + // special case for ".." + if ( lineEdit() ) { + QString txt = lineEdit()->text(); + if ( txt == ".." ) { + QDir dir = directory(); + if ( dir.cdUp() ) { + setDirectory( dir ); + bool block = lineEdit()->blockSignals( true ); + lineEdit()->setText( ".." ); + lineEdit()->selectAll(); + lineEdit()->setFocus( Qt::OtherFocusReason ); + lineEdit()->blockSignals( block ); + return false; + } + } + else if ( fileMode() != DirectoryOnly ) { + QStringList fs = txt.split( " ", QString::SkipEmptyParts ); + for ( int i = 0; i < fs.count(); i++ ) { + QString wc = fs.at( i ); + if ( wc.startsWith( "\"" ) && wc.endsWith( "\"" ) ) + wc = wc.mid( 1, wc.length()-2 ); + if ( hasWildCards( wc ) ) { + addFilter( wc ); + lineEdit()->clear(); + return false; + } + } + } + } + + // special case for wildcards + for ( int i = 0; i < files.count(); ++i ) { + } + + bool bOk = true; + + switch ( fileMode() ) { + case DirectoryOnly: + case Directory: { - if ( acceptMode() == AcceptOpen ) - { - QStringList fileNames = selectedFiles(); - for ( int i = 0; i < (int)fileNames.count(); i++ ) - { - if ( !myValidator->canOpen( fileNames[i] ) ) - return false; - } - return true; + QString fn = files.first(); + if ( validator() ) { + bOk = isOpenDlg() ? validator()->canReadDir( fn, checkPermissions() ) : + validator()->canWriteDir( fn, checkPermissions() ); } - else - { - return myValidator->canOpen( selectedFile() ); + break; + } + case AnyFile: + { + QString fn = files.first(); + QFileInfo info( fn ); + if ( info.isDir() ) { + setDirectory( info.absoluteFilePath() ); + if ( lineEdit() ) { + lineEdit()->selectAll(); + lineEdit()->setFocus( Qt::OtherFocusReason ); + } + return false; + } + // validation is not required + if ( validator() ) { + bOk = isOpenDlg() ? validator()->canOpen( fn, checkPermissions() ) : + validator()->canSave( fn, checkPermissions() ); } + break; + } + case ExistingFile: + case ExistingFiles: + { + for ( int i = 0; i < files.count(); ++i ) { + QFileInfo info( files.at( i ) ); + if ( info.isDir() ) { + setDirectory( info.absoluteFilePath() ); + if ( lineEdit() ) { + lineEdit()->selectAll(); + lineEdit()->setFocus( Qt::OtherFocusReason ); + } + return false; + } + if ( validator() ) { + bOk = isOpenDlg() ? validator()->canOpen( files.at( i ), checkPermissions() ) : + validator()->canSave( files.at( i ), checkPermissions() ); + if ( !bOk ) + return false; + } + } + break; } - else - return myValidator->canSave( selectedFile() ); } - return true; + + if ( bOk ) + emit filesSelected( files ); + + return bOk; } -/*! Adds an extension to the selected file name - * if the file has not it. - * The extension is extracted from the active filter. - */ -void SUIT_FileDlg::addExtension() +/*! + \brief Add an extension to the specified file name. + + The extension is extracted from the active filter. + + \param fileName file name to be processed + \return fileName with the extension added +*/ +QString SUIT_FileDlg::addExtension( const QString& fileName ) const { + QString fname = fileName.trimmed(); + // check if file name entered is empty - if ( mySelectedFile.trimmed().isEmpty() ) - return; + if ( fname.isEmpty() ) + return fileName; // current file extension - QString anExt = "." + SUIT_Tools::extension( mySelectedFile.trimmed() ).trimmed(); + QString anExt = "." + SUIT_Tools::extension( fname ).trimmed(); // If the file already has extension and it does not match the filter there are two choices: // - to leave it 'as is' // - to ignore it // The behavior is defined by IGNORE_NON_MATCHING_EXTENSION constant if ( anExt != "." && !IGNORE_NON_MATCHING_EXTENSION ) - return; + return fileName; QRegExp r( QString::fromLatin1("\\(?[a-zA-Z0-9.*? +;#|]*\\)?$") ); int index = r.indexIn( selectedFilter().trimmed() ); @@ -365,8 +515,7 @@ void SUIT_FileDlg::addExtension() // now we get the list of all extension masks and remove all which does not contain wildcard symbols QStringList extList = aPattern.split( "|", QString::SkipEmptyParts ); - for ( int i = extList.count() - 1; i >= 0; i-- ) - { + for ( int i = extList.count() - 1; i >= 0; i-- ) { if ( !extList[i].contains( "." ) ) extList.removeAt( i ); } @@ -376,129 +525,234 @@ void SUIT_FileDlg::addExtension() QRegExp anExtRExp( "^("+ aPattern + ")$" ); // Check if the current file extension matches the pattern - if ( !anExtRExp.exactMatch( anExt ) ) - { + if ( !anExtRExp.exactMatch( anExt ) ) { // find first appropriate extension in the selected filter // (it should be without wildcard symbols) - for ( int i = 0; i < (int)extList.count(); i++ ) - { + for ( int i = 0; i < extList.count(); i++ ) { QString newExt = extList[i].replace( QRegExp( "[\\\\][+]" ),"+" ); int res = newExt.lastIndexOf( '.' ); if ( res >= 0 ) newExt = newExt.mid( res + 1 ); - if ( newExt.indexOf( QRegExp("[*|?]" ) ) < 0 ) - { - mySelectedFile.trimmed(); - mySelectedFile += mySelectedFile.endsWith(".") ? newExt : QString(".") + newExt; - break; + if ( newExt.indexOf( QRegExp("[*|?]" ) ) < 0 ) { + fname += fname.endsWith( "." ) ? newExt : QString( "." ) + newExt; + return fname; } } } } + return fileName; } -/*! Processes selection : tries to set given path or filename as selection */ +/*! + \brief Processes selection : tries to set specified sirectory or filename + as current file dialog selection. + \param path file or directory path + \return \c true if \a path is processed correctly and \c false otherwise +*/ bool SUIT_FileDlg::processPath( const QString& path ) { - if ( !path.isNull() ) - { + if ( !path.isNull() ) { QFileInfo fi( path ); - if ( fi.exists() ) - { + if ( fi.exists() ) { if ( fi.isFile() ) - selectFile( path ); + selectFile( path ); else if ( fi.isDir() ) - setDirectory( path ); + setDirectory( path ); return true; } - else - { - if ( QFileInfo( SUIT_Tools::dir( path ) ).exists() ) - { - setDirectory( SUIT_Tools::dir( path ) ); - selectFile( path ); - return true; - } + else if ( QFileInfo( SUIT_Tools::dir( path ) ).exists() ) { + setDirectory( SUIT_Tools::dir( path ) ); + selectFile( path ); + return true; } } return false; } -/*! Called when user selects item from "Quick Dir" combo box */ -void SUIT_FileDlg::quickDir(const QString& dirPath) + +/*! + \brief Add file filter and activates it. + \param filter new file filter +*/ +void SUIT_FileDlg::addFilter( const QString& filter ) { - QString aPath = dirPath; - if ( !QDir(aPath).exists() ) - { - aPath = QDir::homePath(); - SUIT_MessageBox::critical( this, tr( "ERR_ERROR" ), tr( "ERR_DIR_NOT_EXIST" ).arg( dirPath ) ); + QStringList flist = filters(); + if ( !flist.contains( filter ) ) { + flist << filter; + setFilters( flist ); } + selectFilter( filter ); +} + +/*! + \brief Check if the string contains wildcard symbols. + \param s string to be checked (for example, file name) + \return \c true if string contains "*" or "?" symbols +*/ +bool SUIT_FileDlg::hasWildCards( const QString& s ) +{ + return s.contains( QRegExp("[*|?]") ); +} + +/*! + \brief Called when the user presses "Open"or "Save" button. + + Verifies the user choice and closes dialog box, setting the return code to QDialog::Accepted + + \sa acceptData() +*/ +void SUIT_FileDlg::accept() +{ + if ( acceptData() ) { + myLastVisitedPath = directory().path(); + QDialog::accept(); + } +} + +/*! + \brief Called when user selects directory from the "Quick Dir" combo box. + + Browses the file dialog to the specified directory (if it is valid). + + \param dirPath selected directory +*/ +void SUIT_FileDlg::quickDir( const QString& dirPath ) +{ + if ( !QDir( dirPath ).exists() ) + SUIT_MessageBox::critical( this, tr( "ERR_ERROR" ), tr( "ERR_DIR_NOT_EXIST" ).arg( dirPath ) ); else - processPath( aPath ); + processPath( dirPath ); } + /*! - Called when user presses "Add" button - adds current directory to quick directory - list and to the preferences + \brief Called when user presses "Quick Dir Add" button. + + Adds current directory to the quick directories list and to the preferences. */ void SUIT_FileDlg::addQuickDir() { QString dp = directory().path(); - if ( !dp.isEmpty() ) - { + if ( !dp.isEmpty() ) { QDir dir( dp ); - // getting dir list from settings - QString dirs; + + QStringList dirList; + SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr(); if ( resMgr ) - dirs = resMgr->stringValue( "FileDlg", QString( "QuickDirList" ) ); - QStringList dirList = dirs.split( ';', QString::SkipEmptyParts ); + dirList = resMgr->stringValue( "FileDlg", QString( "QuickDirList" ) ).split( ';', QString::SkipEmptyParts ); + bool found = false; bool emptyAndHome = false; - if ( dirList.count() > 0 ) - { - for ( int i = 0; i < dirList.count(); i++ ) - { - QDir aDir( dirList[i] ); - if ( aDir.canonicalPath().isNull() && dirList[i] == dir.absolutePath() || - !aDir.canonicalPath().isNull() && aDir.exists() && aDir.canonicalPath() == dir.canonicalPath() ) - { - found = true; - break; - } + if ( dirList.count() > 0 ) { + for ( int i = 0; i < dirList.count() && !found; i++ ) { + QDir aDir( dirList[i] ); + if ( aDir.canonicalPath().isNull() && dirList[i] == dir.absolutePath() || + !aDir.canonicalPath().isNull() && aDir.exists() && + aDir.canonicalPath() == dir.canonicalPath() ) { + found = true; + } } } - else + else { emptyAndHome = dir.canonicalPath() == QDir( QDir::homePath() ).canonicalPath(); + } - if ( !found ) - { + if ( !found ) { dirList.append( dp ); resMgr->setValue( "FileDlg", QString( "QuickDirList" ), dirList.join( ";" ) ); if ( !emptyAndHome ) - myQuickCombo->addItem( dp ); + myQuickCombo->addItem( dp ); } } } + /*! - Returns the file name for Open/Save [ static ] + \brief Polish the dialog box. +*/ +void SUIT_FileDlg::polish() +{ + QList buttons = findChildren(); + + int maxBtnWidth = 0; + + for ( QList::const_iterator it = buttons.begin(); + it != buttons.end(); ++it ) + maxBtnWidth = qMax( maxBtnWidth, (*it)->sizeHint().width() ); + + for ( QList::const_iterator it = buttons.begin(); + it != buttons.end(); ++it ) { + (*it)->setDefault( false ); + (*it)->setAutoDefault( false ); + (*it)->setFixedWidth( maxBtnWidth ); + } + + QList views = findChildren(); + for ( QList::const_iterator it = views.begin(); + it != views.end(); ++it ) { + (*it)->setViewMode( QListView::ListMode ); + } +} + +/*! + \brief Show dialog box for the file opening/saving. + + This method can be used to select the file for opening + or saving. The behavior is defined by the \a open parameter. + Note, that selection validation depends on the dialog mode used. + + If \a initial parameter is not null string it is used as starting directory + or file at which dialog box is opened. + + The parameter \a filters defines file filters (wildcards) to be used. + If filters list is empty, "All files (*)" is used by default. + + The parameter \a caption is used as dialog box title. If it is + is empty, the default title is used. + + The parameter \a showQuickDir specifies if it is necessary to + show additional quick directories list controls in the bottom part + of the dialog box. + + The validation of the user selection is done with help of the file + validator (SUIT_FileValidator class). The last parameter \a validator + can be used to pass the custom file validator to the dialog box. + + \param parent parent widget + \param initial initial file (or directory) dialog box to be opened on + \param filters file filters list + \param caption dialog box title + \param open if \c true dialog box is used for file opening, otherwise - for saving + \param showQuickDir if \c true the quick directory list widgets will be shown + \param validator custom file validator + \return selected file name or null string if dialog box is cancelled + \sa getOpenFileNames(), getExistingDirectory() */ -QString SUIT_FileDlg::getFileName( QWidget* parent, const QString& initial, const QStringList& filters, - const QString& caption, bool open, bool showQuickDir, +QString SUIT_FileDlg::getFileName( QWidget* parent, const QString& initial, + const QStringList& filters, const QString& caption, + const bool open, const bool showQuickDir, SUIT_FileValidator* validator ) { - SUIT_FileDlg* fd = new SUIT_FileDlg( parent, open, showQuickDir, true ); + SUIT_FileDlg fd( parent, open, showQuickDir, true ); + + fd.setFileMode( open ? ExistingFile : AnyFile ); + + if ( filters.isEmpty() ) + fd.setFilter( tr( "ALL_FILES_FILTER" ) ); // All files (*) + else + fd.setFilters( filters ); + if ( !caption.isEmpty() ) - fd->setWindowTitle( caption ); + fd.setWindowTitle( caption ); + if ( !initial.isEmpty() ) - fd->processPath( initial ); // VSR 24/03/03 check for existing of directory has been added to avoid QFileDialog's bug + fd.processPath( initial ); - fd->setFilters( filters ); if ( validator ) - fd->setValidator( validator ); + fd.setValidator( validator ); - fd->exec(); + QString filename; - QString filename = fd->selectedFile(); - delete fd; + if ( fd.exec() == QDialog::Accepted ) + filename = fd.selectedFile(); QApplication::processEvents(); @@ -506,54 +760,213 @@ QString SUIT_FileDlg::getFileName( QWidget* parent, const QString& initial, cons } /*! - Returns the list of files to be opened [ static ] + \brief Show dialog box for the file opening/saving. + \overload + + This method can be used to select the file for opening + or saving. The behavior is defined by the \a open parameter. + Note, that selection validation depends on the dialog mode used. + + If \a initial parameter is not null string it is used as starting directory + or file at which dialog box is opened. + + The parameter \a filters defines file filters (wildcards) to be used. + This is the list of wildcards, separated by the ";;" symbols. + If filters list is empty, "All files (*)" is used by default. + + The parameter \a caption is used as dialog box title. If it is + is empty, the default title is used. + + The parameter \a showQuickDir specifies if it is necessary to + show additional quick directories list controls in the bottom part + of the dialog box. + + The validation of the user selection is done with help of the file + validator (SUIT_FileValidator class). The last parameter \a validator + can be used to pass the custom file validator to the dialog box. + + \param parent parent widget + \param initial initial file (or directory) dialog box to be opened on + \param filters file filters separated by ";;" + \param caption dialog box title + \param open if \c true dialog box is used for file opening, otherwise - for saving + \param showQuickDir if \c true the quick directory list widgets will be shown + \param validator custom file validator + \return selected file name or null string if dialog box is cancelled + \sa getOpenFileNames(), getExistingDirectory() +*/ +QString SUIT_FileDlg::getFileName( QWidget* parent, const QString& initial, + const QString& filters, const QString& caption, + const bool open, const bool showQuickDir, + SUIT_FileValidator* validator ) +{ + return getFileName( parent, initial, filters.split( ";;", QString::SkipEmptyParts ), + caption, open, showQuickDir, validator ); +} + +/*! + \brief Show dialog box for the multiple files selection. + + If \a initial parameter is not null string it is used as starting directory + or file at which dialog box is opened. + + The parameter \a filters defines file filters (wildcards) to be used. + If filters list is empty, "All files (*)" is used by default. + + The parameter \a caption is used as dialog box title. If it is + is empty, the default title is used. + + The parameter \a showQuickDir specifies if it is necessary to + show additional quick directories list controls in the bottom part + of the dialog box. + + The validation of the user selection is done with help of the file + validator (SUIT_FileValidator class). The last parameter \a validator + can be used to pass the custom file validator to the dialog box. + + \param parent parent widget + \param initial initial file (or directory) dialog box to be opened on + \param filters file filters list + \param caption dialog box title + \param showQuickDir if \c true the quick directory list widgets will be shown + \param validator custom file validator + \return selected file names or empty list if dialog box is cancelled + \sa getFileName(), getExistingDirectory() */ -QStringList SUIT_FileDlg::getOpenFileNames( QWidget* parent, const QString& initial, const QStringList& filters, - const QString& caption, bool showQuickDir, SUIT_FileValidator* validator ) +QStringList SUIT_FileDlg::getOpenFileNames( QWidget* parent, const QString& initial, + const QStringList& filters, const QString& caption, + const bool showQuickDir, + SUIT_FileValidator* validator ) { - SUIT_FileDlg* fd = new SUIT_FileDlg( parent, true, showQuickDir, true ); - fd->setFileMode( ExistingFiles ); + SUIT_FileDlg fd( parent, true, showQuickDir, true ); + + fd.setFileMode( ExistingFiles ); + + if ( filters.isEmpty() ) + fd.setFilter( tr( "ALL_FILES_FILTER" ) ); // All files (*) + else + fd.setFilters( filters ); + if ( !caption.isEmpty() ) - fd->setWindowTitle( caption ); + fd.setWindowTitle( caption ); + if ( !initial.isEmpty() ) - fd->processPath( initial ); // VSR 24/03/03 check for existing of directory has been added to avoid QFileDialog's bug + fd.processPath( initial ); - fd->setFilters( filters ); if ( validator ) - fd->setValidator( validator ); + fd.setValidator( validator ); + + QStringList filenames; - fd->exec(); - QStringList filenames = fd->selectedFiles(); - delete fd; + if ( fd.exec() == QDialog::Accepted ) + filenames = fd.selectedFiles(); QApplication::processEvents(); + return filenames; } /*! - Existing directory selection dialog [ static ] + \brief Show dialog box for the multiple file opening. + \overload + + If \a initial parameter is not null string it is used as starting directory + or file at which dialog box is opened. + + The parameter \a filters defines file filters (wildcards) to be used. + This is the list of wildcards, separated by the ";;" symbols. + If filters list is empty, "All files (*)" is used by default. + + The parameter \a caption is used as dialog box title. If it is + is empty, the default title is used. + + The parameter \a showQuickDir specifies if it is necessary to + show additional quick directories list controls in the bottom part + of the dialog box. + + The validation of the user selection is done with help of the file + validator (SUIT_FileValidator class). The last parameter \a validator + can be used to pass the custom file validator to the dialog box. + + \param parent parent widget + \param initial initial file (or directory) dialog box to be opened on + \param filters file filters separated by ";;" + \param caption dialog box title + \param showQuickDir if \c true the quick directory list widgets will be shown + \param validator custom file validator + \return selected file names or empty list if dialog box is cancelled + \sa getFileName(), getExistingDirectory() +*/ +QStringList SUIT_FileDlg::getOpenFileNames( QWidget* parent, const QString& initial, + const QString& filters, const QString& caption, + const bool showQuickDir, + SUIT_FileValidator* validator ) +{ + return getOpenFileNames( parent, initial, filters.split( ";;", QString::SkipEmptyParts ), + caption, showQuickDir, validator ); +} + +/*! + \brief Show dialog box for the existing directory selection. + + If \a initial parameter is not null string it is used as starting directory + at which dialog box is opened. + + The parameter \a caption is used as dialog box title. If it is + is empty, the default title is used. + + The parameter \a showQuickDir specifies if it is necessary to + show additional quick directories list controls in the bottom part + of the dialog box. + + The validation of the user selection is done with help of the file + validator (SUIT_FileValidator class). The last parameter \a validator + can be used to pass the custom file validator to the dialog box. + + \param parent parent widget + \param initial initial directory dialog box to be opened on + \param caption dialog box title + \param showQuickDir if \c true the quick directory list widgets will be shown + \param validator custom file validator + \return selected directory name or null string if dialog box is cancelled + \sa getFileName(), getOpenFileNames() */ QString SUIT_FileDlg::getExistingDirectory( QWidget* parent, const QString& initial, - const QString& caption, bool showQuickDir ) + const QString& caption, const bool showQuickDir, + SUIT_FileValidator* validator ) { - SUIT_FileDlg* fd = new SUIT_FileDlg( parent, true, showQuickDir, true ); + SUIT_FileDlg fd( parent, true, showQuickDir, true ); + + fd.setFileMode( DirectoryOnly ); + if ( !caption.isEmpty() ) - fd->setWindowTitle( caption ); - if ( !initial.isEmpty() ) - fd->processPath( initial ); // VSR 24/03/03 check for existing of directory has been added to avoid QFileDialog's bug + fd.setWindowTitle( caption ); - fd->setFileMode( DirectoryOnly ); - fd->setFilters( QStringList( tr( "INF_DIRECTORIES_FILTER" ) ) ); + if ( !initial.isEmpty() ) + fd.processPath( initial ); + + if ( validator ) + fd.setValidator( validator ); - fd->exec(); + QString dirname; - QString dirname = fd->selectedFile(); - delete fd; + if ( fd.exec() == QDialog::Accepted ) + dirname = fd.selectedFile(); QApplication::processEvents(); + return dirname; } +/*! + \brief Get last visited path + \return last visited path +*/ +QString SUIT_FileDlg::getLastVisitedPath() +{ + return myLastVisitedPath; +} + /*! \brief Selects current file diff --git a/src/SUIT/SUIT_FileDlg.h b/src/SUIT/SUIT_FileDlg.h index 1adee9e3d..76309c67a 100755 --- a/src/SUIT/SUIT_FileDlg.h +++ b/src/SUIT/SUIT_FileDlg.h @@ -16,81 +16,108 @@ // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // -#ifndef SUIT_FILEDIALOG_H -#define SUIT_FILEDIALOG_H +// File : SUIT_FileDlg.h +// Author : Vadim SANDLER, Open CASCADE S.A.S. (vadim.sandler@opencascade.com) +// + +#ifndef SUIT_FILEDLG_H +#define SUIT_FILEDLG_H #include "SUIT.h" #include class QLabel; +class QLineEdit; class QComboBox; class QPushButton; class SUIT_FileValidator; -/*! \class QFileDialog - * For more information see QT documentation. -*/ class SUIT_EXPORT SUIT_FileDlg : public QFileDialog { Q_OBJECT public: - SUIT_FileDlg( QWidget*, bool open, bool showQuickDir = true, bool modal = true ); + SUIT_FileDlg( QWidget*, bool, bool = true, bool = true ); virtual ~SUIT_FileDlg(); -public: bool isOpenDlg() const; + + bool checkPermissions() const; + void setCheckPermissions( const bool ); + + SUIT_FileValidator* validator() const; + void setValidator( SUIT_FileValidator* ); + + bool addWidgets( QWidget*, QWidget*, QWidget* ); + + QStringList selectedFiles() const; QString selectedFile() const; - void selectFile( const QString& ); + void selectFile( const QString& ); - void setValidator( SUIT_FileValidator* ); + static QString getLastVisitedDirectory(); - static QString getFileName( QWidget* parent, const QString& initial, const QStringList& filters, - const QString& caption, const bool open, const bool showQuickDir = true, - SUIT_FileValidator* validator = 0 ); - static QStringList getOpenFileNames( QWidget* parent, const QString& initial, const QStringList& filters, - const QString& caption, bool showQuickDir = true, - SUIT_FileValidator* validator = 0 ); - static QString getExistingDirectory( QWidget* parent, const QString& initial, - const QString& caption, const bool showQuickDir = true ); + static QString getFileName( QWidget*, + const QString&, + const QStringList&, + const QString& = QString(), + const bool = true, + const bool = true, + SUIT_FileValidator* = 0 ); + static QString getFileName( QWidget*, + const QString&, + const QString&, + const QString& = QString(), + const bool = true, + const bool = true, + SUIT_FileValidator* = 0 ); -private: - void polish(); - bool acceptData(); - void addExtension(); - bool processPath( const QString& path ); + static QStringList getOpenFileNames( QWidget*, + const QString&, + const QStringList&, + const QString& = QString(), + const bool = true, + SUIT_FileValidator* = 0 ); + static QStringList getOpenFileNames( QWidget*, + const QString&, + const QString&, + const QString& = QString(), + const bool = true, + SUIT_FileValidator* = 0 ); + + static QString getExistingDirectory( QWidget*, + const QString&, + const QString& = QString(), + const bool = true, + SUIT_FileValidator* = 0 ); + + static QString getLastVisitedPath(); + +protected: + virtual bool event( QEvent* ); + QLineEdit* lineEdit() const; + virtual bool acceptData(); + QString addExtension( const QString& ) const; + bool processPath( const QString& ); + void addFilter( const QString& ); + static bool hasWildCards( const QString& ); protected slots: void accept(); - void reject(); void quickDir( const QString& ); void addQuickDir(); -protected: - virtual bool event( QEvent* ); +private: + void polish(); -protected: - bool myOpen; //!< open/save selector - QString mySelectedFile; //!< selected filename +private: SUIT_FileValidator* myValidator; //!< file validator QLabel* myQuickLab; //!< quick dir combo box QComboBox* myQuickCombo; //!< quick dir combo box QPushButton* myQuickButton; //!< quick dir add button - - /*! \var myAccepted - * \brief flag is used to warkaround the Qt 2.2.2 - * \bug accept() method is called twice if user presses 'Enter' key - * in file name editor while file name is not acceptable by acceptData() - * (e.g. permission denied) - */ -// bool myAccepted; - /*! ASL: this bug can be fixed with help of call setDefault( false ) - * and setAutoDefault( false ) methods for all QPushButtons of this dialog - */ - + bool myCheckPermissions; //!< check permissions option static QString myLastVisitedPath; //!< last visited path }; -#endif +#endif // SUIT_FILEDLG_H diff --git a/src/SUIT/SUIT_FileValidator.cxx b/src/SUIT/SUIT_FileValidator.cxx index 0adb0b331..5885a7892 100755 --- a/src/SUIT/SUIT_FileValidator.cxx +++ b/src/SUIT/SUIT_FileValidator.cxx @@ -16,74 +16,178 @@ // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // -#include "SUIT_FileValidator.h" +// File : SUIT_FileValidator.cxx +// Author : Vadim SANDLER, Open CASCADE S.A.S. (vadim.sandler@opencascade.com) +// +#include "SUIT_FileValidator.h" #include "SUIT_MessageBox.h" - -#include +#include "SUIT_Tools.h" #include -/*! constructor */ -SUIT_FileValidator::SUIT_FileValidator(QWidget* parent) : -myParent(parent) +/*! + \class SUIT_FileValidator + \brief Provides functionality to check the file or directory + existance and permissions. + \sa SUIT_FileDlg class +*/ + +/*! + \brief Constructor. + \param parent parent widget (used as parent when displaying + information message boxes) +*/ +SUIT_FileValidator::SUIT_FileValidator( QWidget* parent ) +: myParent( parent ) { } -/*! returns false if can't open file */ -bool SUIT_FileValidator::canOpen( const QString& file ) +/*! + \brief Check if the specified file exists and (optionally) can be read. + + If file does not exists or can not be read (if \a checkPermission is \c true) + and parent() is not null, shows error message box. + + \param fileName file path + \param checkPermission if \c true (default) check also file permissions + \return \c false if file does not exist or if it does not have + read permissions (if \a checkPermission is \c true) +*/ +bool SUIT_FileValidator::canOpen( const QString& fileName, bool checkPermission ) { - if ( !QFile::exists( file ) ) - { - SUIT_MessageBox::critical( myParent, QObject::tr( "ERR_ERROR" ), - QObject::tr( "ERR_FILE_NOT_EXIST" ).arg( file ) ); - return false; + if ( !QFile::exists( fileName ) ) { + if ( parent() ) + SUIT_MessageBox::critical( parent(), QObject::tr( "ERR_ERROR" ), + QObject::tr( "ERR_FILE_NOT_EXIST" ).arg( fileName ) ); + return false; } - if ( !QFileInfo( file ).isReadable() ) - { - SUIT_MessageBox::critical( myParent, QObject::tr( "ERR_ERROR" ), - QObject::tr( "ERR_PERMISSION_DENIED" ).arg( file ) ); + if ( checkPermission && !QFileInfo( fileName ).isReadable() ) { + if ( parent() ) + SUIT_MessageBox::critical( parent(), QObject::tr( "ERR_ERROR" ), + QObject::tr( "ERR_PERMISSION_DENIED" ).arg( fileName ) ); return false; } return true; } -/*! returns false if can't save file */ -bool SUIT_FileValidator::canSave( const QString& file ) +/*! + \brief Check if the specified file can be written. + + If file already exists and parent() is not null, prompts + question message box to the user to confirm file overwriting. + + If file can not be written (if \a checkPermission is \c true) + and parent() is not null, shows error message box. + + \param fileName file path + \param checkPermission if \c true (default) check also file permissions + \return \c false if file exists and user rejects file overwriting + or if file does not have write permissions (if \a checkPermission is \c true) +*/ +bool SUIT_FileValidator::canSave( const QString& fileName, bool checkPermission ) { - if ( QFile::exists( file ) ) - { - // if file exists - raise warning... - if ( SUIT_MessageBox::question( myParent, QObject::tr( "WRN_WARNING" ), - QObject::tr( "QUE_DOC_FILEEXISTS" ).arg( file ), - SUIT_MessageBox::Yes | SUIT_MessageBox::No, - SUIT_MessageBox::No ) != SUIT_MessageBox::Yes ) - { - return false; - } - // ... and if user wants to overwrite file, check it for writeability - if ( !QFileInfo( file ).isWritable() ) - { - SUIT_MessageBox::critical( myParent, QObject::tr( "ERR_ERROR" ), - QObject::tr( "ERR_PERMISSION_DENIED" ).arg( file ) ); + if ( QFile::exists( fileName ) ) { + if ( parent() ) + if ( SUIT_MessageBox::question( parent(), QObject::tr( "WRN_WARNING" ), + QObject::tr( "QUE_DOC_FILEEXISTS" ).arg( fileName ), + SUIT_MessageBox::Yes | SUIT_MessageBox::No, + SUIT_MessageBox::No ) != SUIT_MessageBox::Yes ) + return false; + + if ( checkPermission && !QFileInfo( fileName ).isWritable() ) { + if ( parent() ) + SUIT_MessageBox::critical( myParent, QObject::tr( "ERR_ERROR" ), + QObject::tr( "ERR_PERMISSION_DENIED" ).arg( fileName ) ); return false; } } - else - { - // if file doesn't exist - try to create it - QFile qf( file ); - if ( !qf.open( QFile::WriteOnly ) ) - { - SUIT_MessageBox::critical( myParent, QObject::tr( "ERR_ERROR" ), - QObject::tr( "ERR_PERMISSION_DENIED" ).arg( file ) ); + else { + QString dirName = SUIT_Tools::dir( fileName ); + if ( checkPermission && !QFileInfo( dirName ).isWritable() ) { + if ( parent() ) + SUIT_MessageBox::critical( parent(), QObject::tr( "ERR_ERROR" ), + QObject::tr( "ERR_PERMISSION_DENIED" ).arg( fileName ) ); return false; } - else - { - // remove just created file - qf.close(); - qf.remove(); - } } return true; } + +/*! + \brief Check if the specified directory exists and (optionally) can be read. + + If directory does not exists or can not be read (if \a checkPermission is \c true) + and parent() is not null, shows error message box. + + \param dirName directory path + \param checkPermission if \c true (default) check also directory permissions + \return \c false if directory does not exist or if it does not have + read permissions (if \a checkPermission is \c true) +*/ +bool SUIT_FileValidator::canReadDir( const QString& dirName, bool checkPermission ) +{ + QFileInfo info( dirName ); + if ( !info.exists() ) { + if ( parent() ) + SUIT_MessageBox::critical( parent(), QObject::tr( "ERR_ERROR" ), + QObject::tr( "ERR_DIR_NOT_EXIST" ).arg( dirName ) ); + return false; + } + if ( !info.isDir() ) { + if ( parent() ) + SUIT_MessageBox::critical( parent(), QObject::tr( "ERR_ERROR" ), + QObject::tr( "ERR_FILE_NOT_DIR" ).arg( dirName ) ); + return false; + } + if ( checkPermission && !info.isReadable() ) { + if ( parent() ) + SUIT_MessageBox::critical( parent(), QObject::tr( "ERR_ERROR" ), + QObject::tr( "ERR_PERMISSION_DENIED" ).arg( dirName ) ); + return false; + } + return true; +} + +/*! + \brief Check if the specified directory can be written. + + If directory does not exists or can not be modified (if \a checkPermission is \c true) + and parent() is not null, shows error message box. + + \param dirName directory path + \param checkPermission if \c true (default) check also directory permissions + \return \c false if directory does not exist or if it does not have + write permissions (if \a checkPermission is \c true) +*/ +bool SUIT_FileValidator::canWriteDir( const QString& dirName, bool checkPermission ) +{ + QFileInfo info( dirName ); + if ( !info.exists() ) { + if ( parent() ) + SUIT_MessageBox::critical( parent(), QObject::tr( "ERR_ERROR" ), + QObject::tr( "ERR_DIR_NOT_EXIST" ).arg( dirName ) ); + return false; + } + if ( !info.isDir() ) { + if ( parent() ) + SUIT_MessageBox::critical( parent(), QObject::tr( "ERR_ERROR" ), + QObject::tr( "ERR_FILE_NOT_DIR" ).arg( dirName ) ); + return false; + } + if ( checkPermission && !info.isWritable() ) { + if ( parent() ) + SUIT_MessageBox::critical( parent(), QObject::tr( "ERR_ERROR" ), + QObject::tr( "ERR_PERMISSION_DENIED" ).arg( dirName ) ); + return false; + } + return true; +} + +/*! + \brief Get parent widget. + \return parent widget +*/ +QWidget* SUIT_FileValidator::parent() const +{ + return myParent; +} diff --git a/src/SUIT/SUIT_FileValidator.h b/src/SUIT/SUIT_FileValidator.h index 9142c381d..edcd3398b 100755 --- a/src/SUIT/SUIT_FileValidator.h +++ b/src/SUIT/SUIT_FileValidator.h @@ -16,8 +16,10 @@ // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // -// SALOME SALOMEGUI : implementation of desktop and GUI kernel +// File : SUIT_FileValidator.h +// Author : Vadim SANDLER, Open CASCADE S.A.S. (vadim.sandler@opencascade.com) // + #ifndef SUIT_FILEVALIDATOR_H #define SUIT_FILEVALIDATOR_H @@ -26,24 +28,21 @@ class QWidget; class QString; -/*! - \class SUIT_FileValidator - Provides functionality to check file -*/ class SUIT_EXPORT SUIT_FileValidator { public: - SUIT_FileValidator(QWidget* parent = 0); + SUIT_FileValidator( QWidget* = 0 ); - virtual bool canOpen( const QString& file ); - virtual bool canSave( const QString& file ); + virtual bool canOpen( const QString&, bool = true ); + virtual bool canSave( const QString&, bool = true ); - //! Return parent widget - QWidget* parent() const { return myParent; } - - private: + virtual bool canReadDir( const QString&, bool = true ); + virtual bool canWriteDir( const QString&, bool = true ); + + QWidget* parent() const; +private: QWidget* myParent; }; -#endif +#endif // SUIT_FILEVALIDATOR_H diff --git a/src/SUIT/SUIT_TreeModel.cxx b/src/SUIT/SUIT_TreeModel.cxx index 48f486896..b2c1e880a 100755 --- a/src/SUIT/SUIT_TreeModel.cxx +++ b/src/SUIT/SUIT_TreeModel.cxx @@ -819,9 +819,11 @@ bool SUIT_TreeModel::autoUpdate() const automatically when data tree is changed. \param on 'auto-update tree' flag value + \param updateImmediately if \c true, the tree is updated immediately; + otherwise the tree must be updated manually \sa autoUpdate(), updateTree() */ -void SUIT_TreeModel::setAutoUpdate( const bool on ) +void SUIT_TreeModel::setAutoUpdate( const bool on, const bool updateImmediately ) { if ( myAutoUpdate == on ) return; @@ -838,7 +840,8 @@ void SUIT_TreeModel::setAutoUpdate( const bool on ) SUIT_DataObject::connect( SIGNAL( removed( SUIT_DataObject*, SUIT_DataObject* ) ), this, SLOT( onRemoved( SUIT_DataObject*, SUIT_DataObject* ) ) ); - updateTree(); + if ( updateImmediately ) + updateTree(); } } @@ -1235,12 +1238,14 @@ bool SUIT_ProxyModel::autoUpdate() const automatically when data tree is changed. \param on 'auto-update tree' flag value + \param updateImmediately if \c true, the tree is updated immediately; + otherwise the tree must be updated manually \sa autoUpdate(), updateTree() */ -void SUIT_ProxyModel::setAutoUpdate( const bool on ) +void SUIT_ProxyModel::setAutoUpdate( const bool on, const bool updateImmediately ) { if ( treeModel() ) - treeModel()->setAutoUpdate( on ); + treeModel()->setAutoUpdate( on, updateImmediately ); } /*! diff --git a/src/SUIT/SUIT_TreeModel.h b/src/SUIT/SUIT_TreeModel.h index 89ca777e2..e5ad92517 100755 --- a/src/SUIT/SUIT_TreeModel.h +++ b/src/SUIT/SUIT_TreeModel.h @@ -97,7 +97,7 @@ public: void setAutoDeleteTree( const bool ); bool autoUpdate() const; - void setAutoUpdate( const bool ); + void setAutoUpdate( const bool, const bool = true ); virtual bool customSorting( const int ) const; virtual bool lessThan( const QModelIndex& left, const QModelIndex& right ) const; @@ -158,7 +158,7 @@ public: void setAutoDeleteTree( const bool ); bool autoUpdate() const; - void setAutoUpdate( const bool ); + void setAutoUpdate( const bool, const bool = true ); bool isSortingEnabled() const; diff --git a/src/SUITApp/SUITApp.pro b/src/SUITApp/SUITApp.pro index 97654e140..e5edddab5 100644 --- a/src/SUITApp/SUITApp.pro +++ b/src/SUITApp/SUITApp.pro @@ -1,4 +1,9 @@ -TEMPLATE = app +unix:TEMPLATE = app +win32:TEMPLATE = vcapp + +CONFIG -= embed_manifest_exe + +win32:QMAKE_MOC=$(QTDIR)\bin\moc.exe DESTDIR = ../../$(CONFIG_ID)/bin MOC_DIR = ../../moc @@ -6,12 +11,20 @@ OBJECTS_DIR = ../../$(CONFIG_ID)/obj/$$TARGET INCLUDEPATH = ../../include LIBS += -L../../$(CONFIG_ID)/lib -lSUIT -lQtx -lStyle -lObjBrowser +win32:LIBS *= -L$(QTLIB) +win32:INCLUDEPATH *= $(QTINC) $(QTINC)\QtCore $(QTINC)\QtGui $(QTINC)\QtXml CONFIG -= debug release debug_and_release CONFIG += qt thread debug dll shared -win32:DEFINES += WIN32 +win32:DEFINES += WNT WIN32 HEADERS = *.h SOURCES = *.cxx + +win32:copy_hdr.name = Install ${QMAKE_FILE_IN} +win32:copy_hdr.commands = type ${QMAKE_FILE_IN} > ../../include/${QMAKE_FILE_BASE}.h +win32:copy_hdr.output = ../../include/${QMAKE_FILE_BASE}.h +win32:copy_hdr.input = HEADERS +win32:QMAKE_EXTRA_COMPILERS += copy_hdr diff --git a/src/SVTK/SVTK.pro b/src/SVTK/SVTK.pro index 1f68c9030..b51c7481e 100644 --- a/src/SVTK/SVTK.pro +++ b/src/SVTK/SVTK.pro @@ -1,22 +1,30 @@ -TEMPLATE = lib +unix:TEMPLATE = lib +win32:TEMPLATE = vclib + +win32:QMAKE_MOC=$(QTDIR)\bin\moc.exe DESTDIR = ../../$(CONFIG_ID)/lib MOC_DIR = ../../moc OBJECTS_DIR = ../../$(CONFIG_ID)/obj/$$TARGET -VTK_LIBS = -L$$(VTKLIB) -lvtkCommon -lvtkGraphics -lvtkImaging -lvtkFiltering -lvtkIO -lvtkRendering -lvtkHybrid -lvtkParallel -lvtkWidgets -lGL -L/usr/X11R6/lib -lGLU -L/usr/X11R6/lib -lX11 -lXt +unix:VTK_LIBS = -L$$(VTKLIB) -lvtkCommon -lvtkGraphics -lvtkImaging -lvtkFiltering -lvtkIO -lvtkRendering -lvtkHybrid -lvtkParallel -lvtkWidgets -lGL -L/usr/X11R6/lib -lGLU -L/usr/X11R6/lib -lX11 -lXt +win32:VTK_LIBS = -L$$(VTKLIB) -lvtkCommon -lvtkGraphics -lvtkImaging -lvtkFiltering -lvtkIO -lvtkRendering -lvtkHybrid -lvtkParallel -lvtkWidgets -lopengl32 CAS_CPPFLAGS = $(CASINC) -OCC_LIBS = +unix:OCC_LIBS = +win32:OCC_LIBS = -L$(CASLIB) -lTKernel INCLUDEPATH += ../../include $${CAS_CPPFLAGS} $$(VTKINC) $$(BOOSTINC) ../Qtx ../SUIT ../OBJECT ../Prs ../VTKViewer LIBS += -L../../$(CONFIG_ID)/lib -lQtx -lSUIT -lOBJECT -lPrs -lVTKViewer $${OCC_LIBS} $${VTK_LIBS} +win32: LIBS += -lTKernel +win32:LIBS *= -L$(QTLIB) +win32:INCLUDEPATH *= $(QTINC) $(QTINC)\QtCore $(QTINC)\QtGui $(QTINC)\QtXml CONFIG -= debug release debug_and_release CONFIG += qt thread debug dll shared -win32:DEFINES += WIN32 +win32:DEFINES += WNT WIN32 DEFINES += SVTK_EXPORTS $(CASDEFINES) OCC_VERSION_MAJOR=6 OCC_VERSION_MINOR=1 OCC_VERSION_MAINTENANCE=1 LIN LINTEL CSFDB No_exception HAVE_CONFIG_H HAVE_LIMITS_H HAVE_WOK_CONFIG_H OCC_CONVERT_SIGNALS HEADERS = SVTK.h @@ -91,7 +99,7 @@ win32:GUIResources = ..\\..\\resources lrelease.name = LRELASE ${QMAKE_FILE_IN} unix:lrelease.commands = $(QTDIR)/bin/lrelease ${QMAKE_FILE_NAME} -qm $${GUIResources}/${QMAKE_FILE_BASE}.qm -win32:lrelease.commands = $(QTDIR)\\bin\\lrelease ${QMAKE_FILE_NAME} -qm $${GUIResources}\\${QMAKE_FILE_BASE}.qm +win32:lrelease.commands = $(QTDIR)\\bin\\lrelease ${QMAKE_FILE_IN} -qm $${GUIResources}\\${QMAKE_FILE_BASE}.qm unix:lrelease.output = $${GUIResources}/${QMAKE_FILE_BASE}.qm win32:lrelease.output = $${GUIResources}\\${QMAKE_FILE_BASE}.qm lrelease.input = TRANSLATIONS @@ -100,6 +108,12 @@ win32:lrelease.clean = $${GUIResources}\\${QMAKE_FILE_BASE}.qm lrelease.CONFIG += no_link target_predeps QMAKE_EXTRA_COMPILERS += lrelease +win32:copy_hdr.name = Install ${QMAKE_FILE_IN} +win32:copy_hdr.commands = type ${QMAKE_FILE_IN} > ../../include/${QMAKE_FILE_BASE}.h +win32:copy_hdr.output = ../../include/${QMAKE_FILE_BASE}.h +win32:copy_hdr.input = HEADERS +win32:QMAKE_EXTRA_COMPILERS += copy_hdr + ICONS = resources/*.png includes.files = $$HEADERS diff --git a/src/SVTK/SVTK_CubeAxesActor2D.cxx b/src/SVTK/SVTK_CubeAxesActor2D.cxx index 4f109801c..eb14e3379 100644 --- a/src/SVTK/SVTK_CubeAxesActor2D.cxx +++ b/src/SVTK/SVTK_CubeAxesActor2D.cxx @@ -208,7 +208,7 @@ static void ChangeValues(vtkFloatingPointType* aArray1, #ifndef WIN32 for(int i=0;i<2; i++){ #else - for(i=0;i<2; i++){ + for(int i=0;i<2; i++){ #endif tmp = aRange1[i]; aRange1[i] = aRange2[i]; aRange2[i] = tmp; } diff --git a/src/SVTK/SVTK_RenderWindowInteractor.cxx b/src/SVTK/SVTK_RenderWindowInteractor.cxx index 56236ad89..439837e68 100644 --- a/src/SVTK/SVTK_RenderWindowInteractor.cxx +++ b/src/SVTK/SVTK_RenderWindowInteractor.cxx @@ -37,7 +37,10 @@ // QT Includes // Put Qt includes before the X11 includes which #define the symbol None // (see SVTK_SpaceMouse.h) to avoid the compilation error. +#ifndef WIN32 #include +#endif + #include #include "SVTK_SpaceMouse.h" @@ -414,10 +417,10 @@ QVTK_RenderWindowInteractor /*! To handle native Win32 events (from such devices as SpaceMouse) */ -bool QVTK_RenderWindowInteractor::winEvent( MSG* msg ) +bool QVTK_RenderWindowInteractor::winEvent( MSG* msg, long* result ) { // TODO: Implement event handling for SpaceMouse - return QWidget::winEvent( msg ); + return QWidget::winEvent( msg, result ); } #else @@ -435,7 +438,7 @@ QVTK_RenderWindowInteractor if ( aSpaceMouse->isSpaceMouseOn() && xEvent->type == ClientMessage ) { SVTK_SpaceMouse::MoveEvent anEvent; - int type = aSpaceMouse->translateEvent( QX11Info::display(), xEvent, &anEvent, 1.0, 1.0 ); + int type = aSpaceMouse->translateEvent( QX11Info::display(), xEvent, &anEvent, 1.0, 1.0 ); switch ( type ) { case SVTK_SpaceMouse::SpaceMouseMove: diff --git a/src/SVTK/SVTK_RenderWindowInteractor.h b/src/SVTK/SVTK_RenderWindowInteractor.h index 51aa1ec59..ab5f9c182 100644 --- a/src/SVTK/SVTK_RenderWindowInteractor.h +++ b/src/SVTK/SVTK_RenderWindowInteractor.h @@ -122,7 +122,7 @@ class SVTK_EXPORT QVTK_RenderWindowInteractor: public QWidget //! To handle native events (from such devices as SpaceMouse) #ifdef WIN32 - virtual bool winEvent( MSG* ); + virtual bool winEvent( MSG*, long* ); #else virtual bool x11Event( XEvent *e ); #endif diff --git a/src/Style/Style.pro b/src/Style/Style.pro index 87c7e2476..6464ee83e 100644 --- a/src/Style/Style.pro +++ b/src/Style/Style.pro @@ -1,22 +1,33 @@ -TEMPLATE = lib +unix:TEMPLATE = lib +win32:TEMPLATE = vclib + +win32:QMAKE_MOC=$(QTDIR)\bin\moc.exe DESTDIR = ../../$(CONFIG_ID)/lib MOC_DIR = ../../moc OBJECTS_DIR = ../../$(CONFIG_ID)/obj/$$TARGET INCLUDEPATH = ../../include -LIBS += -L ../../$(CONFIG_ID)/lib -lQtx +LIBS += -L../../$(CONFIG_ID)/lib -lQtx +win32:LIBS *= -L$(QTLIB) +win32:INCLUDEPATH *= $(QTINC) $(QTINC)\QtCore $(QTINC)\QtGui $(QTINC)\QtXml CONFIG -= debug release debug_and_release CONFIG += qt thread debug dll shared -win32:DEFINES += WIN32 +win32:DEFINES += WNT WIN32 DEFINES += STYLE_SALOME_EXPORTS HEADERS = *.h SOURCES = *.cxx +win32:copy_hdr.name = Install ${QMAKE_FILE_IN} +win32:copy_hdr.commands = type ${QMAKE_FILE_IN} > ../../include/${QMAKE_FILE_BASE}.h +win32:copy_hdr.output = ../../include/${QMAKE_FILE_BASE}.h +win32:copy_hdr.input = HEADERS +win32:QMAKE_EXTRA_COMPILERS += copy_hdr + includes.files = $$HEADERS includes.path = ../../include diff --git a/src/TableViewer/TableViewer.pro b/src/TableViewer/TableViewer.pro index 8e9746fb2..8c0d63320 100644 --- a/src/TableViewer/TableViewer.pro +++ b/src/TableViewer/TableViewer.pro @@ -1,4 +1,7 @@ -TEMPLATE = lib +unix:TEMPLATE = lib +win32:TEMPLATE = vclib + +win32:QMAKE_MOC=$(QTDIR)\bin\moc.exe DESTDIR = ../../$(CONFIG_ID)/lib MOC_DIR = ../../moc @@ -8,13 +11,15 @@ CAS_CPPFLAGS = $(CASINC) CAS_KERNEL = -L$(CASLIB) -lTKernel INCLUDEPATH = ../../include $${CAS_CPPFLAGS} -LIBS += -L../../$(CONFIG_ID)/lib -lSUIT $${CAS_KERNEL} -lHTMLService +LIBS += -L../../$(CONFIG_ID)/lib -lQtx -lSUIT $${CAS_KERNEL} -lHTMLService +win32:LIBS *= -L$(QTLIB) +win32:INCLUDEPATH *= $(QTINC) $(QTINC)\QtCore $(QTINC)\QtGui $(QTINC)\QtXml CONFIG -= debug release debug_and_release CONFIG += qt thread debug dll shared -win32:DEFINES += WIN32 -DEFINES += TABLE_VIEWER_EXPORTS $(CASDEFINES) OCC_VERSION_MAJOR=6 OCC_VERSION_MINOR=1 OCC_VERSION_MAINTENANCE=1 LIN LINTEL CSFDB No_exception HAVE_CONFIG_H HAVE_LIMITS_H HAVE_WOK_CONFIG_H OCC_CONVERT_SIGNALS +win32:DEFINES += WNT WIN32 +DEFINES += TABLEVIEWER_EXPORTS $(CASDEFINES) OCC_VERSION_MAJOR=6 OCC_VERSION_MINOR=1 OCC_VERSION_MAINTENANCE=1 LIN LINTEL CSFDB No_exception HAVE_CONFIG_H HAVE_LIMITS_H HAVE_WOK_CONFIG_H OCC_CONVERT_SIGNALS HEADERS = *.h @@ -28,7 +33,7 @@ win32:GUIResources = ..\\..\\resources lrelease.name = LRELASE ${QMAKE_FILE_IN} unix:lrelease.commands = $(QTDIR)/bin/lrelease ${QMAKE_FILE_NAME} -qm $${GUIResources}/${QMAKE_FILE_BASE}.qm -win32:lrelease.commands = $(QTDIR)\\bin\\lrelease ${QMAKE_FILE_NAME} -qm $${GUIResources}\\${QMAKE_FILE_BASE}.qm +win32:lrelease.commands = $(QTDIR)\\bin\\lrelease ${QMAKE_FILE_IN} -qm $${GUIResources}\\${QMAKE_FILE_BASE}.qm unix:lrelease.output = $${GUIResources}/${QMAKE_FILE_BASE}.qm win32:lrelease.output = $${GUIResources}\\${QMAKE_FILE_BASE}.qm lrelease.input = TRANSLATIONS @@ -37,8 +42,22 @@ win32:lrelease.clean = $${GUIResources}\\${QMAKE_FILE_BASE}.qm lrelease.CONFIG += no_link target_predeps QMAKE_EXTRA_COMPILERS += lrelease +win32:copy_hdr.name = Install ${QMAKE_FILE_IN} +win32:copy_hdr.commands = type ${QMAKE_FILE_IN} > ../../include/${QMAKE_FILE_BASE}.h +win32:copy_hdr.output = ../../include/${QMAKE_FILE_BASE}.h +win32:copy_hdr.input = HEADERS +win32:QMAKE_EXTRA_COMPILERS += copy_hdr + ICONS = resources/*.png +win32:Resource=$$ICONS +win32:SOURCES+=$$ICONS +win32:copy_res.name = Install resources ${QMAKE_FILE_IN} +win32:copy_res.commands = type ${QMAKE_FILE_IN} > ${QMAKE_FILE_OUT} +win32:copy_res.output = $${GUIResources}\\${QMAKE_FILE_BASE}.png +win32:copy_res.input = Resource +win32:QMAKE_EXTRA_COMPILERS += copy_res + includes.files = $$HEADERS includes.path = ../../include diff --git a/src/TableViewer/TableViewer_ViewWindow.cxx b/src/TableViewer/TableViewer_ViewWindow.cxx index ee9b442fc..9e9305ed1 100755 --- a/src/TableViewer/TableViewer_ViewWindow.cxx +++ b/src/TableViewer/TableViewer_ViewWindow.cxx @@ -329,7 +329,7 @@ void TableViewer_ViewWindow::selectionChanged() { bool anEnable = myTable->getSelectedIndexes().count() > 0; myActionsMap[CopyId]->setEnabled( anEnable ); - myActionsMap[PasteId]->setEnabled( anEnable & myCopyLst.count() > 0 ); + myActionsMap[PasteId]->setEnabled( anEnable && myCopyLst.count() > 0 ); } void TableViewer_ViewWindow::onActivated() diff --git a/src/VTKViewer/VTKViewer.pro b/src/VTKViewer/VTKViewer.pro index 04b2493c7..1a8b2bab8 100644 --- a/src/VTKViewer/VTKViewer.pro +++ b/src/VTKViewer/VTKViewer.pro @@ -1,10 +1,14 @@ -TEMPLATE = lib +unix:TEMPLATE = lib +win32:TEMPLATE = vclib + +win32:QMAKE_MOC=$(QTDIR)\bin\moc.exe DESTDIR = ../../$(CONFIG_ID)/lib MOC_DIR = ../../moc OBJECTS_DIR = ../../$(CONFIG_ID)/obj/$$TARGET -VTK_LIBS = -L$$(VTKLIB) -lvtkCommon -lvtkGraphics -lvtkImaging -lvtkFiltering -lvtkIO -lvtkRendering -lvtkHybrid -lvtkParallel -lvtkWidgets -lGL -L/usr/X11R6/lib -lGLU -L/usr/X11R6/lib -lX11 -lXt +unix:VTK_LIBS = -L$$(VTKLIB) -lvtkCommon -lvtkGraphics -lvtkImaging -lvtkFiltering -lvtkIO -lvtkRendering -lvtkHybrid -lvtkParallel -lvtkWidgets -lGL -L/usr/X11R6/lib -lGLU -L/usr/X11R6/lib -lX11 -lXt +win32:VTK_LIBS = -L$$(VTKLIB) -lvtkCommon -lvtkGraphics -lvtkImaging -lvtkFiltering -lvtkIO -lvtkRendering -lvtkHybrid -lvtkParallel -lvtkWidgets CAS_CPPFLAGS = $(CASINC) @@ -12,11 +16,13 @@ CAS_KERNEL = -L$(CASLIB) -lTKernel INCLUDEPATH += ../../include $$(VTKINC) $${CAS_CPPFLAGS} ../Qtx ../SUIT LIBS += -L../../$(CONFIG_ID)/lib -lQtx -lSUIT $${VTK_LIBS} $${CAS_KERNEL} +win32:LIBS *= -L$(QTLIB) +win32:INCLUDEPATH *= $(QTINC) $(QTINC)\QtCore $(QTINC)\QtGui $(QTINC)\QtXml CONFIG -= debug release debug_and_release CONFIG += qt thread debug dll shared -win32:DEFINES += WIN32 +win32:DEFINES += WNT WIN32 DEFINES += VTKVIEWER_EXPORTS $(CASDEFINES) OCC_VERSION_MAJOR=6 OCC_VERSION_MINOR=1 OCC_VERSION_MAINTENANCE=1 LIN LINTEL CSFDB No_exception HAVE_CONFIG_H HAVE_LIMITS_H HAVE_WOK_CONFIG_H OCC_CONVERT_SIGNALS HEADERS = VTKViewer.h @@ -60,7 +66,7 @@ SOURCES += VTKViewer_ViewModel.cxx SOURCES += VTKViewer_ConvexTool.cxx SOURCES += VTKViewer_ViewWindow.cxx -message ( "Sources: $$SOURCES " ) +unix:message ( "Sources: $$SOURCES " ) TRANSLATIONS = resources/VTKViewer_images.ts \ resources/VTKViewer_msg_en.ts @@ -70,7 +76,7 @@ win32:GUIResources = ..\\..\\resources lrelease.name = LRELASE ${QMAKE_FILE_IN} unix:lrelease.commands = $(QTDIR)/bin/lrelease ${QMAKE_FILE_NAME} -qm $${GUIResources}/${QMAKE_FILE_BASE}.qm -win32:lrelease.commands = $(QTDIR)\\bin\\lrelease ${QMAKE_FILE_NAME} -qm $${GUIResources}\\${QMAKE_FILE_BASE}.qm +win32:lrelease.commands = $(QTDIR)\\bin\\lrelease ${QMAKE_FILE_IN} -qm $${GUIResources}\\${QMAKE_FILE_BASE}.qm unix:lrelease.output = $${GUIResources}/${QMAKE_FILE_BASE}.qm win32:lrelease.output = $${GUIResources}\\${QMAKE_FILE_BASE}.qm lrelease.input = TRANSLATIONS @@ -79,8 +85,22 @@ win32:lrelease.clean = $${GUIResources}\\${QMAKE_FILE_BASE}.qm lrelease.CONFIG += no_link target_predeps QMAKE_EXTRA_COMPILERS += lrelease +win32:copy_hdr.name = Install ${QMAKE_FILE_IN} +win32:copy_hdr.commands = type ${QMAKE_FILE_IN} > ../../include/${QMAKE_FILE_BASE}.h +win32:copy_hdr.output = ../../include/${QMAKE_FILE_BASE}.h +win32:copy_hdr.input = HEADERS +win32:QMAKE_EXTRA_COMPILERS += copy_hdr + ICONS = resources/*.png +win32:SOURCES+=$$ICONS +win32:Resource=$$ICONS +win32:copy_res.name = Install resources ${QMAKE_FILE_IN} +win32:copy_res.commands = type ${QMAKE_FILE_IN} > ${QMAKE_FILE_OUT} +win32:copy_res.output = $${GUIResources}\\${QMAKE_FILE_BASE}.png +win32:copy_res.input = Resource +win32:QMAKE_EXTRA_COMPILERS += copy_res + includes.files = $$HEADERS includes.path = ../../include -- 2.39.2