diff options
Diffstat (limited to 'qtruby/rubylib/designer')
52 files changed, 7663 insertions, 0 deletions
diff --git a/qtruby/rubylib/designer/Makefile.am b/qtruby/rubylib/designer/Makefile.am new file mode 100644 index 00000000..80ec1c71 --- /dev/null +++ b/qtruby/rubylib/designer/Makefile.am @@ -0,0 +1 @@ +SUBDIRS = rbuic uilib diff --git a/qtruby/rubylib/designer/examples/colortool/Makefile b/qtruby/rubylib/designer/examples/colortool/Makefile new file mode 100644 index 00000000..df79b963 --- /dev/null +++ b/qtruby/rubylib/designer/examples/colortool/Makefile @@ -0,0 +1,30 @@ +RBUIC=rbuic
+
+RBUICIMPLS=mainform.rb optionsform.rb colornameform.rb \
+ findform.rb qmake_image_collection.rb
+
+all: $(RBUICIMPLS)
+
+mainform.rb:
+ $(RBUIC) mainform.ui -o mainform.rb
+
+optionsform.rb: optionsform.ui
+ $(RBUIC) optionsform.ui -o optionsform.rb
+
+colornameform.rb: colornameform.ui
+ $(RBUIC) colornameform.ui -o colornameform.rb
+
+findform.rb: findform.ui
+ $(RBUIC) findform.ui -o findform.rb
+
+qmake_image_collection.rb:
+ $(RBUIC) -embed colortool images/filenew.png images/fileopen.png \
+ images/filesave.png images/editcut.png images/editcopy.png \
+ images/searchfind.png images/tabwidget.png images/table.png \
+ images/iconview.png images/richtextedit.png images/widgetstack.png \
+ images/editraise.png -o qmake_image_collection.rb
+
+clean:
+ rm -f $(RBUICIMPLS)
+
+
diff --git a/qtruby/rubylib/designer/examples/colortool/README b/qtruby/rubylib/designer/examples/colortool/README new file mode 100644 index 00000000..99d2174b --- /dev/null +++ b/qtruby/rubylib/designer/examples/colortool/README @@ -0,0 +1,8 @@ +This is the Qt Designer Tutorial 'Creating Dialogs' translated into QtRuby. It
+shows how you can combine ruby code generated from .ui files with the rbuic
+tool, with your own code.
+
+The .ui files and images are identical to the original C++ versions.
+
+It features a simple Makefile to run rbuic when you change the .ui files, and
+regenerate the ruby sources.
diff --git a/qtruby/rubylib/designer/examples/colortool/colornameform.ui b/qtruby/rubylib/designer/examples/colortool/colornameform.ui new file mode 100644 index 00000000..50f2d6de --- /dev/null +++ b/qtruby/rubylib/designer/examples/colortool/colornameform.ui @@ -0,0 +1,168 @@ +<!DOCTYPE UI><UI version="3.0" stdsetdef="1"> +<class>ColorNameForm</class> +<widget class="QDialog"> + <property name="name"> + <cstring>ColorNameForm</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>348</width> + <height>105</height> + </rect> + </property> + <property name="caption"> + <string>Color Tool - Color Name</string> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLabel"> + <property name="name"> + <cstring>colorLabel</cstring> + </property> + <property name="minimumSize"> + <size> + <width>80</width> + <height>0</height> + </size> + </property> + <property name="text"> + <string></string> + </property> + <property name="pixmap"> + <pixmap>editraise.png</pixmap> + </property> + <property name="scaledContents"> + <bool>true</bool> + </property> + </widget> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>Layout4</cstring> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>Layout1</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLabel"> + <property name="name"> + <cstring>TextLabel2</cstring> + </property> + <property name="text"> + <string>&Name:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>colorLineEdit</cstring> + </property> + </widget> + <widget class="QLineEdit"> + <property name="name"> + <cstring>colorLineEdit</cstring> + </property> + </widget> + </hbox> + </widget> + <spacer> + <property name="name"> + <cstring>Spacer2</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>0</height> + </size> + </property> + </spacer> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>Layout4</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <spacer> + <property name="name"> + <cstring>Spacer3</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>0</width> + <height>11</height> + </size> + </property> + </spacer> + <widget class="QPushButton"> + <property name="name"> + <cstring>okPushButton</cstring> + </property> + <property name="text"> + <string>&OK</string> + </property> + <property name="default"> + <bool>true</bool> + </property> + </widget> + <widget class="QPushButton"> + <property name="name"> + <cstring>cancelPushButton</cstring> + </property> + <property name="text"> + <string>&Cancel</string> + </property> + </widget> + </hbox> + </widget> + </vbox> + </widget> + </hbox> +</widget> +<connections> + <connection> + <sender>cancelPushButton</sender> + <signal>clicked()</signal> + <receiver>ColorNameForm</receiver> + <slot>reject()</slot> + </connection> + <connection> + <sender>okPushButton</sender> + <signal>clicked()</signal> + <receiver>ColorNameForm</receiver> + <slot>validate()</slot> + </connection> +</connections> +<includes> + <include location="local" impldecl="in implementation">colornameform.ui.h</include> +</includes> +<slots> + <slot>validate()</slot> +</slots> +<functions> + <function>setColors( const QMap<QString, QColor> & colors )</function> +</functions> +<pixmapinproject/> +<layoutdefaults spacing="6" margin="11"/> +</UI> diff --git a/qtruby/rubylib/designer/examples/colortool/colornameform.ui.rb b/qtruby/rubylib/designer/examples/colortool/colornameform.ui.rb new file mode 100644 index 00000000..db671b77 --- /dev/null +++ b/qtruby/rubylib/designer/examples/colortool/colornameform.ui.rb @@ -0,0 +1,19 @@ +class ColorNameForm + +@colors = {} + +def setColors( colors ) + @colors = colors +end + +def validate() + name = @colorLineEdit.text() + if ! name.empty? && + ( @colors.empty? || ! @colors.has_key?( name ) ) + accept() + else + @colorLineEdit.selectAll() + end +end + +end diff --git a/qtruby/rubylib/designer/examples/colortool/findform.ui b/qtruby/rubylib/designer/examples/colortool/findform.ui new file mode 100644 index 00000000..3e627945 --- /dev/null +++ b/qtruby/rubylib/designer/examples/colortool/findform.ui @@ -0,0 +1,141 @@ +<!DOCTYPE UI><UI version="3.0" stdsetdef="1"> +<class>FindForm</class> +<widget class="QDialog"> + <property name="name"> + <cstring>FindForm</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>301</width> + <height>99</height> + </rect> + </property> + <property name="caption"> + <string>Color Tool - Find Color</string> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>Layout11</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLabel"> + <property name="name"> + <cstring>TextLabel3</cstring> + </property> + <property name="text"> + <string>&Look for:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>findLineEdit</cstring> + </property> + </widget> + <widget class="QLineEdit"> + <property name="name"> + <cstring>findLineEdit</cstring> + </property> + </widget> + </hbox> + </widget> + <spacer> + <property name="name"> + <cstring>Spacer4</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>0</height> + </size> + </property> + </spacer> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>Layout10</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <spacer> + <property name="name"> + <cstring>Spacer7</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>0</width> + <height>9</height> + </size> + </property> + </spacer> + <widget class="QPushButton"> + <property name="name"> + <cstring>findPushButton</cstring> + </property> + <property name="text"> + <string>&Find</string> + </property> + <property name="default"> + <bool>true</bool> + </property> + </widget> + <widget class="QPushButton"> + <property name="name"> + <cstring>closePushButton</cstring> + </property> + <property name="text"> + <string>&Close</string> + </property> + </widget> + </hbox> + </widget> + </vbox> +</widget> +<connections> + <connection> + <sender>closePushButton</sender> + <signal>clicked()</signal> + <receiver>FindForm</receiver> + <slot>accept()</slot> + </connection> + <connection> + <sender>findPushButton</sender> + <signal>clicked()</signal> + <receiver>FindForm</receiver> + <slot>find()</slot> + </connection> +</connections> +<includes> + <include location="local" impldecl="in implementation">findform.ui.h</include> +</includes> +<signals> + <signal>lookfor(const QString&)</signal> +</signals> +<slots> + <slot>find()</slot> +</slots> +<functions> + <function>notfound()</function> +</functions> +<pixmapinproject/> +<layoutdefaults spacing="6" margin="11"/> +</UI> diff --git a/qtruby/rubylib/designer/examples/colortool/findform.ui.rb b/qtruby/rubylib/designer/examples/colortool/findform.ui.rb new file mode 100644 index 00000000..6bfb4f0a --- /dev/null +++ b/qtruby/rubylib/designer/examples/colortool/findform.ui.rb @@ -0,0 +1,11 @@ +class FindForm + +def find() + emit lookfor( @findLineEdit.text() ) +end + +def notfound() + @findLineEdit.selectAll() +end + +end diff --git a/qtruby/rubylib/designer/examples/colortool/images/editcopy b/qtruby/rubylib/designer/examples/colortool/images/editcopy Binary files differnew file mode 100644 index 00000000..7b334ca4 --- /dev/null +++ b/qtruby/rubylib/designer/examples/colortool/images/editcopy diff --git a/qtruby/rubylib/designer/examples/colortool/images/editcopy.png b/qtruby/rubylib/designer/examples/colortool/images/editcopy.png Binary files differnew file mode 100644 index 00000000..abfe86e2 --- /dev/null +++ b/qtruby/rubylib/designer/examples/colortool/images/editcopy.png diff --git a/qtruby/rubylib/designer/examples/colortool/images/editcut b/qtruby/rubylib/designer/examples/colortool/images/editcut Binary files differnew file mode 100644 index 00000000..60abc586 --- /dev/null +++ b/qtruby/rubylib/designer/examples/colortool/images/editcut diff --git a/qtruby/rubylib/designer/examples/colortool/images/editcut.png b/qtruby/rubylib/designer/examples/colortool/images/editcut.png Binary files differnew file mode 100644 index 00000000..98efe27a --- /dev/null +++ b/qtruby/rubylib/designer/examples/colortool/images/editcut.png diff --git a/qtruby/rubylib/designer/examples/colortool/images/editraise.png b/qtruby/rubylib/designer/examples/colortool/images/editraise.png Binary files differnew file mode 100644 index 00000000..02415689 --- /dev/null +++ b/qtruby/rubylib/designer/examples/colortool/images/editraise.png diff --git a/qtruby/rubylib/designer/examples/colortool/images/filenew b/qtruby/rubylib/designer/examples/colortool/images/filenew Binary files differnew file mode 100644 index 00000000..9de6e839 --- /dev/null +++ b/qtruby/rubylib/designer/examples/colortool/images/filenew diff --git a/qtruby/rubylib/designer/examples/colortool/images/filenew.png b/qtruby/rubylib/designer/examples/colortool/images/filenew.png Binary files differnew file mode 100644 index 00000000..8577f068 --- /dev/null +++ b/qtruby/rubylib/designer/examples/colortool/images/filenew.png diff --git a/qtruby/rubylib/designer/examples/colortool/images/fileopen b/qtruby/rubylib/designer/examples/colortool/images/fileopen Binary files differnew file mode 100644 index 00000000..a21f9466 --- /dev/null +++ b/qtruby/rubylib/designer/examples/colortool/images/fileopen diff --git a/qtruby/rubylib/designer/examples/colortool/images/fileopen.png b/qtruby/rubylib/designer/examples/colortool/images/fileopen.png Binary files differnew file mode 100644 index 00000000..85dab435 --- /dev/null +++ b/qtruby/rubylib/designer/examples/colortool/images/fileopen.png diff --git a/qtruby/rubylib/designer/examples/colortool/images/filesave b/qtruby/rubylib/designer/examples/colortool/images/filesave Binary files differnew file mode 100644 index 00000000..f6d9af92 --- /dev/null +++ b/qtruby/rubylib/designer/examples/colortool/images/filesave diff --git a/qtruby/rubylib/designer/examples/colortool/images/filesave.png b/qtruby/rubylib/designer/examples/colortool/images/filesave.png Binary files differnew file mode 100644 index 00000000..21309aa6 --- /dev/null +++ b/qtruby/rubylib/designer/examples/colortool/images/filesave.png diff --git a/qtruby/rubylib/designer/examples/colortool/images/iconview.png b/qtruby/rubylib/designer/examples/colortool/images/iconview.png Binary files differnew file mode 100644 index 00000000..d755399d --- /dev/null +++ b/qtruby/rubylib/designer/examples/colortool/images/iconview.png diff --git a/qtruby/rubylib/designer/examples/colortool/images/richtextedit.png b/qtruby/rubylib/designer/examples/colortool/images/richtextedit.png Binary files differnew file mode 100644 index 00000000..9f75c258 --- /dev/null +++ b/qtruby/rubylib/designer/examples/colortool/images/richtextedit.png diff --git a/qtruby/rubylib/designer/examples/colortool/images/searchfind b/qtruby/rubylib/designer/examples/colortool/images/searchfind Binary files differnew file mode 100644 index 00000000..7aaefe22 --- /dev/null +++ b/qtruby/rubylib/designer/examples/colortool/images/searchfind diff --git a/qtruby/rubylib/designer/examples/colortool/images/searchfind.png b/qtruby/rubylib/designer/examples/colortool/images/searchfind.png Binary files differnew file mode 100644 index 00000000..8f7d8adb --- /dev/null +++ b/qtruby/rubylib/designer/examples/colortool/images/searchfind.png diff --git a/qtruby/rubylib/designer/examples/colortool/images/table.png b/qtruby/rubylib/designer/examples/colortool/images/table.png Binary files differnew file mode 100644 index 00000000..663b32f0 --- /dev/null +++ b/qtruby/rubylib/designer/examples/colortool/images/table.png diff --git a/qtruby/rubylib/designer/examples/colortool/images/tabwidget.png b/qtruby/rubylib/designer/examples/colortool/images/tabwidget.png Binary files differnew file mode 100644 index 00000000..3a160446 --- /dev/null +++ b/qtruby/rubylib/designer/examples/colortool/images/tabwidget.png diff --git a/qtruby/rubylib/designer/examples/colortool/images/widgetstack.png b/qtruby/rubylib/designer/examples/colortool/images/widgetstack.png Binary files differnew file mode 100644 index 00000000..979409cf --- /dev/null +++ b/qtruby/rubylib/designer/examples/colortool/images/widgetstack.png diff --git a/qtruby/rubylib/designer/examples/colortool/main.rb b/qtruby/rubylib/designer/examples/colortool/main.rb new file mode 100644 index 00000000..9ebe84cb --- /dev/null +++ b/qtruby/rubylib/designer/examples/colortool/main.rb @@ -0,0 +1,20 @@ +require 'Qt'
+
+require 'mainform.rb'
+require 'mainform.ui.rb'
+
+require 'colornameform.rb'
+require 'colornameform.ui.rb'
+
+require 'optionsform.rb'
+
+require 'findform.rb'
+require 'findform.ui.rb'
+
+require 'qmake_image_collection.rb'
+
+a = Qt::Application.new(ARGV)
+w = MainForm.new
+a.mainWidget = w
+w.show
+a.exec
diff --git a/qtruby/rubylib/designer/examples/colortool/mainform.ui b/qtruby/rubylib/designer/examples/colortool/mainform.ui new file mode 100644 index 00000000..6c89baca --- /dev/null +++ b/qtruby/rubylib/designer/examples/colortool/mainform.ui @@ -0,0 +1,601 @@ +<!DOCTYPE UI><UI version="3.3" stdsetdef="1"> +<class>MainForm</class> +<widget class="QMainWindow"> + <property name="name"> + <cstring>MainForm</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>600</width> + <height>480</height> + </rect> + </property> + <property name="caption"> + <string>Color Tool</string> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QWidgetStack"> + <property name="name"> + <cstring>colorWidgetStack</cstring> + </property> + <property name="frameShape"> + <enum>NoFrame</enum> + </property> + <property name="frameShadow"> + <enum>Plain</enum> + </property> + <widget class="QWidget"> + <property name="name"> + <cstring>tablePage</cstring> + </property> + <attribute name="id"> + <number>0</number> + </attribute> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QTable"> + <column> + <property name="text"> + <string>Name</string> + </property> + </column> + <column> + <property name="text"> + <string>Hex</string> + </property> + </column> + <column> + <property name="text"> + <string>Web</string> + </property> + </column> + <property name="name"> + <cstring>colorTable</cstring> + </property> + <property name="numRows"> + <number>0</number> + </property> + <property name="numCols"> + <number>3</number> + </property> + <property name="readOnly"> + <bool>true</bool> + </property> + </widget> + </hbox> + </widget> + <widget class="QWidget"> + <property name="name"> + <cstring>iconsPage</cstring> + </property> + <attribute name="id"> + <number>1</number> + </attribute> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QIconView"> + <property name="name"> + <cstring>colorIconView</cstring> + </property> + <property name="gridX"> + <number>100</number> + </property> + <property name="resizeMode"> + <enum>Adjust</enum> + </property> + </widget> + </vbox> + </widget> + </widget> + </hbox> +</widget> +<menubar> + <property name="name"> + <cstring>menubar</cstring> + </property> + <item text="&File" name="fileMenu"> + <action name="fileNewAction"/> + <action name="fileOpenAction"/> + <action name="fileSaveAction"/> + <action name="fileSaveAsAction"/> + <separator/> + <action name="fileExitAction"/> + </item> + <item text="&Edit" name="editMenu"> + <action name="editAddAction"/> + <action name="editCutAction"/> + <action name="editCopyAction"/> + <separator/> + <action name="editFindAction"/> + <separator/> + <action name="optionsAction"/> + </item> + <item text="&View" name="viewMenu"> + <action name="viewTableAction"/> + <action name="viewIconsAction"/> + </item> + <item text="&Help" name="helpMenu"> + <action name="helpContentsAction"/> + <action name="helpIndexAction"/> + <separator/> + <action name="helpAboutAction"/> + </item> +</menubar> +<toolbars> + <toolbar dock="2"> + <property name="name"> + <cstring>toolBar</cstring> + </property> + <property name="label"> + <string>Tools</string> + </property> + <action name="fileNewAction"/> + <action name="fileOpenAction"/> + <action name="fileSaveAction"/> + <separator/> + <action name="editAddAction"/> + <action name="editCutAction"/> + <action name="editCopyAction"/> + <action name="editFindAction"/> + <separator/> + <action name="optionsAction"/> + <separator/> + <action name="viewTableAction"/> + <action name="viewIconsAction"/> + </toolbar> +</toolbars> +<actions> + <action> + <property name="name"> + <cstring>fileNewAction</cstring> + </property> + <property name="iconSet"> + <iconset>filenew.png</iconset> + </property> + <property name="text"> + <string>New</string> + </property> + <property name="menuText"> + <string>&New</string> + </property> + <property name="accel"> + <string>Ctrl+N</string> + </property> + </action> + <action> + <property name="name"> + <cstring>fileOpenAction</cstring> + </property> + <property name="iconSet"> + <iconset>fileopen.png</iconset> + </property> + <property name="text"> + <string>Open</string> + </property> + <property name="menuText"> + <string>&Open...</string> + </property> + <property name="accel"> + <string>Ctrl+O</string> + </property> + </action> + <action> + <property name="name"> + <cstring>fileSaveAction</cstring> + </property> + <property name="iconSet"> + <iconset>filesave.png</iconset> + </property> + <property name="text"> + <string>Save</string> + </property> + <property name="menuText"> + <string>&Save</string> + </property> + <property name="accel"> + <string>Ctrl+S</string> + </property> + </action> + <action> + <property name="name"> + <cstring>fileSaveAsAction</cstring> + </property> + <property name="text"> + <string>Save As</string> + </property> + <property name="menuText"> + <string>Save &As...</string> + </property> + <property name="accel"> + <string></string> + </property> + </action> + <action> + <property name="name"> + <cstring>fileExitAction</cstring> + </property> + <property name="text"> + <string>Exit</string> + </property> + <property name="menuText"> + <string>E&xit</string> + </property> + <property name="accel"> + <string></string> + </property> + </action> + <action> + <property name="name"> + <cstring>editCutAction</cstring> + </property> + <property name="iconSet"> + <iconset>editcut.png</iconset> + </property> + <property name="text"> + <string>Delete</string> + </property> + <property name="menuText"> + <string>&Delete</string> + </property> + <property name="accel"> + <string>Ctrl+X</string> + </property> + </action> + <action> + <property name="name"> + <cstring>editCopyAction</cstring> + </property> + <property name="iconSet"> + <iconset>editcopy.png</iconset> + </property> + <property name="text"> + <string>Copy</string> + </property> + <property name="menuText"> + <string>&Copy</string> + </property> + <property name="accel"> + <string>Ctrl+C</string> + </property> + </action> + <action> + <property name="name"> + <cstring>editFindAction</cstring> + </property> + <property name="iconSet"> + <iconset>searchfind.png</iconset> + </property> + <property name="text"> + <string>Find</string> + </property> + <property name="menuText"> + <string>&Find...</string> + </property> + <property name="accel"> + <string>Ctrl+F</string> + </property> + </action> + <action> + <property name="name"> + <cstring>helpContentsAction</cstring> + </property> + <property name="text"> + <string>Contents</string> + </property> + <property name="menuText"> + <string>&Contents...</string> + </property> + <property name="accel"> + <string></string> + </property> + </action> + <action> + <property name="name"> + <cstring>helpIndexAction</cstring> + </property> + <property name="text"> + <string>Index</string> + </property> + <property name="menuText"> + <string>&Index...</string> + </property> + <property name="accel"> + <string></string> + </property> + </action> + <action> + <property name="name"> + <cstring>helpAboutAction</cstring> + </property> + <property name="text"> + <string>About</string> + </property> + <property name="menuText"> + <string>&About</string> + </property> + <property name="accel"> + <string></string> + </property> + </action> + <action> + <property name="name"> + <cstring>optionsAction</cstring> + </property> + <property name="iconSet"> + <iconset>tabwidget.png</iconset> + </property> + <property name="text"> + <string>Options</string> + </property> + <property name="menuText"> + <string>&Options...</string> + </property> + </action> + <actiongroup> + <property name="name"> + <cstring>viewActionGroup</cstring> + </property> + <property name="text"> + <string>View</string> + </property> + <property name="menuText"> + <string>View</string> + </property> + <property name="usesDropDown"> + <bool>false</bool> + </property> + <action> + <property name="name"> + <cstring>viewTableAction</cstring> + </property> + <property name="toggleAction"> + <bool>true</bool> + </property> + <property name="on"> + <bool>true</bool> + </property> + <property name="iconSet"> + <iconset>table.png</iconset> + </property> + <property name="text"> + <string>View Table</string> + </property> + <property name="menuText"> + <string>View &Table</string> + </property> + <property name="toolTip"> + <string>View Table (Ctrl+T)</string> + </property> + <property name="accel"> + <string>Ctrl+T</string> + </property> + </action> + <action> + <property name="name"> + <cstring>viewIconsAction</cstring> + </property> + <property name="toggleAction"> + <bool>true</bool> + </property> + <property name="iconSet"> + <iconset>iconview.png</iconset> + </property> + <property name="text"> + <string>View Icons</string> + </property> + <property name="menuText"> + <string>View &Icons</string> + </property> + <property name="toolTip"> + <string>View Icons (Ctrl+I)</string> + </property> + <property name="accel"> + <string>Ctrl+I</string> + </property> + </action> + </actiongroup> + <action> + <property name="name"> + <cstring>editAddAction</cstring> + </property> + <property name="iconSet"> + <iconset>widgetstack.png</iconset> + </property> + <property name="text"> + <string>Add</string> + </property> + <property name="menuText"> + <string>&Add...</string> + </property> + <property name="accel"> + <string>Ctrl+A</string> + </property> + </action> +</actions> +<connections> + <connection> + <sender>fileNewAction</sender> + <signal>activated()</signal> + <receiver>MainForm</receiver> + <slot>fileNew()</slot> + </connection> + <connection> + <sender>fileOpenAction</sender> + <signal>activated()</signal> + <receiver>MainForm</receiver> + <slot>fileOpen()</slot> + </connection> + <connection> + <sender>fileSaveAction</sender> + <signal>activated()</signal> + <receiver>MainForm</receiver> + <slot>fileSave()</slot> + </connection> + <connection> + <sender>fileSaveAsAction</sender> + <signal>activated()</signal> + <receiver>MainForm</receiver> + <slot>fileSaveAs()</slot> + </connection> + <connection> + <sender>fileExitAction</sender> + <signal>activated()</signal> + <receiver>MainForm</receiver> + <slot>fileExit()</slot> + </connection> + <connection> + <sender>editCutAction</sender> + <signal>activated()</signal> + <receiver>MainForm</receiver> + <slot>editCut()</slot> + </connection> + <connection> + <sender>editCopyAction</sender> + <signal>activated()</signal> + <receiver>MainForm</receiver> + <slot>editCopy()</slot> + </connection> + <connection> + <sender>editFindAction</sender> + <signal>activated()</signal> + <receiver>MainForm</receiver> + <slot>editFind()</slot> + </connection> + <connection> + <sender>helpIndexAction</sender> + <signal>activated()</signal> + <receiver>MainForm</receiver> + <slot>helpIndex()</slot> + </connection> + <connection> + <sender>helpContentsAction</sender> + <signal>activated()</signal> + <receiver>MainForm</receiver> + <slot>helpContents()</slot> + </connection> + <connection> + <sender>helpAboutAction</sender> + <signal>activated()</signal> + <receiver>MainForm</receiver> + <slot>helpAbout()</slot> + </connection> + <connection> + <sender>colorTable</sender> + <signal>currentChanged(int,int)</signal> + <receiver>MainForm</receiver> + <slot>changedTableColor(int,int)</slot> + </connection> + <connection> + <sender>colorIconView</sender> + <signal>currentChanged(QIconViewItem*)</signal> + <receiver>MainForm</receiver> + <slot>changedIconColor(QIconViewItem*)</slot> + </connection> + <connection> + <sender>viewActionGroup</sender> + <signal>selected(QAction*)</signal> + <receiver>MainForm</receiver> + <slot>changeView(QAction*)</slot> + </connection> + <connection> + <sender>editAddAction</sender> + <signal>activated()</signal> + <receiver>MainForm</receiver> + <slot>editAdd()</slot> + </connection> + <connection> + <sender>optionsAction</sender> + <signal>activated()</signal> + <receiver>MainForm</receiver> + <slot>editOptions()</slot> + </connection> + <connection> + <sender>colorWidgetStack</sender> + <signal>aboutToShow(int)</signal> + <receiver>MainForm</receiver> + <slot>aboutToShow()</slot> + </connection> +</connections> +<includes> + <include location="local" impldecl="in declaration">findform.h</include> + <include location="local" impldecl="in implementation">qsettings.h</include> + <include location="local" impldecl="in implementation">qradiobutton.h</include> + <include location="local" impldecl="in implementation">qcheckbox.h</include> + <include location="local" impldecl="in implementation">colornameform.h</include> + <include location="local" impldecl="in implementation">qcolordialog.h</include> + <include location="local" impldecl="in implementation">qregexp.h</include> + <include location="local" impldecl="in implementation">qfile.h</include> + <include location="local" impldecl="in implementation">qfiledialog.h</include> + <include location="local" impldecl="in implementation">qapplication.h</include> + <include location="local" impldecl="in implementation">qcolor.h</include> + <include location="local" impldecl="in implementation">qstring.h</include> + <include location="local" impldecl="in implementation">qpainter.h</include> + <include location="local" impldecl="in implementation">qstatusbar.h</include> + <include location="local" impldecl="in implementation">qmessagebox.h</include> + <include location="local" impldecl="in implementation">qclipboard.h</include> + <include location="local" impldecl="in implementation">qlabel.h</include> + <include location="local" impldecl="in implementation">qlineedit.h</include> + <include location="local" impldecl="in implementation">optionsform.h</include> + <include location="local" impldecl="in implementation">mainform.ui.h</include> +</includes> +<forwards> + <forward>class QString;</forward> + <forward>class QColor;</forward> +</forwards> +<variables> + <variable>QStringList m_comments;</variable> + <variable>QString m_filename;</variable> + <variable>bool m_changed;</variable> + <variable>bool m_table_dirty;</variable> + <variable>bool m_icons_dirty;</variable> + <variable>int m_clip_as;</variable> + <variable>bool m_show_web;</variable> + <variable>QClipboard *clipboard;</variable> + <variable>FindForm *findForm;</variable> + <variable>QMap<QString,QColor> m_colors;</variable> +</variables> +<slots> + <slot>fileNew()</slot> + <slot>fileOpen()</slot> + <slot>fileSave()</slot> + <slot>fileSaveAs()</slot> + <slot>closeEvent( QCloseEvent * )</slot> + <slot>fileExit()</slot> + <slot>editCut()</slot> + <slot>editCopy()</slot> + <slot>editFind()</slot> + <slot>lookfor( const QString & text )</slot> + <slot>helpIndex()</slot> + <slot>helpContents()</slot> + <slot>helpAbout()</slot> + <slot>changedTableColor( int row, int )</slot> + <slot>changedIconColor( QIconViewItem * item )</slot> + <slot>changeView( QAction * action )</slot> + <slot>editAdd()</slot> + <slot>editOptions()</slot> + <slot>aboutToShow()</slot> +</slots> +<functions> + <function access="private">init()</function> + <function>clearData( bool fillWithDefaults )</function> + <function>populate()</function> + <function returnType="QPixmap">colorSwatch( const QColor color )</function> + <function>load( const QString & filename )</function> + <function returnType="bool">okToClear()</function> + <function>changedColor( const QString & name )</function> + <function returnType="bool">isWebColor( QColor color )</function> + <function>loadSettings()</function> + <function>saveSettings()</function> +</functions> +<pixmapinproject/> +<layoutdefaults spacing="6" margin="11"/> +</UI> diff --git a/qtruby/rubylib/designer/examples/colortool/mainform.ui.rb b/qtruby/rubylib/designer/examples/colortool/mainform.ui.rb new file mode 100644 index 00000000..471233bd --- /dev/null +++ b/qtruby/rubylib/designer/examples/colortool/mainform.ui.rb @@ -0,0 +1,530 @@ +class MainForm + + CLIP_AS_HEX = 0 + CLIP_AS_NAME = 1 + CLIP_AS_RGB = 2 + COL_NAME = 0 + COL_HEX = 1 + COL_WEB = 2 + WINDOWS_REGISTRY = "/QtExamples" + APP_KEY = "/ColorTool/" + +def init() + @clipboard = Qt::Application.clipboard() + if @clipboard.supportsSelection() + @clipboard.selectionMode = true + end + + findForm = 0 + loadSettings() + @filename = nil + @changed = false + @table_dirty = true + @icons_dirty = true + @colors = {} + @comments = {} + clearData( true ) +end + +def clearData( fillWithDefaults ) + setCaption( "Color Tool" ) + + @colors.clear() + @comments.clear() + + if fillWithDefaults + @colors["black"] = Qt::black + @colors["blue"] = Qt::blue + @colors["cyan"] = Qt::cyan + @colors["darkblue"] = Qt::darkBlue + @colors["darkcyan"] = Qt::darkCyan + @colors["darkgray"] = Qt::darkGray + @colors["darkgreen"] = Qt::darkGreen + @colors["darkmagenta"] = Qt::darkMagenta + @colors["darkred"] = Qt::darkRed + @colors["darkyellow"] = Qt::darkYellow + @colors["gray"] = Qt::gray + @colors["green"] = Qt::green + @colors["lightgray"] = Qt::lightGray + @colors["magenta"] = Qt::magenta + @colors["red"] = Qt::red + @colors["white"] = Qt::white + @colors["yellow"] = Qt::yellow + end + + populate() +end + +def populate() + if @table_dirty + (0...@colorTable.numRows).each do |r| + (0...@colorTable.numCols).each do |c| + @colorTable.clearCell( r, c ) + end + end + + @colorTable.numRows = @colors.length + if ! @colors.empty? + pixmap = Qt::Pixmap.new( 22, 22 ) + row = 0 + @colors.sort.each do |pair| + key = pair[0] + color = pair[1] + pixmap.fill( color ) + @colorTable.setText( row, COL_NAME, key ) + @colorTable.setPixmap( row, COL_NAME, pixmap ); + @colorTable.setText( row, COL_HEX, color.name().upcase() ) + if @show_web + item = Qt::CheckTableItem.new( @colorTable, "" ) + item.checked = webColor?( color ) + @colorTable.setItem( row, COL_WEB, item ) + end + row += 1 + end + @colorTable.setCurrentCell( 0, 0 ) + end + @colorTable.adjustColumn( COL_NAME ) + @colorTable.adjustColumn( COL_HEX ) + if @show_web + @colorTable.showColumn( COL_WEB ) + @colorTable.adjustColumn( COL_WEB ) + else + @colorTable.hideColumn( COL_WEB ) + end + @table_dirty = FALSE; + end + + if @icons_dirty + @colorIconView.clear() + + @colors.each do |key, data| + Qt::IconViewItem.new( @colorIconView, key, colorSwatch(data) ) + end + @icons_dirty = false + end +end + +def colorSwatch( color ) + pixmap = Qt::Pixmap.new( 80, 80 ) + pixmap.fill( white ) + painter = Qt::Painter.new + painter.begin( pixmap ) + painter.pen = NoPen + painter.brush = color + painter.drawEllipse( 0, 0, 80, 80 ) + painter.end() + return pixmap +end + +def fileNew() + if okToClear() + @filename = nil + @changed = false + @table_dirty = true + @icons_dirty = true + clearData( false ) + end +end + +def fileOpen() + if ! okToClear() + return + end + + filename = Qt::FileDialog.getOpenFileName( + nil, "Colors (*.txt)", self, + "file open", "Color Tool -- File Open" ) + if ! filename.nil? + load( filename ) + else + statusBar().message( "File Open abandoned", 2000 ) + end +end + +def fileSave() + if @filename.nil? + fileSaveAs() + return + end + + file = Qt::File.new( @filename ) + if file.open( Qt::IO_WriteOnly ) + stream = Qt::TextStream.new( file ) + if ! @comments.empty? + stream << @comments + "\n" << "\n" + end + + @colors.each do |key, color| + stream << "%3d %3d %3d \t\t#{key}" % [color.red, color.green, color.blue] << "\n" + end + file.close() + setCaption( "Color Tool -- #{@filename}" ) + statusBar().message( "Saved #{@colors.length} colors to '#{@filename}'", 3000 ) + @changed = false; + else + statusBar().message( "Failed to save '#{@filename}'", 3000 ) + end +end + +def fileSaveAs() + filename = Qt::FileDialog.getSaveFileName( + nil, "Colors (*.txt)", self, + "file save as", "Color Tool -- File Save As" ) + if ! filename.nil? + ans = 0 + if Qt::File.exists( filename ) + ans = Qt::MessageBox.warning( + self, "Color Tool -- Overwrite File", + "Overwrite\n'#{filename}'?" , + "&Yes", "&No", nil, 1, 1 ) + end + if ans == 0 + @filename = filename + fileSave() + return + end + end + statusBar().message( "Saving abandoned", 2000 ) +end + +def load( filename ) + clearData( false ) + @filename = filename + regex = Regexp.new( "^\\s*(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\S+.*)$" ) + file = Qt::File.new( filename ) + if file.open( Qt::IO_ReadOnly ) + statusBar().message( "Loading '#{filename}'..." ) + stream = Qt::TextStream.new( file ) + while ! stream.eof() + line = stream.readLine() + m = regex.match( line ) + if m.nil? + @comments += line + else + @colors[m[4]] = Qt::Color.new(m[1].to_i,m[2].to_i,m[3].to_i ) + end + end + file.close() + @filename = filename + setCaption( "Color Tool -- #{@filename}" ) + statusBar().message( "Loaded '#{@filename}'", 3000 ) + visible = @colorWidgetStack.visibleWidget() + @icons_dirty = ! ( @table_dirty = ( visible == @tablePage ) ) + populate() + @icons_dirty = ! ( @table_dirty = ( visible != @tablePage ) ) + @changed = false + else + statusBar().message( "Failed to load '#{@filename}'", 3000 ) + end +end + + +def okToClear() + if @changed + if @filename.nil? + msg = "Unnamed colors " + else + msg = "Colors '#{@filename}'\n" + end + msg += "has been changed." + ans = Qt::MessageBox.information( + self, + "Color Tool -- Unsaved Changes", + msg, "&Save", "Cancel", "&Abandon", + 0, 1 ) + if ans == 0 + fileSave() + elsif ans == 1 + return false + end + end + + return true +end + +def closeEvent( e ) + fileExit() +end + +def fileExit() + if okToClear() + saveSettings() + Qt::Application.exit( 0 ) + end +end + +def editCut() + visible = @colorWidgetStack.visibleWidget() + statusBar().message( "Deleting '#{name}'" ) + + if visible == @tablePage && @colorTable.numRows() > 0 + row = @colorTable.currentRow() + name = @colorTable.text( row, 0 ) + @colorTable.removeRow( @colorTable.currentRow() ) + if row < @colorTable.numRows() + @colorTable.setCurrentCell( row, 0 ) + elsif @colorTable.numRows() > 0 + @colorTable.setCurrentCell( @colorTable.numRows() - 1, 0 ) + end + @icons_dirty = true + elsif visible == @iconsPage && @colorIconView.currentItem() + item = colorIconView.currentItem() + name = item.text() + if @colorIconView.count() == 1 + @colorIconView.clear() + else + current = item.nextItem() + if ! current + current = item.prevItem() + end + item.dispose + if current + @colorIconView.currentItem = current + end + @colorIconView.arrangeItemsInGrid() + end + @table_dirty = true + end + + if ! name.nil? + @colors.delete( name ) + @changed = true + statusBar().message( "Deleted '#{name}'", 5000 ) + else + statusBar().message( "Failed to delete '#{name}'", 5000 ) + end +end + +def editCopy() + visible = @colorWidgetStack.visibleWidget() + + if visible == @tablePage && @colorTable.numRows() + row = @colorTable.currentRow() + text = @colorTable.text( row, 0 ) + elsif visible == @iconsPage && ! @colorIconView.currentItem().nil? + item = @colorIconView.currentItem() + text = item.text() + end + if ! text.nil? + color = @colors[text] + case @clip_as + when CLIP_AS_HEX then text = color.name() + when CLIP_AS_NAME then + when CLIP_AS_RGB + text = "#{color.red},#{color.green},#{color.blue}" + end + @clipboard.text = text + statusBar().message( "Copied '" + text + "' to the clipboard" ) + end +end + +def editFind() + if ! @findForm + @findForm = FindForm.new( self ) + connect( @findForm, SIGNAL( 'lookfor(const QString&)' ), + self, SLOT( 'lookfor(const QString&)' ) ) + end + @findForm.show() +end + +def lookfor( text ) + if text.empty? + return + end + ltext = text.downcase() + visible = colorWidgetStack.visibleWidget() + found = false + + if visible == @tablePage && @colorTable.numRows() > 0 + row = @colorTable.currentRow() + (row+1...@colorTable.numRows).each do |i| + if @colorTable.text( i, 0 ).downcase().include?( ltext ) + @colorTable.setCurrentCell( i, 0 ) + @colorTable.clearSelection() + @colorTable.selectRow( i ) + found = true + break + end + end + if ! found + @colorTable.setCurrentCell( row, 0 ) + end + elsif visible == @iconsPage + start = @colorIconView.currentItem() + item = start.nextItem() unless start.nil? + while !item.nil? + if item.text().downcase().include?( ltext ) + @colorIconView.currentItem = item + @colorIconView.ensureItemVisible( item ) + found = true + break + end + item = item.nextItem() + end + if ! found && !start.nil? + @colorIconView.currentItem = start + end + end + if ! found + statusBar().message( "Could not find '#{text}' after here" ) + @findForm.notfound() + end +end + + + +def helpIndex() +end + +def helpContents() +end + +def helpAbout() +end + + +def changedTableColor( row, i ) + changedColor( @colorTable.text( row, COL_NAME ) ) +end + +def changedIconColor( item ) + changedColor( item.text() ) +end + +def changedColor( name ) + color = @colors[name] + r = color.red() + g = color.green() + b = color.blue() + statusBar().message( "%s \"%s\" (%d,%d,%d) %s {%.3f %.3f %.3f}" % + [name, color.name.upcase, + r, g, b, webColor?( color ) ? ' web' : '', + r / 255.0, g / 255.0, b / 255.0] ) +end + +def changeView(action) + if action == @viewTableAction + @colorWidgetStack.raiseWidget( @tablePage ) + else + @colorWidgetStack.raiseWidget( @iconsPage ) + end +end + +def webColor?( color ) + r = color.red() + g = color.green() + b = color.blue() + + return ( ( r == 0 || r == 51 || r == 102 || + r == 153 || r == 204 || r == 255 ) && + ( g == 0 || g == 51 || g == 102 || + g == 153 || g == 204 || g == 255 ) && + ( b == 0 || b == 51 || b == 102 || + b == 153 || b == 204 || b == 255 ) ) +end + + +def editAdd() + color = Qt::white + if ! @colors.empty? + visible = @colorWidgetStack.visibleWidget() + if visible == @tablePage + color = Qt::Color.new(@colorTable.text( @colorTable.currentRow(), + @colorTable.currentColumn() )) + else + color = Qt::Color.new(@colorIconView.currentItem().text()) + end + end + color = Qt::ColorDialog.getColor( color, self ) + if color.valid? + pixmap = Qt::Pixmap.new( 80, 10 ) + pixmap.fill( color ) + colorForm = ColorNameForm.new( self, "color", true ) + colorForm.setColors( @colors ) + colorForm.colorLabel.setPixmap( pixmap ) + if colorForm.exec() + name = colorForm.colorLineEdit.text() + @colors[name] = color + pixmap = Qt::Pixmap.new( 22, 22 ) + pixmap.fill( color ) + row = @colorTable.currentRow() + @colorTable.insertRows( row, 1 ) + @colorTable.setText( row, COL_NAME, name ) + @colorTable.setPixmap( row, COL_NAME, pixmap ) + @colorTable.setText( row, COL_HEX, color.name().upcase() ) + if @show_web + item = Qt::CheckTableItem.new( @colorTable, "" ) + item.checked = webColor?( color ) + @colorTable.setItem( row, COL_WEB, item ) + end + @colorTable.setCurrentCell( row, 0 ) + + Qt::IconViewItem.new( @colorIconView, name, + colorSwatch( color ) ) + @changed = true + end + end +end + +def editOptions() + options = OptionsForm.new( self, "options", true ) + case @clip_as + when CLIP_AS_HEX + options.hexRadioButton.checked = true + when CLIP_AS_NAME + options.nameRadioButton.checked = true + when CLIP_AS_RGB + options.rgbRadioButton.checked = true + end + options.webCheckBox.checked = @show_web + + if options.exec() + if options.hexRadioButton.checked? + @clip_as = CLIP_AS_HEX + elsif options.nameRadioButton.checked? + @clip_as = CLIP_AS_NAME + elsif options.rgbRadioButton.checked? + @clip_as = CLIP_AS_RGB + end + @table_dirty = @show_web != options.webCheckBox.checked? + @show_web = options.webCheckBox.checked? + populate() + end +end + +def loadSettings() + settings = Qt::Settings.new + settings.insertSearchPath( Qt::Settings::Windows, WINDOWS_REGISTRY ) + windowWidth = settings.readNumEntry( APP_KEY + "WindowWidth", 550 ) + windowHeight = settings.readNumEntry( APP_KEY + "WindowHeight", 500 ) + windowX = settings.readNumEntry( APP_KEY + "WindowX", 0 ) + windowY = settings.readNumEntry( APP_KEY + "WindowY", 0 ) + @clip_as = settings.readNumEntry( APP_KEY + "ClipAs", CLIP_AS_HEX ) + @show_web = settings.readBoolEntry( APP_KEY + "ShowWeb", true ) + if ! settings.readBoolEntry( APP_KEY + "View", true ) + @colorWidgetStack.raiseWidget( @iconsPage ) + @viewIconsAction.on = true + end + + resize( windowWidth, windowHeight ) + move( windowX, windowY ) +end + +def saveSettings() + settings = Qt::Settings.new + settings.insertSearchPath( Qt::Settings::Windows, WINDOWS_REGISTRY ) + settings.writeEntry( APP_KEY + "WindowWidth", width() ) + settings.writeEntry( APP_KEY + "WindowHeight", height() ) + settings.writeEntry( APP_KEY + "WindowX", x() ) + settings.writeEntry( APP_KEY + "WindowY", y() ) + settings.writeEntry( APP_KEY + "ClipAs", @clip_as ) + settings.writeEntry( APP_KEY + "ShowWeb", @show_web ) + settings.writeEntry( APP_KEY + "View", @colorWidgetStack.visibleWidget() == @tablePage ) +end + + +def aboutToShow() + populate() +end + +end diff --git a/qtruby/rubylib/designer/examples/colortool/optionsform.ui b/qtruby/rubylib/designer/examples/colortool/optionsform.ui new file mode 100644 index 00000000..1bb7e8ef --- /dev/null +++ b/qtruby/rubylib/designer/examples/colortool/optionsform.ui @@ -0,0 +1,153 @@ +<!DOCTYPE UI><UI version="3.0" stdsetdef="1"> +<class>OptionsForm</class> +<widget class="QDialog"> + <property name="name"> + <cstring>OptionsForm</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>306</width> + <height>226</height> + </rect> + </property> + <property name="caption"> + <string>Color Tool - Options</string> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QGroupBox"> + <property name="name"> + <cstring>GroupBox2</cstring> + </property> + <property name="title"> + <string>Table View</string> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QCheckBox"> + <property name="name"> + <cstring>webCheckBox</cstring> + </property> + <property name="text"> + <string>Indicate &Web colors</string> + </property> + <property name="checked"> + <bool>true</bool> + </property> + </widget> + </hbox> + </widget> + <widget class="QButtonGroup"> + <property name="name"> + <cstring>ButtonGroup1</cstring> + </property> + <property name="title"> + <string>Copy to Clipboard As</string> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QRadioButton"> + <property name="name"> + <cstring>hexRadioButton</cstring> + </property> + <property name="text"> + <string>&Hex, e.g. #AB347F</string> + </property> + <property name="checked"> + <bool>true</bool> + </property> + </widget> + <widget class="QRadioButton"> + <property name="name"> + <cstring>nameRadioButton</cstring> + </property> + <property name="text"> + <string>&Name, e.g. light blue</string> + </property> + </widget> + <widget class="QRadioButton"> + <property name="name"> + <cstring>rgbRadioButton</cstring> + </property> + <property name="text"> + <string>&RGB, e.g. 51,255,102</string> + </property> + </widget> + </vbox> + </widget> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>Layout5</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <spacer> + <property name="name"> + <cstring>Spacer2</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>0</width> + <height>10</height> + </size> + </property> + </spacer> + <widget class="QPushButton"> + <property name="name"> + <cstring>okPushButton</cstring> + </property> + <property name="text"> + <string>&OK</string> + </property> + <property name="default"> + <bool>true</bool> + </property> + </widget> + <widget class="QPushButton"> + <property name="name"> + <cstring>cancelPushButton</cstring> + </property> + <property name="text"> + <string>&Cancel</string> + </property> + </widget> + </hbox> + </widget> + </vbox> +</widget> +<connections> + <connection> + <sender>okPushButton</sender> + <signal>clicked()</signal> + <receiver>OptionsForm</receiver> + <slot>accept()</slot> + </connection> + <connection> + <sender>cancelPushButton</sender> + <signal>clicked()</signal> + <receiver>OptionsForm</receiver> + <slot>reject()</slot> + </connection> +</connections> +<includes> + <include location="local" impldecl="in implementation">optionsform.ui.h</include> +</includes> +<pixmapinproject/> +<layoutdefaults spacing="6" margin="11"/> +</UI> diff --git a/qtruby/rubylib/designer/rbuic/LICENSE.GPL b/qtruby/rubylib/designer/rbuic/LICENSE.GPL new file mode 100644 index 00000000..3e51afd8 --- /dev/null +++ b/qtruby/rubylib/designer/rbuic/LICENSE.GPL @@ -0,0 +1,280 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 51 Franklin Street, Fifth Floor, Cambridge, MA 02110-1301, USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS diff --git a/qtruby/rubylib/designer/rbuic/Makefile.am b/qtruby/rubylib/designer/rbuic/Makefile.am new file mode 100644 index 00000000..a8eef55d --- /dev/null +++ b/qtruby/rubylib/designer/rbuic/Makefile.am @@ -0,0 +1,24 @@ +AM_CPPFLAGS = -DUIC -DQT_INTERNAL_XML +AM_CXXFLAGS = $(KDE_CXXFLAGS) + +bin_PROGRAMS = rbuic +noinst_LTLIBRARIES = librbuic.la + +INCLUDES = $(all_includes) + +METASOURCES = AUTO + +librbuic_la_SOURCES = widgetdatabase.cpp uic.cpp subclassing.cpp parser.cpp object.cpp form.cpp embed.cpp domtool.cpp +librbuic_la_LIBADD = $(LIB_QT) $(LIBZ) + +rbuic_SOURCES = main.cpp +rbuic_LDADD = librbuic.la $(all_libraries) +rbuic_LDFLAGS = + +EXTRA_DIST = domtool.cpp domtool.h embed.cpp form.cpp globaldefs.h main.cpp object.cpp parser.cpp parser.h subclassing.cpp uic.cpp uic.h widgetdatabase.cpp widgetdatabase.h widgetinterface.h + +messages: + LIST=`find . -name \*.h -o -name \*.hh -o -name \*.H -o -name \*.hxx -o -name \*.hpp -o -name \*.cpp -o -name \*.cc -o -name \*.cxx -o -name \*.ecpp -o -name \*.C`; \ + if test -n "$$LIST"; then \ + $(XGETTEXT) $$LIST -o $(podir)/puic.pot; \ + fi diff --git a/qtruby/rubylib/designer/rbuic/TODO b/qtruby/rubylib/designer/rbuic/TODO new file mode 100644 index 00000000..8e780973 --- /dev/null +++ b/qtruby/rubylib/designer/rbuic/TODO @@ -0,0 +1,4 @@ + +- Database code needs more testing? + + diff --git a/qtruby/rubylib/designer/rbuic/domtool.cpp b/qtruby/rubylib/designer/rbuic/domtool.cpp new file mode 100644 index 00000000..1c30486f --- /dev/null +++ b/qtruby/rubylib/designer/rbuic/domtool.cpp @@ -0,0 +1,453 @@ +/********************************************************************** +** Copyright (C) 2000 Trolltech AS. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition +** licenses may use this file in accordance with the Qt Commercial License +** Agreement provided with the Software. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for +** information about Qt Commercial License Agreements. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ + +#include "domtool.h" + +#include <qsizepolicy.h> +#include <qcolor.h> +#include <qcursor.h> +#include <qdatetime.h> +#include <qrect.h> +#include <qsize.h> +#include <qfont.h> +#include <qdom.h> + +/*! + \class DomTool domtool.h + \brief Tools for the dom + + A collection of static functions used by Resource (part of the + designer) and Uic. + +*/ + +/*! + Returns the contents of property \a name of object \a e as + variant or the variant passed as \a defValue if the property does + not exist. + + \sa hasProperty() +*/ +QVariant DomTool::readProperty( const QDomElement& e, const QString& name, const QVariant& defValue, QString& comment ) +{ + QDomElement n; + for ( n = e.firstChild().toElement(); !n.isNull(); n = n.nextSibling().toElement() ) { + if ( n.tagName() == "property" ) { + if ( n.attribute( "name" ) != name ) + continue; + return elementToVariant( n.firstChild().toElement(), defValue, comment ); + } + } + return defValue; +} + + +/*! + \overload + */ +QVariant DomTool::readProperty( const QDomElement& e, const QString& name, const QVariant& defValue ) +{ + QString comment; + return readProperty( e, name, defValue, comment ); +} + +/*! + Returns wheter object \a e defines property \a name or not. + + \sa readProperty() + */ +bool DomTool::hasProperty( const QDomElement& e, const QString& name ) +{ + QDomElement n; + for ( n = e.firstChild().toElement(); !n.isNull(); n = n.nextSibling().toElement() ) { + if ( n.tagName() == "property" ) { + if ( n.attribute( "name" ) != name ) + continue; + return true; + } + } + return false; +} + +QStringList DomTool::propertiesOfType( const QDomElement& e, const QString& type ) +{ + QStringList result; + QDomElement n; + for ( n = e.firstChild().toElement(); !n.isNull(); n = n.nextSibling().toElement() ) { + if ( n.tagName() == "property" ) { + QDomElement n2 = n.firstChild().toElement(); + if ( n2.tagName() == type ) + result += n.attribute( "name" ); + } + } + return result; +} + + +QVariant DomTool::elementToVariant( const QDomElement& e, const QVariant& defValue ) +{ + QString dummy; + return elementToVariant( e, defValue, dummy ); +} + +/*! + Interprets element \a e as variant and returns the result of the interpretation. + */ +QVariant DomTool::elementToVariant( const QDomElement& e, const QVariant& defValue, QString &comment ) +{ + QVariant v; + if ( e.tagName() == "rect" ) { + QDomElement n3 = e.firstChild().toElement(); + int x = 0, y = 0, w = 0, h = 0; + while ( !n3.isNull() ) { + if ( n3.tagName() == "x" ) + x = n3.firstChild().toText().data().toInt(); + else if ( n3.tagName() == "y" ) + y = n3.firstChild().toText().data().toInt(); + else if ( n3.tagName() == "width" ) + w = n3.firstChild().toText().data().toInt(); + else if ( n3.tagName() == "height" ) + h = n3.firstChild().toText().data().toInt(); + n3 = n3.nextSibling().toElement(); + } + v = QVariant( QRect( x, y, w, h ) ); + } else if ( e.tagName() == "point" ) { + QDomElement n3 = e.firstChild().toElement(); + int x = 0, y = 0; + while ( !n3.isNull() ) { + if ( n3.tagName() == "x" ) + x = n3.firstChild().toText().data().toInt(); + else if ( n3.tagName() == "y" ) + y = n3.firstChild().toText().data().toInt(); + n3 = n3.nextSibling().toElement(); + } + v = QVariant( QPoint( x, y ) ); + } else if ( e.tagName() == "size" ) { + QDomElement n3 = e.firstChild().toElement(); + int w = 0, h = 0; + while ( !n3.isNull() ) { + if ( n3.tagName() == "width" ) + w = n3.firstChild().toText().data().toInt(); + else if ( n3.tagName() == "height" ) + h = n3.firstChild().toText().data().toInt(); + n3 = n3.nextSibling().toElement(); + } + v = QVariant( QSize( w, h ) ); + } else if ( e.tagName() == "color" ) { + v = QVariant( readColor( e ) ); + } else if ( e.tagName() == "font" ) { + QDomElement n3 = e.firstChild().toElement(); + QFont f( defValue.toFont() ); + while ( !n3.isNull() ) { + if ( n3.tagName() == "family" ) + f.setFamily( n3.firstChild().toText().data() ); + else if ( n3.tagName() == "pointsize" ) + f.setPointSize( n3.firstChild().toText().data().toInt() ); + else if ( n3.tagName() == "bold" ) + f.setBold( n3.firstChild().toText().data().toInt() ); + else if ( n3.tagName() == "italic" ) + f.setItalic( n3.firstChild().toText().data().toInt() ); + else if ( n3.tagName() == "underline" ) + f.setUnderline( n3.firstChild().toText().data().toInt() ); + else if ( n3.tagName() == "strikeout" ) + f.setStrikeOut( n3.firstChild().toText().data().toInt() ); + n3 = n3.nextSibling().toElement(); + } + v = QVariant( f ); + } else if ( e.tagName() == "string" ) { + v = QVariant( e.firstChild().toText().data() ); + QDomElement n = e; + n = n.nextSibling().toElement(); + if ( n.tagName() == "comment" ) + comment = n.firstChild().toText().data(); + } else if ( e.tagName() == "cstring" ) { + v = QVariant( QCString( e.firstChild().toText().data() ) ); + } else if ( e.tagName() == "number" ) { + bool ok = true; + v = QVariant( e.firstChild().toText().data().toInt( &ok ) ); + if ( !ok ) + v = QVariant( e.firstChild().toText().data().toDouble() ); + } else if ( e.tagName() == "bool" ) { + QString t = e.firstChild().toText().data(); + v = QVariant( t == "true" || t == "1", 0 ); + } else if ( e.tagName() == "pixmap" ) { + v = QVariant( e.firstChild().toText().data() ); + } else if ( e.tagName() == "iconset" ) { + v = QVariant( e.firstChild().toText().data() ); + } else if ( e.tagName() == "image" ) { + v = QVariant( e.firstChild().toText().data() ); + } else if ( e.tagName() == "enum" ) { + v = QVariant( e.firstChild().toText().data() ); + } else if ( e.tagName() == "set" ) { + v = QVariant( e.firstChild().toText().data() ); + } else if ( e.tagName() == "sizepolicy" ) { + QDomElement n3 = e.firstChild().toElement(); + QSizePolicy sp; + while ( !n3.isNull() ) { + if ( n3.tagName() == "hsizetype" ) + sp.setHorData( (QSizePolicy::SizeType)n3.firstChild().toText().data().toInt() ); + else if ( n3.tagName() == "vsizetype" ) + sp.setVerData( (QSizePolicy::SizeType)n3.firstChild().toText().data().toInt() ); + else if ( n3.tagName() == "horstretch" ) + sp.setHorStretch( n3.firstChild().toText().data().toInt() ); + else if ( n3.tagName() == "verstretch" ) + sp.setVerStretch( n3.firstChild().toText().data().toInt() ); + n3 = n3.nextSibling().toElement(); + } + v = QVariant( sp ); + } else if ( e.tagName() == "cursor" ) { + v = QVariant( QCursor( e.firstChild().toText().data().toInt() ) ); + } else if ( e.tagName() == "stringlist" ) { + QStringList lst; + QDomElement n; + for ( n = e.firstChild().toElement(); !n.isNull(); n = n.nextSibling().toElement() ) + lst << n.firstChild().toText().data(); + v = QVariant( lst ); + } else if ( e.tagName() == "date" ) { + QDomElement n3 = e.firstChild().toElement(); + int y, m, d; + y = m = d = 0; + while ( !n3.isNull() ) { + if ( n3.tagName() == "year" ) + y = n3.firstChild().toText().data().toInt(); + else if ( n3.tagName() == "month" ) + m = n3.firstChild().toText().data().toInt(); + else if ( n3.tagName() == "day" ) + d = n3.firstChild().toText().data().toInt(); + n3 = n3.nextSibling().toElement(); + } + v = QVariant( QDate( y, m, d ) ); + } else if ( e.tagName() == "time" ) { + QDomElement n3 = e.firstChild().toElement(); + int h, m, s; + h = m = s = 0; + while ( !n3.isNull() ) { + if ( n3.tagName() == "hour" ) + h = n3.firstChild().toText().data().toInt(); + else if ( n3.tagName() == "minute" ) + m = n3.firstChild().toText().data().toInt(); + else if ( n3.tagName() == "second" ) + s = n3.firstChild().toText().data().toInt(); + n3 = n3.nextSibling().toElement(); + } + v = QVariant( QTime( h, m, s ) ); + } else if ( e.tagName() == "datetime" ) { + QDomElement n3 = e.firstChild().toElement(); + int h, mi, s, y, mo, d ; + h = mi = s = y = mo = d = 0; + while ( !n3.isNull() ) { + if ( n3.tagName() == "hour" ) + h = n3.firstChild().toText().data().toInt(); + else if ( n3.tagName() == "minute" ) + mi = n3.firstChild().toText().data().toInt(); + else if ( n3.tagName() == "second" ) + s = n3.firstChild().toText().data().toInt(); + else if ( n3.tagName() == "year" ) + y = n3.firstChild().toText().data().toInt(); + else if ( n3.tagName() == "month" ) + mo = n3.firstChild().toText().data().toInt(); + else if ( n3.tagName() == "day" ) + d = n3.firstChild().toText().data().toInt(); + n3 = n3.nextSibling().toElement(); + } + v = QVariant( QDateTime( QDate( y, mo, d ), QTime( h, mi, s ) ) ); + } + return v; +} + + +/*! Returns the color which is returned in the dom element \a e. + */ + +QColor DomTool::readColor( const QDomElement &e ) +{ + QDomElement n = e.firstChild().toElement(); + int r= 0, g = 0, b = 0; + while ( !n.isNull() ) { + if ( n.tagName() == "red" ) + r = n.firstChild().toText().data().toInt(); + else if ( n.tagName() == "green" ) + g = n.firstChild().toText().data().toInt(); + else if ( n.tagName() == "blue" ) + b = n.firstChild().toText().data().toInt(); + n = n.nextSibling().toElement(); + } + + return QColor( r, g, b ); +} + +/*! + Returns the contents of attribute \a name of object \a e as + variant or the variant passed as \a defValue if the attribute does + not exist. + + \sa hasAttribute() + */ +QVariant DomTool::readAttribute( const QDomElement& e, const QString& name, const QVariant& defValue, QString& comment ) +{ + QDomElement n; + for ( n = e.firstChild().toElement(); !n.isNull(); n = n.nextSibling().toElement() ) { + if ( n.tagName() == "attribute" ) { + if ( n.attribute( "name" ) != name ) + continue; + return elementToVariant( n.firstChild().toElement(), defValue, comment ); + } + } + return defValue; +} + +/*! + \overload +*/ +QVariant DomTool::readAttribute( const QDomElement& e, const QString& name, const QVariant& defValue ) +{ + QString comment; + return readAttribute( e, name, defValue, comment ); +} + +/*! + Returns wheter object \a e defines attribute \a name or not. + + \sa readAttribute() + */ +bool DomTool::hasAttribute( const QDomElement& e, const QString& name ) +{ + QDomElement n; + for ( n = e.firstChild().toElement(); !n.isNull(); n = n.nextSibling().toElement() ) { + if ( n.tagName() == "attribute" ) { + if ( n.attribute( "name" ) != name ) + continue; + return true; + } + } + return false; +} + +static bool toBool( const QString& s ) +{ + return s == "true" || s.toInt() != 0; +} + +/*! + Convert Qt 2.x format to Qt 3.0 format if necessary +*/ +void DomTool::fixDocument( QDomDocument& doc ) +{ + QDomElement e; + QDomNode n; + QDomNodeList nl; + int i = 0; + + e = doc.firstChild().toElement(); + if ( e.tagName() != "UI" ) + return; + + // latest version, don't do anything + if ( e.hasAttribute("version") && e.attribute("version").toDouble() > 3.0 ) + return; + + nl = doc.elementsByTagName( "property" ); + + // in 3.0, we need to fix a spelling error + if ( e.hasAttribute("version") && e.attribute("version").toDouble() == 3.0 ) { + for ( i = 0; i < (int) nl.length(); i++ ) { + QDomElement el = nl.item(i).toElement(); + QString s = el.attribute( "name" ); + if ( s == "resizeable" ) { + el.removeAttribute( "name" ); + el.setAttribute( "name", "resizable" ); + } + } + return; + } + + + // in versions smaller than 3.0 we need to change more + e.setAttribute( "version", 3.0 ); + + e.setAttribute("stdsetdef", 1 ); + for ( i = 0; i < (int) nl.length(); i++ ) { + e = nl.item(i).toElement(); + QString name; + QDomElement n2 = e.firstChild().toElement(); + if ( n2.tagName() == "name" ) { + name = n2.firstChild().toText().data(); + if ( name == "resizeable" ) + e.setAttribute( "name", "resizable" ); + else + e.setAttribute( "name", name ); + e.removeChild( n2 ); + } + bool stdset = toBool( e.attribute( "stdset" ) ); + if ( stdset || name == "toolTip" || name == "whatsThis" || + name == "buddy" || + e.parentNode().toElement().tagName() == "item" || + e.parentNode().toElement().tagName() == "spacer" || + e.parentNode().toElement().tagName() == "column" + ) + e.removeAttribute( "stdset" ); + else + e.setAttribute( "stdset", 0 ); + } + + nl = doc.elementsByTagName( "attribute" ); + for ( i = 0; i < (int) nl.length(); i++ ) { + e = nl.item(i).toElement(); + QString name; + QDomElement n2 = e.firstChild().toElement(); + if ( n2.tagName() == "name" ) { + name = n2.firstChild().toText().data(); + e.setAttribute( "name", name ); + e.removeChild( n2 ); + } + } + + nl = doc.elementsByTagName( "image" ); + for ( i = 0; i < (int) nl.length(); i++ ) { + e = nl.item(i).toElement(); + QString name; + QDomElement n2 = e.firstChild().toElement(); + if ( n2.tagName() == "name" ) { + name = n2.firstChild().toText().data(); + e.setAttribute( "name", name ); + e.removeChild( n2 ); + } + } + + nl = doc.elementsByTagName( "widget" ); + for ( i = 0; i < (int) nl.length(); i++ ) { + e = nl.item(i).toElement(); + QString name; + QDomElement n2 = e.firstChild().toElement(); + if ( n2.tagName() == "class" ) { + name = n2.firstChild().toText().data(); + e.setAttribute( "class", name ); + e.removeChild( n2 ); + } + } + +} + diff --git a/qtruby/rubylib/designer/rbuic/domtool.h b/qtruby/rubylib/designer/rbuic/domtool.h new file mode 100644 index 00000000..61b4269a --- /dev/null +++ b/qtruby/rubylib/designer/rbuic/domtool.h @@ -0,0 +1,53 @@ +/********************************************************************** +** Copyright (C) 2000 Trolltech AS. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition +** licenses may use this file in accordance with the Qt Commercial License +** Agreement provided with the Software. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for +** information about Qt Commercial License Agreements. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ + +#ifndef DOMTOOL_H +#define DOMTOOL_H + +#include <qvariant.h> +#include <qnamespace.h> + +class QDomElement; +class QDomDocument; + +class DomTool : public Qt +{ +public: + static QVariant readProperty( const QDomElement& e, const QString& name, const QVariant& defValue ); + static QVariant readProperty( const QDomElement& e, const QString& name, const QVariant& defValue, QString& comment ); + static bool hasProperty( const QDomElement& e, const QString& name ); + static QStringList propertiesOfType( const QDomElement& e, const QString& type ); + static QVariant elementToVariant( const QDomElement& e, const QVariant& defValue ); + static QVariant elementToVariant( const QDomElement& e, const QVariant& defValue, QString &comment ); + static QVariant readAttribute( const QDomElement& e, const QString& name, const QVariant& defValue ); + static QVariant readAttribute( const QDomElement& e, const QString& name, const QVariant& defValue, QString& comment ); + static bool hasAttribute( const QDomElement& e, const QString& name ); + static QColor readColor( const QDomElement &e ); + static void fixDocument( QDomDocument& ); +}; + + +#endif // DOMTOOL_H diff --git a/qtruby/rubylib/designer/rbuic/embed.cpp b/qtruby/rubylib/designer/rbuic/embed.cpp new file mode 100644 index 00000000..89985968 --- /dev/null +++ b/qtruby/rubylib/designer/rbuic/embed.cpp @@ -0,0 +1,297 @@ +/********************************************************************** +** Copyright (C) 2000 Trolltech AS. All rights reserved. +** Copyright (c) 2001 Phil Thompson <phil@river-bank.demon.co.uk> +** Copyright (c) 2002 Riverbank Computing Limited <info@riverbankcomputing.co.uk> +** Copyright (c) 2002 Germain Garand <germain@ebooksfrance.com> +** +** This file is part of Qt Designer. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ +/* +** 06/2002 : Initial release of puic, the PerlQt User Interface Compiler, +** a work derivated from uic (the Qt User Interface Compiler) +** and pyuic (the PyQt User Interface Compiler). +** +** G.Garand +** +** 08/2003 : Initial release of rbuic, the QtRuby User Interface Compiler, +** a work derived from the PerlQt puic. +** +** Richard Dale +** +**********************************************************************/ + +#include "uic.h" +#include <qfile.h> +#include <qimage.h> +#include <qstringlist.h> +#include <qdatetime.h> +#include <qfileinfo.h> +#define NO_STATIC_COLORS +#include <globaldefs.h> +#include <qregexp.h> +#include <stdio.h> +#include <stdlib.h> +#include <ctype.h> + +struct EmbedImage +{ + int width, height, depth; + int numColors; + QRgb* colorTable; + QString name; + QString cname; + bool alpha; +}; + +static QString convertToCIdentifier( const char *s ) +{ + QString r = s; + int len = r.length(); + if ( len > 0 && !isalpha( (char)r[0].latin1() ) ) + r[0] = '_'; + for ( int i=1; i<len; i++ ) { + if ( !isalnum( (char)r[i].latin1() ) ) + r[i] = '_'; + } + return r; +} + + +static ulong embedData( QTextStream& out, const uchar* input, int nbytes ) +{ +#ifndef QT_NO_IMAGE_COLLECTION_COMPRESSION + QByteArray bazip( qCompress( input, nbytes ) ); + ulong len = bazip.size(); +#else + ulong len = nbytes; +#endif + static const char hexdigits[] = "0123456789abcdef"; + QString s; + for ( int i=0; i<(int)len; i++ ) { + if ( (i%14) == 0 ) { + s += "\n "; + out << (const char*)s; + s.truncate( 0 ); + } + uint v = (uchar) +#ifndef QT_NO_IMAGE_COLLECTION_COMPRESSION + bazip +#else + input +#endif + [i]; + s += "0x"; + s += hexdigits[(v >> 4) & 15]; + s += hexdigits[v & 15]; + if ( i < (int)len-1 ) + s += ','; + } + if ( s.length() ) + out << (const char*)s; + return len; +} + +static void embedData( QTextStream& out, const QRgb* input, int n ) +{ + out << hex; + const QRgb *v = input; + for ( int i=0; i<n; i++ ) { + if ( (i%14) == 0 ) + out << "\n "; + out << "0x"; + out << hex << *v++; + if ( i < n-1 ) + out << ','; + } + out << dec; // back to decimal mode +} + +void Uic::embed( QTextStream& out, const char* project, const QStringList& images ) +{ + + QString cProject = convertToCIdentifier( project ); + + QStringList::ConstIterator it; + out << "# Image collection for project '" << project << "'." << endl; + out << "#" << endl; + out << "# Generated from reading image files: " << endl; + for ( it = images.begin(); it != images.end(); ++it ) + out << "# " << *it << endl; + out << "#" << endl; + out << "# Created: " << QDateTime::currentDateTime().toString() << endl; + out << "# by: The QtRuby User Interface Compiler (rbuic)" << endl; + out << "#" << endl; + out << "# WARNING! All changes made in this file will be lost!" << endl; + out << endl; + if (hasKDEwidget) { + out << "require 'Korundum'" << endl; + } else { + out << "require 'Qt'" << endl; + } + out << endl; + + out << indent << "class MimeSourceFactory_" << cProject << " < Qt::MimeSourceFactory" << endl; + out << endl; + + QPtrList<EmbedImage> list_image; + int image_count = 0; + for ( it = images.begin(); it != images.end(); ++it ) { + QImage img; + if ( !img.load( *it ) ) { + fprintf( stderr, "rbuic: cannot load image file %s\n", (*it).latin1() ); + continue; + } + EmbedImage *e = new EmbedImage; + e->width = img.width(); + e->height = img.height(); + e->depth = img.depth(); + e->numColors = img.numColors(); + e->colorTable = new QRgb[e->numColors]; + e->alpha = img.hasAlphaBuffer(); + memcpy(e->colorTable, img.colorTable(), e->numColors*sizeof(QRgb)); + QFileInfo fi( *it ); + e->name = fi.fileName(); + e->cname = QString("@@image_%1").arg( image_count++); + list_image.append( e ); + out << "# " << *it << endl; + QString imgname = (const char *)e->cname; + + QString s; + if ( e->depth == 1 ) + img = img.convertBitOrder(QImage::BigEndian); + out << indent << imgname << "_data = ["; + embedData( out, img.bits(), img.numBytes() ); + out << "]\n\n"; + if ( e->numColors ) { + out << indent << imgname << "_ctable = ["; + embedData( out, e->colorTable, e->numColors ); + out << "]\n\n"; + } + } + + ++indent; + if ( !list_image.isEmpty() ) { + out << indent << "@@embed_images = {\n"; + ++indent; + EmbedImage *e = list_image.first(); + while ( e ) + { + out << indent << "\"" << e->name << "\"" << " => [" << e->cname << "_data, " + << e->width << ", " << e->height << ", " << e->depth << ", " + << (e->numColors ? e->cname + "_ctable" : QString::fromLatin1( "[]" ) ) << ", " + << (e->alpha ? "true" : "false") << "]," << endl; + e = list_image.next(); + } + --indent; + out << indent << "}" << endl; + + out << endl; + out << indent << "@@images = Hash.new" << endl; + out << endl; + out << indent << "def uic_findImage( name )" << endl; + ++indent; + out << indent << "if !@@images[name].nil?" << endl; + ++indent; + out << indent << "return @@images[name]" << endl; + --indent; + out << indent << "end" << endl; + + out << indent << "if @@embed_images[name].nil?" << endl; + ++indent; + out << indent << "return Qt::Image.new()" << endl; + --indent; + out << indent << "end" << endl; + out << indent << endl; +#ifndef QT_NO_IMAGE_COLLECTION_COMPRESSION + out << indent << "baunzip = qUncompress( @@embed_images[name][0].pack(\"C*\")," << endl; + out << indent << " @@embed_images[name][0].length )" << endl; + out << indent << "img = Qt::Image.new( baunzip.data," << endl; + out << indent << " @@embed_images[name][1]," << endl; + out << indent << " @@embed_images[name][2]," << endl; + out << indent << " @@embed_images[name][3]," << endl; + out << indent << " @@embed_images[name][4]," << endl; + out << indent << " @@embed_images[name][4].length," << endl; + out << indent << " Qt::Image::BigEndian )" << endl; +#else + out << indent << "img = Qt::Image.new( @@embed_images[name][0].pack(\"C*\")," << endl; + out << indent << " @@embed_images[name][1]," << endl; + out << indent << " @@embed_images[name][2]," << endl; + out << indent << " @@embed_images[name][3]," << endl; + out << indent << " @@embed_images[name][4]," << endl; + out << indent << " @@embed_images[name][4].length," << endl; + out << indent << " Qt::Image::BigEndian )" << endl; +#endif + out << indent << "if @@embed_images[name][5]" << endl; + ++indent; + out << indent << "img.setAlphaBuffer(true)" << endl; + --indent; + out << indent << "end" << endl; + out << indent << "@@images[name] = img" << endl; + out << indent << "return img" << endl; + --indent; + out << indent << "end" << endl; + out << endl; + out << indent << "def data( abs_name )" << endl; + ++indent; + out << indent << "img = uic_findImage(abs_name)" << endl; + out << indent << "if img.nil?" << endl; + ++indent; + out << indent << "Qt::MimeSourceFactory.removeFactory(self)" << endl; + out << indent << "s = Qt::MimeSourceFactory.defaultFactory().data(abs_name);" << endl; + out << indent << "Qt::MimeSourceFactory.addFactory(self)" << endl; + out << indent << "return s" << endl; + --indent; + out << indent << "end" << endl; + out << indent << "Qt::MimeSourceFactory.defaultFactory().setImage(abs_name, img)" << endl; + out << indent << "return Qt::MimeSourceFactory.defaultFactory().data(abs_name)" << endl; + --indent; + out << indent << "end" << endl; + --indent; + out << indent << "end" << endl; + + out << endl; + out << endl; + + out << indent << "module StaticInitImages_" << cProject << endl; + ++indent; + out << indent << "@@factories = Hash.new" << endl; + out << indent << endl; + out << indent << "def StaticInitImages_" << cProject << ".qInitImages" << endl; + ++indent; + out << indent << "factory = MimeSourceFactory_" << cProject << ".new()" << endl; + out << indent << "Qt::MimeSourceFactory.defaultFactory().addFactory(factory)" << endl; + out << indent << "@@factories['MimeSourceFactory_" << cProject << "'] = factory" << endl; + --indent; + out << indent << "end" << endl; + out << endl; + out << indent << "def StaticInitImages_" << cProject << ".qCleanupImages" << endl; + ++indent; + out << indent << "for values in @@factories" << endl; + ++indent; + out << indent << "Qt::MimeSourceFactory.defaultFactory().removeFactory(values)" << endl; + --indent; + out << indent << "end" << endl; + out << indent << "@@factories = nil" << endl; + --indent; + out << indent << "end" << endl; + out << endl; + out << indent << "StaticInitImages_" << cProject << ".qInitImages" << endl; + --indent; + out << indent << "end" << endl; + out << endl; + } +} diff --git a/qtruby/rubylib/designer/rbuic/form.cpp b/qtruby/rubylib/designer/rbuic/form.cpp new file mode 100644 index 00000000..7efbacd1 --- /dev/null +++ b/qtruby/rubylib/designer/rbuic/form.cpp @@ -0,0 +1,1017 @@ +/********************************************************************** +** Copyright (C) 2000 Trolltech AS. All rights reserved. +** Copyright (c) 2002 Germain Garand <germain@ebooksfrance.com> +** +** This file is part of Qt Designer. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ +/* +** 06/2002 : Initial release of puic, the PerlQt User Interface Compiler, +** a work derivated from uic (the Qt User Interface Compiler) +** and pyuic (the PyQt User Interface Compiler). +** +** G.Garand +** +**********************************************************************/ + +#include "uic.h" +#include "parser.h" +#include "widgetdatabase.h" +#include "domtool.h" + +#include <qstringlist.h> +#include <qregexp.h> +#include <qfile.h> +#include <qfileinfo.h> + +#define NO_STATIC_COLORS +#include <globaldefs.h> + +#include <zlib.h> + +static QByteArray unzipXPM( QString data, ulong& length ) +{ + const int lengthOffset = 4; + int baSize = data.length() / 2 + lengthOffset; + uchar *ba = new uchar[ baSize ]; + for ( int i = lengthOffset; i < baSize; ++i ) { + char h = data[ 2 * (i-lengthOffset) ].latin1(); + char l = data[ 2 * (i-lengthOffset) + 1 ].latin1(); + uchar r = 0; + if ( h <= '9' ) + r += h - '0'; + else + r += h - 'a' + 10; + r = r << 4; + if ( l <= '9' ) + r += l - '0'; + else + r += l - 'a' + 10; + ba[ i ] = r; + } + // qUncompress() expects the first 4 bytes to be the expected length of the + // uncompressed data + ba[0] = ( length & 0xff000000 ) >> 24; + ba[1] = ( length & 0x00ff0000 ) >> 16; + ba[2] = ( length & 0x0000ff00 ) >> 8; + ba[3] = ( length & 0x000000ff ); + QByteArray baunzip = qUncompress( ba, baSize ); + delete[] ba; + return baunzip; +} + +static QString imageDataName(QString name) { + QString result = name + "_data"; + result.replace("@", "@@"); + return result; +} + +/*! + Creates an implementation ( cpp-file ) for the form given in \a e + + \sa createFormDecl(), createObjectImpl() + */ +void Uic::createFormImpl( const QDomElement &e ) +{ + QDomElement n; + QDomNodeList nl; + int i; + QString objClass = getClassName( e ); + if ( objClass.isEmpty() ) + return; + QString objName = getObjectName( e ); + + if (hasKDEwidget) { + out << indent << "require 'Korundum'" << endl << endl; + } else { + out << indent << "require 'Qt'" << endl << endl; + } + + // generate local and local includes required + QStringList globalIncludes, localIncludes; + QStringList::Iterator it; + QStringList sqlClasses; + + QMap<QString, CustomInclude> customWidgetIncludes; + QMap<QString, QString> functionImpls; + + // find additional slots + QStringList extraSlots; + QStringList extraSlotTypes; + nl = e.parentNode().toElement().elementsByTagName( "slot" ); + for ( i = 0; i < (int) nl.length(); i++ ) { + n = nl.item(i).toElement(); + if ( n.parentNode().toElement().tagName() != "slots" + && n.parentNode().toElement().tagName() != "connections" ) + continue; + if ( n.attribute( "language", "C++" ) != "C++" ) + continue; + QString slotName = n.firstChild().toText().data().stripWhiteSpace(); + if ( slotName.endsWith( ";" ) ) + slotName = slotName.left( slotName.length() - 1 ); + + extraSlots += Parser::cleanArgs(slotName); + extraSlotTypes += n.attribute( "returnType", "void" ); + } + + // find signals + QStringList extraSignals; + nl = e.parentNode().toElement().elementsByTagName( "signal" ); + for ( i = 0; i < (int) nl.length(); i++ ) { + n = nl.item(i).toElement(); + if ( n.parentNode().toElement().tagName() != "signals" + && n.parentNode().toElement().tagName() != "connections" ) + continue; + if ( n.attribute( "language", "C++" ) != "C++" ) + continue; + QString sigName = n.firstChild().toText().data().stripWhiteSpace(); + if ( sigName.endsWith( ";" ) ) + sigName = sigName.left( sigName.length() - 1 ); + extraSignals += sigName; + } + + //find additional functions + QStringList extraFunctions; + for ( n = e; !n.isNull(); n = n.nextSibling().toElement() ) { + if ( n.tagName() == "functions" ) { // compatibility + for ( QDomElement n2 = n.firstChild().toElement(); !n2.isNull(); n2 = n2.nextSibling().toElement() ) { + if ( n2.tagName() == "function" ) { + QString fname; + if( !n2.attribute("name").isNull() ) + { + fname = n2.attribute( "name" ); + fname = Parser::cleanArgs( fname ); + functionImpls.insert( fname, n2.firstChild().toText().data() ); + } + else + { + fname = n2.text(); + fname = Parser::cleanArgs( fname ); + } + extraFunctions += fname; + } + } + } else if ( n.tagName() == "customwidgets" ) { + QDomElement n2 = n.firstChild().toElement(); + while ( !n2.isNull() ) { + if ( n2.tagName() == "customwidget" ) { + QDomElement n3 = n2.firstChild().toElement(); + QString cl, header; + WidgetDatabaseRecord *r = new WidgetDatabaseRecord; + while ( !n3.isNull() ) { + if ( n3.tagName() == "class" ) { + cl = n3.firstChild().toText().data(); + r->name = cl; + } else if ( n3.tagName() == "header" ) { + CustomInclude ci; + ci.header = n3.firstChild().toText().data(); + ci.location = n3.attribute( "location", "global" ); + r->includeFile = ci.header; + header = ci.header; + customWidgetIncludes.insert( cl, ci ); + } + WidgetDatabase::append( r ); + n3 = n3.nextSibling().toElement(); + } + + if (cl.isEmpty()) + cl = "UnnamedCustomClass"; + + int ext = header.findRev('.'); + + if (ext >= 0) + header.truncate(ext); + + if (header.isEmpty()) + header = cl.lower(); + +// if (!nofwd) +// out << "use " << cl << ";" << endl; // FIXME: what about header ? + } + n2 = n2.nextSibling().toElement(); + } + } + } + + out << "class " << nameOfClass << " < " << objClass << endl << endl; + + // QtRuby sig/slot declaration + + ++indent; + + if ( !extraSlots.isEmpty() ) { + out << indent << "slots 'languageChange()'"; + for ( it = extraSlots.begin(); it != extraSlots.end(); ++it ) { + if (it == extraSlots.begin()) { + out << "," << endl; + } + rubySlot( it ); + out << ( ((*it) == extraSlots.last()) ? "":",") << endl; + } + out << endl; + } + + // create signals + if ( !extraSignals.isEmpty() ) { + out << indent << "signals "; + --indent; + for ( it = extraSignals.begin(); it != extraSignals.end(); ++it ) { + rubySlot( it ); + if (it == extraSignals.begin()) { + ++indent; + } + out << ( ((*it) == extraSignals.last()) ? "":",") << endl; + } + out << endl; + } + + + // children + if( !objectNames.isEmpty() ) + qWarning("WARNING : objectNames should be empty at "__FILE__" line %d\n", __LINE__); + nl = e.parentNode().toElement().elementsByTagName( "widget" ); + for ( i = 1; i < (int) nl.length(); i++ ) + { // start at 1, 0 is the toplevel widget + n = nl.item(i).toElement(); + createAttrDecl( n ); + } + objectNames.clear(); + + ++indent; + + // additional attributes (from Designer) + QStringList publicVars, protectedVars, privateVars; + nl = e.parentNode().toElement().elementsByTagName( "variable" ); + for ( i = 0; i < (int)nl.length(); i++ ) { + n = nl.item( i ).toElement(); + // Because of compatibility the next lines have to be commented out. + // Someday it should be uncommented. + //if ( n.parentNode().toElement().tagName() != "variables" ) + // continue; + QString access = n.attribute( "access", "protected" ); + QString var = n.firstChild().toText().data().stripWhiteSpace(); + if ( var.endsWith( ";" ) ) + var.truncate(var.length() - 1); + if ( access == "public" ) + publicVars += var; + else if ( access == "private" ) + privateVars += var; + else + protectedVars += var; + } + + // Databases Connection holders + + registerDatabases( e ); + dbConnections = unique( dbConnections ); + for ( it = dbConnections.begin(); it != dbConnections.end(); ++it ) { + if ( !(*it).isEmpty() && (*it) != "(default)") { + out << indent << (*it) << "Connection" << endl; + } + } + + --indent; + + // additional includes (local or global ) and forward declaractions + nl = e.parentNode().toElement().elementsByTagName( "include" ); + for ( i = 0; i < (int) nl.length(); i++ ) { + QDomElement n2 = nl.item(i).toElement(); + QString s = n2.firstChild().toText().data(); + if ( n2.attribute( "location" ) != "local" ) { + if ( s.right( 5 ) == ".ui.h" && !QFile::exists( s ) ) + continue; + if ( n2.attribute( "impldecl", "in implementation" ) != "in implementation" ) + continue; + globalIncludes += s; + } + } + + // do the local includes afterwards, since global includes have priority on clashes + for ( i = 0; i < (int) nl.length(); i++ ) { + QDomElement n2 = nl.item(i).toElement(); + QString s = n2.firstChild().toText().data(); + if ( n2.attribute( "location" ) == "local" &&!globalIncludes.contains( s ) ) { + if ( s.right( 5 ) == ".ui.h" && !QFile::exists( s ) ) + continue; + if ( n2.attribute( "impldecl", "in implementation" ) != "in implementation" ) + continue; + localIncludes += s; + } + } + + // additional custom widget headers + nl = e.parentNode().toElement().elementsByTagName( "header" ); + for ( i = 0; i < (int) nl.length(); i++ ) { + QDomElement n2 = nl.item(i).toElement(); + QString s = n2.firstChild().toText().data(); + if ( n2.attribute( "location" ) != "local" ) + globalIncludes += s; + else + localIncludes += s; + } + + + // grab slots/funcs defined in ui.h files + for(QStringList::Iterator it = localIncludes.begin(); it != localIncludes.end(); ++it) + { + if((*it).right( 5 ) == ".ui.h") + { + QFile f((*it)); + if( f.open( IO_ReadOnly ) ) + { + QRegExp re("^def\\s+([a-zA-Z0-9_]+)\\s.*$"); + QRegExp re2("^end\\s*$"); + QTextStream t( &f ); + QString s, s2, s3; + while ( !t.eof() ) + { + s = t.readLine(); + int pos = re.search(s); + if(pos == -1) + continue; + s2 = re.cap(1); + s2 += "()"; +// s2 = Parser::cleanArgs(s2); + s3 = "{"; + while( !t.eof() ) + { + s = t.readLine(); + if(re2.search(s) != -1) + break; + s3 += s + "\n"; + } + s3 += "}"; + functionImpls.insert( s2, s3 ); + if( t.eof() ) break; + } + f.close(); + } + } + } + + // includes for child widgets + for ( it = tags.begin(); it != tags.end(); ++it ) { + nl = e.parentNode().toElement().elementsByTagName( *it ); + for ( i = 1; i < (int) nl.length(); i++ ) { // start at 1, 0 is the toplevel widget + QString name = getClassName( nl.item(i).toElement() ); + if ( name == "Spacer" ) { + globalIncludes += "qlayout.h"; + globalIncludes += "qapplication.h"; + continue; + } + if ( name.mid( 4 ) == "ListView" ) + globalIncludes += "qheader.h"; + if ( name != objClass ) { + int wid = WidgetDatabase::idFromClassName( name.replace( QRegExp("^Qt::"), "Q" ) ); + QMap<QString, CustomInclude>::Iterator it = customWidgetIncludes.find( name ); + if ( it == customWidgetIncludes.end() ) + globalIncludes += WidgetDatabase::includeFile( wid ); + } + } + } + + dbConnections = unique( dbConnections ); + if ( dbConnections.count() ) + sqlClasses += "Qt::SqlDatabase"; + if ( dbCursors.count() ) + sqlClasses += "Qt::SqlCursor"; + bool dbForm = false; + if ( dbForms[ "(default)" ].count() ) + dbForm = true; + bool subDbForms = false; + for ( it = dbConnections.begin(); it != dbConnections.end(); ++it ) { + if ( !(*it).isEmpty() && (*it) != "(default)" ) { + if ( dbForms[ (*it) ].count() ) { + subDbForms = true; + break; + } + } + } + if ( dbForm || subDbForms ) { + sqlClasses += "Qt::SqlForm"; + sqlClasses += "Qt::SqlRecord"; + } + + if (globalIncludes.findIndex("qdatatable.h") >= 0) + sqlClasses += "Qt::DataTable"; + + if (globalIncludes.findIndex("qtableview.h") >= 0) + sqlClasses += "Qt::TableView"; + + if (globalIncludes.findIndex("qdatabrowser.h") >= 0) + sqlClasses += "Qt::DataBrowser"; + + out << endl; + + // find out what images are required + QStringList requiredImages; + static const char *imgTags[] = { "pixmap", "iconset", 0 }; + for ( i = 0; imgTags[i] != 0; i++ ) { + nl = e.parentNode().toElement().elementsByTagName( imgTags[i] ); + for ( int j = 0; j < (int) nl.length(); j++ ) { + QString img = "@"; + requiredImages += (img + nl.item(j).firstChild().toText().data()); + } + } + + // register the object and unify its name + QString loadFunction(objName); + objName = registerObject( objName ); + + QStringList images; + QStringList xpmImages; + if ( pixmapLoaderFunction.isEmpty() && !externPixmaps ) + { + // create images + for ( n = e; !n.isNull(); n = n.nextSibling().toElement() ) + { + if ( n.tagName() == "images" ) + { + nl = n.elementsByTagName( "image" ); + for ( i = 0; i < (int) nl.length(); i++ ) + { + QString img = registerObject( nl.item(i).toElement().attribute( "name" ) ); + if ( !requiredImages.contains( img ) ) + continue; + QDomElement tmp = nl.item(i).firstChild().toElement(); + if ( tmp.tagName() != "data" ) + continue; + QString format = tmp.attribute("format", "PNG" ); + QString data = tmp.firstChild().toText().data(); + if ( format == "XPM.GZ" ) + { + xpmImages += img; + ulong length = tmp.attribute("length").toULong(); + QByteArray baunzip = unzipXPM( data, length ); + // shouldn't we test the initial `length' against the + // resulting `length' to catch corrupt UIC files? + int a = 0; + out << indent << imageDataName(img) << " =\n["; + + while ( baunzip[a] != '\"' ) + a++; + for ( ; a < (int) length; a++ ) + { + char ch; + + if ((ch = baunzip[a]) == '}') + { + out << "]\n" << endl; + + break; + } + + out << ch; + } + } + else + { + images += img; + out << indent << imageDataName(img) << " = [ " << endl; + ++indent; + int a ; + for ( a = 0; a < (int) (data.length()/2)-1; a++ ) { + out << "0x" << QString(data[2*a]) << QString(data[2*a+1]) << ","; + if ( a % 12 == 11 ) + out << endl << " "; + else + out << " "; + } + out << "0x" << QString(data[2*a]) << QString(data[2*a+1]) << " ].pack \"C*\"" << endl; + --indent; + out << endl; + } + } + } + } + out << endl; + } + else if ( externPixmaps ) + { + /* + out << indent << "def uic_load_pixmap_" << loadFunction << "( data )" << endl; + ++indent; + out << indent << "pix = Qt::Pixmap.new()" << endl; + out << indent << "m = Qt::MimeSourceFactory.defaultFactory().data(data)" << endl; + out << endl; + out << indent << "if ! m.nil?" << endl; + ++indent; + out << indent << "Qt::ImageDrag.decode(m, pix)" << endl; + --indent; + out << indent << "end" << endl; + out << endl; + out << indent << "return pix" << endl; + --indent; + out << indent << "end" << endl; + out << endl; + out << endl; + pixmapLoaderFunction = "uic_load_pixmap_" + loadFunction; + */ + pixmapLoaderFunction = "Qt::Pixmap.fromMimeSource"; + } + + + // constructor(s) + if ( objClass == "Qt::Dialog" || objClass == "Qt::Wizard" ) { + out << indent << "def initialize(parent = nil, name = nil, modal = false, fl = 0)" << endl; + ++indent; + out << indent << "super" << endl; + } else if ( objClass == "Qt::Widget") { + out << indent << "def initialize(parent = nil, name = nil, fl = 0)" << endl; + ++indent; + out << indent << "super" << endl; + } else if ( objClass == "Qt::MainWindow" ) { + out << indent << "def initialize(parent = nil, name = nil, fl = WType_TopLevel)" << endl; + ++indent; + out << indent << "super" << endl; + isMainWindow = true; + } else { + out << indent << "def initialize(parent = nil, name = nil)" << endl; + ++indent; + out << indent << "super" << endl; + } + + out << endl; + + // create pixmaps for all images + if ( !images.isEmpty() ) { + QStringList::Iterator it; + for ( it = images.begin(); it != images.end(); ++it ) { + out << indent << (*it) << " = Qt::Pixmap.new()" << endl; + out << indent << (*it) << ".loadFromData(" << imageDataName(*it) << ", " << imageDataName(*it) << ".length, \"PNG\")" << endl; + } + out << endl; + } + // create pixmaps for all images + if ( !xpmImages.isEmpty() ) { + for ( it = xpmImages.begin(); it != xpmImages.end(); ++it ) { + out << indent << (*it) << " = Qt::Pixmap.new(" << imageDataName(*it) << ")" << endl; + } + out << endl; + } + + if ( isMainWindow ) + out << indent << "statusBar()" << endl; + + // set the properties + QSize geometry( 0, 0 ); + + for ( n = e.firstChild().toElement(); !n.isNull(); n = n.nextSibling().toElement() ) { + if ( n.tagName() == "property" ) { + bool stdset = stdsetdef; + if ( n.hasAttribute( "stdset" ) ) + stdset = toBool( n.attribute( "stdset" ) ); + QString prop = n.attribute("name"); + QDomElement n2 = n.firstChild().toElement(); + QString value = setObjectProperty( objClass, QString::null, prop, n2, stdset ); + if ( value.isEmpty() ) + continue; + + if ( prop == "geometry" && n2.tagName() == "rect") { + QDomElement n3 = n2.firstChild().toElement(); + while ( !n3.isNull() ) { + if ( n3.tagName() == "width" ) + geometry.setWidth( n3.firstChild().toText().data().toInt() ); + else if ( n3.tagName() == "height" ) + geometry.setHeight( n3.firstChild().toText().data().toInt() ); + n3 = n3.nextSibling().toElement(); + } + } else { + QString call; + if ( stdset ) { + call = mkStdSet( prop ) + "(" + value + ")"; + } else { + call = "setProperty(\"" + prop + "\", Qt::Variant.new(" + value + "))"; + } + + if ( n2.tagName() == "string" ) { + trout << indent << call << endl; + } else if ( prop == "name" ) { + out << indent << "if name.nil?" << endl; + out << indent << "\t" << call << endl; + out << indent << "end" << endl; + } else { + out << indent << call << endl; + } + } + } + } + + out << endl; + + // create all children, some forms have special requirements + + if ( objClass == "Qt::Wizard" ) + { + for ( n = e.firstChild().toElement(); !n.isNull(); n = n.nextSibling().toElement() ) + { + if ( tags.contains( n.tagName() ) ) + { + QString page = createObjectImpl( n, objClass, "self" ); + QString comment; + QString label = DomTool::readAttribute( n, "title", "", comment ).toString(); + out << indent << "addPage(" << page << ", "<< trcall( label ) << ")" << endl; + trout << indent << "setTitle( " << page << ", " << trcall( label, comment ) << " )" << endl; + QVariant def( false, 0 ); + if ( DomTool::hasAttribute( n, "backEnabled" ) ) + out << indent << "setBackEnabled(" << page << "," << mkBool( DomTool::readAttribute( n, "backEnabled", def).toBool() ) << ");" << endl; + if ( DomTool::hasAttribute( n, "nextEnabled" ) ) + out << indent << "setNextEnabled(" << page << "," << mkBool( DomTool::readAttribute( n, "nextEnabled", def).toBool() ) << ");" << endl; + if ( DomTool::hasAttribute( n, "finishEnabled" ) ) + out << indent << "setFinishEnabled(" << page << "," << mkBool( DomTool::readAttribute( n, "finishEnabled", def).toBool() ) << ");" << endl; + if ( DomTool::hasAttribute( n, "helpEnabled" ) ) + out << indent << "setHelpEnabled(" << page << "," << mkBool( DomTool::readAttribute( n, "helpEnabled", def).toBool() ) << ");" << endl; + if ( DomTool::hasAttribute( n, "finish" ) ) + out << indent << "setFinish( " << page << "," << mkBool( DomTool::readAttribute( n, "finish", def).toBool() ) << ");" << endl; + } + } + } + else + { // standard widgets + for ( n = e.firstChild().toElement(); !n.isNull(); n = n.nextSibling().toElement() ) + { + if ( tags.contains( n.tagName() ) ) + createObjectImpl( n, objName, "self" ); + } + } + + // database support + dbConnections = unique( dbConnections ); + if ( dbConnections.count() ) + out << endl; + for ( it = dbConnections.begin(); it != dbConnections.end(); ++it ) { + if ( !(*it).isEmpty() && (*it) != "(default)") { + out << indent << (*it) << "Connection = Qt::SqlDatabase.database(\"" <<(*it) << "\");" << endl; + } + } + + nl = e.parentNode().toElement().elementsByTagName( "widget" ); + for ( i = 1; i < (int) nl.length(); i++ ) { // start at 1, 0 is the toplevel widget + n = nl.item(i).toElement(); + QString s = getClassName( n ); + if ( s == "Qt::DataBrowser" || s == "Qt::DataView" ) { + QString objName = getObjectName( n ); + QString tab = getDatabaseInfo( n, "table" ); + QString con = getDatabaseInfo( n, "connection" ); + out << indent << objName << "Form = Qt::SqlForm.new(self, \"" << objName << "Form\")" << endl; + QDomElement n2; + for ( n2 = n.firstChild().toElement(); !n2.isNull(); n2 = n2.nextSibling().toElement() ) + createFormImpl( n2, objName, con, tab ); + out << indent << objName << ".setForm(" << objName << "Form)" << endl; + } + } + + // actions, toolbars, menubar + bool needEndl = false; + for ( n = e; !n.isNull(); n = n.nextSibling().toElement() ) { + if ( n.tagName() == "actions" ) { + if ( !needEndl ) + out << endl; + createActionImpl( n.firstChild().toElement(), "self" ); + needEndl = true; + } + } + if ( needEndl ) + out << endl; + needEndl = false; + for ( n = e; !n.isNull(); n = n.nextSibling().toElement() ) { + if ( n.tagName() == "toolbars" ) { + if ( !needEndl ) + out << endl; + createToolbarImpl( n, objClass, objName ); + needEndl = true; + } + } + if ( needEndl ) + out << endl; + needEndl = false; + for ( n = e; !n.isNull(); n = n.nextSibling().toElement() ) { + if ( n.tagName() == "menubar" ) { + if ( !needEndl ) + out << endl; + createMenuBarImpl( n, objClass, objName ); + needEndl = true; + } + } + if ( needEndl ) + out << endl; + + out << indent << "languageChange()" << endl; + + // take minimumSizeHint() into account, for height-for-width widgets + if ( !geometry.isNull() ) { + out << indent << "resize( Qt::Size.new(" << geometry.width() << ", " + << geometry.height() << ").expandedTo(minimumSizeHint()) )" << endl; + out << indent << "clearWState( WState_Polished )" << endl; + } + + for ( n = e; !n.isNull(); n = n.nextSibling().toElement() ) { + if ( n.tagName() == "connections" ) { + // setup signals and slots connections + out << endl; + nl = n.elementsByTagName( "connection" ); + for ( i = 0; i < (int) nl.length(); i++ ) { + QString sender, receiver, signal, slot; + for ( QDomElement n2 = nl.item(i).firstChild().toElement(); !n2.isNull(); n2 = n2.nextSibling().toElement() ) { + if ( n2.tagName() == "sender" ) + sender = n2.firstChild().toText().data(); + else if ( n2.tagName() == "receiver" ) + receiver = n2.firstChild().toText().data(); + else if ( n2.tagName() == "signal" ) + signal = n2.firstChild().toText().data(); + else if ( n2.tagName() == "slot" ) + slot = n2.firstChild().toText().data(); + } + if ( sender.isEmpty() || receiver.isEmpty() || signal.isEmpty() || slot.isEmpty() ) + continue; + else if ( sender[0] == '<' || + receiver[0] == '<' || + signal[0] == '<' || + slot[0] == '<' ) + continue; + sender = registeredName( sender ); + receiver = registeredName( receiver ); + + if ( sender == objName ) + sender = "self"; + if ( receiver == objName ) + receiver = "self"; + + out << indent << "Qt::Object.connect(" << sender + << ", SIGNAL(\"" << signal << "\"), "<< receiver << ", SLOT(\"" << slot << "\") )" << endl; + } + } else if ( n.tagName() == "tabstops" ) { + // setup tab order + out << endl; + QString lastName; + QDomElement n2 = n.firstChild().toElement(); + while ( !n2.isNull() ) { + if ( n2.tagName() == "tabstop" ) { + QString name = n2.firstChild().toText().data(); + name = registeredName( name ); + if ( !lastName.isEmpty() ) + out << indent << "setTabOrder(" << lastName << ", " << name << ")" << endl; + lastName = name; + } + n2 = n2.nextSibling().toElement(); + } + } + } + +// QtRuby - FIXME: what the heck is this ? + // buddies + bool firstBuddy = true; + for ( QValueList<Buddy>::Iterator buddy = buddies.begin(); buddy != buddies.end(); ++buddy ) { + if ( isObjectRegistered( (*buddy).buddy ) ) { + if ( firstBuddy ) { + out << endl; + } + out << indent << (*buddy).key << ".setBuddy(" << registeredName( (*buddy).buddy ) << ")" << endl; + firstBuddy = false; + } + + } + if ( extraSlots.find( "init()" ) != extraSlots.end() || + extraFunctions.find( "init()" ) != extraFunctions.end()) + out << endl << indent << "init()" << endl; + + // end of constructor + --indent; + out << indent << "end" << endl; + out << endl; + + + + // handle application events if required + bool needFontEventHandler = false; + bool needSqlTableEventHandler = false; + bool needSqlDataBrowserEventHandler = false; + nl = e.elementsByTagName( "widget" ); + for ( i = 0; i < (int) nl.length(); i++ ) { + if ( !DomTool::propertiesOfType( nl.item(i).toElement() , "font" ).isEmpty() ) + needFontEventHandler = true; + QString s = getClassName( nl.item(i).toElement() ); + if ( s == "Qt::DataTable" || s == "Qt::DataBrowser" ) { + if ( !isFrameworkCodeGenerated( nl.item(i).toElement() ) ) + continue; + if ( s == "Qt::DataTable" ) + needSqlTableEventHandler = true; + if ( s == "Qt::DataBrowser" ) + needSqlDataBrowserEventHandler = true; + } + if ( needFontEventHandler && needSqlTableEventHandler && needSqlDataBrowserEventHandler ) + break; + } + +// PerlQt - TODO: is this needed ? +// Seems not.. let's ifzero for now... + + if ( 0 && needFontEventHandler) { + // indent = "\t"; // increase indentation for if-clause below + out << endl; + out << "# Main event handler. Reimplemented to handle" << endl; + out << "# application font changes" << endl; + out << endl; + out << "def event( ev )" << endl; + out << " ret = super( ev ) " << endl; + if ( needFontEventHandler ) { + ++indent; + out << " if ev.type() == Qt::Event::ApplicationFontChange " << endl; + for ( i = 0; i < (int) nl.length(); i++ ) { + n = nl.item(i).toElement(); + QStringList list = DomTool::propertiesOfType( n, "font" ); + for ( it = list.begin(); it != list.end(); ++it ) + createExclusiveProperty( n, *it ); + } + out << " end" << endl; + --indent; + } + out << "end" << endl; + out << endl; + } + + if ( needSqlTableEventHandler || needSqlDataBrowserEventHandler ) { + out << endl; + out << indent << "# Widget polish. Reimplemented to handle default data" << endl; + if ( needSqlTableEventHandler ) + out << indent << "# table initialization." << endl; + if ( needSqlDataBrowserEventHandler ) + out << indent << "# browser initialization." << endl; + out << indent << "def polish" << endl; + ++indent; + if ( needSqlTableEventHandler ) { + for ( i = 0; i < (int) nl.length(); i++ ) { + QString s = getClassName( nl.item(i).toElement() ); + if ( s == "Qt::DataTable" ) { + n = nl.item(i).toElement(); + QString c = QString("@") + getObjectName( n ); + QString conn = getDatabaseInfo( n, "connection" ); + QString tab = getDatabaseInfo( n, "table" ); + if ( !( conn.isEmpty() || tab.isEmpty() ) ) { + out << indent << "if " << "!" << c << ".nil?" << endl; + ++indent; + out << indent << "cursor = " << c << ".sqlCursor()" << endl; + out << endl; + out << indent << "if !cursor.nil?" << endl; + ++indent; + if ( conn == "(default)" ) + out << indent << "cursor = Qt::SqlCursor.new(\"" << tab << "\")" << endl; + else + out << indent << "cursor = Qt::SqlCursor.new(\"" << tab << "\", true, " << conn << "Connection)" << endl; + out << indent << "if " << c << ".readOnly? " << endl; + ++indent; + out << indent << "cursor.mode = Qt::SqlCursor::ReadOnly" << endl; + --indent; + out << indent << "end " << endl; + out << indent << c << ".setSqlCursor(cursor, false, true)" << endl; + --indent; + out << endl; + out << indent << "end" << endl; + out << indent << "if !cursor.active?" << endl; + ++indent; + out << indent << c << ".refresh(Qt::DataTable::RefreshAll)" << endl; + --indent; + out << indent << "end" << endl; + --indent; + out << indent << "end" << endl; + } + } + } + } + if ( needSqlDataBrowserEventHandler ) { + nl = e.elementsByTagName( "widget" ); + for ( i = 0; i < (int) nl.length(); i++ ) { + QString s = getClassName( nl.item(i).toElement() ); + if ( s == "Qt::DataBrowser" ) { + QString obj = getObjectName( nl.item(i).toElement() ); + QString tab = getDatabaseInfo( nl.item(i).toElement(), + "table" ); + QString conn = getDatabaseInfo( nl.item(i).toElement(), + "connection" ); + if ( !(tab).isEmpty() ) { + out << indent << "if " << obj << endl; + ++indent; + out << indent << "if !" << obj << ".sqlCursor()" << endl; + ++indent; + if ( conn == "(default)" ) + out << indent << "cursor = Qt::SqlCursor.new(\"" << tab << "\")" << endl; + else + out << indent << "cursor = Qt::SqlCursor.new(\"" << tab << "\", true, " << conn << "Connection)" << endl; + out << indent << obj << ".setSqlCursor(cursor, true)" << endl; + out << indent << obj << ".refresh()" << endl; + out << indent << obj << ".first()" << endl; + --indent; + out << indent << "end" << endl; + --indent; + out << indent << "end" << endl; + } + } + } + } + out << indent << "super()" << endl; + --indent; + out << indent << "end" << endl; + } + + out << indent << "#" << endl; + out << indent << "# Sets the strings of the subwidgets using the current" << endl; + out << indent << "# language." << endl; + out << indent << "#" << endl; + out << indent << "def " << "languageChange()" << endl; + out << languageChangeBody; + out << indent << "end" << endl; + out << indent << "protected :languageChange" << endl; + out << endl; + + if ( !extraSlots.isEmpty() && writeSlotImpl ) { + for ( it = extraSlots.begin(); it != extraSlots.end(); ++it ) { + out << endl; + int astart = (*it).find('('); + out << indent << "def " << (*it).left(astart) << "(*k)" << endl; + bool createWarning = true; + QString fname = Parser::cleanArgs( *it ); + QMap<QString, QString>::Iterator fit = functionImpls.find( fname ); + if ( fit != functionImpls.end() ) { + int begin = (*fit).find( "{" ); + QString body = (*fit).mid( begin + 1, (*fit).findRev( "}" ) - begin - 1 ); + createWarning = body.simplifyWhiteSpace().isEmpty(); + if ( !createWarning ) + out << body << endl; + } + if ( createWarning ) { + ++indent; + if ( *it != "init()" && *it != "destroy()" ) + out << indent << "print(\"" << nameOfClass << "." << (*it) << ": Not implemented yet.\\n\")" << endl; + --indent; + } + out << indent << "end" << endl; + + } + } + + if ( !extraFunctions.isEmpty() ) { + for ( it = extraFunctions.begin(); it != extraFunctions.end(); ++it ) { + out << endl; + int astart = (*it).find('('); + out << indent << "def " << (*it).left(astart) << "(*k)" << endl; + QString fname = Parser::cleanArgs( *it ); + QMap<QString, QString>::Iterator fit = functionImpls.find( fname ); + if ( fit != functionImpls.end() ) { + int begin = (*fit).find( "{" ); + QString body = (*fit).mid( begin + 1, (*fit).findRev( "}" ) - begin - 1 ); + body.simplifyWhiteSpace().isEmpty(); + out << body << endl; + } + out << indent << "end" << endl; + + } + } + + + out << endl; + out << "end" << endl; +} + + +/*! Creates form support implementation code for the widgets given + in \a e. + + Traverses recursively over all children. + */ + +void Uic::createFormImpl( const QDomElement& e, const QString& form, const QString& connection, const QString& table ) +{ + if ( e.tagName() == "widget" && + e.attribute( "class" ) != "Qt::DataTable" ) { + QString field = getDatabaseInfo( e, "field" ); + if ( !field.isEmpty() ) { + if ( isWidgetInTable( e, connection, table ) ) + out << indent << form << "Form.insert(" << getObjectName( e ) << ", " << fixString( field ) << ")" << endl; + } + } + QDomElement n; + for ( n = e.firstChild().toElement(); !n.isNull(); n = n.nextSibling().toElement() ) { + createFormImpl( n, form, connection, table ); + } +} + + +// Generate a QtRuby signal/slot definition. + +void Uic::rubySlot(QStringList::Iterator &it) +{ + out << indent << "'" << (*it) << "'"; +} diff --git a/qtruby/rubylib/designer/rbuic/globaldefs.h b/qtruby/rubylib/designer/rbuic/globaldefs.h new file mode 100644 index 00000000..cc6ed400 --- /dev/null +++ b/qtruby/rubylib/designer/rbuic/globaldefs.h @@ -0,0 +1,45 @@ +/********************************************************************** +** Copyright (C) 2000 Trolltech AS. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ + +#ifndef GLOBALDEFS_H +#define GLOBALDEFS_H + +#include <qcolor.h> + +#define BOXLAYOUT_DEFAULT_MARGIN 11 +#define BOXLAYOUT_DEFAULT_SPACING 6 + +#ifndef NO_STATIC_COLORS +static QColor *backColor1 = 0; +static QColor *backColor2 = 0; +static QColor *selectedBack = 0; + +static void init_colors() +{ + if ( backColor1 ) + return; + backColor1 = new QColor( 236, 245, 255 ); + backColor2 = new QColor( 250, 250, 250 ); + selectedBack = new QColor( 221, 221, 221 ); +} + +#endif + +#endif diff --git a/qtruby/rubylib/designer/rbuic/main.cpp b/qtruby/rubylib/designer/rbuic/main.cpp new file mode 100644 index 00000000..a80d8785 --- /dev/null +++ b/qtruby/rubylib/designer/rbuic/main.cpp @@ -0,0 +1,293 @@ +/********************************************************************** +** Copyright (C) 2000 Trolltech AS. All rights reserved. +** Copyright (c) 2001 Phil Thompson <phil@river-bank.demon.co.uk> +** Copyright (c) 2002 Germain Garand <germain@ebooksfrance.com> +** +** This file is part of Qt Designer. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ +/* +** 06/2002 : Initial release of puic, the PerlQt User Interface Compiler, +** a work derivated from uic (the Qt User Interface Compiler) +** and pyuic (the PyQt User Interface Compiler). +** +** G.Garand +** +** 08/2003 : Initial release of rbuic, the QtRuby User Interface Compiler, +** a work derived from the PerlQt puic. +** +** Richard Dale +** +**********************************************************************/ +#include "uic.h" +#include "parser.h" +#include "widgetdatabase.h" +#include "domtool.h" +#include <qapplication.h> +#include <qfile.h> +#include <qstringlist.h> +#include <qdatetime.h> +#define NO_STATIC_COLORS +#include <globaldefs.h> +#include <qregexp.h> +#include <stdio.h> +#include <stdlib.h> +#include <zlib.h> +#define RBUIC_VERSION "0.9" + +void getDBConnections( Uic& uic, QString& s); + +int main( int argc, char * argv[] ) +{ + RubyIndent indent; + bool execCode = false; + bool subcl = false; + bool imagecollection = false; + QStringList images; + const char *error = 0; + const char* fileName = 0; + const char* className = 0; + const char* outputFile = 0; + const char* projectName = 0; + const char* trmacro = 0; + bool nofwd = false; + bool useKDE = false; + bool fix = false; + QApplication app(argc, argv, false); + QString uicClass; + + + for ( int n = 1; n < argc && error == 0; n++ ) { + QCString arg = argv[n]; + if ( arg[0] == '-' ) { // option + QCString opt = &arg[1]; + if ( opt[0] == 'o' ) { // output redirection + if ( opt[1] == '\0' ) { + if ( !(n < argc-1) ) { + error = "Missing output-file name"; + break; + } + outputFile = argv[++n]; + } else + outputFile = &opt[1]; + } else if ( opt[0] == 'e' || opt == "embed" ) { + imagecollection = true; + if ( opt == "embed" || opt[1] == '\0' ) { + if ( !(n < argc-1) ) { + error = "Missing name of project."; + break; + } + projectName = argv[++n]; + } else + projectName = &opt[1]; + } else if ( opt == "nofwd" ) { + nofwd = true; + } else if ( opt == "kde" ) { + useKDE = true; + } else if ( opt == "subimpl" ) { + subcl = true; + if ( !(n < argc-1) ) { + error = "Missing class name."; + break; + } + className = argv[++n]; + } else if ( opt == "tr" ) { + if ( opt == "tr" || opt[1] == '\0' ) { + if ( !(n < argc-1) ) { + error = "Missing tr macro."; + break; + } + trmacro = argv[++n]; + } else { + trmacro = &opt[1]; + } + } else if ( opt == "version" ) { + fprintf( stderr, + "QtRuby User Interface Compiler v%s for Qt version %s\n", RBUIC_VERSION, + QT_VERSION_STR ); + exit( 1 ); + } else if ( opt == "help" ) { + break; + } else if ( opt == "fix" ) { + fix = true; + } else if ( opt[0] == 'p' ) { + uint tabstop; + bool ok; + + if ( opt[1] == '\0' ) { + if ( !(n < argc-1) ) { + error = "Missing indent"; + break; + } + tabstop = QCString(argv[++n]).toUInt(&ok); + } else + tabstop = opt.mid(1).toUInt(&ok); + + if (ok) + indent.setTabStop(tabstop); + else + error = "Invalid indent"; + } else if ( opt == "x" ) { + execCode = true; + } else { + error = "Unrecognized option"; + } + } else { + if ( imagecollection ) + images << argv[n]; + else if ( fileName ) // can handle only one file + error = "Too many input files specified"; + else + fileName = argv[n]; + } + } + + if ( argc < 2 || error || (!fileName && !imagecollection ) ) { + fprintf( stderr, "QtRuby user interface compiler.\n" ); + if ( error ) + fprintf( stderr, "rbuic: %s\n", error ); + + fprintf( stderr, "Usage: %s [options] [mode] <uifile>\n" + "\nGenerate implementation:\n" + " %s [options] <uifile>\n" + "Generate image collection:\n" + " %s [options] -embed <project> <image1> <image2> <image3> ...\n" + "\t<project>\tproject name\n" + "\t<image[0..n]>\timage files\n" + "Generate subclass implementation:\n" + " %s [options] -subimpl <classname> <uifile>\n" + "\t<classname>\tname of the subclass to generate\n" + "Options:\n" + "\t-o file\t\tWrite output to file rather than stdout\n" + "\t-p indent\tSet the indent in spaces (0 to use a tab)\n" + "\t-nofwd\t\tOmit imports of custom widgets\n" + "\t-kde\t\tUse kde widgets, require 'Korundum' extension\n" + "\t-tr func\tUse func(...) rather than trUtf8(...) for i18n\n" + "\t-x\t\tGenerate extra code to test the class\n" + "\t-version\tDisplay version of rbuic\n" + "\t-help\t\tDisplay this information\n" + , argv[0], argv[0], argv[0], argv[0]); + exit( 1 ); + } + + Uic::setIndent(indent); + + QFile fileOut; + if ( outputFile ) { + fileOut.setName( outputFile ); + if (!fileOut.open( IO_WriteOnly ) ) + qFatal( "rbuic: Could not open output file '%s'", outputFile ); + } else { + fileOut.open( IO_WriteOnly, stdout ); + } + QTextStream out( &fileOut ); + + if ( imagecollection ) { + out.setEncoding( QTextStream::Latin1 ); + Uic::embed( out, projectName, images ); + return 0; + } + + + out.setEncoding( QTextStream::UnicodeUTF8 ); + QFile file( fileName ); + if ( !file.open( IO_ReadOnly ) ) + qFatal( "rbuic: Could not open file '%s' ", fileName ); + + QDomDocument doc; + QString errMsg; + int errLine; + if ( !doc.setContent( &file, &errMsg, &errLine ) ) + qFatal( QString("rbuic: Failed to parse %s: ") + errMsg + QString (" in line %d\n"), fileName, errLine ); + + DomTool::fixDocument( doc ); + + if ( fix ) { + out << doc.toString(); + return 0; + } + + if ( !subcl ) { + out << "# Form implementation generated from reading ui file '" << fileName << "'" << endl; + out << "#" << endl; + out << "# Created: " << QDateTime::currentDateTime().toString() << endl; + out << "# by: The QtRuby User Interface Compiler (rbuic)" << endl; + out << "#" << endl; + out << "# WARNING! All changes made in this file will be lost!" << endl; + out << endl; + } + out << endl; + + Uic uic( fileName, out, doc, subcl, trmacro ? trmacro : "trUtf8", className, nofwd, uicClass, useKDE ); + + if (execCode) { + out << endl; + out << indent << "if $0 == __FILE__" << endl; + ++indent; + if (uic.hasKDEwidget) { + out << indent << "about = KDE::AboutData.new(\"" << uicClass.lower() << "\", \"" << uicClass << "\", \"0.1\")" << endl; + out << indent << "KDE::CmdLineArgs.init(ARGV, about)" << endl; + out << indent << "a = KDE::Application.new" << endl; + } else { + out << indent << "a = Qt::Application.new(ARGV)" << endl; + } + QString s; + getDBConnections( uic, s); + out << s; + out << indent << "w = " << (subcl? QString::fromLatin1(className) : uicClass) << ".new" << endl; + out << indent << "a.mainWidget = w" << endl; + out << indent << "w.show" << endl; + out << indent << "a.exec" << endl; + --indent; + out << indent << "end" << endl; + } + + return 0; +} + +void getDBConnections( Uic& uic, QString& s) +{ + int num = 0; + for ( QStringList::Iterator it = uic.dbConnections.begin(); it != uic.dbConnections.end(); ++it ) { + if ( !(*it).isEmpty()) { + QString inc = (num ? QString::number(num+1) : QString::null); + s += "\n # Connection to database " + (*it) + "\n\n"; + s += " DRIVER" + inc + " =\t\t'QMYSQL3'" + (inc?"":" # appropriate driver") + "\n"; + s += " DATABASE" + inc + " =\t\t'foo'" + (inc?"":" # name of your database") + "\n"; + s += " USER" + inc + "=\t\t'john'" + (inc?"":" # username") + "\n"; + s += " PASSWORD" + inc + "=\t\t'ZxjGG34s'" + (inc?"":" # password for USER") + "\n"; + s += " HOST" + inc + "=\t\t'localhost'" + (inc?"":" # host on which the database is running") + "\n"; + s += "\n"; + s += " $db" + inc + " = Qt::SqlDatabase.addDatabase( DRIVER" + inc; + if (inc) + s+= ", '" + (*it) + "'"; + s += " )\n"; + s += " $db" + inc + ".databaseName = DATABASE" + inc + "\n"; + s += " $db" + inc + ".userName = USER" + inc + "\n"; + s += " $db" + inc + ".password = PASSWORD" + inc + "\n"; + s += " $db" + inc + ".hostName = HOST" + inc + "\n"; + s += "\n"; + s += " if !$db" + inc + ".open\n"; + s += " Qt::MessageBox.information( nil, 'Unable to open database',\n"; + s += " $db" + inc + ".lastError().databaseText() + \"\\n\")\n"; + s += " exit 1\n"; + s += " end\n"; + s += "\n"; + num++; + } + } +} + diff --git a/qtruby/rubylib/designer/rbuic/object.cpp b/qtruby/rubylib/designer/rbuic/object.cpp new file mode 100644 index 00000000..ba8e38b7 --- /dev/null +++ b/qtruby/rubylib/designer/rbuic/object.cpp @@ -0,0 +1,750 @@ +/********************************************************************** +** Copyright (C) 2000 Trolltech AS. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +** 08/2003 : Initial release of rbuic, the QtRuby User Interface Compiler, +** a work derived from the PerlQt puic. +** +** Richard Dale +** +**********************************************************************/ + +#include "uic.h" +#include "parser.h" +#include "widgetdatabase.h" +#include "domtool.h" +#include <qregexp.h> +#include <qsizepolicy.h> +#include <qstringlist.h> +#define NO_STATIC_COLORS +#include <globaldefs.h> +#include <zlib.h> + +/*! + Creates a declaration for the object given in \a e. + + Children are not traversed recursively. + + \sa createObjectImpl() + */ +void Uic::createObjectDecl( const QDomElement& e ) +{ + if ( e.tagName() == "vbox" || e.tagName() == "hbox" || e.tagName() == "grid" ) { + out << indent << registerObject(getLayoutName(e) ) << endl; + } else { + QString objClass = getClassName( e ); + if ( objClass.isEmpty() ) + return; + QString objName = getObjectName( e ); + if ( objName.isEmpty() ) + return; + // ignore QLayoutWidgets + if ( objClass == "Qt::LayoutWidget" ) + return; + + // register the object and unify its name + objName = registerObject( objName ); + out << indent << objName << endl; + } +} + +/*! + Creates a QtRuby attribute declaration for the object given in \a e. + + Children are not traversed recursively. + + */ +void Uic::createAttrDecl( const QDomElement& e ) +{ + if ( e.tagName() == "vbox" || e.tagName() == "hbox" || e.tagName() == "grid" ) { +// out << indent << registerObject(getLayoutName(e) ) << endl; + } else { + QString objClass = getClassName( e ); + if ( objClass.isEmpty() ) + return; + QString objName = getObjectName( e ); + if ( objName.isEmpty() ) + return; + // ignore QLayoutWidgets + if ( objClass == "Qt::LayoutWidget" ) + return; + // register the object and unify its name + objName = registerObject( objName ); + QString attr(objName); + attr.replace(QChar('@'), "attr_reader :"); + + out << indent << attr << endl; + QDomElement n = getObjectProperty( e, "font"); +// if ( !n.isNull() ) +// out << indent << objName + "_font" << endl; + } +} + + +/*! + Creates an implementation for the object given in \a e. + + Traverses recursively over all children. + + Returns the name of the generated child object. + + \sa createObjectDecl() + */ + +static bool createdCentralWidget = false; + +QString Uic::createObjectImpl( const QDomElement &e, const QString& parentClass, const QString& par, const QString& layout ) +{ + QString parent( par ); + if ( parent == "self" && isMainWindow ) { + if ( !createdCentralWidget ) + out << indent << "setCentralWidget(Qt::Widget.new(self, \"qt_central_widget\"))" << endl; + createdCentralWidget = true; + parent = "centralWidget()"; + } + QDomElement n; + QString objClass, objName, fullObjName; + int numItems = 0; + int numColumns = 0; + int numRows = 0; + + if ( layouts.contains( e.tagName() ) ) + return createLayoutImpl( e, parentClass, parent, layout ); + + objClass = getClassName( e ); + if ( objClass.isEmpty() ) + return objName; + objName = getObjectName( e ); + + QString definedName = objName; + bool isTmpObject = objName.isEmpty() || objClass == "Qt::LayoutWidget"; + if ( isTmpObject ) { + if ( objClass[0] == 'Q' ) + objName = objClass.mid( 4 ); + else + objName = objClass.lower(); + } + + bool isLine = objClass == "Line"; + if ( isLine ) + objClass = "Qt::Frame"; + + out << endl; + if ( objClass == "Qt::LayoutWidget" ) { + if ( layout.isEmpty() ) { + // register the object and unify its name + objName = registerObject( objName ); + out << indent << (isTmpObject ? QString::fromLatin1("") : QString::null) << objName << " = Qt::Widget.new(" << parent << ", '" << objName << "')" << endl; + } else { + // the layout widget is not necessary, hide it by creating its child in the parent + QString result; + for ( n = e.firstChild().toElement(); !n.isNull(); n = n.nextSibling().toElement() ) { + if (tags.contains( n.tagName() ) ) + result = createObjectImpl( n, parentClass, parent, layout ); + } + return result; + } + + // Layouts don't go into the class instance dictionary. + // FIXME PerlQt: fullObjName isn't used anymore => remove + fullObjName = objName; + } else if ( objClass != "Qt::ToolBar" && objClass != "Qt::MenuBar" ) { + // register the object and unify its name + objName = registerObject( objName ); + + // Temporary objects don't go into the class instance dictionary. + fullObjName = objName; + + out << indent << fullObjName << " = " << createObjectInstance( objClass, parent, objName ) << endl; + } + else + fullObjName = objName; + + if ( objClass == "Qt::AxWidget" ) { + QString controlId; + for ( n = e.firstChild().toElement(); !n.isNull(); n = n.nextSibling().toElement() ) { + if ( n.tagName() == "property" && n.attribute( "name" ) == "control" ) { + controlId = n.firstChild().toElement().text(); + } + } + out << " "; + out << fullObjName << ".setControl(\"" << controlId << "\")" << endl; + } + + lastItem = "nil"; + // set the properties and insert items + bool hadFrameShadow = false; + for ( n = e.firstChild().toElement(); !n.isNull(); n = n.nextSibling().toElement() ) { + if ( n.tagName() == "property" ) { + bool stdset = stdsetdef; + if ( n.hasAttribute( "stdset" ) ) + stdset = toBool( n.attribute( "stdset" ) ); + QString prop = n.attribute("name"); + if ( prop == "database" ) + continue; + QString value = setObjectProperty( objClass, objName, prop, n.firstChild().toElement(), stdset ); + if ( value.isEmpty() ) + continue; + if ( prop == "name" ) + continue; + if ( isLine && prop == "frameShadow" ) + hadFrameShadow = true; + if ( prop == "buddy" && value[0] == '\"' && value[(int)value.length()-1] == '\"' ) { + buddies << Buddy( objName, value.mid(1, value.length() - 2 ) ); + continue; + } + if ( isLine && prop == "orientation" ) { + prop = "frameShape"; + if ( value.right(10) == "Horizontal" ) + value = "Qt::Frame::HLine"; + else + value = "Qt::Frame::VLine"; + if ( !hadFrameShadow ) { + prop = "frameStyle"; + value += " | Qt::Frame::Sunken"; + } + } + if ( prop == "buttonGroupId" ) { + if ( parentClass == "Qt::ButtonGroup" ) + out << indent << parent << ".insert( " << fullObjName << "," << value << ")" << endl; + continue; + } + if ( prop == "frameworkCode" ) + continue; + if ( objClass == "Qt::MultiLineEdit" && + QRegExp("echoMode|hMargin|maxLength|maxLines|undoEnabled").exactMatch(prop) ) + continue; + + QString call = fullObjName + "."; + if (! call.startsWith("@")) { + call.prepend("@"); + } + + if ( stdset ) { + call += mkStdSet( prop ) + "( "; + call += value + " )"; + } else { + call += "setProperty( \"" + prop + "\", Qt::Variant.new(" ; + call += value + " ) )"; + } + + if ( n.firstChild().toElement().tagName() == "string" || + prop == "currentItem" ) { + trout << indent << call << endl; + } else { + out << indent << call << endl; + } + } else if ( n.tagName() == "item" ) { + QString call; + QString value; + + if ( objClass.mid( 4 ) == "ListBox" ) { + call = createListBoxItemImpl( n, fullObjName, &value ); + if ( !call.isEmpty() ) { + if ( numItems == 0 ) + trout << indent << fullObjName << ".clear()" << endl; + trout << indent << call << endl; + } + } else if ( objClass.mid( 4 ) == "ComboBox" ) { + call = createListBoxItemImpl( n, fullObjName, &value ); + if ( !call.isEmpty() ) { + if ( numItems == 0 ) + trout << indent << fullObjName << ".clear()" << endl; + trout << indent << call << endl; + } + } else if ( objClass.mid( 4 ) == "IconView" ) { + call = createIconViewItemImpl( n, fullObjName ); + if ( !call.isEmpty() ) { + if ( numItems == 0 ) + trout << indent << fullObjName << ".clear()" << endl; + trout << indent << call << endl; + } + } else if ( objClass.mid( 4 ) == "ListView" ) { + call = createListViewItemImpl( n, fullObjName, QString::null ); + if ( !call.isEmpty() ) { + if ( numItems == 0 ) + trout << indent << fullObjName << ".clear()" << endl; + trout << call << endl; + } + } + if ( !call.isEmpty() ) + numItems++; + } else if ( n.tagName() == "column" || n.tagName() == "row" ) { + QString call; + QString value; + + if ( objClass.mid( 4 ) == "ListView" ) { + call = createListViewColumnImpl( n, fullObjName, &value ); + if ( !call.isEmpty() ) { + out << call; + trout << indent << fullObjName << ".header().setLabel( " + << numColumns++ << ", " << value << " )\n"; + } + } else if ( objClass == "Qt::Table" || objClass == "Qt::DataTable" ) { + bool isCols = ( n.tagName() == "column" ); + call = createTableRowColumnImpl( n, fullObjName, &value ); + if ( !call.isEmpty() ) { + out << call; + trout << indent << fullObjName << "." + << ( isCols ? "horizontalHeader" : "verticalHeader" ) + << "().setLabel( " + << ( isCols ? numColumns++ : numRows++ ) + << ", " << value << " )\n"; + } + } + } + } + + // create all children, some widgets have special requirements + + if ( objClass == "Qt::TabWidget" ) { + for ( n = e.firstChild().toElement(); !n.isNull(); n = n.nextSibling().toElement() ) { + if ( tags.contains( n.tagName() ) ) { + QString page = createObjectImpl( n, objClass, fullObjName ); + QString comment; + QString label = DomTool::readAttribute( n, "title", "", comment ).toString(); + out << indent << fullObjName << ".insertTab(" << page << ", " << trcall( label ) << ")" << endl; + trout << indent << fullObjName << ".changeTab( " << page << ", " + << trcall( label, comment ) << " )" << endl; + } + } + } else if ( objClass == "Qt::WidgetStack" ) { + for ( n = e.firstChild().toElement(); !n.isNull(); n = n.nextSibling().toElement() ) { + if ( tags.contains( n.tagName() ) ) { + QString page = createObjectImpl( n, objClass, objName ); + int id = DomTool::readAttribute( n, "id", "" ).toInt(); + out << indent << fullObjName << ".addWidget( " << page << ", " << id << " )" << endl; + } + } + } else if ( objClass == "Qt::ToolBox" ) { + for ( n = e.firstChild().toElement(); !n.isNull(); n = n.nextSibling().toElement() ) { + if ( tags.contains( n.tagName() ) ) { + QString page = createObjectImpl( n, objClass, objName ); + QString comment; + QString label = DomTool::readAttribute( n, "label", comment ).toString(); + out << indent << fullObjName << ".addItem( " << page << ", \"\" )" << endl; + trout << indent << fullObjName << ".setItemLabel( " << fullObjName + << ".indexOf(" << page << "), " << trcall( label, comment ) + << " )" << endl; + } + } + } else if ( objClass != "Qt::ToolBar" && objClass != "Qt::MenuBar" ) { // standard widgets + for ( n = e.firstChild().toElement(); !n.isNull(); n = n.nextSibling().toElement() ) { + if ( tags.contains( n.tagName() ) ) + createObjectImpl( n, objClass, fullObjName ); + } + } + + return fullObjName; +} + + + +/*! + Creates a set-call for property \a exclusiveProp of the object + given in \a e. + + If the object does not have this property, the function does nothing. + + Exclusive properties are used to generate the implementation of + application font or palette change handlers in createFormImpl(). + + */ +void Uic::createExclusiveProperty( const QDomElement & e, const QString& exclusiveProp ) +{ + QDomElement n; + QString objClass = getClassName( e ); + if ( objClass.isEmpty() ) + return; + QString objName = getObjectName( e ); + if ( objClass.isEmpty() ) + return; + for ( n = e.firstChild().toElement(); !n.isNull(); n = n.nextSibling().toElement() ) { + if ( n.tagName() == "property" ) { + bool stdset = stdsetdef; + if ( n.hasAttribute( "stdset" ) ) + stdset = toBool( n.attribute( "stdset" ) ); + QString prop = n.attribute("name"); + if ( prop != exclusiveProp ) + continue; + QString value = setObjectProperty( objClass, objName, prop, n.firstChild().toElement(), stdset ); + if ( value.isEmpty() ) + continue; + out << indent << indent << objName << ".setProperty(\"" << prop << "\", Qt::Variant.new(" << value << "))" << endl; + } + } +} + + +/*! Attention: this function has to be in sync with + Resource::saveProperty() and DomTool::elementToVariant. If you + change one, change all. + */ +QString Uic::setObjectProperty( const QString& objClass, const QString& obj, const QString &prop, const QDomElement &e, bool stdset ) +{ + QString v; + if ( e.tagName() == "rect" ) { + QDomElement n3 = e.firstChild().toElement(); + int x = 0, y = 0, w = 0, h = 0; + while ( !n3.isNull() ) { + if ( n3.tagName() == "x" ) + x = n3.firstChild().toText().data().toInt(); + else if ( n3.tagName() == "y" ) + y = n3.firstChild().toText().data().toInt(); + else if ( n3.tagName() == "width" ) + w = n3.firstChild().toText().data().toInt(); + else if ( n3.tagName() == "height" ) + h = n3.firstChild().toText().data().toInt(); + n3 = n3.nextSibling().toElement(); + } + v = "Qt::Rect.new(%1, %2, %3, %4)"; + v = v.arg(x).arg(y).arg(w).arg(h); + + } else if ( e.tagName() == "point" ) { + QDomElement n3 = e.firstChild().toElement(); + int x = 0, y = 0; + while ( !n3.isNull() ) { + if ( n3.tagName() == "x" ) + x = n3.firstChild().toText().data().toInt(); + else if ( n3.tagName() == "y" ) + y = n3.firstChild().toText().data().toInt(); + n3 = n3.nextSibling().toElement(); + } + v = "Qt::Point.new(%1, %2)"; + v = v.arg(x).arg(y); + } else if ( e.tagName() == "size" ) { + QDomElement n3 = e.firstChild().toElement(); + int w = 0, h = 0; + while ( !n3.isNull() ) { + if ( n3.tagName() == "width" ) + w = n3.firstChild().toText().data().toInt(); + else if ( n3.tagName() == "height" ) + h = n3.firstChild().toText().data().toInt(); + n3 = n3.nextSibling().toElement(); + } + v = "Qt::Size.new(%1, %2)"; + v = v.arg(w).arg(h); + } else if ( e.tagName() == "color" ) { + QDomElement n3 = e.firstChild().toElement(); + int r= 0, g = 0, b = 0; + while ( !n3.isNull() ) { + if ( n3.tagName() == "red" ) + r = n3.firstChild().toText().data().toInt(); + else if ( n3.tagName() == "green" ) + g = n3.firstChild().toText().data().toInt(); + else if ( n3.tagName() == "blue" ) + b = n3.firstChild().toText().data().toInt(); + n3 = n3.nextSibling().toElement(); + } + v = "Qt::Color.new(%1, %2, %3)"; + v = v.arg(r).arg(g).arg(b); + } else if ( e.tagName() == "font" ) { + QDomElement n3 = e.firstChild().toElement(); + QString fontname; + if ( !obj.isEmpty() ) { + fontname = obj + "_font"; + out << indent << fontname << " = Qt::Font.new(" << obj << ".font())" << endl; + } else { + fontname = registerObject( "f" ); + out << indent << fontname << " = Qt::Font.new(font())" << endl; + } + while ( !n3.isNull() ) { + if ( n3.tagName() == "family" ) + out << indent << fontname << ".setFamily(\"" << n3.firstChild().toText().data() << "\")" << endl; + else if ( n3.tagName() == "pointsize" ) + out << indent << fontname << ".setPointSize(" << n3.firstChild().toText().data() << ")" << endl; + else if ( n3.tagName() == "bold" ) + out << indent << fontname << ".setBold(" << mkBool( n3.firstChild().toText().data() ) << ")" << endl; + else if ( n3.tagName() == "italic" ) + out << indent << fontname << ".setItalic(" << mkBool( n3.firstChild().toText().data() ) << ")" << endl; + else if ( n3.tagName() == "underline" ) + out << indent << fontname << ".setUnderline(" << mkBool( n3.firstChild().toText().data() ) << ")" << endl; + else if ( n3.tagName() == "strikeout" ) + out << indent << fontname << ".setStrikeOut(" << mkBool( n3.firstChild().toText().data() ) << ")" << endl; + n3 = n3.nextSibling().toElement(); + } + + if ( prop == "font" ) { + if ( !obj.isEmpty() ) + out << indent << obj << ".setFont(" << fontname << ")" << endl; + else + out << indent << "setFont(" << fontname << ")" << endl; + } else { + v = fontname; + } + } else if ( e.tagName() == "string" ) { + QString txt = e.firstChild().toText().data(); + QString com = getComment( e.parentNode() ); + + if ( prop == "toolTip" && objClass != "Qt::Action" && objClass != "Qt::ActionGroup" ) { + if ( !obj.isEmpty() ) + trout << indent << "Qt::ToolTip.add( " << obj << ", " + << trcall( txt, com ) << " )" << endl; + else + trout << indent << "Qt::ToolTip.add( self, " + << trcall( txt, com ) << " )" << endl; + } else if ( prop == "whatsThis" && objClass != "Qt::Action" && objClass != "Qt::ActionGroup" ) { + if ( !obj.isEmpty() ) + trout << indent << "Qt::WhatsThis.add(" << obj << ", " << trcall( txt, com ) << ")" << endl; + else + trout << indent << "Qt::WhatsThis.add(self," << trcall( txt, com ) << ")" << endl; + } else if (e.parentNode().toElement().attribute("name") == "accel") { + v = "Qt::KeySequence.new(" + trcall( txt, com ) + ")"; + } else { + v = trcall( txt, com ); + } + } else if ( e.tagName() == "cstring" ) { + v = "\"%1\""; + v = v.arg( e.firstChild().toText().data() ); + } else if ( e.tagName() == "number" ) { + // FIXME: hack. QtRuby needs a QKeySequence to build an accel + if( e.parentNode().toElement().attribute("name") == "accel" ) + v = "Qt::KeySequence.new(%1)"; + else + v = "%1"; + v = v.arg( e.firstChild().toText().data() ); + } else if ( e.tagName() == "bool" ) { + if ( stdset ) + v = "%1"; + else + v = "Qt::Variant.new(%1, 0)"; + v = v.arg( mkBool( e.firstChild().toText().data() ) ); + } else if ( e.tagName() == "pixmap" ) { + v = e.firstChild().toText().data(); + if( !externPixmaps ) + v.prepend( '@' ); + if ( !pixmapLoaderFunction.isEmpty() ) { + v.prepend( pixmapLoaderFunction + "(" + QString( externPixmaps ? "\"" : "" ) ); + v.append( QString( externPixmaps ? "\"" : "" ) + ")" ); + } + } else if ( e.tagName() == "iconset" ) { + v = "Qt::IconSet.new(%1)"; + QString s = e.firstChild().toText().data(); + if ( !pixmapLoaderFunction.isEmpty() ) { + s.prepend( pixmapLoaderFunction + "(" + QString( externPixmaps ? "\"" : "" ) ); + s.append( QString( externPixmaps ? "\"" : "" ) + ")" ); + } else { + s.prepend("@"); + } + v = v.arg( s ); + } else if ( e.tagName() == "image" ) { + v = e.firstChild().toText().data() + ".convertToImage()"; + } else if ( e.tagName() == "enum" ) { + v = "%1::%2"; + QString oc = objClass; + QString ev = e.firstChild().toText().data(); + if ( oc == "Qt::ListView" && ev == "Manual" ) // #### workaround, rename QListView::Manual of WithMode enum in 3.0 + oc = "Qt::ScrollView"; + v = v.arg( oc ).arg( ev ); + } else if ( e.tagName() == "set" ) { + QString keys( e.firstChild().toText().data() ); + QStringList lst = QStringList::split( '|', keys ); + v = ""; +#if defined(Q_CC_EDG) + // workaround for EDG bug reproduced with MIPSpro C++ 7.3.? + // and KAI C++ 4.0e that will be fixed in KAI C++ 4.0f + QStringList::Iterator it = lst.begin(); + for ( ; it != lst.end(); ++it ) { +#else + for ( QStringList::Iterator it = lst.begin(); it != lst.end(); ++it ) { +#endif + v += objClass + "::" + *it; + if ( it != lst.fromLast() ) + v += " | "; + } + v += ""; + } else if ( e.tagName() == "sizepolicy" ) { + QDomElement n3 = e.firstChild().toElement(); + QSizePolicy sp; + while ( !n3.isNull() ) { + if ( n3.tagName() == "hsizetype" ) + sp.setHorData( (QSizePolicy::SizeType)n3.firstChild().toText().data().toInt() ); + else if ( n3.tagName() == "vsizetype" ) + sp.setVerData( (QSizePolicy::SizeType)n3.firstChild().toText().data().toInt() ); + else if ( n3.tagName() == "horstretch" ) + sp.setHorStretch( n3.firstChild().toText().data().toInt() ); + else if ( n3.tagName() == "verstretch" ) + sp.setVerStretch( n3.firstChild().toText().data().toInt() ); + n3 = n3.nextSibling().toElement(); + } + QString tmp = (obj.isEmpty() ? QString::fromLatin1("self") : obj) + "."; + v = "Qt::SizePolicy.new(%1, %2, %3, %4, " + tmp + "sizePolicy().hasHeightForWidth())"; + v = v.arg( (int)sp.horData() ).arg( (int)sp.verData() ).arg( sp.horStretch() ).arg( sp.verStretch() ); + } else if ( e.tagName() == "palette" ) { + QPalette pal; + bool no_pixmaps = e.elementsByTagName( "pixmap" ).count() == 0; + QDomElement n; + if ( no_pixmaps ) { + n = e.firstChild().toElement(); + while ( !n.isNull() ) { + QColorGroup cg; + if ( n.tagName() == "active" ) { + cg = loadColorGroup( n ); + pal.setActive( cg ); + } else if ( n.tagName() == "inactive" ) { + cg = loadColorGroup( n ); + pal.setInactive( cg ); + } else if ( n.tagName() == "disabled" ) { + cg = loadColorGroup( n ); + pal.setDisabled( cg ); + } + n = n.nextSibling().toElement(); + } + } + if ( no_pixmaps && pal == QPalette( pal.active().button(), pal.active().background() ) ) { + v = "Qt::Palette.new(Qt::Color.new(%1,%2,%3), Qt::Color.new(%1,%2,%3))"; + v = v.arg( pal.active().button().red() ).arg( pal.active().button().green() ).arg( pal.active().button().blue() ); + v = v.arg( pal.active().background().red() ).arg( pal.active().background().green() ).arg( pal.active().background().blue() ); + } else { + QString palette = "pal"; + if ( !pal_used ) { + out << indent << palette << " = Qt::Palette.new()" << endl; + pal_used = true; + } + QString cg = "cg"; + if ( !cg_used ) { + out << indent << cg << " = Qt::ColorGroup.new()" << endl; + cg_used = true; + } + n = e.firstChild().toElement(); + while ( !n.isNull() && n.tagName() != "active" ) + n = n.nextSibling().toElement(); + createColorGroupImpl( cg, n ); + out << indent << palette << ".setActive(" << cg << ")" << endl; + + n = e.firstChild().toElement(); + while ( !n.isNull() && n.tagName() != "inactive" ) + n = n.nextSibling().toElement(); + createColorGroupImpl( cg, n ); + out << indent << palette << ".setInactive(" << cg << ")" << endl; + + n = e.firstChild().toElement(); + while ( !n.isNull() && n.tagName() != "disabled" ) + n = n.nextSibling().toElement(); + createColorGroupImpl( cg, n ); + out << indent << palette << ".setDisabled(" << cg << ")" << endl; + v = palette; + } + } else if ( e.tagName() == "cursor" ) { + v = "Qt::Cursor.new(%1)"; + v = v.arg( e.firstChild().toText().data() ); + } else if ( e.tagName() == "date" ) { + QDomElement n3 = e.firstChild().toElement(); + int y, m, d; + y = m = d = 0; + while ( !n3.isNull() ) { + if ( n3.tagName() == "year" ) + y = n3.firstChild().toText().data().toInt(); + else if ( n3.tagName() == "month" ) + m = n3.firstChild().toText().data().toInt(); + else if ( n3.tagName() == "day" ) + d = n3.firstChild().toText().data().toInt(); + n3 = n3.nextSibling().toElement(); + } + v = "Qt::Date.new(%1,%2,%3)"; + v = v.arg(y).arg(m).arg(d); + } else if ( e.tagName() == "time" ) { + QDomElement n3 = e.firstChild().toElement(); + int h, m, s; + h = m = s = 0; + while ( !n3.isNull() ) { + if ( n3.tagName() == "hour" ) + h = n3.firstChild().toText().data().toInt(); + else if ( n3.tagName() == "minute" ) + m = n3.firstChild().toText().data().toInt(); + else if ( n3.tagName() == "second" ) + s = n3.firstChild().toText().data().toInt(); + n3 = n3.nextSibling().toElement(); + } + v = "Qt::Time.new(%1, %2, %3)"; + v = v.arg(h).arg(m).arg(s); + } else if ( e.tagName() == "datetime" ) { + QDomElement n3 = e.firstChild().toElement(); + int h, mi, s, y, mo, d; + h = mi = s = y = mo = d = 0; + while ( !n3.isNull() ) { + if ( n3.tagName() == "hour" ) + h = n3.firstChild().toText().data().toInt(); + else if ( n3.tagName() == "minute" ) + mi = n3.firstChild().toText().data().toInt(); + else if ( n3.tagName() == "second" ) + s = n3.firstChild().toText().data().toInt(); + else if ( n3.tagName() == "year" ) + y = n3.firstChild().toText().data().toInt(); + else if ( n3.tagName() == "month" ) + mo = n3.firstChild().toText().data().toInt(); + else if ( n3.tagName() == "day" ) + d = n3.firstChild().toText().data().toInt(); + n3 = n3.nextSibling().toElement(); + } + v = "Qt::DateTime.new(Qt::Date.new(%1, %2, %3), Qt::Time.new(%4, %5, %6))"; + v = v.arg(y).arg(mo).arg(d).arg(h).arg(mi).arg(s); + } else if ( e.tagName() == "stringlist" ) { + QStringList l; + QDomElement n3 = e.firstChild().toElement(); + QString listname; + if ( !obj.isEmpty() ) { + listname = obj + "_strlist"; + out << indent << listname << " = ["; + } else { + listname = "strlist"; + out << indent << listname << " = ["; + } + int i = 0; + while ( true ) { + if ( n3.tagName() == "string" ) + { + out << "'" << n3.firstChild().toText().data().simplifyWhiteSpace() << "'"; + n3 = n3.nextSibling().toElement(); + i++; + if( n3.isNull() ) + break; + else if( (i%3) == 0 ) + { + ++indent; + out << "," << endl << indent; + --indent; + } + else if( n3.isNull() ) + break; + else + out << ", "; + } + } + out << "]" << endl; + v = listname; + } + return v; +} + + + + +/*! Extracts a named object property from \a e. + */ +QDomElement Uic::getObjectProperty( const QDomElement& e, const QString& name ) +{ + QDomElement n; + for ( n = e.firstChild().toElement(); + !n.isNull(); + n = n.nextSibling().toElement() ) { + if ( n.tagName() == "property" && n.toElement().attribute("name") == name ) + return n; + } + return n; +} + diff --git a/qtruby/rubylib/designer/rbuic/parser.cpp b/qtruby/rubylib/designer/rbuic/parser.cpp new file mode 100644 index 00000000..b7869f75 --- /dev/null +++ b/qtruby/rubylib/designer/rbuic/parser.cpp @@ -0,0 +1,71 @@ +/********************************************************************** +** Copyright (C) 2000 Trolltech AS. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +** 08/2003 : Initial release of rbuic, the QtRuby User Interface Compiler, +** a work derived from the PerlQt puic. +** +** Richard Dale +** +**********************************************************************/ + +#include "parser.h" +#include <qobject.h> +#include <qstringlist.h> + +class NormalizeObject : public QObject +{ +public: + NormalizeObject() : QObject() {} + static QCString normalizeSignalSlot( const char *signalSlot ) { return QObject::normalizeSignalSlot( signalSlot ); } +}; + +QString Parser::cleanArgs( const QString &func ) +{ + QString slot( func ); + int begin = slot.find( "(" ) + 1; + QString args = slot.mid( begin ); + args = args.left( args.find( ")" ) ); + QStringList lst = QStringList::split( ',', args ); + QString res = slot.left( begin ); + for ( QStringList::Iterator it = lst.begin(); it != lst.end(); ++it ) { + if ( it != lst.begin() ) + res += ","; + QString arg = *it; + int pos = 0; + if ( ( pos = arg.find( "&" ) ) != -1 ) { + arg = arg.left( pos + 1 ); + } else if ( ( pos = arg.find( "*" ) ) != -1 ) { + arg = arg.left( pos + 1 ); + } else { + arg = arg.simplifyWhiteSpace(); + if ( ( pos = arg.find( ':' ) ) != -1 ) + arg = arg.left( pos ).simplifyWhiteSpace() + ":" + arg.mid( pos + 1 ).simplifyWhiteSpace(); + QStringList l = QStringList::split( ' ', arg ); + if ( l.count() == 2 ) { + if ( l[ 0 ] != "const" && l[ 0 ] != "unsigned" && l[ 0 ] != "var" ) + arg = l[ 0 ]; + } else if ( l.count() == 3 ) { + arg = l[ 0 ] + " " + l[ 1 ]; + } + } + res += arg; + } + res += ")"; + + return QString::fromLatin1( NormalizeObject::normalizeSignalSlot( res.latin1() ) ); +} diff --git a/qtruby/rubylib/designer/rbuic/parser.h b/qtruby/rubylib/designer/rbuic/parser.h new file mode 100644 index 00000000..5a5671ad --- /dev/null +++ b/qtruby/rubylib/designer/rbuic/parser.h @@ -0,0 +1,33 @@ +/********************************************************************** +** Copyright (C) 2000 Trolltech AS. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ + +#ifndef PARSER_H +#define PARSER_H + +#include <qstring.h> + +class Parser +{ +public: + static QString cleanArgs( const QString &func ); + +}; + +#endif diff --git a/qtruby/rubylib/designer/rbuic/rbuic.pro b/qtruby/rubylib/designer/rbuic/rbuic.pro new file mode 100644 index 00000000..a9869ab0 --- /dev/null +++ b/qtruby/rubylib/designer/rbuic/rbuic.pro @@ -0,0 +1,24 @@ +TEMPLATE = app +CONFIG += qt console warn_on release professional +HEADERS = uic.h \ + widgetdatabase.h \ + domtool.h \ + parser.h \ + widgetinterface.h + +SOURCES = main.cpp uic.cpp form.cpp object.cpp \ + subclassing.cpp embed.cpp\ + widgetdatabase.cpp \ + domtool.cpp \ + parser.cpp + +DEFINES += QT_INTERNAL_XML +#include( ../../../src/qt_professional.pri ) + +TARGET = rbuic +DEFINES += UIC +DESTDIR = /usr/bin + +#target.path=$$bins.path +#INSTALLS += target + diff --git a/qtruby/rubylib/designer/rbuic/subclassing.cpp b/qtruby/rubylib/designer/rbuic/subclassing.cpp new file mode 100644 index 00000000..a3ad25c3 --- /dev/null +++ b/qtruby/rubylib/designer/rbuic/subclassing.cpp @@ -0,0 +1,197 @@ +/********************************************************************** +** Copyright (C) 2000 Trolltech AS. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ + +#include "uic.h" +#include "parser.h" +#include "widgetdatabase.h" +#include "domtool.h" +#include <qfile.h> +#include <qstringlist.h> +#include <qdatetime.h> +#define NO_STATIC_COLORS +#include <globaldefs.h> +#include <qregexp.h> +#include <stdio.h> +#include <stdlib.h> +#include <zlib.h> + + +/*! + Creates an implementation for a subclass \a subClass of the form + given in \a e + + \sa createSubDecl() + */ +void Uic::createSubImpl( const QDomElement &e, const QString& subClass ) +{ + QDomElement n; + QDomNodeList nl; + int i; + QStringList::Iterator it, it2, it3; + + QString objClass = getClassName( e ); + if ( objClass.isEmpty() ) + return; + if (hasKDEwidget) { + out << indent << "require 'Korundum'" << endl; + } else { + out << indent << "require 'Qt'" << endl; + } + out << endl; + out << indent << "class " << subClass << " < " << nameOfClass << endl; + + out << endl; + ++indent; + + // constructor + if ( objClass == "Qt::Dialog" || objClass == "Qt::Wizard" ) { + out << indent << "# Constructs a " << subClass << " which is a child of 'parent', with the " << endl; + out << indent << "# name 'name' and widget flags set to 'fl' " << endl; + out << indent << "# " << endl; + out << indent << "# The " << objClass.mid(4).lower() << " will by default be modeless, unless you set 'modal' to" << endl; + out << indent << "# true to construct a modal " << objClass.mid(4).lower() << "." << endl; + out << indent << "def initialize(parent = nil, name = nil, modal = false, fl = 0)" << endl; + ++indent; + out << indent << "super" << endl; + } else { + out << indent << "# Constructs a " << subClass << " which is a child of 'parent', with the " << endl; + out << indent << "# name 'name' and widget flags set to 'fl' " << endl; + out << indent << "def initialize(parent = nil, name = nil, fl = 0)" << endl; + ++indent; + out << indent << "super" << endl; + } + --indent; + out << indent << "end" << endl; + out << endl; + + // find additional slots + QStringList publicSlots, protectedSlots, privateSlots; + QStringList publicSlotTypes, protectedSlotTypes, privateSlotTypes; + QStringList publicSlotSpecifier, protectedSlotSpecifier, privateSlotSpecifier; + QMap<QString, QString> functionImpls; + nl = e.parentNode().toElement().elementsByTagName( "slot" ); + for ( i = 0; i < (int) nl.length(); i++ ) { + n = nl.item(i).toElement(); + if ( n.parentNode().toElement().tagName() != "slots" + && n.parentNode().toElement().tagName() != "connections" ) + continue; + if ( n.attribute( "language", "C++" ) != "C++" ) + continue; + QString returnType = n.attribute( "returnType", "void" ); + QString slotName = n.firstChild().toText().data().stripWhiteSpace(); + if ( slotName.endsWith( ";" ) ) + slotName = slotName.left( slotName.length() - 1 ); + QString specifier = n.attribute( "specifier" ); + QString access = n.attribute( "access" ); + if ( access == "protected" ) { + protectedSlots += slotName; + protectedSlotTypes += returnType; + protectedSlotSpecifier += specifier; + } else if ( access == "private" ) { + privateSlots += slotName; + privateSlotTypes += returnType; + privateSlotSpecifier += specifier; + } else { + publicSlots += slotName; + publicSlotTypes += returnType; + publicSlotSpecifier += specifier; + } + } + + + // compatibility with early 3.0 betas + nl = e.parentNode().toElement().elementsByTagName( "function" ); + for ( i = 0; i < (int) nl.length(); i++ ) { + QString fname = n.attribute( "name" ); + fname = Parser::cleanArgs( fname ); + functionImpls.insert( fname, n.firstChild().toText().data() ); + } + // create stubs for public additional slots + if ( !publicSlots.isEmpty() ) { + for ( it = publicSlots.begin(), it2 = publicSlotTypes.begin(), it3 = publicSlotSpecifier.begin(); + it != publicSlots.end(); ++it, ++it2, ++it3 ) { + QString pure; + QString type = *it2; + if ( type.isEmpty() ) + type = "void"; + if ( *it3 == "non virtual" ) + continue; + if ( isEmptyFunction( *it ) ) { + out << endl; + int astart = (*it).find('('); + out << indent << "def " << (*it).left(astart)<< "(*k)" << endl; + ++indent; + out << indent << "print(\"" << subClass << "." << (*it) << ": Not implemented yet.\\n\")" << endl; + --indent; + out << indent << "end" << endl; + } + } + } + + // create stubs for protected additional slots + if ( !protectedSlots.isEmpty() ) { + for ( it = protectedSlots.begin(), it2 = protectedSlotTypes.begin(), it3 = protectedSlotSpecifier.begin(); + it != protectedSlots.end(); ++it, ++it2, ++it3 ) { + QString pure; + QString type = *it2; + if ( type.isEmpty() ) + type = "void"; + if ( *it3 == "non virtual" ) + continue; + if ( isEmptyFunction( *it ) ) { + out << endl; + int astart = (*it).find('('); + out << indent << "def " << (*it).left(astart)<< "(*k)" << endl; + ++indent; + out << indent << "print(\"" << subClass << "." << (*it) << ": (Protected) Not implemented yet.\\n\")" << endl; + --indent; + out << indent << "end" << endl; + out << indent << "protected :" << (*it).left(astart)<< endl; + } + } + } + + + // create stubs for private additional slots + if ( !privateSlots.isEmpty() ) { + for ( it = privateSlots.begin(), it2 = privateSlotTypes.begin(), it3 = privateSlotSpecifier.begin(); + it != privateSlots.end(); ++it, ++it2, ++it3 ) { + QString pure; + QString type = *it2; + if ( type.isEmpty() ) + type = "void"; + if ( *it3 == "non virtual" ) + continue; + if ( isEmptyFunction( *it ) ) { + out << endl; + int astart = (*it).find('('); + out << indent << "def " << (*it).left(astart)<< "(*k)" << endl; + ++indent; + out << indent << "print(\"" << subClass << "." << (*it) << ": (Private) Not implemented yet.\\n\")" << endl; + --indent; + out << indent << "end" << endl; + out << indent << "private :" << (*it).left(astart)<< endl; + } + } + } + + --indent; + out << indent << "end" << endl; +} diff --git a/qtruby/rubylib/designer/rbuic/uic.cpp b/qtruby/rubylib/designer/rbuic/uic.cpp new file mode 100644 index 00000000..e4f8eed7 --- /dev/null +++ b/qtruby/rubylib/designer/rbuic/uic.cpp @@ -0,0 +1,1104 @@ +/********************************************************************** +** Copyright (C) 2000 Trolltech AS. All rights reserved. +** Copyright (c) 2001 Phil Thompson <phil@river-bank.demon.co.uk> +** Copyright (c) 2002 Germain Garand <germain@ebooksfrance.com> +** +** This file is part of Qt Designer. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ +/* +** 06/2002 : Initial release of puic, the PerlQt User Interface Compiler, +** a work derivated from uic (the Qt User Interface Compiler) +** and pyuic (the PyQt User Interface Compiler). +** +** G.Garand +** +** 08/2003 : Initial release of rbuic, the QtRuby User Interface Compiler, +** a work derived from the PerlQt puic. +** +** Richard Dale +** +**********************************************************************/ + +#include "uic.h" +#include "parser.h" +#include "widgetdatabase.h" +#include "domtool.h" +#include <qfile.h> +#include <qstringlist.h> +#include <qdatetime.h> +#define NO_STATIC_COLORS +#include <globaldefs.h> +#include <qregexp.h> +#include <stdio.h> +#include <stdlib.h> +#include <zlib.h> + +bool Uic::hasKDEwidget = false; +bool Uic::isMainWindow = false; +RubyIndent Uic::indent; + + +// Re-calculate the indent string based on the current number and nature of the +// indent. +void RubyIndent::calc() +{ + indstr.truncate(0); + + for (uint i = current; i > 0; --i) + if (tabStop == 0) + indstr += '\t'; + else + for (uint t = 0; t < tabStop; ++t) + indstr += ' '; +} + + +QString Uic::getComment( const QDomNode& n ) +{ + QDomNode child = n.firstChild(); + while ( !child.isNull() ) { + if ( child.toElement().tagName() == "comment" ) + return child.toElement().firstChild().toText().data(); + child = child.nextSibling(); + } + return QString::null; +} + +QString Uic::mkBool( bool b ) +{ + return b? "true" : "false"; +} + +QString Uic::mkBool( const QString& s ) +{ + return mkBool( s == "true" || s == "1" ); +} + +bool Uic::toBool( const QString& s ) +{ + return s == "true" || s.toInt() != 0; +} + +QString Uic::fixString( const QString &str ) +{ + QString s( str ); + s.replace( QRegExp( "\\\\" ), "\\\\" ); + s.replace( QRegExp( "\"" ), "\\\"" ); + s.replace( QRegExp( "\r?\n" ), "\\n\" +\n" + indent + "\"" ); + return "\"" + s + "\""; +} + +QString Uic::trcall( const QString& sourceText, const QString& comment ) +{ + if ( sourceText.isEmpty() && comment.isEmpty() ) + return "nil"; + + if ( comment.isEmpty() ) + return trmacro + "(" + fixString( sourceText ) + ")"; + return trmacro + "(" + fixString( sourceText ) + "," + fixString( comment ) + ")"; +} + +QString Uic::mkStdSet( const QString& prop ) +{ + return QString( "set" ) + prop[0].upper() + prop.mid(1); +} + + + +bool Uic::isEmptyFunction( const QString& fname ) +{ + QMap<QString, QString>::Iterator fit = functionImpls.find( Parser::cleanArgs( fname ) ); + if ( fit != functionImpls.end() ) { + int begin = (*fit).find( "{" ); + QString body = (*fit).mid( begin + 1, (*fit).findRev( "}" ) - begin - 1 ); + return body.simplifyWhiteSpace().isEmpty(); + } + // For now ruby functions are always empty, until a rubyeditor Qt Designer plugin exists.. + return true; +} + + + +/*! + \class Uic uic.h + \brief User Interface Compiler + + The class Uic encapsulates the user interface compiler (uic). + */ +Uic::Uic( const QString &fn, QTextStream &outStream, QDomDocument doc, + bool subcl, const QString &trm, const QString& subClass, + bool omitForwardDecls, QString &uicClass, bool useKDE ) + : out( outStream ), trout( &languageChangeBody ), + trmacro( trm ), nofwd( omitForwardDecls ) +{ + Uic::hasKDEwidget = useKDE; + fileName = fn; + writeSlotImpl = true; + defMargin = BOXLAYOUT_DEFAULT_MARGIN; + defSpacing = BOXLAYOUT_DEFAULT_SPACING; + externPixmaps = false; + + item_used = cg_used = pal_used = 0; + + layouts << "hbox" << "vbox" << "grid"; + tags = layouts; + tags << "widget"; + + pixmapLoaderFunction = getPixmapLoaderFunction( doc.firstChild().toElement() ); + nameOfClass = getFormClassName( doc.firstChild().toElement() ); + + uiFileVersion = doc.firstChild().toElement().attribute("version"); + stdsetdef = toBool( doc.firstChild().toElement().attribute("stdsetdef") ); + + QDomElement e = doc.firstChild().firstChild().toElement(); + QDomElement widget; + while ( !e.isNull() ) { + if ( e.tagName() == "widget" ) { + widget = e; + } else if ( e.tagName() == "pixmapinproject" ) { + externPixmaps = true; + } else if ( e.tagName() == "layoutdefaults" ) { + defSpacing = e.attribute( "spacing", QString::number( defSpacing ) ).toInt(); + defMargin = e.attribute( "margin", QString::number( defMargin ) ).toInt(); + } + e = e.nextSibling().toElement(); + } + e = widget; + + if ( nameOfClass.isEmpty() ) + nameOfClass = getObjectName( e ); + + uicClass = nameOfClass; + + if ( subcl ) { + createSubImpl( e, subClass ); + } else { + createFormImpl( e ); + } +} + +/*! Extracts a pixmap loader function from \a e + */ +QString Uic::getPixmapLoaderFunction( const QDomElement& e ) +{ + QDomElement n; + for ( n = e.firstChild().toElement(); !n.isNull(); n = n.nextSibling().toElement() ) { + if ( n.tagName() == "pixmapfunction" ) + return n.firstChild().toText().data(); + } + return QString::null; +} + + +/*! Extracts the forms class name from \a e + */ +QString Uic::getFormClassName( const QDomElement& e ) +{ + QDomElement n; + QString cn; + for ( n = e.firstChild().toElement(); !n.isNull(); n = n.nextSibling().toElement() ) { + if ( n.tagName() == "class" ) { + QString s = n.firstChild().toText().data(); + int i; + while ( ( i = s.find(' ' )) != -1 ) + s[i] = '_'; + cn = s; + } + } + return cn; +} + +/*! Extracts a Ruby class name from \a e. + */ +QString Uic::getClassName( const QDomElement& e ) +{ + QString s = e.attribute( "class" ); + if ( s.isEmpty() && e.tagName() == "toolbar" ) + s = "Qt::ToolBar"; + else if ( s.isEmpty() && e.tagName() == "menubar" ) + s = "Qt::MenuBar"; + else + { + QRegExp r("^([QK])(\\S+)"); + if( r.search( s ) != -1 ) { + if (r.cap(1) == "K") { + hasKDEwidget = true; + s = "KDE::" + r.cap(2); + } else { + if (s.startsWith("Qext")) { + s = "Qext::" + r.cap(2).mid(4); + } else { + s = "Qt::" + r.cap(2); + } + } + } + } + return s; +} + + + +/*! Returns TRUE if database framework code is generated, else FALSE. +*/ + +bool Uic::isFrameworkCodeGenerated( const QDomElement& e ) +{ + QDomElement n = getObjectProperty( e, "frameworkCode" ); + if ( n.attribute("name") == "frameworkCode" && + !DomTool::elementToVariant( n.firstChild().toElement(), QVariant( true, 0 ) ).toBool() ) + return false; + return true; +} + +/*! Extracts an object name from \a e. It's stored in the 'name' + property. + */ +QString Uic::getObjectName( const QDomElement& e ) +{ + QDomElement n = getObjectProperty( e, "name" ); + if ( n.firstChild().toElement().tagName() == "cstring" ) + return n.firstChild().toElement().firstChild().toText().data(); + return QString::null; +} + +/*! Extracts an layout name from \a e. It's stored in the 'name' + property of the preceeding sibling (the first child of a QLayoutWidget). + */ +QString Uic::getLayoutName( const QDomElement& e ) +{ + QDomElement p = e.parentNode().toElement(); + QString tail = QString::null; + + if ( getClassName(p) != "Qt::LayoutWidget" ) + tail = "Layout"; + + QDomElement n = getObjectProperty( p, "name" ); + if ( n.firstChild().toElement().tagName() == "cstring" ) + return n.firstChild().toElement().firstChild().toText().data() + tail; + return e.tagName(); +} + + +QString Uic::getDatabaseInfo( const QDomElement& e, const QString& tag ) +{ + QDomElement n; + QDomElement n1; + int child = 0; + // database info is a stringlist stored in this order + if ( tag == "connection" ) + child = 0; + else if ( tag == "table" ) + child = 1; + else if ( tag == "field" ) + child = 2; + else + return QString::null; + n = getObjectProperty( e, "database" ); + if ( n.firstChild().toElement().tagName() == "stringlist" ) { + // find correct stringlist entry + QDomElement n1 = n.firstChild().firstChild().toElement(); + for ( int i = 0; i < child && !n1.isNull(); ++i ) + n1 = n1.nextSibling().toElement(); + if ( n1.isNull() ) + return QString::null; + return n1.firstChild().toText().data(); + } + return QString::null; +} + + +void Uic::registerLayouts( const QDomElement &e ) +{ + if ( layouts.contains(e.tagName()) ) + createObjectDecl(e); + + QDomNodeList nl = e.childNodes(); + for ( int i = 0; i < (int) nl.length(); ++i ) + registerLayouts( nl.item(i).toElement() ); +} + + +/*! + Returns include file for class \a className or a null string. + */ +QString Uic::getInclude( const QString& className ) +{ + int wid = WidgetDatabase::idFromClassName( className ); + if ( wid != -1 ) + return WidgetDatabase::includeFile( wid ); + return QString::null; +} + +void Uic::createActionDecl( const QDomElement& e ) +{ + QString objName = getObjectName( e ); + if ( objName.isEmpty() ) + return; + out << indent << objName << endl; + if ( e.tagName() == "actiongroup" ) { + for ( QDomElement n = e.firstChild().toElement(); !n.isNull(); n = n.nextSibling().toElement() ) { + if ( n.tagName() == "action" || n.tagName() == "actiongroup" ) + createActionDecl( n ); + } + } +} + +void Uic::createActionImpl( const QDomElement &n, const QString &parent ) +{ + for ( QDomElement ae = n; !ae.isNull(); ae = ae.nextSibling().toElement() ) { + QString objName = registerObject( getObjectName( ae ) ); + if ( ae.tagName() == "action" ) + out << indent << objName << "= Qt::Action.new(" << parent << ", \"" << objName.mid(1) << "\")" << endl; + else if ( ae.tagName() == "actiongroup" ) + out << indent << objName << "= Qt::ActionGroup.new(" << parent << ", \"" << objName.mid(1) << "\")" << endl; + else + continue; + bool subActionsDone = false; + bool hasMenuText = false; + QString actionText; + for ( QDomElement n2 = ae.firstChild().toElement(); !n2.isNull(); n2 = n2.nextSibling().toElement() ) { + if ( n2.tagName() == "property" ) { + bool stdset = stdsetdef; + if ( n2.hasAttribute( "stdset" ) ) + stdset = toBool( n2.attribute( "stdset" ) ); + QString prop = n2.attribute("name"); + if ( prop == "name" ) + continue; + QString value = setObjectProperty( "Qt::Action", objName, prop, n2.firstChild().toElement(), stdset ); + if ( value.isEmpty() ) + continue; + + QString call = objName + "."; + if ( stdset ) { + call += mkStdSet( prop ) + "(" + value + ")"; + } else { + call += "setProperty( \"" + prop + "\", "; + call += "Qt::Variant.new(" + value + "))"; + } + + if (prop == "menuText") + hasMenuText = true; + else if (prop == "text") + actionText = value; + + if ( n2.firstChild().toElement().tagName() == "string" ) { + trout << indent << call << endl; + } else { + out << indent << call << endl; + } + } else if ( !subActionsDone && ( n2.tagName() == "actiongroup" || n2.tagName() == "action" ) ) { + createActionImpl( n2, objName ); + subActionsDone = true; + } + } + // workaround for loading pre-3.3 files expecting bogus QAction behavior + if (!hasMenuText && !actionText.isEmpty() && uiFileVersion < "3.3") + trout << indent << objName << ".setMenuText(" << actionText << ")" << endl; + } +} + +QString get_dock( const QString &d ) +{ + if ( d == "0" ) + return "DockUnmanaged"; + if ( d == "1" ) + return "DockTornOff"; + if ( d == "2" ) + return "DockTop"; + if ( d == "3" ) + return "DockBottom"; + if ( d == "4" ) + return "DockRight"; + if ( d == "5" ) + return "DockLeft"; + if ( d == "6" ) + return "DockMinimized"; + return ""; +} + +void Uic::createToolbarImpl( const QDomElement &n, const QString &parentClass, const QString &parent ) +{ + QDomNodeList nl = n.elementsByTagName( "toolbar" ); + for ( int i = 0; i < (int) nl.length(); i++ ) { + QDomElement ae = nl.item( i ).toElement(); + QString dock = get_dock( ae.attribute( "dock" ) ); + QString objName = "@" + getObjectName( ae ); + out << indent << objName << " = Qt::ToolBar.new(\"\", self, " << dock << ")" << endl; + createObjectImpl( ae, parentClass, parent ); + for ( QDomElement n2 = ae.firstChild().toElement(); !n2.isNull(); n2 = n2.nextSibling().toElement() ) { + if ( n2.tagName() == "action" ) { + out << indent << "@" << n2.attribute( "name" ) << ".addTo( " << objName << " )" << endl; + } else if ( n2.tagName() == "separator" ) { + out << indent << objName << ".addSeparator;" << endl; + } else if ( n2.tagName() == "widget" ) { + if ( n2.attribute( "class" ) != "Spacer" ) { + createObjectImpl( n2, "Qt::ToolBar", objName ); + } else { + QString child = createSpacerImpl( n2, parentClass, parent, objName ); + out << indent << "Qt::Application.sendPostedEvents( " << objName + << ", Qt::Event::ChildInserted)" << endl; + out << indent << objName << ".boxLayout().addItem(" << child << ")" << endl; + } + } + } + } +} + +void Uic::createMenuBarImpl( const QDomElement &n, const QString &parentClass, const QString &parent ) +{ + QString objName = "@" + getObjectName( n ); + out << indent << objName << " = Qt::MenuBar.new( self, \"" << objName.mid(1) << "\" )" << endl; + createObjectImpl( n, parentClass, parent ); + int i = 0; + QDomElement c = n.firstChild().toElement(); + while ( !c.isNull() ) { + if ( c.tagName() == "item" ) { + QString itemName = "@" + c.attribute( "name" ); + out << endl; + out << indent << itemName << " = Qt::PopupMenu.new( self )" << endl; + createPopupMenuImpl( c, parentClass, itemName ); + out << indent << objName << ".insertItem( \"\", " << itemName << ", " << i << " )" << endl; + QString findItem(objName + ".findItem(%1)"); + findItem = findItem.arg(i); + trout << indent << "if !" << findItem << ".nil?" << endl; + trout << indent << indent << findItem << ".setText( " << trcall( c.attribute( "text" ) ) << " )" << endl; + trout << indent << "end" << endl; + } else if ( c.tagName() == "separator" ) { + out << endl; + out << indent << objName << ".insertSeparator( " << i << " )" << endl; + } + c = c.nextSibling().toElement(); + i++; + } +} + +void Uic::createPopupMenuImpl( const QDomElement &e, const QString &parentClass, const QString &parent ) +{ + int i = 0; + for ( QDomElement n = e.firstChild().toElement(); !n.isNull(); n = n.nextSibling().toElement() ) { + if ( n.tagName() == "action" || n.tagName() == "actiongroup" ) { + QDomElement n2 = n.nextSibling().toElement(); + if ( n2.tagName() == "item" ) { // the action has a sub menu + QString itemName = "@" + n2.attribute( "name" ); + QString itemText = n2.attribute( "text" ); + out << indent << itemName << " = Qt::PopupMenu.new( self )" << endl; + out << indent << indent << parent << ".insertItem( @" << n.attribute( "name" ) << ".iconSet(),"; + out << trcall( itemText ) << ", " << itemName << " )" << endl; + trout << indent << parent << ".changeItem( " << parent << ".idAt( " << i << " ), "; + trout << trcall( itemText ) << " )" << endl; + createPopupMenuImpl( n2, parentClass, itemName ); + n = n2; + } else { + out << indent << "@" << n.attribute( "name" ) << ".addTo( " << parent << " )" << endl; + } + } else if ( n.tagName() == "separator" ) { + out << indent << parent << ".insertSeparator()" << endl; + } + ++i; + } +} + +/*! + Creates implementation of an listbox item tag. +*/ + +QString Uic::createListBoxItemImpl( const QDomElement &e, const QString &parent, + QString *value ) +{ + QDomElement n = e.firstChild().toElement(); + QString txt; + QString com; + QString pix; + while ( !n.isNull() ) { + if ( n.tagName() == "property" ) { + QString attrib = n.attribute("name"); + QVariant v = DomTool::elementToVariant( n.firstChild().toElement(), QVariant() ); + if ( attrib == "text" ) { + txt = v.toString(); + com = getComment( n ); + } else if ( attrib == "pixmap" ) { + pix = v.toString(); + if (!pix.isEmpty()) { + pix.prepend("@"); + } + if ( !pix.isEmpty() && !pixmapLoaderFunction.isEmpty() ) { + pix.prepend( pixmapLoaderFunction + "(" + QString( externPixmaps ? "\"" : "" ) ); + pix.append( QString( externPixmaps ? "\"" : "" ) + ")" ); + } + } + } + n = n.nextSibling().toElement(); + } + + if ( value ) + *value = trcall( txt, com ); + + if ( pix.isEmpty() ) + return parent + ".insertItem(" + trcall( txt, com ) + ")"; + + return parent + ".insertItem(" + pix + ", " + trcall( txt, com ) + ")"; +} + +/*! + Creates implementation of an iconview item tag. +*/ + +QString Uic::createIconViewItemImpl( const QDomElement &e, const QString &parent ) +{ + QDomElement n = e.firstChild().toElement(); + QString txt; + QString com; + QString pix; + while ( !n.isNull() ) { + if ( n.tagName() == "property" ) { + QString attrib = n.attribute("name"); + QVariant v = DomTool::elementToVariant( n.firstChild().toElement(), QVariant() ); + if ( attrib == "text" ) { + txt = v.toString(); + com = getComment( n ); + } else if ( attrib == "pixmap" ) { + pix = v.toString(); + if (!pix.isEmpty()) { + pix.prepend("@"); + } + if ( !pix.isEmpty() && !pixmapLoaderFunction.isEmpty() ) { + pix.prepend( pixmapLoaderFunction + "(" + QString( externPixmaps ? "\"" : "" ) ); + pix.append( QString( externPixmaps ? "\"" : "" ) + ")" ); + } + } + } + n = n.nextSibling().toElement(); + } + + if ( pix.isEmpty() ) + return "Qt::IconViewItem.new(" + parent + ", " + trcall( txt, com ) + ")"; + else + return "Qt::IconViewItem.new(" + parent + ", " + trcall( txt, com ) + ", " + pix + ")"; +} + +/*! + Creates implementation of an listview item tag. +*/ + +QString Uic::createListViewItemImpl( const QDomElement &e, const QString &parent, + const QString &parentItem ) +{ + QString s; + + QDomElement n = e.firstChild().toElement(); + + bool hasChildren = e.elementsByTagName( "item" ).count() > 0; + QString item; + + if ( hasChildren ) { + item = registerObject( "item" ); + s = indent + item + " = "; + } else { + if (! item_used) { + // This is here to make the ruby generated names for 'item', + // the same as the original C++ + item = registerObject( "item" ); + item_used = true; + } + item = "item"; + s = indent + item + " = "; + } + + if ( !parentItem.isEmpty() ) + s += "Qt::ListViewItem.new(" + parentItem + ", " + lastItem + ")\n"; + else + s += "Qt::ListViewItem.new(" + parent + ", " + lastItem + ")\n"; + + QStringList textes; + QStringList pixmaps; + while ( !n.isNull() ) { + if ( n.tagName() == "property" ) { + QString attrib = n.attribute("name"); + QVariant v = DomTool::elementToVariant( n.firstChild().toElement(), QVariant() ); + if ( attrib == "text" ) + textes << v.toString(); + else if ( attrib == "pixmap" ) { + QString pix = v.toString(); + if (!pix.isEmpty()) { + pix.prepend("@"); + } + if ( !pix.isEmpty() && !pixmapLoaderFunction.isEmpty() ) { + pix.prepend( pixmapLoaderFunction + "(" + QString( externPixmaps ? "\"" : "" ) ); + pix.append( QString( externPixmaps ? "\"" : "" ) + ")" ); + } + pixmaps << pix; + } + } else if ( n.tagName() == "item" ) { + s += indent + item + ".setOpen(true)\n"; + s += createListViewItemImpl( n, parent, item ); + } + n = n.nextSibling().toElement(); + } + + for ( int i = 0; i < (int)textes.count(); ++i ) { + if ( !textes[ i ].isEmpty() ) + s += indent + item + ".setText(" + QString::number( i ) + ", " + trcall( textes[ i ] ) + ")\n"; + if ( !pixmaps[ i ].isEmpty() ) + s += indent + item + ".setPixmap(" + QString::number( i ) + ", " + pixmaps[ i ] + ")\n"; + } + + lastItem = item; + return s; +} + +/*! + Creates implementation of an listview column tag. +*/ + +QString Uic::createListViewColumnImpl( const QDomElement &e, const QString &parent, + QString *value ) +{ + QDomElement n = e.firstChild().toElement(); + QString txt; + QString com; + QString pix; + bool clickable = false, resizeable = false; + while ( !n.isNull() ) { + if ( n.tagName() == "property" ) { + QString attrib = n.attribute("name"); + QVariant v = DomTool::elementToVariant( n.firstChild().toElement(), QVariant() ); + if ( attrib == "text" ) { + txt = v.toString(); + com = getComment( n ); + } else if ( attrib == "pixmap" ) { + pix = v.toString(); + if (!pix.isEmpty()) { + pix.prepend("@"); + } + if ( !pix.isEmpty() && !pixmapLoaderFunction.isEmpty() ) { + pix.prepend( pixmapLoaderFunction + "(" + QString( externPixmaps ? "\"" : "" ) ); + pix.append( QString( externPixmaps ? "\"" : "" ) + ")" ); + } + } else if ( attrib == "clickable" ) + clickable = v.toBool(); + else if ( attrib == "resizable" || attrib == "resizeable" ) + resizeable = v.toBool(); + } + n = n.nextSibling().toElement(); + } + + if ( value ) + *value = trcall( txt, com ); + + QString s; + s = indent + parent + ".addColumn(" + trcall( txt, com ) + ")\n"; + if ( !pix.isEmpty() ) + s += indent + parent + ".header().setLabel(" + parent + ".header().count() - 1," + pix + ", " + trcall( txt, com ) + ")\n"; + if ( !clickable ) + s += indent + parent + ".header().setClickEnabled( false, " + parent + ".header().count() - 1 )\n"; + if ( !resizeable ) + s += indent + parent + ".header().setResizeEnabled( false, " + parent + ".header().count() - 1 )\n"; + + return s; +} + +QString Uic::createTableRowColumnImpl( const QDomElement &e, const QString &parent, + QString *value ) +{ + QString objClass = getClassName( e.parentNode().toElement() ); + QDomElement n = e.firstChild().toElement(); + QString txt; + QString com; + QString pix; + QString field; + bool isRow = e.tagName() == "row"; + while ( !n.isNull() ) { + if ( n.tagName() == "property" ) { + QString attrib = n.attribute("name"); + QVariant v = DomTool::elementToVariant( n.firstChild().toElement(), QVariant() ); + if ( attrib == "text" ) { + txt = v.toString(); + com = getComment( n ); + } else if ( attrib == "pixmap" ) { + pix = v.toString(); + if ( !pix.isEmpty() && !pixmapLoaderFunction.isEmpty() ) { + pix.prepend( pixmapLoaderFunction + "(" + QString( externPixmaps ? "\"" : "" ) ); + pix.append( QString( externPixmaps ? "\"" : "" ) + ")" ); + } + } else if ( attrib == "field" ) + field = v.toString(); + } + n = n.nextSibling().toElement(); + } + + if ( value ) + *value = trcall( txt, com ); + + // ### This generated code sucks! We have to set the number of + // rows/cols before and then only do setLabel/() + // ### careful, though, since QDataTable has an API which makes this code pretty good + + QString s; + if ( isRow ) { + s = indent + parent + ".setNumRows(" + parent + ".numRows() + 1 )\n"; + if ( pix.isEmpty() ) + s += indent + parent + ".verticalHeader().setLabel(" + parent + ".numRows() - 1, " + + trcall( txt, com ) + ")\n"; + else + s += indent + parent + ".verticalHeader().setLabel(" + parent + ".numRows() - 1, Qt::IconSet.new(@" + + pix + " ), " + trcall( txt, com ) + ")\n"; + } else { + if ( objClass == "Qt::Table" ) { + s = indent + parent + ".setNumCols(" + parent + ".numCols() + 1)\n"; + if ( pix.isEmpty() ) + s += indent + parent + ".horizontalHeader().setLabel(" + parent + ".numCols() - 1, " + + trcall( txt, com ) + ")\n"; + else + s += indent + parent + ".horizontalHeader().setLabel(" + parent + ".numCols() - 1, Qt::IconSet.new(@" + + pix + " ), " + trcall( txt, com ) + ")\n"; + } else if ( objClass == "Qt::DataTable" ) { + if ( !txt.isEmpty() && !field.isEmpty() ) { + if ( pix.isEmpty() ) + out << indent << parent << ".addColumn(" << fixString( field ) << ", " << trcall( txt, com ) << ")" << endl; + else + out << indent << parent << ".addColumn(" << fixString( field ) << ", " << trcall( txt, com ) << ", Qt::IconSet.new(@" << pix << "))" << endl; + } + } + } + return s; +} + +/*! + Creates the implementation of a layout tag. Called from createObjectImpl(). + */ +QString Uic::createLayoutImpl( const QDomElement &e, const QString& parentClass, const QString& parent, const QString& layout ) +{ + QDomElement n; + QString objClass, objName; + objClass = e.tagName(); + + QString qlayout = "Qt::VBoxLayout.new"; + if ( objClass == "hbox" ) + qlayout = "Qt::HBoxLayout.new"; + else if ( objClass == "grid" ) + qlayout = "Qt::GridLayout.new"; + + bool isGrid = e.tagName() == "grid" ; + objName = registerObject( getLayoutName( e ) ); + layoutObjects += objName; + + QString margin = DomTool::readProperty( e, "margin", defMargin ).toString(); + QString spacing = DomTool::readProperty( e, "spacing", defSpacing ).toString(); + QString resizeMode = DomTool::readProperty( e, "resizeMode", QString::null ).toString(); + + QString optcells; + if ( isGrid ) + optcells = "1, 1, "; + if ( (parentClass == "Qt::GroupBox" || parentClass == "Qt::ButtonGroup") && layout.isEmpty() ) { + // special case for group box + out << indent << parent << ".setColumnLayout( 0, Qt::Vertical )" << endl; + out << indent << parent << ".layout().setSpacing(" << spacing << ")" << endl; + out << indent << parent << ".layout().setMargin(" << margin << ")" << endl; + out << indent << objName << " = " << qlayout << "(" << parent << ".layout() )" << endl; + out << indent << objName << ".setAlignment( AlignTop )" << endl; + } else { + out << indent << objName << " = " << qlayout << "("; + if ( layout.isEmpty() ) + out << parent; + else { + out << "nil"; + if ( !DomTool::hasProperty( e, "margin" ) ) + margin = "0"; + } + out << ", " << optcells << margin << ", " << spacing << ", '" << objName.mid(1) << "')" << endl; + } + if ( !resizeMode.isEmpty() ) + out << indent << objName << ".setResizeMode( Qt::Layout::" << resizeMode << " )" << endl; + + if ( !isGrid ) { + for ( n = e.firstChild().toElement(); !n.isNull(); n = n.nextSibling().toElement() ) { + if ( n.tagName() == "spacer" ) { + QString child = createSpacerImpl( n, parentClass, parent, objName ); + out << indent << objName << ".addItem(" << child << ")" << endl; + } else if ( tags.contains( n.tagName() ) ) { + QString child = createObjectImpl( n, parentClass, parent, objName ); + if ( isLayout( child ) ) + out << indent << objName << ".addLayout(" << child << ")" << endl; + else + out << indent << objName << ".addWidget(" << child << ")" << endl; + } + } + } else { + for ( n = e.firstChild().toElement(); !n.isNull(); n = n.nextSibling().toElement() ) { + QDomElement ae = n; + int row = ae.attribute( "row" ).toInt(); + int col = ae.attribute( "column" ).toInt(); + int rowspan = ae.attribute( "rowspan" ).toInt(); + int colspan = ae.attribute( "colspan" ).toInt(); + if ( rowspan < 1 ) + rowspan = 1; + if ( colspan < 1 ) + colspan = 1; + if ( n.tagName() == "spacer" ) { + QString child = createSpacerImpl( n, parentClass, parent, objName ); + if ( rowspan * colspan != 1 ) + out << indent << objName << ".addMultiCell(" << child << ", " + << row << ", " << row + rowspan - 1 << ", " << col << ", " << col + colspan - 1 << ")" << endl; + else + out << indent << objName << ".addItem(" << child << ", " + << row << ", " << col << ")" << endl; + } else if ( tags.contains( n.tagName() ) ) { + QString child = createObjectImpl( n, parentClass, parent, objName ); + out << endl; + QString o = "Widget"; + if ( isLayout( child ) ) + o = "Layout"; + if ( rowspan * colspan != 1 ) + out << indent << objName << ".addMultiCell" << o << "(" << child << ", " + << row << ", " << row + rowspan - 1 << ", " << col << ", " << col + colspan - 1 << ")" << endl; + else + out << indent << objName << ".add" << o << "(" << child << ", " + << row << ", " << col << ")" << endl; + } + } + } + + return objName; +} + + + +QString Uic::createSpacerImpl( const QDomElement &e, const QString& /*parentClass*/, const QString& /*parent*/, const QString& /*layout*/) +{ + QDomElement n; + QString objClass, objName; + objClass = e.tagName(); + objName = registerObject( getObjectName( e ) ); + + QSize size = DomTool::readProperty( e, "sizeHint", QSize( 0, 0 ) ).toSize(); + QString sizeType = DomTool::readProperty( e, "sizeType", "Expanding" ).toString(); + bool isVspacer = DomTool::readProperty( e, "orientation", "Horizontal" ) == "Vertical"; + + if ( sizeType != "Expanding" && sizeType != "MinimumExpanding" && + DomTool::hasProperty( e, "geometry" ) ) { // compatibility Qt 2.2 + QRect geom = DomTool::readProperty( e, "geometry", QRect(0,0,0,0) ).toRect(); + size = geom.size(); + } + + if ( isVspacer ) + out << indent << objName << " = Qt::SpacerItem.new(" + << size.width() << ", " << size.height() + << ", Qt::SizePolicy::Minimum, Qt::SizePolicy::" << sizeType << ")" << endl; + else + out << indent << objName << " = Qt::SpacerItem.new(" + << size.width() << ", " << size.height() + << ", Qt::SizePolicy::" << sizeType << ", Qt::SizePolicy::Minimum)" << endl; + + return objName; +} + +static const char* const ColorRole[] = { + "Foreground", "Button", "Light", "Midlight", "Dark", "Mid", + "Text", "BrightText", "ButtonText", "Base", "Background", "Shadow", + "Highlight", "HighlightedText", "Link", "LinkVisited", 0 +}; + + +/*! + Creates a colorgroup with name \a name from the color group \a cg + */ +void Uic::createColorGroupImpl( const QString& name, const QDomElement& e ) +{ + QColorGroup cg; + int r = -1; + QDomElement n = e.firstChild().toElement(); + QString color; + while ( !n.isNull() ) { + if ( n.tagName() == "color" ) { + r++; + QColor col = DomTool::readColor( n ); + color = "Qt::Color.new(%1,%2,%3)"; + color = color.arg( col.red() ).arg( col.green() ).arg( col.blue() ); + if ( col == white ) + color = "white"; + else if ( col == black ) + color = "black"; + if ( n.nextSibling().toElement().tagName() != "pixmap" ) { + out << indent << name << ".setColor(Qt::ColorGroup::" << ColorRole[r] << ", " << color << ")" << endl; + } + } else if ( n.tagName() == "pixmap" ) { + QString pixmap = n.firstChild().toText().data(); + pixmap.prepend("@"); + if ( !pixmapLoaderFunction.isEmpty() ) { + pixmap.prepend( pixmapLoaderFunction + "(" + QString( externPixmaps ? "\"" : "" ) ); + pixmap.append( QString( externPixmaps ? "\"" : "" ) + ")" ); + } + out << indent << name << ".setBrush(Qt::ColorGroup::" + << ColorRole[r] << ", Qt::Brush.new(" << color << ", " << pixmap << "))" << endl; + } + n = n.nextSibling().toElement(); + } +} + +/*! + Auxiliary function to load a color group. The colorgroup must not + contain pixmaps. + */ +QColorGroup Uic::loadColorGroup( const QDomElement &e ) +{ + QColorGroup cg; + int r = -1; + QDomElement n = e.firstChild().toElement(); + QColor col; + while ( !n.isNull() ) { + if ( n.tagName() == "color" ) { + r++; + cg.setColor( (QColorGroup::ColorRole)r, (col = DomTool::readColor( n ) ) ); + } + n = n.nextSibling().toElement(); + } + return cg; +} + +/*! Returns TRUE if the widget properties specify that it belongs to + the database \a connection and \a table. +*/ + +bool Uic::isWidgetInTable( const QDomElement& e, const QString& connection, const QString& table ) +{ + QString conn = getDatabaseInfo( e, "connection" ); + QString tab = getDatabaseInfo( e, "table" ); + if ( conn == connection && tab == table ) + return true; + return false; +} + +/*! + Registers all database connections, cursors and forms. +*/ + +void Uic::registerDatabases( const QDomElement& e ) +{ + QDomElement n; + QDomNodeList nl; + int i; + nl = e.parentNode().toElement().elementsByTagName( "widget" ); + for ( i = 0; i < (int) nl.length(); ++i ) { + n = nl.item(i).toElement(); + QString conn = getDatabaseInfo( n, "connection" ); + QString tab = getDatabaseInfo( n, "table" ); + QString fld = getDatabaseInfo( n, "field" ); + if ( !conn.isNull() ) { + dbConnections += conn; + if ( !tab.isNull() ) { + dbCursors[conn] += tab; + if ( !fld.isNull() ) + dbForms[conn] += tab; + } + } + } +} + +/*! + Registers an object with name \a name. + + The returned name is a valid variable identifier, as similar to \a + name as possible and guaranteed to be unique within the form. + + \sa registeredName(), isObjectRegistered() + */ +QString Uic::registerObject( const QString& name ) +{ + if ( objectNames.isEmpty() ) { + // some temporary variables we need + objectNames += "img"; + objectNames += "item"; + objectNames += "cg"; + objectNames += "pal"; + } + QString result("@"); + result += name; + int i; + while ( ( i = result.find(' ' )) != -1 ) { + result[i] = '_'; + } + + if ( objectNames.contains( result ) ) { + int i = 2; + while ( objectNames.contains( result + "_" + QString::number(i) ) ) + i++; + result += "_"; + result += QString::number(i); + } + objectNames += result; + objectMapper.insert( name, result ); + return result; +} + +/*! + Returns the registered name for the original name \a name + or \a name if \a name wasn't registered. + + \sa registerObject(), isObjectRegistered() + */ +QString Uic::registeredName( const QString& name ) +{ + if ( !objectMapper.contains( name ) ) + return name; + return objectMapper[name]; +} + +/*! + Returns whether the object \a name was registered yet or not. + */ +bool Uic::isObjectRegistered( const QString& name ) +{ + return objectMapper.contains( name ); +} + + +/*! + Unifies the entries in stringlist \a list. Should really be a QStringList feature. + */ +QStringList Uic::unique( const QStringList& list ) +{ + QStringList result; + if ( list.isEmpty() ) + return result; + QStringList l = list; + l.sort(); + result += l.first(); + for ( QStringList::Iterator it = l.begin(); it != l.end(); ++it ) { + if ( *it != result.last() ) + result += *it; + } + return result; +} + + + +/*! + Creates an instance of class \a objClass, with parent \a parent and name \a objName + */ +QString Uic::createObjectInstance( const QString& objClass, const QString& parent, const QString& objName ) +{ + + if ( objClass.mid( 4 ) == "ComboBox" ) { + return objClass + ".new(false, " + parent + ", \"" + objName.mid(1) + "\")"; + } + return objClass + ".new(" + parent + ", \"" + objName.mid(1) + "\")"; +} + +bool Uic::isLayout( const QString& name ) const +{ + return layoutObjects.contains( name ); +} diff --git a/qtruby/rubylib/designer/rbuic/uic.h b/qtruby/rubylib/designer/rbuic/uic.h new file mode 100644 index 00000000..707df590 --- /dev/null +++ b/qtruby/rubylib/designer/rbuic/uic.h @@ -0,0 +1,181 @@ +/********************************************************************** +** Copyright (C) 2000 Trolltech AS. All rights reserved. +** Copyright (c) 2001 Phil Thompson <phil@river-bank.demon.co.uk> +** +** This file is part of Qt Designer. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ + +#ifndef UIC_H +#define UIC_H +#include <qdom.h> +#include <qstring.h> +#include <qstringlist.h> +#include <qmap.h> +#include <qtextstream.h> +#include <qpalette.h> + + +class RubyIndent +{ +public: + RubyIndent() : tabStop(4), current(0) {calc();} + + void setTabStop(uint n) {tabStop = n; calc();} + void operator++() {++current; calc();} + void operator--() {--current; calc();} + operator QString() {return indstr;} + +private: + uint tabStop; + uint current; + QString indstr; + + void calc(); +}; + + +class Uic : public Qt +{ +public: + Uic( const QString &fn, QTextStream& out, QDomDocument doc, bool subcl, + const QString &trm, const QString& subclname, bool omitForwardDecls, + QString &uicClass, bool useKDE ); + + static void setIndent(const RubyIndent &rubyind) {indent = rubyind;} + + void createFormImpl( const QDomElement &e ); + + void createSubImpl( const QDomElement &e, const QString& subclname ); + + void createObjectDecl( const QDomElement& e ); + void createAttrDecl( const QDomElement& e ); + void createActionDecl( const QDomElement& e ); + void createActionImpl( const QDomElement& e, const QString &parent ); + void createToolbarImpl( const QDomElement &e, const QString &parentClass, const QString &parent ); + void createMenuBarImpl( const QDomElement &e, const QString &parentClass, const QString &parent ); + void createPopupMenuImpl( const QDomElement &e, const QString &parentClass, const QString &parent ); + QString createObjectImpl( const QDomElement &e, const QString& parentClass, const QString& parent, const QString& layout = QString::null ); + QString createLayoutImpl( const QDomElement &e, const QString& parentClass, const QString& parent, const QString& layout = QString::null ); + QString createObjectInstance( const QString& objClass, const QString& parent, const QString& objName ); + QString createSpacerImpl( const QDomElement &e, const QString& parentClass, const QString& parent, const QString& layout = QString::null ); + void createExclusiveProperty( const QDomElement & e, const QString& exclusiveProp ); + QString createListBoxItemImpl( const QDomElement &e, const QString &parent, QString *value = 0 ); + QString createIconViewItemImpl( const QDomElement &e, const QString &parent ); + QString createListViewColumnImpl( const QDomElement &e, const QString &parent, QString *value = 0 ); + QString createTableRowColumnImpl( const QDomElement &e, const QString &parent, QString *value = 0 ); + QString createListViewItemImpl( const QDomElement &e, const QString &parent, + const QString &parentItem ); + void createColorGroupImpl( const QString& cg, const QDomElement& e ); + QColorGroup loadColorGroup( const QDomElement &e ); + + QDomElement getObjectProperty( const QDomElement& e, const QString& name ); + QString getPixmapLoaderFunction( const QDomElement& e ); + QString getFormClassName( const QDomElement& e ); + QString getClassName( const QDomElement& e ); + QString getObjectName( const QDomElement& e ); + QString getLayoutName( const QDomElement& e ); + QString getInclude( const QString& className ); + + QString setObjectProperty( const QString& objClass, const QString& obj, const QString &prop, const QDomElement &e, bool stdset ); + + QString registerObject( const QString& name ); + QString registeredName( const QString& name ); + bool isObjectRegistered( const QString& name ); + QStringList unique( const QStringList& ); + + QString trcall( const QString& sourceText, const QString& comment = "" ); + + static void embed( QTextStream& out, const char* project, const QStringList& images ); + + friend void getDBConnections(Uic& uic, QString& s); + static bool hasKDEwidget; + +private: + void registerLayouts ( const QDomElement& e ); + + QTextStream& out; + QTextOStream trout; + QString languageChangeBody; + QStringList objectNames; + QMap<QString,QString> objectMapper; + QStringList tags; + QStringList layouts; + QString formName; + QString lastItem; + QString trmacro; + + bool nofwd; + static RubyIndent indent; + + struct Buddy + { + Buddy( const QString& k, const QString& b ) + : key( k ), buddy( b ) {} + Buddy(){} // for valuelist + QString key; + QString buddy; + bool operator==( const Buddy& other ) const + { return (key == other.key); } + }; + struct CustomInclude + { + QString header; + QString location; + }; + QValueList<Buddy> buddies; + + QStringList layoutObjects; + bool isLayout( const QString& name ) const; + + uint item_used : 1; + uint cg_used : 1; + uint pal_used : 1; + uint stdsetdef : 1; + uint externPixmaps : 1; + + QString uiFileVersion; + QString nameOfClass; + QString pixmapLoaderFunction; + + void registerDatabases( const QDomElement& e ); + bool isWidgetInTable( const QDomElement& e, const QString& connection, const QString& table ); + bool isFrameworkCodeGenerated( const QDomElement& e ); + QString getDatabaseInfo( const QDomElement& e, const QString& tag ); + void createFormImpl( const QDomElement& e, const QString& form, const QString& connection, const QString& table ); + QStringList dbConnections; + QMap< QString, QStringList > dbCursors; + QMap< QString, QStringList > dbForms; + + static bool isMainWindow; + static QString mkBool( bool b ); + static QString mkBool( const QString& s ); + bool toBool( const QString& s ); + static QString fixString( const QString &str ); + static bool onlyAscii; + static QString mkStdSet( const QString& prop ); + static QString getComment( const QDomNode& n ); + int defSpacing, defMargin; + QString fileName; + bool writeSlotImpl; + + bool isEmptyFunction( const QString& fname ); + QMap<QString, QString> functionImpls; + + void rubySlot(QStringList::Iterator &it); +}; + +#endif diff --git a/qtruby/rubylib/designer/rbuic/widgetdatabase.cpp b/qtruby/rubylib/designer/rbuic/widgetdatabase.cpp new file mode 100644 index 00000000..c79815b1 --- /dev/null +++ b/qtruby/rubylib/designer/rbuic/widgetdatabase.cpp @@ -0,0 +1,833 @@ +/********************************************************************** +** Copyright (C) 2000 Trolltech AS. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ + +#if !defined(UIC) +#include "../designer/pixmapchooser.h" +#endif +#include "widgetinterface.h" +#include "widgetdatabase.h" + +#include <qapplication.h> +#define NO_STATIC_COLORS +#include <globaldefs.h> +#include <qstrlist.h> +#include <qdict.h> +#include <qfile.h> +#include <qtextstream.h> +#include <qcleanuphandler.h> + +#include <qfeatures.h> + +#include <stdlib.h> + +const int dbsize = 300; +const int dbcustom = 200; +const int dbdictsize = 211; +static WidgetDatabaseRecord* db[ dbsize ]; +static QDict<int> *className2Id = 0; +static int dbcount = 0; +static int dbcustomcount = 200; +static QStrList *wGroups; +static QStrList *invisibleGroups; +static bool whatsThisLoaded = false; +static QPluginManager<WidgetInterface> *widgetPluginManager = 0; +static bool plugins_set_up = false; +static bool was_in_setup = false; + +QCleanupHandler<QPluginManager<WidgetInterface> > cleanup_manager; + +WidgetDatabaseRecord::WidgetDatabaseRecord() +{ + isForm = false; + isContainer = false; + icon = 0; + nameCounter = 0; +} + +WidgetDatabaseRecord::~WidgetDatabaseRecord() +{ + delete icon; +} + + +/*! + \class WidgetDatabase widgetdatabase.h + \brief The WidgetDatabase class holds information about widgets + + The WidgetDatabase holds information about widgets like toolTip(), + iconSet(), ... It works Id-based, so all access functions take the + widget id as parameter. To get the id for a widget (classname), use + idFromClassName(). + + All access functions are static. Having multiple widgetdatabases in + one application doesn't make sense anyway and so you don't need more + than an instance of the widgetdatabase. + + For creating widgets, layouts, etc. see WidgetFactory. +*/ + +/*! + Creates widget database. Does nothing. +*/ + +WidgetDatabase::WidgetDatabase() +{ +} + +/*! Sets up the widget database. If the static widgetdatabase already + exists, the functions returns immediately. +*/ + +void WidgetDatabase::setupDataBase( int id ) +{ + was_in_setup = true; +#ifndef UIC + Q_UNUSED( id ) + if ( dbcount ) + return; +#else + if ( dbcount && id != -2 ) + return; + if ( dbcount && !plugins_set_up ) { + setupPlugins(); + return; + } + if ( dbcount && plugins_set_up) + return; +#endif + + wGroups = new QStrList; + invisibleGroups = new QStrList; + invisibleGroups->append( "Forms" ); + invisibleGroups->append( "Temp" ); + className2Id = new QDict<int>( dbdictsize ); + className2Id->setAutoDelete( true ); + + WidgetDatabaseRecord *r = 0; + + r = new WidgetDatabaseRecord; + r->iconSet = "pushbutton.xpm"; + r->name = "QPushButton"; + r->group = widgetGroup( "Buttons" ); + r->toolTip = "Push Button"; + + append( r ); + + r = new WidgetDatabaseRecord; + r->iconSet = "toolbutton.xpm"; + r->name = "QToolButton"; + r->group = widgetGroup( "Buttons" ); + r->toolTip = "Tool Button"; + + append( r ); + + r = new WidgetDatabaseRecord; + r->iconSet = "radiobutton.xpm"; + r->name = "QRadioButton"; + r->group = widgetGroup( "Buttons" ); + r->toolTip = "Radio Button"; + + append( r ); + + r = new WidgetDatabaseRecord; + r->iconSet = "checkbox.xpm"; + r->name = "QCheckBox"; + r->group = widgetGroup( "Buttons" ); + r->toolTip = "Check Box"; + + append( r ); + + r = new WidgetDatabaseRecord; + r->iconSet = "groupbox.xpm"; + r->name = "QGroupBox"; + r->group = widgetGroup( "Containers" ); + r->toolTip = "Group Box"; + r->isContainer = true; + + append( r ); + + r = new WidgetDatabaseRecord; + r->iconSet = "buttongroup.xpm"; + r->name = "QButtonGroup"; + r->group = widgetGroup( "Containers" ); + r->toolTip = "Button Group"; + r->isContainer = true; + + append( r ); + + r = new WidgetDatabaseRecord; + r->iconSet = "frame.xpm"; + r->name = "QFrame"; + r->group = widgetGroup( "Containers" ); + r->toolTip = "Frame"; + r->isContainer = true; + + append( r ); + + r = new WidgetDatabaseRecord; + r->iconSet = "tabwidget.xpm"; + r->name = "QTabWidget"; + r->group = widgetGroup( "Containers" ); + r->toolTip = "Tabwidget"; + r->isContainer = true; + + append( r ); + + + r = new WidgetDatabaseRecord; + r->iconSet = "listbox.xpm"; + r->name = "QListBox"; + r->group = widgetGroup( "Views" ); + r->toolTip = "List Box"; + + append( r ); + + r = new WidgetDatabaseRecord; + r->iconSet = "listview.xpm"; + r->name = "QListView"; + r->group = widgetGroup( "Views" ); + r->toolTip = "List View"; + + append( r ); + +#if !defined(QT_NO_ICONVIEW) || defined(UIC) + r = new WidgetDatabaseRecord; + r->iconSet = "iconview.xpm"; + r->name = "QIconView"; + r->group = widgetGroup( "Views" ); + r->toolTip = "Icon View"; + + append( r ); +#endif + +#if !defined(QT_NO_TABLE) + r = new WidgetDatabaseRecord; + r->iconSet = "table.xpm"; + r->name = "QTable"; + r->group = widgetGroup( "Views" ); + r->toolTip = "Table"; + + append( r ); +#endif + +#if !defined(QT_NO_SQL) + r = new WidgetDatabaseRecord; + r->iconSet = "datatable.xpm"; + r->includeFile = "qdatatable.h"; + r->name = "QDataTable"; + r->group = widgetGroup( "Database" ); + r->toolTip = "Data Table"; + + append( r ); +#endif + + r = new WidgetDatabaseRecord; + r->iconSet = "lineedit.xpm"; + r->name = "QLineEdit"; + r->group = widgetGroup( "Input" ); + r->toolTip = "Line Edit"; + + append( r ); + + r = new WidgetDatabaseRecord; + r->iconSet = "spinbox.xpm"; + r->name = "QSpinBox"; + r->group = widgetGroup( "Input" ); + r->toolTip = "Spin Box"; + + append( r ); + + r = new WidgetDatabaseRecord; + r->iconSet = "dateedit.xpm"; + r->name = "QDateEdit"; + r->group = widgetGroup( "Input" ); + r->toolTip = "Date Edit"; + r->includeFile = "qdatetimeedit.h"; + + append( r ); + + r = new WidgetDatabaseRecord; + r->iconSet = "timeedit.xpm"; + r->name = "QTimeEdit"; + r->group = widgetGroup( "Input" ); + r->toolTip = "Time Edit"; + r->includeFile = "qdatetimeedit.h"; + + append( r ); + + r = new WidgetDatabaseRecord; + r->iconSet = "datetimeedit.xpm"; + r->name = "QDateTimeEdit"; + r->group = widgetGroup( "Input" ); + r->toolTip = "Date-Time Edit"; + r->includeFile = "qdatetimeedit.h"; + + append( r ); + + r = new WidgetDatabaseRecord; + r->iconSet = "multilineedit.xpm"; + r->name = "QMultiLineEdit"; + r->group = widgetGroup( "Temp" ); + r->toolTip = "Multi Line Edit"; + + append( r ); + + r = new WidgetDatabaseRecord; + r->iconSet = "richtextedit.xpm"; + r->name = "QTextEdit"; + r->group = widgetGroup( "Input" ); + r->toolTip = "Richtext Editor"; + + append( r ); + + r = new WidgetDatabaseRecord; + r->iconSet = "combobox.xpm"; + r->name = "QComboBox"; + r->group = widgetGroup( "Input" ); + r->toolTip = "Combo Box"; + + append( r ); + + r = new WidgetDatabaseRecord; + r->iconSet = "slider.xpm"; + r->name = "QSlider"; + r->group = widgetGroup( "Input" ); + r->toolTip = "Slider"; + + append( r ); + + r = new WidgetDatabaseRecord; + r->iconSet = "scrollbar.xpm"; + r->name = "QScrollBar"; + r->group = widgetGroup( "Input" ); + r->toolTip = "Scrollbar"; + + append( r ); + + r = new WidgetDatabaseRecord; + r->iconSet = "dial.xpm"; + r->name = "QDial"; + r->group = widgetGroup( "Input" ); + r->toolTip = "Dial"; + + append( r ); + + r = new WidgetDatabaseRecord; + r->iconSet = "label.xpm"; + r->name = "QLabel"; + r->group = widgetGroup( "Temp" ); + r->toolTip = "Label"; + + append( r ); + + r = new WidgetDatabaseRecord; + r->iconSet = "label.xpm"; + r->name = "TextLabel"; + r->group = widgetGroup( "Display" ); + r->toolTip = "Text Label"; + r->whatsThis = "The Text Label provides a widget to display static text."; + + append( r ); + + r = new WidgetDatabaseRecord; + r->iconSet = "pixlabel.xpm"; + r->name = "PixmapLabel"; + r->group = widgetGroup( "Display" ); + r->toolTip = "Pixmap Label"; + r->whatsThis = "The Pixmap Label provides a widget to display pixmaps."; + + append( r ); + + r = new WidgetDatabaseRecord; + r->iconSet = "lcdnumber.xpm"; + r->name = "QLCDNumber"; + r->group = widgetGroup( "Display" ); + r->toolTip = "LCD Number"; + + append( r ); + + r = new WidgetDatabaseRecord; + r->iconSet = "line.xpm"; + r->name = "Line"; + r->group = widgetGroup( "Display" ); + r->toolTip = "Line"; + r->includeFile = "qframe.h"; + r->whatsThis = "The Line widget provides horizontal and vertical lines."; + + append( r ); + + r = new WidgetDatabaseRecord; + r->iconSet = "progress.xpm"; + r->name = "QProgressBar"; + r->group = widgetGroup( "Display" ); + r->toolTip = "Progress Bar"; + + append( r ); + + r = new WidgetDatabaseRecord; + r->iconSet = "textview.xpm"; + r->name = "QTextView"; + r->group = widgetGroup( "Temp" ); + r->toolTip = "Text View"; + + append( r ); + + r = new WidgetDatabaseRecord; + r->iconSet = "textbrowser.xpm"; + r->name = "QTextBrowser"; + r->group = widgetGroup( "Display" ); + r->toolTip = "Text Browser"; + + append( r ); + + r = new WidgetDatabaseRecord; + r->iconSet = "spacer.xpm"; + r->name = "Spacer"; + r->group = widgetGroup( "Temp" ); + r->toolTip = "Spacer"; + r->whatsThis = "The Spacer provides horizontal and vertical spacing to be able to manipulate the behaviour of layouts."; + + append( r ); + + r = new WidgetDatabaseRecord; + r->name = "QWidget"; + r->isForm = true; + r->group = widgetGroup( "Forms" ); + + append( r ); + + r = new WidgetDatabaseRecord; + r->name = "QDialog"; + r->group = widgetGroup( "Forms" ); + r->isForm = true; + + append( r ); + + r = new WidgetDatabaseRecord; + r->name = "QWizard"; + r->group = widgetGroup( "Forms" ); + r->isContainer = true; + + append( r ); + + r = new WidgetDatabaseRecord; + r->name = "QDesignerWizard"; + r->group = widgetGroup( "Forms" ); + r->isContainer = true; + + append( r ); + + r = new WidgetDatabaseRecord; + r->name = "QLayoutWidget"; + r->group = widgetGroup( "Temp" ); + r->includeFile = ""; + r->isContainer = true; + + append( r ); + + r = new WidgetDatabaseRecord; + r->name = "QSplitter"; + r->group = widgetGroup( "Temp" ); + r->includeFile = "qsplitter.h"; + r->isContainer = true; + + append( r ); + + r = new WidgetDatabaseRecord; + r->iconSet = "tabwidget.xpm"; + r->name = "QDesignerTabWidget"; + r->group = widgetGroup( "Temp" ); + r->isContainer = true; + + append( r ); + + r = new WidgetDatabaseRecord; + r->iconSet = "tabwidget.xpm"; + r->name = "QDesignerWidget"; + r->group = widgetGroup( "Temp" ); + r->isContainer = true; + + append( r ); + + r = new WidgetDatabaseRecord; + r->iconSet = "tabwidget.xpm"; + r->name = "QDesignerDialog"; + r->group = widgetGroup( "Temp" ); + r->isContainer = true; + + append( r ); + + r = new WidgetDatabaseRecord; + r->iconSet = ""; + r->name = "QMainWindow"; + r->includeFile = "qmainwindow.h"; + r->group = widgetGroup( "Temp" ); + r->isContainer = true; + + append( r ); + +#ifndef QT_NO_SQL + r = new WidgetDatabaseRecord; + r->iconSet = ""; + r->name = "QDataBrowser"; + r->includeFile = "qdatabrowser.h"; + r->group = widgetGroup( "Database" ); + r->toolTip = "Data Browser"; + r->iconSet = "databrowser.xpm"; + r->isContainer = true; + + append( r ); + + r = new WidgetDatabaseRecord; + r->iconSet = ""; + r->name = "QDataView"; + r->includeFile = "qdataview.h"; + r->group = widgetGroup( "Database" ); + r->toolTip = "Data View"; + r->iconSet = "dataview.xpm"; + r->isContainer = true; + + append( r ); +#endif + +#ifndef UIC + setupPlugins(); +#endif +} + +void WidgetDatabase::setupPlugins() +{ + if ( plugins_set_up ) + return; + plugins_set_up = true; + QStringList widgets = widgetManager()->featureList(); + for ( QStringList::Iterator it = widgets.begin(); it != widgets.end(); ++it ) { + if ( hasWidget( *it ) ) + continue; + WidgetDatabaseRecord *r = new WidgetDatabaseRecord; + WidgetInterface *iface = 0; + widgetManager()->queryInterface( *it, &iface ); + if ( !iface ) + continue; + +#ifndef UIC + QIconSet icon = iface->iconSet( *it ); + if ( !icon.pixmap().isNull() ) + r->icon = new QIconSet( icon ); +#endif + QString grp = iface->group( *it ); + if ( grp.isEmpty() ) + grp = "3rd party widgets"; + r->group = widgetGroup( grp ); + r->toolTip = iface->toolTip( *it ); + r->whatsThis = iface->whatsThis( *it ); + r->includeFile = iface->includeFile( *it ); + r->isContainer = iface->isContainer( *it ); + r->name = *it; + append( r ); + iface->release(); + } +} + +/*! + Returns the number of elements in the widget database. +*/ + +int WidgetDatabase::count() +{ + setupDataBase( -1 ); + return dbcount; +} + +/*! + Returns the id at which the ids of custom widgets start. +*/ + +int WidgetDatabase::startCustom() +{ + setupDataBase( -1 ); + return dbcustom; +} + +/*! + Returns the iconset which represents the class registered as \a id. +*/ + +QIconSet WidgetDatabase::iconSet( int id ) +{ + setupDataBase( id ); + WidgetDatabaseRecord *r = at( id ); + if ( !r ) + return QIconSet(); +#if !defined(UIC) && !defined(RESOURCE) + if ( !r->icon ) + r->icon = new QIconSet( PixmapChooser::loadPixmap( r->iconSet, PixmapChooser::Small ), + PixmapChooser::loadPixmap( r->iconSet, PixmapChooser::Large ) ); + return *r->icon; +#else + return QIconSet(); +#endif +} + +/*! + Returns the classname of the widget which is registered as \a id. +*/ + +QString WidgetDatabase::className( int id ) +{ + setupDataBase( id ); + WidgetDatabaseRecord *r = at( id ); + if ( !r ) + return QString::null; + return r->name; +} + +/*! + Returns the group to which the widget registered as \a id belongs. +*/ + +QString WidgetDatabase::group( int id ) +{ + setupDataBase( id ); + WidgetDatabaseRecord *r = at( id ); + if ( !r ) + return QString::null; + return r->group; +} + +/*! Returns the tooltip text of the widget which is registered as \a + id. +*/ + +QString WidgetDatabase::toolTip( int id ) +{ + setupDataBase( id ); + WidgetDatabaseRecord *r = at( id ); + if ( !r ) + return QString::null; + return r->toolTip; +} + +/*! Returns the what's this? test of the widget which is registered + as \a id. +*/ + +QString WidgetDatabase::whatsThis( int id ) +{ + setupDataBase( id ); + WidgetDatabaseRecord *r = at( id ); + if ( !r ) + return QString::null; + return r->whatsThis; +} + +/*! + Returns the include file if the widget which is registered as \a id. +*/ + +QString WidgetDatabase::includeFile( int id ) +{ + setupDataBase( id ); + WidgetDatabaseRecord *r = at( id ); + if ( !r ) + return QString::null; + if ( r->includeFile.isNull() ) + return r->name.lower() + ".h"; + return r->includeFile; +} + +/*! Returns wheather the widget registered as \a id is a form +*/ +bool WidgetDatabase::isForm( int id ) +{ + setupDataBase( id ); + WidgetDatabaseRecord *r = at( id ); + if ( !r ) + return false; + return r->isForm; +} + +/*! Returns wheather the widget registered as \a id is a container + (can have children) or not. +*/ + +bool WidgetDatabase::isContainer( int id ) +{ + setupDataBase( id ); + WidgetDatabaseRecord *r = at( id ); + if ( !r ) + return false; + return r->isContainer || r->isForm; +} + +QString WidgetDatabase::createWidgetName( int id ) +{ + setupDataBase( id ); + QString n = className( id ); + if ( n == "QLayoutWidget" ) + n = "Layout"; + if ( n[ 0 ] == 'Q' ) + n = n.mid( 1 ); + WidgetDatabaseRecord *r = at( id ); + if ( !r ) + return n; + n += QString::number( ++r->nameCounter ); + return n; +} + +/*! Returns the id for \a name or -1 if \a name is unknown. + */ +int WidgetDatabase::idFromClassName( const QString &name ) +{ + setupDataBase( -1 ); + if ( name.isEmpty() ) + return 0; + int *i = className2Id->find( name ); + if ( i ) + return *i; + if ( name == "FormWindow" ) + return idFromClassName( "QLayoutWidget" ); +#ifdef UIC +#ifndef NO_UI_PLUGINS + setupDataBase( -2 ); + i = className2Id->find( name ); + if ( i ) + return *i; +#endif +#endif + return -1; +} + +bool WidgetDatabase::hasWidget( const QString &name ) +{ + return className2Id->find( name ) != 0; +} + +WidgetDatabaseRecord *WidgetDatabase::at( int index ) +{ + if ( index < 0 ) + return 0; + if ( index >= dbcustom && index < dbcustomcount ) + return db[ index ]; + if ( index < dbcount ) + return db[ index ]; + return 0; +} + +void WidgetDatabase::insert( int index, WidgetDatabaseRecord *r ) +{ + if ( index < 0 || index >= dbsize ) + return; + db[ index ] = r; + className2Id->insert( r->name, new int( index ) ); + if ( index < dbcustom ) + dbcount = QMAX( dbcount, index ); +} + +void WidgetDatabase::append( WidgetDatabaseRecord *r ) +{ + if ( !was_in_setup ) + setupDataBase( -1 ); + insert( dbcount++, r ); +} + +QString WidgetDatabase::widgetGroup( const QString &g ) +{ + if ( wGroups->find( g ) == -1 ) + wGroups->append( g ); + return g; +} + +bool WidgetDatabase::isGroupEmpty( const QString &grp ) +{ + WidgetDatabaseRecord *r = 0; + for ( int i = 0; i < dbcount; ++i ) { + if ( !( r = db[ i ] ) ) + continue; + if ( r->group == grp ) + return false; + } + return true; +} + +QString WidgetDatabase::widgetGroup( int i ) +{ + setupDataBase( -1 ); + if ( i >= 0 && i < (int)wGroups->count() ) + return wGroups->at( i ); + return QString::null; +} + +int WidgetDatabase::numWidgetGroups() +{ + setupDataBase( -1 ); + return wGroups->count(); +} + +bool WidgetDatabase::isGroupVisible( const QString &g ) +{ + setupDataBase( -1 ); + return invisibleGroups->find( g ) == -1; +} + +int WidgetDatabase::addCustomWidget( WidgetDatabaseRecord *r ) +{ + insert( dbcustomcount++, r ); + return dbcustomcount - 1; +} + +bool WidgetDatabase::isCustomWidget( int id ) +{ + if ( id >= dbcustom && id < dbcustomcount ) + return true; + return false; +} + +bool WidgetDatabase::isWhatsThisLoaded() +{ + return whatsThisLoaded; +} + +void WidgetDatabase::loadWhatsThis( const QString &docPath ) +{ + QString whatsthisFile = docPath + "/whatsthis"; + QFile f( whatsthisFile ); + if ( !f.open( IO_ReadOnly ) ) + return; + QTextStream ts( &f ); + while ( !ts.atEnd() ) { + QString s = ts.readLine(); + QStringList l = QStringList::split( " | ", s ); + int id = idFromClassName( l[ 1 ] ); + WidgetDatabaseRecord *r = at( id ); + if ( r ) + r->whatsThis = l[ 0 ]; + } + whatsThisLoaded = true; +} + +QPluginManager<WidgetInterface> *widgetManager() +{ + if ( !widgetPluginManager ) { + widgetPluginManager = new QPluginManager<WidgetInterface>( IID_Widget, QApplication::libraryPaths(), "/designer" ); + cleanup_manager.add( &widgetPluginManager ); + } + return widgetPluginManager; +} diff --git a/qtruby/rubylib/designer/rbuic/widgetdatabase.h b/qtruby/rubylib/designer/rbuic/widgetdatabase.h new file mode 100644 index 00000000..efe585ab --- /dev/null +++ b/qtruby/rubylib/designer/rbuic/widgetdatabase.h @@ -0,0 +1,85 @@ +/********************************************************************** +** Copyright (C) 2000 Trolltech AS. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ + +#ifndef WIDGETDATABASE_H +#define WIDGETDATABASE_H + +#include <qiconset.h> +#include <qstring.h> +#include "widgetinterface.h" // up here for GCC 2.7.* compatibility +#include <private/qpluginmanager_p.h> + + +extern QPluginManager<WidgetInterface> *widgetManager(); + +struct WidgetDatabaseRecord +{ + WidgetDatabaseRecord(); + ~WidgetDatabaseRecord(); + QString iconSet, name, group, toolTip, whatsThis, includeFile; + uint isContainer : 1; + uint isForm : 1; + QIconSet *icon; + int nameCounter; +}; + +class WidgetDatabase : public Qt +{ +public: + WidgetDatabase(); + static void setupDataBase( int id ); + static void setupPlugins(); + + static int count(); + static int startCustom(); + + static QIconSet iconSet( int id ); + static QString className( int id ); + static QString group( int id ); + static QString toolTip( int id ); + static QString whatsThis( int id ); + static QString includeFile( int id ); + static bool isForm( int id ); + static bool isContainer( int id ); + + static int idFromClassName( const QString &name ); + static QString createWidgetName( int id ); + + static WidgetDatabaseRecord *at( int index ); + static void insert( int index, WidgetDatabaseRecord *r ); + static void append( WidgetDatabaseRecord *r ); + + static QString widgetGroup( const QString &g ); + static QString widgetGroup( int i ); + static int numWidgetGroups(); + static bool isGroupVisible( const QString &g ); + static bool isGroupEmpty( const QString &grp ); + + static int addCustomWidget( WidgetDatabaseRecord *r ); + static bool isCustomWidget( int id ); + + static bool isWhatsThisLoaded(); + static void loadWhatsThis( const QString &docPath ); + + static bool hasWidget( const QString &name ); + +}; + +#endif diff --git a/qtruby/rubylib/designer/rbuic/widgetinterface.h b/qtruby/rubylib/designer/rbuic/widgetinterface.h new file mode 100644 index 00000000..bf6bcd55 --- /dev/null +++ b/qtruby/rubylib/designer/rbuic/widgetinterface.h @@ -0,0 +1,29 @@ + /********************************************************************** +** Copyright (C) 2000-2001 Trolltech AS. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ + +#ifndef WIDGETINTERFACE_H +#define WIDGETINTERFACE_H + +#include <private/qwidgetinterface_p.h> + +#define WidgetInterface QWidgetFactoryInterface +#define IID_Widget IID_QWidgetFactory + +#endif diff --git a/qtruby/rubylib/designer/uilib/Makefile.am b/qtruby/rubylib/designer/uilib/Makefile.am new file mode 100644 index 00000000..e7f21bea --- /dev/null +++ b/qtruby/rubylib/designer/uilib/Makefile.am @@ -0,0 +1,7 @@ +INCLUDES = -I$(top_srcdir)/smoke -I$(top_srcdir)/qtruby/rubylib/qtruby $(all_includes) -I$(RUBY_ARCHDIR) + +rubylibdir = $(RUBY_SITEARCHDIR) +rubylib_LTLIBRARIES = qui.la +qui_la_SOURCES = qui.cpp +qui_la_LDFLAGS = -module -export-dynamic $(all_libraries) -version-info 0:0:0 +qui_la_LIBADD = -lqui
\ No newline at end of file diff --git a/qtruby/rubylib/designer/uilib/extconf.rb b/qtruby/rubylib/designer/uilib/extconf.rb new file mode 100644 index 00000000..fa742b9a --- /dev/null +++ b/qtruby/rubylib/designer/uilib/extconf.rb @@ -0,0 +1,6 @@ +require 'mkmf' +dir_config('smoke') +dir_config('qt') +$CPPFLAGS += " -I../../../../smoke -I../../qtruby " +$LOCAL_LIBS += '-bundle_loader ../../qtruby/qtruby.bundle -lsmokeqt -lqui -lqt-mt -lstdc++' +create_makefile("qui") diff --git a/qtruby/rubylib/designer/uilib/qui.cpp b/qtruby/rubylib/designer/uilib/qui.cpp new file mode 100644 index 00000000..9aa7513f --- /dev/null +++ b/qtruby/rubylib/designer/uilib/qui.cpp @@ -0,0 +1,175 @@ +/*************************************************************************** + qui.cpp - A ruby wrapper for the QWidgetFactory class + ------------------- + begin : Wed Mar 14 2004 + copyright : (C) 2004 by Richard Dale + email : Richard_Dale@tipitina.demon.co.uk + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include <qwidgetfactory.h> +#include <qwidget.h> + +#include "smoke.h" + +#undef DEBUG +#ifndef _GNU_SOURCE +#define _GNU_SOURCE +#endif +#ifndef __USE_POSIX +#define __USE_POSIX +#endif +#ifndef __USE_XOPEN +#define __USE_XOPEN +#endif +#include <ruby.h> + +#include "qtruby.h" +#include "smokeruby.h" + +extern Smoke *qt_Smoke; +extern bool isDerivedFrom(Smoke *smoke, Smoke::Index classId, Smoke::Index baseId); + +extern "C" { +extern VALUE set_obj_info(const char * className, smokeruby_object * o); + +static VALUE qui_module; +static VALUE qwidget_factory_class; + +static VALUE +create(int argc, VALUE * argv, VALUE /*klass*/) +{ + QWidget * topLevelWidget = 0; + VALUE result = Qnil; + + if (argc == 0 || argc > 4) { + rb_raise(rb_eArgError, "wrong number of arguments (%d)\n", argc); + } + + QObject * connector = 0; + if (argc >= 2) { + if (TYPE(argv[1]) == T_DATA) { + smokeruby_object *o = value_obj_info(argv[1]); + if (o != 0) { + connector = (QObject *) o->ptr; + } + } else { + rb_raise(rb_eArgError, "invalid argument type\n"); + } + } + + QWidget * parent = 0; + if (argc >= 3) { + if (TYPE(argv[2]) == T_DATA) { + smokeruby_object *o = value_obj_info(argv[2]); + if (o != 0) { + parent = (QWidget *) o->ptr; + } + } else { + rb_raise(rb_eArgError, "invalid argument type\n"); + } + } + + const char * name = 0; + if (argc >= 4) { + if (TYPE(argv[3]) == T_STRING) { + name = StringValuePtr(argv[3]); + } else { + rb_raise(rb_eArgError, "invalid argument type\n"); + } + } + + if (TYPE(argv[0]) == T_STRING) { + topLevelWidget = QWidgetFactory::create(QString(StringValuePtr(argv[0])), connector, parent, name); + } else if (TYPE(argv[0]) == T_DATA) { + QIODevice * dev = 0; + smokeruby_object *o = value_obj_info(argv[0]); + + if (o != 0 && o->ptr != 0 && o->classId == qt_Smoke->idClass("QIODevice")) { + dev = (QIODevice *) o->ptr; + } else { + rb_raise(rb_eArgError, "invalid argument type\n"); + } + + topLevelWidget = QWidgetFactory::create(dev, connector, parent, name); + } else { + rb_raise(rb_eArgError, "invalid argument type\n"); + } + + if (topLevelWidget != 0) { + smokeruby_object * o = (smokeruby_object *) malloc(sizeof(smokeruby_object)); + o->smoke = qt_Smoke; + o->classId = qt_Smoke->idClass(topLevelWidget->className()); + o->ptr = topLevelWidget; + o->allocated = false; + + const char * className = qt_Smoke->binding->className(o->classId); + result = set_obj_info(className, o); + } + + return result; +} + +static VALUE +load_images(VALUE klass, VALUE dir) +{ + QWidgetFactory::loadImages(QString(StringValuePtr(dir))); + return klass; +} + +static VALUE +widgets(VALUE /*self*/) +{ + VALUE result = rb_ary_new(); + QStringList widgetList = QWidgetFactory::widgets(); + + for (QStringList::Iterator it = widgetList.begin(); it != widgetList.end(); ++it) { + QString widgetName = *it; + if (widgetName.startsWith("Q")) { + widgetName.replace(0, 1, QString("Qt::")); + } else if (widgetName.startsWith("K")) { + widgetName.replace(0, 1, QString("KDE::")); + } + rb_ary_push(result, rb_str_new2(widgetName.latin1())); + } + + return result; +} + +static VALUE +supports_widget(VALUE /*self*/, VALUE widget) +{ + QString widgetName(StringValuePtr(widget)); + + if (widgetName.startsWith("Qt::")) { + widgetName.replace(0, 4, QString("Q")); + } else if (widgetName.startsWith("KDE::")) { + widgetName.replace(0, 5, QString("K")); + } + + return QWidgetFactory::supportsWidget(widgetName) ? Qtrue : Qfalse; +} + +void +Init_qui() +{ + qui_module = rb_define_module("QUI"); + qwidget_factory_class = rb_define_class_under(qui_module, "WidgetFactory", rb_cObject); + + rb_define_singleton_method(qwidget_factory_class, "create", (VALUE (*) (...)) create, -1); + rb_define_singleton_method(qwidget_factory_class, "loadImages", (VALUE (*) (...)) load_images, 1); + rb_define_singleton_method(qwidget_factory_class, "load_images", (VALUE (*) (...)) load_images, 1); + rb_define_singleton_method(qwidget_factory_class, "widgets", (VALUE (*) (...)) widgets, 0); + rb_define_singleton_method(qwidget_factory_class, "supportsWidget", (VALUE (*) (...)) supports_widget, 1); + rb_define_singleton_method(qwidget_factory_class, "supports_widget", (VALUE (*) (...)) supports_widget, 1); +} + +}; diff --git a/qtruby/rubylib/designer/uilib/test/test.rb b/qtruby/rubylib/designer/uilib/test/test.rb new file mode 100644 index 00000000..628f1270 --- /dev/null +++ b/qtruby/rubylib/designer/uilib/test/test.rb @@ -0,0 +1,20 @@ +require 'Qt'
+require 'qui'
+
+a = Qt::Application.new(ARGV)
+if ARGV.length == 0
+ puts "Usage: test.rb <image dir> <ui file>"
+ exit
+end
+
+if ARGV.length == 2
+ QUI::WidgetFactory.loadImages( ARGV[ 0 ] )
+ w = QUI::WidgetFactory.create( ARGV[ 1 ] )
+ if w.nil?
+ puts "Failed to create top level widget"
+ exit
+ end
+ w.show()
+ a.connect( a, SIGNAL('lastWindowClosed()'), a, SLOT('quit()') )
+ a.exec()
+end
|